diff --git a/src/Token/Tokenizer.php b/src/Token/Tokenizer.php index 9136bb63..42520e6c 100644 --- a/src/Token/Tokenizer.php +++ b/src/Token/Tokenizer.php @@ -601,6 +601,18 @@ private function lexOperator(string $operator): void } } + $this->pushToken(Token::OPERATOR_TYPE, $operator); + } elseif ('?:' === $operator) { + if ( + self::STATE_BLOCK === $this->getState() + && 'types' === $this->getStateParam('blockName') + ) { + // This is an optional variable type declaration instead + $this->pushToken(Token::PUNCTUATION_TYPE, $operator); + + return; + } + $this->pushToken(Token::OPERATOR_TYPE, $operator); } else { $this->pushToken(Token::OPERATOR_TYPE, $operator); diff --git a/tests/Rules/Operator/OperatorSpacing/OperatorSpacingRuleTest.fixed.twig b/tests/Rules/Operator/OperatorSpacing/OperatorSpacingRuleTest.fixed.twig index 6b784c32..0ab9b9d2 100644 --- a/tests/Rules/Operator/OperatorSpacing/OperatorSpacingRuleTest.fixed.twig +++ b/tests/Rules/Operator/OperatorSpacing/OperatorSpacingRuleTest.fixed.twig @@ -51,3 +51,5 @@ Untouch +-/*%==: {{ a is not array }} {{ a is not array or b is foo }} + +{% types {foo: 'int', bar?: 'string'} %} diff --git a/tests/Rules/Operator/OperatorSpacing/OperatorSpacingRuleTest.twig b/tests/Rules/Operator/OperatorSpacing/OperatorSpacingRuleTest.twig index c11e9d43..5e70dd8a 100644 --- a/tests/Rules/Operator/OperatorSpacing/OperatorSpacingRuleTest.twig +++ b/tests/Rules/Operator/OperatorSpacing/OperatorSpacingRuleTest.twig @@ -51,3 +51,5 @@ Untouch +-/*%==: {{ a is not array }} {{ a is not array or b is foo }} + +{% types {foo: 'int', bar?: 'string'} %} diff --git a/tests/Rules/String/HashQuote/HashQuoteRuleTest.fixed.twig b/tests/Rules/String/HashQuote/HashQuoteRuleTest.fixed.twig index ac6a6b43..cce497dd 100644 --- a/tests/Rules/String/HashQuote/HashQuoteRuleTest.fixed.twig +++ b/tests/Rules/String/HashQuote/HashQuoteRuleTest.fixed.twig @@ -17,3 +17,4 @@ {% set needQuote = {'data-foo': a} %} {% set namedArgument = foo(bar: true, baz: false) %} +{% types {foo: 'int', bar?: 'string'} %} diff --git a/tests/Rules/String/HashQuote/HashQuoteRuleTest.twig b/tests/Rules/String/HashQuote/HashQuoteRuleTest.twig index c363d3c7..76ad223a 100644 --- a/tests/Rules/String/HashQuote/HashQuoteRuleTest.twig +++ b/tests/Rules/String/HashQuote/HashQuoteRuleTest.twig @@ -17,3 +17,4 @@ {% set needQuote = {'data-foo': a} %} {% set namedArgument = foo(bar: true, baz: false) %} +{% types {foo: 'int', bar?: 'string'} %} diff --git a/tests/Rules/String/HashQuote/HashQuoteRuleTest.with.fixed.twig b/tests/Rules/String/HashQuote/HashQuoteRuleTest.with.fixed.twig index 8acba392..feea58d0 100644 --- a/tests/Rules/String/HashQuote/HashQuoteRuleTest.with.fixed.twig +++ b/tests/Rules/String/HashQuote/HashQuoteRuleTest.with.fixed.twig @@ -17,3 +17,4 @@ {% set needQuote = {'data-foo': a} %} {% set namedArgument = foo(bar: true, baz: false) %} +{% types {foo: 'int', bar?: 'string'} %} diff --git a/tests/Token/Tokenizer/Fixtures/test16.twig b/tests/Token/Tokenizer/Fixtures/test16.twig new file mode 100644 index 00000000..3234859b --- /dev/null +++ b/tests/Token/Tokenizer/Fixtures/test16.twig @@ -0,0 +1 @@ +{% types {foo: 'int', bar?: 'string'} %} diff --git a/tests/Token/Tokenizer/TokenizerTest.php b/tests/Token/Tokenizer/TokenizerTest.php index 932a729d..db59ad84 100644 --- a/tests/Token/Tokenizer/TokenizerTest.php +++ b/tests/Token/Tokenizer/TokenizerTest.php @@ -773,6 +773,32 @@ public static function tokenizeDataProvider(): iterable 78 => Token::EOF_TYPE, ], ]; + + yield [ + __DIR__.'/Fixtures/test16.twig', + [ + 0 => Token::BLOCK_START_TYPE, + 1 => Token::WHITESPACE_TYPE, + 2 => Token::BLOCK_NAME_TYPE, + 3 => Token::WHITESPACE_TYPE, + 4 => Token::PUNCTUATION_TYPE, + 5 => Token::NAME_TYPE, + 6 => Token::PUNCTUATION_TYPE, + 7 => Token::WHITESPACE_TYPE, + 8 => Token::STRING_TYPE, + 9 => Token::PUNCTUATION_TYPE, + 10 => Token::WHITESPACE_TYPE, + 11 => Token::NAME_TYPE, + 12 => Token::PUNCTUATION_TYPE, + 13 => Token::WHITESPACE_TYPE, + 14 => Token::STRING_TYPE, + 15 => Token::PUNCTUATION_TYPE, + 16 => Token::WHITESPACE_TYPE, + 17 => Token::BLOCK_END_TYPE, + 18 => Token::EOL_TYPE, + 19 => Token::EOF_TYPE, + ], + ]; } /**