示例#1
0
 public function getSupertypes(TypeInfoManagerInterface $manager, $recursive = false)
 {
     if ($recursive) {
         if ($this->supertypesDeep === NULL) {
             $this->supertypesDeep = [];
             foreach ($this->type->getSupertypes() as $typeName) {
                 try {
                     $supertype = $manager->getTypeInfo($typeName);
                 } catch (TypeNotFoundException $e) {
                     continue;
                 }
                 $this->supertypesDeep[strtolower($typeName)] = $supertype;
                 foreach ($supertype->getSupertypes($manager, true) as $sup) {
                     $this->supertypesDeep[strtolower($sup->getName())] = $sup;
                 }
             }
         }
         return $this->supertypesDeep;
     }
     if ($this->supertypes === NULL) {
         $this->supertypes = [];
         foreach ($this->type->getSupertypes() as $typeName) {
             try {
                 $supertype = $manager->getTypeInfo($typeName);
             } catch (TypeNotFoundException $e) {
                 continue;
             }
             $this->supertypes[strtolower($typeName)] = $supertype;
         }
     }
     return $this->supertypes;
 }
示例#2
0
 public function getSupertypes(TypeInfoManagerInterface $manager, $recursive = false)
 {
     if ($recursive) {
         if ($this->supertypesDeep === NULL) {
             $this->supertypesDeep = [];
             $supers = $this->ref->getInterfaceNames();
             if ($sc = $this->ref->getParentClass()) {
                 $supers[] = $sc->name;
             }
             foreach ($supers as $typeName) {
                 try {
                     $supertype = $manager->getTypeInfo($typeName);
                 } catch (TypeNotFoundException $e) {
                     // @codeCoverageIgnoreStart
                     continue;
                     // @codeCoverageIgnoreEnd
                 }
                 $this->supertypesDeep[strtolower($typeName)] = $supertype;
                 foreach ($supertype->getSupertypes($manager, true) as $sup) {
                     $this->supertypesDeep[strtolower($sup->getName())] = $sup;
                 }
             }
         }
         return $this->supertypesDeep;
     }
     if ($this->supertypes === NULL) {
         $this->supertypes = [];
         $exclude = [];
         $supers = $this->ref->getInterfaces();
         if ($sc = $this->ref->getParentClass()) {
             $supers[] = $sc;
         }
         $found = [];
         foreach ($supers as $ref) {
             foreach ($ref->getInterfaceNames() as $name) {
                 $exclude[$name] = true;
                 continue;
             }
             $found[$ref->name] = $ref;
         }
         foreach ($found as $name => $ref) {
             if (empty($exclude[$name])) {
                 $this->supertypes[strtolower($name)] = new ReflectionTypeInfo($ref);
             }
         }
     }
     return $this->supertypes;
 }
示例#3
0
 /**
  * Generates a closure that contains PHP code calling an advice.
  * 
  * @param TypeInfoManagerInterface $manager
  * @param MethodInfoInterface $method
  * @return string
  */
 public function generateMethodInterceptionCode(TypeInfoManagerInterface $manager, MethodInfoInterface $method)
 {
     $acount = 0;
     $typeInfo = $method->getDeclaringType();
     $init = 'function($jp, $rval = NULL) { ';
     $code = ' return $jp->getContainer()->get(' . var_export($this->typeName, true);
     $code .= ')->' . $this->methodName . '(';
     $advice = $manager->getTypeInfo($this->typeName)->getMethod($this->methodName);
     foreach ($advice->getParameters() as $i => $param) {
         if ($i != 0) {
             $code .= ', ';
         }
         if ($param->getName() === $this->subject) {
             $code .= '$jp->getSubject()';
             continue;
         }
         if ($param->getName() === $this->returns) {
             $code .= '$rval';
             continue;
         }
         if ($this->args !== NULL && false !== ($index = array_search($param->getName(), $this->args, true))) {
             $code .= '$jp->getArgument(' . var_export($index, true) . ', NULL)';
             continue;
         }
         $ptypeName = $param->getRequiredType();
         if ($ptypeName === NULL) {
             throw new \RuntimeException(sprintf('Cannot populate parameter "%s" of advice %s without a type-hint', $param->getName(), $this->getInfoSignature($advice)));
         }
         $ptype = $manager->getTypeInfo($ptypeName);
         foreach ($ptype->getSupertypes($manager, true) as $supertype) {
             if ($supertype->getName() === JoinPointInterface::class) {
                 $code .= '$jp';
                 continue 2;
             }
         }
         if (preg_match("'\\W@Annotation\\W'i", $ptype->getDocComment())) {
             $anno = NULL;
             if ($typeInfo->hasAnnotation($ptype->getName())) {
                 $anno = $typeInfo->getAnnotation($ptype->getName());
             }
             if ($method->hasAnnotation($ptype->getName())) {
                 $anno = $method->getAnnotation($ptype->getName());
             }
             if ($anno === NULL) {
                 $code .= 'NULL';
             } else {
                 $init .= 'static $a' . $acount . '; ';
                 $init .= 'if($a' . $acount . ' === NULL) { $a' . $acount;
                 $init .= ' = ' . ParsedAnnotation::compileAnnotation($anno) . '; } ';
                 $code .= '$a' . $acount;
                 $acount++;
             }
             continue;
         }
         throw new \RuntimeException(sprintf('Cannot populate argument "%s" of advice %s using type-hint %s', $param->getName(), $this->getInfoSignature($advice), $ptype->getName()));
     }
     $code .= '); }';
     return $init . $code;
 }
