From bc1d59a538ff8de1db16cef439af1db95f09fe02 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 20 Aug 2014 13:01:20 +0400 Subject: [PATCH] Add KotlinClassFinder#findKotlinClass(ClassId) Will be used to load nested classes correctly at runtime --- .../src/BuiltInsSerializer.kt | 3 ++- .../src/ClassSerializationUtil.kt | 11 ---------- .../kotlin/VirtualFileKotlinClassFinder.kt | 7 ++++++- .../resolve/kotlin/BaseDescriptorLoader.java | 6 +++--- .../kotlin/DeserializedResolverUtils.java | 21 ++++++++++--------- .../resolve/kotlin/JavaClassDataFinder.kt | 5 ++--- .../lang/resolve/kotlin/KotlinClassFinder.kt | 4 +++- .../libraries/DeserializerForDecompiler.kt | 2 +- 8 files changed, 28 insertions(+), 31 deletions(-) diff --git a/compiler/builtins-serializer/src/BuiltInsSerializer.kt b/compiler/builtins-serializer/src/BuiltInsSerializer.kt index 44a5ac77ca7..f224decf4a9 100644 --- a/compiler/builtins-serializer/src/BuiltInsSerializer.kt +++ b/compiler/builtins-serializer/src/BuiltInsSerializer.kt @@ -46,6 +46,7 @@ import org.jetbrains.jet.context.GlobalContext import org.jetbrains.jet.analyzer.ModuleInfo import org.jetbrains.jet.lang.resolve.java.JvmPlatformParameters import org.jetbrains.jet.analyzer.ModuleContent +import org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils public class BuiltInsSerializer(val out: PrintStream?) { private var totalSize = 0 @@ -163,6 +164,6 @@ public class BuiltInsSerializer(val out: PrintStream?) { } fun getFileName(classDescriptor: ClassDescriptor): String { - return BuiltInsSerializationUtil.getClassMetadataPath(ClassSerializationUtil.getClassId(classDescriptor)) + return BuiltInsSerializationUtil.getClassMetadataPath(DeserializedResolverUtils.getClassId(classDescriptor)) } } diff --git a/compiler/builtins-serializer/src/ClassSerializationUtil.kt b/compiler/builtins-serializer/src/ClassSerializationUtil.kt index e3433d5dfc4..41359cc8f0d 100644 --- a/compiler/builtins-serializer/src/ClassSerializationUtil.kt +++ b/compiler/builtins-serializer/src/ClassSerializationUtil.kt @@ -16,13 +16,10 @@ package org.jetbrains.jet.utils.builtinsSerializer -import org.jetbrains.jet.descriptors.serialization.ClassId import org.jetbrains.jet.descriptors.serialization.DescriptorSerializer import org.jetbrains.jet.descriptors.serialization.ProtoBuf import org.jetbrains.jet.lang.descriptors.ClassDescriptor import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor -import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor -import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe public object ClassSerializationUtil { public trait Sink { @@ -48,12 +45,4 @@ public object ClassSerializationUtil { } } } - - public fun getClassId(classDescriptor: ClassDescriptor): ClassId { - val owner = classDescriptor.getContainingDeclaration() - if (owner is PackageFragmentDescriptor) { - return ClassId(owner.fqName, FqNameUnsafe.topLevel(classDescriptor.getName())) - } - return getClassId(owner as ClassDescriptor).createNestedClassId(classDescriptor.getName()) - } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileKotlinClassFinder.kt b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileKotlinClassFinder.kt index 15343660e47..99ae8d02bc1 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileKotlinClassFinder.kt +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileKotlinClassFinder.kt @@ -20,13 +20,18 @@ import org.jetbrains.jet.lang.resolve.java.structure.JavaClass import org.jetbrains.jet.lang.resolve.java.structure.impl.JavaClassImpl import org.jetbrains.jet.lang.resolve.name.FqName import org.jetbrains.kotlin.util.sure +import org.jetbrains.jet.descriptors.serialization.ClassId -public abstract class VirtualFileKotlinClassFinder() : VirtualFileFinder { +public abstract class VirtualFileKotlinClassFinder : VirtualFileFinder { override fun findKotlinClass(fqName: FqName): KotlinJvmBinaryClass? { val file = findVirtualFileWithHeader(fqName) ?: return null return KotlinBinaryClassCache.getKotlinBinaryClass(file) } + override fun findKotlinClass(classId: ClassId): KotlinJvmBinaryClass? { + return findKotlinClass(classId.asSingleFqName().toSafe()) + } + override fun findKotlinClass(javaClass: JavaClass): KotlinJvmBinaryClass? { var file = (javaClass as JavaClassImpl).getPsi().getContainingFile()!!.getVirtualFile() ?: return null if (javaClass.getOuterClass() != null) { diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/BaseDescriptorLoader.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/BaseDescriptorLoader.java index ff41d6e1a65..0a74f511d74 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/BaseDescriptorLoader.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/BaseDescriptorLoader.java @@ -34,8 +34,8 @@ import org.jetbrains.jet.lang.resolve.name.Name; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isTrait; import static org.jetbrains.jet.lang.resolve.kotlin.DescriptorLoadersStorage.MemberSignature; -import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.kotlinFqNameToJavaFqName; -import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.naiveKotlinFqName; +import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.getClassId; +import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.kotlinClassIdToJavaClassId; public abstract class BaseDescriptorLoader { protected KotlinClassFinder kotlinClassFinder; @@ -150,7 +150,7 @@ public abstract class BaseDescriptorLoader { @Nullable protected KotlinJvmBinaryClass findKotlinClassByDescriptor(@NotNull ClassOrPackageFragmentDescriptor descriptor) { if (descriptor instanceof ClassDescriptor) { - return kotlinClassFinder.findKotlinClass(kotlinFqNameToJavaFqName(naiveKotlinFqName((ClassDescriptor) descriptor))); + return kotlinClassFinder.findKotlinClass(kotlinClassIdToJavaClassId(getClassId((ClassDescriptor) descriptor))); } else if (descriptor instanceof PackageFragmentDescriptor) { return kotlinClassFinder.findKotlinClass( diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DeserializedResolverUtils.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DeserializedResolverUtils.java index f7c31371d37..6f975eeb110 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DeserializedResolverUtils.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DeserializedResolverUtils.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.lang.resolve.kotlin; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.descriptors.serialization.ClassId; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor; @@ -45,6 +46,11 @@ public class DeserializedResolverUtils { return FqName.fromSegments(correctedSegments); } + @NotNull + public static ClassId kotlinClassIdToJavaClassId(@NotNull ClassId kotlinClassId) { + return new ClassId(kotlinClassId.getPackageFqName(), kotlinFqNameToJavaFqName(kotlinClassId.getRelativeClassName()).toUnsafe()); + } + @NotNull public static FqNameUnsafe javaFqNameToKotlinFqName(@NotNull FqName javaFqName) { if (javaFqName.isRoot()) { @@ -63,16 +69,11 @@ public class DeserializedResolverUtils { } @NotNull - public static FqNameUnsafe naiveKotlinFqName(@NotNull ClassDescriptor descriptor) { - DeclarationDescriptor containing = descriptor.getContainingDeclaration(); - if (containing instanceof ClassDescriptor) { - return naiveKotlinFqName((ClassDescriptor) containing).child(descriptor.getName()); - } - else if (containing instanceof PackageFragmentDescriptor) { - return ((PackageFragmentDescriptor) containing).getFqName().child(descriptor.getName()).toUnsafe(); - } - else { - throw new IllegalArgumentException("Class doesn't have a FQ name: " + descriptor); + public static ClassId getClassId(@NotNull ClassDescriptor descriptor) { + DeclarationDescriptor owner = descriptor.getContainingDeclaration(); + if (owner instanceof PackageFragmentDescriptor) { + return new ClassId(((PackageFragmentDescriptor) owner).getFqName(), FqNameUnsafe.topLevel(descriptor.getName())); } + return getClassId((ClassDescriptor) owner).createNestedClassId(descriptor.getName()); } } diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/JavaClassDataFinder.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/JavaClassDataFinder.kt index 3a1fc84de32..068331b6d16 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/JavaClassDataFinder.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/JavaClassDataFinder.kt @@ -18,7 +18,6 @@ package org.jetbrains.jet.lang.resolve.kotlin import org.jetbrains.jet.descriptors.serialization.ClassId import org.jetbrains.jet.descriptors.serialization.ClassDataFinder -import org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.kotlinFqNameToJavaFqName import org.jetbrains.jet.descriptors.serialization.ClassData import org.jetbrains.jet.descriptors.serialization.JavaProtoBufUtil import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader @@ -27,9 +26,9 @@ public class JavaClassDataFinder( private val kotlinClassFinder: KotlinClassFinder, private val deserializedDescriptorResolver: DeserializedDescriptorResolver ) : ClassDataFinder { - override fun findClassData(classId: ClassId): ClassData? { - val kotlinJvmBinaryClass = kotlinClassFinder.findKotlinClass(kotlinFqNameToJavaFqName(classId.asSingleFqName())) ?: return null + val javaClassId = DeserializedResolverUtils.kotlinClassIdToJavaClassId(classId) + val kotlinJvmBinaryClass = kotlinClassFinder.findKotlinClass(javaClassId) ?: return null val data = deserializedDescriptorResolver.readData(kotlinJvmBinaryClass, KotlinClassHeader.Kind.CLASS) ?: return null return JavaProtoBufUtil.readClassDataFrom(data) } diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/KotlinClassFinder.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/KotlinClassFinder.kt index 2a99d416ae1..495ab943af5 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/KotlinClassFinder.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/KotlinClassFinder.kt @@ -16,12 +16,14 @@ package org.jetbrains.jet.lang.resolve.kotlin -import org.jetbrains.annotations.Nullable import org.jetbrains.jet.lang.resolve.java.structure.JavaClass import org.jetbrains.jet.lang.resolve.name.FqName +import org.jetbrains.jet.descriptors.serialization.ClassId public trait KotlinClassFinder { public fun findKotlinClass(fqName: FqName): KotlinJvmBinaryClass? + public fun findKotlinClass(classId: ClassId): KotlinJvmBinaryClass? + public fun findKotlinClass(javaClass: JavaClass): KotlinJvmBinaryClass? } diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/libraries/DeserializerForDecompiler.kt b/idea/idea-analysis/src/org/jetbrains/jet/plugin/libraries/DeserializerForDecompiler.kt index 32d67ae118e..e08a81c0456 100644 --- a/idea/idea-analysis/src/org/jetbrains/jet/plugin/libraries/DeserializerForDecompiler.kt +++ b/idea/idea-analysis/src/org/jetbrains/jet/plugin/libraries/DeserializerForDecompiler.kt @@ -83,7 +83,7 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di override fun findKotlinClass(fqName: FqName) = findKotlinClass(fqName.toClassId()) override fun findKotlinClass(javaClass: JavaClass) = findKotlinClass(javaClass.getFqName()!!) - fun findKotlinClass(classId: ClassId): KotlinJvmBinaryClass? { + override fun findKotlinClass(classId: ClassId): KotlinJvmBinaryClass? { if (classId.getPackageFqName() != directoryPackageFqName) { return null }