/** * @return array of match * every match is an array with the following entries: * 0: int startIndex * the index at which the pattern starts * 1: int endIndex * the index at which the pattern ends * */ public function find(array $tokens) { $ret = []; $tai = new TokenArrayIterator($tokens); $start = null; while ($tai->valid()) { $cur = $tai->current(); if (null === $start) { if (TokenTool::match([T_CLASS, T_TRAIT], $cur)) { $start = $tai->key(); } } else { $found = false; TokenArrayIteratorTool::skipWhiteSpaces($tai); $start = $tai->key(); if (TokenArrayIteratorTool::skipNsChain($tai)) { $found = true; // skipNsChain ends AFTER the chain, not AT the end of it. $tai->prev(); $end = $tai->key(); $tai->next(); $ret[] = [$start, $end]; $this->onMatchFound($start, $tai); $start = null; } if (false === $found) { $start = null; } } $tai->next(); } return $ret; }
/** * @return array of match * every match is an array with the following entries: * 0: int startIndex * the index at which the pattern starts * 1: int endIndex * the index at which the pattern ends * */ public function find(array $tokens) { $ret = []; $tai = new TokenArrayIterator($tokens); $start = null; while ($tai->valid()) { $cur = $tai->current(); if (null === $start) { if (TokenTool::match(T_VARIABLE, $cur)) { $start = $tai->key(); } } else { $found = false; TokenArrayIteratorTool::skipWhiteSpaces($tai); if (TokenTool::match('[', $tai->current())) { if (true === TokenArrayIteratorTool::moveToCorrespondingEnd($tai)) { $found = true; $ret[] = [$start, $tai->key()]; $this->onMatchFound($start, $tai); $start = null; } } if (false === $found) { $start = null; } } $tai->next(); } return $ret; }
/** * @return array of match * every match is an array with the following entries: * 0: int startIndex * the index at which the pattern starts * 1: int endIndex * the index at which the pattern ends * */ public function find(array $tokens) { $ret = []; $tai = new TokenArrayIterator($tokens); $start = null; while ($tai->valid()) { $cur = $tai->current(); if (null === $start) { if (TokenTool::match(T_USE, $cur)) { $start = $tai->key(); } } else { $found = false; TokenArrayIteratorTool::skipWhiteSpaces($tai); if (true === TokenArrayIteratorTool::skipNsChain($tai)) { TokenArrayIteratorTool::skipWhiteSpaces($tai); if (TokenTool::match(T_AS, $tai->current())) { $tai->next(); TokenArrayIteratorTool::skipWhiteSpaces($tai); if (TokenTool::match(T_STRING, $tai->current())) { $tai->next(); TokenArrayIteratorTool::skipWhiteSpaces($tai); } else { $start = null; continue; } } if (TokenTool::match(';', $tai->current())) { $found = true; $ret[] = [$start, $tai->key()]; $this->onMatchFound($start, $tai); $start = null; } } if (false === $found) { $start = null; } } $tai->next(); } return $ret; }
/** * @return array of match * every match is an array with the following entries: * 0: int startIndex * the index at which the pattern starts * 1: int endIndex * the index at which the pattern ends * */ public function find(array $tokens) { $ret = []; $tai = new TokenArrayIterator($tokens); $start = null; while ($tai->valid()) { $cur = $tai->current(); if (null === $start) { if (TokenTool::match([T_COMMENT, T_DOC_COMMENT, T_ABSTRACT, T_METHOD_C, T_PUBLIC, T_PROTECTED, T_PRIVATE, T_STATIC], $cur)) { $key = $tai->key(); if (TokenTool::match([T_COMMENT, T_DOC_COMMENT], $cur)) { $tai->next(); TokenArrayIteratorTool::skipWhiteSpaces($tai); $cur = $tai->current(); } while (true === TokenTool::match([T_ABSTRACT, T_PUBLIC, T_PROTECTED, T_PRIVATE, T_STATIC], $cur)) { $tai->next(); TokenArrayIteratorTool::skipWhiteSpaces($tai); $cur = $tai->current(); } /** * Note: this algorithm might match also any function */ if (TokenTool::match([T_FUNCTION], $cur)) { $tai->next(); TokenArrayIteratorTool::skipWhiteSpaces($tai); if (TokenTool::match(T_STRING, $tai->current())) { $start = $key; } } } } else { $found = false; TokenArrayIteratorTool::skipWhiteSpaces($tai); if (TokenTool::match('(', $tai->current())) { if (true === TokenArrayIteratorTool::moveToCorrespondingEnd($tai)) { $tai->next(); TokenArrayIteratorTool::skipWhiteSpaces($tai); if (TokenTool::match('{', $tai->current())) { if (true === TokenArrayIteratorTool::moveToCorrespondingEnd($tai)) { $found = true; $match = [$start, $tai->key()]; $ret[] = $match; $this->onMatchFound($start, $tai); $start = null; } } } } if (false === $found) { $start = null; } } $tai->next(); } return $ret; }
/** * @return array of match * every match is an array with the following entries: * 0: int startIndex * the index at which the pattern starts * 1: int endIndex * the index at which the pattern ends * */ public function find(array $tokens) { $ret = []; $tai = new TokenArrayIterator($tokens); $start = null; while ($tai->valid()) { $cur = $tai->current(); if (null === $start) { if (TokenTool::match(T_VARIABLE, $cur)) { $start = $tai->key(); $isDynamic = false; if (true === $this->allowDynamic) { $tai->prev(); while (TokenTool::match('$', $tai->current())) { $isDynamic = true; $tai->prev(); } if (true === $isDynamic) { $tai->next(); // re-balancing the last prev move from the while loop $parseStart = $start; $start = $tai->key(); $tai->seek($parseStart); } else { $tai->next(); } } /** * By default in this implementation, we have chosen to parse * array affectation ONLY IF the variable is not dynamic, * because this (array affectation on a dynamic var) is not valid php: * * $$x["pou"] = 6; * */ if (true === $this->allowArrayAffectation && false === $isDynamic) { $tai->next(); if (false === TokenArrayIteratorTool::skipSquareBracketsChain($tai)) { $tai->prev(); } } } else { if (true === $this->skipControlStructure) { if (true === TokenTool::match('{', $tai->current())) { TokenArrayIteratorTool::moveToCorrespondingEnd($tai); } } if (true === $this->skipClass) { TokenArrayIteratorTool::skipClassLike($tai); } if (true === $this->skipFunction) { TokenArrayIteratorTool::skipFunction($tai); } if (true === $this->skipForLoopCondition) { if (true === TokenTool::match(T_FOR, $tai->current())) { $tai->next(); TokenArrayIteratorTool::skipWhiteSpaces($tai); if (true === TokenTool::match('(', $tai->current())) { TokenArrayIteratorTool::moveToCorrespondingEnd($tai); } } } } } else { $found = false; TokenArrayIteratorTool::skipWhiteSpaces($tai); if (TokenTool::match("=", $tai->current())) { while ($tai->valid()) { if (false === TokenTool::match(';', $tai->current())) { TokenArrayIteratorTool::skipWhiteSpaces($tai); if (TokenTool::match(['(', '[', '{'], $tai->current())) { TokenArrayIteratorTool::moveToCorrespondingEnd($tai); } elseif (true === TokenTool::match([')', ']', '}'], $tai->current())) { break; } } else { break; } $tai->next(); } if (true === TokenTool::match(';', $tai->current())) { $found = true; $ret[] = [$start, $tai->key()]; $this->onMatchFound($start, $tai); $start = null; } } if (false === $found) { $start = null; } } $tai->next(); } return $ret; }
/** * Strip whitespace (or other characters) from the end of a string. * * @param array $tokens * @param array $chars , an array of tokenProp (see TokenArrayIteratorTool). * @return array representing the trimmed tokens. */ public static function rtrim(array $tokens, array $chars = null) { if (null === $chars) { $chars = [T_WHITESPACE]; } if ($tokens) { $n = count($tokens) - 1; $tai = new TokenArrayIterator($tokens); $tai->seek($n); while ($tai->valid()) { if (TokenTool::match($chars, $tai->current())) { unset($tokens[$tai->key()]); } else { break; } $tai->prev(); } } return array_merge($tokens); }
/** * * @return array of <info>, each info is an array with the following properties: * - startIndex: int, the index at which the pattern starts * - comment: null|string * - commentType: null|oneLine\multiLine * - visibility: public (default)|private|protected * - abstract: bool * - name: string * - args: string * - content: string */ public static function getMethodsInfo(array $tokens) { $ret = []; $o = new MethodTokenFinder(); $matches = $o->find($tokens); if ($matches) { foreach ($matches as $match) { $length = $match[1] - $match[0]; $tokens = array_slice($tokens, $match[0], $length); $comment = null; $commentType = null; $visibility = 'public'; $abstract = false; $name = null; $args = ''; $content = ''; $argsStarted = false; $contentStarted = false; $nameFound = false; $tai = new TokenArrayIterator($tokens); while ($tai->valid()) { $token = $tai->current(); if (false === $nameFound) { if (true === TokenTool::match([T_COMMENT, T_DOC_COMMENT], $token)) { if (true === TokenTool::match(T_COMMENT, $token)) { $commentType = 'oneLine'; } else { $commentType = 'multiLine'; } $comment = $token[1]; } if (true === TokenTool::match([T_PUBLIC, T_PROTECTED, T_PRIVATE], $token)) { $visibility = $token[1]; } if (true === TokenTool::match(T_ABSTRACT, $token)) { $abstract = true; } if (true === TokenTool::match(T_FUNCTION, $token)) { $tai->next(); TokenArrayIteratorTool::skipWhiteSpaces($tai); $name = $tai->current()[1]; $nameFound = true; $tai->next(); TokenArrayIteratorTool::skipWhiteSpaces($tai); } } if (false === $argsStarted && true === TokenTool::match('(', $tai->current())) { $argsTokens = []; TokenArrayIteratorTool::moveToCorrespondingEnd($tai, null, $argsTokens); $args = TokenTool::tokensToString($argsTokens); $argsStarted = true; } if (false === $contentStarted && true === TokenTool::match('{', $tai->current())) { $contentTokens = []; TokenArrayIteratorTool::moveToCorrespondingEnd($tai, null, $contentTokens); $content = TokenTool::tokensToString($contentTokens); $contentStarted = true; } $tai->next(); } $ret[] = ['startIndex' => $match[0], 'comment' => $comment, 'commentType' => $commentType, 'visibility' => $visibility, 'abstract' => $abstract, 'name' => $name, 'args' => $args, 'content' => $content]; } } return $ret; }