/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { for ($index = 0, $limit = $tokens->count(); $index < $limit; ++$index) { $token = $tokens[$index]; if (!$token->isGivenKind(T_DOC_COMMENT)) { continue; } if (1 === preg_match('/inheritdoc/i', $token->getContent())) { continue; } $index = $tokens->getNextMeaningfulToken($index); if (null === $index) { return; } while ($tokens[$index]->isGivenKind(array(T_ABSTRACT, T_FINAL, T_PRIVATE, T_PROTECTED, T_PUBLIC, T_STATIC, T_VAR))) { $index = $tokens->getNextMeaningfulToken($index); } if (!$tokens[$index]->isGivenKind(T_FUNCTION)) { continue; } $openIndex = $tokens->getNextTokenOfKind($index, array('(')); $index = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $openIndex); $arguments = array(); foreach ($this->getArguments($tokens, $openIndex, $index) as $start => $end) { $argumentInfo = $this->prepareArgumentInformation($tokens, $start, $end); if (!$this->configuration['only_untyped'] || '' === $argumentInfo['type']) { $arguments[$argumentInfo['name']] = $argumentInfo; } } if (!count($arguments)) { continue; } $doc = new DocBlock($token->getContent()); $lastParamLine = null; foreach ($doc->getAnnotationsOfType('param') as $annotation) { $pregMatched = preg_match('/^[^$]+(\\$\\w+).*$/s', $annotation->getContent(), $matches); if (1 === $pregMatched) { unset($arguments[$matches[1]]); } $lastParamLine = max($lastParamLine, $annotation->getEnd()); } if (!count($arguments)) { continue; } $lines = $doc->getLines(); $linesCount = count($lines); preg_match('/^(\\s*).*$/', $lines[$linesCount - 1]->getContent(), $matches); $indent = $matches[1]; $newLines = array(); foreach ($arguments as $argument) { $type = $argument['type'] ?: 'mixed'; if ('?' !== $type[0] && 'null' === strtolower($argument['default'])) { $type = 'null|' . $type; } $newLines[] = new Line(sprintf('%s* @param %s %s%s', $indent, $type, $argument['name'], $this->whitespacesConfig->getLineEnding())); } array_splice($lines, $lastParamLine ? $lastParamLine + 1 : $linesCount - 1, 0, $newLines); $token->setContent(implode('', $lines)); } }
/** * Looks up Tokens sequence for suitable candidates and delivers boundaries information, * which can be supplied by other methods in this abstract class. * * @param string $functionNameToSearch * @param Tokens $tokens * @param int $start * @param int|null $end * * @return int[]|null returns $functionName, $openParenthesis, $closeParenthesis packed into array */ protected function find($functionNameToSearch, Tokens $tokens, $start = 0, $end = null) { // make interface consistent with findSequence $end = null === $end ? $tokens->count() : $end; // find raw sequence which we can analyse for context $candidateSequence = array(array(T_STRING, $functionNameToSearch), '('); $matches = $tokens->findSequence($candidateSequence, $start, $end, false); if (null === $matches) { // not found, simply return without further attempts return; } // translate results for humans list($functionName, $openParenthesis) = array_keys($matches); // first criteria check: shall look like function call $functionNamePrefix = $tokens->getPrevMeaningfulToken($functionName); $functionNamePrecedingToken = $tokens[$functionNamePrefix]; if ($functionNamePrecedingToken->isGivenKind(array(T_DOUBLE_COLON, T_NEW, T_OBJECT_OPERATOR, T_FUNCTION))) { // this expression is differs from expected, resume return $this->find($functionNameToSearch, $tokens, $openParenthesis, $end); } // second criteria check: ensure namespace is the root one if ($functionNamePrecedingToken->isGivenKind(T_NS_SEPARATOR)) { $namespaceCandidate = $tokens->getPrevMeaningfulToken($functionNamePrefix); $namespaceCandidateToken = $tokens[$namespaceCandidate]; if ($namespaceCandidateToken->isGivenKind(array(T_NEW, T_STRING, CT::T_NAMESPACE_OPERATOR))) { // here can be added complete namespace scan // this expression is differs from expected, resume return $this->find($functionNameToSearch, $tokens, $openParenthesis, $end); } } // final step: find closing parenthesis $closeParenthesis = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $openParenthesis); return array($functionName, $openParenthesis, $closeParenthesis); }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { static $nativeFunctionNames = null; if (null === $nativeFunctionNames) { $nativeFunctionNames = $this->getNativeFunctionNames(); } for ($index = 0, $count = $tokens->count(); $index < $count; ++$index) { // test if we are at a function all if (!$tokens[$index]->isGivenKind(T_STRING)) { continue; } $next = $tokens->getNextMeaningfulToken($index); if (!$tokens[$next]->equals('(')) { $index = $next; continue; } $functionNamePrefix = $tokens->getPrevMeaningfulToken($index); if ($tokens[$functionNamePrefix]->isGivenKind(array(T_DOUBLE_COLON, T_NEW, T_OBJECT_OPERATOR, T_FUNCTION))) { continue; } // do not though the function call if it is to a function in a namespace other than the default if ($tokens[$functionNamePrefix]->isGivenKind(T_NS_SEPARATOR) && $tokens[$tokens->getPrevMeaningfulToken($functionNamePrefix)]->isGivenKind(T_STRING)) { continue; } // test if the function call is to a native PHP function $lower = strtolower($tokens[$index]->getContent()); if (!array_key_exists($lower, $nativeFunctionNames)) { continue; } $tokens[$index]->setContent($nativeFunctionNames[$lower]); $index = $next; } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { for ($index = $tokens->count() - 1; $index >= 0; --$index) { if (!$tokens[$index]->isGivenKind(T_UNSET)) { continue; } $previousUnsetCall = $this->getPreviousUnsetCall($tokens, $index); if (is_int($previousUnsetCall)) { $index = $previousUnsetCall; continue; } list($previousUnset, $previousUnsetBraceStart, $previousUnsetBraceEnd, $previousUnsetSemicolon) = $previousUnsetCall; // Merge the tokens inside the 'unset' call into the previous one 'unset' call. $tokensAddCount = $this->moveTokens($tokens, $nextUnsetContentStart = $tokens->getNextTokenOfKind($index, array('(')), $nextUnsetContentEnd = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $nextUnsetContentStart), $previousUnsetBraceEnd - 1); if (!$tokens[$previousUnsetBraceEnd]->isWhitespace()) { $tokens->insertAt($previousUnsetBraceEnd, new Token(array(T_WHITESPACE, ' '))); ++$tokensAddCount; } $tokens->insertAt($previousUnsetBraceEnd, new Token(',')); ++$tokensAddCount; // Remove 'unset', '(', ')' and (possibly) ';' from the merged 'unset' call. $this->clearOffsetTokens($tokens, $tokensAddCount, array($index, $nextUnsetContentStart, $nextUnsetContentEnd)); $nextUnsetSemicolon = $tokens->getNextMeaningfulToken($nextUnsetContentEnd); if (null !== $nextUnsetSemicolon && $tokens[$nextUnsetSemicolon]->equals(';')) { $tokens->clearTokenAndMergeSurroundingWhitespace($nextUnsetSemicolon); } $index = $previousUnset + 1; } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { for ($index = $tokens->count() - 3; $index > 0; --$index) { $token = $tokens[$index]; if (!$token->isGivenKind(T_NEW)) { continue; } $nextIndex = $tokens->getNextTokenOfKind($index, array(':', ';', ',', '(', ')', '[', ']', array(T_CLOSE_TAG), array(CT_ARRAY_SQUARE_BRACE_OPEN), array(CT_ARRAY_SQUARE_BRACE_CLOSE), array(CT_BRACE_CLASS_INSTANTIATION_OPEN), array(CT_BRACE_CLASS_INSTANTIATION_CLOSE))); $nextToken = $tokens[$nextIndex]; // entrance into array index syntax - need to look for exit while ($nextToken->equals('[')) { $nextIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_INDEX_SQUARE_BRACE, $nextIndex) + 1; $nextToken = $tokens[$nextIndex]; } // new statement has a gap in it - advance to the next token if ($nextToken->isWhitespace()) { $nextIndex = $tokens->getNextNonWhitespace($nextIndex); $nextToken = $tokens[$nextIndex]; } // new statement with () - nothing to do if ($nextToken->equals('(')) { continue; } $meaningBeforeNextIndex = $tokens->getPrevMeaningfulToken($nextIndex); $tokens->insertAt($meaningBeforeNextIndex + 1, array(new Token('('), new Token(')'))); } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { $lineEnding = $this->whitespacesConfig->getLineEnding(); for ($index = 0, $limit = $tokens->count(); $index < $limit; ++$index) { $token = $tokens[$index]; if (!$token->isGivenKind(T_RETURN)) { continue; } $prevNonWhitespaceToken = $tokens[$tokens->getPrevNonWhitespace($index)]; if (!$prevNonWhitespaceToken->equalsAny(array(';', '}'))) { continue; } $prevToken = $tokens[$index - 1]; if ($prevToken->isWhitespace()) { $parts = explode("\n", $prevToken->getContent()); $countParts = count($parts); if (1 === $countParts) { $prevToken->setContent(rtrim($prevToken->getContent(), " \t") . $lineEnding . $lineEnding); } elseif (count($parts) <= 2) { $prevToken->setContent($lineEnding . $prevToken->getContent()); } } else { $tokens->insertAt($index, new Token(array(T_WHITESPACE, $lineEnding . $lineEnding))); ++$index; ++$limit; } } }
/** * Inject into the text placeholders of candidates of vertical alignment. * * @param Tokens $tokens */ private function injectAlignmentPlaceholders(Tokens $tokens) { $deepestLevel = 0; $limit = $tokens->count(); for ($index = 0; $index < $limit; ++$index) { $token = $tokens[$index]; if ($token->equals('=')) { $token->setContent(sprintf(self::ALIGNABLE_PLACEHOLDER, $deepestLevel) . $token->getContent()); continue; } if ($token->isGivenKind(T_FUNCTION)) { ++$deepestLevel; continue; } if ($token->equals('(')) { $index = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $index); continue; } if ($token->equals('[')) { $index = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_INDEX_SQUARE_BRACE, $index); continue; } if ($token->isGivenKind(CT_ARRAY_SQUARE_BRACE_OPEN)) { $index = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_ARRAY_SQUARE_BRACE, $index); continue; } } $this->deepestLevel = $deepestLevel; }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { $count = $tokens->count(); if ($count && !$tokens[$count - 1]->isGivenKind(array(T_INLINE_HTML, T_CLOSE_TAG, T_OPEN_TAG))) { $tokens->ensureWhitespaceAtIndex($count - 1, 1, $this->whitespacesConfig->getLineEnding()); } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { for ($index = $tokens->count() - 1; $index >= 0; --$index) { $token = $tokens[$index]; if (!$token->isGivenKind(T_FUNCTION)) { continue; } $startParenthesisIndex = $tokens->getNextTokenOfKind($index, array('(')); $endParenthesisIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $startParenthesisIndex); for ($iter = $endParenthesisIndex - 1; $iter > $startParenthesisIndex; --$iter) { if (!$tokens[$iter]->isGivenKind(T_VARIABLE)) { continue; } // skip ... before $variable for variadic parameter if (defined('T_ELLIPSIS')) { $prevNonWhitespaceIndex = $tokens->getPrevNonWhitespace($iter); if ($tokens[$prevNonWhitespaceIndex]->isGivenKind(T_ELLIPSIS)) { $iter = $prevNonWhitespaceIndex; } } // skip & before $variable for parameter passed by reference $prevNonWhitespaceIndex = $tokens->getPrevNonWhitespace($iter); if ($tokens[$prevNonWhitespaceIndex]->equals('&')) { $iter = $prevNonWhitespaceIndex; } if (!$tokens[$iter - 1]->equalsAny(array(array(T_WHITESPACE), array(T_COMMENT), array(T_DOC_COMMENT), '(', ','))) { $tokens->insertAt($iter, new Token(array(T_WHITESPACE, ' '))); } } } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { for ($index = $tokens->count() - 1; $index >= 0; --$index) { if ($tokens[$index]->isGivenKind(array(T_ARRAY, CT::T_ARRAY_SQUARE_BRACE_OPEN))) { $this->fixSpacing($index, $tokens); } } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { for ($index = 0, $c = $tokens->count(); $index < $c; ++$index) { if ($tokens[$index]->isGivenKind(array(T_ARRAY, CT::T_ARRAY_SQUARE_BRACE_OPEN))) { self::fixArray($tokens, $index); } } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { for ($index = $tokens->count() - 1; $index >= 0; --$index) { $token = $tokens[$index]; if ($token->isGivenKind(T_NAMESPACE)) { $this->fixLinesBeforeNamespace($tokens, $index, 2); } } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { $tokensAnalyzer = new TokensAnalyzer($tokens); for ($index = $tokens->count() - 1; $index >= 0; --$index) { if ($tokensAnalyzer->isArray($index)) { $this->fixArray($tokens, $index); } } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { $callBack = $this->fixCallback; for ($index = $tokens->count() - 1; $index >= 0; --$index) { if ($tokens[$index]->equals('.')) { $this->{$callBack}($tokens, $index); } } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { $callback = $this->fixCallback; for ($index = $tokens->count() - 1; 0 <= $index; --$index) { if ($tokens[$index]->isGivenKind($this->candidateTokenKind)) { $this->{$callback}($tokens, $index); } } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { for ($index = 0, $count = $tokens->count(); $index < $count; ++$index) { if (!$tokens[$index]->isCast()) { continue; } $tokens[$index]->setContent(strtolower($tokens[$index]->getContent())); } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { for ($index = $tokens->count() - 1; $index >= 0; --$index) { $token = $tokens[$index]; if ($token->equals('(') && !$tokens[$index - 1]->isGivenKind(T_ARRAY)) { $this->fixFunction($tokens, $index); } } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { for ($index = 0, $limit = $tokens->count(); $index < $limit; ++$index) { $token = $tokens[$index]; if (!$token->isGivenKind(T_NAMESPACE)) { continue; } $this->fixLinesBeforeNamespace($tokens, $index, 1); } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { for ($index = $tokens->count() - 1; $index >= 0; --$index) { if (!$tokens[$index]->equals('.')) { continue; } $this->fixWhiteSpaceAroundConcatToken($tokens, $index, 1); $this->fixWhiteSpaceAroundConcatToken($tokens, $index, -1); } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { for ($i = 0, $l = $tokens->count(); $i < $l; ++$i) { if (!$tokens[$i]->isGivenKind(T_FUNCTION)) { continue; } $startIndex = $tokens->getNextTokenOfKind($i, array('(')); $i = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $startIndex); $this->fixFunctionDefinition($tokens, $startIndex, $i); } }
/** * Replaces ::class keyword, namespace by namespace. * * It uses recursive method to get rid of token index changes. * * @param Tokens $tokens * @param int $namespaceNumber */ private function replaceClassKeywords(Tokens $tokens, $namespaceNumber = -1) { $namespaceIndexes = array_keys($tokens->findGivenKind(T_NAMESPACE)); // Namespace blocks if (!empty($namespaceIndexes) && isset($namespaceIndexes[$namespaceNumber])) { $startIndex = $namespaceIndexes[$namespaceNumber]; $namespaceBlockStartIndex = $tokens->getNextTokenOfKind($startIndex, array(';', '{')); $endIndex = $tokens[$namespaceBlockStartIndex]->equals('{') ? $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $namespaceBlockStartIndex) : $tokens->getNextTokenOfKind($namespaceBlockStartIndex, array(T_NAMESPACE)); $endIndex = $endIndex ?: $tokens->count() - 1; } elseif (-1 === $namespaceNumber) { // Out of any namespace block $startIndex = 0; $endIndex = !empty($namespaceIndexes) ? $namespaceIndexes[0] : $tokens->count() - 1; } else { return; } $this->storeImports($tokens, $startIndex, $endIndex); $tokens->rewind(); $this->replaceClassKeywordsSection($tokens, $startIndex, $endIndex); $this->replaceClassKeywords($tokens, $namespaceNumber + 1); }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { for ($index = $tokens->count() - 1; $index >= 0; --$index) { $token = $tokens[$index]; if ($token->equals('!')) { if (!$tokens[$index + 1]->isWhitespace()) { $tokens->insertAt($index + 1, new Token(array(T_WHITESPACE, ' '))); } else { $tokens[$index + 1]->setContent(' '); } } } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { for ($index = $tokens->count() - 1; 0 <= $index; --$index) { $token = $tokens[$index]; if (!$token->isGivenKind(CT::T_ARRAY_SQUARE_BRACE_OPEN)) { continue; } $closeIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_ARRAY_SQUARE_BRACE, $index); $tokens->overrideAt($index, '('); $tokens->overrideAt($closeIndex, ')'); $tokens->insertAt($index, new Token(array(T_ARRAY, 'array'))); } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { $count = $tokens->count(); for ($index = 0; $index < $count; ++$index) { if (!$tokens[$index]->isGivenKind(T_DECLARE)) { continue; } while (!$tokens[++$index]->equals('=')) { } $tokens->removeLeadingWhitespace($index); $tokens->removeTrailingWhitespace($index); } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokensOrg) { $content = $tokensOrg->generateCode(); // replace all <? with <?php to replace all short open tags even without short_open_tag option enabled $newContent = preg_replace('/<\\?(\\s|$)/', '<?php$1', $content, -1, $count); if (!$count) { return; } /* the following code is magic to revert previous replacements which should NOT be replaced, for example incorrectly replacing * > echo '<? '; * with * > echo '<?php '; */ $tokens = Tokens::fromCode($newContent); $tokensOldContent = ''; $tokensOldContentLength = 0; foreach ($tokens as $token) { if ($token->isGivenKind(T_OPEN_TAG)) { $tokenContent = $token->getContent(); if ('<?php' !== substr($content, $tokensOldContentLength, 5)) { $tokenContent = '<? '; } $tokensOldContent .= $tokenContent; $tokensOldContentLength += strlen($tokenContent); continue; } if ($token->isGivenKind(array(T_COMMENT, T_DOC_COMMENT, T_CONSTANT_ENCAPSED_STRING, T_ENCAPSED_AND_WHITESPACE, T_STRING))) { $tokenContent = ''; $tokenContentLength = 0; $parts = explode('<?php', $token->getContent()); $iLast = count($parts) - 1; foreach ($parts as $i => $part) { $tokenContent .= $part; $tokenContentLength += strlen($part); if ($i !== $iLast) { if ('<?php' === substr($content, $tokensOldContentLength + $tokenContentLength, 5)) { $tokenContent .= '<?php'; $tokenContentLength += 5; } else { $tokenContent .= '<?'; $tokenContentLength += 2; } } } $token->setContent($tokenContent); } $tokensOldContent .= $token->getContent(); $tokensOldContentLength += strlen($token->getContent()); } $tokensOrg->overrideRange(0, $tokensOrg->count() - 1, $tokens); }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { $tokensAnalyzer = new TokensAnalyzer($tokens); for ($index = $tokens->count() - 1; $index >= 0; --$index) { if ($tokensAnalyzer->isUnarySuccessorOperator($index)) { $tokens->removeLeadingWhitespace($index); continue; } if ($tokensAnalyzer->isUnaryPredecessorOperator($index)) { $tokens->removeTrailingWhitespace($index); continue; } } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { static $map = null; if (null === $map) { $trueToken = new Token(array(T_STRING, 'true')); $map = array('array_keys' => array(null, null, $trueToken), 'array_search' => array(null, null, $trueToken), 'base64_decode' => array(null, $trueToken), 'in_array' => array(null, null, $trueToken), 'mb_detect_encoding' => array(null, array(new Token(array(T_STRING, 'mb_detect_order')), new Token('('), new Token(')')), $trueToken)); } for ($index = $tokens->count() - 1; 0 <= $index; --$index) { $token = $tokens[$index]; if ($token->isGivenKind(T_STRING) && isset($map[$token->getContent()])) { $this->fixFunction($tokens, $index, $map[$token->getContent()]); } } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { for ($index = 0, $limit = $tokens->count(); $index < $limit; ++$index) { $token = $tokens[$index]; if (!$token->isGivenKind(CT::T_TYPE_COLON)) { continue; } if ($tokens[$index - 1]->isWhitespace()) { $tokens[$index - 1]->clear(); } ++$index; $tokens->ensureWhitespaceAtIndex($index, 0, ' '); } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { foreach ($this->configuration as $methodBefore => $methodAfter) { for ($index = 0, $limit = $tokens->count(); $index < $limit; ++$index) { $sequence = $tokens->findSequence(array(array(T_VARIABLE, '$this'), array(T_OBJECT_OPERATOR, '->'), array(T_STRING, $methodBefore), '('), $index); if (null === $sequence) { break; } $sequenceIndexes = array_keys($sequence); $tokens[$sequenceIndexes[2]]->setContent($methodAfter); $index = $sequenceIndexes[3]; } } }
/** * {@inheritdoc} */ public function fix(\SplFileInfo $file, Tokens $tokens) { $tokensAnalyzer = new TokensAnalyzer($tokens); for ($index = $tokens->count() - 1; $index >= 0; --$index) { $token = $tokens[$index]; if ($tokensAnalyzer->isUnaryPredecessorOperator($index) && $token->equals('!')) { if (!$tokens[$index + 1]->isWhitespace()) { $tokens->insertAt($index + 1, new Token(array(T_WHITESPACE, ' '))); } if (!$tokens[$index - 1]->isWhitespace()) { $tokens->insertAt($index, new Token(array(T_WHITESPACE, ' '))); } } } }