diff --git a/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/MockPossibleMatch.java b/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/MockPossibleMatch.java index 4dc9fff786..a0e3bbc294 100644 --- a/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/MockPossibleMatch.java +++ b/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/MockPossibleMatch.java @@ -1,5 +1,5 @@ /* - * Copyright 2009-2019 the original author or authors. + * Copyright 2009-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,23 +16,22 @@ package org.eclipse.jdt.core.groovy.tests; import org.codehaus.jdt.groovy.model.GroovyCompilationUnit; +import org.eclipse.jdt.core.search.SearchEngine; import org.eclipse.jdt.core.search.SearchMatch; import org.eclipse.jdt.internal.core.search.JavaSearchDocument; -import org.eclipse.jdt.internal.core.search.JavaSearchParticipant; import org.eclipse.jdt.internal.core.search.matching.PossibleMatch; public class MockPossibleMatch extends PossibleMatch { - public MockPossibleMatch(GroovyCompilationUnit unit) { - super(null, unit.getResource(), unit, new JavaSearchDocument(unit.getResource().getFullPath().toPortableString(), new JavaSearchParticipant()), false); + public MockPossibleMatch(final GroovyCompilationUnit unit) { + super(null, unit.getResource(), unit, new JavaSearchDocument(unit.getResource().getFullPath().toPortableString(), SearchEngine.getDefaultSearchParticipant()), false); } - public static String printMatch(SearchMatch match) { - return "Match at: (" + match.getOffset() + ", " + match.getLength() + ")," + - " accuracy: " + accuracy(match) + "\n Matched object: " + match.getElement() + "\n"; + public static String printMatch(final SearchMatch match) { + return "Match at: (" + match.getOffset() + ", " + match.getLength() + ")," + " accuracy: " + accuracy(match) + "\n Matched object: " + match.getElement() + "\n"; } - public static String accuracy(SearchMatch match) { - return match.getAccuracy() == SearchMatch.A_ACCURATE ? "ACCURATE" : "INACCURATE"; + public static String accuracy(final SearchMatch match) { + return (match.getAccuracy() == SearchMatch.A_ACCURATE ? "ACCURATE" : "INACCURATE"); } } 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 2acf43df9d..6b613d52d0 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 @@ -261,37 +261,60 @@ public void testConstructorReferences10() throws Exception { 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(int i=42) {}\n" + // search for this " Foo(String s) {}\n" + "}"); createUnit("", "Bar", "import p.Foo\n" + - "new Foo()\n" + // yes + "new Foo()\n" + // no "new Foo(0)\n" + // yes "new Foo('')\n"); // no - long ctorRefs = searchForReferences(foo.getType("Foo").getMethods()[0]).stream() - .filter(match -> ((IMethod) match.getElement()).getResource().getName().equals("Bar.groovy")) - .count(); - assertEquals(2, ctorRefs); + List ctorRefs = searchForReferences(foo.getType("Foo").getMethods()[0]); + + assertEquals(1, ctorRefs.size()); + assertEquals(27, ctorRefs.get(0).getOffset()); + assertEquals(SearchMatch.A_ACCURATE, ctorRefs.get(0).getAccuracy()); } - @Test // same-unit references exercise patch in Verifier.addDefaultParameterConstructors + @Test // default value generates a synthetic constructor public void testConstructorReferences11a() 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 + " Foo(int i=42) {}\n" + // search for this + " Foo(String s) {}\n" + + "}"); + createUnit("", "Bar", "import p.Foo\n" + + "new Foo()\n" + // yes + "new Foo(0)\n" + // no + "new Foo('')\n"); // no + + List ctorRefs = searchForReferences(foo.getType("Foo").getMethods()[1]); + + assertEquals(1, ctorRefs.size()); + assertEquals(17, ctorRefs.get(0).getOffset()); + assertEquals(SearchMatch.A_ACCURATE, ctorRefs.get(0).getAccuracy()); + } + + @Test // same-unit references exercise patch in Verifier.addDefaultParameterConstructors + public void testConstructorReferences11b() throws Exception { + GroovyCompilationUnit foo = createUnit("p", "Foo", "package p\n" + + "class Foo {\n" + + " Foo(int i=42) {}\n" + // search for this + " Foo(String s) {this(666)}\n" + // yes " def m() {\n" + - " new Foo()\n" + // yes + " new Foo()\n" + // no " 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); + List ctorRefs = searchForReferences(foo.getType("Foo").getMethods()[0]); + + assertEquals(2, ctorRefs.size()); + assertEquals(58, ctorRefs.get(0).getOffset()); + assertEquals(SearchMatch.A_ACCURATE, ctorRefs.get(0).getAccuracy()); + assertEquals(103, ctorRefs.get(1).getOffset()); + assertEquals(SearchMatch.A_ACCURATE, ctorRefs.get(1).getAccuracy()); } @Test // default value generates a synthetic constructor @@ -302,33 +325,56 @@ public void testConstructorReferences12() throws Exception { " Foo(String s = '') {}\n" + // search for this "}"); createUnit("", "Bar", "import p.Foo\n" + - "new Foo()\n" + // yes + "new Foo()\n" + // no "new Foo(0)\n" + // no "new Foo('')\n"); // yes - long ctorRefs = searchForReferences(foo.getType("Foo").getMethods()[1]).stream() - .filter(match -> ((IMethod) match.getElement()).getResource().getName().equals("Bar.groovy")) - .count(); - assertEquals(2, ctorRefs); + List ctorRefs = searchForReferences(foo.getType("Foo").getMethods()[1]); + + assertEquals(1, ctorRefs.size()); + assertEquals(38, ctorRefs.get(0).getOffset()); + assertEquals(SearchMatch.A_ACCURATE, ctorRefs.get(0).getAccuracy()); } - @Test // same-unit references exercise patch in Verifier.addDefaultParameterConstructors + @Test // default value generates a synthetic constructor public void testConstructorReferences12a() throws Exception { GroovyCompilationUnit foo = createUnit("p", "Foo", "package p\n" + "class Foo {\n" + - " Foo(int i) {this()}\n" + // yes + " Foo(int i) {}\n" + + " Foo(String s = '') {}\n" + // search for this + "}"); + createUnit("", "Bar", "import p.Foo\n" + + "new Foo()\n" + // yes + "new Foo(0)\n" + // no + "new Foo('')\n"); // no + + List ctorRefs = searchForReferences(foo.getType("Foo").getMethods()[2]); + + assertEquals(1, ctorRefs.size()); + assertEquals(17, ctorRefs.get(0).getOffset()); + assertEquals(SearchMatch.A_ACCURATE, ctorRefs.get(0).getAccuracy()); + } + + @Test // same-unit references exercise patch in Verifier.addDefaultParameterConstructors + public void testConstructorReferences12b() throws Exception { + GroovyCompilationUnit foo = createUnit("p", "Foo", "package p\n" + + "class Foo {\n" + + " Foo(int i) {this('xxx')}\n" + // yes " Foo(String s = '') {}\n" + // search for this " def m() {\n" + - " new Foo()\n" + // yes + " new Foo()\n" + // no " 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 ctorRefs = searchForReferences(foo.getType("Foo").getMethods()[1]); + + assertEquals(2, ctorRefs.size()); + assertEquals(36, ctorRefs.get(0).getOffset()); + assertEquals(SearchMatch.A_ACCURATE, ctorRefs.get(0).getAccuracy()); + assertEquals(122, ctorRefs.get(1).getOffset()); + assertEquals(SearchMatch.A_ACCURATE, ctorRefs.get(1).getAccuracy()); } @Test diff --git a/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/search/MethodReferenceSearchTests.java b/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/search/MethodReferenceSearchTests.java index 52d124ae51..09b68fe0a6 100644 --- a/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/search/MethodReferenceSearchTests.java +++ b/base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/search/MethodReferenceSearchTests.java @@ -315,50 +315,86 @@ public void testOverloadedMethodReferences5b() throws Exception { @Test public void testMethodWithDefaultParameters1() throws Exception { - doTestForTwoMethodReferences( - "class First {\n" + - " void xxx(a, b = 9) {}\n" + - " void xxx(a, b, c) {}\n" + - "}\n", - "class Second {\n" + - " void other0() {\n" + - " First f\n" + - " f.xxx(a)\n" + - " }\n" + - " void other1() {\n" + - " First f\n" + - " f.xxx(a,b,c)\n" + - " }\n" + - " void other2() {\n" + - " First f\n" + - " f.xxx(a,b)\n" + - " }\n" + - "}\n", - false, 0, "xxx"); + GroovyCompilationUnit groovyUnit = createUnit("foo", "Bar", + "package foo\n" + + "class Bar {\n" + + " def xxx(a, b='') {}\n" + + " def xxx(a, b, c) {}\n" + + "}\n"); + createUnit("foo", "Baz", + "package foo\n" + + "class Baz {\n" + + " void m1(Bar bar) {\n" + + " bar.xxx(a)\n" + //no! + " }\n" + + " void m2(Bar bar) {\n" + + " bar.xxx(a,b)\n" + //yes + " }\n" + + " void m3(Bar bar) {\n" + + " bar.xxx(a,b,c)\n" + //no! + " }\n" + + " void m4(Bar bar) {\n" + + " def x = bar.&xxx\n" + //yes-ish + " }\n" + + "}\n"); + + IMethod method = groovyUnit.getType("Bar").getMethods()[0]; + new SearchEngine().search( + SearchPattern.createPattern(method, IJavaSearchConstants.REFERENCES), + new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}, + SearchEngine.createJavaSearchScope(new IJavaElement[] {groovyUnit.getPackageFragmentRoot()}, false), + searchRequestor, new NullProgressMonitor()); + List matches = searchRequestor.getMatches(); + + assertEquals(2, matches.size()); + assertEquals(SearchMatch.A_ACCURATE, matches.get(0).getAccuracy()); + assertEquals("m2", ((IJavaElement) matches.get(0).getElement()).getElementName()); + assertEquals("Baz.groovy", ((IJavaElement) matches.get(0).getElement()).getResource().getName()); + assertEquals(SearchMatch.A_INACCURATE, matches.get(1).getAccuracy()); + assertEquals("m4", ((IJavaElement) matches.get(1).getElement()).getElementName()); + assertEquals("Baz.groovy", ((IJavaElement) matches.get(1).getElement()).getResource().getName()); } @Test public void testMethodWithDefaultParameters2() throws Exception { - doTestForTwoMethodReferences( - "class First {\n" + - " void xxx(a, b = 9) {}\n" + - " void xxx(a, b, c) {}\n" + - "}\n", - "class Second {\n" + - " void other0() {\n" + - " First f\n" + - " f.xxx(a)\n" + - " }\n" + - " void other1() {\n" + - " First f\n" + - " f.xxx(a,b,c)\n" + - " }\n" + - " void other2() {\n" + - " First f\n" + - " f.&xxx\n" + - " }\n" + - "}\n", - false, 0, "xxx"); + GroovyCompilationUnit groovyUnit = createUnit("foo", "Bar", + "package foo\n" + + "class Bar {\n" + + " def xxx(a, b='') {}\n" + + " def xxx(a, b, c) {}\n" + + "}\n"); + createUnit("foo", "Baz", + "package foo\n" + + "class Baz {\n" + + " void m1(Bar bar) {\n" + + " bar.xxx(a)\n" + //yes + " }\n" + + " void m2(Bar bar) {\n" + + " bar.xxx(a,b)\n" + //no! + " }\n" + + " void m3(Bar bar) {\n" + + " bar.xxx(a,b,c)\n" + //no! + " }\n" + + " void m4(Bar bar) {\n" + + " def x = bar.&xxx\n" + //yes-ish + " }\n" + + "}\n"); + + IMethod method = groovyUnit.getType("Bar").getMethods()[1]; + new SearchEngine().search( + SearchPattern.createPattern(method, IJavaSearchConstants.REFERENCES), + new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}, + SearchEngine.createJavaSearchScope(new IJavaElement[] {groovyUnit.getPackageFragmentRoot()}, false), + searchRequestor, new NullProgressMonitor()); + List matches = searchRequestor.getMatches(); + + assertEquals(2, matches.size()); + assertEquals(SearchMatch.A_ACCURATE, matches.get(0).getAccuracy()); + assertEquals("m1", ((IJavaElement) matches.get(0).getElement()).getElementName()); + assertEquals("Baz.groovy", ((IJavaElement) matches.get(0).getElement()).getResource().getName()); + assertEquals(SearchMatch.A_INACCURATE, matches.get(1).getAccuracy()); + assertEquals("m4", ((IJavaElement) matches.get(1).getElement()).getElementName()); + assertEquals("Baz.groovy", ((IJavaElement) matches.get(1).getElement()).getResource().getName()); } @Test @@ -366,50 +402,65 @@ public void testMethodWithDefaultParameters3() throws Exception { GroovyCompilationUnit groovyUnit = createUnit("foo", "Bar", "package foo\n" + "class Bar {\n" + - " void doSomething() {}\n" + - " void doSomething(String one, String two = 'x') {}\n" + + " def xxx(a, b='') {}\n" + + " def xxx(a, b, c) {}\n" + "}\n"); - createUnit("foo", "Baz", + createJavaUnit("foo", "Baz", "package foo;\n" + - "public class Baz {\n" + - " void test(Bar bar) {\n" + - " bar.doSomething();\n" + //no! - " bar.doSomething(\"one\");\n" + //yes - " bar.doSomething(\"one\", \"two\");\n" + //yes + "class Baz {\n" + + " void m1(Bar bar) {\n" + + " bar.xxx(null);\n" + //no! + " }\n" + + " void m2(Bar bar) {\n" + + " bar.xxx(null,null);\n" + //yes + " }\n" + + " void m3(Bar bar) {\n" + + " bar.xxx(null,null,null);\n" + //no! + " }\n" + + " void m4(Bar bar) {\n" + + " java.util.function.BiFunction x = bar::xxx;\n" + //yes " }\n" + "}\n"); - IMethod method = groovyUnit.getType("Bar").getMethods()[1]; + IMethod method = groovyUnit.getType("Bar").getMethods()[0]; new SearchEngine().search( SearchPattern.createPattern(method, IJavaSearchConstants.REFERENCES), new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}, SearchEngine.createJavaSearchScope(new IJavaElement[] {groovyUnit.getPackageFragmentRoot()}, false), searchRequestor, new NullProgressMonitor()); - List matches = searchRequestor.getMatches(); assertEquals(2, matches.size()); assertEquals(SearchMatch.A_ACCURATE, matches.get(0).getAccuracy()); - assertEquals("Baz.groovy", ((IJavaElement) matches.get(0).getElement()).getResource().getName()); + assertEquals("m2", ((IJavaElement) matches.get(0).getElement()).getElementName()); + assertEquals("Baz.java", ((IJavaElement) matches.get(0).getElement()).getResource().getName()); assertEquals(SearchMatch.A_ACCURATE, matches.get(1).getAccuracy()); - assertEquals("Baz.groovy", ((IJavaElement) matches.get(1).getElement()).getResource().getName()); + assertEquals("m4", ((IJavaElement) matches.get(1).getElement()).getElementName()); + assertEquals("Baz.java", ((IJavaElement) matches.get(1).getElement()).getResource().getName()); } - @Test @Ignore("Only one method signature is searched and Java lacks link to original method") + @Test public void testMethodWithDefaultParameters4() throws Exception { GroovyCompilationUnit groovyUnit = createUnit("foo", "Bar", "package foo\n" + "class Bar {\n" + - " void doSomething() {}\n" + - " void doSomething(String one, String two = 'x') {}\n" + + " def xxx(a, b='') {}\n" + + " def xxx(a, b, c) {}\n" + "}\n"); createJavaUnit("foo", "Baz", "package foo;\n" + - "public class Baz {\n" + - " void test(Bar bar) {\n" + - " bar.doSomething();\n" + //no! - " bar.doSomething(\"one\");\n" + //no! (want to be yes) - " bar.doSomething(\"one\", \"two\");\n" + //yes + "class Baz {\n" + + " void m1(Bar bar) {\n" + + " bar.xxx(null);\n" + //yes + " }\n" + + " void m2(Bar bar) {\n" + + " bar.xxx(null,null);\n" + //no! + " }\n" + + " void m3(Bar bar) {\n" + + " bar.xxx(null,null,null);\n" + //no! + " }\n" + + " void m4(Bar bar) {\n" + + " java.util.function.Function x = bar::xxx;\n" + //yes " }\n" + "}\n"); @@ -419,13 +470,14 @@ public void testMethodWithDefaultParameters4() throws Exception { new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}, SearchEngine.createJavaSearchScope(new IJavaElement[] {groovyUnit.getPackageFragmentRoot()}, false), searchRequestor, new NullProgressMonitor()); - List matches = searchRequestor.getMatches(); assertEquals(2, matches.size()); assertEquals(SearchMatch.A_ACCURATE, matches.get(0).getAccuracy()); + assertEquals("m1", ((IJavaElement) matches.get(0).getElement()).getElementName()); assertEquals("Baz.java", ((IJavaElement) matches.get(0).getElement()).getResource().getName()); assertEquals(SearchMatch.A_ACCURATE, matches.get(1).getAccuracy()); + assertEquals("m4", ((IJavaElement) matches.get(1).getElement()).getElementName()); assertEquals("Baz.java", ((IJavaElement) matches.get(1).getElement()).getResource().getName()); } 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 2aa9dd1b90..488bf16d22 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 @@ -1,11 +1,11 @@ /* - * Copyright 2009-2018 the original author or authors. + * Copyright 2009-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -103,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).getOriginal().getParameters(); + Parameter[] parameters = ((ConstructorNode) result.declaration).getParameters(); if (typeName.equals(declaringQualifiedName) && hasMatchingParameters(parameters)) { reportSearchMatch(enclosingElement, element -> { boolean isConstructor = true, isSynthetic = false, isSuperInvocation = call.isSuperCall(), isWithinComment = false; diff --git a/base/org.eclipse.jdt.groovy.core/src/org/eclipse/jdt/groovy/search/MethodReferenceSearchRequestor.java b/base/org.eclipse.jdt.groovy.core/src/org/eclipse/jdt/groovy/search/MethodReferenceSearchRequestor.java index 290db2fd1c..f7718fc1a3 100644 --- a/base/org.eclipse.jdt.groovy.core/src/org/eclipse/jdt/groovy/search/MethodReferenceSearchRequestor.java +++ b/base/org.eclipse.jdt.groovy.core/src/org/eclipse/jdt/groovy/search/MethodReferenceSearchRequestor.java @@ -314,7 +314,7 @@ private boolean declaringTypeMatches(ClassNode declaringType) { } private boolean parameterTypesMatch(MethodNode methodNode) { - Parameter[] parameters = methodNode.getOriginal().getParameters(); + Parameter[] parameters = methodNode.getParameters(); List parameterTypes = GroovyUtils.getParameterTypes(parameters); int n; if ((n = parameterTypes.size()) != parameterTypeSignatures.length) { return false; 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 c6e7366a8d..7eb541b880 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 @@ -711,6 +711,8 @@ private void visitAnnotationKeys(final AnnotationNode node) { } noLookup.enclosingAnnotation = node; // set context for requestor VisitStatus status = notifyRequestor(attr, requestor, noLookup); + + if (status == VisitStatus.STOP_VISIT) throw new VisitCompleted(status); if (status != VisitStatus.CONTINUE) break; } } diff --git a/ide-test/org.codehaus.groovy.eclipse.codebrowsing.test/src/org/codehaus/groovy/eclipse/codebrowsing/tests/BrowsingTestSuite.groovy b/ide-test/org.codehaus.groovy.eclipse.codebrowsing.test/src/org/codehaus/groovy/eclipse/codebrowsing/tests/BrowsingTestSuite.groovy index 7842c2e861..63bde3cb37 100644 --- a/ide-test/org.codehaus.groovy.eclipse.codebrowsing.test/src/org/codehaus/groovy/eclipse/codebrowsing/tests/BrowsingTestSuite.groovy +++ b/ide-test/org.codehaus.groovy.eclipse.codebrowsing.test/src/org/codehaus/groovy/eclipse/codebrowsing/tests/BrowsingTestSuite.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2009-2019 the original author or authors. + * Copyright 2009-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,8 +15,6 @@ */ package org.codehaus.groovy.eclipse.codebrowsing.tests -import static org.junit.Assert.* - import org.codehaus.groovy.eclipse.test.GroovyEclipseTestSuite import org.codehaus.jdt.groovy.model.GroovyCompilationUnit import org.eclipse.jdt.core.ICompilationUnit @@ -25,8 +23,8 @@ import org.eclipse.jdt.core.SourceRange abstract class BrowsingTestSuite extends GroovyEclipseTestSuite { - protected IJavaElement assertCodeSelect(Iterable sources, String target, String elementName = target) { - def unit = null + protected IJavaElement assertCodeSelect(final Iterable sources, final String target, final String elementName = target) { + GroovyCompilationUnit unit = null sources.each { unit = addGroovySource(it.toString(), nextUnitName()) } @@ -35,37 +33,39 @@ abstract class BrowsingTestSuite extends GroovyEclipseTestSuite { int offset = unit.source.lastIndexOf(target), length = target.length() assert offset >= 0 && length > 0 && offset + length <= unit.source.length() - IJavaElement[] elems = unit.codeSelect(offset, length) + IJavaElement[] elements = unit.codeSelect(offset, length) if (!elementName) { - assertEquals(0, elems.length) + assert elements.length == 0 } else { - assertEquals('Should have found a selection', 1, elems.length) - assertEquals('Should have found reference to: ' + elementName, elementName, elems[0].elementName) - assertTrue('Element should have existed in the model', elems[0].exists()) - return elems[0] + assert elements.length == 1 : 'Should have found a selection' + + assert elements[0].elementName == elementName : "Should have found reference to: $elementName" + assert elements[0].exists() : 'Element should exist in the model' + return elements[0] } } - protected IJavaElement assertCodeSelect(CharSequence source, SourceRange targetRange, String elementName) { - GroovyCompilationUnit gunit = addGroovySource(source, nextUnitName()) - prepareForCodeSelect(gunit) + protected IJavaElement assertCodeSelect(final CharSequence source, final SourceRange targetRange, final String elementName) { + GroovyCompilationUnit unit = addGroovySource(source, nextUnitName()) + prepareForCodeSelect(unit) - IJavaElement[] elems = gunit.codeSelect(targetRange.offset, targetRange.length) + IJavaElement[] elements = unit.codeSelect(targetRange.offset, targetRange.length) if (!elementName) { - assertEquals(0, elems.length) + assert elements.length == 0 } else { - assertEquals('Should have found a selection', 1, elems.length) - assertEquals('Should have found reference to: ' + elementName, elementName, elems[0].elementName) - assertTrue(elems[0].exists()) - return elems[0] + assert elements.length == 1 : 'Should have found a selection' + + assert elements[0].elementName == elementName : "Should have found reference to: $elementName" + assert elements[0].exists() : 'Element should exist in the model' + return elements[0] } } - protected void prepareForCodeSelect(ICompilationUnit unit) { + protected void prepareForCodeSelect(final ICompilationUnit unit) { openInEditor(unit) if (unit instanceof GroovyCompilationUnit) { def problems = unit.getModuleInfo(true).result.problems - problems?.findAll { it.error }?.each { println it } + problems?.each { if (it.error) println it } } } } diff --git a/ide-test/org.codehaus.groovy.eclipse.codebrowsing.test/src/org/codehaus/groovy/eclipse/codebrowsing/tests/CodeSelectMethodsTests.groovy b/ide-test/org.codehaus.groovy.eclipse.codebrowsing.test/src/org/codehaus/groovy/eclipse/codebrowsing/tests/CodeSelectMethodsTests.groovy index f4b705a807..6d73a3871b 100644 --- a/ide-test/org.codehaus.groovy.eclipse.codebrowsing.test/src/org/codehaus/groovy/eclipse/codebrowsing/tests/CodeSelectMethodsTests.groovy +++ b/ide-test/org.codehaus.groovy.eclipse.codebrowsing.test/src/org/codehaus/groovy/eclipse/codebrowsing/tests/CodeSelectMethodsTests.groovy @@ -26,39 +26,63 @@ import org.junit.Test final class CodeSelectMethodsTests extends BrowsingTestSuite { + private IMethod assertConstructor(final CharSequence contents, final String toSearch) { + def unit = addGroovySource(contents, nextUnitName(), 'p') + prepareForCodeSelect(unit) + + IJavaElement[] elements = unit.codeSelect(unit.source.lastIndexOf(toSearch), toSearch.length()) + assert elements.length == 1 : 'Should have found a selection' + + String elementName = toSearch.substring(toSearch.lastIndexOf((int) '.') + 1) + assert elements[0].elementName == elementName : "Should have found constructor '$elementName'" + assert elements[0].isConstructor() : 'Should be a constructor' + return elements[0] + } + @Test void testCodeSelectDefaultParams1() { - String one = 'class Structure {\n def meth(int a, int b = 9, int c=8) {}\n}' - String two = 'class Java { { new Structure().meth(0, 0, 0); } }' - assertCodeSelect([one, two, 'new Structure().meth(0)'], 'meth') + String one = 'class One {\n def m(int a, int b = 1, int c = 2) {}\n}' + String two = 'class Two {\n {\n\tnew One().m(0, 0, 0)\n }\n}' + assertCodeSelect([one, two], 'm') } @Test void testCodeSelectDefaultParams2() { - String one = 'class Structure {\n def meth(int a, int b = 9, int c=8) {}\n}' - String two = 'class Java { { new Structure().meth(0); } }' - assertCodeSelect([one, two, 'new Structure().meth(0)'], 'meth') + String one = 'class One {\n def m(int a, int b = 1, int c = 2) {}\n}' + String two = 'class Two {\n {\n\tnew One().m(0, 0)\n }\n}' + assertCodeSelect([one, two], 'm') } @Test void testCodeSelectDefaultParams3() { - String one = 'class Structure {\n def meth(int a, int b = 9, int c=8) {}\n}' - String two = 'class Java { { new Structure().meth(0, 0); } }' - assertCodeSelect([one, two, 'new Structure().meth(0, 0)'], 'meth') + String one = 'class One {\n def m(int a, int b = 1, int c = 2) {}\n}' + String two = 'class Two {\n {\n\tnew One().m(0)\n }\n}' + assertCodeSelect([one, two], 'm') } - @Test + @Test // https://github.com/groovy/groovy-eclipse/issues/794 void testCodeSelectDefaultParams4() { - String one = 'class Structure {\n def meth(int a, int b = 9, int c=8) {}\n}' - String two = 'class Java { { new Structure().meth(0, 0, 0); } }' - assertCodeSelect([one, two, 'new Structure().meth(0, 0, 0)'], 'meth') + def unit = addGroovySource('class C {\n def m(a, b = 1, c = 2) {}\n}', nextUnitName(), 'p') + prepareForCodeSelect(unit) + + IJavaElement[] elements = unit.codeSelect(unit.source.lastIndexOf((int) 'm'), 1) + assert elements.length == 3 : 'Should have found three choices' + } + + @Test // https://github.com/groovy/groovy-eclipse/issues/794 + void testCodeSelectDefaultParams5() { + def unit = addGroovySource('class C {\n C(a, b = 1, c = 2) {}\n}', nextUnitName(), 'p') + prepareForCodeSelect(unit) + + IJavaElement[] elements = unit.codeSelect(unit.source.lastIndexOf((int) 'C'), 1) + assert elements.length == 3 : 'Should have found three choices' } @Test void testCodeSelectClosure() { String contents = 'def x = { t -> print t }\nx("hello")' - IJavaElement elem = assertCodeSelect([contents], 'x') - assert elem.typeSignature =~ 'groovy.lang.Closure' + IJavaElement element = assertCodeSelect([contents], 'x') + assert element.typeSignature =~ 'groovy.lang.Closure' } @Test @@ -125,8 +149,8 @@ final class CodeSelectMethodsTests extends BrowsingTestSuite { |} |'''.stripMargin() - IJavaElement elem = assertCodeSelect([contents1, contents2], 'redirect') - assert elem.declaringType.fullyQualifiedName == 'PlantController' + IJavaElement element = assertCodeSelect([contents1, contents2], 'redirect') + assert element.declaringType.fullyQualifiedName == 'PlantController' } @Test // GRECLIPSE-1755 @@ -156,8 +180,8 @@ final class CodeSelectMethodsTests extends BrowsingTestSuite { |} |'''.stripMargin() - IJavaElement elem = assertCodeSelect([contents1, contents2, contents3, contents4], 'foo') - assert elem.declaringType.fullyQualifiedName == 'SuperInterface' + IJavaElement element = assertCodeSelect([contents1, contents2, contents3, contents4], 'foo') + assert element.declaringType.fullyQualifiedName == 'SuperInterface' } @Test @@ -275,8 +299,8 @@ final class CodeSelectMethodsTests extends BrowsingTestSuite { | } |} |'''.stripMargin() - IJavaElement elem = assertCodeSelect([contents], 'x') - assert elem.declaringType.fullyQualifiedName == 'T' + IJavaElement element = assertCodeSelect([contents], 'x') + assert element.declaringType.fullyQualifiedName == 'T' } @Test // https://github.com/groovy/groovy-eclipse/issues/960 @@ -291,9 +315,9 @@ final class CodeSelectMethodsTests extends BrowsingTestSuite { | } |} |'''.stripMargin() - IJavaElement elem = assertCodeSelect([contents], 'getNumber') - assert elem.declaringType.fullyQualifiedName == 'T' - assert elem.elementInfo.nameSourceStart == contents.indexOf('number') + IJavaElement element = assertCodeSelect([contents], 'getNumber') + assert element.declaringType.fullyQualifiedName == 'T' + assert element.elementInfo.nameSourceStart == contents.indexOf('number') } @Test // https://github.com/groovy/groovy-eclipse/issues/960 @@ -308,9 +332,9 @@ final class CodeSelectMethodsTests extends BrowsingTestSuite { | } |} |'''.stripMargin() - IJavaElement elem = assertCodeSelect([contents], 'setNumber') - assert elem.declaringType.fullyQualifiedName == 'T' - assert elem.elementInfo.nameSourceStart == contents.indexOf('number') + IJavaElement element = assertCodeSelect([contents], 'setNumber') + assert element.declaringType.fullyQualifiedName == 'T' + assert element.elementInfo.nameSourceStart == contents.indexOf('number') } @Test // https://github.com/groovy/groovy-eclipse/issues/960 @@ -325,9 +349,9 @@ final class CodeSelectMethodsTests extends BrowsingTestSuite { | } |} |'''.stripMargin() - IJavaElement elem = assertCodeSelect([contents], 'isCondition') - assert elem.declaringType.fullyQualifiedName == 'T' - assert elem.elementInfo.nameSourceStart == contents.indexOf('condition') + IJavaElement element = assertCodeSelect([contents], 'isCondition') + assert element.declaringType.fullyQualifiedName == 'T' + assert element.elementInfo.nameSourceStart == contents.indexOf('condition') } @Test // https://github.com/groovy/groovy-eclipse/issues/1113 @@ -344,9 +368,9 @@ final class CodeSelectMethodsTests extends BrowsingTestSuite { | } |} |'''.stripMargin() - IJavaElement elem = assertCodeSelect([contents], 'getFoo') - assert elem.declaringType.fullyQualifiedName == 'T' - assert elem.elementInfo.nameSourceStart == 19 + IJavaElement element = assertCodeSelect([contents], 'getFoo') + assert element.declaringType.fullyQualifiedName == 'T' + assert element.elementInfo.nameSourceStart == 19 } @Test @@ -420,16 +444,16 @@ final class CodeSelectMethodsTests extends BrowsingTestSuite { @Test void testCodeSelectStaticMethod1() { String contents = 'class Parent {\n static p() {}\n}\nclass Child extends Parent {\n def c() {\n p()\n }\n}' - IJavaElement elem = assertCodeSelect([contents], 'p') - assert elem.parent.elementName == 'Parent' + IJavaElement element = assertCodeSelect([contents], 'p') + assert element.parent.elementName == 'Parent' } @Test void testCodeSelectStaticMethod2() { String another = 'class Parent {\n static p() {}\n}' String contents = 'class Child extends Parent {\n def c() {\n p()\n }\n}' - IJavaElement elem = assertCodeSelect([another, contents], 'p') - assert elem.parent.elementName == 'Parent' + IJavaElement element = assertCodeSelect([another, contents], 'p') + assert element.parent.elementName == 'Parent' } @Test @@ -441,8 +465,8 @@ final class CodeSelectMethodsTests extends BrowsingTestSuite { @Test void testCodeSelectStaticMethod4() { String contents = 'List empty = Collections.&emptyList' - IJavaElement elem = assertCodeSelect([contents], 'emptyList') - assert elem.inferredElement.returnType.toString(false) == 'java.util.List ' // TODO: want T to be java.lang.String + IJavaElement element = assertCodeSelect([contents], 'emptyList') + assert element.inferredElement.returnType.toString(false) == 'java.util.List ' // TODO: want T to be java.lang.String } @Test @@ -455,8 +479,8 @@ final class CodeSelectMethodsTests extends BrowsingTestSuite { | singletonList("") | } |}'''.stripMargin() - IJavaElement elem = assertCodeSelect([contents], 'singletonList') - assert elem.inferredElement.returnType.toString(false) == 'java.util.List ' + IJavaElement element = assertCodeSelect([contents], 'singletonList') + assert element.inferredElement.returnType.toString(false) == 'java.util.List ' } @Test @@ -468,8 +492,8 @@ final class CodeSelectMethodsTests extends BrowsingTestSuite { |} |Foo.comparatorByNumber() |'''.stripMargin() - IJavaElement elem = assertCodeSelect([contents], 'comparatorByNumber') - assert elem.inferredElement.returnType.toString(false) == 'java.util.Comparator' + IJavaElement element = assertCodeSelect([contents], 'comparatorByNumber') + assert element.inferredElement.returnType.toString(false) == 'java.util.Comparator' } @Test @@ -480,22 +504,22 @@ final class CodeSelectMethodsTests extends BrowsingTestSuite { |} |Foo.getFoo() |'''.stripMargin() - IJavaElement elem = assertCodeSelect([contents], 'getFoo') - assert elem.inferredElement.returnType.toString(false) == 'Foo' + IJavaElement element = assertCodeSelect([contents], 'getFoo') + assert element.inferredElement.returnType.toString(false) == 'Foo' } @Test // GRECLIPSE-831 void testCodeSelectOverloadedMethod1() { String contents = '\"\".substring(0)' - IJavaElement elem = assertCodeSelect([contents], 'substring') - assert elem.parameterTypes.length == 1 : 'Wrong number of parameters to method' + IJavaElement element = assertCodeSelect([contents], 'substring') + assert element.parameterTypes.length == 1 : 'Wrong number of parameters to method' } @Test // GRECLIPSE-831 void testCodeSelectOverloadedMethod2() { String contents = '"".substring(0,1)' - IJavaElement elem = assertCodeSelect([contents], 'substring') - assert elem.parameterTypes.length == 2 : 'Wrong number of parameters to method' + IJavaElement element = assertCodeSelect([contents], 'substring') + assert element.parameterTypes.length == 2 : 'Wrong number of parameters to method' } @Test @@ -564,8 +588,8 @@ final class CodeSelectMethodsTests extends BrowsingTestSuite { |} |'''.stripMargin() - IJavaElement elem = assertCodeSelect([contents], 'compute') - assert elem.sourceRange.offset > 0 + IJavaElement element = assertCodeSelect([contents], 'compute') + assert element.sourceRange.offset > 0 } @Test @@ -641,9 +665,9 @@ final class CodeSelectMethodsTests extends BrowsingTestSuite { @Test void testCodeSelectConstructor() { String contents = 'def x = new java.util.Date()' - IJavaElement elem = assertCodeSelect([contents], 'Date') - assert elem instanceof IMethod : 'Expected method not type' - assert elem.isConstructor() : 'Expected ctor not method' + IJavaElement element = assertCodeSelect([contents], 'Date') + assert element instanceof IMethod : 'Expected method not type' + assert element.isConstructor() : 'Expected ctor not method' // check the preceding elements for selection bleedthrough assertCodeSelect([contents], 'util', 'java.util') @@ -655,24 +679,24 @@ final class CodeSelectMethodsTests extends BrowsingTestSuite { @Test void testCodeSelectNewifyConstructor1() { String contents = 'class Foo { @Newify(Date) def x = Date(123L) }' - IJavaElement elem = assertCodeSelect([contents], 'Date') - assert elem instanceof IMethod : 'Expected method not type' - assert elem.isConstructor() : 'Expected ctor not method' + IJavaElement element = assertCodeSelect([contents], 'Date') + assert element instanceof IMethod : 'Expected method not type' + assert element.isConstructor() : 'Expected ctor not method' } @Test void testCodeSelectNewifyConstructor2() { String contents = 'class Foo { @Newify(Date) def x = Date.new(123L) }' - IJavaElement elem = assertCodeSelect([contents], 'new', 'Date') - assert elem instanceof IMethod : 'Expected method not type' - assert elem.isConstructor() : 'Expected ctor not method' + IJavaElement element = assertCodeSelect([contents], 'new', 'Date') + assert element instanceof IMethod : 'Expected method not type' + assert element.isConstructor() : 'Expected ctor not method' } @Test void testCodeSelectNewifyConstructor2a() { String contents = 'class Foo { @Newify(Date) def x = Date.new(123L) }' - IJavaElement elem = assertCodeSelect([contents], 'Date') - assert elem instanceof IType : 'Expected type not ctor' + IJavaElement element = assertCodeSelect([contents], 'Date') + assert element instanceof IType : 'Expected type not ctor' } @Test @@ -729,9 +753,9 @@ final class CodeSelectMethodsTests extends BrowsingTestSuite { ICompilationUnit unit = addGroovySource('def bean = new Bean(number: 0, string: "")', nextUnitName(), 'p') prepareForCodeSelect(unit) - IJavaElement[] elems = unit.codeSelect(unit.source.lastIndexOf('Bean'), 4) - assert elems[0].elementName == 'Bean' - assert elems[0].elementType == TYPE + IJavaElement[] elements = unit.codeSelect(unit.source.lastIndexOf('Bean'), 4) + assert elements[0].elementName == 'Bean' + assert elements[0].elementType == TYPE } @Test @@ -785,16 +809,4 @@ final class CodeSelectMethodsTests extends BrowsingTestSuite { IMethod method = assertConstructor('new Foo(Bar.CONST)', 'Foo') assert method.parameters.length == 1 : 'Should have found constructor with 1 arg' } - - private IMethod assertConstructor(String contents, String toSearch) { - ICompilationUnit unit = addGroovySource(contents, nextUnitName(), 'p') - prepareForCodeSelect(unit) - - IJavaElement[] elems = unit.codeSelect(unit.source.lastIndexOf(toSearch), toSearch.length()) - assert elems.length == 1 : 'Should have found a selection' - String elementName = toSearch.substring(toSearch.lastIndexOf('.') + 1) - assert elems[0].elementName == elementName : "Should have found constructor '$elementName'" - assert elems[0].isConstructor() : 'Should be a constructor' - return elems[0] - } } diff --git a/ide-test/org.codehaus.groovy.eclipse.core.test/src/org/codehaus/groovy/eclipse/core/test/SyntheticMemberSearchTests.groovy b/ide-test/org.codehaus.groovy.eclipse.core.test/src/org/codehaus/groovy/eclipse/core/test/SyntheticMemberSearchTests.groovy index 134fc0bbc8..a8359dd275 100644 --- a/ide-test/org.codehaus.groovy.eclipse.core.test/src/org/codehaus/groovy/eclipse/core/test/SyntheticMemberSearchTests.groovy +++ b/ide-test/org.codehaus.groovy.eclipse.core.test/src/org/codehaus/groovy/eclipse/core/test/SyntheticMemberSearchTests.groovy @@ -23,7 +23,6 @@ import org.eclipse.jdt.core.search.IJavaSearchConstants import org.eclipse.jdt.core.search.SearchEngine import org.eclipse.jdt.core.search.SearchMatch import org.eclipse.jdt.core.search.SearchParticipant -import org.eclipse.jdt.internal.core.search.JavaSearchParticipant import org.junit.Assert import org.junit.Before import org.junit.Test @@ -249,7 +248,7 @@ final class SyntheticMemberSearchTests extends GroovyEclipseTestSuite { List matches = [] new SyntheticAccessorSearchRequestor().findSyntheticMatches(gType.children.find { it.elementName == 'proper' }, IJavaSearchConstants.DECLARATIONS | IJavaSearchConstants.IGNORE_DECLARING_TYPE | IJavaSearchConstants.IGNORE_RETURN_TYPE, - [new JavaSearchParticipant()] as SearchParticipant[], + [SearchEngine.defaultSearchParticipant] as SearchParticipant[], SearchEngine.createWorkspaceScope(), matches.&add, null) diff --git a/ide-test/org.codehaus.groovy.eclipse.refactoring.test/resources/RenameMethod/testOverload4/in/A.groovy b/ide-test/org.codehaus.groovy.eclipse.refactoring.test/resources/RenameMethod/testOverload4/in/A.groovy new file mode 100644 index 0000000000..83e44b67f1 --- /dev/null +++ b/ide-test/org.codehaus.groovy.eclipse.refactoring.test/resources/RenameMethod/testOverload4/in/A.groovy @@ -0,0 +1,21 @@ +package p + +class A { + def m() { + } + def m(i, j = 1, k = 2) { + } + def n(A a) { + a.m() + a.m(0) + a.m(0,0) + a.m(0,0,0) + a.with { + m() + m(0) + m(0,0) + m(0,0,0) + } + def f = a.&m + } +} diff --git a/ide-test/org.codehaus.groovy.eclipse.refactoring.test/resources/RenameMethod/testOverload4/out/A.groovy b/ide-test/org.codehaus.groovy.eclipse.refactoring.test/resources/RenameMethod/testOverload4/out/A.groovy new file mode 100644 index 0000000000..a47730235b --- /dev/null +++ b/ide-test/org.codehaus.groovy.eclipse.refactoring.test/resources/RenameMethod/testOverload4/out/A.groovy @@ -0,0 +1,21 @@ +package p + +class A { + def m() { + } + def x(i, j = 1, k = 2) { + } + def n(A a) { + a.m() + a.x(0) + a.x(0,0) + a.x(0,0,0) + a.with { + m() + x(0) + x(0,0) + x(0,0,0) + } + def f = a.&x + } +} diff --git a/ide-test/org.codehaus.groovy.eclipse.refactoring.test/src/org/codehaus/groovy/eclipse/refactoring/test/rename/RenameMethodTests.groovy b/ide-test/org.codehaus.groovy.eclipse.refactoring.test/src/org/codehaus/groovy/eclipse/refactoring/test/rename/RenameMethodTests.groovy index f43864f6af..252b074bda 100644 --- a/ide-test/org.codehaus.groovy.eclipse.refactoring.test/src/org/codehaus/groovy/eclipse/refactoring/test/rename/RenameMethodTests.groovy +++ b/ide-test/org.codehaus.groovy.eclipse.refactoring.test/src/org/codehaus/groovy/eclipse/refactoring/test/rename/RenameMethodTests.groovy @@ -249,4 +249,11 @@ final class RenameMethodTests extends RefactoringTestSuite { def status = runTest('A', 'm', 'k', ['Ljava.lang.Object;']) assert status.isOK() : 'rename failed' } + + @Test + void testOverload4() { + // rename single-parameter method 'm' to 'x' + def status = runTest('A', 'm', 'x', ['Ljava.lang.Object;']) + assert status.entries[0].message.startsWith('Found potential matches.') + } } diff --git a/ide/org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/requestor/CodeSelectHelper.java b/ide/org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/requestor/CodeSelectHelper.java index 081071aa8c..75676878ac 100644 --- a/ide/org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/requestor/CodeSelectHelper.java +++ b/ide/org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/requestor/CodeSelectHelper.java @@ -85,11 +85,7 @@ public IJavaElement[] select(final GroovyCompilationUnit unit, int start, int le CodeSelectRequestor requestor = createRequestor(node, region, select, unit); TypeInferencingVisitorWithRequestor visitor = new TypeInferencingVisitorFactory().createVisitor(unit); visitor.visitCompilationUnit(requestor); - - IJavaElement element = requestor.getRequestedElement(); - if (element != null) { - return new IJavaElement[] {element}; - } + return requestor.getRequestedElements(); } } catch (RuntimeException e) { if (event != null) { diff --git a/ide/org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/requestor/CodeSelectRequestor.java b/ide/org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/requestor/CodeSelectRequestor.java index b182d8e39c..10de59a5ae 100644 --- a/ide/org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/requestor/CodeSelectRequestor.java +++ b/ide/org.codehaus.groovy.eclipse.codebrowsing/src/org/codehaus/groovy/eclipse/codebrowsing/requestor/CodeSelectRequestor.java @@ -18,9 +18,11 @@ import static java.beans.Introspector.decapitalize; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Stream; import org.codehaus.groovy.ast.ASTNode; import org.codehaus.groovy.ast.AnnotatedNode; @@ -85,14 +87,14 @@ public class CodeSelectRequestor implements ITypeRequestor { /** The AST node of interest. */ - private final ASTNode nodeToLookFor; + private ASTNode nodeToLookFor; private final Region nodeRegion; private final Region selectRegion; private final GroovyCompilationUnit gunit; private ASTNode requestedNode; - private IJavaElement requestedElement; + private final List requestedElements = new java.util.ArrayList<>(); public CodeSelectRequestor(final ASTNode node, final GroovyCompilationUnit unit) { this(node, null, new Region(Integer.MIN_VALUE, 0), unit); @@ -110,8 +112,12 @@ public ASTNode getRequestedNode() { return requestedNode; } - public IJavaElement getRequestedElement() { - return requestedElement; + public IJavaElement[] getRequestedElements() { + return requestedElements.toArray(new IJavaElement[requestedElements.size()]); + } + + private void putRequestedElement(final IJavaElement requestedElement) { + requestedElements.add(Objects.requireNonNull(requestedElement)); } @Override @@ -202,8 +208,7 @@ private void handleMatch(final TypeLookupResult result, final IJavaElement enclo if (!GroovyUtils.getBaseType(classNode).isGenericsPlaceHolder()) { requestedNode = classNode.redirect(); } else { - requestedElement = findTypeParam( - GroovyUtils.getBaseType(classNode).getUnresolvedName(), enclosingElement); + putRequestedElement(findTypeParam(GroovyUtils.getBaseType(classNode).getUnresolvedName(), enclosingElement)); return; } } else if (requestedNode instanceof ConstructorNode) { @@ -228,7 +233,7 @@ private void handleMatch(final TypeLookupResult result, final IJavaElement enclo if (result.declaration instanceof VariableExpression) { VariableExpression varExp = (VariableExpression) result.declaration; // look in the local scope - requestedElement = createLocalVariable(result, enclosingElement, varExp); + putRequestedElement(createLocalVariable(result, enclosingElement, varExp)); } else if (result.declaration instanceof Parameter) { Parameter param = (Parameter) result.declaration; @@ -239,7 +244,7 @@ private void handleMatch(final TypeLookupResult result, final IJavaElement enclo position = nodeToLookFor.getStart() - 1; } try { - requestedElement = createLocalVariable(result, gunit.getElementAt(position), param); + putRequestedElement(createLocalVariable(result, gunit.getElementAt(position), param)); } catch (JavaModelException e) { Util.log(e, "Problem getting element at " + position + " for file " + gunit.getElementName()); } @@ -249,7 +254,7 @@ private void handleMatch(final TypeLookupResult result, final IJavaElement enclo if (start < until) { String pack = gunit.getSource().substring(start, until); IPackageFragmentRoot root = gunit.getPackageFragmentRoot(); - requestedElement = root.getPackageFragment(pack); + putRequestedElement(root.getPackageFragment(pack)); } } else if (nodeToLookFor instanceof ImportNode && ((ImportNode) nodeToLookFor).isStar() && !((ImportNode) nodeToLookFor).isStatic()) { @@ -259,7 +264,7 @@ private void handleMatch(final TypeLookupResult result, final IJavaElement enclo for (IPackageFragmentRoot root : gunit.getJavaProject().getPackageFragmentRoots()) { IPackageFragment fragment = root.getPackageFragment(pack); if (fragment != null && fragment.exists()) { - requestedElement = fragment; + putRequestedElement(fragment); break; } } @@ -288,12 +293,12 @@ private void handleMatch(final TypeLookupResult result, final IJavaElement enclo // find the requested java element IJavaElement maybeRequested = findRequestedElement(result.declaration, declaringType, type); // try to resolve the type of the requested element; this will add the proper metadata to the hover - requestedElement = resolveRequestedElement(maybeRequested, result); + putRequestedElement(resolveRequestedElement(maybeRequested, result)); } else { // try to resolve as a type (outer class) then as a package IType candidate = gunit.getJavaProject().findType(qualifier); if (candidate != null) { - requestedElement = candidate; + putRequestedElement(candidate); } else { IPackageFragmentRoot root; if (type instanceof BinaryType) { @@ -301,7 +306,7 @@ private void handleMatch(final TypeLookupResult result, final IJavaElement enclo } else { root = (IPackageFragmentRoot) ((SourceType) type).getPackageFragment().getParent(); } - requestedElement = root.getPackageFragment(qualifier); + putRequestedElement(root.getPackageFragment(qualifier)); } requestedNode = nodeToLookFor; } @@ -316,6 +321,36 @@ private void handleMatch(final TypeLookupResult result, final IJavaElement enclo } } } + + // + + if (nodeToLookFor instanceof MethodNode && ((MethodNode) nodeToLookFor).hasDefaultValue()) { + final ASTNode ntlf = nodeToLookFor, rn = requestedNode; + try { + Stream nodes; + if (nodeToLookFor instanceof ConstructorNode) { + nodes = result.declaringType.getDeclaredConstructors().stream().filter(cn -> cn != ntlf && cn.getOriginal() == ntlf); + } else { + String methodName = ((MethodNode) nodeToLookFor).getName(); + nodes = result.declaringType.getDeclaredMethods(methodName).stream().filter(mn -> mn != ntlf && mn.getOriginal() == ntlf); + } + + // find java elements for each generated method variant + for (TypeLookupResult tlr : nodes.map(mn -> { + TypeLookupResult tlr = new TypeLookupResult(result.type, result.declaringType, mn, result.confidence, result.scope); + tlr.enclosingAnnotation = result.enclosingAnnotation; + tlr.enclosingAssignment = result.enclosingAssignment; + tlr.isGroovy = result.isGroovy; + return tlr; + }).toArray(TypeLookupResult[]::new)) { + nodeToLookFor = tlr.declaration; + handleMatch(tlr, enclosingElement); + } + } finally { + nodeToLookFor = ntlf; + requestedNode = rn; + } + } } private LocalVariable createLocalVariable(final TypeLookupResult result, final IJavaElement enclosingElement, final Variable var) { @@ -508,7 +543,7 @@ else if (existsOnlyInGroovyModel(node.getField(), name, declaringType, jdtDeclar Parameter[] parameters = null; if (declaration instanceof MethodNode) { name = ((MethodNode) declaration).getName(); - parameters = ((MethodNode) declaration).getOriginal().getParameters(); + parameters = ((MethodNode) declaration).getParameters(); } maybeRequested = findElement(jdtDeclaringType, name, parameters); } @@ -628,8 +663,7 @@ private IJavaElement resolveRequestedElement(final IJavaElement maybeRequested, default: candidate = maybeRequested; } - requestedElement = candidate; - return requestedElement; + return candidate; } //-------------------------------------------------------------------------- diff --git a/ide/org.codehaus.groovy.eclipse.core/src/org/codehaus/groovy/eclipse/core/search/SyntheticAccessorSearchRequestor.java b/ide/org.codehaus.groovy.eclipse.core/src/org/codehaus/groovy/eclipse/core/search/SyntheticAccessorSearchRequestor.java index 785c88944f..0614c10800 100644 --- a/ide/org.codehaus.groovy.eclipse.core/src/org/codehaus/groovy/eclipse/core/search/SyntheticAccessorSearchRequestor.java +++ b/ide/org.codehaus.groovy.eclipse.core/src/org/codehaus/groovy/eclipse/core/search/SyntheticAccessorSearchRequestor.java @@ -40,7 +40,6 @@ import org.eclipse.jdt.core.search.SearchParticipant; import org.eclipse.jdt.core.search.SearchPattern; import org.eclipse.jdt.core.search.SearchRequestor; -import org.eclipse.jdt.internal.core.search.JavaSearchParticipant; /** * Java search requestor that finds synthetic accessors. That is, searching for @@ -49,7 +48,7 @@ public class SyntheticAccessorSearchRequestor { public void findSyntheticMatches(IJavaElement element, ISearchRequestor requestor, IProgressMonitor monitor) throws CoreException { - findSyntheticMatches(element, IJavaSearchConstants.REFERENCES, new SearchParticipant[] {new JavaSearchParticipant()}, SearchEngine.createWorkspaceScope(), requestor, monitor); + findSyntheticMatches(element, IJavaSearchConstants.REFERENCES, new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}, SearchEngine.createWorkspaceScope(), requestor, monitor); } public void findSyntheticMatches(IJavaElement element, int limitTo, SearchParticipant[] participants, IJavaSearchScope scope, final ISearchRequestor requestor, IProgressMonitor monitor) throws CoreException { diff --git a/ide/org.codehaus.groovy.eclipse.refactoring/plugin.xml b/ide/org.codehaus.groovy.eclipse.refactoring/plugin.xml index 95e4b3c313..b2cf68cb47 100644 --- a/ide/org.codehaus.groovy.eclipse.refactoring/plugin.xml +++ b/ide/org.codehaus.groovy.eclipse.refactoring/plugin.xml @@ -114,9 +114,24 @@ + class="org.codehaus.groovy.eclipse.refactoring.core.rename.MethodVariantRenameParticipant" + id="org.codehaus.groovy.eclipse.refactoring.methodVariantRenameParticipant" + name="Groovy method variant participant"> + + + + + + + + + + + + diff --git a/ide/org.codehaus.groovy.eclipse.refactoring/src/org/codehaus/groovy/eclipse/refactoring/core/rename/MethodVariantRenameParticipant.java b/ide/org.codehaus.groovy.eclipse.refactoring/src/org/codehaus/groovy/eclipse/refactoring/core/rename/MethodVariantRenameParticipant.java new file mode 100644 index 0000000000..33bc0014d7 --- /dev/null +++ b/ide/org.codehaus.groovy.eclipse.refactoring/src/org/codehaus/groovy/eclipse/refactoring/core/rename/MethodVariantRenameParticipant.java @@ -0,0 +1,150 @@ +/* + * Copyright 2009-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.codehaus.groovy.eclipse.refactoring.core.rename; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.codehaus.groovy.ast.ASTNode; +import org.codehaus.groovy.ast.MethodNode; +import org.codehaus.groovy.eclipse.codebrowsing.requestor.ASTNodeFinder; +import org.codehaus.groovy.eclipse.codebrowsing.requestor.Region; +import org.codehaus.groovy.eclipse.core.GroovyCore; +import org.codehaus.jdt.groovy.model.GroovyCompilationUnit; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.ISourceRange; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.refactoring.CompilationUnitChange; +import org.eclipse.jdt.core.search.IJavaSearchConstants; +import org.eclipse.jdt.core.search.SearchEngine; +import org.eclipse.jdt.core.search.SearchMatch; +import org.eclipse.jdt.core.search.SearchPattern; +import org.eclipse.jdt.internal.corext.refactoring.Checks; +import org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine; +import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup; +import org.eclipse.jdt.internal.corext.refactoring.base.ReferencesInBinaryContext; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.CompositeChange; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext; +import org.eclipse.ltk.core.refactoring.participants.RenameParticipant; +import org.eclipse.text.edits.MultiTextEdit; +import org.eclipse.text.edits.ReplaceEdit; + +public class MethodVariantRenameParticipant extends RenameParticipant { + + private IMethod target; + private Map> matches; + + @Override + public String getName() { + return "Rename Groovy method variant references."; + } + + @Override + protected boolean initialize(final Object element) { + target = (IMethod) element; + if (getArguments().getUpdateReferences()) { + try { + // must be method with default value(s) + ISourceRange range = target.getNameRange(); + ICompilationUnit unit = target.getCompilationUnit(); + if (!target.isBinary() && !target.isReadOnly() && range.getOffset() > 0 && unit instanceof GroovyCompilationUnit) { + Region region = new Region(range.getOffset(), range.getLength()); // find associated Groovy AST node + ASTNode method = new ASTNodeFinder(region).doVisit(((GroovyCompilationUnit) unit).getModuleNode()); + if (method instanceof MethodNode && ((MethodNode) method).getOriginal().hasDefaultValue()) { + return true; + } + } + } catch (JavaModelException e) { + GroovyCore.logException(e.getLocalizedMessage(), e); + } + } + return false; + } + + @Override + public RefactoringStatus checkConditions(final IProgressMonitor pm, final CheckConditionsContext context) { + RefactoringStatus status = new RefactoringStatus(); + SubMonitor submon = SubMonitor.convert(pm, "Searching for Groovy method variant references", 13); + try { + SearchPattern pattern = null; + for (IMethod method : target.getDeclaringType().getMethods()) { + if (!method.equals(target) && method.getNameRange().equals(target.getNameRange())) { + if (pattern == null) { + pattern = SearchPattern.createPattern(method, IJavaSearchConstants.REFERENCES); + } else { + pattern = SearchPattern.createOrPattern(pattern, SearchPattern.createPattern(method, IJavaSearchConstants.REFERENCES)); + } + } + } + submon.worked(1); + + SearchResultGroup[] groups = RefactoringSearchEngine.search(pattern, SearchEngine.createWorkspaceScope(), submon.split(10), status); + groups = Checks.excludeCompilationUnits(groups, status); // exclude non-parsable compilation units + status.merge(Checks.checkCompileErrorsInAffectedFiles(groups)); + matches = new HashMap<>(); + submon.worked(1); + + ReferencesInBinaryContext binaryReferences = new ReferencesInBinaryContext("Binary references to method '" + target.getElementName() + "'"); + for (SearchResultGroup group : groups) { + for (SearchMatch match : group.getSearchResults()) { + if (match.getAccuracy() == SearchMatch.A_ACCURATE) { + if (((IMethod) match.getElement()).isBinary()) { + binaryReferences.add(match); + } else { + matches.computeIfAbsent(group.getCompilationUnit(), x -> new ArrayList<>()).add(match); + } + } + } + } + binaryReferences.addErrorIfNecessary(status); + + submon.worked(1); + } catch (CoreException e) { + status.merge(RefactoringStatus.createFatalErrorStatus(e.getLocalizedMessage())); + } + return status; + } + + @Override + public Change createChange(final IProgressMonitor pm) throws CoreException { + CompositeChange change = new CompositeChange(getName()); + SubMonitor submon = SubMonitor.convert(pm, matches.size()); + for (Map.Entry> entry : matches.entrySet()) { + CompilationUnitChange edits = Optional.ofNullable((CompilationUnitChange) getTextChange(entry.getKey())).orElseGet(() -> { + CompilationUnitChange cuc = new CompilationUnitChange(getName(), entry.getKey()); + cuc.setEdit(new MultiTextEdit()); + change.add(cuc); + return cuc; + }); + for (SearchMatch match : entry.getValue()) { + edits.addEdit(new ReplaceEdit(match.getOffset(), target.getElementName().length(), getArguments().getNewName())); + } + submon.worked(1); + } + matches = null; + target = null; + return change; + } +} diff --git a/ide/org.codehaus.groovy.eclipse.refactoring/src/org/codehaus/groovy/eclipse/refactoring/core/rename/SyntheticAccessorsRenameParticipant.java b/ide/org.codehaus.groovy.eclipse.refactoring/src/org/codehaus/groovy/eclipse/refactoring/core/rename/PropertyAccessRenameParticipant.java similarity index 81% rename from ide/org.codehaus.groovy.eclipse.refactoring/src/org/codehaus/groovy/eclipse/refactoring/core/rename/SyntheticAccessorsRenameParticipant.java rename to ide/org.codehaus.groovy.eclipse.refactoring/src/org/codehaus/groovy/eclipse/refactoring/core/rename/PropertyAccessRenameParticipant.java index af3bc00dc7..43c1673364 100644 --- a/ide/org.codehaus.groovy.eclipse.refactoring/src/org/codehaus/groovy/eclipse/refactoring/core/rename/SyntheticAccessorsRenameParticipant.java +++ b/ide/org.codehaus.groovy.eclipse.refactoring/src/org/codehaus/groovy/eclipse/refactoring/core/rename/PropertyAccessRenameParticipant.java @@ -1,11 +1,11 @@ /* - * Copyright 2009-2018 the original author or authors. + * Copyright 2009-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -27,7 +27,6 @@ import org.codehaus.groovy.eclipse.core.search.SyntheticAccessorSearchRequestor; import org.codehaus.groovy.eclipse.refactoring.core.utils.StatusHelper; import org.codehaus.groovy.runtime.MetaClassHelper; -import org.codehaus.jdt.groovy.model.GroovyNature; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; @@ -53,13 +52,10 @@ import org.eclipse.jdt.core.search.SearchParticipant; import org.eclipse.jdt.core.search.SearchPattern; import org.eclipse.jdt.core.search.SearchRequestor; -import org.eclipse.jdt.internal.core.search.JavaSearchParticipant; import org.eclipse.jdt.internal.corext.refactoring.Checks; import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup; import org.eclipse.jdt.internal.corext.refactoring.base.ReferencesInBinaryContext; -import org.eclipse.jdt.internal.corext.refactoring.rename.RenameFieldProcessor; -import org.eclipse.jdt.internal.corext.refactoring.rename.RenameMethodProcessor; import org.eclipse.ltk.core.refactoring.Change; import org.eclipse.ltk.core.refactoring.CompositeChange; import org.eclipse.ltk.core.refactoring.RefactoringStatus; @@ -67,7 +63,6 @@ import org.eclipse.ltk.core.refactoring.TextChange; import org.eclipse.ltk.core.refactoring.TextEditChangeGroup; import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext; -import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor; import org.eclipse.ltk.core.refactoring.participants.RenameParticipant; import org.eclipse.text.edits.MultiTextEdit; import org.eclipse.text.edits.ReplaceEdit; @@ -80,18 +75,33 @@ * and java files for groovy properties. Renames accesses to synthetic groovy * properties that are backed by a getter, setter, and/or isser. */ -public class SyntheticAccessorsRenameParticipant extends RenameParticipant { +public class PropertyAccessRenameParticipant extends RenameParticipant { private IMember renameTarget; - private List matches; @Override - public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context) throws OperationCanceledException { + public String getName() { + return "Rename Groovy property getters and setters."; + } + + @Override + protected boolean initialize(final Object element) { + if (element instanceof IMethod || element instanceof IField) { + renameTarget = (IMember) element; + if (!renameTarget.isReadOnly()) { + return true; + } + } + return false; + } + + @Override + public RefactoringStatus checkConditions(final IProgressMonitor pm, final CheckConditionsContext context) { RefactoringStatus status = new RefactoringStatus(); matches = new ArrayList<>(); try { - if (shouldUpdateReferences()) { + if (getArguments().getUpdateReferences()) { findExtraReferences(SubMonitor.convert(pm, "Finding Groovy property references", 20)); } checkForBinaryRefs(status); @@ -106,37 +116,24 @@ public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsCon return status; } - private boolean shouldUpdateReferences() { - RefactoringProcessor processor = getProcessor(); - if (processor instanceof RenameFieldProcessor) { - return ((RenameFieldProcessor) processor).getUpdateReferences(); - } else if (processor instanceof RenameMethodProcessor) { - return ((RenameMethodProcessor) processor).getUpdateReferences(); - } - return true; - } - - private void findExtraReferences(IProgressMonitor pm) throws CoreException { + private void findExtraReferences(final IProgressMonitor pm) throws CoreException { SyntheticAccessorSearchRequestor requestor = new SyntheticAccessorSearchRequestor(); requestor.findSyntheticMatches(renameTarget, matches::add, SubMonitor.convert(pm, "Find synthetic property accessors", 10)); // when searching for an accessor method, also search for pseudo-property uses of the method; "foo.bar" for "getBar()", "isBar()" or "setBar(...)" if (renameTarget.getElementType() == IJavaElement.METHOD && renameTarget.getElementName().matches("(?:[gs]et|is)\\p{javaJavaIdentifierPart}+") && - ((IMethod) renameTarget).getParameters().length == (renameTarget.getElementName().startsWith("set") ? 1 : 0) && - GroovyNature.hasGroovyNature(renameTarget.getJavaProject().getProject())) { - - String name = renameTarget.getElementName(); - name = Introspector.decapitalize(name.substring(name.startsWith("is") ? 2 : 3)); + ((IMethod) renameTarget).getParameters().length == (renameTarget.getElementName().startsWith("set") ? 1 : 0)) { + String name = propertyName(renameTarget.getElementName()); IMethod method = ((IType) renameTarget.getParent()).getMethod(name, ((IMethod) renameTarget).getParameterTypes()); if (!method.exists()) { method = SyntheticAccessorSearchRequestor.syntheticMemberProxy( IMethod.class, method, ((IMethod) renameTarget).getReturnType()); SearchPattern pattern = SearchPattern.createPattern(method, IJavaSearchConstants.REFERENCES); - SearchParticipant[] searchParticipants = new SearchParticipant[] {new JavaSearchParticipant()}; + SearchParticipant[] searchParticipants = new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}; new SearchEngine().search(pattern, searchParticipants, SearchEngine.createWorkspaceScope(), new SearchRequestor() { @Override - public void acceptSearchMatch(SearchMatch match) throws CoreException { + public void acceptSearchMatch(final SearchMatch match) throws CoreException { matches.add(match); } }, SubMonitor.convert(pm, "Find property-style uses of non-synthetic methods", 10)); @@ -147,7 +144,7 @@ public void acceptSearchMatch(SearchMatch match) throws CoreException { pm.worked(10); } - private void checkForBinaryRefs(RefactoringStatus status) throws JavaModelException { + private void checkForBinaryRefs(final RefactoringStatus status) throws JavaModelException { ReferencesInBinaryContext binaryRefs = new ReferencesInBinaryContext( "Elements containing binary references to refactored element ''" + renameTarget.getElementName() + "''"); for (Iterator it = matches.iterator(); it.hasNext();) { @@ -164,7 +161,7 @@ private void checkForBinaryRefs(RefactoringStatus status) throws JavaModelExcept binaryRefs.addErrorIfNecessary(status); } - private static boolean isBinaryElement(Object element) throws JavaModelException { + private static boolean isBinaryElement(final Object element) throws JavaModelException { if (element instanceof IMember) { return ((IMember) element).isBinary(); } else if (element instanceof IClassFile) { @@ -179,7 +176,7 @@ private static boolean isBinaryElement(Object element) throws JavaModelException return false; } - private void checkForPotentialMatches(RefactoringStatus status) { + private void checkForPotentialMatches(final RefactoringStatus status) { for (SearchMatch match : matches) { if (match.getAccuracy() == SearchMatch.A_INACCURATE) { final RefactoringStatusEntry entry = new RefactoringStatusEntry(RefactoringStatus.WARNING, @@ -206,7 +203,7 @@ private SearchResultGroup[] convertMatches() { //-------------------------------------------------------------------------- @Override - public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { + public Change createChange(final IProgressMonitor pm) throws CoreException, OperationCanceledException { CompositeChange change = new CompositeChange(getName()); createMatchedChanges(matches, change, getNameMap()); if (change.getChildren().length > 0) { @@ -215,29 +212,7 @@ public Change createChange(IProgressMonitor pm) throws CoreException, OperationC return null; } - @Override - public String getName() { - return "Rename Groovy synthetic getters and setters."; - } - - /** - * Only activate participant if this is a method or field rename in a Groovy - * project. Must be source. - */ - @Override - protected boolean initialize(Object element) { - if (element instanceof IMethod || element instanceof IField) { - renameTarget = (IMember) element; - if (!renameTarget.isReadOnly() && - GroovyNature.hasGroovyNature(renameTarget.getJavaProject().getProject())) { - return true; - } - } - return false; - } - - private void addChange(CompositeChange finalChange, IMember enclosingElement, int offset, int length, - String newName) { + private void addChange(final CompositeChange finalChange, final IMember enclosingElement, final int offset, final int length, final String newName) { CompilationUnitChange existingChange = findOrCreateChange(enclosingElement, finalChange); TextEditChangeGroup[] groups = existingChange.getTextEditChangeGroups(); TextEdit occurrenceEdit = new ReplaceEdit(offset, length, newName); @@ -258,8 +233,7 @@ private void addChange(CompositeChange finalChange, IMember enclosingElement, in new TextEditGroup("Update synthetic Groovy accessor", occurrenceEdit))); } - private void createMatchedChanges(List references, CompositeChange finalChange, - Map nameMap) throws JavaModelException { + private void createMatchedChanges(final List references, final CompositeChange finalChange, final Map nameMap) throws JavaModelException { for (SearchMatch searchMatch : references) { Object elt = searchMatch.getElement(); if (elt instanceof IMember) { @@ -272,7 +246,7 @@ private void createMatchedChanges(List references, CompositeChange } } - private String findMatchName(SearchMatch searchMatch, Set keySet) throws JavaModelException { + private String findMatchName(final SearchMatch searchMatch, final Set keySet) throws JavaModelException { IJavaElement element = JavaCore.create(searchMatch.getResource()); if (element.getElementType() == IJavaElement.COMPILATION_UNIT) { ICompilationUnit unit = (ICompilationUnit) element; @@ -286,7 +260,7 @@ private String findMatchName(SearchMatch searchMatch, Set keySet) throws return null; } - private CompilationUnitChange findOrCreateChange(IMember accessor, CompositeChange finalChange) { + private CompilationUnitChange findOrCreateChange(final IMember accessor, final CompositeChange finalChange) { TextChange textChange = getTextChange(accessor.getCompilationUnit()); CompilationUnitChange existingChange = null; if (textChange instanceof CompilationUnitChange) { @@ -330,11 +304,11 @@ private Map getNameMap() { return nameMap; } - private static String accessorName(String prefix, String name) { + private static String accessorName(final String prefix, final String name) { return prefix + MetaClassHelper.capitalize(name); } - private static String propertyName(String fullName) { + private static String propertyName(final String fullName) { int prefixLength = 0; if (fullName.startsWith("is")) { prefixLength = 2; diff --git a/jdt-patch/e416/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchEngine.java b/jdt-patch/e416/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchEngine.java index 68fcb88a04..641f51c630 100644 --- a/jdt-patch/e416/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchEngine.java +++ b/jdt-patch/e416/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchEngine.java @@ -668,8 +668,7 @@ public void search(IWorkspace workspace, ISearchPattern searchPattern, IJavaSear *@since 3.0 */ public void search(SearchPattern pattern, SearchParticipant[] participants, IJavaSearchScope scope, SearchRequestor requestor, IProgressMonitor monitor) throws CoreException { - // GROOVY add - // GRECLIPSE-1054: potentially expand search scope because private declarations can be referenced outside the class that declares them. + // GROOVY add -- GRECLIPSE-1054: maybe expand search scope because private declarations can be referenced outside the class that declares them if (pattern.focus != null && LanguageSupportFactory.isInterestingProject(pattern.focus.getJavaProject().getProject())) { scope = LanguageSupportFactory.expandSearchScope(scope, pattern, requestor); } diff --git a/jdt-patch/e417/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchEngine.java b/jdt-patch/e417/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchEngine.java index 68fcb88a04..641f51c630 100644 --- a/jdt-patch/e417/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchEngine.java +++ b/jdt-patch/e417/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchEngine.java @@ -668,8 +668,7 @@ public void search(IWorkspace workspace, ISearchPattern searchPattern, IJavaSear *@since 3.0 */ public void search(SearchPattern pattern, SearchParticipant[] participants, IJavaSearchScope scope, SearchRequestor requestor, IProgressMonitor monitor) throws CoreException { - // GROOVY add - // GRECLIPSE-1054: potentially expand search scope because private declarations can be referenced outside the class that declares them. + // GROOVY add -- GRECLIPSE-1054: maybe expand search scope because private declarations can be referenced outside the class that declares them if (pattern.focus != null && LanguageSupportFactory.isInterestingProject(pattern.focus.getJavaProject().getProject())) { scope = LanguageSupportFactory.expandSearchScope(scope, pattern, requestor); }