Beispiel #1
0
 public function addFunction(FunctionDefine $aFunction)
 {
     if ($aClass = $aFunction->belongsClass()) {
         $sClassName = $aClass->fullName();
     } else {
         $sClassName = '';
     }
     if (!($sFuncName = $aFunction->name())) {
         $sFuncName = '';
     }
     $this->arrMethods[$sClassName][$sFuncName] = $aFunction;
 }
Beispiel #2
0
 public static function createFromToken(FunctionDefine $aFunctionDefine, Aspect $aAspect)
 {
     if (!($aClassDefine = $aFunctionDefine->belongsClass())) {
         throw new Exception("传入的 \$aFunctionDefine 参数无效,必须是一个类方法的定义Token");
     }
     if (!($aDocToken = $aFunctionDefine->docToken())) {
         throw new Exception("传入了无效Advice %s::%s() :没有DocComment申明。", array($aClassDefine->fullName(), $aFunctionDefine->name()));
     }
     $aDocComment = $aDocToken->docComment();
     $sPosition = null;
     if ($aDocComment->hasItem('advice')) {
         $sPosition = $aDocComment->item('advice');
         $sPosition = trim($sPosition);
         $sPosition = strtolower($sPosition);
     }
     if (!$sPosition) {
         $sPosition = self::after;
     }
     $aAdvice = new self($aFunctionDefine->name(), $aFunctionDefine->bodySource(), $sPosition, $aFunctionDefine);
     $aAdvice->aDefineAspect = $aAspect;
     // for pointcut
     foreach ($aDocComment->itemIterator('for') as $sPointcutName) {
         if (!($aPointcut = $aAspect->pointcuts()->getByName($sPointcutName))) {
             throw new Exception("定义Aspect %s 的 Advice %s 时,申明了一个不存在的 Pointcut: %s 。", array($sAspectName, $aAdvice->name(), $sPointcutName));
         }
         $aAdvice->arrForPointcuts[] = $sPointcutName;
     }
     return $aAdvice;
 }
 private function parseArgvs(TokenPool $aTokenPool, FunctionDefine $aOriFunctionDefine)
 {
     $aArgLstStart = $aOriFunctionDefine->argListToken();
     $aArgLstEnd = $aArgLstStart->theOther();
     $aIter = $aTokenPool->iterator();
     $nPos = $aIter->search($aArgLstStart);
     if ($nPos === false) {
         return array();
     }
     $aIter->seek($nPos);
     $aIter->next();
     $arrArgvs = array();
     while ($aToken = $aIter->current() and $aToken !== $aArgLstEnd) {
         // 跳过成对的token
         if ($aToken instanceof ClosureToken) {
             if (!($aTheOtherToken = $aToken->theOther())) {
                 throw new Exception("ClosureToken Token没有正确配对。");
             }
             if (($nPos = $aIter->search($aTheOtherToken)) === false) {
                 throw new Exception("ClosureToken Token配对的token无效。");
             }
             $aIter->seek($nPos);
         }
         if ($aToken->tokenType() === T_VARIABLE) {
             $sArgv = $aToken->targetCode();
             $sArgvName = substr($sArgv, 0, 1) == '$' ? @substr($sArgv, 1) : $sArgv;
             $arrArgvs[$sArgvName] = $sArgv;
         }
         $aIter->next();
     }
     return $arrArgvs;
 }
