Bug 377883 - NPE on open Call Hierarchy
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java
index d85f742..a9b5963 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java
@@ -7,6 +7,8 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for
+ * Bug 377883 - NPE on open Call Hierarchy
*******************************************************************************/
package org.eclipse.jdt.core.tests.model;
@@ -1628,4 +1630,62 @@
deleteProject("P");
}
}
+
+ public void testBug401272() throws CoreException, IOException {
+ // the strategy of this test was outlined in https://bugs.eclipse.org/bugs/show_bug.cgi?id=401272#c16
+ try {
+ IJavaProject p = createJavaProject("P", new String[] { "src" }, new String[] { "JCL15_LIB", "/P/libStuff.jar" }, "bin", "1.5");
+
+ org.eclipse.jdt.core.tests.util.Util.createJar(
+ new String[] {
+ // this class must be our possibleMatch #401
+ // it must be binary to trigger the ClassFileMatchLocator
+ // the match must be impossible-due-to-mismatching-type-variables to trigger matchLocator.getMethodBinding(this.pattern);
+ "p2/A.java",
+ "package p2;\n" +
+ "public class A<E> {\n" +
+ " public int test(E b) { return 1; }\n" +
+ " void bar() {\n" +
+ " test(null);\n" +
+ " }\n" +
+ "}\n",
+ // this class contains the method we search for, possibleMatch #402
+ // (must be > 401 possibleMatches to trigger environment cleanup)
+ "p2/B.java",
+ "package p2;\n" +
+ "public class B<T> {\n" +
+ " public int test(T t) {\n" +
+ " return 0;\n" +
+ " }\n" +
+ "}\n"
+ },
+ p.getProject().getLocation().append("libStuff.jar").toOSString(), "1.5");
+ refresh(p);
+
+ createFolder("/P/src/pkg");
+ // 400 matches, which populate MatchLocator.unitScope
+ // all 400 matches are processed in one go of MatchLocator.locateMatches(JavaProject, PossibleMatch[], int, int)
+ // next round will call nameEnvironment.cleanup() but reuse MatchLocator.unitScope ==> BOOM
+ for (int i = 0; i < 400; i++) {
+ createFile("/P/src/pkg/Bug"+i+".java",
+ "package pkg;\n"+
+ "public class Bug"+i+" {\n"+
+ " String[] test(p2.B<String> b) {\n" +
+ " return b.test(\"S\");\n" +
+ " }\n" +
+ "}");
+ }
+
+ waitUntilIndexesReady();
+ IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { p },
+ IJavaSearchScope.SOURCES|IJavaSearchScope.SYSTEM_LIBRARIES|IJavaSearchScope.APPLICATION_LIBRARIES);
+
+ IMethod method = p.findType("p2.B").getMethods()[1];
+ search(method, METHOD, ALL_OCCURRENCES, scope, this.resultCollector);
+
+ assertSearchResults("libStuff.jar int p2.B.test(T) [No source] EXACT_MATCH"); // an NPE was thrown without the fix
+ } finally {
+ deleteProject("P");
+ }
+ }
}
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 1372e06..c1b487b 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,8 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for
+ * Bug 377883 - NPE on open Call Hierarchy
*******************************************************************************/
package org.eclipse.jdt.internal.core.search.matching;
@@ -1027,8 +1029,10 @@
public void initialize(JavaProject project, int possibleMatchSize) throws JavaModelException {
// clean up name environment only if there are several possible match as it is reused
// when only one possible match (bug 58581)
- if (this.nameEnvironment != null && possibleMatchSize != 1)
+ if (this.nameEnvironment != null && possibleMatchSize != 1) {
this.nameEnvironment.cleanup();
+ this.unitScope = null; // don't leak a reference to the cleaned-up name environment
+ }
SearchableEnvironment searchableEnvironment = project.newSearchableNameEnvironment(this.workingCopies);
@@ -1329,6 +1333,7 @@
this.progressMonitor.done();
if (this.nameEnvironment != null)
this.nameEnvironment.cleanup();
+ this.unitScope = null;
manager.flushZipFiles(this);
this.bindings = null;
}