diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliKotlinAsJavaSupport.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliKotlinAsJavaSupport.kt index 8adaa5e5555..15d545583e1 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliKotlinAsJavaSupport.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliKotlinAsJavaSupport.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.cli.jvm.compiler import com.intellij.openapi.project.Project import com.intellij.psi.PsiClass -import com.intellij.psi.PsiManager import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.PsiSearchScopeUtil import com.intellij.util.SmartList @@ -27,16 +26,14 @@ import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope class CliKotlinAsJavaSupport( - project: Project, + private val project: Project, private val traceHolder: CliTraceHolder ) : KotlinAsJavaSupport() { - private val psiManager = PsiManager.getInstance(project) - override fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection { return findFacadeFilesInPackage(packageFqName, scope) .groupBy { it.javaFileFacadeFqName } .mapNotNull { (facadeClassFqName, _) -> - KotlinLightClassFactory.createFacade(psiManager, facadeClassFqName, scope) + KotlinLightClassFactory.createFacade(project, facadeClassFqName, scope) } } @@ -53,7 +50,7 @@ class CliKotlinAsJavaSupport( .orEmpty() override fun getFacadeClasses(facadeFqName: FqName, scope: GlobalSearchScope): Collection { - return listOfNotNull(KotlinLightClassFactory.createFacade(psiManager, facadeFqName, scope)) + return listOfNotNull(KotlinLightClassFactory.createFacade(project, facadeFqName, scope)) } override fun getScriptClasses(scriptFqName: FqName, scope: GlobalSearchScope): Collection { diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt index e5996377641..3a7bb35212f 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt @@ -43,6 +43,8 @@ import org.jetbrains.annotations.TestOnly import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport import org.jetbrains.kotlin.asJava.LightClassGenerationSupport import org.jetbrains.kotlin.asJava.classes.FacadeCache +import org.jetbrains.kotlin.asJava.classes.KotlinK1LightClassFactory +import org.jetbrains.kotlin.asJava.classes.KotlinLightClassFactory import org.jetbrains.kotlin.asJava.finder.JavaElementFinder import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension import org.jetbrains.kotlin.cli.common.* @@ -63,8 +65,8 @@ import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleResolver import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension import org.jetbrains.kotlin.codegen.extensions.ClassFileFactoryFinalizerExtension import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension -import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar +import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar import org.jetbrains.kotlin.compiler.plugin.registerInProject import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.extensions.* @@ -673,6 +675,7 @@ class KotlinCoreEnvironment private constructor( // ability to get text from annotations xml files applicationEnvironment.registerFileType(PlainTextFileType.INSTANCE, "xml") applicationEnvironment.registerParserDefinition(JavaParserDefinition()) + applicationEnvironment.registerApplicationService(KotlinLightClassFactory::class.java, KotlinK1LightClassFactory()) } // made public for Upsource diff --git a/compiler/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/KotlinLightClassFactory.kt b/compiler/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/KotlinLightClassFactory.kt new file mode 100644 index 00000000000..132412c891b --- /dev/null +++ b/compiler/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/KotlinLightClassFactory.kt @@ -0,0 +1,44 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +@file:Suppress("unused") + +package org.jetbrains.kotlin.asJava.classes + +import com.intellij.openapi.components.ServiceManager +import com.intellij.openapi.project.Project +import com.intellij.psi.search.GlobalSearchScope +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtScript + +interface KotlinLightClassFactory { + fun createClass(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? + fun createFacade(project: Project, facadeClassFqName: FqName, searchScope: GlobalSearchScope): KtLightClassForFacade? + fun createFacadeForSyntheticFile(facadeClassFqName: FqName, file: KtFile): KtLightClassForFacade + fun createScript(script: KtScript): KtLightClassForScript? + + companion object { + private val instance: KotlinLightClassFactory + get() = ServiceManager.getService(KotlinLightClassFactory::class.java) + + fun createClass(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? { + return instance.createClass(classOrObject) + } + + fun createFacade(project: Project, facadeClassFqName: FqName, searchScope: GlobalSearchScope): KtLightClassForFacade? { + return instance.createFacade(project, facadeClassFqName, searchScope) + } + + fun createFacadeForSyntheticFile(facadeClassFqName: FqName, file: KtFile): KtLightClassForFacade { + return instance.createFacadeForSyntheticFile(facadeClassFqName, file) + } + + fun createScript(script: KtScript): KtLightClassForScript? { + return instance.createScript(script) + } + } +} \ No newline at end of file diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/FacadeCache.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/FacadeCache.kt index 2843e86509d..c567409015c 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/FacadeCache.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/FacadeCache.kt @@ -27,7 +27,7 @@ class FacadeCache(private val project: Project) { private inner class FacadeCacheData { val cache = object : SLRUCache(20, 30) { override fun createValue(key: FacadeCacheKey): ValueWrapper = - KotlinLightClassFactory.createFacadeNoCache(key.fqName, key.searchScope, project) + KotlinK1LightClassFactory.createFacadeNoCache(key.fqName, key.searchScope, project) ?.let { ValueWrapper(it) } ?: ValueWrapper.Null } diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KotlinK1LightClassFactory.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KotlinK1LightClassFactory.kt new file mode 100644 index 00000000000..eca1621a116 --- /dev/null +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KotlinK1LightClassFactory.kt @@ -0,0 +1,95 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.asJava.classes + +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiManager +import com.intellij.psi.search.GlobalSearchScope +import com.intellij.psi.util.CachedValueProvider +import com.intellij.psi.util.CachedValuesManager +import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService +import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport +import org.jetbrains.kotlin.asJava.LightClassGenerationSupport +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.psi.KtCodeFragment +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtScript + +class KotlinK1LightClassFactory : KotlinLightClassFactory { + override fun createClass(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? = + CachedValuesManager.getCachedValue(classOrObject) { + CachedValueProvider.Result.create( + createClassNoCache(classOrObject), + KotlinModificationTrackerService.getInstance(classOrObject.project).outOfBlockModificationTracker, + ) + } + + override fun createFacade( + project: Project, + facadeClassFqName: FqName, + searchScope: GlobalSearchScope, + ): KtLightClassForFacade? = FacadeCache.getInstance(project)[facadeClassFqName, searchScope] + + override fun createFacadeForSyntheticFile(facadeClassFqName: FqName, file: KtFile): KtLightClassForFacade { + val project = file.project + val manager = PsiManager.getInstance(project) + return LightClassGenerationSupport.getInstance(project).run { + createUltraLightClassForFacade(manager, facadeClassFqName, listOf(file)) ?: error { "Unable to create UL class for facade" } + } + } + + override fun createScript(script: KtScript): KtLightClassForScript? = CachedValuesManager.getCachedValue(script) { + CachedValueProvider.Result.create( + createScriptNoCache(script), + KotlinModificationTrackerService.getInstance(script.project).outOfBlockModificationTracker, + ) + } + + companion object { + fun createScriptNoCache(script: KtScript): KtLightClassForScript? { + val containingFile = script.containingFile + if (containingFile is KtCodeFragment) { + // Avoid building light classes for code fragments + return null + } + + return LightClassGenerationSupport.getInstance(script.project).run { + createUltraLightClassForScript(script) + } + } + + fun createClassNoCache(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? { + val containingFile = classOrObject.containingFile + if (containingFile is KtCodeFragment) { + // Avoid building light classes for code fragments + return null + } + + if (classOrObject.shouldNotBeVisibleAsLightClass()) { + return null + } + + return LightClassGenerationSupport.getInstance(classOrObject.project).run { + createUltraLightClass(classOrObject) + } + } + + fun createFacadeNoCache(fqName: FqName, searchScope: GlobalSearchScope, project: Project): KtLightClassForFacade? { + val sources = KotlinAsJavaSupport.getInstance(project) + .findFilesForFacade(fqName, searchScope) + .filterNot { it.isCompiled || it.isScript() } + + if (sources.isEmpty()) return null + val manager = PsiManager.getInstance(project) + return LightClassGenerationSupport.getInstance(project).run { + if (!canCreateUltraLightClassForFacade(sources)) return null + createUltraLightClassForFacade(manager, fqName, sources) + ?: error("Unable to create UL class for facade: $fqName for ${sources.joinToString { it.virtualFilePath }}") + } + } + } +} \ No newline at end of file diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KotlinLightClassFactory.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KotlinLightClassFactory.kt deleted file mode 100644 index 361168d0500..00000000000 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KotlinLightClassFactory.kt +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -@file:Suppress("unused", "MemberVisibilityCanBePrivate") - -package org.jetbrains.kotlin.asJava.classes - -import com.intellij.openapi.project.Project -import com.intellij.psi.PsiManager -import com.intellij.psi.search.GlobalSearchScope -import com.intellij.psi.util.CachedValueProvider -import com.intellij.psi.util.CachedValuesManager -import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService -import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport -import org.jetbrains.kotlin.asJava.LightClassGenerationSupport -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.psi.KtClassOrObject -import org.jetbrains.kotlin.psi.KtCodeFragment -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi.KtScript - -object KotlinLightClassFactory { - fun createClass(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? = - CachedValuesManager.getCachedValue(classOrObject) { - CachedValueProvider.Result.create( - createClassNoCache(classOrObject), - KotlinModificationTrackerService.getInstance(classOrObject.project).outOfBlockModificationTracker, - ) - } - - fun createClassNoCache(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? { - val containingFile = classOrObject.containingFile - if (containingFile is KtCodeFragment) { - // Avoid building light classes for code fragments - return null - } - - if (classOrObject.shouldNotBeVisibleAsLightClass()) { - return null - } - - return LightClassGenerationSupport.getInstance(classOrObject.project).run { - createUltraLightClass(classOrObject) - } - } - - fun createFacadeNoCache(fqName: FqName, searchScope: GlobalSearchScope, project: Project): KtLightClassForFacade? { - val sources = KotlinAsJavaSupport.getInstance(project) - .findFilesForFacade(fqName, searchScope) - .filterNot { it.isCompiled || it.isScript() } - - if (sources.isEmpty()) return null - val manager = PsiManager.getInstance(project) - return LightClassGenerationSupport.getInstance(project).run { - if (!canCreateUltraLightClassForFacade(sources)) return null - createUltraLightClassForFacade(manager, fqName, sources) - ?: error("Unable to create UL class for facade: $fqName for ${sources.joinToString { it.virtualFilePath }}") - } - } - - fun createFacade( - manager: PsiManager, - facadeClassFqName: FqName, - searchScope: GlobalSearchScope - ): KtLightClassForFacade? { - return FacadeCache.getInstance(manager.project)[facadeClassFqName, searchScope] - } - - fun createFacadeForSyntheticFile( - facadeClassFqName: FqName, - file: KtFile - ): KtLightClassForFacade { - val project = file.project - val manager = PsiManager.getInstance(project) - return LightClassGenerationSupport.getInstance(project).run { - createUltraLightClassForFacade(manager, facadeClassFqName, listOf(file)) ?: error { "Unable to create UL class for facade" } - } - } - - fun createScript(script: KtScript): KtLightClassForScript? = - CachedValuesManager.getCachedValue(script) { - CachedValueProvider.Result.create( - createScriptNoCache(script), - KotlinModificationTrackerService.getInstance(script.project).outOfBlockModificationTracker, - ) - } - - fun createScriptNoCache(script: KtScript): KtLightClassForScript? { - val containingFile = script.containingFile - if (containingFile is KtCodeFragment) { - // Avoid building light classes for code fragments - return null - } - - return LightClassGenerationSupport.getInstance(script.project).run { - createUltraLightClassForScript(script) - } - } -} \ No newline at end of file