diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/FileBasedKotlinClass.java b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/FileBasedKotlinClass.java index 71eb9182d64..f071fc432fd 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/FileBasedKotlinClass.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/FileBasedKotlinClass.java @@ -143,8 +143,9 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass { } @Override - public void loadClassAnnotations(@NotNull final AnnotationVisitor annotationVisitor) { - new ClassReader(getFileContents()).accept(new ClassVisitor(ASM5) { + public void loadClassAnnotations(@NotNull final AnnotationVisitor annotationVisitor, @Nullable byte[] cachedContents) { + byte[] fileContents = cachedContents != null ? cachedContents : getFileContents(); + new ClassReader(fileContents).accept(new ClassVisitor(ASM5) { @Override public org.jetbrains.org.objectweb.asm.AnnotationVisitor visitAnnotation(@NotNull String desc, boolean visible) { return convertAnnotationVisitor(annotationVisitor, desc, innerClasses); @@ -215,8 +216,9 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass { } @Override - public void visitMembers(@NotNull final MemberVisitor memberVisitor) { - new ClassReader(getFileContents()).accept(new ClassVisitor(ASM5) { + public void visitMembers(@NotNull final MemberVisitor memberVisitor, @Nullable byte[] cachedContents) { + byte[] fileContents = cachedContents != null ? cachedContents : getFileContents(); + new ClassReader(fileContents).accept(new ClassVisitor(ASM5) { @Override public FieldVisitor visitField(int access, @NotNull String name, @NotNull String desc, String signature, Object value) { final AnnotationVisitor v = memberVisitor.visitField(Name.identifier(name), desc, value); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt index 21aed97d04a..3e0e8165537 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt @@ -67,6 +67,8 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader { val kotlinClass = container.toBinaryClass() ?: error("Class for loading annotations is not found: ${container.debugFqName()}") @@ -79,7 +81,7 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader? { val virtualFile = content.file assert(virtualFile.fileType == KotlinBuiltInFileType) { "Unexpected file type ${virtualFile.fileType}" } - val file = BuiltInDefinitionFile.read(virtualFile) ?: return null + val file = BuiltInDefinitionFile.read(content.content, virtualFile) ?: return null when (file) { is BuiltInDefinitionFile.Incompatible -> { diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KotlinClsStubBuilder.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KotlinClsStubBuilder.kt index 385660981cc..025c979c368 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KotlinClsStubBuilder.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KotlinClsStubBuilder.kt @@ -26,10 +26,7 @@ import org.jetbrains.kotlin.descriptors.SourceElement import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.idea.caches.IDEKotlinBinaryClassCache import org.jetbrains.kotlin.idea.decompiler.stubBuilder.* -import org.jetbrains.kotlin.load.kotlin.AbstractBinaryClassAnnotationAndConstantLoader -import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder -import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass -import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement +import org.jetbrains.kotlin.load.kotlin.* import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName @@ -51,11 +48,11 @@ open class KotlinClsStubBuilder : ClsStubBuilder() { return null } - return doBuildFileStub(file) + return doBuildFileStub(file, content.content) } - fun doBuildFileStub(file: VirtualFile): PsiFileStub? { - val kotlinClass = IDEKotlinBinaryClassCache.getKotlinBinaryClass(file) ?: error("Can't find binary class for Kotlin file: $file") + fun doBuildFileStub(file: VirtualFile, fileContent: ByteArray): PsiFileStub? { + val kotlinClass = IDEKotlinBinaryClassCache.getKotlinBinaryClass(file, fileContent) ?: error("Can't find binary class for Kotlin file: $file") val header = kotlinClass.classHeader val classId = kotlinClass.classId val packageFqName = classId.packageFqName @@ -63,7 +60,7 @@ open class KotlinClsStubBuilder : ClsStubBuilder() { return createIncompatibleAbiVersionFileStub() } - val components = createStubBuilderComponents(file, packageFqName) + val components = createStubBuilderComponents(file, packageFqName, fileContent) if (header.kind == KotlinClassHeader.Kind.MULTIFILE_CLASS) { val partFiles = findMultifileClassParts(file, classId, header) return createMultifileClassStub(header, partFiles, classId.asSingleFqName(), components) @@ -95,10 +92,10 @@ open class KotlinClsStubBuilder : ClsStubBuilder() { } } - private fun createStubBuilderComponents(file: VirtualFile, packageFqName: FqName): ClsStubBuilderComponents { + private fun createStubBuilderComponents(file: VirtualFile, packageFqName: FqName, fileContent: ByteArray): ClsStubBuilderComponents { val classFinder = DirectoryBasedClassFinder(file.parent!!, packageFqName) val classDataFinder = DirectoryBasedDataFinder(classFinder, LOG) - val annotationLoader = AnnotationLoaderForClassFileStubBuilder(classFinder) + val annotationLoader = AnnotationLoaderForClassFileStubBuilder(classFinder, file, fileContent) return ClsStubBuilderComponents(classDataFinder, annotationLoader, file) } @@ -108,9 +105,18 @@ open class KotlinClsStubBuilder : ClsStubBuilder() { } class AnnotationLoaderForClassFileStubBuilder( - kotlinClassFinder: KotlinClassFinder + kotlinClassFinder: KotlinClassFinder, + private val cachedFile: VirtualFile, + private val cachedFileContent: ByteArray ) : AbstractBinaryClassAnnotationAndConstantLoader(LockBasedStorageManager.NO_LOCKS, kotlinClassFinder) { + override fun getCachedFileContent(kotlinClass: KotlinJvmBinaryClass): ByteArray? { + if ((kotlinClass as? VirtualFileKotlinClass)?.file == cachedFile) { + return cachedFileContent + } + return null + } + override fun loadTypeAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): ClassId = nameResolver.getClassId(proto.id)