Get rid of dependency on PsiClass from deserialized resolver

This commit is contained in:
Alexander Udalov
2013-07-22 21:07:38 +04:00
committed by Pavel V. Talanov
parent 8746ee2895
commit bd54e070bb
5 changed files with 45 additions and 58 deletions
@@ -22,6 +22,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.*; import org.jetbrains.asm4.*;
import org.jetbrains.asm4.commons.Method; import org.jetbrains.asm4.commons.Method;
import org.jetbrains.jet.descriptors.serialization.ClassId;
import org.jetbrains.jet.descriptors.serialization.JavaProtoBufUtil; import org.jetbrains.jet.descriptors.serialization.JavaProtoBufUtil;
import org.jetbrains.jet.descriptors.serialization.NameResolver; import org.jetbrains.jet.descriptors.serialization.NameResolver;
import org.jetbrains.jet.descriptors.serialization.ProtoBuf; import org.jetbrains.jet.descriptors.serialization.ProtoBuf;
@@ -111,7 +112,12 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
if (psiClass == null) { if (psiClass == null) {
throw new IllegalStateException("Psi class is not found for class: " + descriptor); throw new IllegalStateException("Psi class is not found for class: " + descriptor);
} }
VirtualFile virtualFile = getVirtualFile(psiClass, fqName, (ClassOrNamespaceDescriptor) descriptor.getContainingDeclaration()); VirtualFile outerClassFile = psiClass.getContainingFile().getVirtualFile();
if (outerClassFile == null) {
throw new IllegalStateException("Outer class file is not found for class: " + descriptor);
}
ClassId id = ClassId.fromFqNameAndContainingDeclaration(fqName, (ClassOrNamespaceDescriptor) descriptor.getContainingDeclaration());
VirtualFile virtualFile = getVirtualFile(id, outerClassFile);
if (virtualFile == null) { if (virtualFile == null) {
throw new IllegalStateException("Virtual file is not found for class: " + descriptor); throw new IllegalStateException("Virtual file is not found for class: " + descriptor);
} }
@@ -17,14 +17,12 @@
package org.jetbrains.jet.lang.resolve.java.resolver; package org.jetbrains.jet.lang.resolve.java.resolver;
import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.*; import org.jetbrains.jet.descriptors.serialization.*;
import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedClassDescriptor; import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedClassDescriptor;
import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedPackageMemberScope; import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedPackageMemberScope;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.resolve.lazy.storage.LockBasedStorageManager; import org.jetbrains.jet.lang.resolve.lazy.storage.LockBasedStorageManager;
@@ -37,7 +35,6 @@ import java.util.Collection;
import static org.jetbrains.jet.lang.resolve.java.AbiVersionUtil.isAbiVersionCompatible; import static org.jetbrains.jet.lang.resolve.java.AbiVersionUtil.isAbiVersionCompatible;
import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.INCLUDE_KOTLIN; import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.INCLUDE_KOTLIN;
import static org.jetbrains.jet.lang.resolve.java.resolver.DeserializedResolverUtils.getVirtualFile;
import static org.jetbrains.jet.lang.resolve.java.resolver.DeserializedResolverUtils.kotlinFqNameToJavaFqName; import static org.jetbrains.jet.lang.resolve.java.resolver.DeserializedResolverUtils.kotlinFqNameToJavaFqName;
public final class DeserializedDescriptorResolver { public final class DeserializedDescriptorResolver {
@@ -87,50 +84,29 @@ public final class DeserializedDescriptorResolver {
} }
@Nullable @Nullable
public ClassDescriptor resolveClass( public ClassDescriptor resolveClass(@NotNull ClassId id, @NotNull VirtualFile file, @NotNull ErrorReporter reporter) {
@NotNull FqName fqName, ClassData classData = readClassDataFromClassFile(file, reporter);
@NotNull PsiClass psiClass,
@NotNull ClassOrNamespaceDescriptor containingDeclaration,
@NotNull ErrorReporter reporter
) {
VirtualFile virtualFile = getVirtualFile(psiClass, fqName, containingDeclaration);
if (virtualFile == null) {
// TODO: use ErrorReporter here
return null;
}
ClassData classData = readClassDataFromClassFile(virtualFile, reporter);
if (classData == null) { if (classData == null) {
return null; return null;
} }
return deserializeClass(classData, fqName, containingDeclaration); return createDeserializedClass(classData, id);
} }
@Nullable @Nullable
public JetScope createKotlinPackageScope( public JetScope createKotlinPackageScope(
@NotNull PsiClass kotlinPackagePsiClass, @NotNull NamespaceDescriptor descriptor,
@NotNull NamespaceDescriptor packageDescriptor, @NotNull VirtualFile file,
@NotNull ErrorReporter reporter @NotNull ErrorReporter reporter
) { ) {
VirtualFile virtualFile = kotlinPackagePsiClass.getContainingFile().getVirtualFile(); PackageData packageData = readPackageDataFromClassFile(file, reporter);
if (virtualFile == null) {
return null;
}
PackageData packageData = readPackageDataFromClassFile(virtualFile, reporter);
if (packageData == null) { if (packageData == null) {
return null; return null;
} }
return new DeserializedPackageMemberScope(storageManager, packageDescriptor, annotationDeserializer, javaDescriptorFinder, return new DeserializedPackageMemberScope(storageManager, descriptor, annotationDeserializer, javaDescriptorFinder, packageData);
packageData);
} }
@Nullable @Nullable
private ClassDescriptor deserializeClass( private ClassDescriptor createDeserializedClass(@NotNull ClassData classData, @NotNull ClassId classId) {
@NotNull ClassData classData,
@NotNull FqName fqName,
@NotNull ClassOrNamespaceDescriptor containingDeclaration
) {
ClassId classId = ClassId.fromFqNameAndContainingDeclaration(fqName, containingDeclaration);
DeclarationDescriptor owner = classId.isTopLevelClass() DeclarationDescriptor owner = classId.isTopLevelClass()
? javaNamespaceResolver.resolveNamespace(classId.getPackageFqName(), INCLUDE_KOTLIN) ? javaNamespaceResolver.resolveNamespace(classId.getPackageFqName(), INCLUDE_KOTLIN)
: javaClassResolver : javaClassResolver
@@ -17,12 +17,10 @@
package org.jetbrains.jet.lang.resolve.java.resolver; package org.jetbrains.jet.lang.resolve.java.resolver;
import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.ClassId; import org.jetbrains.jet.descriptors.serialization.ClassId;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
@@ -54,26 +52,17 @@ public class DeserializedResolverUtils {
} }
@Nullable @Nullable
public static VirtualFile getVirtualFile( public static VirtualFile getVirtualFile(@NotNull ClassId id, @NotNull VirtualFile outerClassFile) {
@NotNull PsiClass psiClass, String fileExtension = outerClassFile.getExtension();
@NotNull FqName classFqName, if (!"class".equals(fileExtension)) {
@NotNull ClassOrNamespaceDescriptor containingDeclaration
) {
VirtualFile mostOuterClassVirtualFile = psiClass.getContainingFile().getVirtualFile();
if (mostOuterClassVirtualFile == null) {
throw new IllegalStateException("Could not find virtual file for " + classFqName.asString());
}
String fileExtension = mostOuterClassVirtualFile.getExtension();
if (fileExtension == null || !fileExtension.equals("class")) {
return null; return null;
} }
ClassId id = ClassId.fromFqNameAndContainingDeclaration(classFqName, containingDeclaration);
FqNameUnsafe relativeClassName = id.getRelativeClassName(); FqNameUnsafe relativeClassName = id.getRelativeClassName();
assert relativeClassName.isSafe() : "Relative class name " + relativeClassName.asString() + " should be safe at this point"; assert relativeClassName.isSafe() : "Relative class name " + relativeClassName.asString() + " should be safe at this point";
String classNameWithBucks = relativeClassName.asString().replace(".", "$") + ".class"; String classNameWithBucks = relativeClassName.asString().replace(".", "$") + ".class";
VirtualFile virtualFile = mostOuterClassVirtualFile.getParent().findChild(classNameWithBucks); VirtualFile virtualFile = outerClassFile.getParent().findChild(classNameWithBucks);
if (virtualFile == null) { if (virtualFile == null) {
throw new IllegalStateException("No virtual file for " + classFqName.asString()); throw new IllegalStateException("No virtual file for " + id.asSingleFqName().asString());
} }
return virtualFile; return virtualFile;
} }
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.resolve.java.resolver;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass; import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiModifier;
@@ -26,6 +27,7 @@ import gnu.trove.THashMap;
import gnu.trove.TObjectHashingStrategy; import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.ClassId;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.BindingTrace;
@@ -56,6 +58,7 @@ import java.util.*;
import static org.jetbrains.jet.lang.resolve.DescriptorResolver.createEnumClassObjectValueOfMethod; import static org.jetbrains.jet.lang.resolve.DescriptorResolver.createEnumClassObjectValueOfMethod;
import static org.jetbrains.jet.lang.resolve.DescriptorResolver.createEnumClassObjectValuesMethod; import static org.jetbrains.jet.lang.resolve.DescriptorResolver.createEnumClassObjectValuesMethod;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getClassObjectName; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getClassObjectName;
import static org.jetbrains.jet.lang.resolve.java.resolver.DeserializedResolverUtils.getVirtualFile;
public final class JavaClassResolver { public final class JavaClassResolver {
@@ -245,13 +248,20 @@ public final class JavaClassResolver {
assert (!unresolvedCache.contains(fqName)) : "We can resolve the class, so it can't be 'unresolved' during parent resolution"; assert (!unresolvedCache.contains(fqName)) : "We can resolve the class, so it can't be 'unresolved' during parent resolution";
ClassDescriptor deserializedDescriptor = kotlinDescriptorResolver.resolveClass(fqName, psiClass, containingDeclaration, VirtualFile outerClassFile = psiClass.getContainingFile().getVirtualFile();
DescriptorResolverUtils.createPsiBasedErrorReporter(psiClass, trace)); if (outerClassFile != null) {
ClassId id = ClassId.fromFqNameAndContainingDeclaration(fqName, containingDeclaration);
VirtualFile file = getVirtualFile(id, outerClassFile);
if (file != null) {
ClassDescriptor deserializedDescriptor = kotlinDescriptorResolver.resolveClass(id, file,
DescriptorResolverUtils.createPsiBasedErrorReporter(psiClass, trace));
if (deserializedDescriptor != null) { if (deserializedDescriptor != null) {
//TODO: class object and psi class //TODO: class object and psi class
cache(javaClassToKotlinFqName(fqName), deserializedDescriptor); cache(javaClassToKotlinFqName(fqName), deserializedDescriptor);
return deserializedDescriptor; return deserializedDescriptor;
}
}
} }
return doCreateClassDescriptor(fqName, psiClass, taskList, containingDeclaration); return doCreateClassDescriptor(fqName, psiClass, taskList, containingDeclaration);
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve.java.resolver;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass; import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMember; import com.intellij.psi.PsiMember;
import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiModifier;
@@ -174,9 +175,14 @@ public final class JavaNamespaceResolver {
if (isCompiledKotlinPackageClass) { if (isCompiledKotlinPackageClass) {
// If psiClass has @KotlinPackage (regardless of whether it has @JetPackage or not), deserialize it to Kotlin descriptor. // If psiClass has @KotlinPackage (regardless of whether it has @JetPackage or not), deserialize it to Kotlin descriptor.
// Note that @KotlinPackage may still have an old ABI version, in which case null is returned by createKotlinPackageScope // Note that @KotlinPackage may still have an old ABI version, in which case null is returned by createKotlinPackageScope
JetScope kotlinPackageScope = deserializedDescriptorResolver.createKotlinPackageScope(psiClass, namespaceDescriptor, VirtualFile file = psiClass.getContainingFile().getVirtualFile();
DescriptorResolverUtils.createPsiBasedErrorReporter(psiClass, trace)); if (file != null) {
if (kotlinPackageScope != null) return kotlinPackageScope; JetScope kotlinPackageScope = deserializedDescriptorResolver.createKotlinPackageScope(namespaceDescriptor,
file, DescriptorResolverUtils.createPsiBasedErrorReporter(psiClass, trace));
if (kotlinPackageScope != null) {
return kotlinPackageScope;
}
}
} }
} }