示例#1
0
 /**
 ----------------------------------------------------------------------+
 * @desc 	Split token stream into nodes of type function, comment,
 * 			class or method.
 * @param	int			Start position
 * @param	Object		Node
 * @param	int			Depth
 * @return	int
 ----------------------------------------------------------------------+
 */
 protected function measure($pos, Lint\Node $node, &$ret)
 {
     $start = $this->last_newline($pos);
     $node->start = $start;
     if ($node->type === T_FILE) {
         $node->start_line = 1;
         $node->empty = false;
     } else {
         $node->start_line = $this->tokens[$start][2] + 1;
         $node->empty = true;
     }
     $this->debug(sprintf('In Node `%s` of type `%s` line %d; Owned by `%s`', $node->name, Tokenizer::token_name($node->type), $node->start_line, $node->owner), $node->depth, OPT_SCOPE_MAP, true);
     $this->scope = array();
     $next_node = new Lint\Node();
     $last_comment = null;
     $tokens = $this->tokens;
     for ($i = $pos; $i < $this->tcount; $i++) {
         if (count($this->scope) > 0 && $node->empty && Tokenizer::meaningfull($tokens[$i][0]) && $tokens[$i][0] !== T_CURLY_CLOSE) {
             $node->empty = false;
         }
         if (!empty($this->ignore_next) && $tokens[$i][0] === $this->ignore_next[count($this->ignore_next) - 1]) {
             $node->tokens[] = $tokens[$i];
             array_pop($this->ignore_next);
             continue;
         }
         switch ($tokens[$i][0]) {
             case T_INLINE_HTML:
                 // Gather inline html into one token
                 $node->tokens[] = $tokens[$i];
                 while (++$i < $this->tcount && in_array($tokens[$i][0], array(T_INLINE_HTML, T_NEWLINE))) {
                 }
                 $i--;
                 break;
             case T_ELSE:
                 // treat `else if` like `elseif`
                 // perhaps the tokenizer should do this ?
                 if ($tokens[$this->next($i)][0] === T_IF) {
                     $this->tokens[$i][0] = T_ELSEIF;
                     $this->tokens[$i][1] = 'elseif';
                     $this->ignore_next[] = T_IF;
                 }
                 $this->open_scope($i, $node);
                 break;
             case T_IF:
             case T_ELSEIF:
             case T_THEN:
             case T_FOREACH:
             case T_WHILE:
             case T_SWITCH:
                 $this->open_scope($i, $node);
                 break;
             case T_FOR:
                 $this->open_scope($i, $node);
                 $this->ignore_next[] = T_SEMICOLON;
                 $this->ignore_next[] = T_SEMICOLON;
                 break;
             case T_BASIC_CURLY_OPEN:
                 $this->open_scope($i, $node);
                 break;
             case T_SEMICOLON:
                 $this->close_scope($i, $node);
                 $node->tokens[] = $tokens[$i];
                 if (empty($this->scope) && $node->empty) {
                     $i++;
                     break 2;
                 }
                 break;
             case T_CURLY_CLOSE:
                 $this->close_scope($i, $node);
                 if (empty($this->scope) && $node->type !== T_FILE) {
                     $i++;
                     break 2;
                 }
                 break;
             case T_CURLY_OPEN:
                 $this->ignore_next[] = T_CURLY_CLOSE;
                 break;
             case T_PUBLIC:
             case T_PRIVATE:
             case T_PROTECTED:
                 $next_node->visibility = Tokenizer::token_name($tokens[$i][0]);
                 break;
             case T_ABSTRACT:
                 $next_node->abstract = true;
                 break;
             case T_STATIC:
                 $next_node->static = true;
                 break;
             case T_COMMENT:
                 $node->tokens[] = $tokens[$i];
                 $node->comments[] = $this->measure_comment($i, $node->depth, $i);
                 break;
             case T_DOC_COMMENT:
                 $node->tokens[] = $tokens[$i];
                 if ($last_comment) {
                     $node->comments[] = $last_comment;
                 }
                 $last_comment = $this->measure_comment($i, $node->depth, $i);
                 break;
             case T_CLASS:
             case T_INTERFACE:
             case T_FUNCTION:
                 list($type, $name, $owner) = $this->determine_type($i, $node, $next_node);
                 $next_node->type = $type;
                 $next_node->name = $name;
                 $next_node->depth = $node->depth + 1;
                 $next_node->owner = $owner;
                 $next_node->file = $node->file;
                 if ($last_comment) {
                     $next_node->comments[] = $last_comment;
                 }
                 $node->tokens[] = $tokens[$i];
                 // preserve scope
                 $scope = $this->scope;
                 $node->nodes[] = $this->measure($i + 1, $next_node, $i);
                 $this->scope = $scope;
                 $next_node = new Lint\Node();
                 $last_comment = null;
                 break;
             default:
                 $node->tokens[] = $tokens[$i];
                 break;
         }
     }
     // In case $i is over the buffer
     $node->end = $i >= $this->tcount ? --$i : $i;
     $node->end_line = $tokens[$i][2];
     $node->length = $node->end_line - $node->start_line;
     $node->token_count = count($node->tokens);
     $ret = $i > 0 ? --$i : $i;
     $this->debug(sprintf('Exiting Node `%s` of type `%s` line %d', $node->name, Tokenizer::token_name($node->type), $node->end_line), $node->depth, OPT_SCOPE_MAP, true);
     return $node;
 }