예제 #1
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;
 }