Do not call findKotlinClass when loading class annotations

The main change is in AbstractBinaryClassAnnotationAndConstantLoader, where we
no longer perform unnecessary IO operations for classes which are already
loaded to memory
This commit is contained in:
Alexander Udalov
2016-04-06 16:18:10 +03:00
parent 7620d66019
commit ad068ed4ac
16 changed files with 68 additions and 70 deletions
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.load.java.components package org.jetbrains.kotlin.load.java.components
import com.intellij.openapi.diagnostic.Logger
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
@@ -28,10 +27,7 @@ import org.jetbrains.kotlin.util.slicedMap.Slices
import org.jetbrains.kotlin.util.slicedMap.WritableSlice import org.jetbrains.kotlin.util.slicedMap.WritableSlice
class TraceBasedErrorReporter(private val trace: BindingTrace) : ErrorReporter { class TraceBasedErrorReporter(private val trace: BindingTrace) : ErrorReporter {
companion object { companion object {
private val LOG = Logger.getInstance(TraceBasedErrorReporter::class.java)
@JvmField @JvmField
val METADATA_VERSION_ERRORS: WritableSlice<String, IncompatibleVersionErrorData> = Slices.createCollectiveSlice() val METADATA_VERSION_ERRORS: WritableSlice<String, IncompatibleVersionErrorData> = Slices.createCollectiveSlice()
@@ -50,8 +46,4 @@ class TraceBasedErrorReporter(private val trace: BindingTrace) : ErrorReporter {
override fun reportCannotInferVisibility(descriptor: CallableMemberDescriptor) { override fun reportCannotInferVisibility(descriptor: CallableMemberDescriptor) {
OverrideResolver.createCannotInferVisibilityReporter(trace).invoke(descriptor) OverrideResolver.createCannotInferVisibilityReporter(trace).invoke(descriptor)
} }
override fun reportLoadingError(message: String, exception: Exception?) {
LOG.error(message, exception)
}
} }
@@ -38,8 +38,7 @@ import java.util.*
abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any, T : Any>( abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any, T : Any>(
storageManager: StorageManager, storageManager: StorageManager,
private val kotlinClassFinder: KotlinClassFinder, private val kotlinClassFinder: KotlinClassFinder
private val errorReporter: ErrorReporter
) : AnnotationAndConstantLoader<A, C, T> { ) : AnnotationAndConstantLoader<A, C, T> {
private val storage = storageManager.createMemoizedFunction<KotlinJvmBinaryClass, Storage<A, C>> { private val storage = storageManager.createMemoizedFunction<KotlinJvmBinaryClass, Storage<A, C>> {
kotlinClass -> kotlinClass ->
@@ -66,14 +65,11 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any,
return loadAnnotation(annotationClassId, source, result) return loadAnnotation(annotationClassId, source, result)
} }
private fun ProtoContainer.Class.toBinaryClass(): KotlinJvmBinaryClass? =
(source as? KotlinJvmBinarySourceElement)?.binaryClass
override fun loadClassAnnotations(container: ProtoContainer.Class): List<A> { override fun loadClassAnnotations(container: ProtoContainer.Class): List<A> {
val kotlinClass = kotlinClassFinder.findKotlinClass(container.classId) val kotlinClass = container.toBinaryClass() ?: error("Class for loading annotations is not found: ${container.debugFqName()}")
if (kotlinClass == null) {
// This means that the resource we're constructing the descriptor from is no longer present: KotlinClassFinder had found the
// class earlier, but it can't now
errorReporter.reportLoadingError("Kotlin class for loading class annotations is not found: ${container.debugFqName()}", null)
return listOf()
}
val result = ArrayList<A>(1) val result = ArrayList<A>(1)
@@ -208,18 +204,28 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any,
private fun findClassWithAnnotationsAndInitializers( private fun findClassWithAnnotationsAndInitializers(
container: ProtoContainer, implClassName: ClassId?, field: Boolean container: ProtoContainer, implClassName: ClassId?, field: Boolean
): KotlinJvmBinaryClass? { ): KotlinJvmBinaryClass? {
if (implClassName != null) {
return kotlinClassFinder.findKotlinClass(implClassName)
}
if (container is ProtoContainer.Class) { if (container is ProtoContainer.Class) {
val containerBinaryClass = container.toBinaryClass()
if (implClassName == container.classId) {
return containerBinaryClass
}
if (implClassName != null) {
return kotlinClassFinder.findKotlinClass(implClassName)
}
if (field && container.kind == ProtoBuf.Class.Kind.COMPANION_OBJECT && if (field && container.kind == ProtoBuf.Class.Kind.COMPANION_OBJECT &&
(container.outerClassKind == ClassKind.CLASS || container.outerClassKind == ClassKind.ENUM_CLASS)) { (container.outerClassKind == ClassKind.CLASS || container.outerClassKind == ClassKind.ENUM_CLASS)) {
// Backing fields of properties of a companion object in a class are generated in the outer class // Backing fields of properties of a companion object in a class are generated in the outer class
return kotlinClassFinder.findKotlinClass(container.classId.outerClassId) return kotlinClassFinder.findKotlinClass(container.classId.outerClassId)
} }
return kotlinClassFinder.findKotlinClass(container.classId) return containerBinaryClass
}
if (implClassName != null) {
return kotlinClassFinder.findKotlinClass(implClassName)
} }
return null return null
@@ -30,7 +30,10 @@ import org.jetbrains.kotlin.resolve.constants.AnnotationValue
import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory
import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.* import org.jetbrains.kotlin.serialization.deserialization.AnnotationDeserializer
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
import org.jetbrains.kotlin.serialization.deserialization.NotFoundClasses
import org.jetbrains.kotlin.serialization.deserialization.findNonGenericClassAcrossDependencies
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
import java.util.* import java.util.*
@@ -38,10 +41,9 @@ class BinaryClassAnnotationAndConstantLoaderImpl(
private val module: ModuleDescriptor, private val module: ModuleDescriptor,
private val notFoundClasses: NotFoundClasses, private val notFoundClasses: NotFoundClasses,
storageManager: StorageManager, storageManager: StorageManager,
kotlinClassFinder: KotlinClassFinder, kotlinClassFinder: KotlinClassFinder
errorReporter: ErrorReporter
) : AbstractBinaryClassAnnotationAndConstantLoader<AnnotationDescriptor, ConstantValue<*>, AnnotationWithTarget>( ) : AbstractBinaryClassAnnotationAndConstantLoader<AnnotationDescriptor, ConstantValue<*>, AnnotationWithTarget>(
storageManager, kotlinClassFinder, errorReporter storageManager, kotlinClassFinder
) { ) {
private val annotationDeserializer = AnnotationDeserializer(module, notFoundClasses) private val annotationDeserializer = AnnotationDeserializer(module, notFoundClasses)
private val factory = ConstantValueFactory(module.builtIns) private val factory = ConstantValueFactory(module.builtIns)
@@ -18,8 +18,9 @@ package org.jetbrains.kotlin.load.kotlin
import org.jetbrains.kotlin.descriptors.SourceElement import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.SourceFile import org.jetbrains.kotlin.descriptors.SourceFile
import org.jetbrains.kotlin.serialization.deserialization.descriptors.BinarySource
class KotlinJvmBinarySourceElement(val binaryClass: KotlinJvmBinaryClass) : SourceElement { class KotlinJvmBinarySourceElement(val binaryClass: KotlinJvmBinaryClass) : SourceElement, BinarySource {
override fun toString() = javaClass.name + ": " + binaryClass.toString() override fun toString() = javaClass.name + ": " + binaryClass.toString()
override fun getContainingFile(): SourceFile = SourceFile.NO_SOURCE_FILE override fun getContainingFile(): SourceFile = SourceFile.NO_SOURCE_FILE
} }
@@ -39,7 +39,4 @@ object RuntimeErrorReporter : ErrorReporter {
throw IllegalStateException("Cannot infer visibility for $descriptor") throw IllegalStateException("Cannot infer visibility for $descriptor")
} }
override fun reportLoadingError(message: String, exception: Exception?) {
throw IllegalStateException(message, exception)
}
} }
@@ -68,7 +68,7 @@ class RuntimeModuleData private constructor(val deserialization: Deserialization
val javaClassDataFinder = JavaClassDataFinder(reflectKotlinClassFinder, deserializedDescriptorResolver) val javaClassDataFinder = JavaClassDataFinder(reflectKotlinClassFinder, deserializedDescriptorResolver)
val notFoundClasses = NotFoundClasses(storageManager, module) val notFoundClasses = NotFoundClasses(storageManager, module)
val binaryClassAnnotationAndConstantLoader = BinaryClassAnnotationAndConstantLoaderImpl( val binaryClassAnnotationAndConstantLoader = BinaryClassAnnotationAndConstantLoaderImpl(
module, notFoundClasses, storageManager, reflectKotlinClassFinder, RuntimeErrorReporter module, notFoundClasses, storageManager, reflectKotlinClassFinder
) )
val deserializationComponentsForJava = DeserializationComponentsForJava( val deserializationComponentsForJava = DeserializationComponentsForJava(
storageManager, module, javaClassDataFinder, binaryClassAnnotationAndConstantLoader, storageManager, module, javaClassDataFinder, binaryClassAnnotationAndConstantLoader,
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.serialization.deserialization; package org.jetbrains.kotlin.serialization.deserialization;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor; import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
import org.jetbrains.kotlin.descriptors.ClassDescriptor; import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.name.ClassId; import org.jetbrains.kotlin.name.ClassId;
@@ -31,8 +30,6 @@ public interface ErrorReporter {
void reportCannotInferVisibility(@NotNull CallableMemberDescriptor descriptor); void reportCannotInferVisibility(@NotNull CallableMemberDescriptor descriptor);
void reportLoadingError(@NotNull String message, @Nullable Exception exception);
ErrorReporter DO_NOTHING = new ErrorReporter() { ErrorReporter DO_NOTHING = new ErrorReporter() {
@Override @Override
public void reportIncompatibleMetadataVersion( public void reportIncompatibleMetadataVersion(
@@ -47,9 +44,5 @@ public interface ErrorReporter {
@Override @Override
public void reportCannotInferVisibility(@NotNull CallableMemberDescriptor descriptor) { public void reportCannotInferVisibility(@NotNull CallableMemberDescriptor descriptor) {
} }
@Override
public void reportLoadingError(@NotNull String message, @Nullable Exception exception) {
}
}; };
} }
@@ -25,14 +25,16 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.BinarySour
sealed class ProtoContainer( sealed class ProtoContainer(
val nameResolver: NameResolver, val nameResolver: NameResolver,
val typeTable: TypeTable val typeTable: TypeTable,
val source: BinarySource?
) { ) {
class Class( class Class(
val classProto: ProtoBuf.Class, val classProto: ProtoBuf.Class,
nameResolver: NameResolver, nameResolver: NameResolver,
typeTable: TypeTable, typeTable: TypeTable,
source: BinarySource?,
val outerClassKind: ClassKind? val outerClassKind: ClassKind?
) : ProtoContainer(nameResolver, typeTable) { ) : ProtoContainer(nameResolver, typeTable, source) {
val classId: ClassId = nameResolver.getClassId(classProto.fqName) val classId: ClassId = nameResolver.getClassId(classProto.fqName)
val kind: ProtoBuf.Class.Kind = Flags.CLASS_KIND.get(classProto.flags) ?: ProtoBuf.Class.Kind.CLASS val kind: ProtoBuf.Class.Kind = Flags.CLASS_KIND.get(classProto.flags) ?: ProtoBuf.Class.Kind.CLASS
@@ -45,8 +47,8 @@ sealed class ProtoContainer(
val fqName: FqName, val fqName: FqName,
nameResolver: NameResolver, nameResolver: NameResolver,
typeTable: TypeTable, typeTable: TypeTable,
val source: BinarySource? source: BinarySource?
) : ProtoContainer(nameResolver, typeTable) { ) : ProtoContainer(nameResolver, typeTable, source) {
override fun debugFqName(): FqName = fqName override fun debugFqName(): FqName = fqName
} }
@@ -73,8 +73,9 @@ class DeserializedClassDescriptor(
private val constructors = c.storageManager.createLazyValue { computeConstructors() } private val constructors = c.storageManager.createLazyValue { computeConstructors() }
private val companionObjectDescriptor = c.storageManager.createNullableLazyValue { computeCompanionObjectDescriptor() } private val companionObjectDescriptor = c.storageManager.createNullableLazyValue { computeCompanionObjectDescriptor() }
internal val thisAsProtoContainer = internal val thisAsProtoContainer = ProtoContainer.Class(
ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, (containingDeclaration as? ClassDescriptor)?.kind) classProto, c.nameResolver, c.typeTable, sourceElement as? BinarySource, (containingDeclaration as? ClassDescriptor)?.kind
)
private val annotations = private val annotations =
if (!Flags.HAS_ANNOTATIONS.get(classProto.flags)) { if (!Flags.HAS_ANNOTATIONS.get(classProto.flags)) {
@@ -57,7 +57,9 @@ class KotlinBuiltInStubBuilder : ClsStubBuilder() {
packageProto.functionList, packageProto.propertyList packageProto.functionList, packageProto.propertyList
) )
for (classProto in file.classesToDecompile) { for (classProto in file.classesToDecompile) {
createClassStub(fileStub, classProto, nameResolver, nameResolver.getClassId(classProto.fqName), context) createClassStub(
fileStub, classProto, nameResolver, nameResolver.getClassId(classProto.fqName), source = null, context = context
)
} }
return fileStub return fileStub
} }
@@ -57,14 +57,13 @@ class DeserializerForClassfileDecompiler(
init { init {
val classDataFinder = DirectoryBasedDataFinder(classFinder, LOG) val classDataFinder = DirectoryBasedDataFinder(classFinder, LOG)
val errorReporter = LoggingErrorReporter(LOG)
val notFoundClasses = NotFoundClasses(storageManager, moduleDescriptor) val notFoundClasses = NotFoundClasses(storageManager, moduleDescriptor)
val annotationAndConstantLoader = val annotationAndConstantLoader =
BinaryClassAnnotationAndConstantLoaderImpl(moduleDescriptor, notFoundClasses, storageManager, classFinder, errorReporter) BinaryClassAnnotationAndConstantLoaderImpl(moduleDescriptor, notFoundClasses, storageManager, classFinder)
deserializationComponents = DeserializationComponents( deserializationComponents = DeserializationComponents(
storageManager, moduleDescriptor, classDataFinder, annotationAndConstantLoader, packageFragmentProvider, storageManager, moduleDescriptor, classDataFinder, annotationAndConstantLoader, packageFragmentProvider,
ResolveEverythingToKotlinAnyLocalClassResolver(targetPlatform.builtIns), errorReporter, ResolveEverythingToKotlinAnyLocalClassResolver(targetPlatform.builtIns), LoggingErrorReporter(LOG),
LookupTracker.DO_NOTHING, JavaFlexibleTypeCapabilitiesDeserializer, ClassDescriptorFactory.EMPTY, notFoundClasses LookupTracker.DO_NOTHING, JavaFlexibleTypeCapabilitiesDeserializer, ClassDescriptorFactory.EMPTY, notFoundClasses
) )
} }
@@ -26,16 +26,15 @@ import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.idea.caches.IDEKotlinBinaryClassCache import org.jetbrains.kotlin.idea.caches.IDEKotlinBinaryClassCache
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.* import org.jetbrains.kotlin.idea.decompiler.stubBuilder.*
import org.jetbrains.kotlin.idea.decompiler.textBuilder.LoggingErrorReporter
import org.jetbrains.kotlin.load.kotlin.AbstractBinaryClassAnnotationAndConstantLoader import org.jetbrains.kotlin.load.kotlin.AbstractBinaryClassAnnotationAndConstantLoader
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
import org.jetbrains.kotlin.serialization.deserialization.NameResolver import org.jetbrains.kotlin.serialization.deserialization.NameResolver
import org.jetbrains.kotlin.serialization.deserialization.TypeTable import org.jetbrains.kotlin.serialization.deserialization.TypeTable
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
@@ -55,9 +54,9 @@ open class KotlinClsStubBuilder : ClsStubBuilder() {
} }
fun doBuildFileStub(file: VirtualFile): PsiFileStub<KtFile>? { fun doBuildFileStub(file: VirtualFile): PsiFileStub<KtFile>? {
val kotlinClassHeaderInfo = IDEKotlinBinaryClassCache.getKotlinBinaryClassHeaderData(file)!! val kotlinClass = IDEKotlinBinaryClassCache.getKotlinBinaryClass(file)!!
val header = kotlinClassHeaderInfo.classHeader val header = kotlinClass.classHeader
val classId = kotlinClassHeaderInfo.classId val classId = kotlinClass.classId
val packageFqName = classId.packageFqName val packageFqName = classId.packageFqName
if (!header.metadataVersion.isCompatible()) { if (!header.metadataVersion.isCompatible()) {
return createIncompatibleAbiVersionFileStub() return createIncompatibleAbiVersionFileStub()
@@ -84,7 +83,7 @@ open class KotlinClsStubBuilder : ClsStubBuilder() {
if (classId.isLocal) return null if (classId.isLocal) return null
val (nameResolver, classProto) = JvmProtoBufUtil.readClassDataFrom(annotationData, strings) val (nameResolver, classProto) = JvmProtoBufUtil.readClassDataFrom(annotationData, strings)
val context = components.createContext(nameResolver, packageFqName, TypeTable(classProto.typeTable)) val context = components.createContext(nameResolver, packageFqName, TypeTable(classProto.typeTable))
createTopLevelClassStub(classId, classProto, context) createTopLevelClassStub(classId, classProto, KotlinJvmBinarySourceElement(kotlinClass), context)
} }
KotlinClassHeader.Kind.FILE_FACADE -> { KotlinClassHeader.Kind.FILE_FACADE -> {
val (nameResolver, packageProto) = JvmProtoBufUtil.readPackageDataFrom(annotationData, strings) val (nameResolver, packageProto) = JvmProtoBufUtil.readPackageDataFrom(annotationData, strings)
@@ -98,7 +97,7 @@ open class KotlinClsStubBuilder : ClsStubBuilder() {
private fun createStubBuilderComponents(file: VirtualFile, packageFqName: FqName): ClsStubBuilderComponents { private fun createStubBuilderComponents(file: VirtualFile, packageFqName: FqName): ClsStubBuilderComponents {
val classFinder = DirectoryBasedClassFinder(file.parent!!, packageFqName) val classFinder = DirectoryBasedClassFinder(file.parent!!, packageFqName)
val classDataFinder = DirectoryBasedDataFinder(classFinder, LOG) val classDataFinder = DirectoryBasedDataFinder(classFinder, LOG)
val annotationLoader = AnnotationLoaderForClassFileStubBuilder(classFinder, LoggingErrorReporter(LOG)) val annotationLoader = AnnotationLoaderForClassFileStubBuilder(classFinder)
return ClsStubBuilderComponents(classDataFinder, annotationLoader, file) return ClsStubBuilderComponents(classDataFinder, annotationLoader, file)
} }
@@ -108,10 +107,8 @@ open class KotlinClsStubBuilder : ClsStubBuilder() {
} }
class AnnotationLoaderForClassFileStubBuilder( class AnnotationLoaderForClassFileStubBuilder(
kotlinClassFinder: KotlinClassFinder, kotlinClassFinder: KotlinClassFinder
errorReporter: ErrorReporter ) : AbstractBinaryClassAnnotationAndConstantLoader<ClassId, Unit, ClassIdWithTarget>(LockBasedStorageManager.NO_LOCKS, kotlinClassFinder) {
) : AbstractBinaryClassAnnotationAndConstantLoader<ClassId, Unit, ClassIdWithTarget>(
LockBasedStorageManager.NO_LOCKS, kotlinClassFinder, errorReporter) {
override fun loadTypeAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): ClassId = override fun loadTypeAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): ClassId =
nameResolver.getClassId(proto.id) nameResolver.getClassId(proto.id)
@@ -70,7 +70,7 @@ class KotlinJavaScriptStubBuilder : ClsStubBuilder() {
val classProto = ProtoBuf.Class.parseFrom(content, JsSerializerProtocol.extensionRegistry) val classProto = ProtoBuf.Class.parseFrom(content, JsSerializerProtocol.extensionRegistry)
val context = components.createContext(nameResolver, packageFqName, TypeTable(classProto.typeTable)) val context = components.createContext(nameResolver, packageFqName, TypeTable(classProto.typeTable))
val classId = JsMetaFileUtils.getClassId(file) val classId = JsMetaFileUtils.getClassId(file)
return createTopLevelClassStub(classId, classProto, context) return createTopLevelClassStub(classId, classProto, source = null, context = context)
} }
} }
@@ -37,15 +37,17 @@ import org.jetbrains.kotlin.psi.stubs.impl.KotlinPlaceHolderStubImpl
import org.jetbrains.kotlin.serialization.Flags import org.jetbrains.kotlin.serialization.Flags
import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.* import org.jetbrains.kotlin.serialization.deserialization.*
import org.jetbrains.kotlin.serialization.deserialization.descriptors.BinarySource
fun createClassStub( fun createClassStub(
parent: StubElement<out PsiElement>, parent: StubElement<out PsiElement>,
classProto: ProtoBuf.Class, classProto: ProtoBuf.Class,
nameResolver: NameResolver, nameResolver: NameResolver,
classId: ClassId, classId: ClassId,
source: BinarySource?,
context: ClsStubBuilderContext context: ClsStubBuilderContext
) { ) {
ClassClsStubBuilder(parent, classProto, nameResolver, classId, context).build() ClassClsStubBuilder(parent, classProto, nameResolver, classId, source, context).build()
} }
private class ClassClsStubBuilder( private class ClassClsStubBuilder(
@@ -53,6 +55,7 @@ private class ClassClsStubBuilder(
private val classProto: ProtoBuf.Class, private val classProto: ProtoBuf.Class,
private val nameResolver: NameResolver, private val nameResolver: NameResolver,
private val classId: ClassId, private val classId: ClassId,
private val source: BinarySource?,
private val outerContext: ClsStubBuilderContext private val outerContext: ClsStubBuilderContext
) { ) {
private val classKind = Flags.CLASS_KIND[classProto.flags] private val classKind = Flags.CLASS_KIND[classProto.flags]
@@ -73,8 +76,9 @@ private class ClassClsStubBuilder(
private val companionObjectName = private val companionObjectName =
if (classProto.hasCompanionObjectName()) c.nameResolver.getName(classProto.companionObjectName) else null if (classProto.hasCompanionObjectName()) c.nameResolver.getName(classProto.companionObjectName) else null
private val thisAsProtoContainer = private val thisAsProtoContainer = ProtoContainer.Class(
ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, outerContext.classKind?.let { Deserialization.classKind(it) }) classProto, c.nameResolver, c.typeTable, source, outerContext.classKind?.let { Deserialization.classKind(it) }
)
private val classOrObjectStub = createClassOrObjectStubAndModifierListStub() private val classOrObjectStub = createClassOrObjectStubAndModifierListStub()
@@ -249,7 +253,7 @@ private class ClassClsStubBuilder(
return return
} }
val (nameResolver, classProto) = classDataWithSource.classData val (nameResolver, classProto) = classDataWithSource.classData
createClassStub(classBody, classProto, nameResolver, nestedClassId, c) createClassStub(classBody, classProto, nameResolver, nestedClassId, classDataWithSource.sourceElement as? BinarySource, c)
} }
companion object { companion object {
@@ -40,11 +40,17 @@ import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.AnnotatedCallableKind import org.jetbrains.kotlin.serialization.deserialization.AnnotatedCallableKind
import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
import org.jetbrains.kotlin.serialization.deserialization.TypeTable import org.jetbrains.kotlin.serialization.deserialization.TypeTable
import org.jetbrains.kotlin.serialization.deserialization.descriptors.BinarySource
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
fun createTopLevelClassStub(classId: ClassId, classProto: ProtoBuf.Class, context: ClsStubBuilderContext): KotlinFileStubImpl { fun createTopLevelClassStub(
classId: ClassId,
classProto: ProtoBuf.Class,
source: BinarySource?,
context: ClsStubBuilderContext
): KotlinFileStubImpl {
val fileStub = createFileStub(classId.packageFqName) val fileStub = createFileStub(classId.packageFqName)
createClassStub(fileStub, classProto, context.nameResolver, classId, context) createClassStub(fileStub, classProto, context.nameResolver, classId, source, context)
return fileStub return fileStub
} }
@@ -24,10 +24,6 @@ import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
class LoggingErrorReporter(private val log: Logger) : ErrorReporter { class LoggingErrorReporter(private val log: Logger) : ErrorReporter {
override fun reportLoadingError(message: String, exception: Exception?) {
log.error(message, exception)
}
override fun reportIncompleteHierarchy(descriptor: ClassDescriptor, unresolvedSuperClasses: List<String>) { override fun reportIncompleteHierarchy(descriptor: ClassDescriptor, unresolvedSuperClasses: List<String>) {
// This is absolutely fine for the decompiler // This is absolutely fine for the decompiler
} }