/** * {@inheritdoc} */ public function check(\Twig_TokenStream $tokens) { $this->reset(); $macros = []; while (!$tokens->isEOF()) { $token = $tokens->getCurrent(); if ($token->getType() === \Twig_Token::NAME_TYPE && $token->getValue() === 'import') { while ($tokens->getCurrent()->getValue() !== 'as') { $tokens->next(); } $tokens->next(); while (in_array($tokens->getCurrent()->getType(), [\Twig_Token::NAME_TYPE, \Twig_Token::PUNCTUATION_TYPE, Token::WHITESPACE_TYPE])) { $next = $tokens->getCurrent(); if ($next->getType() === \Twig_Token::NAME_TYPE) { $macros[$next->getValue()] = $next; } $tokens->next(); } } elseif ($token->getType() === \Twig_Token::NAME_TYPE && array_key_exists($token->getValue(), $macros)) { unset($macros[$token->getValue()]); } $tokens->next(); } foreach ($macros as $name => $originalToken) { $this->addViolation($tokens->getFilename(), $originalToken->getLine(), $originalToken->getColumn(), sprintf('Unused macro "%s".', $name)); } return $this->violations; }
/** * {@inheritdoc} */ public function check(\Twig_TokenStream $tokens) { $this->violations = []; $ternaryDepth = 0; $closingTokens = []; while (!$tokens->isEOF()) { $token = $tokens->getCurrent(); if ($token->getValue() === '?' && $token->getType() === \Twig_Token::PUNCTUATION_TYPE) { // Memorize where is the closing ":" punctuation to validate spacing later. $closingTokens[] = $this->seekTernaryElse($tokens); $next = $tokens->look(Lexer::NEXT_TOKEN); if ($next->getValue() !== ':') { $this->assertSpacing($tokens, Lexer::NEXT_TOKEN, $this->spacing); } $this->assertSpacing($tokens, Lexer::PREVIOUS_TOKEN, $this->spacing); } if (in_array($token, $closingTokens)) { $previous = $tokens->look(Lexer::PREVIOUS_TOKEN); if ($previous->getValue() !== '?') { $this->assertSpacing($tokens, Lexer::PREVIOUS_TOKEN, $this->spacing); } $this->assertSpacing($tokens, Lexer::NEXT_TOKEN, $this->spacing); } $tokens->next(); } return $this->violations; }
/** * @param \Twig_TokenStream $tokens * @param integer $position * @param message $target * @param boolean $acceptNewLines */ protected function assertSpacing(\Twig_TokenStream $tokens, $position, $spacing, $acceptNewLines = true) { $current = $tokens->getCurrent(); $token = $tokens->look($position); $orientation = round($position / abs($position)); $positionName = $orientation > 0 ? 'after' : 'before'; if ($this->whitelist && !$this->whitelist->pass($tokens, $orientation)) { return; } if ($acceptNewLines && $token->getType() == Token::NEWLINE_TYPE) { return; } // special case of no spaces allowed. if ($spacing === 0) { if ($token->getType() === Token::WHITESPACE_TYPE) { $this->addViolation($tokens->getFilename(), $current->getLine(), $current->getColumn(), sprintf('There should be no space %s "%s".', $positionName, $current->getValue())); } if ($token->getType() === Token::NEWLINE_TYPE) { $this->addViolation($tokens->getFilename(), $current->getLine(), $current->getColumn(), sprintf('There should be no new line %s "%s".', $positionName, $current->getValue())); } return; } if ($token->getType() !== Token::WHITESPACE_TYPE || strlen($token->getValue()) < $spacing) { $this->addViolation($tokens->getFilename(), $current->getLine(), $current->getColumn(), sprintf('There should be %d space(s) %s "%s".', $spacing, $positionName, $current->getValue())); } if ($token->getType() === Token::WHITESPACE_TYPE && strlen($token->getValue()) > $spacing) { $this->addViolation($tokens->getFilename(), $current->getLine(), $current->getColumn(), sprintf('More than %d space(s) found %s "%s".', $spacing, $positionName, $current->getValue())); } }
/** * {@inheritdoc} */ public function check(\Twig_TokenStream $tokens) { $this->violations = []; $arrayDepth = 0; $skip = false; while (!$tokens->isEOF()) { $token = $tokens->getCurrent(); if ($token->getType() === \Twig_Token::PUNCTUATION_TYPE && $token->getValue() === '(') { $skip = true; // Ignore function arguments or embedded expressions (eg. [ func(1, 2) ] ) // This prevents this rule from having influence on arguments spacing. } if ($token->getType() === \Twig_Token::PUNCTUATION_TYPE && $token->getValue() === '?') { $skip = true; } if ($token->getValue() === '[' && $token->getType() === \Twig_Token::PUNCTUATION_TYPE) { if ($tokens->look(-1)->getType() === \Twig_Token::NAME_TYPE) { break; // This is not an array declaration, but an array access ( eg. : foo[1] ) } $arrayDepth++; $skip = false; // We entered a new array or hash, from now on do not skip anything. } if ($token->getValue() === ']' && $token->getType() === \Twig_Token::PUNCTUATION_TYPE) { $arrayDepth--; } if (!$skip && $arrayDepth > 0 && $token->getType() === \Twig_Token::PUNCTUATION_TYPE && $token->getValue() === ',') { $this->assertSpacing($tokens, Lexer::NEXT_TOKEN, $this->spaceAfter); $this->assertSpacing($tokens, Lexer::PREVIOUS_TOKEN, $this->spaceBefore, false); } $tokens->next(); } return $this->violations; }
/** * {@inheritdoc} */ public function check(\Twig_TokenStream $tokens) { $this->violations = []; while (!$tokens->isEOF()) { $token = $tokens->getCurrent(); if ($token->getType() === \Twig_Token::PUNCTUATION_TYPE && in_array($token->getValue(), $this->punctuations)) { $this->assertSpacing($tokens, Lexer::PREVIOUS_TOKEN, $this->spacing); $this->assertSpacing($tokens, Lexer::NEXT_TOKEN, $this->spacing); } $tokens->next(); } return $this->violations; }
/** * {@inheritdoc} */ public function check(\Twig_TokenStream $tokens) { $this->violations = []; $watchList = array_keys(self::CHECKS); while (!$tokens->isEOF()) { $token = $tokens->getCurrent(); if (in_array($token->getType(), $watchList)) { $checks = self::CHECKS[$token->getType()]; $this->assertSpacing($tokens, $checks[0], $checks[1]); } $tokens->next(); } return $this->violations; }
/** * {@inheritdoc} */ public function check(\Twig_TokenStream $tokens) { $this->reset(); while (!$tokens->isEOF()) { $token = $tokens->getCurrent(); if ($token->getType() === \Twig_Token::NAME_TYPE && preg_match('/[A-Z]/', $token->getValue())) { if ($tokens->look(Lexer::PREVIOUS_TOKEN)->getType() === Token::WHITESPACE_TYPE && $tokens->look(-2)->getValue() === 'set') { $this->addViolation($tokens->getFilename(), $token->getLine(), $token->getColumn(), sprintf('The "%s" variable should be in lower case (use _ as a separator).', $token->getValue())); } } $tokens->next(); } return $this->violations; }
/** * {@inheritdoc} */ public function check(\Twig_TokenStream $tokens) { $this->reset(); while (!$tokens->isEOF()) { $token = $tokens->getCurrent(); if ($token->getType() === Token::NEWLINE_TYPE && $tokens->look(-1)->getType() === Token::WHITESPACE_TYPE || $token->getType() === Token::TEXT_TYPE) { if (preg_match("/[[:blank:]]+\n/", $token->getValue())) { $this->addViolation($tokens->getFilename(), $token->getLine(), $token->getColumn(), 'A line should not end with blank space(s).'); } } $tokens->next(); } return $this->violations; }
/** * {@inheritdoc} */ public function check(\Twig_TokenStream $tokens) { $this->violations = []; while (!$tokens->isEOF()) { $token = $tokens->getCurrent(); if ($token->getType() === \Twig_Token::OPERATOR_TYPE && in_array($token->getValue(), $this->operators)) { // allows unary operators to be next to an opening parenthesis. if (!($this->isUnary($token->getValue()) && $tokens->look(-1)->getValue() == '(')) { $this->assertSpacing($tokens, Lexer::PREVIOUS_TOKEN, $this->spacing); } $this->assertSpacing($tokens, Lexer::NEXT_TOKEN, $this->spacing); } $tokens->next(); } return $this->violations; }
/** * @param \Twig_TokenStream $stream * @param int $lineno * @param string $export_type * @return WebpackNode * @throws \Twig_Error_Syntax */ private function parseType(\Twig_TokenStream $stream, $lineno, $export_type) { $files = []; while (!$stream->isEOF() && !$stream->getCurrent()->test(\Twig_Token::BLOCK_END_TYPE)) { $asset = $stream->expect(\Twig_Token::STRING_TYPE)->getValue(); if (false === ($file = $this->extension->webpackAsset($asset)[$export_type])) { continue; } $files[] = $file; } $stream->expect(\Twig_Token::BLOCK_END_TYPE); $body = $this->parser->subparse(function ($token) { return $token->test(['end' . $this->getTag()]); }, true); $stream->expect(\Twig_Token::BLOCK_END_TYPE); return new WebpackNode([$body], ['files' => $files], $lineno, $this->getTag()); }
/** * Método que revisa cada l�nea de la plantilla * @param \Twig_TokenStream $stream * @return \Twig_TokenStream */ protected function checkTemplateLine(\Twig_TokenStream $stream) { $value = $stream->getCurrent(); switch ($value->getType()) { case \Twig_Token::STRING_TYPE: $this->values[] = $this->parser->getExpressionParser()->parseExpression(); break; case \Twig_Token::BLOCK_END_TYPE: $this->end = true; $stream->next(); break; default: $stream->next(); break; } return $stream; }
/** * {@inheritdoc} */ public function check(\Twig_TokenStream $tokens) { $this->violations = []; $sliceOpened = false; while (!$tokens->isEOF()) { $token = $tokens->getCurrent(); if ($token->getValue() === '[' && $tokens->look(-1)->getType() === \Twig_Token::NAME_TYPE) { $sliceOpened = true; } if ($sliceOpened > 0 && $token->getValue() === ':') { $this->assertSpacing($tokens, Lexer::NEXT_TOKEN, $this->spaces); $this->assertSpacing($tokens, Lexer::PREVIOUS_TOKEN, $this->spaces, false); } if ($token->getValue() === ']') { $sliceOpened = false; } $tokens->next(); } return $this->violations; }
/** * {@inheritdoc} */ public function check(\Twig_TokenStream $tokens) { $this->reset(); $variables = []; while (!$tokens->isEOF()) { $token = $tokens->getCurrent(); if ($token->getType() === \Twig_Token::NAME_TYPE) { if ($tokens->look(Lexer::PREVIOUS_TOKEN)->getType() === Token::WHITESPACE_TYPE && $tokens->look(-2)->getValue() === 'set') { $variables[$token->getValue()] = $token; } else { unset($variables[$token->getValue()]); } } $tokens->next(); } foreach ($variables as $name => $originalToken) { $this->addViolation($tokens->getFilename(), $originalToken->getLine(), $originalToken->getColumn(), sprintf('Unused variable "%s".', $name)); } return $this->violations; }
/** * {@inheritdoc} */ public function check(\Twig_TokenStream $tokens) { $this->violations = []; while (!$tokens->isEOF()) { $token = $tokens->getCurrent(); if ($token->getValue() === '(' && $token->getType() === \Twig_Token::PUNCTUATION_TYPE) { $this->assertSpacing($tokens, Lexer::NEXT_TOKEN, $this->spacing); // Space allowed if previous token is not a function name. // Space also allowed in case of control structure if ($tokens->look(-2)->getType() === \Twig_Token::NAME_TYPE) { $value = $tokens->look(-2)->getValue(); $spacing = in_array($value, ['if', 'elseif', 'in']) ? $this->controlStructureSpacing : $this->spacing; $this->assertSpacing($tokens, Lexer::PREVIOUS_TOKEN, $spacing); } } if ($token->getValue() === ')' && $token->getType() === \Twig_Token::PUNCTUATION_TYPE && $tokens->look(Lexer::PREVIOUS_TOKEN)->getType() === Token::WHITESPACE_TYPE) { $this->assertSpacing($tokens, Lexer::PREVIOUS_TOKEN, $this->spacing); } $tokens->next(); } return $this->violations; }
/** * @param \Twig_TokenStream $stream * * @throws \Twig_Error_Syntax */ private function throwSyntaxError(\Twig_TokenStream $stream) { $token = $stream->getCurrent(); throw new \Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s"', \Twig_Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $stream->getFilename()); }
/** * Helper method for the common operation of grabbing the next boolean value * from the stream * * @param \Twig_TokenStream $stream * @param string $optionName * @return string */ protected function getNextExpectedBoolValueFromStream(\Twig_TokenStream $stream, $optionName) { $stream->next(); $stream->expect(\Twig_Token::PUNCTUATION_TYPE); $expr = $this->parser->getExpressionParser()->parseExpression(); if (!$expr instanceof \Twig_Node_Expression_Constant || !is_bool($expr->getAttribute('value'))) { throw new SyntaxException(sprintf('The %s option must be boolean true or false (i.e. %s:false)', $optionName, $optionName), $stream->getCurrent()->getLine(), $stream->getFilename()); } return $expr->getAttribute('value'); }