Serialize FQ names of Kotlin classes

This helps to avoid a nasty hack with loading inner Kotlin classes in JDR,
which makes it a bit easier to 'lazify' JDR, since now the container of a
Kotlin class is no longer required to be resolved eagerly before resolution of
the class itself
This commit is contained in:
Alexander Udalov
2013-09-23 18:49:05 +04:00
parent a16db2c773
commit a97bb80216
219 changed files with 208 additions and 230 deletions
@@ -25,7 +25,7 @@ public final class JvmAbi {
* This constant is used to identify binary format (class file) versions
* If you change class file metadata format and/or naming conventions, please increase this number
*/
public static final int VERSION = 7;
public static final int VERSION = 8;
public static final String TRAIT_IMPL_CLASS_NAME = "$TImpl";
public static final String TRAIT_IMPL_SUFFIX = "$" + TRAIT_IMPL_CLASS_NAME;
@@ -21,7 +21,6 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.ClassId;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.DescriptorFactory;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
@@ -192,20 +191,7 @@ public final class JavaClassResolver {
//TODO: correct scope
VirtualFile file = virtualFileFinder.find(qualifiedName);
if (file != null) {
//TODO: code duplication
//TODO: it is a hackish way to determine whether it is inner class or not
boolean isInnerClass = file.getName().contains("$");
ClassOrNamespaceDescriptor containingDeclaration = resolveParentDescriptor(qualifiedName, isInnerClass);
// class may be resolved during resolution of parent
ClassDescriptor cachedDescriptor = classDescriptorCache.get(javaClassToKotlinFqName(qualifiedName));
if (cachedDescriptor != null) {
return cachedDescriptor;
}
assert !unresolvedCache.contains(qualifiedName.toUnsafe())
: "We can resolve the class, so it can't be 'unresolved' during parent resolution";
ClassId id = ClassId.fromFqNameAndContainingDeclaration(qualifiedName.toUnsafe(), containingDeclaration);
ClassDescriptor deserializedDescriptor = deserializedDescriptorResolver.resolveClass(id, file);
ClassDescriptor deserializedDescriptor = deserializedDescriptorResolver.resolveClass(file);
if (deserializedDescriptor != null) {
cache(javaClassToKotlinFqName(qualifiedName), deserializedDescriptor);
return deserializedDescriptor;
@@ -234,7 +220,6 @@ public final class JavaClassResolver {
return alreadyResolved;
}
//TODO: code duplication
ClassOrNamespaceDescriptor containingDeclaration = resolveParentDescriptor(qualifiedName, javaClass.getOuterClass() != null);
// class may be resolved during resolution of parent
ClassDescriptor cachedDescriptor = classDescriptorCache.get(javaClassToKotlinFqName(qualifiedName));
@@ -19,11 +19,12 @@ package org.jetbrains.jet.lang.resolve.kotlin;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.*;
import org.jetbrains.jet.descriptors.serialization.ClassId;
import org.jetbrains.jet.descriptors.serialization.DescriptorFinder;
import org.jetbrains.jet.descriptors.serialization.JavaProtoBufUtil;
import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedClassDescriptor;
import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedPackageMemberScope;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaClassResolver;
@@ -95,36 +96,17 @@ public final class DeserializedDescriptorResolver {
}
@Nullable
public ClassDescriptor resolveClass(@NotNull ClassId id, @NotNull VirtualFile file) {
String[] data = readData(file);
if (data != null) {
ClassData classData = JavaProtoBufUtil.readClassDataFrom(data);
return createDeserializedClass(classData, id);
}
return null;
public ClassDescriptor resolveClass(@NotNull VirtualFile virtualFile) {
String[] data = readData(virtualFile);
return data == null ? null : new DeserializedClassDescriptor(storageManager, annotationDeserializer, javaDescriptorFinder,
JavaProtoBufUtil.readClassDataFrom(data));
}
@Nullable
public JetScope createKotlinPackageScope(@NotNull NamespaceDescriptor descriptor, @NotNull VirtualFile file) {
String[] data = readData(file);
if (data != null) {
PackageData packageData = JavaProtoBufUtil.readPackageDataFrom(data);
return new DeserializedPackageMemberScope(storageManager, descriptor, annotationDeserializer, javaDescriptorFinder,
packageData);
}
return null;
}
@Nullable
private ClassDescriptor createDeserializedClass(@NotNull ClassData classData, @NotNull ClassId classId) {
DeclarationDescriptor owner = classId.isTopLevelClass()
? javaNamespaceResolver.resolveNamespace(classId.getPackageFqName(), INCLUDE_KOTLIN_SOURCES)
: javaClassResolver.resolveClass(kotlinFqNameToJavaFqName(classId.getOuterClassId().asSingleFqName()),
IGNORE_KOTLIN_SOURCES);
assert owner != null : "No owner found for " + classId;
return new DeserializedClassDescriptor(classId, storageManager, owner, classData.getNameResolver(),
annotationDeserializer, javaDescriptorFinder, classData.getClassProto(), null);
public JetScope createKotlinPackageScope(@NotNull NamespaceDescriptor descriptor, @NotNull VirtualFile virtualFile) {
String[] data = readData(virtualFile);
return data == null ? null : new DeserializedPackageMemberScope(storageManager, descriptor, annotationDeserializer,
javaDescriptorFinder, JavaProtoBufUtil.readPackageDataFrom(data));
}
@Nullable