diff --git a/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/test/configurator/AnalysisApiFe10TestServiceRegistrar.kt b/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/test/configurator/AnalysisApiFe10TestServiceRegistrar.kt index 011f594fc12..c1c041d5ce6 100644 --- a/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/test/configurator/AnalysisApiFe10TestServiceRegistrar.kt +++ b/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/test/configurator/AnalysisApiFe10TestServiceRegistrar.kt @@ -8,20 +8,19 @@ package org.jetbrains.kotlin.analysis.api.fe10.test.configurator import com.intellij.mock.MockApplication import com.intellij.mock.MockProject import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals -import org.jetbrains.kotlin.analysis.api.session.KtAnalysisSessionProvider import org.jetbrains.kotlin.analysis.api.descriptors.CliFe10AnalysisFacade import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisHandlerExtension import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSessionProvider import org.jetbrains.kotlin.analysis.api.descriptors.references.ReadWriteAccessCheckerDescriptorsImpl -import org.jetbrains.kotlin.references.fe10.base.KtFe10KotlinReferenceProviderContributor +import org.jetbrains.kotlin.analysis.api.session.KtAnalysisSessionProvider import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar import org.jetbrains.kotlin.cli.common.CliModuleVisibilityManagerImpl import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.idea.references.KotlinReferenceProviderContributor import org.jetbrains.kotlin.idea.references.ReadWriteAccessChecker -import org.jetbrains.kotlin.light.classes.symbol.caches.SymbolLightClassFacadeCache import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager +import org.jetbrains.kotlin.references.fe10.base.KtFe10KotlinReferenceProviderContributor import org.jetbrains.kotlin.resolve.extensions.AnalysisHandlerExtension import org.jetbrains.kotlin.test.services.TestServices @@ -37,7 +36,6 @@ object AnalysisApiFe10TestServiceRegistrar : AnalysisApiTestServiceRegistrar() { registerService(Fe10AnalysisFacade::class.java, CliFe10AnalysisFacade(project)) registerService(ModuleVisibilityManager::class.java, CliModuleVisibilityManagerImpl(enabled = true)) - registerService(SymbolLightClassFacadeCache::class.java) registerService(ReadWriteAccessChecker::class.java, ReadWriteAccessCheckerDescriptorsImpl()) } AnalysisHandlerExtension.registerExtension(project, KtFe10AnalysisHandlerExtension()) diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/psiTypeProvider/AbstractAnalysisApiPsiTypeProviderTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/psiTypeProvider/AbstractAnalysisApiPsiTypeProviderTest.kt index ce86b0e21db..92f401910ab 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/psiTypeProvider/AbstractAnalysisApiPsiTypeProviderTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/psiTypeProvider/AbstractAnalysisApiPsiTypeProviderTest.kt @@ -10,14 +10,12 @@ import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import com.intellij.psi.PsiElementVisitor import org.jetbrains.kotlin.analysis.api.analyze -import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiSingleFileTest +import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider import org.jetbrains.kotlin.analysis.test.framework.utils.executeOnPooledThreadInReadAction import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport import org.jetbrains.kotlin.asJava.classes.KtLightClass import org.jetbrains.kotlin.asJava.elements.KtLightElement -import org.jetbrains.kotlin.light.classes.symbol.caches.SymbolLightClassFacadeCache -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtFile @@ -60,18 +58,14 @@ abstract class AbstractAnalysisApiPsiTypeProviderTest : AbstractAnalysisApiSingl private fun getFacadeLightClass( ktFile: KtFile, project: Project, - ): KtLightClass? { - val mainKtFileFqName = ktFile.packageFqName.child(Name.identifier(ktFile.name)) - return project.getService(SymbolLightClassFacadeCache::class.java) - .getOrCreateSymbolLightFacade(listOf(ktFile), mainKtFileFqName) - } + ): KtLightClass? = project.getService(KotlinAsJavaSupport::class.java).getLightFacade(ktFile) private fun createLightClassByContainingClass( declaration: KtDeclaration, project: Project ): KtLightClass? { val containingClass = declaration.parents.firstIsInstanceOrNull() ?: return null - return project.getService(KotlinAsJavaSupport::class.java).getLightClass(containingClass) + return KotlinAsJavaSupport.getInstance(project).getLightClass(containingClass) } private fun KtLightClass.findLightDeclarationContext(ktDeclaration: KtDeclaration): KtLightElement<*, *>? { diff --git a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/KotlinDeclarationProvider.kt b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/KotlinDeclarationProvider.kt index 8695d1db40a..f08b33f5d01 100644 --- a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/KotlinDeclarationProvider.kt +++ b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/KotlinDeclarationProvider.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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. */ @@ -31,7 +31,7 @@ public abstract class KotlinDeclarationProvider { public abstract fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set - public abstract fun getFacadeFilesInPackage(packageFqName: FqName): Collection + public abstract fun findFilesForFacadeByPackage(packageFqName: FqName): Collection public abstract fun findFilesForFacade(facadeFqName: FqName): Collection } diff --git a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationProvider.kt b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationProvider.kt index 7ab0013918a..d676fc47d8d 100644 --- a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationProvider.kt +++ b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationProvider.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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. */ @@ -67,7 +67,7 @@ public class KotlinStaticDeclarationProvider internal constructor( } - override fun getFacadeFilesInPackage(packageFqName: FqName): Collection = + override fun findFilesForFacadeByPackage(packageFqName: FqName): Collection = index.facadeFileMap[packageFqName] ?.filter { ktFile -> ktFile.virtualFile in scope @@ -76,7 +76,7 @@ public class KotlinStaticDeclarationProvider internal constructor( override fun findFilesForFacade(facadeFqName: FqName): Collection { if (facadeFqName.shortNameOrSpecial().isSpecial) return emptyList() - return getFacadeFilesInPackage(facadeFqName.parent()) //TODO Not work correctly for classes with JvmPackageName + return findFilesForFacadeByPackage(facadeFqName.parent()) //TODO Not work correctly for classes with JvmPackageName .filter { it.javaFileFacadeFqName == facadeFqName } } diff --git a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/StandaloneAnalysisAPISessionBuilder.kt b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/StandaloneAnalysisAPISessionBuilder.kt index 1ec67261fbd..81754544e19 100644 --- a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/StandaloneAnalysisAPISessionBuilder.kt +++ b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/StandaloneAnalysisAPISessionBuilder.kt @@ -47,7 +47,6 @@ import org.jetbrains.kotlin.idea.references.KotlinFirReferenceContributor import org.jetbrains.kotlin.idea.references.KotlinReferenceProviderContributor import org.jetbrains.kotlin.idea.references.ReadWriteAccessChecker import org.jetbrains.kotlin.light.classes.symbol.SymbolKotlinAsJavaSupport -import org.jetbrains.kotlin.light.classes.symbol.caches.SymbolLightClassFacadeCache import org.jetbrains.kotlin.load.kotlin.PackagePartProvider import org.jetbrains.kotlin.psi.KotlinReferenceProvidersService import org.jetbrains.kotlin.psi.KtFile @@ -150,7 +149,6 @@ public class StandaloneAnalysisAPISessionBuilder( } ) - registerService(SymbolLightClassFacadeCache::class.java, SymbolLightClassFacadeCache(this)) registerService(ClsJavaStubByVirtualFileCache::class.java, ClsJavaStubByVirtualFileCache()) registerService(KotlinAsJavaSupport::class.java, SymbolKotlinAsJavaSupport(this)) registerService(ReadWriteAccessChecker::class.java, ReadWriteAccessCheckerFirImpl()) diff --git a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/StandaloneUtils.kt b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/StandaloneUtils.kt index 636a48abe00..4d07d4f0959 100644 --- a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/StandaloneUtils.kt +++ b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/StandaloneUtils.kt @@ -33,7 +33,6 @@ import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProviderImpl import org.jetbrains.kotlin.idea.references.KotlinFirReferenceContributor import org.jetbrains.kotlin.idea.references.KotlinReferenceProviderContributor import org.jetbrains.kotlin.light.classes.symbol.SymbolKotlinAsJavaSupport -import org.jetbrains.kotlin.light.classes.symbol.caches.SymbolLightClassFacadeCache import org.jetbrains.kotlin.load.kotlin.PackagePartProvider import org.jetbrains.kotlin.psi.KotlinReferenceProvidersService import org.jetbrains.kotlin.psi.KtFile @@ -70,7 +69,6 @@ public fun configureApplicationEnvironment(app: MockApplication) { * In particular, this will register: * * [KtAnalysisSessionProvider] * * [SymbolKotlinAsJavaSupport] - * * [SymbolLightClassFacadeCache] for FIR light class support * * [ClsJavaStubByVirtualFileCache] * * [KotlinModificationTrackerFactory] * * [KotlinAnnotationsResolverFactory] @@ -114,10 +112,6 @@ internal fun configureProjectEnvironment( ) // FIR LC - project.registerService( - SymbolLightClassFacadeCache::class.java, - SymbolLightClassFacadeCache(project) - ) project.registerService( ClsJavaStubByVirtualFileCache::class.java, ClsJavaStubByVirtualFileCache() diff --git a/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/KotlinAsJavaSupport.kt b/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/KotlinAsJavaSupport.kt index f69d1332a41..79ccd2eb34e 100644 --- a/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/KotlinAsJavaSupport.kt +++ b/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/KotlinAsJavaSupport.kt @@ -11,6 +11,7 @@ import com.intellij.psi.PsiClass import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.asJava.classes.KtFakeLightClass import org.jetbrains.kotlin.asJava.classes.KtLightClass +import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtFile @@ -21,12 +22,13 @@ abstract class KotlinAsJavaSupport { abstract fun getLightClassForScript(script: KtScript): KtLightClass? - abstract fun getFacadeClasses(facadeFqName: FqName, scope: GlobalSearchScope): Collection - abstract fun getFakeLightClass(classOrObject: KtClassOrObject): KtFakeLightClass - abstract fun createFacadeForSyntheticFile(facadeClassFqName: FqName, file: KtFile): PsiClass + abstract fun getLightFacade(file: KtFile): KtLightClassForFacade? + abstract fun createFacadeForSyntheticFile(file: KtFile): KtLightClassForFacade + + abstract fun getFacadeClasses(facadeFqName: FqName, scope: GlobalSearchScope): Collection // Returns only immediately declared classes/objects, package classes are not included (they have no declarations) abstract fun findClassOrObjectDeclarationsInPackage(packageFqName: FqName, searchScope: GlobalSearchScope): Collection @@ -38,7 +40,11 @@ abstract class KotlinAsJavaSupport { * * If the resulting collection is empty, it means that this package has not other declarations than sub-packages */ - abstract fun findFilesForPackage(fqName: FqName, searchScope: GlobalSearchScope): Collection + abstract fun findFilesForPackage(packageFqName: FqName, searchScope: GlobalSearchScope): Collection + + abstract fun findFilesForFacade(facadeFqName: FqName, searchScope: GlobalSearchScope): Collection + + abstract fun findFilesForFacadeByPackage(packageFqName: FqName, searchScope: GlobalSearchScope): Collection abstract fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection @@ -50,12 +56,10 @@ abstract class KotlinAsJavaSupport { abstract fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection - abstract fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection + abstract fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection abstract fun getFacadeNames(packageFqName: FqName, scope: GlobalSearchScope): Collection - abstract fun findFilesForFacade(facadeFqName: FqName, scope: GlobalSearchScope): Collection - companion object { @JvmStatic fun getInstance(project: Project): KotlinAsJavaSupport { diff --git a/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/KotlinAsJavaSupportBase.kt b/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/KotlinAsJavaSupportBase.kt new file mode 100644 index 00000000000..1cb8190d040 --- /dev/null +++ b/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/KotlinAsJavaSupportBase.kt @@ -0,0 +1,84 @@ +/* + * 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 + +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.ModificationTracker +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.classes.KtLightClassForFacade +import org.jetbrains.kotlin.fileClasses.isJvmMultifileClassFile +import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.KtFile + +abstract class KotlinAsJavaSupportBase(protected val project: Project) : KotlinAsJavaSupport() { + fun createLightFacade(file: KtFile): KtLightClassForFacade? { + if (file.isScript()) return null + + val module = file.findModule().takeIf { facadeIsApplicable(it, file) } ?: return null + val facadeFqName = file.javaFileFacadeFqName + val facadeFiles = if (file.isJvmMultifileClassFile) { + findFilesForFacade(facadeFqName, module.contentSearchScope).filter(KtFile::isJvmMultifileClassFile) + } else { + listOf(file) + } + + if (facadeFiles.none(KtFile::hasTopLevelCallables)) return null + return when { + facadeFiles.none(KtFile::isCompiled) -> createInstanceOfLightFacade(facadeFqName, facadeFiles, module) + facadeFiles.all(KtFile::isCompiled) -> createInstanceOfDecompiledLightFacade(facadeFqName, facadeFiles, module) + else -> error("Source and compiled files are mixed: $facadeFiles") + } + } + + abstract fun KtFile.findModule(): TModule + abstract fun facadeIsApplicable(module: TModule, file: KtFile): Boolean + abstract val TModule.contentSearchScope: GlobalSearchScope + + abstract fun createInstanceOfLightFacade(facadeFqName: FqName, files: List, module: TModule): KtLightClassForFacade + abstract fun createInstanceOfDecompiledLightFacade(facadeFqName: FqName, files: List, module: TModule): KtLightClassForFacade? + + override fun createFacadeForSyntheticFile(file: KtFile): KtLightClassForFacade { + return createInstanceOfLightFacade(file.javaFileFacadeFqName, listOf(file), file.findModule()) + } + + override fun getLightFacade(file: KtFile): KtLightClassForFacade? = CachedValuesManager.getCachedValue(file) { + CachedValueProvider.Result.create( + createLightFacade(file), + tracker(file), + ) + } + + open fun tracker(file: KtFile): ModificationTracker { + return KotlinModificationTrackerService.getInstance(project).outOfBlockModificationTracker + } + + override fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection { + return findFilesForFacadeByPackage(packageFqName, scope).toFacadeClasses() + } + + override fun getFacadeClasses(facadeFqName: FqName, scope: GlobalSearchScope): Collection { + return findFilesForFacade(facadeFqName, scope).toFacadeClasses() + } + + override fun getFacadeNames(packageFqName: FqName, scope: GlobalSearchScope): Collection { + return findFilesForFacadeByPackage(packageFqName, scope).mapNotNullTo(mutableSetOf()) { file -> + file.takeIf { facadeIsApplicable(it.findModule(), file) }?.javaFileFacadeFqName?.shortName()?.asString() + }.toSet() + } + + private fun Collection.toFacadeClasses(): List = groupBy { + FacadeKey(it.javaFileFacadeFqName, it.isJvmMultifileClassFile, it.findModule()) + }.mapNotNull { (key, files) -> + files.firstOrNull { facadeIsApplicable(key.module, it) }?.let(::getLightFacade) + } + + private data class FacadeKey(val fqName: FqName, val isMultifile: Boolean, val module: TModule) +} + diff --git a/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/KotlinLightClassFactory.kt b/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/KotlinLightClassFactory.kt index 132412c891b..b7cfae48deb 100644 --- a/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/KotlinLightClassFactory.kt +++ b/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/KotlinLightClassFactory.kt @@ -8,17 +8,11 @@ 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 { @@ -29,14 +23,6 @@ interface KotlinLightClassFactory { 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) } diff --git a/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForFacadeBase.kt b/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForFacadeBase.kt index 175e4727f71..d960253d5cc 100644 --- a/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForFacadeBase.kt +++ b/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForFacadeBase.kt @@ -15,12 +15,12 @@ import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass import org.jetbrains.kotlin.asJava.elements.KtLightField import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil +import org.jetbrains.kotlin.fileClasses.isJvmMultifileClassFile import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.JvmNames import org.jetbrains.kotlin.name.JvmNames.JVM_NAME_SHORT import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtFile @@ -36,7 +36,7 @@ abstract class KtLightClassForFacadeBase constructor( private val firstFileInFacade by lazyPub { files.first() } val isMultiFileClass: Boolean by lazyPub { - files.size > 1 || JvmFileClassUtil.findAnnotationEntryOnFileNoResolve(firstFileInFacade, JvmNames.JVM_MULTIFILE_CLASS_SHORT) != null + files.size > 1 || firstFileInFacade.isJvmMultifileClassFile } private val _modifierList: PsiModifierList by lazyPub { diff --git a/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/lightClassUtils.kt b/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/lightClassUtils.kt index 7fd21c55d94..303e59f7ae3 100644 --- a/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/lightClassUtils.kt +++ b/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/lightClassUtils.kt @@ -10,7 +10,6 @@ import com.intellij.psi.* import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.asJava.classes.KtFakeLightClass import org.jetbrains.kotlin.asJava.classes.KtLightClass -import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade import org.jetbrains.kotlin.asJava.elements.* import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap import org.jetbrains.kotlin.lexer.KtTokens @@ -40,9 +39,7 @@ fun KtClassOrObject.toLightClassWithBuiltinMapping(): PsiClass? { fun KtClassOrObject.toFakeLightClass(): KtFakeLightClass = KotlinAsJavaSupport.getInstance(project).getFakeLightClass(this) -fun KtFile.findFacadeClass(): KtLightClass? = KotlinAsJavaSupport.getInstance(project) - .getFacadeClassesInPackage(packageFqName, this.useScope as? GlobalSearchScope ?: GlobalSearchScope.projectScope(project)) - .firstOrNull { it is KtLightClassForFacade && this in it.files } as? KtLightClass +fun KtFile.findFacadeClass(): KtLightClass? = KotlinAsJavaSupport.getInstance(project).getLightFacade(this) fun KtScript.toLightClass(): KtLightClass? = KotlinAsJavaSupport.getInstance(project).getLightClassForScript(this) diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/AnalysisApiFirTestServiceRegistrar.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/AnalysisApiFirTestServiceRegistrar.kt index ba466423b0f..67e112c1de6 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/AnalysisApiFirTestServiceRegistrar.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/AnalysisApiFirTestServiceRegistrar.kt @@ -31,7 +31,6 @@ import org.jetbrains.kotlin.idea.references.KotlinFirReferenceContributor import org.jetbrains.kotlin.idea.references.KotlinReferenceProviderContributor import org.jetbrains.kotlin.idea.references.ReadWriteAccessChecker import org.jetbrains.kotlin.light.classes.symbol.SymbolKotlinAsJavaSupport -import org.jetbrains.kotlin.light.classes.symbol.caches.SymbolLightClassFacadeCache import org.jetbrains.kotlin.test.TestInfrastructureInternals import org.jetbrains.kotlin.test.impl.testConfiguration import org.jetbrains.kotlin.test.services.TestServices @@ -52,7 +51,6 @@ object AnalysisApiFirTestServiceRegistrar : AnalysisApiTestServiceRegistrar() { registerService(LLFirBuiltinsSessionFactory::class.java) registerService(PackagePartProviderFactory::class.java, PackagePartProviderTestImpl(testServices)) - registerService(SymbolLightClassFacadeCache::class.java) registerService(KotlinAsJavaSupport::class.java, SymbolKotlinAsJavaSupport(project)) registerService(KtCompilerPluginsProvider::class.java, KtCompilerPluginsProviderForTests(project)) registerService(ReadWriteAccessChecker::class.java, ReadWriteAccessCheckerFirImpl()) diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/SymbolKotlinAsJavaSupport.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/SymbolKotlinAsJavaSupport.kt index 7ff8fc205f4..6fb6605710c 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/SymbolKotlinAsJavaSupport.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/SymbolKotlinAsJavaSupport.kt @@ -6,20 +6,24 @@ package org.jetbrains.kotlin.light.classes.symbol import com.intellij.openapi.project.Project +import com.intellij.openapi.util.ModificationTracker import com.intellij.psi.PsiClass import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.analysis.decompiled.light.classes.DecompiledLightClassesFactory import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule +import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule import org.jetbrains.kotlin.analysis.project.structure.getKtModule +import org.jetbrains.kotlin.analysis.providers.createAllLibrariesModificationTracker import org.jetbrains.kotlin.analysis.providers.createDeclarationProvider +import org.jetbrains.kotlin.analysis.providers.createModuleWithoutDependenciesOutOfBlockModificationTracker import org.jetbrains.kotlin.analysis.providers.createPackageProvider -import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport +import org.jetbrains.kotlin.asJava.KotlinAsJavaSupportBase import org.jetbrains.kotlin.asJava.classes.KtFakeLightClass import org.jetbrains.kotlin.asJava.classes.KtLightClass -import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName -import org.jetbrains.kotlin.light.classes.symbol.caches.SymbolLightClassFacadeCache +import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolBasedFakeLightClass +import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForFacade import org.jetbrains.kotlin.light.classes.symbol.classes.analyzeForLightClasses import org.jetbrains.kotlin.light.classes.symbol.classes.getOrCreateSymbolLightClass import org.jetbrains.kotlin.name.ClassId @@ -30,7 +34,7 @@ import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtScript -class SymbolKotlinAsJavaSupport(private val project: Project) : KotlinAsJavaSupport() { +class SymbolKotlinAsJavaSupport(project: Project) : KotlinAsJavaSupportBase(project) { override fun findClassOrObjectDeclarationsInPackage( packageFqName: FqName, searchScope: GlobalSearchScope @@ -40,13 +44,18 @@ class SymbolKotlinAsJavaSupport(private val project: Project) : KotlinAsJavaSupp } } - override fun findFilesForPackage(fqName: FqName, searchScope: GlobalSearchScope): Collection = - buildSet { - addAll(project.createDeclarationProvider(searchScope).getFacadeFilesInPackage(fqName)) - findClassOrObjectDeclarationsInPackage(fqName, searchScope).mapTo(this) { - it.containingKtFile - } + override fun findFilesForPackage(packageFqName: FqName, searchScope: GlobalSearchScope): Collection = buildSet { + addAll(project.createDeclarationProvider(searchScope).findFilesForFacadeByPackage(packageFqName)) + findClassOrObjectDeclarationsInPackage(packageFqName, searchScope).mapTo(this) { + it.containingKtFile } + } + + override fun findFilesForFacadeByPackage(packageFqName: FqName, searchScope: GlobalSearchScope): Collection { + return project.createDeclarationProvider(searchScope) + .findFilesForFacadeByPackage(packageFqName) + .filter { it.isFromSourceOrLibraryBinary(project) } + } private fun FqName.toClassIdSequence(): Sequence { var currentName = shortNameOrSpecial() @@ -88,64 +97,50 @@ class SymbolKotlinAsJavaSupport(private val project: Project) : KotlinAsJavaSupp } } - override fun getLightClassForScript(script: KtScript): KtLightClass = - error("Should not be called") + override fun getLightClassForScript(script: KtScript): KtLightClass = error("Should not be called") - override fun getFacadeClasses(facadeFqName: FqName, scope: GlobalSearchScope): Collection { - val filesForFacade = findFilesForFacade(facadeFqName, scope) + override fun KtFile.findModule(): KtModule = getKtModule(project) - return getFacadeClassesForFiles(facadeFqName, filesForFacade) + override fun createInstanceOfDecompiledLightFacade( + facadeFqName: FqName, + files: List, + module: KtModule, + ): KtLightClassForFacade? = DecompiledLightClassesFactory.createLightFacadeForDecompiledKotlinFile(project, facadeFqName, files) + + override fun tracker(file: KtFile): ModificationTracker = when (val module = file.getKtModule(project)) { + is KtSourceModule -> module.createModuleWithoutDependenciesOutOfBlockModificationTracker(project) + is KtLibraryModule -> project.createAllLibrariesModificationTracker() + else -> super.tracker(file) } - override fun getScriptClasses(scriptFqName: FqName, scope: GlobalSearchScope): Collection = - error("Should not be called") + override fun createInstanceOfLightFacade( + facadeFqName: FqName, + files: List, + module: KtModule, + ): KtLightClassForFacade = analyzeForLightClasses(files.first()) { + SymbolLightClassForFacade(facadeFqName, files) + } + + override val KtModule.contentSearchScope: GlobalSearchScope get() = this.contentScope + + override fun facadeIsApplicable(module: KtModule, file: KtFile): Boolean = module.isFromSourceOrLibraryBinary() + + override fun getScriptClasses(scriptFqName: FqName, scope: GlobalSearchScope): Collection = error("Should not be called") override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection = emptyList() //TODO Implement if necessary for symbol - override fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection = - project.createDeclarationProvider(scope) - .getFacadeFilesInPackage(packageFqName) - .asSequence() - .filter { it.isFromSourceOrLibraryBinary(project) } - .groupBy { it.javaFileFacadeFqName } - .flatMap { (fqName, files) -> getFacadeClassesForFiles(fqName, files) } - - override fun getFacadeNames(packageFqName: FqName, scope: GlobalSearchScope): Collection = - project.createDeclarationProvider(scope) - .getFacadeFilesInPackage(packageFqName) - .filter { it.isFromSourceOrLibraryBinary(project) } - .mapTo(mutableSetOf()) { it.javaFileFacadeFqName.shortName().asString() } - - override fun findFilesForFacade(facadeFqName: FqName, scope: GlobalSearchScope): Collection { - return project.createDeclarationProvider(scope) + override fun findFilesForFacade(facadeFqName: FqName, searchScope: GlobalSearchScope): Collection { + return project.createDeclarationProvider(searchScope) .findFilesForFacade(facadeFqName) .filter { it.isFromSourceOrLibraryBinary(project) } } - override fun getFakeLightClass(classOrObject: KtClassOrObject): KtFakeLightClass = - SymbolBasedFakeLightClass(classOrObject) + override fun getFakeLightClass(classOrObject: KtClassOrObject): KtFakeLightClass = SymbolBasedFakeLightClass(classOrObject) - override fun createFacadeForSyntheticFile(facadeClassFqName: FqName, file: KtFile): PsiClass = - TODO("Not implemented") + private fun KtElement.isFromSourceOrLibraryBinary(project: Project): Boolean = getKtModule(project).isFromSourceOrLibraryBinary() - private fun getFacadeClassesForFiles(facadeFqName: FqName, allFiles: Collection): Collection { - if (allFiles.isEmpty()) return emptyList() - val filesByModule = allFiles.groupBy { it.getKtModule(project) } - - val lightClassFacadeCache = project.getService(SymbolLightClassFacadeCache::class.java) - - return filesByModule.mapNotNull { (module, files) -> - analyzeForLightClasses(module) { - lightClassFacadeCache.getOrCreateSymbolLightFacade(files, facadeFqName) - } - } - } -} - - -private fun KtElement.isFromSourceOrLibraryBinary(project: Project): Boolean { - return when (getKtModule(project)) { + private fun KtModule.isFromSourceOrLibraryBinary() = when (this) { is KtSourceModule -> true is KtLibraryModule -> true else -> false diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/caches/SymbolLightClassFacadeCache.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/caches/SymbolLightClassFacadeCache.kt deleted file mode 100644 index 4765b3ee598..00000000000 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/caches/SymbolLightClassFacadeCache.kt +++ /dev/null @@ -1,62 +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. - */ - -package org.jetbrains.kotlin.light.classes.symbol.caches - -import com.intellij.openapi.project.Project -import org.jetbrains.kotlin.analysis.decompiled.light.classes.DecompiledLightClassesFactory -import org.jetbrains.kotlin.analysis.providers.createProjectWideOutOfBlockModificationTracker -import org.jetbrains.kotlin.analysis.utils.caches.getValue -import org.jetbrains.kotlin.analysis.utils.caches.softCachedValue -import org.jetbrains.kotlin.analysis.utils.collections.ConcurrentMapBasedCache -import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade -import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForFacade -import org.jetbrains.kotlin.light.classes.symbol.classes.analyzeForLightClasses -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.psi.KtFile -import java.util.concurrent.ConcurrentHashMap - -class SymbolLightClassFacadeCache(private val project: Project) { - private val cache by softCachedValue( - project, - project.createProjectWideOutOfBlockModificationTracker() - ) { - ConcurrentMapBasedCache(ConcurrentHashMap()) - } - - fun getOrCreateSymbolLightFacade( - ktFiles: List, - facadeClassFqName: FqName, - ): KtLightClassForFacade? { - val ktFilesWithoutScript = ktFiles.filterNot { it.isScript() } - if (ktFilesWithoutScript.isEmpty()) return null - val key = FacadeKey(facadeClassFqName, ktFilesWithoutScript.toSet()) - return cache.getOrPut(key) { - getOrCreateSymbolLightFacadeNoCache(ktFilesWithoutScript, facadeClassFqName) - } - } - - private fun getOrCreateSymbolLightFacadeNoCache( - ktFiles: List, - facadeClassFqName: FqName, - ): KtLightClassForFacade? { - val firstFile = ktFiles.first() - return when { - ktFiles.none { it.isCompiled } -> - analyzeForLightClasses(firstFile) { - SymbolLightClassForFacade(firstFile.manager, facadeClassFqName, ktFiles) - } - - ktFiles.all { it.isCompiled } -> { - DecompiledLightClassesFactory.createLightFacadeForDecompiledKotlinFile(project, facadeClassFqName, ktFiles) - } - - else -> - error("Source and compiled files are mixed: $ktFiles}") - } - } - - private data class FacadeKey(val fqName: FqName, val files: Set) -} \ No newline at end of file diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForFacade.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForFacade.kt index 8105386368f..d6279f28a64 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForFacade.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForFacade.kt @@ -40,10 +40,9 @@ import org.jetbrains.kotlin.psi.KtFile context(KtAnalysisSession) class SymbolLightClassForFacade( - manager: PsiManager, override val facadeClassFqName: FqName, override val files: Collection -) : SymbolLightClassBase(manager), KtLightClassForFacade { +) : SymbolLightClassBase(files.first().manager), KtLightClassForFacade { init { require(files.isNotEmpty()) @@ -158,17 +157,13 @@ class SymbolLightClassForFacade( override fun getOwnMethods() = _ownMethods - override fun copy(): SymbolLightClassForFacade = - SymbolLightClassForFacade(manager, facadeClassFqName, files) + override fun copy(): SymbolLightClassForFacade = SymbolLightClassForFacade(facadeClassFqName, files) - private val packageFqName: FqName = - facadeClassFqName.parent() + private val packageFqName: FqName = facadeClassFqName.parent() - private val modifierList: PsiModifierList = - LightModifierList(manager, KotlinLanguage.INSTANCE, PsiModifier.PUBLIC, PsiModifier.FINAL) + private val modifierList: PsiModifierList = LightModifierList(manager, KotlinLanguage.INSTANCE, PsiModifier.PUBLIC, PsiModifier.FINAL) - private val implementsList: LightEmptyImplementsList = - LightEmptyImplementsList(manager) + private val implementsList: LightEmptyImplementsList = LightEmptyImplementsList(manager) private val packageClsFile = FakeFileForLightClass( firstFileInFacade, diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliExtraDiagnosticsProvider.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliExtraDiagnosticsProvider.kt index 2d19617a810..cb63117d1df 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliExtraDiagnosticsProvider.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliExtraDiagnosticsProvider.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.asJava.classes.getOutermostClassOrObject import org.jetbrains.kotlin.asJava.classes.shouldNotBeVisibleAsLightClass import org.jetbrains.kotlin.cli.jvm.compiler.builder.extraJvmDiagnosticsFromBackend import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil +import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics @@ -42,7 +43,7 @@ object CliExtraDiagnosticsProvider { private fun calculateForFacade(file: KtFile): Diagnostics { val project = file.project - val facadeFqName = JvmFileClassUtil.getFileClassInfoNoResolve(file).facadeClassFqName + val facadeFqName = file.javaFileFacadeFqName val facadeCollection = KotlinAsJavaSupport.getInstance(project) .findFilesForFacade(facadeFqName, GlobalSearchScope.allScope(project)) .ifEmpty { return Diagnostics.EMPTY } 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 15d545583e1..00189081353 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 @@ -10,10 +10,10 @@ import com.intellij.psi.PsiClass import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.PsiSearchScopeUtil import com.intellij.util.SmartList -import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport +import org.jetbrains.kotlin.asJava.KotlinAsJavaSupportBase +import org.jetbrains.kotlin.asJava.LightClassGenerationSupport import org.jetbrains.kotlin.asJava.classes.* import org.jetbrains.kotlin.descriptors.PackageViewDescriptor -import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName import org.jetbrains.kotlin.load.java.components.FilesByFacadeFqNameIndexer import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtClassOrObject @@ -25,32 +25,33 @@ import org.jetbrains.kotlin.resolve.lazy.ResolveSessionUtils import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope -class CliKotlinAsJavaSupport( - private val project: Project, - private val traceHolder: CliTraceHolder -) : KotlinAsJavaSupport() { - override fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection { - return findFacadeFilesInPackage(packageFqName, scope) - .groupBy { it.javaFileFacadeFqName } - .mapNotNull { (facadeClassFqName, _) -> - KotlinLightClassFactory.createFacade(project, facadeClassFqName, scope) - } - } - - override fun getFacadeNames(packageFqName: FqName, scope: GlobalSearchScope): Collection { - return findFacadeFilesInPackage(packageFqName, scope) - .map { it.javaFileFacadeFqName.shortName().asString() } - } - - private fun findFacadeFilesInPackage( +class CliKotlinAsJavaSupport(project: Project, private val traceHolder: CliTraceHolder) : KotlinAsJavaSupportBase(project) { + override fun findFilesForFacadeByPackage( packageFqName: FqName, - scope: GlobalSearchScope + searchScope: GlobalSearchScope ) = traceHolder.bindingContext.get(FilesByFacadeFqNameIndexer.FACADE_FILES_BY_PACKAGE_NAME, packageFqName) - ?.filter { PsiSearchScopeUtil.isInScope(scope, it) } + ?.filter { PsiSearchScopeUtil.isInScope(searchScope, it) } .orEmpty() - override fun getFacadeClasses(facadeFqName: FqName, scope: GlobalSearchScope): Collection { - return listOfNotNull(KotlinLightClassFactory.createFacade(project, facadeFqName, scope)) + override fun KtFile.findModule(): KtFile = this + + override fun createInstanceOfDecompiledLightFacade(facadeFqName: FqName, files: List, module: KtFile): KtLightClassForFacade? { + error("Should not be called") + } + + override fun createInstanceOfLightFacade(facadeFqName: FqName, files: List, module: KtFile): KtLightClassForFacade { + return LightClassGenerationSupport.getInstance(files.first().project).createUltraLightClassForFacade(facadeFqName, files) + } + + override val KtFile.contentSearchScope: GlobalSearchScope get() = GlobalSearchScope.allScope(project) + override fun facadeIsApplicable(module: KtFile, file: KtFile): Boolean = !module.isCompiled + + override fun findFilesForFacade(facadeFqName: FqName, searchScope: GlobalSearchScope): List { + if (facadeFqName.isRoot) return emptyList() + + return traceHolder.bindingContext.get(FilesByFacadeFqNameIndexer.FACADE_FILES_BY_FQ_NAME, facadeFqName)?.filter { + PsiSearchScopeUtil.isInScope(searchScope, it) + }.orEmpty() } override fun getScriptClasses(scriptFqName: FqName, scope: GlobalSearchScope): Collection { @@ -59,24 +60,13 @@ class CliKotlinAsJavaSupport( } return findFilesForPackage(scriptFqName.parent(), scope).mapNotNull { file -> - file.script?.takeIf { it.fqName == scriptFqName }?.let { it -> getLightClassForScript(it) } + file.script?.takeIf { it.fqName == scriptFqName }?.let { getLightClassForScript(it) } } } - override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection { - return emptyList() - } + override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection = emptyList() - override fun findFilesForFacade(facadeFqName: FqName, scope: GlobalSearchScope): Collection { - if (facadeFqName.isRoot) return emptyList() - - return traceHolder.bindingContext.get(FilesByFacadeFqNameIndexer.FACADE_FILES_BY_FQ_NAME, facadeFqName)?.filter { - PsiSearchScopeUtil.isInScope(scope, it) - }.orEmpty() - } - - override fun getFakeLightClass(classOrObject: KtClassOrObject): KtFakeLightClass = - KtDescriptorBasedFakeLightClass(classOrObject) + override fun getFakeLightClass(classOrObject: KtClassOrObject): KtFakeLightClass = KtDescriptorBasedFakeLightClass(classOrObject) override fun findClassOrObjectDeclarationsInPackage( packageFqName: FqName, searchScope: GlobalSearchScope @@ -90,12 +80,11 @@ class CliKotlinAsJavaSupport( } } } + return result } - override fun packageExists(fqName: FqName, scope: GlobalSearchScope): Boolean { - return !traceHolder.module.getPackage(fqName).isEmpty() - } + override fun packageExists(fqName: FqName, scope: GlobalSearchScope): Boolean = !traceHolder.module.getPackage(fqName).isEmpty() override fun getSubPackages(fqn: FqName, scope: GlobalSearchScope): Collection { val packageView = traceHolder.module.getPackage(fqn) @@ -118,11 +107,11 @@ class CliKotlinAsJavaSupport( } } - override fun findFilesForPackage(fqName: FqName, searchScope: GlobalSearchScope): Collection { - return traceHolder.bindingContext.get(BindingContext.PACKAGE_TO_FILES, fqName)?.filter { + override fun findFilesForPackage(packageFqName: FqName, searchScope: GlobalSearchScope): Collection { + return traceHolder.bindingContext.get(BindingContext.PACKAGE_TO_FILES, packageFqName)?.filter { PsiSearchScopeUtil.isInScope(searchScope, it) }.orEmpty() } - override fun createFacadeForSyntheticFile(facadeClassFqName: FqName, file: KtFile): PsiClass = error("Should not be called") + override fun createFacadeForSyntheticFile(file: KtFile): KtLightClassForFacade = error("Should not be called") } 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 3a7bb35212f..14c148430ad 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 @@ -42,7 +42,6 @@ import com.intellij.util.lang.UrlClassLoader 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 @@ -717,7 +716,6 @@ class KotlinCoreEnvironment private constructor( fun registerProjectServices(project: MockProject) { with(project) { registerService(KotlinJavaPsiFacade::class.java, KotlinJavaPsiFacade(this)) - registerService(FacadeCache::class.java, FacadeCache(this)) registerService(ModuleAnnotationsResolver::class.java, CliModuleAnnotationsResolver()) } } @@ -735,7 +733,7 @@ class KotlinCoreEnvironment private constructor( with(project) { val traceHolder = CliTraceHolder() val cliLightClassGenerationSupport = CliLightClassGenerationSupport(traceHolder, project) - val kotlinAsJavaSupport = CliKotlinAsJavaSupport(this, traceHolder) + val kotlinAsJavaSupport = CliKotlinAsJavaSupport(project, traceHolder) registerService(LightClassGenerationSupport::class.java, cliLightClassGenerationSupport) registerService(CliLightClassGenerationSupport::class.java, cliLightClassGenerationSupport) registerService(KotlinAsJavaSupport::class.java, kotlinAsJavaSupport) diff --git a/compiler/frontend.common.jvm/src/org/jetbrains/kotlin/fileClasses/JvmFileClassUtil.kt b/compiler/frontend.common.jvm/src/org/jetbrains/kotlin/fileClasses/JvmFileClassUtil.kt index 94a620d2a61..ecf70296289 100644 --- a/compiler/frontend.common.jvm/src/org/jetbrains/kotlin/fileClasses/JvmFileClassUtil.kt +++ b/compiler/frontend.common.jvm/src/org/jetbrains/kotlin/fileClasses/JvmFileClassUtil.kt @@ -70,7 +70,7 @@ object JvmFileClassUtil { if (jvmName == null && jvmPackageName == null) return null - val isMultifileClass = findAnnotationEntryOnFileNoResolve(file, JVM_MULTIFILE_CLASS_SHORT) != null + val isMultifileClass = file.isJvmMultifileClassFile return ParsedJvmFileClassAnnotations(jvmName, jvmPackageName, isMultifileClass) } @@ -122,10 +122,12 @@ val KtFile.javaFileFacadeFqName: FqName return facadeFqName } +val KtFile.isJvmMultifileClassFile: Boolean + get() = JvmFileClassUtil.findAnnotationEntryOnFileNoResolve(this, JVM_MULTIFILE_CLASS_SHORT) != null + private val LOG = Logger.getInstance("JvmFileClassUtil") -fun KtDeclaration.isInsideJvmMultifileClassFile() = - JvmFileClassUtil.findAnnotationEntryOnFileNoResolve(containingKtFile, JVM_MULTIFILE_CLASS_SHORT) != null +fun KtDeclaration.isInsideJvmMultifileClassFile() = containingKtFile.isJvmMultifileClassFile val FqName.internalNameWithoutInnerClasses: String get() = JvmClassName.byFqNameWithoutInnerClasses(this).internalName 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 2427575ed52..f442d0039f8 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/LightClassGenerationSupport.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/LightClassGenerationSupport.kt @@ -33,11 +33,7 @@ abstract class LightClassGenerationSupport { ConstantExpressionEvaluator(moduleDescriptor, languageVersionSettings, expression.project) } - internal fun canCreateUltraLightClassForFacade(files: Collection): Boolean = files.none { it.isScript() } - - fun createUltraLightClassForFacade(facadeClassFqName: FqName, files: Collection): KtUltraLightClassForFacade? { - if (!canCreateUltraLightClassForFacade(files)) return null - + fun createUltraLightClassForFacade(facadeClassFqName: FqName, files: Collection): KtUltraLightClassForFacade { val filesToSupports: List> = files.map { it to getUltraLightClassSupport(it) } 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 deleted file mode 100644 index c567409015c..00000000000 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/FacadeCache.kt +++ /dev/null @@ -1,56 +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. - */ - -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 com.intellij.psi.util.CachedValue -import com.intellij.psi.util.CachedValueProvider -import com.intellij.psi.util.CachedValuesManager -import com.intellij.util.containers.SLRUCache -import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService -import org.jetbrains.kotlin.name.FqName - -private data class FacadeCacheKey(val fqName: FqName, val searchScope: GlobalSearchScope) - -private data class ValueWrapper(val value: KtLightClassForFacade?) { - companion object { - val Null = ValueWrapper(null) - } -} - -class FacadeCache(private val project: Project) { - private inner class FacadeCacheData { - val cache = object : SLRUCache(20, 30) { - override fun createValue(key: FacadeCacheKey): ValueWrapper = - KotlinK1LightClassFactory.createFacadeNoCache(key.fqName, key.searchScope, project) - ?.let { ValueWrapper(it) } - ?: ValueWrapper.Null - } - } - - private val cachedValue: CachedValue = CachedValuesManager.getManager(project).createCachedValue( - { - CachedValueProvider.Result.create( - FacadeCacheData(), - KotlinModificationTrackerService.getInstance(project).outOfBlockModificationTracker - ) - }, false - ) - - operator fun get(qualifiedName: FqName, searchScope: GlobalSearchScope): KtLightClassForFacade? { - synchronized(cachedValue) { - return cachedValue.value.cache.get(FacadeCacheKey(qualifiedName, searchScope)).value - } - } - - companion object { - fun getInstance(project: Project): FacadeCache { - return ServiceManager.getService(project, FacadeCache::class.java) - } - } -} 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 index 9a8203582cb..76529cfae6e 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KotlinK1LightClassFactory.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KotlinK1LightClassFactory.kt @@ -5,17 +5,12 @@ package org.jetbrains.kotlin.asJava.classes -import com.intellij.openapi.project.Project -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 { @@ -27,18 +22,6 @@ class KotlinK1LightClassFactory : KotlinLightClassFactory { ) } - override fun createFacade( - project: Project, - facadeClassFqName: FqName, - searchScope: GlobalSearchScope, - ): KtLightClassForFacade? = FacadeCache.getInstance(project)[facadeClassFqName, searchScope] - - override fun createFacadeForSyntheticFile(facadeClassFqName: FqName, file: KtFile): KtLightClassForFacade { - return LightClassGenerationSupport.getInstance(file.project).run { - createUltraLightClassForFacade(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), @@ -54,9 +37,7 @@ class KotlinK1LightClassFactory : KotlinLightClassFactory { return null } - return LightClassGenerationSupport.getInstance(script.project).run { - createUltraLightClassForScript(script) - } + return LightClassGenerationSupport.getInstance(script.project).createUltraLightClassForScript(script) } fun createClassNoCache(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? { @@ -70,22 +51,7 @@ class KotlinK1LightClassFactory : KotlinLightClassFactory { 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 - return LightClassGenerationSupport.getInstance(project).run { - if (!canCreateUltraLightClassForFacade(sources)) return null - createUltraLightClassForFacade(fqName, sources) - ?: error("Unable to create UL class for facade: $fqName for ${sources.joinToString { it.virtualFilePath }}") - } + return LightClassGenerationSupport.getInstance(classOrObject.project).createUltraLightClass(classOrObject) } } } \ No newline at end of file