Beispiel #4
0
 protected function createMethod($sFuncName, $argLstToken = null, $sAccess, $bStatic = false, TokenPool $aTokenPool, Token $aTargetToken, $sWhere = 'insertAfter')
 {
     $aFuncToken = new FunctionDefine(new Token(T_FUNCTION, 'function'));
     // 函数体
     $aBodyStart = new ClosureToken(new Token(T_STRING, '{'));
     $aBodyEnd = new ClosureToken(new Token(T_STRING, '}'));
     $aBodyStart->setTheOther($aBodyEnd);
     $aTokenPool->{$sWhere}($aTargetToken, $aBodyStart);
     $aTokenPool->insertAfter($aBodyStart, $aBodyEnd);
     $aTokenPool->insertAfter($aBodyEnd, new Token(T_WHITESPACE, "\r\n"));
     $aTokenPool->insertBefore($aBodyStart, new Token(T_WHITESPACE, "\r\n\t"));
     // static
     if ($bStatic) {
         $aStaticToken = new Token(T_PRIVATE, 'static');
         $aTokenPool->insertBefore($aBodyStart, $aStaticToken);
         $aTokenPool->insertBefore($aBodyStart, new Token(T_WHITESPACE, "\r\n\t"));
         $aFuncToken->setStaticToken($aStaticToken);
     }
     // access
     $arrAccessTokenTypes = array('private' => T_PRIVATE, 'protected' => T_PROTECTED, 'public' => T_PUBLIC);
     $aAccessToken = new Token($arrAccessTokenTypes[$sAccess], $sAccess);
     $aTokenPool->insertBefore($aBodyStart, $aAccessToken);
     $aTokenPool->insertBefore($aBodyStart, new Token(T_WHITESPACE, ' '));
     $aFuncToken->setAccessToken($aAccessToken);
     // function
     $aTokenPool->insertBefore($aBodyStart, $aFuncToken);
     $aTokenPool->insertBefore($aBodyStart, new Token(T_WHITESPACE, ' '));
     $aFuncToken->setBodyToken($aBodyStart);
     // function name
     $aFuncNameToken = new Token(T_STRING, $sFuncName);
     $aTokenPool->insertBefore($aBodyStart, $aFuncNameToken);
     $aFuncToken->setNameToken($aFuncNameToken);
     // 参数表
     $aArgvLstStart = new ClosureToken(new Token(T_STRING, '('));
     $aArgvLstEnd = new ClosureToken(new Token(T_STRING, ')'));
     $aArgvLstStart->setTheOther($aArgvLstEnd);
     $aTokenPool->insertBefore($aBodyStart, $aArgvLstStart);
     if ($argLstToken) {
         $aTokenPool->insertBefore($aBodyStart, new Token(T_STRING, $argLstToken));
     }
     $aTokenPool->insertBefore($aBodyStart, $aArgvLstEnd);
     $aTokenPool->insertBefore($aBodyStart, new Token(T_WHITESPACE, "\r\n\t"));
     $aFuncToken->setArgListToken($aArgvLstStart);
     return $aFuncToken;
 }
