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