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; }
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; }
/** * 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; }
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); } } } }