From 5298abf2d68907701d391ac9f9d3f05ecc527b96 Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Fri, 21 Apr 2023 22:50:13 -0700 Subject: [PATCH] AA/LC: introduce an API to find script files --- .../providers/KotlinDeclarationProvider.kt | 3 +++ .../impl/KotlinStaticDeclarationIndex.kt | 1 + .../impl/KotlinStaticDeclarationProvider.kt | 20 +++++++++++++------ .../kotlin/asJava/KotlinAsJavaSupport.kt | 2 ++ .../kotlin/asJava/KotlinAsJavaSupportBase.kt | 4 +--- .../CompositeKotlinDeclarationProvider.kt | 4 ++++ .../EmptyKotlinDeclarationProvider.kt | 1 + .../FileBasedKotlinDeclarationProvider.kt | 3 +++ .../extensions/LLFirResolveExtensionTool.kt | 14 +++++++++---- .../symbol/SymbolKotlinAsJavaSupport.kt | 4 ++++ .../jvm/compiler/CliKotlinAsJavaSupport.kt | 7 +++++++ 11 files changed, 50 insertions(+), 13 deletions(-) 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 33b2f9ec697..1ff572adb5b 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 @@ -33,12 +33,15 @@ public abstract class KotlinDeclarationProvider { public abstract fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set public abstract fun findFilesForFacadeByPackage(packageFqName: FqName): Collection + public abstract fun findFilesForFacade(facadeFqName: FqName): Collection /** * Currently we want only classes from libraries ([org.jetbrains.kotlin.analysis.decompiler.psi.file.KtClsFile]) */ public abstract fun findInternalFilesForFacade(facadeFqName: FqName): Collection + + public abstract fun findFilesForScript(scriptFqName: FqName): Collection } public abstract class KotlinDeclarationProviderFactory { diff --git a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationIndex.kt b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationIndex.kt index c4b4c46550b..768de5a092f 100644 --- a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationIndex.kt +++ b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationIndex.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.psi.* internal class KotlinStaticDeclarationIndex { internal val facadeFileMap: MutableMap> = mutableMapOf() internal val multiFileClassPartMap: MutableMap> = mutableMapOf() + internal val scriptMap: MutableMap> = mutableMapOf() internal val classMap: MutableMap> = mutableMapOf() internal val typeAliasMap: MutableMap> = mutableMapOf() internal val topLevelFunctionMap: MutableMap> = mutableMapOf() 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 0e50d57efac..3a3b97a528e 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 @@ -66,12 +66,9 @@ public class KotlinStaticDeclarationProvider internal constructor( .mapNotNullTo(mutableSetOf()) { it.nameAsName } } - override fun findFilesForFacadeByPackage(packageFqName: FqName): Collection = - index.facadeFileMap[packageFqName] - ?.filter { ktFile -> - ktFile.virtualFile in scope - } - ?: emptyList() + override fun findFilesForFacadeByPackage(packageFqName: FqName): Collection { + return index.facadeFileMap[packageFqName].orEmpty().filter { it.virtualFile in scope } + } override fun findFilesForFacade(facadeFqName: FqName): Collection { if (facadeFqName.shortNameOrSpecial().isSpecial) return emptyList() @@ -83,6 +80,10 @@ public class KotlinStaticDeclarationProvider internal constructor( return index.multiFileClassPartMap[facadeFqName].orEmpty().filter { it.virtualFile in scope } } + override fun findFilesForScript(scriptFqName: FqName): Collection { + return index.scriptMap[scriptFqName].orEmpty().filter { it.containingKtFile.virtualFile in scope } + } + override fun getTopLevelProperties(callableId: CallableId): Collection = index.topLevelPropertyMap[callableId.packageName] ?.filter { ktProperty -> @@ -165,6 +166,7 @@ public class KotlinStaticDeclarationProviderFactory( override fun visitKtFile(file: KtFile) { addToFacadeFileMap(file) + file.script?.let { addToScriptMap(it) } super.visitKtFile(file) } @@ -196,6 +198,12 @@ public class KotlinStaticDeclarationProviderFactory( }.add(file) } + private fun addToScriptMap(script: KtScript) { + index.scriptMap.computeIfAbsent(script.fqName) { + mutableSetOf() + }.add(script) + } + private fun addToClassMap(classOrObject: KtClassOrObject) { classOrObject.getClassId()?.let { classId -> index.classMap.computeIfAbsent(classId.packageFqName) { 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 39600cc9084..72a5be8aa4a 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 @@ -45,6 +45,8 @@ abstract class KotlinAsJavaSupport { abstract fun findFilesForFacadeByPackage(packageFqName: FqName, searchScope: GlobalSearchScope): Collection + abstract fun findFilesForScript(scriptFqName: FqName, searchScope: GlobalSearchScope): Collection + abstract fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection abstract fun packageExists(fqName: FqName, scope: GlobalSearchScope): Boolean 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 d6448660b24..88f004b63d8 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 @@ -207,9 +207,7 @@ abstract class KotlinAsJavaSupportBase(protected val project: Project) return emptyList() } - return findFilesForPackage(scriptFqName.parent(), scope).mapNotNull { file -> - file.script?.takeIf { it.fqName == scriptFqName }?.let { getLightClassForScript(it) } - } + return findFilesForScript(scriptFqName, scope).mapNotNull { getLightClassForScript(it) } } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/CompositeKotlinDeclarationProvider.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/CompositeKotlinDeclarationProvider.kt index aa17fcd390a..191b4d88b2b 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/CompositeKotlinDeclarationProvider.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/CompositeKotlinDeclarationProvider.kt @@ -61,6 +61,10 @@ private constructor( return providers.flatMapTo(mutableListOf()) { it.findInternalFilesForFacade(facadeFqName) } } + override fun findFilesForScript(scriptFqName: FqName): Collection { + return providers.flatMapTo(mutableListOf()) { it.findFilesForScript(scriptFqName) } + } + companion object { fun create(providers: List): KotlinDeclarationProvider { return when (providers.size) { diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/EmptyKotlinDeclarationProvider.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/EmptyKotlinDeclarationProvider.kt index 18a2c46de10..3cc5eb67d57 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/EmptyKotlinDeclarationProvider.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/EmptyKotlinDeclarationProvider.kt @@ -24,4 +24,5 @@ internal object EmptyKotlinDeclarationProvider : KotlinDeclarationProvider() { override fun findFilesForFacadeByPackage(packageFqName: FqName) = emptyList() override fun findFilesForFacade(facadeFqName: FqName) = emptyList() override fun findInternalFilesForFacade(facadeFqName: FqName) = emptyList() + override fun findFilesForScript(scriptFqName: FqName) = emptyList() } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/FileBasedKotlinDeclarationProvider.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/FileBasedKotlinDeclarationProvider.kt index 240dc1bdfd8..15f53209e09 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/FileBasedKotlinDeclarationProvider.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/FileBasedKotlinDeclarationProvider.kt @@ -130,6 +130,9 @@ internal class FileBasedKotlinDeclarationProvider(val kotlinFile: KtFile) : Kotl override fun findInternalFilesForFacade(facadeFqName: FqName): Collection = emptyList() + override fun findFilesForScript(scriptFqName: FqName): Collection = + listOfNotNull(kotlinFile.script?.takeIf { it.fqName == scriptFqName }) + private inline fun getTopLevelCallables(callableId: CallableId): Collection { require(callableId.classId == null) return getTopLevelDeclarations(callableId.packageName, callableId.callableName) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolve/extensions/LLFirResolveExtensionTool.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolve/extensions/LLFirResolveExtensionTool.kt index c2c0c372022..a98bd4caef4 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolve/extensions/LLFirResolveExtensionTool.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolve/extensions/LLFirResolveExtensionTool.kt @@ -24,10 +24,7 @@ import org.jetbrains.kotlin.analysis.providers.KotlinPackageProvider import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSessionComponent import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils -import org.jetbrains.kotlin.name.CallableId -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.name.* import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.psi.* import java.util.concurrent.ConcurrentHashMap @@ -181,6 +178,15 @@ private class LLFirResolveExtensionToolDeclarationProvider( return emptyList() } + override fun findFilesForScript(scriptFqName: FqName): Collection = forbidAnalysis { + if (scriptFqName.isRoot) return emptyList() + val packageFqName = scriptFqName.parent() + return getDeclarationProvidersByPackage(packageFqName) { file -> + scriptFqName.shortName() == NameUtils.getScriptNameForFile(file.getFileName()) + } + .mapNotNullTo(mutableListOf()) { it.kotlinFile.script } + } + private inline fun getDeclarationProvidersByPackage( packageFqName: FqName, crossinline filter: (KtResolveExtensionFile) -> Boolean 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 d524e2aae3a..9abf3fb77e4 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 @@ -55,6 +55,10 @@ class SymbolKotlinAsJavaSupport(project: Project) : KotlinAsJavaSupportBase { + return project.createDeclarationProvider(searchScope).findFilesForScript(scriptFqName) + } + private fun FqName.toClassIdSequence(): Sequence { var currentName = shortNameOrSpecial() if (currentName.isSpecial) return emptySequence() diff --git a/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/jvm/compiler/CliKotlinAsJavaSupport.kt b/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/jvm/compiler/CliKotlinAsJavaSupport.kt index ec6400a4770..8c883dcc86f 100644 --- a/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/jvm/compiler/CliKotlinAsJavaSupport.kt +++ b/compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/jvm/compiler/CliKotlinAsJavaSupport.kt @@ -112,6 +112,13 @@ class CliKotlinAsJavaSupport(project: Project, private val traceHolder: CliTrace }.orEmpty() } + override fun findFilesForScript(scriptFqName: FqName, searchScope: GlobalSearchScope): Collection { + return findFilesForPackage(scriptFqName.parent(), searchScope) + .mapNotNull { file -> + file.script?.takeIf { it.fqName == scriptFqName } + } + } + override fun createFacadeForSyntheticFile(file: KtFile): KtLightClassForFacade = error("Should not be called") override fun declarationLocation(file: KtFile): DeclarationLocation = DeclarationLocation.ProjectSources override fun createInstanceOfDecompiledLightClass(classOrObject: KtClassOrObject): KtLightClass = error("Should not be called")