Skip to content

Commit 9f76c94

Browse files
authored
Parse dynamic method invocation (#5778)
1 parent 6bddacb commit 9f76c94

File tree

3 files changed

+40
-15
lines changed

3 files changed

+40
-15
lines changed

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

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -504,8 +504,8 @@ class B { class B {
504504
methodName = method.getName();
505505
} else {
506506
// Method name might be in quotes
507-
char openingQuote = source.charAt(cursor);
508-
methodName = openingQuote + method.getName() + openingQuote;
507+
String delim = source.charAt(cursor) + "";
508+
methodName = sourceSubstring(cursor, delim) + delim;
509509
}
510510
cursor += methodName.length();
511511
J.Identifier name = new J.Identifier(randomId(),
@@ -1739,25 +1739,26 @@ public void visitMethodCallExpression(MethodCallExpression call) {
17391739
// So the "select" that was just parsed _may_ have actually been the method name
17401740
J.Identifier name;
17411741

1742-
String methodNameExpression = call.getMethodAsString();
1742+
String methodName = call.getMethodAsString();
1743+
// Check for escaped method name, often used in tests (def 'description'() {}) or to avoid clashing with Groovy keywords
17431744
if (source.charAt(cursor) == '"' || source.charAt(cursor) == '\'') {
1744-
// we have an escaped groovy method name, commonly used for test `def 'some scenario description'() {}`
1745-
// or to workaround names that are also keywords in groovy
1746-
methodNameExpression = source.charAt(cursor) + methodNameExpression + source.charAt(cursor);
1745+
// TODO: Methods with string interpolation are parsed as just one method name instead of multiple LST elements
1746+
String delim = source.charAt(cursor) + "";
1747+
methodName = sourceSubstring(cursor, delim) + delim;
17471748
}
17481749

17491750
Space prefix = whitespace();
1750-
boolean implicitCall = (methodNameExpression != null && cursor < source.length() &&
1751-
source.charAt(cursor) == '(' && (cursor + methodNameExpression.length() > source.length() ||
1752-
!methodNameExpression.equals(source.substring(cursor, cursor + methodNameExpression.length())))
1751+
boolean implicitCall = (methodName != null && cursor < source.length() &&
1752+
source.charAt(cursor) == '(' && (cursor + methodName.length() > source.length() ||
1753+
!methodName.equals(source.substring(cursor, cursor + methodName.length())))
17531754
);
17541755
if (implicitCall) {
17551756
// This is an implicit call() method - create identifier but it doesn't get printed
17561757
name = new J.Identifier(randomId(), prefix, Markers.EMPTY, emptyList(), "", null, null);
17571758
} else {
1758-
if (methodNameExpression.equals(source.substring(cursor, cursor + methodNameExpression.length()))) {
1759-
skip(methodNameExpression);
1760-
name = new J.Identifier(randomId(), prefix, Markers.EMPTY, emptyList(), methodNameExpression, null, null);
1759+
if (methodName.equals(source.substring(cursor, cursor + methodName.length()))) {
1760+
skip(methodName);
1761+
name = new J.Identifier(randomId(), prefix, Markers.EMPTY, emptyList(), methodName, null, null);
17611762
} else if (select != null && select.getElement() instanceof J.Identifier) {
17621763
name = (J.Identifier) select.getElement();
17631764
select = null;

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ public J.ArrayType visitArrayType(J.ArrayType arrayType, Object o) {
212212

213213
@Test
214214
@Issue("https://github.com/openrewrite/rewrite/issues/3559")
215-
void escapedMethodNameTest() {
215+
void escapedMethodName() {
216216
rewriteRun(
217217
groovy(
218218
"""
@@ -224,7 +224,7 @@ void escapedMethodNameTest() {
224224
}
225225

226226
@Test
227-
void escapedMethodNameWithSpacesTest() {
227+
void escapedMethodNameWithSpaces() {
228228
rewriteRun(
229229
groovy(
230230
"""
@@ -235,6 +235,18 @@ void escapedMethodNameWithSpacesTest() {
235235
);
236236
}
237237

238+
@Test
239+
void escapedMethodNameWithDollarSign() {
240+
rewriteRun(
241+
groovy(
242+
"""
243+
def "xMethod\\${regularText}"() {}
244+
"xMethod\\${regularText}"()
245+
"""
246+
)
247+
);
248+
}
249+
238250
@Issue("https://github.com/openrewrite/rewrite/issues/4705")
239251
@Test
240252
void functionWithDefAndExplicitReturnType() {

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,19 @@ void useClassAsArgumentJavaStyle() {
198198
);
199199
}
200200

201+
@Test
202+
void dynamicMethodInvocation() {
203+
rewriteRun(
204+
groovy(
205+
"""
206+
def xMethod() {}
207+
def prefix = "x"
208+
"${prefix}Method"()
209+
"""
210+
)
211+
);
212+
}
213+
201214
@Test
202215
void staticMethodReference() {
203216
rewriteRun(
@@ -696,5 +709,4 @@ static <T> boolean compare(T t1, T t2) {
696709
)
697710
);
698711
}
699-
700712
}

0 commit comments

Comments
 (0)