[ 
https://issues.apache.org/jira/browse/GROOVY-12353?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18111756#comment-18111756
 ] 

ASF GitHub Bot commented on GROOVY-12353:
-----------------------------------------

testlens-app[bot] commented on PR #2877:
URL: https://github.com/apache/groovy/pull/2877#issuecomment-5547426949

   ## ✅ All tests passed ✅
   
   🏷️ Commit: a32b515ebff79d6487b9a11a48238bd592720449
   ▶️ Tests:  116986 executed
   ⚪️ Checks: 31/31 completed
   
   ---
   _Learn more about TestLens at 
[testlens.app/docs](https://testlens.app/docs/features/pr-comment/)._
   




> Improve remaining common syntax error messages (unclosed literals, unexpected 
> characters, missing punctuation, reserved keywords)
> ---------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: GROOVY-12353
>                 URL: https://issues.apache.org/jira/browse/GROOVY-12353
>             Project: Groovy
>          Issue Type: Improvement
>            Reporter: Daniel Sun
>            Priority: Major
>
> h3. Problem
> After GROOVY-12169 and GROOVY-12171, several everyday syntax mistakes still 
> produce a generic *Unexpected input* or *Unexpected character* message that 
> does not name the actual problem.
> Invisible characters (zero-width space, BOM, NUL, form feed) appear as an 
> empty glyph in quotes. Unclosed quotes and comments are reported as an 
> unexpected quote or slash rather than as an unclosed literal. {{if true}} 
> without parentheses, {{x ? y}}, and {{const x = 1}} look like random 
> unexpected tokens instead of a missing {{(}} / {{:}} or an unimplemented 
> keyword.
> h3. Examples (before)
>  * Source:
> {noformat}
> println 'Hello
> {noformat}
> Report:
> {noformat}
> Unexpected character: ''' @ line 1, column 9.
> {noformat}
> (caret on the opening quote)
>  * Source:
> {noformat}
> /* comment
> {noformat}
> Report:
> {noformat}
> Unexpected input: '/'
> {noformat}
> (no mention of an unclosed comment)
>  * Source: {{def}} + zero-width space + {{name = null}}
> Report:
> {noformat}
> Unexpected character: ''
> {noformat}
> (the offending character is invisible)
>  * Source:
> {noformat}
> if true { x = 1 }
> {noformat}
> Report:
> {noformat}
> Unexpected input: 'true'
> {noformat}
>  * Source:
> {noformat}
> const x = 1
> {noformat}
> Report:
> {noformat}
> Unexpected input: 'const'
> {noformat}
>  * Source:
> {noformat}
> def n = 1_
> {noformat}
> Report:
> {noformat}
> Number ending with underscores is invalid @ line 1, column 10 @ line 1, 
> column 10.
> {noformat}
> (position duplicated)
>  * Source:
> {noformat}
> def m(int... a, int b) {}
> {noformat}
> Report:
> {noformat}
> The var-arg parameter strs must be the last parameter
> {noformat}
> (hard-coded name {{strs}})
> h3. Root cause
>  * Lexer {{UNEXPECTED_CHAR}} inlined the raw character with only a 
> quote-escape, so control / format characters vanish in the message. An 
> unexpected quote is almost always an unclosed string, but the message never 
> said so.
>  * Unclosed block comments failed the comment rule and were retokenised as 
> {{/}}, so the parser saw an unexpected slash.
>  * Parser fallback wording was still ANTLR's *Unexpected input*, even when 
> the expected set was a single punctuation token (open paren, colon, {{>}}) or 
> the offending token was a reserved keyword ({{const}}, {{goto}}, {{else}}, 
> {{catch}}, {{finally}}, {{case}}) or EOF.
>  * Lexer {{require(..., true)}} appended {{@ line N, column M}} to 
> {{GroovySyntaxError}}, and {{SyntaxException}} appended the same location 
> again.
>  * {{AstBuilder}} used a hard-coded parameter name {{strs}} in the 
> varargs-not-last diagnostic.
> Grammar-level parser error alternatives are not an option: GROOVY-9588 showed 
> they enlarge the ATN and slow successful parses.
> h3. Goal
> Give javac-aligned, developer-facing sentences for these common mistakes, 
> with an accurate caret, without reintroducing parser error alternatives on 
> the hot path.
> h3. Approach
> Error-path-only, two layers:
>  * Lexer ({{GroovyLexer.g4}} / {{AbstractLexer}}): unexpected quote becomes 
> *Unclosed string literal*; unclosed block comment becomes *Unclosed comment* 
> at the opener (same-rule EOF alternative, not a second lexer rule); other 
> unexpected characters via {{getCharErrorDisplay}} (shared with the GString 
> {{$}} path from GROOVY-12171). Stop attaching position text on lexer 
> {{require}} calls so {{SyntaxException}} is the only source of {{@ line N, 
> column M}}.
>  * Parser ({{AbstractFriendlyErrorStrategy}}): {{MissingDelimiterDiagnostic}} 
> still relocates the caret for a missing closer (GROOVY-12169). Everything 
> else only refines the fallback sentence and keeps ANTLR's offending token: 
> reserved/misplaced keyword, then a singleton expected punctuation token 
> ({{Missing '('}}, {{Missing ':'}}, {{Missing '>'}}, ...), then *Unexpected 
> end of input* for EOF.
> {{AstBuilder}} reports the actual varargs parameter name.
> h3. Expected result (after)
>  * unclosed single-quoted string becomes *Unclosed string literal*
>  * unclosed block comment becomes *Unclosed comment* (caret on the opener)
>  * zero-width space in an identifier becomes {{Unexpected character: 
> '\u200b'}}
>  * {{if true}} without parentheses becomes {{Missing '('}}
>  * {{x ? y}} becomes {{Missing ':'}}
>  * a generic type missing {{>}} before {{(}} becomes {{Missing '>'}}
>  * {{const x = 1}} becomes {{'const' is not supported; use 'val' or 'static 
> final' instead}}
>  * {{goto label}} becomes {{'goto' is not supported}}
>  * stray {{else}} / {{catch}} / {{case}} become {{'else' without 'if'}} / 
> {{'catch' without 'try'}} / {{'case' outside of switch}}
>  * {{throw}} at EOF becomes *Unexpected end of input*
>  * {{def n = 1_}} becomes *Number ending with underscores is invalid* 
> (position once)
>  * {{def m(int... a, int b)}} with a later parameter becomes {{The var-arg 
> parameter a must be the last parameter}}
> Valid programs are unchanged. Successful parses never enter these helpers.
> h3. Related
> GROOVY-12169, GROOVY-12171, GROOVY-9588, GROOVY-10146



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to