public function addFunction(FunctionDefine $aFunction) { if ($aClass = $aFunction->belongsClass()) { $sClassName = $aClass->fullName(); } else { $sClassName = ''; } if (!($sFuncName = $aFunction->name())) { $sFuncName = ''; } $this->arrMethods[$sClassName][$sFuncName] = $aFunction; }
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; }
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; }
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); } }