예제 #1
0
 public function setTheOther(self $aToken = null)
 {
     // 先解除原有配对的token关系
     if ($this->aTheOther) {
         // nothing to do
         if ($this->aTheOther === $aToken) {
             return;
         }
         $this->aTheOther->setTheOther(null);
         $this->aTheOther = null;
     }
     // 设置一个配对的 闭合token
     if ($aToken) {
         $thisTokenType = $this->tokenType();
         if ($this->isOpen()) {
             if (!self::isPair($thisTokenType, $aToken->tokenType())) {
                 throw new ClassCompileException(null, $aToken, "遇到意外的闭合token类型,“%s”和“%s”类型不匹配。", array($thisTokenType, $aToken->tokenTypeName()));
             }
         } else {
             if (!self::isPair($aToken->tokenType(), $thisTokenType)) {
                 throw new ClassCompileException(null, $aToken, "遇到意外的闭合token类型,“%s”和“%s”类型不匹配。", array($thisTokenType, $aToken->tokenTypeName()));
             }
         }
         $this->aTheOther = $aToken;
         $aToken->aTheOther = $this;
     }
 }
예제 #2
0
 public function setArgListToken(ClosureToken $aTokenArgList)
 {
     if ($aTokenArgList->tokenType() != Token::T_BRACE_ROUND_OPEN or $aTokenArgList->sourceCode() != '(') {
         throw new ClassCompileException(null, $aTokenArgList, "参数 \$aTokenArgList 必须是一个内容为 “(” 的Token对象");
     }
     $this->aTokenArgList = $aTokenArgList;
 }
예제 #3
0
 /**
  * 设置class body 开始的大括号token
  */
 public function setBodyToken(ClosureToken $aTokenBody)
 {
     if ($aTokenBody->tokenType() != Token::T_BRACE_OPEN or $aTokenBody->sourceCode() != '{') {
         throw new ClassCompileException(null, $aTokenBody, "参数 \$aTokenBody 必须是一个内容为 “{” 的Token对象");
     }
     $this->aTokenBody = $aTokenBody;
 }
예제 #4
0
 public function analyze(TokenPool $aObjectContainer)
 {
     $arrStacks = array(Token::T_BRACE_OPEN => new Stack(), Token::T_BRACE_SQUARE_OPEN => new Stack(), Token::T_BRACE_ROUND_OPEN => new Stack(), T_OPEN_TAG => new Stack());
     $arrStacks[Token::T_BRACE_CLOSE] = $arrStacks[Token::T_BRACE_OPEN];
     $arrStacks[Token::T_BRACE_SQUARE_CLOSE] = $arrStacks[Token::T_BRACE_SQUARE_OPEN];
     $arrStacks[Token::T_BRACE_ROUND_CLOSE] = $arrStacks[Token::T_BRACE_ROUND_OPEN];
     $arrStacks[T_OPEN_TAG_WITH_ECHO] = $arrStacks[T_OPEN_TAG];
     $arrStacks[T_CLOSE_TAG] = $arrStacks[T_OPEN_TAG];
     $arrStacks[T_DOLLAR_OPEN_CURLY_BRACES] = $arrStacks[Token::T_BRACE_OPEN];
     $arrStacks[T_CURLY_OPEN] = $arrStacks[Token::T_BRACE_OPEN];
     $aTokenIter = $aObjectContainer->iterator();
     foreach ($aTokenIter as $aObject) {
         $nIdx = $aTokenIter->key();
         $tokenType = $aObject->tokenType();
         if (!in_array($tokenType, ClosureToken::openClosureTokens()) and !in_array($tokenType, ClosureToken::closeClosureTokens())) {
             continue;
         }
         $aNewToken = new ClosureToken($aObject);
         $aObjectContainer->replace($aObject, $aNewToken);
         if ($aNewToken->isOpen()) {
             $arrStacks[$tokenType]->put($aNewToken);
         } else {
             if (!($aOpenToken = $arrStacks[$tokenType]->out())) {
                 throw new ClassCompileException(null, $aNewToken, "编译class时遇到了语法错误,闭合对象的结尾没有对应的开始:%s; on position %d", array($aNewToken->sourceCode(), $aNewToken->position()));
             }
             $aNewToken->setTheOther($aOpenToken);
         }
     }
     return;
 }
