From cec10dac853b6b4a2113b73c82c952f7253df8d0 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Tue, 23 Apr 2019 04:21:40 +0300 Subject: [PATCH] FIR deserializer: remove cycle in annotations loading --- .../KotlinDeserializedJvmSymbolsProvider.kt | 80 ++++++++++--------- .../annotations/AnnotatedAnnotation.txt | 2 +- 2 files changed, 44 insertions(+), 38 deletions(-) diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/KotlinDeserializedJvmSymbolsProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/KotlinDeserializedJvmSymbolsProvider.kt index 38613113657..7830a50cebc 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/KotlinDeserializedJvmSymbolsProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/KotlinDeserializedJvmSymbolsProvider.kt @@ -280,48 +280,54 @@ class KotlinDeserializedJvmSymbolsProvider( parentContext: FirDeserializationContext? = null ): FirClassSymbol? { if (!hasTopLevelClassOf(classId)) return null - return classesCache.getOrPut(classId) { - //return null - val kotlinJvmBinaryClass = kotlinClassFinder.findKotlinClass(classId) - if (kotlinJvmBinaryClass == null) { - val outerClassId = classId.outerClassId ?: return null - val outerJvmBinaryClass = kotlinClassFinder.findKotlinClass(outerClassId) ?: return null - if (outerJvmBinaryClass.classHeader.kind != KotlinClassHeader.Kind.CLASS) return null - val (nameResolver, outerClassProto) = outerJvmBinaryClass.readClassDataFrom() ?: return null - if (outerClassProto.enumEntryList.none { nameResolver.getName(it.name) == classId.shortClassName }) { - return null + if (classesCache.containsKey(classId)) return classesCache[classId] + + +// return classesCache.getOrPut(classId) { + //return null + val kotlinJvmBinaryClass = kotlinClassFinder.findKotlinClass(classId) + if (kotlinJvmBinaryClass == null) { + val outerClassId = classId.outerClassId ?: return null + val outerJvmBinaryClass = kotlinClassFinder.findKotlinClass(outerClassId) ?: return null + if (outerJvmBinaryClass.classHeader.kind != KotlinClassHeader.Kind.CLASS) return null + val (nameResolver, outerClassProto) = outerJvmBinaryClass.readClassDataFrom() ?: return null + if (outerClassProto.enumEntryList.none { nameResolver.getName(it.name) == classId.shortClassName }) { + return null + } + + val symbol = FirClassSymbol(classId) + FirEnumEntryImpl(session, null, symbol, classId.shortClassName) + classesCache[classId] = symbol + } else { + if (kotlinJvmBinaryClass.classHeader.kind != KotlinClassHeader.Kind.CLASS) return null + val (nameResolver, classProto) = kotlinJvmBinaryClass.readClassDataFrom() ?: return null + + val symbol = FirClassSymbol(classId) + deserializeClassToSymbol( + classId, classProto, symbol, nameResolver, session, + parentContext ?: FirDeserializationContext.createForClass( + classId, classProto, nameResolver, session, + JvmBinaryAnnotationDeserializer(session, nameResolver) + ), + this::findAndDeserializeClass + ) + classesCache[classId] = symbol + val annotations = mutableListOf() + kotlinJvmBinaryClass.loadClassAnnotations(object : KotlinJvmBinaryClass.AnnotationVisitor { + override fun visitAnnotation(classId: ClassId, source: SourceElement): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { + return loadAnnotationIfNotSpecial(classId, annotations) } - val symbol = FirClassSymbol(classId) - FirEnumEntryImpl(session, null, symbol, classId.shortClassName) - symbol - } else { - if (kotlinJvmBinaryClass.classHeader.kind != KotlinClassHeader.Kind.CLASS) return null - val (nameResolver, classProto) = kotlinJvmBinaryClass.readClassDataFrom() ?: return null + override fun visitEnd() { + } - val symbol = FirClassSymbol(classId) - deserializeClassToSymbol( - classId, classProto, symbol, nameResolver, session, - parentContext ?: FirDeserializationContext.createForClass( - classId, classProto, nameResolver, session, - JvmBinaryAnnotationDeserializer(session, nameResolver) - ), - this::findAndDeserializeClass - ) - val annotations = mutableListOf() - kotlinJvmBinaryClass.loadClassAnnotations(object : KotlinJvmBinaryClass.AnnotationVisitor { - override fun visitAnnotation(classId: ClassId, source: SourceElement): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { - return loadAnnotationIfNotSpecial(classId, annotations) - } - override fun visitEnd() { - } - - }, null) - (symbol.fir as FirAbstractAnnotatedElement).annotations += annotations - symbol - } + }, null) + (symbol.fir as FirAbstractAnnotatedElement).annotations += annotations } + + return classesCache[classId] +// } } private fun loadFunctionsByName(part: PackagePartsCacheData, name: Name): List { diff --git a/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/AnnotatedAnnotation.txt b/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/AnnotatedAnnotation.txt index 303b8c0ae52..3bd4f57141b 100644 --- a/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/AnnotatedAnnotation.txt +++ b/compiler/fir/resolve/testData/loadCompiledKotlin/annotations/AnnotatedAnnotation.txt @@ -1,4 +1,4 @@ -public final annotation class AnnotatedAnnotation : R|kotlin/Annotation| { +@R|test/AnnotatedAnnotation|() public final annotation class AnnotatedAnnotation : R|kotlin/Annotation| { public constructor(): R|test/AnnotatedAnnotation| }