示例#4
0
 protected function loadAdvisors($aspectType, TypeInfoManagerInterface $manager)
 {
     $type = $manager->getTypeInfo($aspectType);
     $lexer = new Pointcut\PointcutLexer();
     $parser = new Pointcut\PointcutParser();
     foreach ($this->collectMethods($type, $manager) as $method) {
         if (!$method->isPublic()) {
             continue;
         }
         if ($method->isStatic()) {
             continue;
         }
         if ($method->isAbstract()) {
             continue;
         }
         $annotations = $method->getAnnotations();
         $exposeThis = NULL;
         $exposeArgs = NULL;
         $exposeReturns = NULL;
         // 			foreach($annotations as $anno)
         // 			{
         // 				if($anno instanceof Expose)
         // 				{
         // 					$pointcut = $parser->parse($lexer->tokenize($anno->value), $this->createPointcutContext($type, $method));
         // 					$exposeThis = $this->findThis($pointcut);
         // 					$args = $this->findArgs($pointcut);
         // 					$exposeArgs = ($args instanceof ArgsPointcut) ? $args->getMapping() : NULL;
         // 					$exposeReturns = $this->findReturns($pointcut);
         // 					break;
         // 				}
         // 			}
         foreach ($annotations as $anno) {
             if ($anno instanceof Before) {
                 $context = $this->createPointcutContext($type, $method);
                 $pointcut = $parser->parse($lexer->tokenize($anno->value), $context);
                 $interceptor = new ContainerInterceptor($type->getName(), $method->getName(), $context, $exposeThis, $exposeArgs, $exposeReturns);
                 $advice = new BeforeAdvice($interceptor, $anno->order);
                 $this->advisors[] = new Advisor(Advisor::TARGET_ELEMENT, $advice, $pointcut);
             }
             if ($anno instanceof Around) {
                 $context = $this->createPointcutContext($type, $method);
                 $pointcut = $parser->parse($lexer->tokenize($anno->value), $context);
                 $interceptor = new ContainerInterceptor($type->getName(), $method->getName(), $context, $exposeThis, $exposeArgs, $exposeReturns);
                 $advice = new AroundAdvice($interceptor, $anno->order);
                 $this->advisors[] = new Advisor(Advisor::TARGET_ELEMENT, $advice, $pointcut);
             }
             if ($anno instanceof After) {
                 $context = $this->createPointcutContext($type, $method);
                 $pointcut = $parser->parse($lexer->tokenize($anno->value), $context);
                 $interceptor = new ContainerInterceptor($type->getName(), $method->getName(), $context, $exposeThis, $exposeArgs, $exposeReturns);
                 $advice = new AfterAdvice($interceptor, $anno->order);
                 $this->advisors[] = new Advisor(Advisor::TARGET_ELEMENT, $advice, $pointcut);
             }
         }
     }
 }