public function build(): void
    {
        $allAvailableClassNamesByPackage = $this->objectManager->getRegisteredClassNames();
        $possibleTargetClassNames = $this->getProxyableClasses($allAvailableClassNamesByPackage);
        $actualAspectClassNames = $this->reflectionService->getClassNamesByAnnotation(Flow\Aspect::class);
        sort($possibleTargetClassNames);
        sort($actualAspectClassNames);

        $this->aspectContainers = $this->buildAspectContainers($actualAspectClassNames);

        $rebuildEverything = false;
        if ($this->objectConfigurationCache->has('allAspectClassesUpToDate') === false) {
            $rebuildEverything = true;
            $this->logger->info('Aspects have been modified, therefore rebuilding all target classes.', LogEnvironment::fromMethodName(__METHOD__));
            $this->objectConfigurationCache->set('allAspectClassesUpToDate', true);
        }

        $possibleTargetClassNameIndex = new ClassNameIndex();
        $possibleTargetClassNameIndex->setClassNames($possibleTargetClassNames);

        $targetClassNameCandidates = new ClassNameIndex();
        foreach ($this->aspectContainers as $aspectContainer) {
            $targetClassNameCandidates->applyUnion($aspectContainer->reduceTargetClassNames($possibleTargetClassNameIndex));
        }
        $targetClassNameCandidates->sort();

        $treatedSubClasses = new ClassNameIndex();

        foreach ($targetClassNameCandidates->getClassNames() as $targetClassName) {
            $isUnproxied = $this->objectConfigurationCache->has('unproxiedClass-' . str_replace('\\', '_', $targetClassName));
            $hasCacheEntry = $this->compiler->hasCacheEntryForClass($targetClassName) || $isUnproxied;
            if ($rebuildEverything === true || $hasCacheEntry === false) {
                $proxyBuildResult = $this->buildProxyClass($targetClassName, $this->aspectContainers);
                if ($proxyBuildResult === false) {
                    // In case the proxy was not build because there was nothing adviced,
                    // it might be an advice in the parent and so we need to try to treat this class.
                    $treatedSubClasses = $this->addBuildMethodsAndAdvicesCodeToClass($targetClassName, $treatedSubClasses);
                }
                $treatedSubClasses = $this->proxySubClassesOfClassToEnsureAdvices($targetClassName, $targetClassNameCandidates, $treatedSubClasses);
                if ($proxyBuildResult !== false) {
                    if ($isUnproxied) {
                        $this->objectConfigurationCache->remove('unproxiedClass-' . str_replace('\\', '_', $targetClassName));
                    }
                    $this->logger->debug(sprintf('Built AOP proxy for class "%s".', $targetClassName));
                } else {
                    $this->objectConfigurationCache->set('unproxiedClass-' . str_replace('\\', '_', $targetClassName), true);
                }
            }
        }
    }
public function build(): void
    {
        $allAvailableClassNamesByPackage = $this->objectManager->getRegisteredClassNames();
        $possibleTargetClassNames = $this->getProxyableClasses($allAvailableClassNamesByPackage);
        $actualAspectClassNames = $this->reflectionService->getClassNamesByAnnotation(Flow\Aspect::class);
        sort($possibleTargetClassNames);
        sort($actualAspectClassNames);

        $this->aspectContainers = $this->buildAspectContainers($actualAspectClassNames);

        $rebuildEverything = false;
        if ($this->objectConfigurationCache->has('allAspectClassesUpToDate') === false) {
            $rebuildEverything = true;
            $this->logger->info('Aspects have been modified, therefore rebuilding all target classes.', LogEnvironment::fromMethodName(__METHOD__));
            $this->objectConfigurationCache->set('allAspectClassesUpToDate', true);
        }

        $possibleTargetClassNameIndex = new ClassNameIndex();
        $possibleTargetClassNameIndex->setClassNames($possibleTargetClassNames);

        $targetClassNameCandidates = new ClassNameIndex();
        foreach ($this->aspectContainers as $aspectContainer) {
            $targetClassNameCandidates->applyUnion($aspectContainer->reduceTargetClassNames($possibleTargetClassNameIndex));
        }
        $targetClassNameCandidates->sort();

        $treatedSubClasses = new ClassNameIndex();

        foreach ($targetClassNameCandidates->getClassNames() as $targetClassName) {
            $isUnproxied = $this->objectConfigurationCache->has('unproxiedClass-' . str_replace('\\', '_', $targetClassName));
            $hasCacheEntry = $this->compiler->hasCacheEntryForClass($targetClassName) || $isUnproxied;
            if ($rebuildEverything === true || $hasCacheEntry === false) {
                $proxyBuildResult = $this->buildProxyClass($targetClassName, $this->aspectContainers);
                if ($proxyBuildResult === false) {
                    // In case the proxy was not build because there was nothing adviced,
                    // it might be an advice in the parent and so we need to try to treat this class.
                    $treatedSubClasses = $this->addBuildMethodsAndAdvicesCodeToClass($targetClassName, $treatedSubClasses);
                }
                $treatedSubClasses = $this->proxySubClassesOfClassToEnsureAdvices($targetClassName, $targetClassNameCandidates, $treatedSubClasses);
                if ($proxyBuildResult !== false) {
                    if ($isUnproxied) {
                        $this->objectConfigurationCache->remove('unproxiedClass-' . str_replace('\\', '_', $targetClassName));
                    }
                    $this->logger->debug(sprintf('Built AOP proxy for class "%s".', $targetClassName));
                } else {
                    $this->objectConfigurationCache->set('unproxiedClass-' . str_replace('\\', '_', $targetClassName), true);
                }
            }
        }
    }
