codeconsole opened a new pull request, #3216: URL: https://github.com/apache/groovy/pull/3216
Declaring a variable named after a primitive type keyword is rejected, but the diagnostic depends on which declaration keyword was used and neither variant says what is wrong. `var long = 1` and `val long = 1` report ResolveVisitor's "you tried to assign a value to the class 'long'": `var` and `val` are soft keywords, so once the declaration fails to parse the parser accepts the statement as the command expression `var(long = 1)`, AstBuilder builds an assignment to the built-in type name, and the resolve phase complains about assigning to a class. `def long = 1` and `final long = 1` report "Unexpected input: 'def long ='" with the caret on the `=`: `def` and `final` are reserved, the parser commits to a declaration, consumes `long` as the declared type and fails one token past the mistake. The same two shapes cover the other primitive names and `void`, typed declarations such as `String long = "x"` or a field `int long = 1`, and a bare `long = 1`. All of these now report `'long' is a keyword and cannot be used as a variable name` with the caret on the keyword. `AstBuilder.visitAssignmentExprAlt` rejects an assignment whose left-hand side is a built-in type name (the `IS_BUILT_IN_TYPE` variable expression that `builtInType` produces) before the resolve phase sees it. That covers `var`/`val`, typed declarations in scripts and blocks, declarator lists such as `var a = 1, long = 2`, and bare or compound assignments to the keyword. The input was always an error, so no valid program changes; `var long` without an initializer still parses as a call to a method named `var`. `AbstractFriendlyErrorStrategy` gets `keywordAsVariableName`, an error-path-only lookup that runs after `MissingDelimiterDiagnostic` and before the sentence-only refinements, and that, like the delimiter diagnostic, moves the caret: back onto the keyword when ANTLR consumed it as the declared type and failed on the `=`, `,`, `;`, `)` or `}` after it (the keyword must follow a variable modifier, or the parser must have been inside `identifier`, which is the shape of the failure inside a block and in `def (a, long) = ...`), or on the keyword itself when it is the offender after a primitive type or an array dimension (`int long = 1` in a class body) or after a `,` where only a name was accepted (`def a, long = 2`). A keyword followed by `(` is a method name and keeps the generic sentence, an enum constant list keeps the `';' expected after the last enum constant` sentence (its expected set also accepts a type), and `def long` at end of input stays "Unexpected end of input". The looku p reads the token after the offender through `TokenStream.LT`, because prediction stops at the offender and the buffer may end there; the scan is bounded and wrapped in the same defensive try as the other refinements. No grammar change, so successful parses are unaffected (GROOVY-9588). Tests: `ParserNegativeSyntaxTest` pins the exact message and caret for the four reported forms and checks the sibling forms (other primitives, `void`, bare and compound assignment, declarator lists, block, field, multi-assignment pairs) plus the cases that must keep their own diagnostic (`int long()`, enum constant list, `import long`, `def long` at EOF); `ErrorStrategyTest` unit-tests the lookup over real token streams, including the stream-failure and start-of-stream guards. `ParserNegativeSyntaxTest` was run red before the fix (5 failures) and green after; `ErrorStrategyTest`, `ParserNegativeSyntaxTest` and the rest of `org.apache.groovy.parser.antlr4` pass with the fix; `checkstyleMain` reports nothing new for the changed sources. Suggested backport: GROOVY_6_0_X (the behaviour is the same on 6.0.0, 6.0.1-SNAPSHOT and master). -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
