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

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

sonarqubecloud[bot] commented on PR #2718:
URL: https://github.com/apache/groovy/pull/2718#issuecomment-5008181901

   ## [![Quality Gate 
Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png
 'Quality Gate 
Passed')](https://sonarcloud.io/dashboard?id=apache_groovy&pullRequest=2718) 
**Quality Gate passed**  
   Issues  
   
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png
 '') [10 New 
issues](https://sonarcloud.io/project/issues?id=apache_groovy&pullRequest=2718&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)
  
   
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png
 '') [0 Accepted 
issues](https://sonarcloud.io/project/issues?id=apache_groovy&pullRequest=2718&issueStatuses=ACCEPTED)
   
   Measures  
   
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png
 '') [0 Security 
Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_groovy&pullRequest=2718&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)
  
   
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png
 '') [96.4% Coverage on New 
Code](https://sonarcloud.io/component_measures?id=apache_groovy&pullRequest=2718&metric=new_coverage&view=list)
  
   
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png
 '') [0.0% Duplication on New 
Code](https://sonarcloud.io/component_measures?id=apache_groovy&pullRequest=2718&metric=new_duplicated_lines_density&view=list)
  
     
   <!

> Improve syntax error messages and caret positions for missing ')', ']', and 
> '}'
> -------------------------------------------------------------------------------
>
>                 Key: GROOVY-12169
>                 URL: https://issues.apache.org/jira/browse/GROOVY-12169
>             Project: Groovy
>          Issue Type: Improvement
>            Reporter: Daniel Sun
>            Priority: Major
>
> h3. Problem
> When Groovy source is missing a closing delimiter (right paren, right 
> bracket, or right brace), the ANTLR4 parser often reports a generic 
> *Unexpected input* message at a *misleading* location (commonly the opening 
> token or an earlier construct), instead of a clear *Missing ...* message at 
> the place where the closer should be inserted.
> That makes simple typos hard to diagnose, especially with:
>  * casts and parenthesised expressions (missing right paren)
>  * lists, maps, and indexing (missing right bracket, including safe-index)
>  * blocks, classes, and closures (missing right brace)
> h3. Examples (before)
>  * Source:
> {noformat}
> println ((int 123)
> {noformat}
> Report: Unexpected input for open-paren at the *opening* parenthesis
>  * Source:
> {noformat}
> [1, 2
> {noformat}
> Report: Unexpected input: '<EOF>' at end of input
>  * Source:
> {noformat}
> foo[1
> {noformat}
> Report: Unexpected input for the open-bracket token
>  * Source:
> {noformat}
> def m() {
>     println 1
> {noformat}
> Report: Unexpected input far from the missing brace
>  * Source:
> {noformat}
> foo([1, 2)
> {noformat}
> Report: Unexpected input for open-paren (real issue: missing right bracket 
> before right paren)
> h3. Root cause
>  * ANTLR4 does not recover missing tokens as helpfully as the old Antlr2 path.
>  * Grammar-level error alternatives (for example on {{{}rparen{}}}) can yield 
> a *Missing right-paren* message, but they enlarge the ATN and hurt 
> {*}successful{*}-parse performance. They were removed in the GROOVY-9588 work 
> for that reason.
>  * With {{BailErrorStrategy}} plus generic mismatch reporting, prediction 
> often abandons a deep delimited alternative and falls back to a shorter 
> parse, so the surface error points far from the real omission.
> h3. Goal
> Report {*}Missing right-paren{*}, {*}Missing right-bracket{*}, or *Missing 
> right-brace* with an accurate caret when the token stream clearly indicates a 
> missing or incomplete closer — *without* reintroducing grammar error 
> alternatives on the hot (successful) parse path.
> h3. Approach
> Error-path-only diagnostics wired into the existing error strategy:
>  * {{DescriptiveErrorStrategy}} — on input mismatch / no viable alternative, 
> prefer a missing-delimiter hit over the generic message.
>  * {{MissingDelimiterDiagnostic}} — one linear scan of the fully filled token 
> stream *after* failure; no work on successful parses.
> Detection order (most specific first):
> *1. Sole expected closer* — RecognitionException whose *sole* expected token 
> is RPAREN, RBRACK, or RBRACE, and the corresponding open-depth is still 
> positive. This avoids false positives where delimiters are balanced but an 
> intermediate token is wrong, for example:
> {noformat}
> foo(1;2;3)
> {noformat}
> *2. Cast pattern* — open-paren, type, then expression-start without the 
> cast's close-paren, for example:
> {noformat}
> (int 123
> {noformat}
> *3. Delimiter stack* — walk openers for paren, bracket, safe-index, and 
> brace; report the *innermost* missing closer on mismatch or at EOF, for 
> example:
> {noformat}
> foo([1, 2)
> {noformat}
> (missing right bracket before the right paren)
> The token stream is force-filled to EOF before scanning so a trailing closer 
> is visible even when the parser failed earlier inside the construct.
> h3. Expected result (after)
>  * Source:
> {noformat}
> println ((int 123)
> {noformat}
> Expected: *Missing right-paren* at 123
>  * Source:
> {noformat}
> def x() {
>     println((int) 123
> }
> {noformat}
> Expected: *Missing right-paren* after 123
>  * Source:
> {noformat}
> def m( {
> }
> {noformat}
> Expected: *Missing right-paren* at the open brace
>  * Source:
> {noformat}
> foo(1, 2
> {noformat}
> Expected: *Missing right-paren* at end of line
>  * Source:
> {noformat}
> [1, 2
> {noformat}
> Expected: *Missing right-bracket* at end of line
>  * Source:
> {noformat}
> foo[1
> {noformat}
> Expected: *Missing right-bracket* after 1
>  * Source:
> {noformat}
> def x = [[1, 2]
> {noformat}
> Expected: *Missing right-bracket* after the inner closing bracket
>  * Source:
> {noformat}
> foo([1, 2)
> {noformat}
> Expected: *Missing right-bracket* before the closing paren
>  * Source:
> {noformat}
> a?[0
> {noformat}
> Expected: *Missing right-bracket* after 0
>  * Source:
> {noformat}
> def m() {
>     println 1
> {noformat}
> Expected: *Missing right-brace* after 1
>  * Source:
> {noformat}
> class C {
>     def x
> {noformat}
> Expected: *Missing right-brace* after x
>  * Source:
> {noformat}
> def c = { it
> {noformat}
> Expected: *Missing right-brace* after it
> False-positive guard (delimiters balanced; must *not* report a 
> Missing-delimiter message):
> {noformat}
> [].bar(1;2;3)
> {noformat}
> h3. Compatibility and performance
>  * No grammar, lexer, or public API changes — valid programs parse as before.
>  * Successful path remains {{BailErrorStrategy}} with no ATN error 
> alternatives.
>  * Extra work is a single O\(n\) token scan only after a recognition failure.



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

Reply via email to