Skip to content

Commit 23ffa6a

Browse files
datho7561rgrunber
authored andcommitted
Cache type hierarchy in DOMCompletionUtil.findInSupers
Speeds up completion of types significantly, since the type hierarchy of `java.lang.Exception` is only created once every completion invocation. Signed-off-by: David Thompson <[email protected]>
1 parent 989d758 commit 23ffa6a

File tree

4 files changed

+35
-15
lines changed

4 files changed

+35
-15
lines changed

org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacBindingResolver.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import java.util.Map;
2020
import java.util.Objects;
2121
import java.util.function.Function;
22-
import java.util.stream.Collectors;
2322
import java.util.stream.Stream;
2423

2524
import javax.lang.model.element.Element;

org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/codeassist/DOMCompletionEngine.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ public class DOMCompletionEngine implements ICompletionEngine {
209209
private ASTNode toComplete;
210210
private String textContent;
211211
private ExtendsOrImplementsInfo extendsOrImplementsInfo;
212+
213+
private Map<String, ITypeHierarchy> typeHierarchyCache = new HashMap<>();
212214

213215
class Bindings {
214216
// those need to be list since the order matters
@@ -4126,7 +4128,7 @@ private CompletionProposal toProposal(IType type) {
41264128
inSamePackage = type.getPackageFragment().getElementName().isEmpty();
41274129
}
41284130
boolean inCatchClause = DOMCompletionUtil.findParent(this.toComplete, new int[] { ASTNode.CATCH_CLAUSE }) != null;
4129-
boolean subclassesException = DOMCompletionUtil.findInSupers(type, "Ljava/lang/Exception;");
4131+
boolean subclassesException = DOMCompletionUtil.findInSupers(type, "Ljava/lang/Exception;", this.workingCopyOwner, this.typeHierarchyCache);
41304132
int relevance = RelevanceConstants.R_DEFAULT
41314133
+ RelevanceConstants.R_RESOLVED
41324134
+ RelevanceUtils.computeRelevanceForInteresting(type, expectedTypes)
@@ -4136,7 +4138,7 @@ private CompletionProposal toProposal(IType type) {
41364138
+ RelevanceUtils.computeRelevanceForQualification(!type.getFullyQualifiedName().startsWith("java.") && !nodeInImports && !fromCurrentCU && !inSamePackage && !typeIsImported, this.prefix, this.qualifiedPrefix)
41374139
+ (type.getFullyQualifiedName().startsWith("java.") ? RelevanceConstants.R_JAVA_LIBRARY : 0)
41384140
// sometimes subclasses and superclasses are considered, sometimes they aren't
4139-
+ (inCatchClause ? RelevanceUtils.computeRelevanceForExpectingType(type, expectedTypes) : RelevanceUtils.simpleComputeRelevanceForExpectingType(type, expectedTypes))
4141+
+ (inCatchClause ? RelevanceUtils.computeRelevanceForExpectingType(type, expectedTypes, this.workingCopyOwner, this.typeHierarchyCache) : RelevanceUtils.simpleComputeRelevanceForExpectingType(type, expectedTypes))
41404142
+ RelevanceUtils.computeRelevanceForCaseMatching(this.prefix.toCharArray(), simpleName, this.assistOptions);
41414143
try {
41424144
if (type.isAnnotation()) {

org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/codeassist/DOMCompletionUtil.java

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import java.util.HashSet;
1414
import java.util.LinkedList;
1515
import java.util.List;
16+
import java.util.Map;
1617
import java.util.Queue;
1718
import java.util.Set;
1819
import java.util.function.Consumer;
@@ -21,6 +22,8 @@
2122
import org.eclipse.jdt.core.IType;
2223
import org.eclipse.jdt.core.ITypeHierarchy;
2324
import org.eclipse.jdt.core.JavaModelException;
25+
import org.eclipse.jdt.core.Signature;
26+
import org.eclipse.jdt.core.WorkingCopyOwner;
2427
import org.eclipse.jdt.core.dom.ASTNode;
2528
import org.eclipse.jdt.core.dom.ASTVisitor;
2629
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
@@ -145,30 +148,43 @@ public static boolean findInSupers(ITypeBinding root, String keyOfTypeToFind) {
145148
}
146149
return false;
147150
}
148-
151+
149152
/**
150153
* Returns true if the type indicated by keyOfTypeToFind is a superclass of root.
151154
*
152-
* @param root the class to begin searching in
153-
* @param keyOfTypeToFind the key of the class to find
155+
* @param root the class to begin searching in
156+
* @param keyOfTypeToFind the key of the class to find
157+
* @param workignCopyOwner the working copy owner
158+
* @param hierarchyCache the cache of existing type hierarchies (rebuilding
159+
* the type hierarchy is very expensive)
154160
* @return true if the type indicated by keyOfTypeToFind is a superclass of root
155161
*/
156-
public static boolean findInSupers(IType root, String keyOfTypeToFind) {
162+
public static boolean findInSupers(IType root, String keyOfTypeToFind, WorkingCopyOwner workingCopyOwner, Map<String, ITypeHierarchy> hierarchyCache) {
157163
if (root.getKey().equals(keyOfTypeToFind)) {
158164
return true;
159165
}
160-
ITypeHierarchy hierarchy;
161166
try {
162-
hierarchy = root.newSupertypeHierarchy(new NullProgressMonitor());
163-
for (IType superType : hierarchy.getAllSupertypes(root)) {
164-
if (superType.getKey().equals(keyOfTypeToFind)) {
165-
return true;
167+
String signature = SignatureUtils.getSignatureForTypeKey(keyOfTypeToFind);
168+
IType typeToFind = root.getJavaProject().findType(Signature.getSignatureQualifier(signature)+ "." + Signature.getSignatureSimpleName(signature));
169+
if (typeToFind != null) {
170+
ITypeHierarchy hierarchy;
171+
if (hierarchyCache.containsKey(keyOfTypeToFind)) {
172+
hierarchy = hierarchyCache.get(keyOfTypeToFind);
173+
} else {
174+
hierarchy = typeToFind.newTypeHierarchy(root.getJavaProject(), workingCopyOwner, new NullProgressMonitor());
175+
hierarchyCache.put(keyOfTypeToFind, hierarchy);
176+
}
177+
178+
for (IType subType : hierarchy.getAllSubtypes(typeToFind)) {
179+
if (subType.getKey().equals(root.getKey())) {
180+
return true;
181+
}
166182
}
167183
}
168184
return false;
169185
} catch (JavaModelException e) {
170186
return false;
171187
}
172188
}
173-
189+
174190
}

org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/codeassist/RelevanceUtils.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@
1010
*******************************************************************************/
1111
package org.eclipse.jdt.internal.codeassist;
1212

13+
import java.util.Map;
1314
import java.util.Objects;
1415
import java.util.Set;
1516

1617
import org.eclipse.jdt.core.IJavaElement;
1718
import org.eclipse.jdt.core.IPackageFragment;
1819
import org.eclipse.jdt.core.IType;
20+
import org.eclipse.jdt.core.ITypeHierarchy;
21+
import org.eclipse.jdt.core.WorkingCopyOwner;
1922
import org.eclipse.jdt.core.compiler.CharOperation;
2023
import org.eclipse.jdt.core.dom.IBinding;
2124
import org.eclipse.jdt.core.dom.IMethodBinding;
@@ -134,7 +137,7 @@ static int computeRelevanceForExpectingType(ITypeBinding proposalType, ExpectedT
134137
return 0;
135138
}
136139

137-
static int computeRelevanceForExpectingType(IType proposalType, ExpectedTypes expectedTypes) {
140+
static int computeRelevanceForExpectingType(IType proposalType, ExpectedTypes expectedTypes, WorkingCopyOwner workingCopyOwner, Map<String, ITypeHierarchy> typeHierarchyCache) {
138141
if (proposalType != null) {
139142
IPackageFragment packageFragment = (IPackageFragment)proposalType.getAncestor(IJavaElement.PACKAGE_FRAGMENT);
140143
int relevance = 0;
@@ -145,7 +148,7 @@ static int computeRelevanceForExpectingType(IType proposalType, ExpectedTypes ex
145148
}
146149
for (ITypeBinding expectedType : expectedTypes.getExpectedTypes()) {
147150
if(expectedTypes.allowsSubtypes()
148-
&& DOMCompletionUtil.findInSupers(proposalType, expectedType.getKey())) {
151+
&& DOMCompletionUtil.findInSupers(proposalType, expectedType.getKey(), workingCopyOwner, typeHierarchyCache)) {
149152
if (expectedType.getKey().equals(proposalType.getKey())) {
150153
return RelevanceConstants.R_EXACT_EXPECTED_TYPE;
151154
// ??? I'm just guessing on the default packages name here, it might be the empty string

0 commit comments

Comments
 (0)