From 909f0d8bdb7085ff5653153628eeeda0fac33f76 Mon Sep 17 00:00:00 2001 From: Victor Petukhov Date: Sun, 25 Apr 2021 16:27:35 +0300 Subject: [PATCH] Implement caching module annotations per class id --- .../cli/jvm/modules/CliJavaModuleResolver.kt | 8 ++++++- .../lazy/JavaModuleAnnotationsProvider.kt | 2 +- .../descriptors/LazyJavaClassDescriptor.kt | 5 ++++ .../typeEnhancement/signatureEnhancement.kt | 4 ++-- .../runtime/components/RuntimeModuleData.kt | 2 +- .../idea/modules/IdeJavaModuleResolver.kt | 23 +++++++++++++++---- 6 files changed, 35 insertions(+), 9 deletions(-) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/modules/CliJavaModuleResolver.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/modules/CliJavaModuleResolver.kt index afc064a0483..e3ea14f7f90 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/modules/CliJavaModuleResolver.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/modules/CliJavaModuleResolver.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.jvm.modules.JavaModule import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver +import java.util.concurrent.ConcurrentHashMap class CliJavaModuleResolver( private val moduleGraph: JavaModuleGraph, @@ -44,8 +45,9 @@ class CliJavaModuleResolver( private val virtualFileFinder by lazy { VirtualFileFinder.getInstance(project) } - override fun getModuleAnnotations(classId: ClassId): List? { + override fun getAnnotationsForModuleOwnerOfClass(classId: ClassId): List? { val virtualFile = virtualFileFinder.findSourceOrBinaryVirtualFile(classId) ?: return null + return (findJavaModule(virtualFile) as? JavaModule.Explicit)?.moduleInfo?.annotations } @@ -89,4 +91,8 @@ class CliJavaModuleResolver( return null } + + companion object { + private const val MODULE_ANNOTATIONS_CACHE_SIZE = 10000 + } } diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/JavaModuleAnnotationsProvider.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/JavaModuleAnnotationsProvider.kt index 62a87ce2be5..23a358c1683 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/JavaModuleAnnotationsProvider.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/JavaModuleAnnotationsProvider.kt @@ -9,5 +9,5 @@ import org.jetbrains.kotlin.load.java.structure.JavaAnnotation import org.jetbrains.kotlin.name.ClassId interface JavaModuleAnnotationsProvider { - fun getModuleAnnotations(classId: ClassId): List? + fun getAnnotationsForModuleOwnerOfClass(classId: ClassId): List? } diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt index 16f5643fbb1..04fcb739d66 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.load.java.toDescriptorVisibility import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.isValidJavaFqName import org.jetbrains.kotlin.resolve.constants.StringValue +import org.jetbrains.kotlin.resolve.descriptorUtil.classId import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.resolve.descriptorUtil.resolveTopLevelClass @@ -67,6 +68,10 @@ class LazyJavaClassDescriptor( } } + val moduleAnnotations by lazy { + classId?.let { outerContext.components.javaModuleResolver.getAnnotationsForModuleOwnerOfClass(it) } + } + private val kind = when { jClass.isAnnotationType -> ClassKind.ANNOTATION_CLASS jClass.isInterface -> ClassKind.INTERFACE diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt index ddc23f58b7a..4b6251754eb 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.load.java.descriptors.* import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext import org.jetbrains.kotlin.load.java.lazy.copyWithNewDefaultTypeQualifiers import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaAnnotationDescriptor +import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaClassDescriptor import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaTypeParameterDescriptor import org.jetbrains.kotlin.load.java.lazy.descriptors.isJavaField import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents @@ -150,8 +151,7 @@ class SignatureEnhancement( private fun D.getDefaultAnnotations(c: LazyJavaResolverContext): Annotations { val topLevelClassifier = getTopLevelContainingClassifier() ?: return annotations - val classId = topLevelClassifier.classId ?: return annotations - val moduleAnnotations = c.components.javaModuleResolver.getModuleAnnotations(classId) + val moduleAnnotations = (topLevelClassifier as? LazyJavaClassDescriptor)?.moduleAnnotations if (moduleAnnotations.isNullOrEmpty()) return annotations diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/descriptors/runtime/components/RuntimeModuleData.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/descriptors/runtime/components/RuntimeModuleData.kt index cd3c2cfc446..5e0fff4de47 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/descriptors/runtime/components/RuntimeModuleData.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/descriptors/runtime/components/RuntimeModuleData.kt @@ -123,7 +123,7 @@ fun makeLazyJavaPackageFragmentFromClassLoaderProvider( SignatureEnhancement(annotationTypeQualifierResolver, JavaTypeEnhancementState.DISABLED_JSR_305, JavaTypeEnhancement(JavaResolverSettings.Default)), JavaClassesTracker.Default, JavaResolverSettings.Default, NewKotlinTypeChecker.Default, javaTypeEnhancementState, object : JavaModuleAnnotationsProvider { - override fun getModuleAnnotations(classId: ClassId): List? = null + override fun getAnnotationsForModuleOwnerOfClass(classId: ClassId): List? = null } ) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/modules/IdeJavaModuleResolver.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/modules/IdeJavaModuleResolver.kt index aa36b3bf595..147afe57825 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/modules/IdeJavaModuleResolver.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/modules/IdeJavaModuleResolver.kt @@ -16,16 +16,27 @@ import org.jetbrains.kotlin.load.java.structure.impl.convert import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.resolve.jvm.modules.JavaModule import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver +import java.util.concurrent.ConcurrentHashMap class IdeJavaModuleResolver(private val project: Project) : JavaModuleResolver { private val virtualFileFinder by lazy { VirtualFileFinder.getInstance(project) } - override fun getModuleAnnotations(classId: ClassId): List? { - val virtualFile = virtualFileFinder.findVirtualFileWithHeader(classId) ?: return null + private val modulesAnnotationCache = ConcurrentHashMap>() - return findJavaModule(virtualFile)?.annotations?.convert(::JavaAnnotationImpl) + override fun getAnnotationsForModuleOwnerOfClass(classId: ClassId): List? { + if (modulesAnnotationCache.containsKey(classId)) { + return modulesAnnotationCache[classId] + } + + val virtualFile = virtualFileFinder.findVirtualFileWithHeader(classId) ?: return null + val moduleAnnotations = findJavaModule(virtualFile)?.annotations?.convert(::JavaAnnotationImpl) + + if (moduleAnnotations != null && moduleAnnotations.size < MODULE_ANNOTATIONS_CACHE_SIZE) { + modulesAnnotationCache[classId] = moduleAnnotations + } + + return moduleAnnotations } private fun findJavaModule(file: VirtualFile): PsiJavaModule? = ModuleHighlightUtil2.getModuleDescriptor(file, project) @@ -65,4 +76,8 @@ class IdeJavaModuleResolver(private val project: Project) : JavaModuleResolver { // Returns whether or not [source] exports [packageName] to [target] private fun exports(source: PsiJavaModule, packageName: String, target: PsiJavaModule): Boolean = source is LightJavaModule || JavaModuleGraphUtil.exports(source, packageName, target) + + companion object { + private const val MODULE_ANNOTATIONS_CACHE_SIZE = 10000 + } }