Restructure JavaClassResolver caches to contain ClassDescriptor instead of ResolverClassData
This commit is contained in:
-6
@@ -34,10 +34,4 @@ public class ResolverBinaryClassData extends ResolverClassData {
|
||||
) {
|
||||
super(psiClass, null, fqName, false, classDescriptor);
|
||||
}
|
||||
|
||||
public ResolverBinaryClassData(boolean negative) {
|
||||
super(negative);
|
||||
}
|
||||
|
||||
public static final ResolverClassData NEGATIVE = new ResolverBinaryClassData(true);
|
||||
}
|
||||
|
||||
+43
-20
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.jet.lang.resolve.java.resolver;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
@@ -29,7 +30,6 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.java.*;
|
||||
import org.jetbrains.jet.lang.resolve.java.data.ResolverBinaryClassData;
|
||||
import org.jetbrains.jet.lang.resolve.java.data.ResolverClassData;
|
||||
import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode;
|
||||
import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation;
|
||||
@@ -45,12 +45,14 @@ import javax.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public final class JavaClassResolver {
|
||||
|
||||
// NOTE: this complexity is introduced because class descriptors do not always have valid fqnames (class objects)
|
||||
private final Map<FqNameBase, ResolverClassData> classDescriptorCache =
|
||||
new THashMap<FqNameBase, ResolverClassData>(new TObjectHashingStrategy<FqNameBase>() {
|
||||
@NotNull
|
||||
private final Map<FqNameBase, ClassDescriptor> classDescriptorCache =
|
||||
new THashMap<FqNameBase, ClassDescriptor>(new TObjectHashingStrategy<FqNameBase>() {
|
||||
@Override
|
||||
public int computeHashCode(FqNameBase o) {
|
||||
if (o instanceof FqName) {
|
||||
@@ -66,6 +68,9 @@ public final class JavaClassResolver {
|
||||
}
|
||||
});
|
||||
|
||||
@NotNull
|
||||
private final Set<FqNameBase> unresolvedCache = Sets.newHashSet();
|
||||
|
||||
private BindingTrace trace;
|
||||
private JavaDescriptorResolver javaDescriptorResolver;
|
||||
private JavaSignatureResolver signatureResolver;
|
||||
@@ -154,9 +159,14 @@ public final class JavaClassResolver {
|
||||
}
|
||||
|
||||
// Not let's take a descriptor of a Java class
|
||||
ResolverClassData classData = classDescriptorCache.get(javaClassToKotlinFqName(qualifiedName));
|
||||
if (classData != null) {
|
||||
return classData.getClassDescriptor();
|
||||
FqNameUnsafe fqName = javaClassToKotlinFqName(qualifiedName);
|
||||
ClassDescriptor cachedDescriptor = classDescriptorCache.get(fqName);
|
||||
if (cachedDescriptor != null) {
|
||||
return cachedDescriptor;
|
||||
}
|
||||
|
||||
if (unresolvedCache.contains(fqName)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return doResolveClass(qualifiedName, tasks);
|
||||
@@ -166,18 +176,17 @@ public final class JavaClassResolver {
|
||||
private ClassDescriptor doResolveClass(@NotNull FqName qualifiedName, @NotNull PostponedTasks tasks) {
|
||||
PsiClass psiClass = psiClassFinder.findPsiClass(qualifiedName, PsiClassFinder.RuntimeClassesHandleMode.THROW);
|
||||
if (psiClass == null) {
|
||||
cacheNegativeValue(qualifiedName);
|
||||
cacheNegativeValue(javaClassToKotlinFqName(qualifiedName));
|
||||
return null;
|
||||
}
|
||||
ResolverClassData classData = createJavaClassDescriptor(qualifiedName, psiClass, tasks);
|
||||
return classData.getClassDescriptor();
|
||||
return createJavaClassDescriptor(qualifiedName, psiClass, tasks);
|
||||
}
|
||||
|
||||
private void cacheNegativeValue(@NotNull FqName qualifiedName) {
|
||||
ResolverClassData oldValue = classDescriptorCache.put(javaClassToKotlinFqName(qualifiedName), ResolverBinaryClassData.NEGATIVE);
|
||||
if (oldValue != null) {
|
||||
private void cacheNegativeValue(@NotNull FqNameBase qualifiedName) {
|
||||
if (unresolvedCache.contains(qualifiedName) || classDescriptorCache.containsKey(qualifiedName)) {
|
||||
throw new IllegalStateException("rewrite at " + qualifiedName);
|
||||
}
|
||||
unresolvedCache.add(qualifiedName);
|
||||
}
|
||||
|
||||
private static boolean isTraitImplementation(@NotNull FqName qualifiedName) {
|
||||
@@ -186,7 +195,7 @@ public final class JavaClassResolver {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ResolverClassData createJavaClassDescriptor(
|
||||
private ClassDescriptor createJavaClassDescriptor(
|
||||
@NotNull FqName fqName, @NotNull final PsiClass psiClass,
|
||||
@NotNull PostponedTasks taskList
|
||||
) {
|
||||
@@ -196,12 +205,14 @@ public final class JavaClassResolver {
|
||||
|
||||
ClassOrNamespaceDescriptor containingDeclaration = resolveParentDescriptor(psiClass);
|
||||
// class may be resolved during resolution of parent
|
||||
ResolverClassData classData = classDescriptorCache.get(javaClassToKotlinFqName(fqName));
|
||||
if (classData != null) {
|
||||
return classData;
|
||||
ClassDescriptor cachedDescriptor = classDescriptorCache.get(fqName);
|
||||
if (cachedDescriptor != null) {
|
||||
return cachedDescriptor;
|
||||
}
|
||||
|
||||
return doCreateClassDescriptor(fqName, psiClass, taskList, containingDeclaration);
|
||||
assert (!unresolvedCache.contains(fqName)) : "We can resolve the class, so it can't be 'unresolved' during parent resolution";
|
||||
|
||||
return doCreateClassDescriptor(fqName, psiClass, taskList, containingDeclaration).getClassDescriptor();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -217,7 +228,7 @@ public final class JavaClassResolver {
|
||||
= new ClassDescriptorFromJvmBytecode(containingDeclaration, kind, psiClass, fqName, javaDescriptorResolver);
|
||||
|
||||
ResolverClassData classData = classDescriptor.getResolverBinaryClassData();
|
||||
classDescriptorCache.put(javaClassToKotlinFqName(fqName), classData);
|
||||
cache(javaClassToKotlinFqName(fqName), classDescriptor);
|
||||
classDescriptor.setName(Name.identifier(psiClass.getName()));
|
||||
|
||||
List<JavaSignatureResolver.TypeParameterDescriptorInitialization> typeParameterDescriptorInitializations
|
||||
@@ -239,7 +250,8 @@ public final class JavaClassResolver {
|
||||
supertypes.addAll(supertypesResolver.getSupertypes(new PsiClassWrapper(psiClass), classData, classTypeParameters));
|
||||
|
||||
ResolverClassData classObjectData = classObjectResolver.createClassObjectDescriptor(classDescriptor, psiClass);
|
||||
classDescriptorCache.put(DescriptorResolverUtils.getFqNameForClassObject(psiClass), classObjectData);
|
||||
cache(DescriptorResolverUtils.getFqNameForClassObject(psiClass),
|
||||
classObjectData != null ? classObjectData.getClassDescriptor() : null);
|
||||
if (classObjectData != null) {
|
||||
ClassDescriptorFromJvmBytecode classObjectDescriptor = classObjectData.getClassDescriptor();
|
||||
classDescriptor.getBuilder().setClassObjectDescriptor(classObjectDescriptor);
|
||||
@@ -252,6 +264,16 @@ public final class JavaClassResolver {
|
||||
return classData;
|
||||
}
|
||||
|
||||
private void cache(@NotNull FqNameBase fqName, @Nullable ClassDescriptor classDescriptor) {
|
||||
if (classDescriptor == null) {
|
||||
cacheNegativeValue(fqName);
|
||||
}
|
||||
else {
|
||||
ClassDescriptor oldValue = classDescriptorCache.put(fqName, classDescriptor);
|
||||
assert oldValue == null;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<TypeParameterDescriptor> getTypeParametersDescriptors(
|
||||
@NotNull List<JavaSignatureResolver.TypeParameterDescriptorInitialization> typeParameterDescriptorInitializations
|
||||
@@ -279,7 +301,8 @@ public final class JavaClassResolver {
|
||||
|
||||
FqName fqName = new FqName(qualifiedName);
|
||||
assert fqName.equals(desiredFqName);
|
||||
if (classDescriptorCache.containsKey(javaClassToKotlinFqName(fqName))) {
|
||||
FqNameUnsafe correctedName = javaClassToKotlinFqName(fqName);
|
||||
if (classDescriptorCache.containsKey(correctedName) || unresolvedCache.contains(correctedName)) {
|
||||
throw new IllegalStateException(qualifiedName);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user