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]

Reply via email to