a more compact storage for stub hierarchy names

This commit is contained in:
peter
2016-07-04 10:39:25 +02:00
parent 33273be517
commit af05034f6e
12 changed files with 161 additions and 227 deletions
@@ -30,11 +30,7 @@ public class Imports {
return (int)(importMask >>> 32);
}
public static QualifiedName getFullName(long importMask, NameEnvironment nameEnvironment) {
return nameEnvironment.qualifiedName(getFullNameId(importMask));
}
private static int getFullNameId(long importMask) {
static int getFullNameId(long importMask) {
int fullNameId = (int)importMask;
fullNameId &= mask;
return fullNameId;
@@ -48,8 +44,8 @@ public class Imports {
return BitUtil.isSet(importMask, staticMask);
}
public static long mkImport(QualifiedName fullname, boolean importStatic, boolean onDemand, int alias) {
long lower = fullname.myId;
public static long mkImport(@QNameId int fullname, boolean importStatic, boolean onDemand, int alias) {
long lower = fullname;
if (importStatic) lower |= staticMask;
if (onDemand) lower |= onDemandMask;
return (((long)alias) << 32) | lower;
@@ -16,60 +16,71 @@
package com.intellij.psi.stubsHierarchy.impl;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.psi.CommonClassNames;
import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree;
import org.jetbrains.annotations.Nullable;
import gnu.trove.TIntArrayList;
import gnu.trove.TLongIntHashMap;
import java.util.Arrays;
public class NameEnvironment extends UserDataHolderBase {
class NameEnvironment extends UserDataHolderBase {
public static final int OBJECT_NAME = IndexTree.hashIdentifier("Object");
public final QualifiedName empty;
public final QualifiedName java_lang;
public static final int NO_NAME = 0;
@QNameId public final int java_lang;
public final QualifiedName java_lang_Enum;
public final QualifiedName annotation;
public final NamesEnumerator myNamesEnumerator;
public final QualifiedName java_lang_annotation_Annotation;
public NameEnvironment() {
myNamesEnumerator = new NamesEnumerator();
empty = myNamesEnumerator.getFullName(new int[]{}, true);
java_lang = fromString("java.lang", true);
java_lang_Enum = fromString("java.lang.Enum", true);
annotation = fromString("java.lang.annotation.Annotation", true);
private final TIntArrayList mySuffixes = new TIntArrayList();
private final TIntArrayList myStems = new TIntArrayList();
private final TLongIntHashMap myConcatenations = new TLongIntHashMap();
NameEnvironment() {
mySuffixes.add(0);
myStems.add(0);
java_lang = fromString("java.lang");
java_lang_Enum = new QualifiedName(fromString(CommonClassNames.JAVA_LANG_ENUM));
java_lang_annotation_Annotation = new QualifiedName(fromString(CommonClassNames.JAVA_LANG_ANNOTATION_ANNOTATION));
}
@Nullable
public QualifiedName fromString(String s, boolean create) {
return myNamesEnumerator.getFullName(IndexTree.hashQualifiedName(s), create);
@QNameId
int fromString(String s) {
return internQualifiedName(IndexTree.hashQualifiedName(s));
}
public QualifiedName prefix(QualifiedName name) {
if (name.myComponents.length <= 1) {
return empty;
@QNameId int prefixId(@QNameId int nameId) {
return myStems.get(nameId);
}
@ShortName int shortName(@QNameId int id) {
return mySuffixes.get(id);
}
@QNameId int findExistingName(@QNameId int stemId, @ShortName int suffix) {
int existing = myConcatenations.get(pack(stemId, suffix));
return existing > 0 ? existing : -1;
}
@QNameId int internQualifiedName(@ShortName int[] qname) {
int id = 0;
for (int shortName : qname) {
id = qualifiedName(id, shortName);
}
return myNamesEnumerator.getFullName(Arrays.copyOf(name.myComponents, name.myComponents.length - 1), true);
return id;
}
public QualifiedName qualifiedName(int id) {
return myNamesEnumerator.qualifiedName(id);
@QNameId int qualifiedName(@QNameId int prefix, @ShortName int shortName) {
int existing = findExistingName(prefix, shortName);
return existing >= 0 ? existing : addName(prefix, shortName);
}
public int shortName(QualifiedName name) {
int[] ids = name.myComponents;
return ids[ids.length - 1];
private int addName(@QNameId int stemId, @ShortName int suffix) {
int newId = mySuffixes.size();
mySuffixes.add(suffix);
myStems.add(stemId);
myConcatenations.put(pack(stemId, suffix), newId);
return newId;
}
public QualifiedName qualifiedName(QualifiedName prefix, int shortName, boolean create) {
if (shortName == NamesEnumerator.NO_NAME)
return null;
if (prefix == null || prefix.isEmpty())
return myNamesEnumerator.getFullName(new int[]{shortName}, create);
int[] ids = Arrays.copyOf(prefix.myComponents, prefix.myComponents.length + 1);
ids[ids.length - 1] = shortName;
return myNamesEnumerator.getFullName(ids, create);
}
QualifiedName concat(int[] ids, boolean create) {
return myNamesEnumerator.getFullName(ids, create);
private static long pack(@QNameId int stemId, @ShortName int suffix) {
return ((long)suffix << 32) + stemId;
}
}
@@ -1,70 +0,0 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi.stubsHierarchy.impl;
import gnu.trove.TObjectHashingStrategy;
import gnu.trove.TObjectIntHashMap;
import java.util.Arrays;
public class NamesEnumerator {
final static int NO_NAME = 0;
private final TObjectIntHashMap<int[]> myFullNameMap = new TObjectIntHashMap<int[]>(new TObjectHashingStrategy<int[]>() {
@Override
public int computeHashCode(int[] object) {
return Arrays.hashCode(object);
}
@Override
public boolean equals(int[] o1, int[] o2) {
return Arrays.equals(o1, o2);
}
});
private QualifiedName[] myQualifiedNames = new QualifiedName[0x8000];
QualifiedName qualifiedName(int id) {
return myQualifiedNames[id];
}
public QualifiedName getFullName(int[] ids, boolean create) {
int id = myFullNameMap.get(ids);
if (id == 0 && create) {
id = myFullNameMap.size() + 1;
myFullNameMap.put(ids, id);
ensureFullCapacity(id);
myQualifiedNames[id] = new QualifiedName(id, ids);
}
return myQualifiedNames[id];
}
private void ensureFullCapacity(int maxIndex) {
if (maxIndex >= myQualifiedNames.length) {
int newLength = calculateNewLength(myQualifiedNames.length, maxIndex);
QualifiedName[] names1 = new QualifiedName[newLength];
System.arraycopy(myQualifiedNames, 0, names1, 0, myQualifiedNames.length);
myQualifiedNames = names1;
}
}
private static int calculateNewLength(int currentLength, int maxIndex) {
while (currentLength < maxIndex + 1)
currentLength *= 2;
return currentLength;
}
}
@@ -15,33 +15,21 @@
*/
package com.intellij.psi.stubsHierarchy.impl;
import java.util.Arrays;
public final class QualifiedName {
public static final QualifiedName[] EMPTY_ARRAY = new QualifiedName[0];
// unique id of this full name
final class QualifiedName {
public final int myId;
// ids of parts of this name
public final int[] myComponents;
QualifiedName(int id, int[] components) {
QualifiedName(int id) {
this.myId = id;
this.myComponents = components;
}
public boolean isEmpty() {
return myComponents.length == 0;
return myId == 0;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o instanceof QualifiedName) {
QualifiedName other = (QualifiedName)o;
return myId == other.myId && Arrays.equals(myComponents, other.myComponents);
}
return false;
return o instanceof QualifiedName && myId == ((QualifiedName)o).myId;
}
@Override
@@ -71,7 +71,7 @@ public class SingleClassHierarchy extends ClassHierarchy {
private static BitSet calcAnonymous(ClassSymbol[] classSymbols) {
BitSet answer = new BitSet();
for (ClassSymbol symbol : classSymbols) {
if (!symbol.isHierarchyIncomplete() && symbol.myShortName == NamesEnumerator.NO_NAME) {
if (!symbol.isHierarchyIncomplete() && symbol.myShortName == NameEnvironment.NO_NAME) {
answer.set(symbol.myAnchorId);
}
}
@@ -38,10 +38,8 @@ public class StubEnter {
}
void unitEnter(IndexTree.Unit unit, int fileId) {
PackageSymbol pkg = unit.myPackageName.length > 0
? mySymbols.enterPackage(myNameEnvironment.myNamesEnumerator.getFullName(unit.myPackageName, true))
: mySymbols.myRootPackage;
enter(unit.myDecls, UnitInfo.mkUnitInfo(unit.myUnitType, internImports(unit)), pkg, pkg.myQualifiedName, fileId);
@QNameId int pkgName = unit.myPackageName.length > 0 ? myNameEnvironment.internQualifiedName(unit.myPackageName) : 0;
enter(unit.myDecls, UnitInfo.mkUnitInfo(unit.myUnitType, internImports(unit)), mySymbols.enterPackage(pkgName), pkgName, fileId);
}
private long[] internImports(IndexTree.Unit unit) {
@@ -53,17 +51,17 @@ public class StubEnter {
}
private long processImport(IndexTree.Import anImport) {
QualifiedName fullname = myNameEnvironment.myNamesEnumerator.getFullName(anImport.myFullname, true);
int fullname = myNameEnvironment.internQualifiedName(anImport.myFullname);
return Imports.mkImport(fullname, anImport.myStaticImport, anImport.myOnDemand, anImport.myAlias);
}
private void enter(IndexTree.ClassDecl[] trees, UnitInfo info, Symbol owner, @Nullable QualifiedName ownerName, int fileId) {
private void enter(IndexTree.ClassDecl[] trees, UnitInfo info, Symbol owner, @QNameId int ownerName, int fileId) {
for (IndexTree.ClassDecl tree : trees) {
enter(tree, info, owner, ownerName, fileId);
}
}
private ClassSymbol[] enter(IndexTree.Decl[] trees, UnitInfo info, Symbol owner, @Nullable QualifiedName ownerName, int fileId) {
private ClassSymbol[] enter(IndexTree.Decl[] trees, UnitInfo info, Symbol owner, @QNameId int ownerName, int fileId) {
ClassSymbol[] members = new ClassSymbol[trees.length];
int i = 0;
for (IndexTree.Decl tree : trees) {
@@ -81,7 +79,7 @@ public class StubEnter {
return members;
}
private ClassSymbol enter(IndexTree.Decl tree, UnitInfo info, Symbol owner, QualifiedName ownerName, int fileId) {
private ClassSymbol enter(IndexTree.Decl tree, UnitInfo info, Symbol owner, @QNameId int ownerName, int fileId) {
if (tree instanceof IndexTree.ClassDecl) {
return classEnter((IndexTree.ClassDecl)tree, info, owner, ownerName, fileId);
}
@@ -92,20 +90,20 @@ public class StubEnter {
return null;
}
private void memberEnter(IndexTree.MemberDecl tree, UnitInfo info, Symbol owner, @Nullable QualifiedName ownerName, int fileId) {
private void memberEnter(IndexTree.MemberDecl tree, UnitInfo info, Symbol owner, @QNameId int ownerName, int fileId) {
MemberSymbol mc = new MemberSymbol(owner);
mc.setMembers(enter(tree.myDecls, info, mc, ownerName, fileId));
}
private ClassSymbol classEnter(IndexTree.ClassDecl tree, UnitInfo info, Symbol owner, @Nullable QualifiedName ownerName, int fileId) {
private ClassSymbol classEnter(IndexTree.ClassDecl tree, UnitInfo info, Symbol owner, @QNameId int ownerName, int fileId) {
int flags = checkFlags(tree.myMods, owner);
if (info.getType() == IndexTree.BYTECODE) {
flags |= IndexTree.COMPILED;
}
int name = tree.myName;
QualifiedName qname = name == NamesEnumerator.NO_NAME || ownerName == null ? null
: myNameEnvironment.qualifiedName(ownerName, name, true);
@QNameId int qname = name == NameEnvironment.NO_NAME || ownerName < 0 ? -1
: myNameEnvironment.qualifiedName(ownerName, name);
@CompactArray(QualifiedName.class) Object supers = internSupers(tree.myMods, tree.mySupers);
ClassSymbol classSymbol = mySymbols.enterClass(fileId, tree.myStubId, flags, name, owner, info, supers, qname);
@@ -122,7 +120,7 @@ public class StubEnter {
@CompactArray(QualifiedName.class)
private Object internSupers(int flags, int[][] superNames) {
if (BitUtil.isSet(flags, IndexTree.ANNOTATION)) {
return myNameEnvironment.annotation;
return myNameEnvironment.java_lang_annotation_Annotation;
}
boolean isEnum = BitUtil.isSet(flags, IndexTree.ENUM);
@@ -130,12 +128,12 @@ public class StubEnter {
return isEnum ? myNameEnvironment.java_lang_Enum : null;
}
if (superNames.length == 1 && !isEnum) {
return myNameEnvironment.concat(superNames[0], true);
return new QualifiedName(myNameEnvironment.internQualifiedName(superNames[0]));
}
QualifiedName[] array = new QualifiedName[superNames.length + (isEnum ? 1 : 0)];
for (int i = 0; i < superNames.length; i++) {
array[i] = myNameEnvironment.concat(superNames[i], true);
array[i] = new QualifiedName(myNameEnvironment.internQualifiedName(superNames[i]));
}
if (isEnum) {
array[array.length - 1] = myNameEnvironment.java_lang_Enum;
@@ -31,14 +31,14 @@ public class StubHierarchyConnector {
private void resolveName(Symbol.ClassSymbol place, QualifiedName name, Set<Symbol.ClassSymbol> result) throws IncompleteHierarchyException {
if (place.isCompiled()) {
Symbol.ClassSymbol[] candidates = myResolve.findGlobalType(name);
Symbol.ClassSymbol[] candidates = myResolve.findGlobalType(name.myId);
if (candidates.length == 0) {
throw new IncompleteHierarchyException();
}
Collections.addAll(result, candidates);
} else {
for (Symbol symbol : myResolve.resolveBase(place, name.myComponents)) {
for (Symbol symbol : myResolve.resolveBase(place, name.myId, false)) {
if (symbol instanceof Symbol.ClassSymbol) {
result.add((Symbol.ClassSymbol)symbol);
}
@@ -17,6 +17,7 @@ package com.intellij.psi.stubsHierarchy.impl;
import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree;
import com.intellij.util.BitUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -36,16 +37,22 @@ public class StubResolver {
}
// resolve class `sym` extends/implements `baseId`
Set<Symbol> resolveBase(Symbol.ClassSymbol sym, int[] baseId) throws IncompleteHierarchyException {
Set<Symbol> result = findIdent(sym.myOwner, sym.myUnitInfo, baseId[0], baseId.length > 1);
for (int i = 1; i < baseId.length; i++) {
Set<Symbol> prev = result;
int k = (i == baseId.length - 1) ? IndexTree.CLASS : IndexTree.CLASS | IndexTree.PACKAGE;
result = new HashSet<>();
for (Symbol symbol : prev) {
selectSym(symbol, baseId[i], k, result);
Set<Symbol> resolveBase(Symbol.ClassSymbol sym, @QNameId int name, boolean processPackages) throws IncompleteHierarchyException {
@QNameId int prefix = myNameEnvironment.prefixId(name);
@ShortName int shortName = myNameEnvironment.shortName(name);
if (prefix == NameEnvironment.NO_NAME) {
Set<Symbol> result = findIdent(sym.myOwner, sym.myUnitInfo, shortName, processPackages);
if (result.isEmpty()) {
throw IncompleteHierarchyException.INSTANCE;
}
return result;
}
int k = processPackages ? IndexTree.CLASS | IndexTree.PACKAGE : IndexTree.CLASS;
Set<Symbol> prev = resolveBase(sym, prefix, true);
Set<Symbol> result = new HashSet<>();
for (Symbol symbol : prev) {
selectSym(symbol, shortName, k, result);
}
if (result.isEmpty()) {
throw IncompleteHierarchyException.INSTANCE;
@@ -54,15 +61,15 @@ public class StubResolver {
}
@NotNull
private Set<Symbol> findIdent(Symbol startScope, UnitInfo info, int name, boolean processPackages) throws IncompleteHierarchyException {
private Set<Symbol> findIdent(Symbol startScope, UnitInfo info, @ShortName int name, boolean processPackages) throws IncompleteHierarchyException {
Set<Symbol> result = new HashSet<Symbol>();
findType(startScope, name, result);
findGlobalType(info, name, result);
if (processPackages) {
Symbol.PackageSymbol pkg = mySymbols.getPackage(myNameEnvironment.qualifiedName(null, name, false));
if (pkg != null)
result.add(pkg);
@QNameId int nameId = myNameEnvironment.findExistingName(0, name);
Symbol.PackageSymbol pkg = nameId < 0 ? null : mySymbols.getPackage(nameId);
ContainerUtil.addIfNotNull(result, pkg);
}
return result;
}
@@ -76,16 +83,16 @@ public class StubResolver {
}
// resolving `receiver.name`
private void selectSym(Symbol receiver, int name, int kind, Set<Symbol> symbols) throws IncompleteHierarchyException {
private void selectSym(Symbol receiver, @ShortName int name, int kind, Set<Symbol> symbols) throws IncompleteHierarchyException {
if (receiver.isPackage())
findIdentInPackage((Symbol.PackageSymbol)receiver, name, kind, symbols);
else
findMemberType(receiver, name, symbols);
}
private void findIdentInPackage(Symbol.PackageSymbol pck, int name, int kind, Set<Symbol> symbols) {
QualifiedName fullname = mySymbols.myNameEnvironment.qualifiedName(pck.myQualifiedName, name, false);
if (fullname == null) {
private void findIdentInPackage(Symbol.PackageSymbol pck, @ShortName int name, int kind, Set<Symbol> symbols) {
@QNameId int fullname = mySymbols.myNameEnvironment.findExistingName(pck.myQualifiedName, name);
if (fullname < 0) {
return;
}
if (BitUtil.isSet(kind, IndexTree.PACKAGE)) {
@@ -94,11 +101,11 @@ public class StubResolver {
symbols.add(pkg);
}
if (BitUtil.isSet(kind, IndexTree.CLASS)) {
Collections.addAll(symbols, loadClass(fullname));
Collections.addAll(symbols, findGlobalType(fullname));
}
}
private void findMemberType(Symbol s, int name, Set<Symbol> symbols) throws IncompleteHierarchyException {
private void findMemberType(Symbol s, @ShortName int name, Set<Symbol> symbols) throws IncompleteHierarchyException {
if (s.isClass()) {
processInheritedMembers((Symbol.ClassSymbol)s, name, false, symbols, null);
} else {
@@ -107,7 +114,7 @@ public class StubResolver {
}
private void processInheritedMembers(Symbol.ClassSymbol s,
int name,
@ShortName int name,
boolean requireStatic,
Set<Symbol> symbols,
@Nullable Set<Symbol> processed) throws IncompleteHierarchyException {
@@ -128,23 +135,19 @@ public class StubResolver {
}
}
private Symbol.ClassSymbol[] loadClass(@NotNull QualifiedName fqn) {
return mySymbols.loadClass(fqn);
public Symbol.ClassSymbol[] findGlobalType(@QNameId int nameId) {
return mySymbols.loadClass(nameId);
}
public Symbol.ClassSymbol[] findGlobalType(@NotNull QualifiedName name) {
return loadClass(name);
}
private void findGlobalType(UnitInfo info, int name, Set<Symbol> symbols) throws IncompleteHierarchyException {
private void findGlobalType(UnitInfo info, @ShortName int name, Set<Symbol> symbols) throws IncompleteHierarchyException {
for (long anImport : Translator.getDefaultImports(info.getType(), myNameEnvironment))
handleImport(anImport, name, symbols);
for (long anImport : info.getImports())
handleImport(anImport, name, symbols);
}
public void handleImport(long tree, int name, Set<Symbol> symbols) throws IncompleteHierarchyException {
QualifiedName fullname = Imports.getFullName(tree, myNameEnvironment);
public void handleImport(long tree, @ShortName int name, Set<Symbol> symbols) throws IncompleteHierarchyException {
@QNameId int fullname = Imports.getFullNameId(tree);
if (Imports.isOnDemand(tree)) {
if (Imports.isStatic(tree)) {
for (Symbol.ClassSymbol p : findGlobalType(fullname))
@@ -155,12 +158,12 @@ public class StubResolver {
}
}
else {
QualifiedName prefix = myNameEnvironment.prefix(fullname);
if (prefix.isEmpty()) {
@QNameId int prefix = myNameEnvironment.prefixId(fullname);
if (prefix == 0) {
return;
}
int shortName = myNameEnvironment.shortName(fullname);
int alias = Imports.getAlias(tree);
@ShortName int shortName = myNameEnvironment.shortName(fullname);
@ShortName int alias = Imports.getAlias(tree);
boolean shouldImport = ((alias & name) == name) || shortName == name;
if (!shouldImport)
return;
@@ -175,22 +178,19 @@ public class StubResolver {
}
// handling of `import prefix.*`
private void importAll(@NotNull final QualifiedName prefix, int suffix, final Set<Symbol> symbols) {
QualifiedName fullname = myNameEnvironment.qualifiedName(prefix, suffix, false);
// existing only
if (fullname != null) {
Symbol.ClassSymbol[] ss = findGlobalType(fullname);
Collections.addAll(symbols, ss);
}
private void importAll(@QNameId int prefix, @ShortName int suffix, final Set<Symbol> symbols) {
@QNameId int fullname = myNameEnvironment.findExistingName(prefix, suffix);
if (fullname >= 0) {
Collections.addAll(symbols, findGlobalType(fullname));
}
}
// handling of import static `tsym.name` as
private void importNamedStatic(final Symbol.ClassSymbol tsym, final int name, final Set<Symbol> symbols) throws IncompleteHierarchyException {
private void importNamedStatic(final Symbol.ClassSymbol tsym, @ShortName final int name, final Set<Symbol> symbols) throws IncompleteHierarchyException {
processInheritedMembers(tsym, name, true, symbols, null);
}
private static void processMembers(Symbol.ClassSymbol[] members, int name, Set<Symbol> symbols, boolean requireStatic) {
private static void processMembers(Symbol.ClassSymbol[] members, @ShortName int name, Set<Symbol> symbols, boolean requireStatic) {
int index = getIndex(name, members);
if (index < 0) return;
@@ -74,9 +74,9 @@ public abstract class Symbol {
}
public static class PackageSymbol extends Symbol {
final QualifiedName myQualifiedName;
@QNameId final int myQualifiedName;
public PackageSymbol(Symbol owner, QualifiedName fullname, int name) {
public PackageSymbol(Symbol owner, @QNameId int fullname, int name) {
super(IndexTree.PACKAGE, owner, name);
myQualifiedName = fullname;
}
@@ -186,7 +186,7 @@ public abstract class Symbol {
@CompactArray(ClassSymbol.class) private Object myMembers = null;
MemberSymbol(Symbol owner) {
super(IndexTree.MEMBER, owner, NamesEnumerator.NO_NAME);
super(IndexTree.MEMBER, owner, NameEnvironment.NO_NAME);
}
MemberSymbol(int flags, Symbol owner, int name) {
@@ -21,35 +21,29 @@ public class Symbols {
private Object[] myClassSymbolsByNameId = new Object[0x8000];
protected Symbols() {
myRootPackage = new PackageSymbol(null, myNameEnvironment.empty, NamesEnumerator.NO_NAME);
myPackages.put(myNameEnvironment.empty.myId, myRootPackage);
myRootPackage = new PackageSymbol(null, 0, NameEnvironment.NO_NAME);
myPackages.put(0, myRootPackage);
}
public PackageSymbol enterPackage(QualifiedName qualifiedName) {
PackageSymbol p = myPackages.get(qualifiedName.myId);
public PackageSymbol enterPackage(@QNameId int qualifiedName) {
PackageSymbol p = myPackages.get(qualifiedName);
if (p == null) {
PackageSymbol owner = enterPackage(myNameEnvironment.prefix(qualifiedName));
PackageSymbol owner = enterPackage(myNameEnvironment.prefixId(qualifiedName));
int shortName = myNameEnvironment.shortName(qualifiedName);
p = new PackageSymbol(owner, qualifiedName, shortName);
myPackages.put(qualifiedName.myId, p);
myPackages.put(qualifiedName, p);
}
return p;
}
@Nullable
public PackageSymbol getPackage(QualifiedName qualifiedName) {
if (qualifiedName == null)
return null;
return myPackages.get(qualifiedName.myId);
PackageSymbol getPackage(@QNameId int qualifiedName) {
return myPackages.get(qualifiedName);
}
@NotNull
public ClassSymbol[] loadClass(@NotNull QualifiedName qualifiedName) {
int i = qualifiedName.myId;
if (i >= myClassSymbolsByNameId.length) {
return ClassSymbol.EMPTY_ARRAY;
}
return getClassSymbols(i);
ClassSymbol[] loadClass(@QNameId int name) {
return name >= myClassSymbolsByNameId.length ? ClassSymbol.EMPTY_ARRAY : getClassSymbols(name);
}
private ClassSymbol[] getClassSymbols(int id) {
@@ -70,12 +64,12 @@ public class Symbols {
Symbol owner,
UnitInfo info,
@CompactArray(QualifiedName.class) Object supers,
@Nullable QualifiedName qualifiedName) {
@QNameId int qualifiedName) {
int anchorId = myClassAnchors.registerClass(fileId, stubId);
ClassSymbol c = new ClassSymbol(anchorId, flags, owner, shortName, info, supers);
myClassSymbols.add(c);
if (qualifiedName != null) {
putClassByName(c, qualifiedName.myId);
if (qualifiedName >= 0) {
putClassByName(c, qualifiedName);
}
return c;
}
@@ -33,7 +33,7 @@ public class Translator {
private static long[] createDefaultJavaImports(NameEnvironment nameEnvironment) {
return new long[]{
Imports.mkImport(nameEnvironment.fromString("java.lang", true), false, true, 0)
Imports.mkImport(nameEnvironment.fromString("java.lang"), false, true, 0)
};
}
@@ -48,14 +48,14 @@ public class Translator {
private static long[] createDefaultGroovyImports(NameEnvironment nameEnvironment) {
return new long[] {
Imports.mkImport(nameEnvironment.fromString("java.lang", true), false, true, 0),
Imports.mkImport(nameEnvironment.fromString("java.util", true), false, true, 0),
Imports.mkImport(nameEnvironment.fromString("java.io", true), false, true, 0),
Imports.mkImport(nameEnvironment.fromString("java.net", true), false, true, 0),
Imports.mkImport(nameEnvironment.fromString("groovy.lang", true), false, true, 0),
Imports.mkImport(nameEnvironment.fromString("groovy.util", true), false, true, 0),
Imports.mkImport(nameEnvironment.fromString("java.math.BigInteger", true), false, true, 0),
Imports.mkImport(nameEnvironment.fromString("java.math.BigDecimal", true), false, true, 0),
Imports.mkImport(nameEnvironment.fromString("java.lang"), false, true, 0),
Imports.mkImport(nameEnvironment.fromString("java.util"), false, true, 0),
Imports.mkImport(nameEnvironment.fromString("java.io"), false, true, 0),
Imports.mkImport(nameEnvironment.fromString("java.net"), false, true, 0),
Imports.mkImport(nameEnvironment.fromString("groovy.lang"), false, true, 0),
Imports.mkImport(nameEnvironment.fromString("groovy.util"), false, true, 0),
Imports.mkImport(nameEnvironment.fromString("java.math.BigInteger"), false, true, 0),
Imports.mkImport(nameEnvironment.fromString("java.math.BigDecimal"), false, true, 0),
};
}
@@ -15,8 +15,12 @@
*/
package com.intellij.psi.stubsHierarchy.impl;
import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* This annotation exists for documentation purposes only.<p/>
@@ -24,10 +28,23 @@ import java.lang.annotation.RetentionPolicy;
* The value annotated with this annotation is used to save memory when storing mostly-singular or empty collections.
* For empty collection, 'null' value is used. For one-element collection, the value is the single element. Otherwise,
* an array is used. Possible component types are specified in the annotation value.
*
* @author peter
*/
@Retention(RetentionPolicy.SOURCE)
public @interface CompactArray {
@Target(ElementType.TYPE_USE)
@interface CompactArray {
Class[] value();
}
/**
* int id of a qualified name in a {@link NameEnvironment}
*/
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE_USE)
@interface QNameId { }
/**
* int hash of a qualified name part, produced by {@link IndexTree#hashIdentifier(String)}
*/
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE_USE)
@interface ShortName { }