/**
  * Renders the PHP code for this Proxy Method
  *
  * @return string PHP code
  */
 public function render()
 {
     $methodDocumentation = $this->buildMethodDocumentation($this->fullOriginalClassName, $this->methodName);
     $methodParametersCode = $this->methodParametersCode !== '' ? $this->methodParametersCode : $this->buildMethodParametersCode($this->fullOriginalClassName, $this->methodName);
     $callParentMethodCode = $this->buildCallParentMethodCode($this->fullOriginalClassName, $this->methodName);
     $staticKeyword = $this->reflectionService->isMethodStatic($this->fullOriginalClassName, $this->methodName) ? 'static' : '';
     $visibility = $this->visibility === NULL ? $this->getMethodVisibilityString() : $this->visibility;
     $code = '';
     if ($this->addedPreParentCallCode !== '' || $this->addedPostParentCallCode !== '' || $this->methodBody !== '') {
         $code = "\n" . $methodDocumentation . '	' . $staticKeyword . ' ' . $visibility . ' function ' . $this->methodName . '(' . $methodParametersCode . ") {\n";
         if ($this->methodBody !== '') {
             $code .= "\n" . $this->methodBody . "\n";
         } else {
             $code .= $this->addedPreParentCallCode;
             if ($this->addedPostParentCallCode !== '') {
                 $code .= '		$result = ' . ($callParentMethodCode === '' ? "NULL;\n" : $callParentMethodCode);
                 $code .= $this->addedPostParentCallCode;
                 $code .= "\t\treturn \$result;\n";
             } else {
                 $code .= $callParentMethodCode === '' ? '' : '		return ' . $callParentMethodCode . ";\n";
             }
         }
         $code .= "\t}\n";
     }
     return $code;
 }
 /**
  * Traverses all aspect containers, their aspects and their advisors and adds the
  * methods and their advices to the (usually empty) array of intercepted methods.
  *
  * @param array &$interceptedMethods An array (empty or not) which contains the names of the intercepted methods and additional information
  * @param array $methods An array of class and method names which are matched against the pointcut (class name = name of the class or interface the method was declared)
  * @param string $targetClassName Name of the class the pointcut should match with
  * @param array &$aspectContainers All aspects to take into consideration
  * @return void
  */
 protected function addAdvicedMethodsToInterceptedMethods(array &$interceptedMethods, array $methods, $targetClassName, array &$aspectContainers)
 {
     $pointcutQueryIdentifier = 0;
     foreach ($aspectContainers as $aspectContainer) {
         if (!$aspectContainer->getCachedTargetClassNameCandidates()->hasClassName($targetClassName)) {
             continue;
         }
         foreach ($aspectContainer->getAdvisors() as $advisor) {
             $pointcut = $advisor->getPointcut();
             foreach ($methods as $method) {
                 list($methodDeclaringClassName, $methodName) = $method;
                 if ($this->reflectionService->isMethodFinal($targetClassName, $methodName)) {
                     continue;
                 }
                 if ($this->reflectionService->isMethodStatic($targetClassName, $methodName)) {
                     continue;
                 }
                 if ($pointcut->matches($targetClassName, $methodName, $methodDeclaringClassName, $pointcutQueryIdentifier)) {
                     $advice = $advisor->getAdvice();
                     $interceptedMethods[$methodName]['groupedAdvices'][get_class($advice)][] = array('advice' => $advice, 'runtimeEvaluationsClosureCode' => $pointcut->getRuntimeEvaluationsClosureCode());
                     $interceptedMethods[$methodName]['declaringClassName'] = $methodDeclaringClassName;
                 }
                 $pointcutQueryIdentifier++;
             }
         }
     }
 }
 /**
  * @return array
  */
 protected function getDeclarations()
 {
     $declarations = array();
     $methodNames = get_class_methods(get_class($this));
     foreach ($methodNames as $methodName) {
         if (substr($methodName, -11, 11) === 'Declaration' && $this->reflectionService->isMethodStatic(get_class($this), $methodName)) {
             $declarations[] = substr($methodName, 0, -11);
         }
     }
     return $declarations;
 }
 /**
  * Compile the result of methods marked with CompileStatic into the proxy class
  *
  * @param string $className
  * @param \TYPO3\Flow\Object\Proxy\ProxyClass $proxyClass
  * @return void
  */
 protected function compileStaticMethods($className, $proxyClass)
 {
     if ($this->classesWithCompileStaticAnnotation === null) {
         $this->classesWithCompileStaticAnnotation = array_flip($this->reflectionService->getClassesContainingMethodsAnnotatedWith(\TYPO3\Flow\Annotations\CompileStatic::class));
     }
     if (!isset($this->classesWithCompileStaticAnnotation[$className])) {
         return;
     }
     $methodNames = get_class_methods($className);
     foreach ($methodNames as $methodName) {
         if ($this->reflectionService->isMethodStatic($className, $methodName) && $this->reflectionService->isMethodAnnotatedWith($className, $methodName, \TYPO3\Flow\Annotations\CompileStatic::class)) {
             $compiledMethod = $proxyClass->getMethod($methodName);
             $value = call_user_func(array($className, $methodName), $this->objectManager);
             $compiledResult = var_export($value, true);
             $compiledMethod->setMethodBody('return ' . $compiledResult . ';');
         }
     }
 }
 /**
  * Compile the result of methods marked with CompileStatic into the proxy class
  *
  * @param string $className
  * @param ProxyClass $proxyClass
  * @return void
  * @throws ObjectException
  */
 protected function compileStaticMethods($className, ProxyClass $proxyClass)
 {
     $methodNames = $this->reflectionService->getMethodsAnnotatedWith($className, Flow\CompileStatic::class);
     foreach ($methodNames as $methodName) {
         if (!$this->reflectionService->isMethodStatic($className, $methodName)) {
             throw new ObjectException(sprintf('The method %s:%s() is annotated CompileStatic so it must be static', $className, $methodName), 1476348303);
         }
         if ($this->reflectionService->isMethodPrivate($className, $methodName)) {
             throw new ObjectException(sprintf('The method %s:%s() is annotated CompileStatic so it must not be private', $className, $methodName), 1476348306);
         }
         $reflectedMethod = new MethodReflection($className, $methodName);
         $reflectedMethod->setAccessible(true);
         $value = $reflectedMethod->invoke(null, $this->objectManager);
         $compiledResult = var_export($value, true);
         $compiledMethod = $proxyClass->getMethod($methodName);
         $compiledMethod->setMethodBody('return ' . $compiledResult . ';');
     }
 }