From c094093d471529ddef3087c6e97f04d62f5d238b Mon Sep 17 00:00:00 2001 From: Eric Milles Date: Wed, 22 Apr 2020 08:02:55 -0500 Subject: [PATCH] Fix for #1096: save enclosing call reference for static method call args --- .../tests/search/ClosureInferencingTests.java | 17 ++++++++++++++++ .../core/tests/xform/TypeCheckedTests.java | 20 +++++++++++++++++++ .../TypeInferencingVisitorWithRequestor.java | 13 +++++++----- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/search/ClosureInferencingTests.java b/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/search/ClosureInferencingTests.java index c7f4f1b8f4..b4f5a52596 100644 --- a/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/search/ClosureInferencingTests.java +++ b/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/search/ClosureInferencingTests.java @@ -1450,6 +1450,23 @@ public void testClosureParamsAnnotation3() { assertType(contents, "list", "java.util.List"); } + @Test + public void testClosureParamsAnnotation4() { + String contents = + //@formatter:off + "import groovy.transform.stc.*\n" + + "class C {\n" + + " static m(String s, @ClosureParams(value=SimpleType, options='java.util.List') Closure c) {\n" + + " }\n" + + " static test() {\n" + + " m('str', { list -> null })\n" + + " }\n" + + "}\n"; + //@formatter:on + + assertType(contents, "list", "java.util.List"); + } + @Test public void testClosureReferencesSuperClass() { String contents = diff --git a/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java b/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java index 9a412e0747..e0eae09894 100644 --- a/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java +++ b/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java @@ -193,4 +193,24 @@ public void testTypeChecked8() { runNegativeTest(sources, ""); } + + @Test + public void testTypeChecked9() { + //@formatter:off + String[] sources = { + "Foo.groovy", + "class C {\n" + + " static m(String s, Comparable> c) {\n" + + " }\n" + + " @groovy.transform.TypeChecked\n" + + " static test() {\n" + + " m('blah', { list -> list.get(0) })\n" + + " }\n" + + "}\n" + + "C.test()\n", + }; + //@formatter:on + + runNegativeTest(sources, ""); + } } diff --git a/base/org.eclipse.jdt.groovy.core/src/org/eclipse/jdt/groovy/search/TypeInferencingVisitorWithRequestor.java b/base/org.eclipse.jdt.groovy.core/src/org/eclipse/jdt/groovy/search/TypeInferencingVisitorWithRequestor.java index 1b9737bc9a..2291d3ba68 100644 --- a/base/org.eclipse.jdt.groovy.core/src/org/eclipse/jdt/groovy/search/TypeInferencingVisitorWithRequestor.java +++ b/base/org.eclipse.jdt.groovy.core/src/org/eclipse/jdt/groovy/search/TypeInferencingVisitorWithRequestor.java @@ -1648,18 +1648,20 @@ public void visitSpreadMapExpression(final SpreadMapExpression node) { @Override public void visitStaticMethodCallExpression(final StaticMethodCallExpression node) { - ClassNode type = node.getOwnerType(); - if (isPrimaryExpression(node)) { - visitMethodCallExpression(new MethodCallExpression(new ClassExpression(type), node.getMethod(), node.getArguments())); - } handleSimpleExpression(node, () -> { + Tuple t = dependentDeclarationStack.removeLast(); boolean isPresentInSource = (node.getEnd() > 0); + ClassNode type = node.getOwnerType(); if (isPresentInSource) { visitClassReference(type); } if (isPresentInSource || isEnumInit(node)) { // visit static method call arguments + scopes.getLast().addEnclosingMethodCall( + new VariableScope.CallAndType(node, t.declaration, t.declaringType, enclosingModule)); super.visitStaticMethodCallExpression(node); + scopes.getLast().forgetEnclosingMethodCall(); + // visit anonymous inner class members if (GroovyUtils.isAnonymous(type)) { visitMethodOverrides(type); @@ -1986,7 +1988,8 @@ private boolean handleRequestor(final Expression node, final ClassNode primaryTy } switch (status) { case CONTINUE: - if (node instanceof ConstructorCallExpression) { + // TODO: (node instanceof MethodCall && !(node instanceof MethodCallExpression)) + if (node instanceof ConstructorCallExpression || node instanceof StaticMethodCallExpression) { dependentDeclarationStack.add(new Tuple(result.declaringType, result.declaration)); } // fall through