Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManoj Palat2014-10-29 08:04:11 +0000
committerManoj Palat2014-10-29 08:04:11 +0000
commitdbfcb8d7fd5ffcddbe22e6b1ba82be9083ee4d44 (patch)
tree50bc41b24e01a69730f00272bd34cae3a3c701ab
parent05396c2aadbdf694b3e24041198b7173f55ce8f9 (diff)
downloadeclipse.jdt.core-dbfcb8d7fd5ffcddbe22e6b1ba82be9083ee4d44.tar.gz
eclipse.jdt.core-dbfcb8d7fd5ffcddbe22e6b1ba82be9083ee4d44.tar.xz
eclipse.jdt.core-dbfcb8d7fd5ffcddbe22e6b1ba82be9083ee4d44.zip
Fix for Bug 431357 [search] Search API got wrong result, when searchingI20141029-2000I20141029-0800
for method references, where the parameter is a member type of another type.
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java803
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java109
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java27
3 files changed, 927 insertions, 12 deletions
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java
index e03059eaa4..5adcc7dc34 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java
@@ -80,6 +80,7 @@ import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
import org.eclipse.jdt.internal.core.search.indexing.IndexRequest;
import org.eclipse.jdt.internal.core.search.matching.AndPattern;
import org.eclipse.jdt.internal.core.search.matching.MatchLocator;
+import org.eclipse.jdt.internal.core.search.matching.MethodPattern;
import org.eclipse.jdt.internal.core.search.matching.PatternLocator;
import org.eclipse.jdt.internal.core.search.matching.TypeDeclarationPattern;
@@ -13426,5 +13427,805 @@ public void testBug400919c() throws CoreException {
"src/b400919/X.java b400919.X2 [Marker] EXACT_MATCH"
);
}
-// Add new tests in JavaSearchBugsTests2
+/** @bug 431357
+ * [search] Search API got wrong result, when searching for method references, where the parameter is a member type of another type.
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=431357"
+ */
+public void testBug431357_001() throws CoreException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+ "interface I { \n" +
+ " public void query(Foo.InnerKey key);// Search result of method query(Foo.InnerKey) returns the method query(Bar.InnerKey) too \n" +
+ " public void query(Bar.InnerKey key);\n" +
+ "}\n" +
+ "\n" +
+ "class Foo { \n" +
+ " static class InnerKey {}\n" +
+ "}\n" +
+ "class Bar {\n" +
+ " static class InnerKey {}\n" +
+ "}\n" +
+ "\n" +
+ "class X {\n" +
+ " public static void foo(I i, Foo.InnerKey key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ " public static void bar(I i, Bar.InnerKey key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ " public static I getInstance() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n"
+ );
+
+ String str = this.workingCopies[0].getSource();
+ String selection = "query";
+ int start = str.indexOf(selection);
+ int length = selection.length();
+
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, length);
+ MethodPattern pattern = (MethodPattern) SearchPattern.createPattern(elements[0], REFERENCES, EXACT_RULE | ERASURE_RULE);
+
+ new SearchEngine(this.workingCopies).search(pattern,
+ new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
+ getJavaSearchWorkingCopiesScope(),
+ this.resultCollector,
+ null);
+ assertSearchResults(
+ "src/X.java void X.foo(I, Foo.InnerKey) [query(key)] EXACT_MATCH"
+ );
+}
+/** @bug 431357
+ * [search] Search API got wrong result, when searching for method references, where the parameter is a member type of another type.
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=431357"
+ */
+public void testBug431357_002() throws CoreException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+ "interface I { \n" +
+ " public void query(Foo.InnerKey key);// Search result of method query(Foo.InnerKey) returns the method query(Bar.InnerKey) too \n" +
+ " public void query(Bar.InnerKey key);\n" +
+ "}\n" +
+ "\n" +
+ "class Foo { \n" +
+ " static class InnerKey {}\n" +
+ "}\n" +
+ "class Bar {\n" +
+ " static class InnerKey {}\n" +
+ "}\n" +
+ "\n" +
+ "class X {\n" +
+ " public static void foo(I i, Foo.InnerKey key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ " public static void bar(I i, Bar.InnerKey key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ " public static I getInstance() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n"
+ );
+
+ String str = this.workingCopies[0].getSource();
+ String selection = "query";
+ int start = str.indexOf(selection);
+ int length = selection.length();
+
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, length);
+ MethodPattern pattern = (MethodPattern) SearchPattern.createPattern(elements[0], ALL_OCCURRENCES, EXACT_RULE | ERASURE_RULE);
+
+ new SearchEngine(this.workingCopies).search(pattern,
+ new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
+ getJavaSearchWorkingCopiesScope(),
+ this.resultCollector,
+ null);
+ assertSearchResults( "src/X.java void I.query(Foo.InnerKey) [query] EXACT_MATCH\n" +
+ "src/X.java void X.foo(I, Foo.InnerKey) [query(key)] EXACT_MATCH"
+ );
+}
+/** @bug 431357
+ * [search] Search API got wrong result, when searching for method references, where the parameter is a member type of another type.
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=431357"
+ */
+public void testBug431357_003() throws CoreException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+ "interface I { \n" +
+ " public void query(Foo.InnerKey key);// Search result of method query(Foo.InnerKey) returns the method query(Bar.InnerKey) too \n" +
+ " public void query/*here*/(Bar.InnerKey key);\n" +
+ "}\n" +
+ "\n" +
+ "class Foo { \n" +
+ " static class InnerKey {}\n" +
+ "}\n" +
+ "class Bar {\n" +
+ " static class InnerKey {}\n" +
+ "}\n" +
+ "\n" +
+ "class X {\n" +
+ " public static void foo(I i, Foo.InnerKey key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ " public static void bar(I i, Bar.InnerKey key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ " public static I getInstance() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n"
+ );
+
+ String str = this.workingCopies[0].getSource();
+ String selection = "query/*here*/";
+ int start = str.indexOf(selection);
+ int length = "query".length();
+
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, length);
+ MethodPattern pattern = (MethodPattern) SearchPattern.createPattern(elements[0], ALL_OCCURRENCES, EXACT_RULE | ERASURE_RULE);
+
+ new SearchEngine(this.workingCopies).search(pattern,
+ new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
+ getJavaSearchWorkingCopiesScope(),
+ this.resultCollector,
+ null);
+ assertSearchResults("src/X.java void I.query(Bar.InnerKey) [query] EXACT_MATCH\n" +
+ "src/X.java void X.bar(I, Bar.InnerKey) [query(key)] EXACT_MATCH"
+ );
+}
+/** @bug 431357
+ * [search] Search API got wrong result, when searching for method references, where the parameter is a member type of another type.
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=431357"
+ */
+public void testBug431357_004() throws CoreException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+ "// --\n" +
+ "interface I { \n" +
+ " public void query/*here*/(Foo.Key key);// Search result of method query(Foo.Key) returns the method query(Bar.Key) too \n" +
+ " public void query(Key key);\n" +
+ "}\n" +
+ "\n" +
+ "class Foo { \n" +
+ " static class Key { \n" +
+ " }\n" +
+ " public static void foo(I i, Key key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ " \n" +
+ "}\n" +
+ "\n" +
+ "class Key {\n" +
+ " \n" +
+ "}\n" +
+ "class Bar {\n" +
+ " \n" +
+ " public static void bar(I i, Key key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ "}\n" +
+ "\n" +
+ "public class X {\n" +
+ " public static I getInstance() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n"
+ );
+
+ String str = this.workingCopies[0].getSource();
+ String selection = "query/*here*/";
+ int start = str.indexOf(selection);
+ int length = "query".length();
+
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, length);
+ MethodPattern pattern = (MethodPattern) SearchPattern.createPattern(elements[0], ALL_OCCURRENCES, EXACT_RULE | ERASURE_RULE);
+
+ new SearchEngine(this.workingCopies).search(pattern,
+ new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
+ getJavaSearchWorkingCopiesScope(),
+ this.resultCollector,
+ null);
+ assertSearchResults(
+ "src/X.java void I.query(Foo.Key) [query] EXACT_MATCH\n" +
+ "src/X.java void Foo.foo(I, Key) [query(key)] EXACT_MATCH"
+ );
+}
+/** @bug 431357
+ * [search] Search API got wrong result, when searching for method references, where the parameter is a member type of another type.
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=431357"
+ */
+public void testBug431357_005() throws CoreException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+ "// --\n" +
+ "interface I { \n" +
+ " public void query(Foo.Key key);// Search result of method query(Foo.Key) returns the method query(Bar.Key) too \n" +
+ " public void query/*here*/(Key key);\n" +
+ "}\n" +
+ "\n" +
+ "class Foo { \n" +
+ " static class Key { \n" +
+ " }\n" +
+ " public static void foo(I i, Key key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ " \n" +
+ "}\n" +
+ "\n" +
+ "class Key {\n" +
+ " \n" +
+ "}\n" +
+ "class Bar {\n" +
+ " \n" +
+ " public static void bar(I i, Key key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ "}\n" +
+ "\n" +
+ "public class X {\n" +
+ " public static I getInstance() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n"
+ );
+
+ String str = this.workingCopies[0].getSource();
+ String selection = "query/*here*/";
+ int start = str.indexOf(selection);
+ int length = "query".length();
+
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, length);
+ MethodPattern pattern = (MethodPattern) SearchPattern.createPattern(elements[0], ALL_OCCURRENCES, EXACT_RULE | ERASURE_RULE);
+
+ new SearchEngine(this.workingCopies).search(pattern,
+ new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
+ getJavaSearchWorkingCopiesScope(),
+ this.resultCollector,
+ null);
+ assertSearchResults(
+ "src/X.java void I.query(Key) [query] EXACT_MATCH\n" +
+ "src/X.java void Bar.bar(I, Key) [query(key)] EXACT_MATCH"
+ );
+}
+/** @bug 431357
+ * [search] Search API got wrong result, when searching for method references, where the parameter is a member type of another type.
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=431357"
+ */
+public void testBug431357_006() throws CoreException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+ "// --\n" +
+ "interface I { \n" +
+ " public void query/*here*/(Foo.Key key);// Search result of method query(Foo.Key) returns the method query(Bar.Key) too \n" +
+ " public void query(Key key);\n" +
+ " public void query(Bar.Key key);\n" +
+ "}\n" +
+ "\n" +
+ "class Foo { \n" +
+ " static class Key { \n" +
+ " }\n" +
+ " public static void foo(I i, Key key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ " \n" +
+ "}\n" +
+ "\n" +
+ "class Key {\n" +
+ " \n" +
+ "}\n" +
+ "class Bar {\n" +
+ " static class Key {\n" +
+ " \n" +
+ " } \n" +
+ " public static void bar(I i, Key key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ "}\n" +
+ "\n" +
+ "public class X {\n" +
+ " public static I getInstance() {\n" +
+ " return null;\n" +
+ " }\n" +
+ " public static void bar(I i, Key key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ "}\n"
+ );
+
+ String str = this.workingCopies[0].getSource();
+ String selection = "query/*here*/";
+ int start = str.indexOf(selection);
+ int length = "query".length();
+
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, length);
+ MethodPattern pattern = (MethodPattern) SearchPattern.createPattern(elements[0], ALL_OCCURRENCES, EXACT_RULE | ERASURE_RULE);
+
+ new SearchEngine(this.workingCopies).search(pattern,
+ new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
+ getJavaSearchWorkingCopiesScope(),
+ this.resultCollector,
+ null);
+ assertSearchResults(
+ "src/X.java void I.query(Foo.Key) [query] EXACT_MATCH\n" +
+ "src/X.java void Foo.foo(I, Key) [query(key)] EXACT_MATCH"
+ );
+}
+/** @bug 431357
+ * [search] Search API got wrong result, when searching for method references, where the parameter is a member type of another type.
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=431357"
+ */
+public void testBug431357_007() throws CoreException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+ "// --\n" +
+ "interface I { \n" +
+ " public void query(Foo.Key key);// Search result of method query(Foo.Key) returns the method query(Bar.Key) too \n" +
+ " public void query/*here*/(Key key);\n" +
+ " public void query(Bar.Key key);\n" +
+ "}\n" +
+ "\n" +
+ "class Foo { \n" +
+ " static class Key { \n" +
+ " }\n" +
+ " public static void foo(I i, Key key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ " \n" +
+ "}\n" +
+ "\n" +
+ "class Key {\n" +
+ " \n" +
+ "}\n" +
+ "class Bar {\n" +
+ " static class Key {\n" +
+ " \n" +
+ " } \n" +
+ " public static void bar(I i, Key key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ "}\n" +
+ "\n" +
+ "public class X {\n" +
+ " public static I getInstance() {\n" +
+ " return null;\n" +
+ " }\n" +
+ " public static void bar(I i, Key key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ "}\n"
+ );
+
+ String str = this.workingCopies[0].getSource();
+ String selection = "query/*here*/";
+ int start = str.indexOf(selection);
+ int length = "query".length();
+
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, length);
+ MethodPattern pattern = (MethodPattern) SearchPattern.createPattern(elements[0], ALL_OCCURRENCES, EXACT_RULE | ERASURE_RULE);
+
+ new SearchEngine(this.workingCopies).search(pattern,
+ new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
+ getJavaSearchWorkingCopiesScope(),
+ this.resultCollector,
+ null);
+ assertSearchResults(
+ "src/X.java void I.query(Key) [query] EXACT_MATCH\n" +
+ "src/X.java void X.bar(I, Key) [query(key)] EXACT_MATCH"
+ );
+}
+
+/** @bug 431357
+ * [search] Search API got wrong result, when searching for method references, where the parameter is a member type of another type.
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=431357"
+ */
+public void testBug431357_008() throws CoreException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+ "// --\n" +
+ "interface I { \n" +
+ " public void query(Foo.Key key);// Search result of method query(Foo.Key) returns the method query(Bar.Key) too \n" +
+ " public void query(Key key);\n" +
+ " public void query/*here*/(Bar.Key key);\n" +
+ "}\n" +
+ "\n" +
+ "class Foo { \n" +
+ " static class Key { \n" +
+ " }\n" +
+ " public static void foo(I i, Key key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ " \n" +
+ "}\n" +
+ "\n" +
+ "class Key {\n" +
+ " \n" +
+ "}\n" +
+ "class Bar {\n" +
+ " static class Key {\n" +
+ " \n" +
+ " } \n" +
+ " public static void bar(I i, Key key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ "}\n" +
+ "\n" +
+ "public class X {\n" +
+ " public static I getInstance() {\n" +
+ " return null;\n" +
+ " }\n" +
+ " public static void bar(I i, Key key) {\n" +
+ " i.query(key);\n" +
+ " }\n" +
+ "}\n"
+ );
+
+ String str = this.workingCopies[0].getSource();
+ String selection = "query/*here*/";
+ int start = str.indexOf(selection);
+ int length = "query".length();
+
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, length);
+ MethodPattern pattern = (MethodPattern) SearchPattern.createPattern(elements[0], ALL_OCCURRENCES, EXACT_RULE | ERASURE_RULE);
+
+ new SearchEngine(this.workingCopies).search(pattern,
+ new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
+ getJavaSearchWorkingCopiesScope(),
+ this.resultCollector,
+ null);
+ assertSearchResults(
+ "src/X.java void I.query(Bar.Key) [query] EXACT_MATCH\n" +
+ "src/X.java void Bar.bar(I, Key) [query(key)] EXACT_MATCH"
+ );
+}
+
+/** @bug 431357
+ * [search] Search API got wrong result, when searching for method references, where the parameter is a member type of another type.
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=431357"
+ */
+public void testBug431357_009() throws CoreException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+ "interface MyIF { \n" +
+ " public void query(Foo.InnerKey fk, Bar.InnerKey bk, String s); \n" +
+ " public void query/*here*/(Bar.InnerKey fk, Bar.InnerKey bk, String s);\n" +
+ "}\n" +
+ "\n" +
+ "class Foo { \n" +
+ " static class InnerKey { \n" +
+ " }\n" +
+ "\n" +
+ "}\n" +
+ "\n" +
+ "class Bar {\n" +
+ " static class InnerKey {\n" +
+ " }\n" +
+ " public static void bar(MyIF i, Foo.InnerKey fk, Bar.InnerKey bk) {\n" +
+ " i.query(fk, bk, \"\");\n" +
+ " }\n" +
+ "}\n" +
+ "public class X {}\n"
+ );
+
+ String str = this.workingCopies[0].getSource();
+ String selection = "query/*here*/";
+ int start = str.indexOf(selection);
+ int length = "query".length();
+
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, length);
+ MethodPattern pattern = (MethodPattern) SearchPattern.createPattern(elements[0], REFERENCES, EXACT_RULE | ERASURE_RULE);
+
+ new SearchEngine(this.workingCopies).search(pattern,
+ new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
+ getJavaSearchWorkingCopiesScope(),
+ this.resultCollector,
+ null);
+ assertSearchResults(""
+ );
+}
+
+/** @bug 431357
+ * [search] Search API got wrong result, when searching for method references, where the parameter is a member type of another type.
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=431357"
+ */
+public void testBug431357_010() throws CoreException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+ "interface MyIF { \n" +
+ " public void query(Foo.InnerKey fk, String s); \n" +
+ " public void query/*here*/(Bar.InnerKey fk, String s);\n" +
+ "}\n" +
+ "\n" +
+ "class Foo { \n" +
+ " static class InnerKey {}\n" +
+ "}\n" +
+ "\n" +
+ "class Bar {\n" +
+ " static class InnerKey {}\n" +
+ " public static void bar(MyIF i, Foo.InnerKey fk) {\n" +
+ " i.query(fk, \"\");\n" +
+ " }\n" +
+ "}\n" +
+ "public class X {}\n"
+ );
+
+ String str = this.workingCopies[0].getSource();
+ String selection = "query/*here*/";
+ int start = str.indexOf(selection);
+ int length = "query".length();
+
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, length);
+ MethodPattern pattern = (MethodPattern) SearchPattern.createPattern(elements[0], REFERENCES, EXACT_RULE | ERASURE_RULE);
+
+ new SearchEngine(this.workingCopies).search(pattern,
+ new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
+ getJavaSearchWorkingCopiesScope(),
+ this.resultCollector,
+ null);
+ assertSearchResults(""
+ );
+}
+
+/** @bug 431357
+ * [search] Search API got wrong result, when searching for method references, where the parameter is a member type of another type.
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=431357"
+ */
+public void testBug431357_011() throws CoreException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+ "interface MyIF { \n" +
+ " public void query(String s, Foo.InnerKey fk); \n" +
+ "}\n" +
+ "\n" +
+ "class Foo { \n" +
+ " static class InnerKey {}\n" +
+ "}\n" +
+ "\n" +
+ "class Bar {\n" +
+ " static class InnerKey {}\n" +
+ " public static void bar(MyIF i, Foo.InnerKey fk) {\n" +
+ " i.query(\"\", fk);\n" +
+ " }\n" +
+ "}\n" +
+ "public class X {}\n"
+ );
+
+ String nonExistentPattern = "MyIF.query(String, Bar.InnerKey)";
+ MethodPattern pattern = (MethodPattern) SearchPattern.createPattern(nonExistentPattern, IJavaSearchConstants.METHOD, REFERENCES, EXACT_RULE | ERASURE_RULE);
+
+ new SearchEngine(this.workingCopies).search(pattern,
+ new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
+ getJavaSearchWorkingCopiesScope(),
+ this.resultCollector,
+ null);
+ assertSearchResults(""
+ );
+}
+
+/** @bug 431357
+ * [search] Search API got wrong result, when searching for method references, where the parameter is a member type of another type.
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=431357"
+ */
+public void testBug431357_012() throws CoreException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+ "interface MyIF { \n" +
+ " public void query/*here*/(Foo.InnerKey fk, Bar.InnerKey bk, String s); \n" +
+ " public void query(Bar.InnerKey fk, Bar.InnerKey bk, String s);\n" +
+ "}\n" +
+ "\n" +
+ "class Foo { \n" +
+ " static class InnerKey { \n" +
+ " }\n" +
+ " \n" +
+ "}\n" +
+ "\n" +
+ "class Bar {\n" +
+ " static class InnerKey extends Foo.InnerKey {\n" +
+ " }\n" +
+ " public static void bar(MyIF i, Foo.InnerKey fk, Bar.InnerKey bk) {\n" +
+ " i.query(fk, bk, \"\");\n" +
+ " }\n" +
+ "}\n" +
+ "public class X {}\n"
+ );
+
+ String str = this.workingCopies[0].getSource();
+ String selection = "query/*here*/";
+ int start = str.indexOf(selection);
+ int length = "query".length();
+
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, length);
+ MethodPattern pattern = (MethodPattern) SearchPattern.createPattern(elements[0], ALL_OCCURRENCES, EXACT_RULE | ERASURE_RULE);
+
+ new SearchEngine(this.workingCopies).search(pattern,
+ new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
+ getJavaSearchWorkingCopiesScope(),
+ this.resultCollector,
+ null);
+ assertSearchResults("src/X.java void MyIF.query(Foo.InnerKey, Bar.InnerKey, String) [query] EXACT_MATCH\n" +
+ "src/X.java void Bar.bar(MyIF, Foo.InnerKey, Bar.InnerKey) [query(fk, bk, \"\")] EXACT_MATCH"
+ );
+}
+
+/** @bug 431357
+ * [search] Search API got wrong result, when searching for method references, where the parameter is a member type of another type.
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=431357"
+ */
+public void testBug431357_013() throws CoreException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+ "interface MyIF { \n" +
+ " public void query/*here*/(Foo.InnerKey key); \n" +
+ " public void query(Bar.InnerKey key);\n" +
+ "}\n" +
+ "\n" +
+ "class Foo { \n" +
+ " static class InnerKey { \n" +
+ " }\n" +
+ " \n" +
+ "}\n" +
+ "\n" +
+ "class Bar {\n" +
+ " static class InnerKey{}\n" +
+ "}\n" +
+ "public class X {}\n"
+ );
+
+ String str = this.workingCopies[0].getSource();
+ String selection = "query/*here*/";
+ int start = str.indexOf(selection);
+ int length = "query".length();
+
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, length);
+ MethodPattern pattern = (MethodPattern) SearchPattern.createPattern(elements[0], ALL_OCCURRENCES, EXACT_RULE | ERASURE_RULE);
+
+ new SearchEngine(this.workingCopies).search(pattern,
+ new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
+ getJavaSearchWorkingCopiesScope(),
+ this.resultCollector,
+ null);
+ assertSearchResults("src/X.java void MyIF.query(Foo.InnerKey) [query] EXACT_MATCH"
+ );
+}
+
+/** @bug 431357
+ * [search] Search API got wrong result, when searching for method references, where the parameter is a member type of another type.
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=431357"
+ */
+public void testBug431357_014() throws CoreException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+ "interface MyIF { \n" +
+ " public void query/*here*/(Foo.InnerKey key); \n" +
+ " public void query(Bar.InnerKey key);\n" +
+ "}\n" +
+ "\n" +
+ "class Foo { \n" +
+ " static class InnerKey { \n" +
+ " }\n" +
+ " \n" +
+ "}\n" +
+ "\n" +
+ "class Bar {\n" +
+ " static class InnerKey{}\n" +
+ "}\n" +
+ "public class X {}\n"
+ );
+
+ String str = this.workingCopies[0].getSource();
+ String selection = "query/*here*/";
+ int start = str.indexOf(selection);
+ int length = "query".length();
+
+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, length);
+ MethodPattern pattern = (MethodPattern) SearchPattern.createPattern(elements[0], DECLARATIONS, EXACT_RULE | ERASURE_RULE);
+
+ new SearchEngine(this.workingCopies).search(pattern,
+ new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
+ getJavaSearchWorkingCopiesScope(),
+ this.resultCollector,
+ null);
+ assertSearchResults("src/X.java void MyIF.query(Foo.InnerKey) [query] EXACT_MATCH");
+}
+
+/** @bug 431357
+ * [search] Search API got wrong result, when searching for method references, where the parameter is a member type of another type.
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=431357"
+ */
+public void testBug431357_015() throws CoreException {
+ String folder = "/JavaSearchBugs/src/testBug431357_015";
+ String filename = folder + "/" + "X.java";
+ try {
+ String contents =
+ "package testBug431357_015;\n" +
+ "interface MyIF { \n" +
+ " public void query/*here*/(Foo.InnerKey key); \n" +
+ " public void query(Bar.InnerKey key);\n" +
+ "}\n" +
+ "\n" +
+ "class Foo { \n" +
+ " static class InnerKey { \n" +
+ " }\n" +
+ " \n" +
+ "}\n" +
+ "\n" +
+ "class Bar {\n" +
+ " static class InnerKey{}\n" +
+ "}\n" +
+ "public class X {}\n";
+ // create files
+ createFolder(folder);
+ createFile(filename, contents);
+ waitUntilIndexesReady();
+
+ // search
+ IType[] types = getCompilationUnit(filename).getTypes();
+ IMethod method = types[0].getMethods()[0];
+ search(method, DECLARATIONS | IJavaSearchConstants.IGNORE_DECLARING_TYPE | IJavaSearchConstants.IGNORE_RETURN_TYPE, ERASURE_RULE);
+ assertSearchResults("src/testBug431357_015/X.java void testBug431357_015.MyIF.query(Foo.InnerKey) [query] EXACT_MATCH");
+ }
+ finally {
+ // delete files
+ deleteFolder(folder);
+ }
+}
+
+/** @bug 431357
+ * [search] Search API got wrong result, when searching for method references, where the parameter is a member type of another type.
+ * enable this once 88997 is fixed
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=431357"
+ */
+public void _testBug431357_016() throws CoreException {
+ String folder = "/JavaSearchBugs/src/testBug431357_016";
+ String filename = folder + "/" + "X.java";
+ try {
+ String contents =
+ "package testBug431357_016;\n" +
+ "interface I { \n " +
+ " public void query(Foo.Key key);\n" +
+ " public void query/*here*/(Key key);\n " +
+ "}\n " +
+ "\n " +
+ "class Foo { \n " +
+ " static class Key { \n " +
+ " }\n " +
+ " public static void foo(I i, Key key) {\n " +
+ " i.query(key);\n " +
+ " }\n " +
+ " \n " +
+ "}\n " +
+ "\n " +
+ "class Key {\n " +
+ " \n " +
+ "}\n " +
+ "class Bar {\n " +
+ " \n " +
+ " public static void bar(I i, Key key) {\n " +
+ " i.query(key);\n " +
+ " }\n " +
+ "}\n " +
+ "\n " +
+ "public class X {\n " +
+ " public static I getInstance() {\n " +
+ " return null;\n " +
+ " }\n " +
+ "}\n ";
+ // create files
+ createFolder(folder);
+ createFile(filename, contents);
+ waitUntilIndexesReady();
+
+ // search
+ IType[] types = getCompilationUnit(filename).getTypes();
+ IMethod method = types[0].getMethods()[1];
+ search(method, DECLARATIONS | IJavaSearchConstants.IGNORE_DECLARING_TYPE | IJavaSearchConstants.IGNORE_RETURN_TYPE, ERASURE_RULE);
+ assertSearchResults("src/testBug431357_016/X.java void testBug431357_016.I.query(Key) [query] EXACT_MATCH");
+ }
+ finally {
+ // delete files
+ deleteFolder(folder);
+ }
+}
+
} \ No newline at end of file
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
index 9c8056397b..4148ad0471 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
@@ -14,9 +14,12 @@ package org.eclipse.jdt.internal.core.search.matching;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.zip.ZipFile;
@@ -953,6 +956,102 @@ public MethodBinding getMethodBinding(MethodPattern methodPattern) {
}
return null;
}
+
+private List<String> getInverseFullName(char[] qualifier, char[] simpleName) {
+ List <String> result = new ArrayList<String>();
+ if (qualifier != null && qualifier.length > 0) {
+ result.addAll(Arrays.asList(new String(qualifier).split("\\.")));//$NON-NLS-1$
+ Collections.reverse(result);
+ }
+ if (simpleName != null) result.add(0, new String(simpleName));
+ return result;
+}
+
+/** returns the row index which has the highest column entry.
+ * TODO: rewrite this code with list when (if) we move to 1.8 [with FP constructs].
+ */
+private int getMaxResult(int[][] resultsMap) {
+ int rows = resultsMap.length;
+ int cols = resultsMap[0].length;
+ List <Integer> candidates = new ArrayList<Integer>();
+ candidates.add(0); //default row
+
+ for (int j = 0; j < cols; ++j) {
+ int current = resultsMap[0][j];
+ for (int i = 1; i < rows; ++i) {
+ int tmp = resultsMap[i][j];
+ if (tmp < current) continue;
+ if (tmp > current) {
+ current = tmp;
+ candidates.clear();
+ }
+ candidates.add(i);// there is atleast one element always.
+ }
+ if (candidates.size() <= 1) break; // found
+ }
+ return candidates.get(0);
+}
+
+/** apply the function to map the parameter full name to an index
+ */
+private int mapParameter(List <String> patternParameterFullName, List <String> methodParameterFullName) {
+ int patternLen = patternParameterFullName.size();
+ int methodLen = methodParameterFullName.size();
+ int size = patternLen < methodLen ? patternLen : methodLen;
+ int result = -1;
+ for (int i = 0; i < size; i++) {
+ if (!patternParameterFullName.get(i).equals(methodParameterFullName.get(i))) break;
+ ++result;
+ }
+ return patternLen == methodLen && result + 1 == patternLen ? Integer.MAX_VALUE : result;
+}
+/**
+ * returns an array of integers whose elements are matching indices.
+ * As a special case, full match would have max value as the index.
+ */
+private int[] getResultMap(Map<Integer, List<String>> patternMap, Map<Integer, List<String>> methodMap) {
+ int paramLength = methodMap.size();
+ int[] result = new int[paramLength];
+ for (int p = 0; p < paramLength; p++) {
+ result[p] = mapParameter(patternMap.get(p), methodMap.get(p));
+ }
+ return result;
+}
+
+private Map<Integer, List<String>> getSplitNames(char[][] qualifiedNames, char[][] simpleNames) {
+ int paramLength = simpleNames.length;
+ Map <Integer, List<String>> result = new HashMap<Integer, List<String>>();
+ for (int p = 0; p < paramLength; p++) result.put(p, getInverseFullName(qualifiedNames[p], simpleNames[p]));
+ return result;
+}
+
+private Map<Integer, List<String>> getSplitNames(MethodBinding method) {
+ TypeBinding[] methodParameters = method.parameters;
+ int paramLength = methodParameters == null ? 0 : methodParameters.length;
+ Map <Integer, List<String>> result = new HashMap<Integer, List<String>>();
+ for (int p = 0; p < paramLength; p++) result.put(p, getInverseFullName(methodParameters[p].qualifiedSourceName(), null)); // source is part of qualifiedSourceName here);
+ return result;
+}
+
+/**
+ * Selects the most applicable method (though similar but not to be confused with its namesake in jls)
+ * All this machinery for that elusive uncommon case referred in bug 431357.
+ */
+private MethodBinding getMostApplicableMethod(List<MethodBinding> possibleMethods) {
+ int size = possibleMethods.size();
+ MethodBinding result = size != 0 ? possibleMethods.get(0) : null;
+ if (size > 1) {
+ MethodPattern methodPattern = ((MethodPattern) this.pattern);
+ // can cache but may not be worth since this is not a common case
+ Map<Integer, List<String>> methodPatternReverseNames = getSplitNames(methodPattern.parameterQualifications, methodPattern.parameterSimpleNames);
+ int len = possibleMethods.size();
+ int[][] resultMaps = new int[len][];
+ for (int i = 0; i < len; ++i) resultMaps[i] = getResultMap(methodPatternReverseNames, getSplitNames(possibleMethods.get(i)));
+ result = possibleMethods.get(getMaxResult(resultMaps));
+ }
+ return result;
+}
+
private MethodBinding getMethodBinding0(MethodPattern methodPattern) {
if (this.unitScope == null) return null;
// Try to get binding from cache
@@ -969,6 +1068,7 @@ private MethodBinding getMethodBinding0(MethodPattern methodPattern) {
typeName = methodPattern.declaringType.getFullyQualifiedName().toCharArray();
}
TypeBinding declaringTypeBinding = getType(typeName, typeName);
+ MethodBinding result = null;
if (declaringTypeBinding != null) {
if (declaringTypeBinding.isArrayType()) {
declaringTypeBinding = declaringTypeBinding.leafComponentType();
@@ -982,6 +1082,7 @@ private MethodBinding getMethodBinding0(MethodPattern methodPattern) {
int methodsLength = methods.length;
TypeVariableBinding[] refTypeVariables = referenceBinding.typeVariables();
int typeVarLength = refTypeVariables==null ? 0 : refTypeVariables.length;
+ List <MethodBinding> possibleMethods = new ArrayList<MethodBinding>(methodsLength);
for (int i=0; i<methodsLength; i++) {
TypeBinding[] methodParameters = methods[i].parameters;
int paramLength = methodParameters==null ? 0 : methodParameters.length;
@@ -1019,14 +1120,14 @@ private MethodBinding getMethodBinding0(MethodPattern methodPattern) {
}
}
if (found) {
- this.bindings.put(methodPattern, methods[i]);
- return methods[i];
+ possibleMethods.add(methods[i]);
}
}
+ result = getMostApplicableMethod(possibleMethods);
}
}
- this.bindings.put(methodPattern, new ProblemMethodBinding(methodPattern.selector, null, ProblemReasons.NotFound));
- return null;
+ this.bindings.put(methodPattern, result != null ? result : new ProblemMethodBinding(methodPattern.selector, null, ProblemReasons.NotFound));
+ return result;
}
protected boolean hasAlreadyDefinedType(CompilationUnitDeclaration parsedUnit) {
CompilationResult result = parsedUnit.compilationResult;
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java
index 61bc89ce87..17635e31e2 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java
@@ -309,15 +309,25 @@ protected int matchMethod(MethodBinding method, boolean skipImpossibleArg) {
return INACCURATE_MATCH;
}
boolean foundTypeVariable = false;
+ MethodBinding focusMethodBinding = null;
+ boolean checkedFocus = false;
// verify each parameter
for (int i = 0; i < parameterCount; i++) {
TypeBinding argType = method.parameters[i];
int newLevel = IMPOSSIBLE_MATCH;
- if (argType.isMemberType()) {
- // only compare source name for member type (bug 41018)
- newLevel = CharOperation.match(this.pattern.parameterSimpleNames[i], argType.sourceName(), this.isCaseSensitive)
- ? ACCURATE_MATCH
- : IMPOSSIBLE_MATCH;
+ boolean foundLevel = false;
+ if (argType.isMemberType() || this.pattern.parameterQualifications[i] != null) {
+ if (!checkedFocus) {
+ focusMethodBinding = this.matchLocator.getMethodBinding(this.pattern);
+ checkedFocus = true;
+ }
+ if (focusMethodBinding != null) {// textual comparison insufficient
+ TypeBinding[] parameters = focusMethodBinding.parameters;
+ if (parameters.length >= parameterCount) {
+ newLevel = argType.isEquivalentTo((parameters[i])) ? ACCURATE_MATCH : IMPOSSIBLE_MATCH;
+ foundLevel = true;
+ }
+ }
} else {
// TODO (frederic) use this call to refine accuracy on parameter types
// newLevel = resolveLevelForType(this.pattern.parameterSimpleNames[i], this.pattern.parameterQualifications[i], this.pattern.parametersTypeArguments[i], 0, argType);
@@ -328,7 +338,9 @@ protected int matchMethod(MethodBinding method, boolean skipImpossibleArg) {
if (skipImpossibleArg) {
// Do not consider match as impossible while finding declarations and source level >= 1.5
// (see bugs https://bugs.eclipse.org/bugs/show_bug.cgi?id=79990, 96761, 96763)
- newLevel = level;
+ if (!foundLevel) {
+ newLevel = level;
+ }
} else if (argType.isTypeVariable()) {
newLevel = level;
foundTypeVariable = true;
@@ -342,7 +354,8 @@ protected int matchMethod(MethodBinding method, boolean skipImpossibleArg) {
if (foundTypeVariable) {
if (!method.isStatic() && !method.isPrivate()) {
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=123836, No point in textually comparing type variables, captures etc with concrete types.
- MethodBinding focusMethodBinding = this.matchLocator.getMethodBinding(this.pattern);
+ if (!checkedFocus)
+ focusMethodBinding = this.matchLocator.getMethodBinding(this.pattern);
if (focusMethodBinding != null) {
if (matchOverriddenMethod(focusMethodBinding.declaringClass, focusMethodBinding, method)) {
return ACCURATE_MATCH;

Back to the top