stub hierarchy: keep qualified names only in package symbols

This commit is contained in:
peter
2016-06-25 14:03:03 +02:00
parent 4fddc9abcd
commit df8fa93a89
6 changed files with 53 additions and 52 deletions
@@ -22,8 +22,9 @@ import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
public class NameEnvironment extends UserDataHolderBase {
public static final int OBJECT_NAME = IndexTree.hashIdentifier("Object");
public final QualifiedName empty;
public final QualifiedName java_lang_Object;
public final QualifiedName java_lang;
public final QualifiedName java_lang_Enum;
public final QualifiedName[] annotation;
public final NamesEnumerator myNamesEnumerator;
@@ -31,7 +32,7 @@ public class NameEnvironment extends UserDataHolderBase {
public NameEnvironment() {
myNamesEnumerator = new NamesEnumerator();
empty = myNamesEnumerator.getFullName(new int[]{}, true);
java_lang_Object = fromString("java.lang.Object", true);
java_lang = fromString("java.lang", true);
java_lang_Enum = fromString("java.lang.Enum", true);
annotation = new QualifiedName[]{fromString("java.lang.annotation.Annotation", true)};
}
@@ -57,13 +58,6 @@ public class NameEnvironment extends UserDataHolderBase {
return ids[ids.length - 1];
}
public QualifiedName qualifiedName(Symbol owner, int shortName) {
if (shortName == NamesEnumerator.NO_NAME || owner == null || owner.myQualifiedName == null) {
return null;
}
return qualifiedName(owner.myQualifiedName, shortName, true);
}
public QualifiedName qualifiedName(QualifiedName prefix, int shortName, boolean create) {
if (shortName == NamesEnumerator.NO_NAME)
return null;
@@ -17,6 +17,7 @@ package com.intellij.psi.stubsHierarchy.impl;
import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree;
import com.intellij.psi.stubsHierarchy.stubs.*;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
@@ -38,20 +39,20 @@ public class StubEnter {
void unitEnter(Unit tree) {
PackageSymbol pkg = tree.myPackageId != null ? mySymbols.enterPackage(tree.myPackageId) : mySymbols.myRootPackage;
enter(tree.myClasses, tree.myUnitInfo, pkg);
enter(tree.myClasses, tree.myUnitInfo, pkg, pkg.myQualifiedName);
}
private void enter(ClassDeclaration[] trees, UnitInfo info, Symbol owner) {
private void enter(ClassDeclaration[] trees, UnitInfo info, Symbol owner, @Nullable QualifiedName ownerName) {
for (ClassDeclaration tree : trees) {
enter(tree, info, owner);
enter(tree, info, owner, ownerName);
}
}
private ClassSymbol[] enter(Declaration[] trees, UnitInfo info, Symbol owner) {
private ClassSymbol[] enter(Declaration[] trees, UnitInfo info, Symbol owner, @Nullable QualifiedName ownerName) {
ClassSymbol[] members = new ClassSymbol[trees.length];
int i = 0;
for (Declaration tree : trees) {
ClassSymbol member = enter(tree, info, owner);
ClassSymbol member = enter(tree, info, owner, ownerName);
if (member != null && member.myShortName != 0) {
members[i++] = member;
}
@@ -61,24 +62,24 @@ public class StubEnter {
return members;
}
private ClassSymbol enter(Declaration tree, UnitInfo info, Symbol owner) {
private ClassSymbol enter(Declaration tree, UnitInfo info, Symbol owner, QualifiedName ownerName) {
if (tree instanceof ClassDeclaration) {
return classEnter((ClassDeclaration)tree, info, owner);
return classEnter((ClassDeclaration)tree, info, owner, ownerName);
}
if (tree instanceof MemberDeclaration) {
memberEnter((MemberDeclaration)tree, info, owner);
memberEnter((MemberDeclaration)tree, info, owner, ownerName);
return null;
}
return null;
}
private void memberEnter(MemberDeclaration tree, UnitInfo info, Symbol owner) {
private void memberEnter(MemberDeclaration tree, UnitInfo info, Symbol owner, @Nullable QualifiedName ownerName) {
MemberSymbol mc = new MemberSymbol(owner);
ClassSymbol[] members = enter(tree.myDeclarations, info, mc);
ClassSymbol[] members = enter(tree.myDeclarations, info, mc, ownerName);
mc.setMembers(members);
}
private ClassSymbol classEnter(ClassDeclaration tree, UnitInfo info, Symbol owner) {
private ClassSymbol classEnter(ClassDeclaration tree, UnitInfo info, Symbol owner, @Nullable QualifiedName ownerName) {
int flags = checkFlags(tree.mods, owner);
if (info.getType() == IndexTree.BYTECODE) {
flags |= IndexTree.COMPILED;
@@ -88,12 +89,15 @@ public class StubEnter {
supers = myNameEnvironment.annotation;
}
ClassSymbol classSymbol = mySymbols.enterClass(tree.myClassAnchor, flags, tree.myName, owner, info, supers);
int name = tree.myName;
QualifiedName qname = name == NamesEnumerator.NO_NAME || ownerName == null ? null
: myNameEnvironment.qualifiedName(ownerName, name, true);
ClassSymbol classSymbol = mySymbols.enterClass(tree.myClassAnchor, flags, name, owner, info, supers, qname);
if (uncompleted != null) {
if (uncompleted != null) {
uncompleted.add(classSymbol);
}
ClassSymbol[] members = enter(tree.myDeclarations, info, classSymbol);
ClassSymbol[] members = enter(tree.myDeclarations, info, classSymbol, qname);
classSymbol.setMembers(members);
return classSymbol;
}
@@ -54,12 +54,12 @@ public class StubHierarchyConnector {
}
}
if (c.myQualifiedName == myNameEnvironment.java_lang_Object || c.isHierarchyIncomplete()) {
if (isJavaLangObject(c) || c.isHierarchyIncomplete()) {
c.mySuperClasses = Symbol.ClassSymbol.EMPTY_ARRAY;
} else {
for (Iterator<Symbol> iter = supertypes.iterator(); iter.hasNext();) {
Symbol s = iter.next();
if (!(s instanceof Symbol.ClassSymbol) || s.myQualifiedName == myNameEnvironment.java_lang_Object) {
if (!(s instanceof Symbol.ClassSymbol) || isJavaLangObject(s)) {
iter.remove();
}
}
@@ -77,4 +77,9 @@ public class StubHierarchyConnector {
c.myUnitInfo = null;
}
private boolean isJavaLangObject(Symbol s) {
return s.myShortName == NameEnvironment.OBJECT_NAME &&
s.myOwner instanceof Symbol.PackageSymbol &&
((Symbol.PackageSymbol)s.myOwner).myQualifiedName == myNameEnvironment.java_lang;
}
}
@@ -30,13 +30,11 @@ import java.util.Comparator;
public abstract class Symbol {
public int myFlags;
public int myShortName;
public final QualifiedName myQualifiedName;
public final Symbol myOwner;
public Symbol(int flags, Symbol owner, QualifiedName qualifiedName, int name) {
public Symbol(int flags, Symbol owner, int name) {
this.myFlags = flags;
this.myOwner = owner;
this.myQualifiedName = qualifiedName;
this.myShortName = name;
}
@@ -49,9 +47,6 @@ public abstract class Symbol {
return ClassSymbol.EMPTY_ARRAY;
}
public void setMembers(ClassSymbol[] members) {
}
public boolean isStatic() {
return BitUtil.isSet(myFlags, IndexTree.STATIC);
}
@@ -77,9 +72,11 @@ public abstract class Symbol {
}
public static class PackageSymbol extends Symbol {
final QualifiedName myQualifiedName;
public PackageSymbol(Symbol owner, QualifiedName fullname, int name) {
super(IndexTree.PACKAGE, owner, fullname, name);
setMembers(ClassSymbol.EMPTY_ARRAY);
super(IndexTree.PACKAGE, owner, name);
myQualifiedName = fullname;
}
}
@@ -97,13 +94,12 @@ public abstract class Symbol {
private ClassSymbol[] myMembers;
ClassSymbol(StubClassAnchor classAnchor,
int flags,
Symbol owner,
QualifiedName fullname,
int name,
UnitInfo unitInfo,
QualifiedName[] supers) {
super(flags | IndexTree.CLASS, owner, fullname, name);
int flags,
Symbol owner,
int name,
UnitInfo unitInfo,
QualifiedName[] supers) {
super(flags | IndexTree.CLASS, owner, name);
this.myClassAnchor = classAnchor;
this.mySuperNames = supers;
this.myUnitInfo = unitInfo;
@@ -184,7 +180,7 @@ public abstract class Symbol {
public static class MemberSymbol extends Symbol {
private ClassSymbol[] myMembers;
public MemberSymbol(Symbol owner) {
super(IndexTree.MEMBER, owner, null, NamesEnumerator.NO_NAME);
super(IndexTree.MEMBER, owner, NamesEnumerator.NO_NAME);
}
public ClassSymbol[] members() {
return myMembers;
@@ -63,21 +63,23 @@ public class Symbols {
return (ClassSymbol[])cs;
}
public ClassSymbol enterClass(ClassAnchor classAnchor, int flags, int shortName, Symbol owner, UnitInfo info, QualifiedName[] supers) {
QualifiedName qualifiedName = myNameEnvironment.qualifiedName(owner, shortName);
public ClassSymbol enterClass(ClassAnchor classAnchor,
int flags,
int shortName,
Symbol owner,
UnitInfo info,
QualifiedName[] supers,
@Nullable QualifiedName qualifiedName) {
StubClassAnchor stubClassAnchor = new StubClassAnchor(myClassSymbols.size(), classAnchor);
ClassSymbol c = new ClassSymbol(stubClassAnchor, flags, owner, qualifiedName, shortName, info, supers);
ClassSymbol c = new ClassSymbol(stubClassAnchor, flags, owner, shortName, info, supers);
myClassSymbols.add(c);
putClassByName(c);
if (qualifiedName != null) {
putClassByName(c, qualifiedName.myId);
}
return c;
}
private void putClassByName(ClassSymbol classSymbol) {
QualifiedName name = classSymbol.myQualifiedName;
// anonymous class
if (name == null)
return;
int nameId = name.myId;
private void putClassByName(ClassSymbol classSymbol, int nameId) {
ensureByNameCapacity(nameId);
Object cs = myClassSymbolsByNameId[nameId];
if (cs == null) {