diff options
| author | Manoj Palat | 2014-10-29 08:04:11 +0000 |
|---|---|---|
| committer | Manoj Palat | 2014-10-29 08:04:11 +0000 |
| commit | dbfcb8d7fd5ffcddbe22e6b1ba82be9083ee4d44 (patch) | |
| tree | 50bc41b24e01a69730f00272bd34cae3a3c701ab | |
| parent | 05396c2aadbdf694b3e24041198b7173f55ce8f9 (diff) | |
| download | eclipse.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.
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; |
