stub hierarchy: store supers in a more compact form

This commit is contained in:
peter
2016-06-25 14:03:04 +02:00
parent d30e4bceda
commit 602e2e08f7
2 changed files with 43 additions and 28 deletions
@@ -53,34 +53,35 @@ public class StubHierarchyConnector {
((Symbol.ClassSymbol)c.myOwner).connect(this);
}
Object supers = c.mySuperClasses;
if (supers == null) {
c.setSupers(Collections.emptySet());
return;
}
// Determine supertype.
Set<Symbol.ClassSymbol> supertypes = new HashSet<>();
for (QualifiedName name : c.mySuperNames) {
try {
resolveName(c, name, supertypes);
}
catch (IncompleteHierarchyException ignore) {
c.markHierarchyIncomplete();
return;
}
}
if (isJavaLangObject(c) || c.isHierarchyIncomplete()) {
c.mySuperClasses = Symbol.ClassSymbol.EMPTY_ARRAY;
} else {
for (Iterator<Symbol.ClassSymbol> iter = supertypes.iterator(); iter.hasNext();) {
Symbol.ClassSymbol s = iter.next();
if (isJavaLangObject(s)) {
iter.remove();
try {
if (supers instanceof QualifiedName[]) {
for (QualifiedName name : (QualifiedName[])supers) {
resolveName(c, name, supertypes);
}
} else {
resolveName(c, (QualifiedName)supers, supertypes);
}
c.mySuperClasses =
supertypes.isEmpty() ? Symbol.ClassSymbol.EMPTY_ARRAY : supertypes.toArray(new Symbol.ClassSymbol[supertypes.size()]);
}
catch (IncompleteHierarchyException ignore) {
c.markHierarchyIncomplete();
return;
}
// cleaning up
c.mySuperNames = null;
c.myUnitInfo = null;
for (Iterator<Symbol.ClassSymbol> iterator = supertypes.iterator(); iterator.hasNext();) {
if (isJavaLangObject(iterator.next())) {
iterator.remove();
}
}
c.setSupers(supertypes);
}
private boolean isJavaLangObject(Symbol s) {
@@ -21,7 +21,9 @@ import com.intellij.util.BitUtil;
import gnu.trove.TIntHashSet;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.Comparator;
import java.util.Set;
/**
* Java symbols needed for hierarchy building. Mostly classes ({@link ClassSymbol}) or packages ({@link PackageSymbol}),
@@ -88,9 +90,14 @@ public abstract class Symbol {
public static final ClassSymbol[] EMPTY_ARRAY = new ClassSymbol[0];
final StubClassAnchor myClassAnchor;
ClassSymbol[] mySuperClasses;
/**
* null for empty 'supers' list
* ClassSymbol/QualifiedName for a single resolved/unresolved super
* ClassSymbol[]/QualifiedName[] for multiple resolved/unresolved supers
*/
Object mySuperClasses;
UnitInfo myUnitInfo;
QualifiedName[] mySuperNames;
private ClassSymbol[] myMembers;
ClassSymbol(StubClassAnchor classAnchor,
@@ -101,7 +108,7 @@ public abstract class Symbol {
QualifiedName[] supers) {
super(flags | IndexTree.CLASS, owner, name);
this.myClassAnchor = classAnchor;
this.mySuperNames = supers;
this.mySuperClasses = supers.length == 0 ? null : supers.length == 1 ? supers[0] : supers;
this.myUnitInfo = unitInfo;
}
@@ -133,7 +140,9 @@ public abstract class Symbol {
@NotNull
ClassSymbol[] rawSuperClasses() {
assert isConnectStarted();
return mySuperClasses == null ? EMPTY_ARRAY : mySuperClasses;
return mySuperClasses instanceof ClassSymbol ? new ClassSymbol[]{(ClassSymbol)mySuperClasses} :
mySuperClasses instanceof ClassSymbol[] ? (ClassSymbol[])mySuperClasses :
EMPTY_ARRAY;
}
boolean isCompiled() {
@@ -149,12 +158,17 @@ public abstract class Symbol {
}
void markHierarchyIncomplete() {
mySuperClasses = EMPTY_ARRAY;
mySuperNames = null;
myUnitInfo = null;
setSupers(Collections.emptySet());
myFlags = BitUtil.set(myFlags, HIERARCHY_INCOMPLETE, true);
}
void setSupers(Set<ClassSymbol> supers) {
mySuperClasses = supers.isEmpty() ? null :
supers.size() == 1 ? supers.iterator().next() :
supers.toArray(new ClassSymbol[supers.size()]);
myUnitInfo = null;
}
boolean isHierarchyIncomplete() {
return BitUtil.isSet(myFlags, HIERARCHY_INCOMPLETE);
}