public class BackwardReferenceIndexUtil {
static void registerFile(String filePath,
- Collection<? extends JavacRef> refs,
+ TObjectIntHashMap<? extends JavacRef> refs,
List<JavacDef> defs,
final BackwardReferenceIndexWriter writer) {
- final int fileId = writer.enumeratePath(filePath);
- int funExprId = 0;
- final Map<LightRef, Void> definitions = new THashMap<>(defs.size());
- final Map<LightRef, Collection<LightRef>> backwardHierarchyMap = new THashMap<>();
- final Map<SignatureData, Collection<LightRef>> signatureData = new THashMap<>();
+ try {
+ final int fileId = writer.enumeratePath(filePath);
+ int funExprId = 0;
- final AnonymousClassEnumerator anonymousClassEnumerator = new AnonymousClassEnumerator();
+ final Map<LightRef, Void> definitions = new HashMap<>(defs.size());
+ final Map<LightRef, Collection<LightRef>> backwardHierarchyMap = new HashMap<>();
++ final Map<SignatureData, Collection<LightRef>> signatureData = new THashMap<>();
+
- for (JavacDef def : defs) {
- if (def instanceof JavacDef.JavacClassDef) {
- JavacRef.JavacClass sym = (JavacRef.JavacClass)def.getDefinedElement();
++ final AnonymousClassEnumerator anonymousClassEnumerator = new AnonymousClassEnumerator();
- final LightRef.LightClassHierarchyElementDef aClass;
- if (sym.isAnonymous()) {
- final JavacRef[] classes = ((JavacDef.JavacClassDef)def).getSuperClasses();
- aClass = anonymousClassEnumerator.addAnonymous(sym.getName(), writer.asClassUsage(classes[0]));
- } else {
- aClass = writer.asClassUsage(sym);
- }
- definitions.put(aClass, null);
+ for (JavacDef def : defs) {
+ if (def instanceof JavacDef.JavacClassDef) {
+ JavacRef.JavacClass sym = (JavacRef.JavacClass)def.getDefinedElement();
- final LightRef.JavaLightClassRef aClass = writer.asClassUsage(sym);
+
- final JavacRef[] superClasses = ((JavacDef.JavacClassDef)def).getSuperClasses();
- for (JavacRef superClass : superClasses) {
- LightRef.JavaLightClassRef superClassRef = writer.asClassUsage(superClass);
++ final LightRef.LightClassHierarchyElementDef aClass;
++ if (sym.isAnonymous()) {
++ final JavacRef[] classes = ((JavacDef.JavacClassDef)def).getSuperClasses();
++ aClass = anonymousClassEnumerator.addAnonymous(sym.getName(), writer.asClassUsage(classes[0]));
++ } else {
++ aClass = writer.asClassUsage(sym);
++ }
+ definitions.put(aClass, null);
- backwardHierarchyMap.computeIfAbsent(superClassRef, k -> new SmartList<>()).add(aClass);
- }
- }
- else if (def instanceof JavacDef.JavacFunExprDef) {
- final LightRef.JavaLightClassRef functionalType = writer.asClassUsage(def.getDefinedElement());
- int id = funExprId++;
- LightRef.JavaLightFunExprDef result = new LightRef.JavaLightFunExprDef(id);
- definitions.put(result, null);
+ final JavacRef[] superClasses = ((JavacDef.JavacClassDef)def).getSuperClasses();
+ for (JavacRef superClass : superClasses) {
+ LightRef.JavaLightClassRef superClassRef = writer.asClassUsage(superClass);
- Collection<LightRef> children = backwardHierarchyMap.get(superClassRef);
- if (children == null) {
- backwardHierarchyMap.put(superClassRef, children = new SmartList<>());
- }
- children.add(aClass);
- ContainerUtil.getOrCreate(backwardHierarchyMap, functionalType,
- (Factory<Collection<LightRef>>)() -> new SmartList<>()).add(result);
- }
- else if (def instanceof JavacDef.JavacMemberDef) {
- final LightRef ref = writer.enumerateNames(def.getDefinedElement(), name -> anonymousClassEnumerator.getLightRefIfAnonymous(name));
- final LightRef.JavaLightClassRef returnType = writer.asClassUsage(((JavacDef.JavacMemberDef)def).getReturnType());
- if (ref != null && returnType != null) {
- final SignatureData data = new SignatureData(returnType.getName(), ((JavacDef.JavacMemberDef)def).isStatic());
- signatureData.computeIfAbsent(data, element -> new SmartList<>()).add(ref);
++ backwardHierarchyMap.computeIfAbsent(superClassRef, k -> new SmartList<>()).add(aClass);
+ }
}
- }
- }
+ else if (def instanceof JavacDef.JavacFunExprDef) {
+ final LightRef.JavaLightClassRef functionalType = writer.asClassUsage(def.getDefinedElement());
+ int id = funExprId++;
+ LightRef.JavaLightFunExprDef result = new LightRef.JavaLightFunExprDef(id);
+ definitions.put(result, null);
- Map<LightRef, Integer> convertedRefs = new THashMap<>();
- refs.forEachEntry((ref, count) -> {
- final LightRef lightRef = writer.enumerateNames(ref, name -> anonymousClassEnumerator.getLightRefIfAnonymous(name));
- if (lightRef != null) {
- convertedRefs.put(lightRef, count);
+ ContainerUtil.getOrCreate(backwardHierarchyMap, functionalType,
+ (Factory<Collection<LightRef>>)() -> new SmartList<>()).add(result);
+ }
++ else if (def instanceof JavacDef.JavacMemberDef) {
++ final LightRef ref = writer.enumerateNames(def.getDefinedElement(), name -> anonymousClassEnumerator.getLightRefIfAnonymous(name));
++ final LightRef.JavaLightClassRef returnType = writer.asClassUsage(((JavacDef.JavacMemberDef)def).getReturnType());
++ if (ref != null && returnType != null) {
++ final SignatureData data = new SignatureData(returnType.getName(), ((JavacDef.JavacMemberDef)def).isStatic());
++ signatureData.computeIfAbsent(data, element -> new SmartList<>()).add(ref);
++ }
++ }
}
- return true;
- });
- Map<LightRef, Void> convertedRefs = new HashMap<>(refs.size());
- for (JavacRef ref : refs) {
- LightRef key = writer.enumerateNames(ref);
- if (key != null) {
- convertedRefs.put(key, null);
- writer.writeData(fileId, new CompiledFileData(backwardHierarchyMap, convertedRefs, definitions, signatureData));
++ Map<LightRef, Integer> convertedRefs = new THashMap<>();
++ refs.forEachEntry((ref, count) -> {
++ final LightRef lightRef = writer.enumerateNames(ref, name -> anonymousClassEnumerator.getLightRefIfAnonymous(name));
++ if (lightRef != null) {
++ convertedRefs.put(lightRef, count);
+ }
- }
++ return true;
++ });
+ writer.writeData(fileId, new CompiledFileData(backwardHierarchyMap, convertedRefs, definitions));
+ }
+ catch (IOException e) {
+ writer.setRebuildCause(e);
+ }
}
+
+ private static class AnonymousClassEnumerator {
+ private THashMap<String, LightRef.LightClassHierarchyElementDef> myAnonymousName2Id = null;
+
+ private LightRef.JavaLightAnonymousClassRef addAnonymous(String internalName,
+ LightRef.JavaLightClassRef base) {
+ if (myAnonymousName2Id == null) {
+ myAnonymousName2Id = new THashMap<>();
+ }
+ final int anonymousIdx = myAnonymousName2Id.size();
+ myAnonymousName2Id.put(internalName, base);
+ return new LightRef.JavaLightAnonymousClassRef(anonymousIdx);
+ }
+
+ private Integer getLightRefIfAnonymous(String className) {
+ if (myAnonymousName2Id == null) return null;
+ final LightRef.LightClassHierarchyElementDef ref = myAnonymousName2Id.get(className);
+ return ref == null ? null : ref.getName();
+ }
+ }
}