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)