Skip to content

Commit 305085c

Browse files
Fix GroovyParserVisitor cast dispatch for parenthesized expressions (#7470)
`visitCastExpression` distinguished Java-style `(Type) expr` from Groovy `as`-style `expr as Type` by peeking at `source.charAt(cursor)`: if the next character was `(`, assume Java-style. For an expression like `(foo as Bar).name as Set`, the outer `as`-style cast's expression itself starts with `(`, so the parser took the Java-style branch, mis-parsed the cast as a C-style cast, and produced an LST that failed print idempotency. Downstream, this can cascade into later parse failures (observed as `Failed to parse ... at cursor position N` on unrelated single-quoted strings far past the actual offending cast). Use `CastExpression#isCoerce()` — the Groovy AST's authoritative flag for `as`-style coercion — instead of peeking at the source.
1 parent ace0569 commit 305085c

2 files changed

Lines changed: 15 additions & 2 deletions

File tree

rewrite-groovy/src/main/java/org/openrewrite/groovy/GroovyParserVisitor.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1482,8 +1482,10 @@ private J.Case visitDefaultCaseStatement(BlockStatement statement) {
14821482
@Override
14831483
public void visitCastExpression(CastExpression cast) {
14841484
queue.add(insideParentheses(cast, prefix -> {
1485-
// Might be looking at a Java-style cast "(type)object" or a groovy-style cast "object as type"
1486-
if (source.charAt(cursor) == '(') {
1485+
// Java-style cast "(type)object" vs groovy-style cast "object as type".
1486+
// Can't detect by looking at cursor character because the expression
1487+
// itself may start with '(' (e.g. "(foo as Bar).name as Set").
1488+
if (!cast.isCoerce()) {
14871489
skip("(");
14881490
return new J.TypeCast(randomId(), prefix, Markers.EMPTY,
14891491
new J.ControlParentheses<>(randomId(), EMPTY, Markers.EMPTY,

rewrite-groovy/src/test/java/org/openrewrite/groovy/tree/CastTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,15 @@ void javaCastAndInvokeMethodWithParentheses() {
123123
)
124124
);
125125
}
126+
127+
@Test
128+
void asStyleCastOfParenthesizedCast() {
129+
rewriteRun(
130+
groovy(
131+
"""
132+
def x = (foo as Bar).name as Set
133+
"""
134+
)
135+
);
136+
}
126137
}

0 commit comments

Comments
 (0)