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:
-8
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-14
@@ -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
|
||||||
|
|||||||
+6
-4
@@ -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)
|
||||||
|
|||||||
+2
-1
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
-3
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -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,
|
||||||
|
|||||||
-7
@@ -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) {
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-4
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -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)) {
|
||||||
|
|||||||
+3
-1
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-3
@@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-11
@@ -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)
|
||||||
|
|||||||
+1
-1
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-4
@@ -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 {
|
||||||
|
|||||||
+8
-2
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-4
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user