From 24253e21d01303dbfb7f387315105f62c0f00dfe Mon Sep 17 00:00:00 2001 From: Igor Yakovlev Date: Thu, 23 May 2019 16:27:57 +0300 Subject: [PATCH] Add ultraKtLightClassForFacade multifile support --- .../CliLightClassGenerationSupport.kt | 4 +- .../asJava/LightClassGenerationSupport.kt | 4 +- .../asJava/classes/KtLightClassForFacade.kt | 24 ++++------ .../classes/ultraKtLightClassForFacade.kt | 47 ++++++++++++------- .../resolve/IDELightClassGenerationSupport.kt | 17 ++++--- 5 files changed, 54 insertions(+), 42 deletions(-) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliLightClassGenerationSupport.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliLightClassGenerationSupport.kt index 23799777df8..a0ac46fbdf4 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliLightClassGenerationSupport.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliLightClassGenerationSupport.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.cli.jvm.compiler +import com.intellij.psi.PsiManager import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.util.CachedValue import org.jetbrains.kotlin.asJava.LightClassBuilder @@ -45,9 +46,10 @@ import org.jetbrains.kotlin.resolve.BindingContext class CliLightClassGenerationSupport(private val traceHolder: CliTraceHolder) : LightClassGenerationSupport() { override fun createUltraLightClassForFacade( + manager: PsiManager, facadeClassFqName: FqName, lightClassDataCache: CachedValue, - facadeFile: KtFile + files: Collection ): KtUltraLightClassForFacade? = null override fun createUltraLightClass(element: KtClassOrObject) = null diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/LightClassGenerationSupport.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/LightClassGenerationSupport.kt index 1dffa29b290..02031349ac9 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/LightClassGenerationSupport.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/LightClassGenerationSupport.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.asJava import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.project.Project +import com.intellij.psi.PsiManager import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.util.CachedValue import org.jetbrains.kotlin.asJava.builder.LightClassBuilderResult @@ -50,9 +51,10 @@ abstract class LightClassGenerationSupport { abstract fun createUltraLightClass(element: KtClassOrObject): KtUltraLightClass? abstract fun createUltraLightClassForFacade( + manager: PsiManager, facadeClassFqName: FqName, lightClassDataCache: CachedValue, - facadeFile: KtFile + files: Collection ): KtUltraLightClassForFacade? companion object { diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForFacade.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForFacade.kt index 46a69278f7a..3075eccf966 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForFacade.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForFacade.kt @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.asJava.LightClassGenerationSupport import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForFileFacade import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass +import org.jetbrains.kotlin.codegen.inline.getOrPut import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName import org.jetbrains.kotlin.idea.KotlinLanguage @@ -266,23 +267,14 @@ open class KtLightClassForFacade protected constructor( val ultraLightEnabled = !KtUltraLightSupport.forceUsingOldLightClasses && Registry.`is`("kotlin.use.ultra.light.classes", true) - if (ultraLightEnabled && files.count() == 1) { - val facadeFile = files.first() - - return CachedValuesManager.getCachedValue(facadeFile) { - - val lightClassDataCache = FacadeStubCache.getInstance(manager.project).get(facadeClassFqName, searchScope) - - val classForFacade = LightClassGenerationSupport.getInstance(facadeFile.project) - .createUltraLightClassForFacade(facadeClassFqName, lightClassDataCache, facadeFile) - ?: KtLightClassForFacade(manager, facadeClassFqName, lightClassDataCache, files) - - CachedValueProvider.Result.create(classForFacade, OUT_OF_CODE_BLOCK_MODIFICATION_COUNT) - } - } - val lightClassDataCache = FacadeStubCache.getInstance(manager.project).get(facadeClassFqName, searchScope) - return KtLightClassForFacade(manager, facadeClassFqName, lightClassDataCache, files) + + val ultraLightClass = if (ultraLightEnabled) + LightClassGenerationSupport.getInstance(manager.project) + .createUltraLightClassForFacade(manager, facadeClassFqName, lightClassDataCache, files) + else null + + return ultraLightClass ?: KtLightClassForFacade(manager, facadeClassFqName, lightClassDataCache, files) } fun createForSyntheticFile( diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraKtLightClassForFacade.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraKtLightClassForFacade.kt index 1a26042e496..671709a3e62 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraKtLightClassForFacade.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraKtLightClassForFacade.kt @@ -20,11 +20,9 @@ class KtUltraLightClassForFacade( manager: PsiManager, facadeClassFqName: FqName, lightClassDataCache: CachedValue, - private val file: KtFile, - private val support: KtUltraLightSupport -) : KtLightClassForFacade(manager, facadeClassFqName, lightClassDataCache, listOf(file)) { - - private val membersBuilder by lazyPub { UltraLightMembersCreator(this, false, true, support) } + files: Collection, + private val filesToSupports: Collection> +) : KtLightClassForFacade(manager, facadeClassFqName, lightClassDataCache, files) { private inline fun forTooComplex(getter: () -> T): T { check(tooComplex) { @@ -39,17 +37,30 @@ class KtUltraLightClassForFacade( override val clsDelegate: PsiClass get() = forTooComplex { super.clsDelegate } - private val tooComplex: Boolean by lazyPub { file.declarations.any { support.isTooComplexForUltraLightGeneration(it) } } + private val tooComplex: Boolean by lazyPub { + filesToSupports.any { (file, support) -> + file.declarations.any { support.isTooComplexForUltraLightGeneration(it) } + } + } + + private val filesToSupportsToMemberCreators by lazyPub { + filesToSupports.map { (file, support) -> + Triple(file, support, UltraLightMembersCreator(this, false, true, support)) + } + } private val ownMethodsForNotTooComplex: List by lazyPub { val result = arrayListOf() - for (declaration in file.declarations.filterNot { it.isHiddenByDeprecation(support) }) { - if (declaration.hasModifier(KtTokens.PRIVATE_KEYWORD)) continue - when (declaration) { - is KtNamedFunction -> result.addAll(membersBuilder.createMethods(declaration, true)) - is KtProperty -> result.addAll(membersBuilder.propertyAccessors(declaration, declaration.isVar, true, false)) + for ((file, support, creator) in filesToSupportsToMemberCreators) { + + for (declaration in file.declarations.filterNot { it.isHiddenByDeprecation(support) }) { + if (declaration.hasModifier(KtTokens.PRIVATE_KEYWORD)) continue + when (declaration) { + is KtNamedFunction -> result.addAll(creator.createMethods(declaration, true)) + is KtProperty -> result.addAll(creator.propertyAccessors(declaration, declaration.isVar, true, false)) + } } } @@ -57,9 +68,11 @@ class KtUltraLightClassForFacade( } private val ownFieldsForNotTooComplex: List by lazyPub { - hashSetOf().run { - file.declarations.filterIsInstance().mapNotNull { - membersBuilder.createPropertyField(it, this, forceStatic = true) + hashSetOf().let { nameCache -> + filesToSupportsToMemberCreators.flatMap { (file, support, creator) -> + file.declarations.filterIsInstance().mapNotNull { + creator.createPropertyField(it, nameCache, forceStatic = true) + } } } } @@ -68,8 +81,6 @@ class KtUltraLightClassForFacade( override fun getOwnMethods() = if (!tooComplex) ownMethodsForNotTooComplex else super.getOwnMethods() - override fun toString(): String = "UltraLight class for file facade" - - override fun copy(): KtLightClassForFacade = KtUltraLightClassForFacade(manager, facadeClassFqName, lightClassDataCache, file, support) - + override fun copy(): KtLightClassForFacade = + KtUltraLightClassForFacade(manager, facadeClassFqName, lightClassDataCache, files, filesToSupports) } \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt index 9cd8ae6fbf0..74979ac3a16 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt @@ -60,6 +60,7 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.NoDescriptorForDeclarationException import org.jetbrains.kotlin.resolve.source.getPsi import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.utils.keysToMap import java.util.concurrent.ConcurrentMap class IDELightClassGenerationSupport(private val project: Project) : LightClassGenerationSupport() { @@ -178,21 +179,25 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG } override fun createUltraLightClassForFacade( + manager: PsiManager, facadeClassFqName: FqName, lightClassDataCache: CachedValue, - facadeFile: KtFile + files: Collection ): KtUltraLightClassForFacade? { - if (facadeFile.isScript()) return null + if (files.any { it.isScript() }) return null - val module = ModuleUtilCore.findModuleForPsiElement(facadeFile) ?: return null + val filesToSupports: List> = files.map { + val module = ModuleUtilCore.findModuleForPsiElement(it) ?: return null + it to KtUltraLightSupportImpl(it, module) + } return KtUltraLightClassForFacade( - facadeFile.manager, + manager, facadeClassFqName, lightClassDataCache, - facadeFile, - KtUltraLightSupportImpl(facadeFile, module) + files, + filesToSupports ) }