From 7fa7d8ea8d2ee4e166aab6893fa5bd9b5dc56aca Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Fri, 25 Aug 2023 15:13:51 +0200 Subject: [PATCH] [SLC] provide light classes only for platforms with jvm target Light classes are not supposed to work on non-jvm platforms due to its specific ^KT-60318 Fixed --- .../kotlin/asJava/KotlinAsJavaSupportBase.kt | 33 ++++++++------ .../symbol/SymbolKotlinAsJavaSupport.kt | 43 ++++++++++--------- 2 files changed, 44 insertions(+), 32 deletions(-) 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 index 88f004b63d8..14d38b1df03 100644 --- a/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/KotlinAsJavaSupportBase.kt +++ b/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/KotlinAsJavaSupportBase.kt @@ -21,13 +21,15 @@ import org.jetbrains.kotlin.fileClasses.isJvmMultifileClassFile import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment +import org.jetbrains.kotlin.utils.exceptions.withPsiEntry -abstract class KotlinAsJavaSupportBase(protected val project: Project) : KotlinAsJavaSupport() { +abstract class KotlinAsJavaSupportBase(protected val project: Project) : KotlinAsJavaSupport() { @Suppress("MemberVisibilityCanBePrivate") fun createLightFacade(file: KtFile): LightClassCachedValue? { if (!file.facadeIsPossible()) return null - val module = file.findModule().takeIf { facadeIsApplicable(it, file) } ?: return null + val module = file.findModule()?.takeIf { facadeIsApplicable(it, file) } ?: return null val facadeFqName = file.javaFileFacadeFqName val facadeFiles = if (file.canHaveAdditionalFilesInFacade()) { findFilesForFacade(facadeFqName, module.contentSearchScope).filter(KtFile::isJvmMultifileClassFile) @@ -61,11 +63,11 @@ abstract class KotlinAsJavaSupportBase(protected val project: Project) private fun KtFile.canHaveAdditionalFilesInFacade(): Boolean = !isCompiled && isJvmMultifileClassFile - protected abstract fun KtFile.findModule(): TModule + protected abstract fun KtFile.findModule(): TModule? protected abstract fun facadeIsApplicable(module: TModule, file: KtFile): Boolean protected abstract val TModule.contentSearchScope: GlobalSearchScope - protected abstract fun createInstanceOfLightFacade(facadeFqName: FqName, files: List): KtLightClassForFacade + protected abstract fun createInstanceOfLightFacade(facadeFqName: FqName, files: List): KtLightClassForFacade? protected abstract fun createInstanceOfDecompiledLightFacade(facadeFqName: FqName, files: List): KtLightClassForFacade? protected open fun projectWideOutOfBlockModificationTracker(): ModificationTracker { @@ -85,7 +87,12 @@ abstract class KotlinAsJavaSupportBase(protected val project: Project) } override fun createFacadeForSyntheticFile(file: KtFile): KtLightClassForFacade { - return createInstanceOfLightFacade(file.javaFileFacadeFqName, listOf(file)) + return createInstanceOfLightFacade(file.javaFileFacadeFqName, listOf(file)) ?: errorWithAttachment( + "Unsupported ${file::class.simpleName}" + ) { + withEntry("module", file.findModule().toString()) + withPsiEntry("file", file) + } } override fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection { @@ -99,19 +106,21 @@ abstract class KotlinAsJavaSupportBase(protected val project: Project) override fun getFacadeNames(packageFqName: FqName, scope: GlobalSearchScope): Collection { return findFilesForFacadeByPackage(packageFqName, scope).mapNotNullTo(mutableSetOf()) { file -> file.takeIf { it.facadeIsPossible() } - ?.takeIf { facadeIsApplicable(it.findModule(), file) } + ?.takeIf { it.findModule()?.let { module -> facadeIsApplicable(module, file) } == true } ?.javaFileFacadeFqName ?.shortName() ?.asString() }.toSet() } - private fun Collection.toFacadeClasses(): List = filter { - it.facadeIsPossible() - }.groupBy { - FacadeKey(it.javaFileFacadeFqName, it.isJvmMultifileClassFile, it.findModule()) - }.mapNotNull { (key, files) -> - files.firstOrNull { facadeIsApplicable(key.module, it) }?.let(::getLightFacade) + private fun Collection.toFacadeClasses(): List = mapNotNull { file -> + file.takeIf { it.facadeIsPossible() }?.findModule()?.let { file to it } + }.groupBy { (file, module) -> + FacadeKey(file.javaFileFacadeFqName, file.isJvmMultifileClassFile, module) + }.mapNotNull { (_, pairs) -> + pairs.firstNotNullOfOrNull { (file, module) -> + file.takeIf { facadeIsApplicable(module, file) } + }?.let(::getLightFacade) } private data class FacadeKey(val fqName: FqName, val isMultifile: Boolean, val module: TModule) 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 7ed1d438d6b..3685722ae3c 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 @@ -29,6 +29,8 @@ import org.jetbrains.kotlin.light.classes.symbol.classes.createSymbolLightClassN import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.parentOrNull +import org.jetbrains.kotlin.platform.has +import org.jetbrains.kotlin.platform.jvm.JvmPlatform import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile @@ -37,6 +39,11 @@ import org.jetbrains.kotlin.psi.KtScript class SymbolKotlinAsJavaSupport(project: Project) : KotlinAsJavaSupportBase(project) { private val projectStructureProvider by lazy { ProjectStructureProvider.getInstance(project) } + private fun PsiElement.getModuleIfSupportEnabled(): KtModule? = projectStructureProvider.getModule( + element = this, + contextualModule = null, + ).takeIf(KtModule::isLightClassesEnabled) + override fun findClassOrObjectDeclarationsInPackage( packageFqName: FqName, searchScope: GlobalSearchScope @@ -93,22 +100,18 @@ class SymbolKotlinAsJavaSupport(project: Project) : KotlinAsJavaSupportBase DeclarationLocation.ProjectSources - is KtLibraryModule -> DeclarationLocation.LibraryClasses - is KtLibrarySourceModule -> DeclarationLocation.LibrarySources - else -> null - } + override fun declarationLocation(file: KtFile): DeclarationLocation? = when (file.getModuleIfSupportEnabled()) { + is KtSourceModule -> DeclarationLocation.ProjectSources + is KtLibraryModule -> DeclarationLocation.LibraryClasses + is KtLibrarySourceModule -> DeclarationLocation.LibrarySources + else -> null } override fun createInstanceOfDecompiledLightClass(classOrObject: KtClassOrObject): KtLightClass? { @@ -116,7 +119,7 @@ class SymbolKotlinAsJavaSupport(project: Project) : KotlinAsJavaSupportBase): KtLightClassForFacade { - val module = projectStructureProvider.getModule(files.first(), contextualModule = null) + override fun createInstanceOfLightFacade(facadeFqName: FqName, files: List): KtLightClassForFacade? { + val module = files.first().getModuleIfSupportEnabled() ?: return null return SymbolLightClassForFacade(facadeFqName, files, module) } override val KtModule.contentSearchScope: GlobalSearchScope get() = this.contentScope - override fun facadeIsApplicable(module: KtModule, file: KtFile): Boolean = module.isFromSourceOrLibraryBinary() + override fun facadeIsApplicable(module: KtModule, file: KtFile): Boolean = + module.isFromSourceOrLibraryBinary() && module.isLightClassesEnabled() override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection { val facadeKtFiles = project.createDeclarationProvider(scope, null).findInternalFilesForFacade(fqName) @@ -176,10 +180,7 @@ class SymbolKotlinAsJavaSupport(project: Project) : KotlinAsJavaSupportBase true @@ -187,3 +188,5 @@ class SymbolKotlinAsJavaSupport(project: Project) : KotlinAsJavaSupportBase false } } + +private fun KtModule.isLightClassesEnabled(): Boolean = platform.has()