/**
  * This method is used to optimize the matching process.
  *
  * @param \Neos\Flow\Aop\Builder\ClassNameIndex $classNameIndex
  * @return \Neos\Flow\Aop\Builder\ClassNameIndex
  */
 public function reduceTargetClassNames(\Neos\Flow\Aop\Builder\ClassNameIndex $classNameIndex)
 {
     $classNames = $this->reflectionService->getClassNamesByAnnotation(Flow\ValueObject::class);
     $annotatedIndex = new \Neos\Flow\Aop\Builder\ClassNameIndex();
     $annotatedIndex->setClassNames($classNames);
     return $classNameIndex->intersect($annotatedIndex);
 }
 /**
  * @test
  */
 public function filterByPrefixWork()
 {
     $index1 = new Aop\Builder\ClassNameIndex();
     $index1->setClassNames(['\\Foo\\Bar', '\\Foo\\Baz', '\\Bar\\Baz', '\\Foo\\Blubb']);
     // We need to call sort manually!
     $index1->sort();
     $filteredIndex = $index1->filterByPrefix('\\Foo');
     $this->assertEquals(['\\Foo\\Bar', '\\Foo\\Baz', '\\Foo\\Blubb'], $filteredIndex->getClassNames());
 }
 /**
  * @test
  */
 public function reduceTargetClassNamesFiltersAllClassesNotMatchedByAClassNameFilterWithRegularExpressions()
 {
     $availableClassNames = ['TestPackage\\Subpackage\\Class1', 'TestPackage\\Class2', 'TestPackage\\Subpackage\\SubSubPackage\\Class3', 'TestPackage\\Subpackage2\\Class4'];
     sort($availableClassNames);
     $availableClassNamesIndex = new Aop\Builder\ClassNameIndex();
     $availableClassNamesIndex->setClassNames($availableClassNames);
     $expectedClassNames = ['TestPackage\\Subpackage\\Class1', 'TestPackage\\Subpackage\\SubSubPackage\\Class3'];
     sort($expectedClassNames);
     $expectedClassNamesIndex = new Aop\Builder\ClassNameIndex();
     $expectedClassNamesIndex->setClassNames($expectedClassNames);
     $classNameFilter = new Aop\Pointcut\PointcutClassNameFilter('TestPackage\\Subpackage\\.*');
     $result = $classNameFilter->reduceTargetClassNames($availableClassNamesIndex);
     $this->assertEquals($expectedClassNamesIndex, $result, 'The wrong class names have been filtered');
 }
 /**
  * @test
  */
 public function reduceTargetClassNamesFiltersAllClassesNotHavingAMethodWithTheGivenAnnotation()
 {
     $availableClassNames = ['TestPackage\\Subpackage\\Class1', 'TestPackage\\Class2', 'TestPackage\\Subpackage\\SubSubPackage\\Class3', 'TestPackage\\Subpackage2\\Class4'];
     sort($availableClassNames);
     $availableClassNamesIndex = new Aop\Builder\ClassNameIndex();
     $availableClassNamesIndex->setClassNames($availableClassNames);
     $mockReflectionService = $this->getMockBuilder(ReflectionService::class)->disableOriginalConstructor()->getMock();
     $mockReflectionService->expects($this->any())->method('getClassesContainingMethodsAnnotatedWith')->with('SomeAnnotationClass')->will($this->returnValue(['TestPackage\\Subpackage\\Class1', 'TestPackage\\Subpackage\\SubSubPackage\\Class3', 'SomeMoreClass']));
     $methodAnnotatedWithFilter = new Aop\Pointcut\PointcutMethodAnnotatedWithFilter('SomeAnnotationClass');
     $methodAnnotatedWithFilter->injectReflectionService($mockReflectionService);
     $expectedClassNames = ['TestPackage\\Subpackage\\Class1', 'TestPackage\\Subpackage\\SubSubPackage\\Class3'];
     sort($expectedClassNames);
     $expectedClassNamesIndex = new Aop\Builder\ClassNameIndex();
     $expectedClassNamesIndex->setClassNames($expectedClassNames);
     $result = $methodAnnotatedWithFilter->reduceTargetClassNames($availableClassNamesIndex);
     $this->assertEquals($expectedClassNamesIndex, $result, 'The wrong class names have been filtered');
 }
 /**
  * @test
  */
 public function reduceTargetClassNamesFiltersAllClassesNotBeeingConfiguredAsScopeSession()
 {
     $availableClassNames = ['TestPackage\\Subpackage\\Class1', 'TestPackage\\Class2', 'TestPackage\\Subpackage\\SubSubPackage\\Class3', 'TestPackage\\Subpackage2\\Class4'];
     sort($availableClassNames);
     $availableClassNamesIndex = new ClassNameIndex();
     $availableClassNamesIndex->setClassNames($availableClassNames);
     $mockCompileTimeObjectManager = $this->getMockBuilder(CompileTimeObjectManager::class)->disableOriginalConstructor()->getMock();
     $mockCompileTimeObjectManager->expects($this->any())->method('getClassNamesByScope')->with(Configuration::SCOPE_SESSION)->will($this->returnValue(['TestPackage\\Subpackage\\Class1', 'TestPackage\\Subpackage\\SubSubPackage\\Class3', 'SomeMoreClass']));
     $sessionObjectMethodsPointcutFilter = new SessionObjectMethodsPointcutFilter();
     $sessionObjectMethodsPointcutFilter->injectObjectManager($mockCompileTimeObjectManager);
     $expectedClassNames = ['TestPackage\\Subpackage\\Class1', 'TestPackage\\Subpackage\\SubSubPackage\\Class3'];
     sort($expectedClassNames);
     $expectedClassNamesIndex = new ClassNameIndex();
     $expectedClassNamesIndex->setClassNames($expectedClassNames);
     $result = $sessionObjectMethodsPointcutFilter->reduceTargetClassNames($availableClassNamesIndex);
     $this->assertEquals($expectedClassNamesIndex, $result, 'The wrong class names have been filtered');
 }
 /**
  * @test
  */
 public function reduceTargetClassNamesFiltersAllClassesExceptTheClassItselfAndAllItsSubclasses()
 {
     $testClassName = uniqid('someTestInterface');
     eval('class ' . $testClassName . ' {}');
     $availableClassNames = [$testClassName, 'TestPackage\\Subpackage\\Class1', 'TestPackage\\Class2', 'TestPackage\\Subpackage\\SubSubPackage\\Class3', 'TestPackage\\Subpackage2\\Class4'];
     sort($availableClassNames);
     $availableClassNamesIndex = new Aop\Builder\ClassNameIndex();
     $availableClassNamesIndex->setClassNames($availableClassNames);
     $mockReflectionService = $this->getMockBuilder(ReflectionService::class)->disableOriginalConstructor()->getMock();
     $mockReflectionService->expects($this->any())->method('getAllSubClassNamesForClass')->with($testClassName)->will($this->returnValue(['TestPackage\\Subpackage\\Class1', 'TestPackage\\Subpackage\\SubSubPackage\\Class3', 'SomeMoreClass']));
     $classTypeFilter = new Aop\Pointcut\PointcutClassTypeFilter($testClassName);
     $classTypeFilter->injectReflectionService($mockReflectionService);
     $expectedClassNames = [$testClassName, 'TestPackage\\Subpackage\\Class1', 'TestPackage\\Subpackage\\SubSubPackage\\Class3'];
     sort($expectedClassNames);
     $expectedClassNamesIndex = new Aop\Builder\ClassNameIndex();
     $expectedClassNamesIndex->setClassNames($expectedClassNames);
     $result = $classTypeFilter->reduceTargetClassNames($availableClassNamesIndex);
     $this->assertEquals($expectedClassNamesIndex, $result, 'The wrong class names have been filtered');
 }
 /**
  * This method is used to optimize the matching process.
  *
  * @param ClassNameIndex $classNameIndex
  * @return ClassNameIndex
  */
 public function reduceTargetClassNames(ClassNameIndex $classNameIndex)
 {
     if (!preg_match('/^([^\\.\\(\\)\\{\\}\\[\\]\\?\\+\\$\\!\\|]+)/', $this->originalExpressionString, $matches)) {
         return $classNameIndex;
     }
     $prefixFilter = $matches[1];
     // We sort here to make sure the index is okay
     $classNameIndex->sort();
     return $classNameIndex->filterByPrefix($prefixFilter);
 }
 /**
  * This method is used to optimize the matching process.
  *
  * @param ClassNameIndex $classNameIndex
  * @return ClassNameIndex
  */
 public function reduceTargetClassNames(ClassNameIndex $classNameIndex)
 {
     $classNames = $this->reflectionService->getClassesContainingMethodsAnnotatedWith($this->annotation);
     $annotatedIndex = new ClassNameIndex();
     $annotatedIndex->setClassNames($classNames);
     return $classNameIndex->intersect($annotatedIndex);
 }
 /**
  * @test
  */
 public function reduceTargetClassNamesFiltersAllClassesNotMatchedAByClassNameFilter()
 {
     $availableClassNames = ['TestPackage\\Subpackage\\Class1', 'TestPackage\\Class2', 'TestPackage\\Subpackage\\SubSubPackage\\Class3', 'TestPackage\\Subpackage2\\Class4'];
     sort($availableClassNames);
     $availableClassNamesIndex = new Aop\Builder\ClassNameIndex();
     $availableClassNamesIndex->setClassNames($availableClassNames);
     $classNameFilter1 = new Pointcut\PointcutClassNameFilter('TestPackage\\Subpackage\\SubSubPackage\\Class3');
     $classNameFilter2 = new Pointcut\PointcutClassNameFilter('TestPackage\\Subpackage\\Class1');
     $methodNameFilter1 = new Pointcut\PointcutMethodNameFilter('method2');
     $expectedClassNames = ['TestPackage\\Subpackage\\Class1', 'TestPackage\\Subpackage\\SubSubPackage\\Class3'];
     sort($expectedClassNames);
     $expectedClassNamesIndex = new Aop\Builder\ClassNameIndex();
     $expectedClassNamesIndex->setClassNames($expectedClassNames);
     $pointcutFilterComposite = new Pointcut\PointcutFilterComposite();
     $pointcutFilterComposite->addFilter('&&', $classNameFilter1);
     $pointcutFilterComposite->addFilter('||', $classNameFilter2);
     $pointcutFilterComposite->addFilter('&&', $methodNameFilter1);
     $result = $pointcutFilterComposite->reduceTargetClassNames($availableClassNamesIndex);
     $this->assertEquals($expectedClassNamesIndex, $result, 'The wrong class names have been filtered');
 }
 /**
  * This method is used to optimize the matching process.
  *
  * @param ClassNameIndex $classNameIndex
  * @return ClassNameIndex
  */
 public function reduceTargetClassNames(ClassNameIndex $classNameIndex)
 {
     if (interface_exists($this->interfaceOrClassName)) {
         $classNames = $this->reflectionService->getAllImplementationClassNamesForInterface($this->interfaceOrClassName);
     } elseif (class_exists($this->interfaceOrClassName)) {
         $classNames = $this->reflectionService->getAllSubClassNamesForClass($this->interfaceOrClassName);
         $classNames[] = $this->interfaceOrClassName;
     } else {
         $classNames = [];
     }
     $filteredIndex = new ClassNameIndex();
     $filteredIndex->setClassNames($classNames);
     return $classNameIndex->intersect($filteredIndex);
 }
 /**
  * This method is used to optimize the matching process.
  *
  * @param ClassNameIndex $classNameIndex
  * @return ClassNameIndex
  */
 public function reduceTargetClassNames(ClassNameIndex $classNameIndex)
 {
     $sessionClasses = new ClassNameIndex();
     $sessionClasses->setClassNames($this->objectManager->getClassNamesByScope(ObjectConfiguration::SCOPE_SESSION));
     return $classNameIndex->intersect($sessionClasses);
 }
 /**
  * This method is used to optimize the matching process.
  *
  * @param \Neos\Flow\Aop\Builder\ClassNameIndex $classNameIndex
  * @return \Neos\Flow\Aop\Builder\ClassNameIndex
  */
 public function reduceTargetClassNames(Builder\ClassNameIndex $classNameIndex)
 {
     $result = new Builder\ClassNameIndex();
     foreach ($this->advisors as $advisor) {
         $result->applyUnion($advisor->getPointcut()->reduceTargetClassNames($classNameIndex));
     }
     foreach ($this->interfaceIntroductions as $interfaceIntroduction) {
         $result->applyUnion($interfaceIntroduction->getPointcut()->reduceTargetClassNames($classNameIndex));
     }
     foreach ($this->propertyIntroductions as $propertyIntroduction) {
         $result->applyUnion($propertyIntroduction->getPointcut()->reduceTargetClassNames($classNameIndex));
     }
     foreach ($this->traitIntroductions as $traitIntroduction) {
         $result->applyUnion($traitIntroduction->getPointcut()->reduceTargetClassNames($classNameIndex));
     }
     $this->cachedTargetClassNameCandidates = $result;
     return $result;
 }
 /**
  * Adds code to build the methods and advices array in case the parent class has some.
  *
  * @param string $className
  * @param ClassNameIndex $treatedSubClasses
  * @return ClassNameIndex
  */
 protected function addBuildMethodsAndAdvicesCodeToClass($className, ClassNameIndex $treatedSubClasses)
 {
     if ($treatedSubClasses->hasClassName($className)) {
         return $treatedSubClasses;
     }
     $treatedSubClasses = $treatedSubClasses->union(new ClassNameIndex([$className]));
     if ($this->reflectionService->isClassReflected($className) === false) {
         return $treatedSubClasses;
     }
     $proxyClass = $this->compiler->getProxyClass($className);
     if ($proxyClass === false) {
         return $treatedSubClasses;
     }
     $callBuildMethodsAndAdvicesArrayCode = "        if (method_exists(get_parent_class(), 'Flow_Aop_Proxy_buildMethodsAndAdvicesArray') && is_callable('parent::Flow_Aop_Proxy_buildMethodsAndAdvicesArray')) parent::Flow_Aop_Proxy_buildMethodsAndAdvicesArray();\n";
     $proxyClass->getConstructor()->addPreParentCallCode($callBuildMethodsAndAdvicesArrayCode);
     $proxyClass->getMethod('__wakeup')->addPreParentCallCode($callBuildMethodsAndAdvicesArrayCode);
     return $treatedSubClasses;
 }
 /**
  * Returns a new index object which contains all class names of this index
  * starting with the given prefix
  *
  * @param string $prefixFilter A prefix string to filter the class names of this index
  * @return \Neos\Flow\Aop\Builder\ClassNameIndex A new index object
  */
 public function filterByPrefix($prefixFilter)
 {
     $pointcuts = array_keys($this->classNames);
     $result = new ClassNameIndex();
     $right = count($pointcuts) - 1;
     $left = 0;
     $found = false;
     $currentPosition = -1;
     while ($found === false) {
         if ($left > $right) {
             break;
         }
         $currentPosition = $left + floor(($right - $left) / 2);
         if (strpos($pointcuts[$currentPosition], $prefixFilter) === 0) {
             $found = true;
             break;
         } else {
             $comparisonResult = strcmp($prefixFilter, $pointcuts[$currentPosition]);
             if ($comparisonResult > 0) {
                 $left = $currentPosition + 1;
             } else {
                 $right = $currentPosition - 1;
             }
         }
     }
     if ($found === true) {
         $startIndex = $currentPosition;
         while ($startIndex >= 0 && strpos($pointcuts[$startIndex], $prefixFilter) === 0) {
             $startIndex--;
         }
         $startIndex++;
         $endIndex = $currentPosition;
         while ($endIndex < count($pointcuts) && strpos($pointcuts[$endIndex], $prefixFilter) === 0) {
             $endIndex++;
         }
         $result->setClassNames(array_slice($pointcuts, $startIndex, $endIndex - $startIndex));
     }
     return $result;
 }
 /**
  * This method is used to optimize the matching process.
  *
  * @param ClassNameIndex $classNameIndex
  * @return ClassNameIndex
  */
 public function reduceTargetClassNames(ClassNameIndex $classNameIndex)
 {
     if ($this->filters === null) {
         $this->buildPointcutFilters();
     }
     $result = new ClassNameIndex();
     foreach ($this->filters as $filter) {
         $result->applyUnion($filter->reduceTargetClassNames($classNameIndex));
     }
     return $result;
 }