예제 #5
0
 /**
  * 创建并织入一个用于集中调用各个advice的函数
  */
 protected function generateAdviceDispatchFunction(GenerateStat $aStat)
 {
     Assert::type("org\\jecat\\framework\\lang\\compile\\object\\FunctionDefine", $aStat->aExecutePoint);
     if (!$aStat->aExecutePoint->bodyToken()) {
         throw new Exception("AOP织入遇到错误:正在对一个抽象方法(%s::%s)进行织入操作。", array($aStat->aExecutePoint->belongsClass()->fullName(), $aStat->aExecutePoint->name()));
     }
     // 新建同名方法
     $aOriFuncStart = $aStat->aExecutePoint->startToken();
     $aOriFuncEnd = $aStat->aExecutePoint->endToken();
     $aStat->aAdvicesDispatchFunc = new FunctionDefine($aStat->aExecutePoint, new Token(T_STRING, $aStat->aExecutePoint->name(), 0), null, null);
     // static declare
     if ($aStat->aExecutePoint->staticToken()) {
         $aStaticClareToken = new Token(T_STATIC, 'static', 0);
         $aStat->aAdvicesDispatchFunc->setStaticToken($aStaticClareToken);
         $aStat->aTokenPool->insertBefore($aOriFuncStart, $aStaticClareToken);
         $aStat->aTokenPool->insertBefore($aOriFuncStart, new Token(T_WHITESPACE, ' ', 0));
     }
     // private, protected, public
     $aOriAccess = $aStat->aExecutePoint->accessToken();
     $aNewAccess = $aOriAccess ? new Token($aOriAccess->tokenType(), $aOriAccess->sourceCode(), 0) : new Token(T_PUBLIC, 'public', 0);
     $aStat->aAdvicesDispatchFunc->setAccessToken($aNewAccess);
     $aStat->aTokenPool->insertBefore($aOriFuncStart, $aNewAccess);
     $aStat->aTokenPool->insertBefore($aOriFuncStart, new Token(T_WHITESPACE, ' ', 0));
     // function keyword
     $aStat->aTokenPool->insertBefore($aOriFuncStart, $aStat->aAdvicesDispatchFunc);
     $aStat->aTokenPool->insertBefore($aOriFuncStart, new Token(T_WHITESPACE, ' ', 0));
     // function name
     $aStat->aTokenPool->insertBefore($aOriFuncStart, $aStat->aAdvicesDispatchFunc->nameToken());
     // 参数表
     $aArgvLstStart = new ClosureToken($aStat->aExecutePoint->argListToken());
     $aArgvLstEnd = new ClosureToken($aStat->aExecutePoint->argListToken()->theOther());
     $aArgvLstStart->setTheOther($aArgvLstEnd);
     $aStat->aAdvicesDispatchFunc->setArgListToken($aArgvLstStart);
     $aStat->aTokenPool->insertBefore($aOriFuncStart, $aArgvLstStart);
     foreach ($this->cloneFunctionArgvLst($aStat->aTokenPool, $aStat->aExecutePoint) as $aToken) {
         $aStat->aTokenPool->insertBefore($aOriFuncStart, $aToken);
     }
     $aStat->aTokenPool->insertBefore($aOriFuncStart, $aArgvLstEnd);
     // 换行
     $aStat->aTokenPool->insertBefore($aOriFuncStart, new Token(T_WHITESPACE, "\r\n\t"));
     // 函数体
     $aBodyStart = new ClosureToken($aStat->aExecutePoint->bodyToken());
     $aBodyEnd = new ClosureToken($aOriFuncEnd);
     $aBodyStart->setTheOther($aBodyEnd);
     $aStat->aAdvicesDispatchFunc->setBodyToken($aBodyStart);
     $aStat->aTokenPool->insertBefore($aOriFuncStart, $aBodyStart);
     $aStat->aTokenPool->insertBefore($aOriFuncStart, $aBodyEnd);
     // init call state 对像
     $sLines = "\r\n";
     $sLines .= "\t\t\$__apo_aCallState = new \\org\\jecat\\framework\\lang\\aop\\AdviceCallState() ;\r\n";
     if (!$aStat->aExecutePoint->staticToken()) {
         $sLines .= "\t\t\$__apo_aCallState->aOriginObject = \$this ;\r\n";
     }
     $sLines .= "\t\t\$__apo_aCallState->sOriginClass = '" . addslashes($aStat->aAdvicesDispatchFunc->belongsClass()->fullName()) . "';\r\n";
     $sLines .= "\t\t\$__apo_aCallState->sOriginMethod = '" . $aStat->aAdvicesDispatchFunc->name() . "' ;\r\n";
     foreach ($this->parseArgvs($aStat->aTokenPool, $aStat->aAdvicesDispatchFunc) as $sArgvName => $sArgv) {
         $sLines .= "\t\t\$__apo_aCallState->arrAvgvs['{$sArgvName}'] =& \${$sArgvName} ;\r\n";
     }
     $aStat->aTokenPool->insertAfter($aBodyStart, new Token(T_WHITESPACE, $sLines));
     // 换行
     $aStat->aTokenPool->insertBefore($aOriFuncStart, new Token(T_WHITESPACE, "\r\n\r\n\t"));
 }
예제 #6
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;
 }