Skip to content

Commit

Permalink
GROOVY-11374: handle type argument(s) and dynamic or non-identifier name
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed May 13, 2024
1 parent 26851b8 commit 580aee1
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import java.util.Collections;
import java.util.List;

import static org.codehaus.groovy.tools.Utilities.isJavaIdentifier;

/**
* A method call on an object or class.
*/
Expand All @@ -42,7 +44,6 @@ public class MethodCallExpression extends Expression implements MethodCall {

// type spec for generics
private GenericsType[] genericsTypes;
private boolean usesGenerics;

private MethodNode target;

Expand Down Expand Up @@ -137,12 +138,40 @@ public ASTNode getReceiver() {

@Override
public String getText() {
String object = objectExpression.getText();
String meth = method.getText();
String args = arguments.getText();
String spread = spreadSafe ? "*" : "";
String dereference = safe ? "?" : "";
return object + spread + dereference + "." + meth + args;
StringBuilder builder = new StringBuilder( 64 );
builder.append(getObjectExpression().getText());
if (isSpreadSafe()) builder.append('*');
if (isSafe()) builder.append('?');
builder.append('.');

if (isUsingGenerics()) {
builder.append('<');
boolean first = true;
for (GenericsType t : getGenericsTypes()) {
if (!first) builder.append(", ");
else first = false;
builder.append(t);
}
builder.append('>');
}

Expression method = getMethod();
if (method instanceof GStringExpression) {
builder.append('"').append(method.getText()).append('"');
} else if (!(method instanceof ConstantExpression)) {
builder.append('(').append(method.getText()).append(')');
} else {
Object value = ((ConstantExpression) method).getValue();
if (!(value instanceof String) || !isJavaIdentifier((String) value)) {
builder.append("'").append(value).append("'");
} else {
builder.append((String) value);
}
}

builder.append(getArguments().getText());

return builder.toString();
}

/**
Expand Down Expand Up @@ -183,12 +212,11 @@ public GenericsType[] getGenericsTypes() {
}

public void setGenericsTypes(GenericsType[] genericsTypes) {
usesGenerics = usesGenerics || genericsTypes != null;
this.genericsTypes = genericsTypes;
}

public boolean isUsingGenerics() {
return usesGenerics;
return (genericsTypes != null && genericsTypes.length > 0);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,76 @@
*/
package org.codehaus.groovy.ast.expr

import groovy.test.GroovyTestCase
import org.junit.Test

class MethodCallExpressionTest extends GroovyTestCase {
import static org.codehaus.groovy.ast.ClassHelper.OBJECT_TYPE
import static org.codehaus.groovy.ast.ClassHelper.STRING_TYPE

void testGetText() {
final class MethodCallExpressionTest {

@Test
void testGetText1() {
MethodCallExpression method = new MethodCallExpression(
new VariableExpression('foo'),
'bar',
new ArgumentListExpression(new ConstantExpression('baz'))
)
assert 'foo.bar(baz)' == method.text
assert method.text == 'foo.bar(baz)'

method.safe = true
method.spreadSafe = false
assert 'foo?.bar(baz)' == method.text
assert method.text == 'foo?.bar(baz)'

method.safe = false
method.spreadSafe = true
assert 'foo*.bar(baz)' == method.text
assert method.text == 'foo*.bar(baz)'

method.safe = true
method.spreadSafe = true
assert 'foo*?.bar(baz)' == method.text
assert method.text == 'foo*?.bar(baz)'
}

@Test
void testGetText2() {
MethodCallExpression method = new MethodCallExpression(
new VariableExpression('foo'),
new VariableExpression('bar'),
new ArgumentListExpression(new VariableExpression('baz'))
)
assert method.text == 'foo.(bar)(baz)'
}

@Test
void testGetText3() {
MethodCallExpression method = new MethodCallExpression(
new VariableExpression('foo'),
new GStringExpression('$bar'),
new ArgumentListExpression(new VariableExpression('baz'))
)
assert method.text == 'foo."$bar"(baz)'
}

@Test
void testGetText4() {
MethodCallExpression method = new MethodCallExpression(
new VariableExpression('foo'),
new ConstantExpression(12345),
new ArgumentListExpression(new VariableExpression('baz'))
)
assert method.text == "foo.'12345'(baz)"
}

@Test
void testGetText5() {
MethodCallExpression method = new MethodCallExpression(
new VariableExpression('foo'),
'bar',
new ArgumentListExpression(new VariableExpression('baz'))
)
method.setGenericsTypes(
STRING_TYPE.asGenericsType(),
OBJECT_TYPE.asGenericsType()
)
assert method.text == "foo.<java.lang.String, java.lang.Object>bar(baz)"
}
}

0 comments on commit 580aee1

Please sign in to comment.