### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java,v retrieving revision 1.91 diff -u -r1.91 MethodLocator.java --- search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java 21 Jan 2011 14:47:04 -0000 1.91 +++ search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java 17 Mar 2011 05:20:32 -0000 @@ -50,8 +50,8 @@ return this.pattern.fineGrain; } -private MethodBinding getMethodBinding(ReferenceBinding type, TypeBinding[] argumentTypes) { - MethodBinding[] methods = type.getMethods(this.pattern.selector); +private MethodBinding getMethodBinding(ReferenceBinding type, char[] methodName, TypeBinding[] argumentTypes) { + MethodBinding[] methods = type.getMethods(methodName); MethodBinding method = null; methodsLoop: for (int i=0, length=methods.length; i (declaringLevel & MATCH_LEVEL_MASK) ? declaringLevel : methodLevel; // return the weaker match } @@ -646,7 +646,7 @@ int declaringLevel; if (isVirtualInvoke(method, messageSend) && (messageSend.actualReceiverType instanceof ReferenceBinding)) { ReferenceBinding methodReceiverType = (ReferenceBinding) messageSend.actualReceiverType; - declaringLevel = resolveLevelAsSubtype(this.pattern.declaringSimpleName, this.pattern.declaringQualification, methodReceiverType, method.parameters); + declaringLevel = resolveLevelAsSubtype(this.pattern.declaringSimpleName, this.pattern.declaringQualification, methodReceiverType, method.selector, method.parameters); if (declaringLevel == IMPOSSIBLE_MATCH) { if (method.declaringClass == null || this.allSuperDeclaringTypeNames == null) { declaringLevel = INACCURATE_MATCH; @@ -674,12 +674,12 @@ * Returns INACCURATE_MATCH if resolve fails * Returns IMPOSSIBLE_MATCH if it doesn't. */ -protected int resolveLevelAsSubtype(char[] simplePattern, char[] qualifiedPattern, ReferenceBinding type, TypeBinding[] argumentTypes) { +protected int resolveLevelAsSubtype(char[] simplePattern, char[] qualifiedPattern, ReferenceBinding type, char[] methodName, TypeBinding[] argumentTypes) { if (type == null) return INACCURATE_MATCH; int level = resolveLevelForType(simplePattern, qualifiedPattern, type); if (level != IMPOSSIBLE_MATCH) { - MethodBinding method = argumentTypes == null ? null : getMethodBinding(type, argumentTypes); + MethodBinding method = argumentTypes == null ? null : getMethodBinding(type, methodName, argumentTypes); if (((method != null && !method.isAbstract()) || !type.isAbstract()) && !type.isInterface()) { // if concrete, then method is overridden level |= OVERRIDDEN_METHOD_FLAVOR; } @@ -688,11 +688,11 @@ // matches superclass if (!type.isInterface() && !CharOperation.equals(type.compoundName, TypeConstants.JAVA_LANG_OBJECT)) { - level = resolveLevelAsSubtype(simplePattern, qualifiedPattern, type.superclass(), argumentTypes); + level = resolveLevelAsSubtype(simplePattern, qualifiedPattern, type.superclass(), methodName, argumentTypes); if (level != IMPOSSIBLE_MATCH) { if (argumentTypes != null) { // need to verify if method may be overridden - MethodBinding method = getMethodBinding(type, argumentTypes); + MethodBinding method = getMethodBinding(type, methodName, argumentTypes); if (method != null) { // one method match in hierarchy if ((level & OVERRIDDEN_METHOD_FLAVOR) != 0) { // this method is already overridden on a super class, current match is impossible @@ -712,7 +712,7 @@ ReferenceBinding[] interfaces = type.superInterfaces(); if (interfaces == null) return INACCURATE_MATCH; for (int i = 0; i < interfaces.length; i++) { - level = resolveLevelAsSubtype(simplePattern, qualifiedPattern, interfaces[i], null); + level = resolveLevelAsSubtype(simplePattern, qualifiedPattern, interfaces[i], methodName, null); if (level != IMPOSSIBLE_MATCH) { if (!type.isAbstract() && !type.isInterface()) { // if concrete class, then method is overridden level |= OVERRIDDEN_METHOD_FLAVOR; #P org.eclipse.jdt.core.tests.model Index: src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java,v retrieving revision 1.216 diff -u -r1.216 JavaSearchBugsTests.java --- src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java 4 Mar 2011 09:26:34 -0000 1.216 +++ src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java 17 Mar 2011 05:20:40 -0000 @@ -699,6 +699,7 @@ suite.addTest(new JavaSearchBugsTests("testBug324189c")); suite.addTest(new JavaSearchBugsTests("testBug324189d")); suite.addTest(new JavaSearchBugsTests("testBug324189e")); + suite.addTest(new JavaSearchBugsTests("testBug339891")); return suite; } class TestCollector extends JavaSearchResultCollector { @@ -13452,4 +13453,32 @@ search("A.run()", METHOD, DECLARATIONS); assertSearchResults("src/b324189/A.java void b324189.A.run() [run] EXACT_MATCH"); } +/** + * @bug 339891: NPE when searching for method (with '*' wildcard character) + * @test Search for Worker.run() should not return results like TestWorker + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=339891" + */ +public void testBug339891() throws CoreException { + try { + IJavaProject project = createJavaProject("P"); + createFile("/P/Ref.java", + "public class Ref{\n"+ + " public void foo() {}\n"+ + "}\n"+ + "}\n"); + createFile("/P/Test.java", + "public class Test{\n"+ + " public void foo(Ref ref) {" + + " ref.foo();\n"+ + "}\n" + + "}\n"); + waitUntilIndexesReady(); + IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[]{project}, IJavaSearchScope.SOURCES); + search("Ref.*", METHOD, REFERENCES, EXACT_RULE, scope, this.resultCollector); + assertSearchResults("Test.java void Test.foo(Ref) [foo()] EXACT_MATCH"); + } finally { + deleteProject("P"); + } +} + } \ No newline at end of file