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