[
https://issues.apache.org/jira/browse/GROOVY-12694?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18138417#comment-18138417
]
ASF GitHub Bot commented on GROOVY-12694:
-----------------------------------------
testlens-app[bot] commented on PR #3215:
URL: https://github.com/apache/groovy/pull/3215#issuecomment-6646207146
## ✅ All tests passed ✅
🏷️ Commit: 5ca604047038cb7c8694ce03051e1e3401e5c717
▶️ Tests: 127841 executed
⚪️ Checks: 26/26 completed
---
_Learn more about TestLens at
[testlens.app/docs](https://testlens.app/docs/features/pr-comment/)._
> Parser reports Missing ')' at an earlier closed paren group instead of the
> actual syntax error
> ----------------------------------------------------------------------------------------------
>
> Key: GROOVY-12694
> URL: https://issues.apache.org/jira/browse/GROOVY-12694
> Project: Groovy
> Issue Type: Bug
> Components: parser
> Affects Versions: 6.0.0
> Reporter: Scott Murphy Heiberg
> Priority: Major
>
> *Environment:* macOS 26.5 (Darwin 25.5.0), JDK 21.0.12 (BellSoft Liberica);
> diagnostics taken from {{groovyc --check --error-format=short}}. Also
> reproduces on 6.0.1-SNAPSHOT (GROOVY_6_0_X at 7c0dcf17dd) and master
> 7.0.0-SNAPSHOT (d86ea7eb85).
> h3. Description
> A Java-style type pattern in a switch case label ({{case Circle c ->}}) is
> not Groovy syntax, so the script below must fail to parse. When a record
> declaration precedes the switch, however, the error is reported as {{Missing
> ')'}} inside the record header on line 1 -- which parses fine on its own --
> instead of at the offending case label on line 3.
> h3. Reproducer
> {code:groovy}
> record Circle(double radius) {}
> Object o = new Circle(1)
> String s = switch (o) { case Circle c -> 'circle'; default -> 'other' }
> println s
> {code}
> h3. Actual
> {noformat}
> record.groovy:1:22: error: Missing ')'
> {noformat}
> Column 22 is {{radius}} in the record header. Replacing {{case Circle c ->}}
> with {{case Circle ->}} makes the file compile, so there is nothing missing
> on line 1.
> h3. Expected
> The diagnostic at the unsupported case label, which is what the same switch
> gets when a plain class ({{class Circle { double radius }}}) precedes it
> instead of the record:
> {noformat}
> record.groovy:3:37: error: Unexpected input: 'String s = switch (o) { case
> Circle c'
> {noformat}
> h3. Scope
> The record is incidental. Any parenthesised group of the shape {{( <type>
> <literal | identifier | (>}} that the parser has already accepted is reported
> as a missing {{)}} whenever a syntax error occurs later in the file:
> {code:groovy}
> def foo(int x) { x }
> def y = 1 +
> {code}
> {noformat}
> Missing ')' @ line 1, column 13
> {noformat}
> Expected {{Unexpected input: '+' @ line 2, column 11}}, which is what the
> second line reports on its own. The same happens with {{for (int i = 0; i <
> 3; i++) { }}} or {{def y = (Math.max(1, 2))}} on the first line.
> h3. Cause
> {{org.apache.groovy.parser.antlr4.internal.MissingDelimiterDiagnostic#fromCastPattern}}
> (the "unclosed cast" heuristic added for the friendlier missing-delimiter
> messages) scans the whole token stream for {{'(' type <expr-start>}} and
> reports the earliest match, without checking whether that group's {{)}} was
> already matched before the point where the parser failed. A formal parameter
> list with a primitive-typed parameter, a classic {{for}} header or a
> parenthesised call all match that pattern. Restricting the scan to groups
> that are still open at the failure point (the offending token, or the start
> token of a failed {{NoViableAltException}} decision) fixes the position while
> keeping the real unclosed-cast diagnostics ({{println ((int 123)}} still
> reports at {{123}}).
> A pull request with regression tests follows.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)