AA/LC: introduce an API to find script files
This commit is contained in:
committed by
Dmitrii Gridin
parent
f9086daf4d
commit
5298abf2d6
+3
@@ -33,12 +33,15 @@ public abstract class KotlinDeclarationProvider {
|
|||||||
public abstract fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name>
|
public abstract fun getTopLevelCallableNamesInPackage(packageFqName: FqName): Set<Name>
|
||||||
|
|
||||||
public abstract fun findFilesForFacadeByPackage(packageFqName: FqName): Collection<KtFile>
|
public abstract fun findFilesForFacadeByPackage(packageFqName: FqName): Collection<KtFile>
|
||||||
|
|
||||||
public abstract fun findFilesForFacade(facadeFqName: FqName): Collection<KtFile>
|
public abstract fun findFilesForFacade(facadeFqName: FqName): Collection<KtFile>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Currently we want only classes from libraries ([org.jetbrains.kotlin.analysis.decompiler.psi.file.KtClsFile])
|
* Currently we want only classes from libraries ([org.jetbrains.kotlin.analysis.decompiler.psi.file.KtClsFile])
|
||||||
*/
|
*/
|
||||||
public abstract fun findInternalFilesForFacade(facadeFqName: FqName): Collection<KtFile>
|
public abstract fun findInternalFilesForFacade(facadeFqName: FqName): Collection<KtFile>
|
||||||
|
|
||||||
|
public abstract fun findFilesForScript(scriptFqName: FqName): Collection<KtScript>
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class KotlinDeclarationProviderFactory {
|
public abstract class KotlinDeclarationProviderFactory {
|
||||||
|
|||||||
+1
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.psi.*
|
|||||||
internal class KotlinStaticDeclarationIndex {
|
internal class KotlinStaticDeclarationIndex {
|
||||||
internal val facadeFileMap: MutableMap<FqName, MutableSet<KtFile>> = mutableMapOf()
|
internal val facadeFileMap: MutableMap<FqName, MutableSet<KtFile>> = mutableMapOf()
|
||||||
internal val multiFileClassPartMap: MutableMap<FqName, MutableSet<KtFile>> = mutableMapOf()
|
internal val multiFileClassPartMap: MutableMap<FqName, MutableSet<KtFile>> = mutableMapOf()
|
||||||
|
internal val scriptMap: MutableMap<FqName, MutableSet<KtScript>> = mutableMapOf()
|
||||||
internal val classMap: MutableMap<FqName, MutableSet<KtClassOrObject>> = mutableMapOf()
|
internal val classMap: MutableMap<FqName, MutableSet<KtClassOrObject>> = mutableMapOf()
|
||||||
internal val typeAliasMap: MutableMap<FqName, MutableSet<KtTypeAlias>> = mutableMapOf()
|
internal val typeAliasMap: MutableMap<FqName, MutableSet<KtTypeAlias>> = mutableMapOf()
|
||||||
internal val topLevelFunctionMap: MutableMap<FqName, MutableSet<KtNamedFunction>> = mutableMapOf()
|
internal val topLevelFunctionMap: MutableMap<FqName, MutableSet<KtNamedFunction>> = mutableMapOf()
|
||||||
|
|||||||
+14
-6
@@ -66,12 +66,9 @@ public class KotlinStaticDeclarationProvider internal constructor(
|
|||||||
.mapNotNullTo(mutableSetOf()) { it.nameAsName }
|
.mapNotNullTo(mutableSetOf()) { it.nameAsName }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun findFilesForFacadeByPackage(packageFqName: FqName): Collection<KtFile> =
|
override fun findFilesForFacadeByPackage(packageFqName: FqName): Collection<KtFile> {
|
||||||
index.facadeFileMap[packageFqName]
|
return index.facadeFileMap[packageFqName].orEmpty().filter { it.virtualFile in scope }
|
||||||
?.filter { ktFile ->
|
}
|
||||||
ktFile.virtualFile in scope
|
|
||||||
}
|
|
||||||
?: emptyList()
|
|
||||||
|
|
||||||
override fun findFilesForFacade(facadeFqName: FqName): Collection<KtFile> {
|
override fun findFilesForFacade(facadeFqName: FqName): Collection<KtFile> {
|
||||||
if (facadeFqName.shortNameOrSpecial().isSpecial) return emptyList()
|
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 }
|
return index.multiFileClassPartMap[facadeFqName].orEmpty().filter { it.virtualFile in scope }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun findFilesForScript(scriptFqName: FqName): Collection<KtScript> {
|
||||||
|
return index.scriptMap[scriptFqName].orEmpty().filter { it.containingKtFile.virtualFile in scope }
|
||||||
|
}
|
||||||
|
|
||||||
override fun getTopLevelProperties(callableId: CallableId): Collection<KtProperty> =
|
override fun getTopLevelProperties(callableId: CallableId): Collection<KtProperty> =
|
||||||
index.topLevelPropertyMap[callableId.packageName]
|
index.topLevelPropertyMap[callableId.packageName]
|
||||||
?.filter { ktProperty ->
|
?.filter { ktProperty ->
|
||||||
@@ -165,6 +166,7 @@ public class KotlinStaticDeclarationProviderFactory(
|
|||||||
|
|
||||||
override fun visitKtFile(file: KtFile) {
|
override fun visitKtFile(file: KtFile) {
|
||||||
addToFacadeFileMap(file)
|
addToFacadeFileMap(file)
|
||||||
|
file.script?.let { addToScriptMap(it) }
|
||||||
super.visitKtFile(file)
|
super.visitKtFile(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,6 +198,12 @@ public class KotlinStaticDeclarationProviderFactory(
|
|||||||
}.add(file)
|
}.add(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun addToScriptMap(script: KtScript) {
|
||||||
|
index.scriptMap.computeIfAbsent(script.fqName) {
|
||||||
|
mutableSetOf()
|
||||||
|
}.add(script)
|
||||||
|
}
|
||||||
|
|
||||||
private fun addToClassMap(classOrObject: KtClassOrObject) {
|
private fun addToClassMap(classOrObject: KtClassOrObject) {
|
||||||
classOrObject.getClassId()?.let { classId ->
|
classOrObject.getClassId()?.let { classId ->
|
||||||
index.classMap.computeIfAbsent(classId.packageFqName) {
|
index.classMap.computeIfAbsent(classId.packageFqName) {
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ abstract class KotlinAsJavaSupport {
|
|||||||
|
|
||||||
abstract fun findFilesForFacadeByPackage(packageFqName: FqName, searchScope: GlobalSearchScope): Collection<KtFile>
|
abstract fun findFilesForFacadeByPackage(packageFqName: FqName, searchScope: GlobalSearchScope): Collection<KtFile>
|
||||||
|
|
||||||
|
abstract fun findFilesForScript(scriptFqName: FqName, searchScope: GlobalSearchScope): Collection<KtScript>
|
||||||
|
|
||||||
abstract fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject>
|
abstract fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject>
|
||||||
|
|
||||||
abstract fun packageExists(fqName: FqName, scope: GlobalSearchScope): Boolean
|
abstract fun packageExists(fqName: FqName, scope: GlobalSearchScope): Boolean
|
||||||
|
|||||||
+1
-3
@@ -207,9 +207,7 @@ abstract class KotlinAsJavaSupportBase<TModule>(protected val project: Project)
|
|||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
return findFilesForPackage(scriptFqName.parent(), scope).mapNotNull { file ->
|
return findFilesForScript(scriptFqName, scope).mapNotNull { getLightClassForScript(it) }
|
||||||
file.script?.takeIf { it.fqName == scriptFqName }?.let { getLightClassForScript(it) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
@@ -61,6 +61,10 @@ private constructor(
|
|||||||
return providers.flatMapTo(mutableListOf()) { it.findInternalFilesForFacade(facadeFqName) }
|
return providers.flatMapTo(mutableListOf()) { it.findInternalFilesForFacade(facadeFqName) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun findFilesForScript(scriptFqName: FqName): Collection<KtScript> {
|
||||||
|
return providers.flatMapTo(mutableListOf()) { it.findFilesForScript(scriptFqName) }
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun create(providers: List<KotlinDeclarationProvider>): KotlinDeclarationProvider {
|
fun create(providers: List<KotlinDeclarationProvider>): KotlinDeclarationProvider {
|
||||||
return when (providers.size) {
|
return when (providers.size) {
|
||||||
|
|||||||
+1
@@ -24,4 +24,5 @@ internal object EmptyKotlinDeclarationProvider : KotlinDeclarationProvider() {
|
|||||||
override fun findFilesForFacadeByPackage(packageFqName: FqName) = emptyList<KtFile>()
|
override fun findFilesForFacadeByPackage(packageFqName: FqName) = emptyList<KtFile>()
|
||||||
override fun findFilesForFacade(facadeFqName: FqName) = emptyList<KtFile>()
|
override fun findFilesForFacade(facadeFqName: FqName) = emptyList<KtFile>()
|
||||||
override fun findInternalFilesForFacade(facadeFqName: FqName) = emptyList<KtFile>()
|
override fun findInternalFilesForFacade(facadeFqName: FqName) = emptyList<KtFile>()
|
||||||
|
override fun findFilesForScript(scriptFqName: FqName) = emptyList<KtScript>()
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -130,6 +130,9 @@ internal class FileBasedKotlinDeclarationProvider(val kotlinFile: KtFile) : Kotl
|
|||||||
|
|
||||||
override fun findInternalFilesForFacade(facadeFqName: FqName): Collection<KtFile> = emptyList()
|
override fun findInternalFilesForFacade(facadeFqName: FqName): Collection<KtFile> = emptyList()
|
||||||
|
|
||||||
|
override fun findFilesForScript(scriptFqName: FqName): Collection<KtScript> =
|
||||||
|
listOfNotNull(kotlinFile.script?.takeIf { it.fqName == scriptFqName })
|
||||||
|
|
||||||
private inline fun <reified T : KtCallableDeclaration> getTopLevelCallables(callableId: CallableId): Collection<T> {
|
private inline fun <reified T : KtCallableDeclaration> getTopLevelCallables(callableId: CallableId): Collection<T> {
|
||||||
require(callableId.classId == null)
|
require(callableId.classId == null)
|
||||||
return getTopLevelDeclarations(callableId.packageName, callableId.callableName)
|
return getTopLevelDeclarations(callableId.packageName, callableId.callableName)
|
||||||
|
|||||||
+10
-4
@@ -24,10 +24,7 @@ import org.jetbrains.kotlin.analysis.providers.KotlinPackageProvider
|
|||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.FirSessionComponent
|
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
|
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
import org.jetbrains.kotlin.name.*
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
@@ -181,6 +178,15 @@ private class LLFirResolveExtensionToolDeclarationProvider(
|
|||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun findFilesForScript(scriptFqName: FqName): Collection<KtScript> = 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(
|
private inline fun getDeclarationProvidersByPackage(
|
||||||
packageFqName: FqName,
|
packageFqName: FqName,
|
||||||
crossinline filter: (KtResolveExtensionFile) -> Boolean
|
crossinline filter: (KtResolveExtensionFile) -> Boolean
|
||||||
|
|||||||
+4
@@ -55,6 +55,10 @@ class SymbolKotlinAsJavaSupport(project: Project) : KotlinAsJavaSupportBase<KtMo
|
|||||||
return project.createDeclarationProvider(searchScope).findFilesForFacadeByPackage(packageFqName)
|
return project.createDeclarationProvider(searchScope).findFilesForFacadeByPackage(packageFqName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun findFilesForScript(scriptFqName: FqName, searchScope: GlobalSearchScope): Collection<KtScript> {
|
||||||
|
return project.createDeclarationProvider(searchScope).findFilesForScript(scriptFqName)
|
||||||
|
}
|
||||||
|
|
||||||
private fun FqName.toClassIdSequence(): Sequence<ClassId> {
|
private fun FqName.toClassIdSequence(): Sequence<ClassId> {
|
||||||
var currentName = shortNameOrSpecial()
|
var currentName = shortNameOrSpecial()
|
||||||
if (currentName.isSpecial) return emptySequence()
|
if (currentName.isSpecial) return emptySequence()
|
||||||
|
|||||||
+7
@@ -112,6 +112,13 @@ class CliKotlinAsJavaSupport(project: Project, private val traceHolder: CliTrace
|
|||||||
}.orEmpty()
|
}.orEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun findFilesForScript(scriptFqName: FqName, searchScope: GlobalSearchScope): Collection<KtScript> {
|
||||||
|
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 createFacadeForSyntheticFile(file: KtFile): KtLightClassForFacade = error("Should not be called")
|
||||||
override fun declarationLocation(file: KtFile): DeclarationLocation = DeclarationLocation.ProjectSources
|
override fun declarationLocation(file: KtFile): DeclarationLocation = DeclarationLocation.ProjectSources
|
||||||
override fun createInstanceOfDecompiledLightClass(classOrObject: KtClassOrObject): KtLightClass = error("Should not be called")
|
override fun createInstanceOfDecompiledLightClass(classOrObject: KtClassOrObject): KtLightClass = error("Should not be called")
|
||||||
|
|||||||
Reference in New Issue
Block a user