From a3c04d37bd4825f67673b2dd9969461e285ff7dc Mon Sep 17 00:00:00 2001 From: Eric Milles Date: Mon, 26 Nov 2018 16:07:58 -0600 Subject: [PATCH] Fix for same-unit default parameter constructor reference searching #768 --- .../ConstructorReferenceSearchTests.java | 38 +++++++++++++++++++ .../codehaus/groovy/classgen/Verifier.java | 11 +++++- .../codehaus/groovy/classgen/Verifier.java | 11 +++++- .../codehaus/groovy/classgen/Verifier.java | 11 +++++- .../ConstructorReferenceSearchRequestor.java | 5 ++- 5 files changed, 68 insertions(+), 8 deletions(-) diff --git a/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/search/ConstructorReferenceSearchTests.java b/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/search/ConstructorReferenceSearchTests.java index a9a564706e..87b69dfd95 100644 --- a/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/search/ConstructorReferenceSearchTests.java +++ b/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/search/ConstructorReferenceSearchTests.java @@ -258,6 +258,44 @@ public void testConstructorReferences10() throws Exception { assertEquals(1, ctorRefs); } + @Test // default value generates a synthetic constructor + public void testConstructorReferences11() throws Exception { + GroovyCompilationUnit foo = createUnit("p", "Foo", "package p\n" + + "class Foo {\n" + + " Foo(int i = 0) {}\n" + // search for this + " Foo(String s) {this()}\n" + // yes + " def m() {\n" + + " new Foo()\n" + // yes + " new Foo(0)\n" + // yes + " new Foo('')\n" + // no + " }\n" + + "}"); + + long ctorRefs = searchForReferences(foo.getType("Foo").getMethods()[0]).stream() + .filter(match -> ((IMethod) match.getElement()).getResource().getName().equals("Foo.groovy")) + .count(); + assertEquals(3, ctorRefs); + } + + @Test // default value generates a synthetic constructor + public void testConstructorReferences12() throws Exception { + GroovyCompilationUnit foo = createUnit("p", "Foo", "package p\n" + + "class Foo {\n" + + " Foo(int i) {this()}\n" + // yes + " Foo(String s = '') {}\n" + // search for this + " def m() {\n" + + " new Foo()\n" + // yes + " new Foo(0)\n" + // no + " new Foo('')\n" + // yes + " }\n" + + "}"); + + long ctorRefs = searchForReferences(foo.getType("Foo").getMethods()[1]).stream() + .filter(match -> ((IMethod) match.getElement()).getResource().getName().equals("Foo.groovy")) + .count(); + assertEquals(3, ctorRefs); + } + //-------------------------------------------------------------------------- List searchForReferences(IMethod method) throws CoreException { diff --git a/base/org.codehaus.groovy24/src/org/codehaus/groovy/classgen/Verifier.java b/base/org.codehaus.groovy24/src/org/codehaus/groovy/classgen/Verifier.java index efa751a884..e0abc836a6 100644 --- a/base/org.codehaus.groovy24/src/org/codehaus/groovy/classgen/Verifier.java +++ b/base/org.codehaus.groovy24/src/org/codehaus/groovy/classgen/Verifier.java @@ -60,6 +60,7 @@ import org.codehaus.groovy.classgen.asm.OptimizingStatementWriter.ClassNodeSkip; import org.codehaus.groovy.classgen.asm.WriterController; import org.codehaus.groovy.reflection.ClassInfo; +import org.codehaus.groovy.runtime.DefaultGroovyMethods; import org.codehaus.groovy.runtime.MetaClassHelper; import org.codehaus.groovy.syntax.RuntimeParserException; import org.codehaus.groovy.syntax.Token; @@ -817,12 +818,11 @@ public void visitVariableExpression(VariableExpression expression) { addPropertyMethod(newMethod); // GRECLIPSE add newMethod.setOriginal(method); - newMethod.setSourcePosition(method); newMethod.setNameEnd(method.getNameEnd()); newMethod.setNameStart(method.getNameStart()); // GRECLIPSE end newMethod.setGenericsTypes(method.getGenericsTypes()); - newMethod.putNodeMetaData(DEFAULT_PARAMETER_GENERATED, true); + newMethod.putNodeMetaData(DEFAULT_PARAMETER_GENERATED, Boolean.TRUE); } }); } @@ -835,6 +835,13 @@ public void call(ArgumentListExpression arguments, Parameter[] newParams, Method ConstructorCallExpression expression = new ConstructorCallExpression(ClassNode.THIS, arguments); Statement code = new ExpressionStatement(expression); addConstructor(newParams, ctor, code, node); + // GRECLIPSE add + ctor = DefaultGroovyMethods.last(node.getDeclaredConstructors()); + ctor.setOriginal(method); + ctor.setNameEnd(method.getNameEnd()); + ctor.setNameStart(method.getNameStart()); + ctor.putNodeMetaData(DEFAULT_PARAMETER_GENERATED, Boolean.TRUE); + // GRECLIPSE end } }); } diff --git a/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/Verifier.java b/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/Verifier.java index 5c3d5f312f..7050a40e12 100644 --- a/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/Verifier.java +++ b/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/Verifier.java @@ -62,6 +62,7 @@ import org.codehaus.groovy.classgen.asm.OptimizingStatementWriter.ClassNodeSkip; import org.codehaus.groovy.classgen.asm.WriterController; import org.codehaus.groovy.reflection.ClassInfo; +import org.codehaus.groovy.runtime.DefaultGroovyMethods; import org.codehaus.groovy.runtime.MetaClassHelper; import org.codehaus.groovy.syntax.RuntimeParserException; import org.codehaus.groovy.syntax.Token; @@ -884,12 +885,11 @@ public void visitVariableExpression(VariableExpression expression) { addPropertyMethod(newMethod); // GRECLIPSE add newMethod.setOriginal(method); - newMethod.setSourcePosition(method); newMethod.setNameEnd(method.getNameEnd()); newMethod.setNameStart(method.getNameStart()); // GRECLIPSE end newMethod.setGenericsTypes(method.getGenericsTypes()); - newMethod.putNodeMetaData(DEFAULT_PARAMETER_GENERATED, true); + newMethod.putNodeMetaData(DEFAULT_PARAMETER_GENERATED, Boolean.TRUE); } }); } @@ -902,6 +902,13 @@ public void call(ArgumentListExpression arguments, Parameter[] newParams, Method ConstructorCallExpression expression = new ConstructorCallExpression(ClassNode.THIS, arguments); Statement code = new ExpressionStatement(expression); addConstructor(newParams, ctor, code, node); + // GRECLIPSE add + ctor = DefaultGroovyMethods.last(node.getDeclaredConstructors()); + ctor.setOriginal(method); + ctor.setNameEnd(method.getNameEnd()); + ctor.setNameStart(method.getNameStart()); + ctor.putNodeMetaData(DEFAULT_PARAMETER_GENERATED, Boolean.TRUE); + // GRECLIPSE end } }); } diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/Verifier.java b/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/Verifier.java index f81c8ae36b..7362ccf779 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/Verifier.java +++ b/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/Verifier.java @@ -61,6 +61,7 @@ import org.codehaus.groovy.classgen.asm.OptimizingStatementWriter.ClassNodeSkip; import org.codehaus.groovy.classgen.asm.WriterController; import org.codehaus.groovy.reflection.ClassInfo; +import org.codehaus.groovy.runtime.DefaultGroovyMethods; import org.codehaus.groovy.runtime.MetaClassHelper; import org.codehaus.groovy.syntax.RuntimeParserException; import org.codehaus.groovy.syntax.Token; @@ -864,12 +865,11 @@ public void visitVariableExpression(VariableExpression expression) { addPropertyMethod(newMethod); // GRECLIPSE add newMethod.setOriginal(method); - newMethod.setSourcePosition(method); newMethod.setNameEnd(method.getNameEnd()); newMethod.setNameStart(method.getNameStart()); // GRECLIPSE end newMethod.setGenericsTypes(method.getGenericsTypes()); - newMethod.putNodeMetaData(DEFAULT_PARAMETER_GENERATED, true); + newMethod.putNodeMetaData(DEFAULT_PARAMETER_GENERATED, Boolean.TRUE); } }); } @@ -882,6 +882,13 @@ public void call(ArgumentListExpression arguments, Parameter[] newParams, Method ConstructorCallExpression expression = new ConstructorCallExpression(ClassNode.THIS, arguments); Statement code = new ExpressionStatement(expression); addConstructor(newParams, ctor, code, node); + // GRECLIPSE add + ctor = DefaultGroovyMethods.last(node.getDeclaredConstructors()); + ctor.setOriginal(method); + ctor.setNameEnd(method.getNameEnd()); + ctor.setNameStart(method.getNameStart()); + ctor.putNodeMetaData(DEFAULT_PARAMETER_GENERATED, Boolean.TRUE); + // GRECLIPSE end } }); } diff --git a/base/org.eclipse.jdt.groovy.core/src/org/eclipse/jdt/groovy/search/ConstructorReferenceSearchRequestor.java b/base/org.eclipse.jdt.groovy.core/src/org/eclipse/jdt/groovy/search/ConstructorReferenceSearchRequestor.java index f1395e9fda..2aa9dd1b90 100644 --- a/base/org.eclipse.jdt.groovy.core/src/org/eclipse/jdt/groovy/search/ConstructorReferenceSearchRequestor.java +++ b/base/org.eclipse.jdt.groovy.core/src/org/eclipse/jdt/groovy/search/ConstructorReferenceSearchRequestor.java @@ -19,6 +19,7 @@ import java.util.function.Function; import org.codehaus.groovy.ast.ASTNode; +import org.codehaus.groovy.ast.AnnotatedNode; import org.codehaus.groovy.ast.ClassHelper; import org.codehaus.groovy.ast.ClassNode; import org.codehaus.groovy.ast.ConstructorNode; @@ -88,7 +89,7 @@ public ConstructorReferenceSearchRequestor(ConstructorPattern pattern, SearchReq @Override public VisitStatus acceptASTNode(ASTNode node, TypeLookupResult result, IJavaElement enclosingElement) { - if (node.getEnd() > 0 && result.declaration instanceof ConstructorNode) { + if (node instanceof AnnotatedNode && ((AnnotatedNode) node).getNameEnd() > 0 && result.declaration instanceof ConstructorNode) { if (findDeclarations && node instanceof ConstructorNode) { ConstructorNode decl = (ConstructorNode) node; @@ -102,7 +103,7 @@ public VisitStatus acceptASTNode(ASTNode node, TypeLookupResult result, IJavaEle if (findReferences && node instanceof ConstructorCallExpression) { ConstructorCallExpression call = (ConstructorCallExpression) node; String typeName = result.declaringType.getName().replace('$', '.'); - Parameter[] parameters = ((ConstructorNode) result.declaration).getParameters(); + Parameter[] parameters = ((ConstructorNode) result.declaration).getOriginal().getParameters(); if (typeName.equals(declaringQualifiedName) && hasMatchingParameters(parameters)) { reportSearchMatch(enclosingElement, element -> { boolean isConstructor = true, isSynthetic = false, isSuperInvocation = call.isSuperCall(), isWithinComment = false;