mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
avoid qualified name destructuring during stub hierarchy resolve in src file data
This commit is contained in:
@@ -42,8 +42,8 @@ class NameEnvironment extends UserDataHolderBase {
|
||||
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));
|
||||
java_lang_Enum = new QualifiedName.Interned(fromString(CommonClassNames.JAVA_LANG_ENUM));
|
||||
java_lang_annotation_Annotation = new QualifiedName.Interned(fromString(CommonClassNames.JAVA_LANG_ANNOTATION_ANNOTATION));
|
||||
}
|
||||
|
||||
@QNameId
|
||||
|
||||
@@ -15,25 +15,66 @@
|
||||
*/
|
||||
package com.intellij.psi.stubsHierarchy.impl;
|
||||
|
||||
final class QualifiedName {
|
||||
public final int myId;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
QualifiedName(int id) {
|
||||
this.myId = id;
|
||||
abstract class QualifiedName {
|
||||
|
||||
abstract void resolveCandidates(StubResolver resolver, Symbol.ClassSymbol place, Set<Symbol.ClassSymbol> result)
|
||||
throws IncompleteHierarchyException;
|
||||
|
||||
static class OfComponents extends QualifiedName {
|
||||
@ShortName final int[] components;
|
||||
|
||||
OfComponents(int[] components) {
|
||||
this.components = components;
|
||||
}
|
||||
|
||||
@Override
|
||||
void resolveCandidates(StubResolver resolver, Symbol.ClassSymbol place, Set<Symbol.ClassSymbol> result)
|
||||
throws IncompleteHierarchyException {
|
||||
for (Symbol symbol : resolver.resolveBase(place, components)) {
|
||||
if (symbol instanceof Symbol.ClassSymbol) {
|
||||
result.add((Symbol.ClassSymbol)symbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return myId == 0;
|
||||
static class OfSingleComponent extends QualifiedName {
|
||||
@ShortName final int shortName;
|
||||
|
||||
OfSingleComponent(@ShortName int shortName) {
|
||||
this.shortName = shortName;
|
||||
}
|
||||
|
||||
@Override
|
||||
void resolveCandidates(StubResolver resolver, Symbol.ClassSymbol place, Set<Symbol.ClassSymbol> result)
|
||||
throws IncompleteHierarchyException {
|
||||
for (Symbol symbol : resolver.resolveUnqualified(place, shortName, false)) {
|
||||
if (symbol instanceof Symbol.ClassSymbol) {
|
||||
result.add((Symbol.ClassSymbol)symbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
return o instanceof QualifiedName && myId == ((QualifiedName)o).myId;
|
||||
}
|
||||
static class Interned extends QualifiedName {
|
||||
@QNameId final int id;
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return myId;
|
||||
Interned(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
void resolveCandidates(StubResolver resolver, Symbol.ClassSymbol place, Set<Symbol.ClassSymbol> result)
|
||||
throws IncompleteHierarchyException {
|
||||
Symbol.ClassSymbol[] candidates = resolver.findGlobalType(id);
|
||||
if (candidates.length == 0) {
|
||||
throw new IncompleteHierarchyException();
|
||||
}
|
||||
|
||||
Collections.addAll(result, candidates);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +76,17 @@ class SerializedUnit {
|
||||
}
|
||||
}
|
||||
|
||||
static QualifiedName readNameComponents(DataInput in) throws IOException {
|
||||
int length = DataInputOutputUtil.readINT(in);
|
||||
if (length == 1) return new QualifiedName.OfSingleComponent(in.readInt());
|
||||
|
||||
int[] result = new int[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
result[i] = in.readInt();
|
||||
}
|
||||
return new QualifiedName.OfComponents(result);
|
||||
}
|
||||
|
||||
// unit
|
||||
|
||||
private static void writeUnit(@NotNull DataOutput out, IndexTree.Unit value) throws IOException {
|
||||
@@ -117,7 +128,7 @@ class SerializedUnit {
|
||||
int stubId = DataInputOutputUtil.readINT(in);
|
||||
int mods = DataInputOutputUtil.readINT(in);
|
||||
@ShortName int name = in.readInt();
|
||||
@QNameId int[] superNames = readSupers(in);
|
||||
@CompactArray(QualifiedName.class) Object superNames = readSupers(in, info.getType() == IndexTree.BYTECODE);
|
||||
|
||||
@QNameId int qname = in.names.memberQualifiedName(ownerName, name);
|
||||
ClassSymbol symbol = in.stubEnter.classEnter(info, owner, stubId, mods, name, superNames, qname, in.fileId);
|
||||
@@ -135,14 +146,22 @@ class SerializedUnit {
|
||||
}
|
||||
}
|
||||
|
||||
private static @QNameId int[] readSupers(UnitInputStream in) throws IOException {
|
||||
@QNameId int[] superNames = new int[DataInputOutputUtil.readINT(in)];
|
||||
private static @CompactArray(QualifiedName.class) Object readSupers(UnitInputStream in, boolean intern) throws IOException {
|
||||
int length = DataInputOutputUtil.readINT(in);
|
||||
if (length == 0) return null;
|
||||
if (length == 1) return readSuperName(in, intern);
|
||||
|
||||
QualifiedName[] superNames = new QualifiedName[length];
|
||||
for (int i = 0; i < superNames.length; i++) {
|
||||
superNames[i] = in.names.readQualifiedName(in);
|
||||
superNames[i] = readSuperName(in, intern);
|
||||
}
|
||||
return superNames;
|
||||
}
|
||||
|
||||
private static QualifiedName readSuperName(UnitInputStream in, boolean intern) throws IOException {
|
||||
return intern ? new QualifiedName.Interned(in.names.readQualifiedName(in)) : readNameComponents(in);
|
||||
}
|
||||
|
||||
// members
|
||||
|
||||
private static void writeMembers(@NotNull DataOutput out, IndexTree.Decl[] decls) throws IOException {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.psi.stubsHierarchy.impl;
|
||||
|
||||
import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.BitUtil;
|
||||
import com.intellij.util.io.DataInputOutputUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -57,10 +58,10 @@ public class StubEnter {
|
||||
int stubId,
|
||||
int mods,
|
||||
@ShortName int name,
|
||||
@QNameId int[] superNames,
|
||||
@CompactArray(QualifiedName.class) Object superNames,
|
||||
@QNameId int qname, int fileId) throws IOException {
|
||||
int flags = checkFlags(mods, owner, info.getType() == IndexTree.BYTECODE);
|
||||
@CompactArray(QualifiedName.class) Object supers = internSupers(mods, superNames);
|
||||
@CompactArray(QualifiedName.class) Object supers = handleSpecialSupers(mods, superNames);
|
||||
|
||||
ClassSymbol classSymbol = mySymbols.enterClass(fileId, stubId, flags, name, owner, info, supers, qname);
|
||||
if (uncompleted != null) {
|
||||
@@ -71,27 +72,18 @@ public class StubEnter {
|
||||
|
||||
@Nullable
|
||||
@CompactArray(QualifiedName.class)
|
||||
Object internSupers(int flags, int[] superNames) {
|
||||
Object handleSpecialSupers(int flags, @CompactArray(QualifiedName.class) Object superNames) {
|
||||
if (BitUtil.isSet(flags, IndexTree.ANNOTATION)) {
|
||||
return myNameEnvironment.java_lang_annotation_Annotation;
|
||||
}
|
||||
|
||||
boolean isEnum = BitUtil.isSet(flags, IndexTree.ENUM);
|
||||
if (superNames.length == 0) {
|
||||
return isEnum ? myNameEnvironment.java_lang_Enum : null;
|
||||
}
|
||||
if (superNames.length == 1 && !isEnum) {
|
||||
return new QualifiedName(superNames[0]);
|
||||
if (BitUtil.isSet(flags, IndexTree.ENUM)) {
|
||||
if (superNames == null) return myNameEnvironment.java_lang_Enum;
|
||||
if (superNames instanceof QualifiedName) return new QualifiedName[]{(QualifiedName)superNames, myNameEnvironment.java_lang_Enum};
|
||||
return ArrayUtil.append((QualifiedName[])superNames, myNameEnvironment.java_lang_Enum);
|
||||
}
|
||||
|
||||
QualifiedName[] array = new QualifiedName[superNames.length + (isEnum ? 1 : 0)];
|
||||
for (int i = 0; i < superNames.length; i++) {
|
||||
array[i] = new QualifiedName(superNames[i]);
|
||||
}
|
||||
if (isEnum) {
|
||||
array[array.length - 1] = myNameEnvironment.java_lang_Enum;
|
||||
}
|
||||
return array;
|
||||
return superNames;
|
||||
}
|
||||
|
||||
public void connect1() {
|
||||
|
||||
+2
-19
@@ -29,23 +29,6 @@ public class StubHierarchyConnector {
|
||||
myResolve = new StubResolver(symbols, this);
|
||||
}
|
||||
|
||||
private void resolveName(Symbol.ClassSymbol place, QualifiedName name, Set<Symbol.ClassSymbol> result) throws IncompleteHierarchyException {
|
||||
if (place.isCompiled()) {
|
||||
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.myId, false)) {
|
||||
if (symbol instanceof Symbol.ClassSymbol) {
|
||||
result.add((Symbol.ClassSymbol)symbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void connect(Symbol sym) {
|
||||
Symbol.ClassSymbol c = (Symbol.ClassSymbol) sym;
|
||||
|
||||
@@ -65,10 +48,10 @@ public class StubHierarchyConnector {
|
||||
try {
|
||||
if (supers instanceof QualifiedName[]) {
|
||||
for (QualifiedName name : (QualifiedName[])supers) {
|
||||
resolveName(c, name, supertypes);
|
||||
name.resolveCandidates(myResolve, c, supertypes);
|
||||
}
|
||||
} else {
|
||||
resolveName(c, (QualifiedName)supers, supertypes);
|
||||
((QualifiedName)supers).resolveCandidates(myResolve, c, supertypes);
|
||||
}
|
||||
}
|
||||
catch (IncompleteHierarchyException ignore) {
|
||||
|
||||
@@ -35,21 +35,10 @@ public class StubResolver {
|
||||
}
|
||||
|
||||
// resolve class `sym` extends/implements `baseId`
|
||||
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;
|
||||
}
|
||||
|
||||
Set<Symbol> prev = resolveBase(sym, prefix, true);
|
||||
Set<Symbol> result = new HashSet<>();
|
||||
for (Symbol symbol : prev) {
|
||||
selectSym(symbol, shortName, processPackages, result);
|
||||
Set<Symbol> resolveBase(Symbol.ClassSymbol sym, @ShortName int[] qname) throws IncompleteHierarchyException {
|
||||
Set<Symbol> result = resolveUnqualified(sym, qname[0], qname.length > 1);
|
||||
for (int i = 1; i < qname.length; i++) {
|
||||
result = processQualifier(result, qname[i], i != qname.length - 1);
|
||||
}
|
||||
if (result.isEmpty()) {
|
||||
throw IncompleteHierarchyException.INSTANCE;
|
||||
@@ -57,6 +46,22 @@ public class StubResolver {
|
||||
return result;
|
||||
}
|
||||
|
||||
Set<Symbol> resolveUnqualified(Symbol.ClassSymbol sym, @ShortName final int shortName, boolean processPackages) throws IncompleteHierarchyException {
|
||||
Set<Symbol> symbols = findIdent(sym.myOwner, sym.myUnitInfo, shortName, processPackages);
|
||||
if (symbols.isEmpty()) {
|
||||
throw IncompleteHierarchyException.INSTANCE;
|
||||
}
|
||||
return symbols;
|
||||
}
|
||||
|
||||
private Set<Symbol> processQualifier(Set<Symbol> contextResults, @ShortName final int shortName, final boolean processPackages) throws IncompleteHierarchyException {
|
||||
Set<Symbol> result = new HashSet<>();
|
||||
for (Symbol symbol : contextResults) {
|
||||
selectSym(symbol, shortName, processPackages, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Set<Symbol> findIdent(Symbol startScope, UnitInfo info, @ShortName int name, boolean processPackages) throws IncompleteHierarchyException {
|
||||
Set<Symbol> result = new HashSet<Symbol>();
|
||||
|
||||
Reference in New Issue
Block a user