diff --git a/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-97816-TypoScriptSyntaxChanges.rst b/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-97816-TypoScriptSyntaxChanges.rst index 8b4c1cb6d75c..942cf1177f52 100644 --- a/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-97816-TypoScriptSyntaxChanges.rst +++ b/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-97816-TypoScriptSyntaxChanges.rst @@ -261,4 +261,29 @@ used "\\r" as single linebreak character. This old linebreak type is no longer d when parsing TypoScript and may lead to funny results, but chances are very low any instance is affected by this. +Operator matching has higher precedence +--------------------------------------- + +The new parser looks for valid operators first, then parses things behind it. +Consider this example: + +.. code-block:: typoscript + + lib.nav.wrap = + +This is ambiguous: The above :typoscript:`=| + + .. index:: Backend, Frontend, TSConfig, TypoScript, NotScanned, ext:core diff --git a/typo3/sysext/core/Tests/Unit/TypoScript/Tokenizer/TokenizerInterfaceTest.php b/typo3/sysext/core/Tests/Unit/TypoScript/Tokenizer/TokenizerInterfaceTest.php index e044139170da..ffef55851e23 100644 --- a/typo3/sysext/core/Tests/Unit/TypoScript/Tokenizer/TokenizerInterfaceTest.php +++ b/typo3/sysext/core/Tests/Unit/TypoScript/Tokenizer/TokenizerInterfaceTest.php @@ -387,7 +387,7 @@ public static function tokenizeStringDataProvider(): array ) ), ], - 'identifier, assignment, value with whitespaces' => [ + 'identifier, assignment, whitespace, value' => [ 'foo = bar', (new LineStream()) ->append( @@ -422,6 +422,41 @@ public static function tokenizeStringDataProvider(): array ) ), ], + 'identifier, assignment, whitespace, value with < is considered an assignment line, not a reference' => [ + 'foo = append( + (new IdentifierAssignmentLine()) + ->setTokenStream( + (new TokenStream()) + ->append(new IdentifierToken(TokenType::T_IDENTIFIER, 'foo', 0, 0)) + ->append(new Token(TokenType::T_BLANK, ' ', 0, 3)) + ->append(new Token(TokenType::T_OPERATOR_ASSIGNMENT, '=', 0, 4)) + ->append(new Token(TokenType::T_BLANK, ' ', 0, 5)) + ->append(new Token(TokenType::T_VALUE, 'setIdentifierTokenStream( + (new IdentifierTokenStream()) + ->append(new IdentifierToken(TokenType::T_IDENTIFIER, 'foo', 0, 0)) + ) + ->setValueTokenStream( + (new TokenStream()) + ->append(new Token(TokenType::T_VALUE, 'append( + (new IdentifierAssignmentLine()) + ->setIdentifierTokenStream( + (new IdentifierTokenStream()) + ->append(new IdentifierToken(TokenType::T_IDENTIFIER, 'foo')) + ) + ->setValueTokenStream( + (new TokenStream()) + ->append(new Token(TokenType::T_VALUE, ' [ 'foo:bar = fooValue', (new LineStream()) @@ -1731,7 +1766,7 @@ public static function tokenizeStringDataProvider(): array ) ), ], - 'identifier, reference, identifiers with whitespaces' => [ + 'identifier, reference, whitespace, identifiers' => [ 'foo =< bar1.bar2', (new LineStream()) ->append( @@ -1770,7 +1805,7 @@ public static function tokenizeStringDataProvider(): array ) ), ], - 'identifier, reference, relative identifiers with whitespaces' => [ + 'identifier, reference, whitespace, relative identifiers' => [ 'foo =< .bar1.bar2', (new LineStream()) ->append(