public function build ( ) : void { $ allAvailableClassNamesByPackage = $ this -> objectManager -> getRegisteredClassNames ( ) ; $ possibleTargetClassNames = $ this -> getProxyableClasses ( $ allAvailableClassNamesByPackage ) ; $ actualAspectClassNames = $ this -> reflectionService -> getClassNamesByAnnotation ( Flow \ Aspect :: class ) ; sort ( $ possibleTargetClassNames ) ; sort ( $ actualAspectClassNames ) ; $ this -> aspectContainers = $ this -> buildAspectContainers ( $ actualAspectClassNames ) ; $ rebuildEverything = false ; if ( $ this -> objectConfigurationCache -> has ( 'allAspectClassesUpToDate' ) === false ) { $ rebuildEverything = true ; $ this -> logger -> info ( 'Aspects have been modified, therefore rebuilding all target classes.' , LogEnvironment :: fromMethodName ( __METHOD__ ) ) ; $ this -> objectConfigurationCache -> set ( 'allAspectClassesUpToDate' , true ) ; } $ possibleTargetClassNameIndex = new ClassNameIndex ( ) ; $ possibleTargetClassNameIndex -> setClassNames ( $ possibleTargetClassNames ) ; $ targetClassNameCandidates = new ClassNameIndex ( ) ; foreach ( $ this -> aspectContainers as $ aspectContainer ) { $ targetClassNameCandidates -> applyUnion ( $ aspectContainer -> reduceTargetClassNames ( $ possibleTargetClassNameIndex ) ) ; } $ targetClassNameCandidates -> sort ( ) ; $ treatedSubClasses = new ClassNameIndex ( ) ; foreach ( $ targetClassNameCandidates -> getClassNames ( ) as $ targetClassName ) { $ isUnproxied = $ this -> objectConfigurationCache -> has ( 'unproxiedClass-' . str_replace ( '\\' , '_' , $ targetClassName ) ) ; $ hasCacheEntry = $ this -> compiler -> hasCacheEntryForClass ( $ targetClassName ) || $ isUnproxied ; if ( $ rebuildEverything === true || $ hasCacheEntry === false ) { $ proxyBuildResult = $ this -> buildProxyClass ( $ targetClassName , $ this -> aspectContainers ) ; if ( $ proxyBuildResult === false ) { // In case the proxy was not build because there was nothing adviced, // it might be an advice in the parent and so we need to try to treat this class. $ treatedSubClasses = $ this -> addBuildMethodsAndAdvicesCodeToClass ( $ targetClassName , $ treatedSubClasses ) ; } $ treatedSubClasses = $ this -> proxySubClassesOfClassToEnsureAdvices ( $ targetClassName , $ targetClassNameCandidates , $ treatedSubClasses ) ; if ( $ proxyBuildResult !== false ) { if ( $ isUnproxied ) { $ this -> objectConfigurationCache -> remove ( 'unproxiedClass-' . str_replace ( '\\' , '_' , $ targetClassName ) ) ; } $ this -> logger -> debug ( sprintf ( 'Built AOP proxy for class "%s".' , $ targetClassName ) ) ; } else { $ this -> objectConfigurationCache -> set ( 'unproxiedClass-' . str_replace ( '\\' , '_' , $ targetClassName ) , true ) ; } } } }
Builds proxy class code which weaves advices into the respective target classes.

The object configurations provided by the Compiler are searched for possible aspect
annotations. If an aspect class is found, the pointcut expressions are parsed and
a new aspect with one or more advisors is added to the aspect registry of the AOP framework.
Finally all advices are woven into their target classes by generating proxy classes.

In general, the command neos.flow:core:compile is responsible for compilation
and calls this method to do so.

In order to distinguish between an emerged / changed possible target class and
a class which has been matched previously but just didn't have to be proxied,
the latter are kept track of by an "unproxiedClass-*" cache entry.

@return void
Builds proxy class code which weaves advices into the respective target classes .