Beispiel #5
0
 public static function createFromToken(FunctionDefine $aFunctionDefine)
 {
     if (!($aClassDefine = $aFunctionDefine->belongsClass())) {
         throw new Exception("传入的 \$aFunctionDefine 参数无效,必须是一个类方法的定义Token");
     }
     try {
         $aMethodRef = new \ReflectionMethod($aClassDefine->fullName(), $aFunctionDefine->name());
     } catch (\Exception $e) {
         throw new Exception("无法找到 Pointcut %s::%s 的定义", array($aClassDefine->fullName(), $aFunctionDefine->name()), $e);
     }
     // 检查参数(不能有非可缺省的参数)
     if ($aMethodRef->getNumberOfRequiredParameters()) {
         throw new Exception("Pointcut %s::%s() 的定义无效:要求了非可缺省的参数; 请检查该Pointcut的参数表。", array($aClassDefine->fullName(), $aFunctionDefine->name()));
     }
     // 声明为静态方法
     if ($aMethodRef->isStatic()) {
         if (!$aMethodRef->isPublic()) {
             throw new Exception("Pointcut %s::%s() 声明为 static 类型,static 类型的 Pointcut 必须为 public。", array($aClassDefine->fullName(), $aFunctionDefine->name()));
         }
         $arrJointPoints = call_user_func(array($aClassDefine->fullName(), $aFunctionDefine->name()));
     } else {
         try {
             $aClassRef = new \ReflectionClass($aClassDefine->fullName());
         } catch (\Exception $e) {
             throw new Exception("无法找到 Aspect %s 的定义,无法定义Pointcut:%s::%s", array($aClassDefine->fullName(), $aClassDefine->fullName(), $aFunctionDefine->name()), $e);
         }
         // 检查该类的构造函数的参数
         if ($aConstructor = $aClassRef->getConstructor() and $aConstructor->getNumberOfRequiredParameters()) {
             throw new Exception("由于 Pointcut %s::%s() 没有被申明为 static ,则所属的Aspect(%s)的构造函数不能要求非可省的参数。将 Pointcut %s::%s() 声明为 static,或者取消Aspect(%s)的构造函数所要求的非可省参数。", array($aClassDefine->fullName(), $aFunctionDefine->name(), $aClassDefine->fullName(), $aClassDefine->fullName(), $aFunctionDefine->name(), $aClassDefine->fullName()));
         }
         $aMethodRef->setAccessible(true);
         $arrJointPoints = $aMethodRef->invokeArgs($aClassRef->newInstanceArgs(), array());
     }
     $aPointcut = new self($aFunctionDefine->name());
     $aPointcut->sDefineMethod = $aFunctionDefine->name();
     if (is_array($arrJointPoints)) {
         foreach ($arrJointPoints as $aJointPoint) {
             if ($aJointPoint instanceof JointPoint) {
                 $aPointcut->jointPoints()->add($aJointPoint);
                 $aJointPoint->setPointcut($aPointcut);
             } else {
                 throw new Exception("Pointcut %s::%s 的定义中,申明了无效的 JointPoint: %s", array($aClassDefine->fullName(), $aFunctionDefine->name(), var_export($aJointPoint, true)));
             }
         }
     }
     return $aPointcut;
 }
 public function parse(TokenPool $aTokenPool, INonlinearIterator $aTokenPoolIter, State $aState)
 {
     if (!($aOriToken = $aTokenPoolIter->current())) {
         return;
     }
     // 已经处于 function 状态中
     if ($aFunction = $aState->currentFunction()) {
         // 遇到
         if ($aFunction->bodyToken() and $aFunction->bodyToken()->theOther() === $aOriToken) {
             $aState->setCurrentFunction(null);
         }
         return;
     } else {
         if ($aOriToken->tokenType() != T_FUNCTION) {
             return;
         }
         $aTokenPoolIter = clone $aTokenPoolIter;
         $aNewToken = new FunctionDefine($aOriToken);
         // function 修饰符 ------
         for ($aTokenPoolIter->prev(); $aToken = $aTokenPoolIter->current(); $aTokenPoolIter->prev()) {
             switch ($aToken->tokenType()) {
                 case T_PUBLIC:
                     $aNewToken->setAccessToken($aToken);
                     break;
                 case T_PROTECTED:
                     $aNewToken->setAccessToken($aToken);
                     break;
                 case T_PRIVATE:
                     $aNewToken->setAccessToken($aToken);
                     break;
                 case T_STATIC:
                     $aNewToken->setStaticToken($aToken);
                     break;
                 case T_ABSTRACT:
                     $aNewToken->setAbstractToken($aToken);
                     break;
                 case T_DOC_COMMENT:
                     $aDocToken = new DocCommentDeclare($aToken);
                     $aNewToken->setDocToken($aDocToken);
                     $aTokenPool->replace($aToken, $aDocToken);
                     break 2;
                 case T_WHITESPACE:
                     break;
                 default:
                     break 2;
             }
         }
         // function name ------
         for ($aTokenPoolIter->next(); $aToken = $aTokenPoolIter->current(); $aTokenPoolIter->next()) {
             switch ($aToken->tokenType()) {
                 // 函数名称
                 case T_STRING:
                     $aNewToken->setNameToken($aToken);
                     break 2;
                     // 匿名函数
                 // 匿名函数
                 case Token::T_BRACE_ROUND_OPEN:
                     $aTokenPoolIter->prev();
                     break 2;
                 case Token::T_BIT_AND:
                     $aNewToken->setReturnByRef(true);
                     break;
             }
         }
         // function argv list ------
         do {
             $aTokenPoolIter->next();
         } while ($aToken = $aTokenPoolIter->current() and $aToken->tokenType() != Token::T_BRACE_ROUND_OPEN);
         $aNewToken->setArgListToken($aToken);
         // 移动到参数表结束符号后
         $nPosition = $aTokenPoolIter->search($aToken->theOther());
         $aTokenPoolIter->seek($nPosition);
         // function body ------
         do {
             $aTokenPoolIter->next();
         } while ($aToken = $aTokenPoolIter->current() and !in_array($aToken->tokenType(), array(Token::T_BRACE_OPEN, Token::T_SEMICOLON)));
         if ($aToken) {
             if ($aToken->tokenType() == Token::T_BRACE_OPEN) {
                 $aNewToken->setBodyToken($aToken);
                 $aState->setCurrentFunction($aNewToken);
             } else {
                 if ($aToken->tokenType() == Token::T_SEMICOLON) {
                     $aNewToken->setEndToken($aToken);
                 }
             }
         }
         $aTokenPool->replace($aOriToken, $aNewToken);
         $aNewToken->setBelongsNamespace($aState->currentNamespace());
         $aNewToken->setBelongsClass($aState->currentClass());
         $aTokenPool->addFunction($aNewToken);
     }
 }