Skip to content

Commit

Permalink
Fox for #1199: use LHS type to further resolve method call
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Nov 18, 2020
1 parent 9068081 commit 1b89cca
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 0 deletions.
Expand Up @@ -1229,6 +1229,27 @@ public void testStaticMethod6() {
assertType(contents, "col", "B");
}

@Test // https://github.com/groovy/groovy-eclipse/issues/1199
public void testStaticMethod7() {
// Arrays: public static final <T> List<T> asList(T...)
String contents = "List<String> list = Arrays.asList()";
assertType(contents, "asList", "java.util.List<java.lang.String>");
}

@Test // https://github.com/groovy/groovy-eclipse/issues/1199
public void testStaticMethod8() {
// Collections: public static final <T> List<T> emptyList()
String contents = "List<String> list = Collections.emptyList()";
assertType(contents, "emptyList", "java.util.List<java.lang.String>");
}

@Test // https://github.com/groovy/groovy-eclipse/issues/1199
public void testStaticMethod8a() {
// Collections: public static final <T> List<T> emptyList()
String contents = "import static java.util.Collections.*; List<String> list = emptyList()";
assertType(contents, "emptyList", "java.util.List<java.lang.String>");
}

@Test
public void testStaticMethod9() {
// Collections: public static final <T> List<T> emptyList()
Expand Down
Expand Up @@ -1681,6 +1681,7 @@ public void visitSpreadMapExpression(final SpreadMapExpression node) {

@Override
public void visitStaticMethodCallExpression(final StaticMethodCallExpression node) {
scopes.getLast().setCurrentNode(node);
handleSimpleExpression(node, () -> {
Tuple t = dependentDeclarationStack.removeLast();
VariableScope.CallAndType cat = new VariableScope.CallAndType(node, t.declaration, t.declaringType, enclosingModule);
Expand All @@ -1694,6 +1695,7 @@ public void visitStaticMethodCallExpression(final StaticMethodCallExpression nod
visitEnumConstBody(node.getOwnerType());
}
});
scopes.getLast().forgetCurrentNode();
}

@Override
Expand Down Expand Up @@ -2355,6 +2357,19 @@ private List<ClassNode> getMethodCallArgumentTypes(ASTNode node) {
scope.setMethodCallArgumentTypes(getMethodCallArgumentTypes(expression));
tlr = lookupExpressionType(expression, null, true, scope);

// } else if (expression instanceof MethodPointerExpression) {
// MethodPointerExpression ref = (MethodPointerExpression) expression;
// scope.setCurrentNode(ref);
// tlr = lookupExpressionType(ref.getExpression(), null, false, scope);
// scope.setCurrentNode(ref.getMethodName());
// tlr = lookupExpressionType(ref.getMethodName(), tlr.type, ref.getExpression() instanceof ClassExpression || VariableScope.CLASS_CLASS_NODE.equals(tlr.type), scope);
// if (tlr.confidence.isAtLeast(TypeConfidence.LOOSELY_INFERRED))
// types.add(createParameterizedClosure(tlr.type));
// else types.add(exprType);
// scope.forgetCurrentNode();
// scope.forgetCurrentNode();
// continue;

} else if (expression instanceof BinaryExpression && ((BinaryExpression) expression).getOperation().isA(Types.LEFT_SQUARE_BRACKET)) {
tlr = lookupExpressionType(((BinaryExpression) expression).getLeftExpression(), null, false, scope);
scope.setMethodCallArgumentTypes(Collections.singletonList(
Expand Down
Expand Up @@ -35,7 +35,9 @@
import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.ast.expr.BinaryExpression;
import org.codehaus.groovy.ast.expr.DeclarationExpression;
import org.codehaus.groovy.ast.expr.MethodCallExpression;
import org.codehaus.groovy.ast.expr.MethodPointerExpression;
import org.codehaus.groovy.ast.expr.StaticMethodCallExpression;
import org.codehaus.groovy.ast.expr.TupleExpression;
import org.codehaus.groovy.ast.tools.GenericsUtils;
import org.eclipse.jdt.groovy.core.util.GroovyUtils;
Expand Down Expand Up @@ -222,6 +224,19 @@ public TypeLookupResult resolveTypeParameterization(final ClassNode objExprType,
if (scope.getMethodCallArgumentTypes() != null) argumentTypes.addAll(scope.getMethodCallArgumentTypes());
mapper = GenericsMapper.gatherGenerics(argumentTypes, objectType, method, scope.getMethodCallGenericsTypes());
method = VariableScope.resolveTypeParameterization(mapper, method);

if (scope.getMethodCallGenericsTypes() == null && GenericsUtils.hasUnresolvedGenerics(method.getReturnType()) &&
(argumentTypes.size() == (isGroovy ? 1 : 0) || false/*return type placeholder(s) not in parameters*/) &&
testEnclosingAssignment(scope, rhs ->
(rhs instanceof StaticMethodCallExpression && rhs == scope.getCurrentNode()) ||
(rhs instanceof MethodCallExpression && ((MethodCallExpression) rhs).getMethod() == scope.getCurrentNode())
)) {
// maybe the assign target type can help resolve type parameters of method call
ClassNode targetType = scope.getEnclosingAssignment().getLeftExpression().getType();

mapper = GenericsMapper.gatherGenerics(singletonList(targetType), declaringType, returnTypeStub(method));
method = VariableScope.resolveTypeParameterization(mapper, method);
}
}
if (method != declaration) {
TypeLookupResult result = new TypeLookupResult(method.getReturnType(), method.getDeclaringClass(), method, confidence, scope, extraDoc);
Expand Down

0 comments on commit 1b89cca

Please sign in to comment.