private function adjustOriginalClass(
        ReflectionClass $class,
        array $advices,
        StreamMetaData $streamMetaData,
        string $newClassName
    ): void {
        $classNode = $class->getNode();
        $position  = $classNode->getAttribute('startTokenPos');
        do {
            if (isset($streamMetaData->tokenStream[$position])) {
                $token = $streamMetaData->tokenStream[$position];
                // Remove final and following whitespace from the class, child will be final instead
                if ($token[0] === T_FINAL) {
                    unset($streamMetaData->tokenStream[$position], $streamMetaData->tokenStream[$position+1]);
                }
                // First string is class/trait name
                if ($token[0] === T_STRING) {
                    $streamMetaData->tokenStream[$position][1] = $newClassName;
                    // We have finished our job, can break this loop
                    break;
                }
            }
            ++$position;
        } while (true);

        foreach ($class->getMethods(ReflectionMethod::IS_FINAL) as $finalMethod) {
            if (!$finalMethod instanceof ReflectionMethod || $finalMethod->getDeclaringClass()->name !== $class->name) {
                continue;
            }
            $hasDynamicAdvice = isset($advices[AspectContainer::METHOD_PREFIX][$finalMethod->name]);
            $hasStaticAdvice  = isset($advices[AspectContainer::STATIC_METHOD_PREFIX][$finalMethod->name]);
            if (!$hasDynamicAdvice && !$hasStaticAdvice) {
                continue;
            }
            $methodNode = $finalMethod->getNode();
            $position   = $methodNode->getAttribute('startTokenPos');
            do {
                if (isset($streamMetaData->tokenStream[$position])) {
                    $token = $streamMetaData->tokenStream[$position];
                    // Remove final and following whitespace from the method, child will be final instead
                    if ($token[0] === T_FINAL) {
                        unset($streamMetaData->tokenStream[$position], $streamMetaData->tokenStream[$position+1]);
                        break;
                    }
                }
                ++$position;
            } while (true);
        }
    }
private function adjustOriginalClass(
        ReflectionClass $class,
        array $advices,
        StreamMetaData $streamMetaData,
        string $newClassName
    ): void {
        $classNode = $class->getNode();
        $position  = $classNode->getAttribute('startTokenPos');
        do {
            if (isset($streamMetaData->tokenStream[$position])) {
                $token = $streamMetaData->tokenStream[$position];
                // Remove final and following whitespace from the class, child will be final instead
                if ($token[0] === T_FINAL) {
                    unset($streamMetaData->tokenStream[$position], $streamMetaData->tokenStream[$position+1]);
                }
                // First string is class/trait name
                if ($token[0] === T_STRING) {
                    $streamMetaData->tokenStream[$position][1] = $newClassName;
                    // We have finished our job, can break this loop
                    break;
                }
            }
            ++$position;
        } while (true);

        foreach ($class->getMethods(ReflectionMethod::IS_FINAL) as $finalMethod) {
            if (!$finalMethod instanceof ReflectionMethod || $finalMethod->getDeclaringClass()->name !== $class->name) {
                continue;
            }
            $hasDynamicAdvice = isset($advices[AspectContainer::METHOD_PREFIX][$finalMethod->name]);
            $hasStaticAdvice  = isset($advices[AspectContainer::STATIC_METHOD_PREFIX][$finalMethod->name]);
            if (!$hasDynamicAdvice && !$hasStaticAdvice) {
                continue;
            }
            $methodNode = $finalMethod->getNode();
            $position   = $methodNode->getAttribute('startTokenPos');
            do {
                if (isset($streamMetaData->tokenStream[$position])) {
                    $token = $streamMetaData->tokenStream[$position];
                    // Remove final and following whitespace from the method, child will be final instead
                    if ($token[0] === T_FINAL) {
                        unset($streamMetaData->tokenStream[$position], $streamMetaData->tokenStream[$position+1]);
                        break;
                    }
                }
                ++$position;
            } while (true);
        }
    }
private function adjustOriginalClass ( ReflectionClass $ class , array $ advices , StreamMetaData $ streamMetaData , string $ newClassName ) : void { $ classNode = $ class -> getNode ( ) ; $ position = $ classNode -> getAttribute ( 'startTokenPos' ) ; do { if ( isset ( $ streamMetaData -> tokenStream [ $ position ] ) ) { $ token = $ streamMetaData -> tokenStream [ $ position ] ; // Remove final and following whitespace from the class, child will be final instead if ( $ token [ 0 ] === T_FINAL ) { unset ( $ streamMetaData -> tokenStream [ $ position ] , $ streamMetaData -> tokenStream [ $ position + 1 ] ) ; } // First string is class/trait name if ( $ token [ 0 ] === T_STRING ) { $ streamMetaData -> tokenStream [ $ position ] [ 1 ] = $ newClassName ; // We have finished our job, can break this loop break ; } } ++ $ position ; } while ( true ) ; foreach ( $ class -> getMethods ( ReflectionMethod :: IS_FINAL ) as $ finalMethod ) { if ( ! $ finalMethod instanceof ReflectionMethod || $ finalMethod -> getDeclaringClass ( ) -> name !== $ class -> name ) { continue ; } $ hasDynamicAdvice = isset ( $ advices [ AspectContainer :: METHOD_PREFIX ] [ $ finalMethod -> name ] ) ; $ hasStaticAdvice = isset ( $ advices [ AspectContainer :: STATIC_METHOD_PREFIX ] [ $ finalMethod -> name ] ) ; if ( ! $ hasDynamicAdvice && ! $ hasStaticAdvice ) { continue ; } $ methodNode = $ finalMethod -> getNode ( ) ; $ position = $ methodNode -> getAttribute ( 'startTokenPos' ) ; do { if ( isset ( $ streamMetaData -> tokenStream [ $ position ] ) ) { $ token = $ streamMetaData -> tokenStream [ $ position ] ; // Remove final and following whitespace from the method, child will be final instead if ( $ token [ 0 ] === T_FINAL ) { unset ( $ streamMetaData -> tokenStream [ $ position ] , $ streamMetaData -> tokenStream [ $ position + 1 ] ) ; break ; } } ++ $ position ; } while ( true ) ; } }
Adjust definition of original class source to enable extending

@param array $advices List of class advices (used to check for final methods and make them non-final)
Adjust definition of original class source to enable extending