[Analysis API Standalone] use compiler FirSymbolProvider for standalone mode
^KT-61371 fixed
This commit is contained in:
committed by
Space Team
parent
d377d87c77
commit
b25185530f
+74
@@ -9,14 +9,24 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirLibrarySymbolProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirModuleData
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule
|
||||
import org.jetbrains.kotlin.backend.common.CommonKLibResolver
|
||||
import org.jetbrains.kotlin.fir.BinaryModuleData
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.deserialization.SingleModuleDataProvider
|
||||
import org.jetbrains.kotlin.fir.java.FirJavaFacade
|
||||
import org.jetbrains.kotlin.fir.java.deserialization.JvmClassFileBasedSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
||||
import org.jetbrains.kotlin.fir.session.KlibBasedSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.session.MetadataSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.session.NativeForwardDeclarationsSymbolProvider
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.library.metadata.impl.KlibResolvedModuleDescriptorsFactoryImpl.Companion.FORWARD_DECLARATIONS_MODULE_NAME
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageAndMetadataPartProvider
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
|
||||
import org.jetbrains.kotlin.util.DummyLogger
|
||||
|
||||
class LLFirStandaloneLibrarySymbolProviderFactory(private val project: Project) : LLFirLibrarySymbolProviderFactory() {
|
||||
override fun createJvmLibrarySymbolProvider(
|
||||
@@ -39,4 +49,68 @@ class LLFirStandaloneLibrarySymbolProviderFactory(private val project: Project)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun createCommonLibrarySymbolProvider(
|
||||
session: FirSession,
|
||||
moduleData: LLFirModuleData,
|
||||
kotlinScopeProvider: FirKotlinScopeProvider,
|
||||
moduleDataProvider: SingleModuleDataProvider,
|
||||
packagePartProvider: PackagePartProvider,
|
||||
scope: GlobalSearchScope,
|
||||
): List<FirSymbolProvider> {
|
||||
return listOf(
|
||||
MetadataSymbolProvider(
|
||||
session,
|
||||
moduleDataProvider,
|
||||
kotlinScopeProvider,
|
||||
packagePartProvider as PackageAndMetadataPartProvider,
|
||||
VirtualFileFinderFactory.getInstance(project).create(scope),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun createNativeLibrarySymbolProvider(
|
||||
session: FirSession,
|
||||
moduleData: LLFirModuleData,
|
||||
kotlinScopeProvider: FirKotlinScopeProvider,
|
||||
moduleDataProvider: SingleModuleDataProvider,
|
||||
scope: GlobalSearchScope,
|
||||
): List<FirSymbolProvider> {
|
||||
val forwardDeclarationsModuleData = BinaryModuleData.createDependencyModuleData(
|
||||
FORWARD_DECLARATIONS_MODULE_NAME,
|
||||
moduleDataProvider.platform,
|
||||
moduleDataProvider.analyzerServices,
|
||||
).apply {
|
||||
bindSession(session)
|
||||
}
|
||||
val kLibs = moduleData.getLibraryKLibs()
|
||||
return listOfNotNull(
|
||||
KlibBasedSymbolProvider(session, moduleDataProvider, kotlinScopeProvider, kLibs),
|
||||
NativeForwardDeclarationsSymbolProvider(session, forwardDeclarationsModuleData, kotlinScopeProvider, kLibs),
|
||||
)
|
||||
}
|
||||
|
||||
override fun createJsLibrarySymbolProvider(
|
||||
session: FirSession,
|
||||
moduleData: LLFirModuleData,
|
||||
kotlinScopeProvider: FirKotlinScopeProvider,
|
||||
moduleDataProvider: SingleModuleDataProvider,
|
||||
scope: GlobalSearchScope,
|
||||
): List<FirSymbolProvider> {
|
||||
val kLibs = moduleData.getLibraryKLibs()
|
||||
|
||||
return listOf(
|
||||
KlibBasedSymbolProvider(session, moduleDataProvider, kotlinScopeProvider, kLibs)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
private fun LLFirModuleData.getLibraryKLibs(): List<KotlinLibrary> {
|
||||
val ktLibraryModule = ktModule as? KtLibraryModule ?: return emptyList()
|
||||
val resolveResult = CommonKLibResolver.resolve(
|
||||
ktLibraryModule.getBinaryRoots().map { it.toString() },
|
||||
DummyLogger
|
||||
)
|
||||
return resolveResult.getFullResolvedList().map { it.library }
|
||||
}
|
||||
}
|
||||
+44
-26
@@ -26,12 +26,16 @@ 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.platform.CommonPlatforms
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.js.JsPlatforms
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
|
||||
@OptIn(KtAnalysisApiInternals::class)
|
||||
@@ -74,33 +78,18 @@ class StandaloneSessionBuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testKotlinSdkSessionBuilder() {
|
||||
lateinit var sourceModule: KtSourceModule
|
||||
val session = buildStandaloneAnalysisAPISession {
|
||||
registerProjectService(KtLifetimeTokenProvider::class.java, KtAlwaysAccessibleLifetimeTokenProvider())
|
||||
fun testKotlinStdlibJvm() {
|
||||
doTestKotlinStdLibResolve(JvmPlatforms.defaultJvmPlatform, ForTestCompileRuntime.runtimeJarForTests().toPath())
|
||||
}
|
||||
|
||||
buildKtModuleProvider {
|
||||
platform = JvmPlatforms.defaultJvmPlatform
|
||||
val stdlib = addModule(
|
||||
buildKtLibraryModule {
|
||||
addBinaryRoot(ForTestCompileRuntime.runtimeJarForTests().toPath())
|
||||
platform = JvmPlatforms.defaultJvmPlatform
|
||||
libraryName = "stdlib"
|
||||
}
|
||||
)
|
||||
sourceModule = addModule(
|
||||
buildKtSourceModule {
|
||||
addSourceRoot(testDataPath("stdlibFunctionUsage"))
|
||||
addRegularDependency(stdlib)
|
||||
platform = JvmPlatforms.defaultJvmPlatform
|
||||
moduleName = "source"
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
val ktFile = session.modulesWithFiles.getValue(sourceModule).single() as KtFile
|
||||
val ktCallExpression = ktFile.findDescendantOfType<KtCallExpression>()!!
|
||||
ktCallExpression.assertIsCallOf(CallableId(StandardNames.COLLECTIONS_PACKAGE_FQ_NAME, Name.identifier("listOf")))
|
||||
@Test
|
||||
fun testKotlinStdLibCommon() {
|
||||
doTestKotlinStdLibResolve(CommonPlatforms.defaultCommonPlatform, Paths.get("dist/common/kotlin-stdlib-common.jar"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testKotlinStdLibJs() {
|
||||
doTestKotlinStdLibResolve(JsPlatforms.defaultJsPlatform, Paths.get("dist/kotlinc/lib/kotlin-stdlib-js.jar"))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -133,6 +122,35 @@ class StandaloneSessionBuilderTest {
|
||||
ktCallExpression.assertIsCallOf(CallableId(FqName.ROOT, Name.identifier("foo")))
|
||||
}
|
||||
|
||||
private fun doTestKotlinStdLibResolve(targetPlatform: TargetPlatform, platformStdlibPath: Path) {
|
||||
lateinit var sourceModule: KtSourceModule
|
||||
val session = buildStandaloneAnalysisAPISession {
|
||||
registerProjectService(KtLifetimeTokenProvider::class.java, KtAlwaysAccessibleLifetimeTokenProvider())
|
||||
|
||||
buildKtModuleProvider {
|
||||
platform = targetPlatform
|
||||
val stdlib = addModule(
|
||||
buildKtLibraryModule {
|
||||
addBinaryRoot(platformStdlibPath)
|
||||
platform = targetPlatform
|
||||
libraryName = "stdlib"
|
||||
}
|
||||
)
|
||||
sourceModule = addModule(
|
||||
buildKtSourceModule {
|
||||
addSourceRoot(testDataPath("stdlibFunctionUsage"))
|
||||
addRegularDependency(stdlib)
|
||||
platform = targetPlatform
|
||||
moduleName = "source"
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
val ktFile = session.modulesWithFiles.getValue(sourceModule).single() as KtFile
|
||||
val ktCallExpression = ktFile.findDescendantOfType<KtCallExpression>()!!
|
||||
ktCallExpression.assertIsCallOf(CallableId(StandardNames.COLLECTIONS_PACKAGE_FQ_NAME, Name.identifier("listOf")))
|
||||
}
|
||||
|
||||
|
||||
private fun KtCallExpression.assertIsCallOf(callableId: CallableId) {
|
||||
analyze(this) {
|
||||
|
||||
+26
@@ -25,6 +25,32 @@ abstract class LLFirLibrarySymbolProviderFactory {
|
||||
scope: GlobalSearchScope,
|
||||
): List<FirSymbolProvider>
|
||||
|
||||
abstract fun createCommonLibrarySymbolProvider(
|
||||
session: FirSession,
|
||||
moduleData: LLFirModuleData,
|
||||
kotlinScopeProvider: FirKotlinScopeProvider,
|
||||
moduleDataProvider: SingleModuleDataProvider,
|
||||
packagePartProvider: PackagePartProvider,
|
||||
scope: GlobalSearchScope,
|
||||
): List<FirSymbolProvider>
|
||||
|
||||
abstract fun createNativeLibrarySymbolProvider(
|
||||
session: FirSession,
|
||||
moduleData: LLFirModuleData,
|
||||
kotlinScopeProvider: FirKotlinScopeProvider,
|
||||
moduleDataProvider: SingleModuleDataProvider,
|
||||
scope: GlobalSearchScope,
|
||||
): List<FirSymbolProvider>
|
||||
|
||||
|
||||
abstract fun createJsLibrarySymbolProvider(
|
||||
session: FirSession,
|
||||
moduleData: LLFirModuleData,
|
||||
kotlinScopeProvider: FirKotlinScopeProvider,
|
||||
moduleDataProvider: SingleModuleDataProvider,
|
||||
scope: GlobalSearchScope,
|
||||
): List<FirSymbolProvider>
|
||||
|
||||
companion object {
|
||||
fun getService(project: Project): LLFirLibrarySymbolProviderFactory =
|
||||
project.getService(LLFirLibrarySymbolProviderFactory::class.java)
|
||||
|
||||
+6
-2
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirLibrarySymbolProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirModuleData
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirModuleWithDependenciesSymbolProvider
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserialization.createStubBasedFirSymbolProviderForCommonMetadataFiles
|
||||
@@ -90,8 +91,11 @@ internal class LLFirCommonSessionFactory(project: Project) : LLFirAbstractSessio
|
||||
val moduleDataProvider = SingleModuleDataProvider(moduleData)
|
||||
val packagePartProvider = project.createPackagePartProvider(scope)
|
||||
return buildList {
|
||||
add(createStubBasedFirSymbolProviderForCommonMetadataFiles(project, scope, session, moduleDataProvider, kotlinScopeProvider))
|
||||
add(createStubBasedFirSymbolProviderForKotlinNativeMetadataFiles(project, scope, session, moduleDataProvider, kotlinScopeProvider))
|
||||
addAll(
|
||||
LLFirLibrarySymbolProviderFactory.getService(project).createCommonLibrarySymbolProvider(
|
||||
session, moduleData, kotlinScopeProvider, moduleDataProvider, packagePartProvider, scope,
|
||||
)
|
||||
)
|
||||
|
||||
addIfNotNull(
|
||||
OptionalAnnotationClassesProvider.createIfNeeded(
|
||||
|
||||
+5
-1
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirLibrarySymbolProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirModuleData
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirModuleWithDependenciesSymbolProvider
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtBinaryModule
|
||||
@@ -20,6 +21,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.FirPlatformDiagnosticSuppresso
|
||||
import org.jetbrains.kotlin.fir.analysis.js.checkers.FirJsPlatformDiagnosticSuppressor
|
||||
import org.jetbrains.kotlin.fir.analysis.jvm.FirJvmOverridesBackwardCompatibilityHelper
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeSpecificityComparatorProvider
|
||||
import org.jetbrains.kotlin.fir.deserialization.SingleModuleDataProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
||||
@@ -80,7 +82,9 @@ internal class LLFirJsSessionFactory(project: Project) : LLFirAbstractSessionFac
|
||||
builtinTypes: BuiltinTypes,
|
||||
scope: GlobalSearchScope,
|
||||
): List<FirSymbolProvider> {
|
||||
return emptyList() // TODO(kirpichenkov)
|
||||
val moduleDataProvider = SingleModuleDataProvider(moduleData)
|
||||
return LLFirLibrarySymbolProviderFactory.getService(project)
|
||||
.createJsLibrarySymbolProvider(session, moduleData, kotlinScopeProvider, moduleDataProvider, scope)
|
||||
}
|
||||
|
||||
private fun LLFirSession.registerModuleIndependentJsComponents() {
|
||||
|
||||
+4
-3
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirLibrarySymbolProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirModuleData
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirModuleWithDependenciesSymbolProvider
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserialization.createStubBasedFirSymbolProviderForKotlinNativeMetadataFiles
|
||||
@@ -82,9 +83,9 @@ internal class LLFirNativeSessionFactory(project: Project) : LLFirAbstractSessio
|
||||
val moduleDataProvider = SingleModuleDataProvider(moduleData)
|
||||
val packagePartProvider = project.createPackagePartProvider(scope)
|
||||
return buildList {
|
||||
add(
|
||||
createStubBasedFirSymbolProviderForKotlinNativeMetadataFiles(
|
||||
project, scope, session, moduleDataProvider, kotlinScopeProvider
|
||||
addAll(
|
||||
LLFirLibrarySymbolProviderFactory.getService(project).createNativeLibrarySymbolProvider(
|
||||
session, moduleData, kotlinScopeProvider, moduleDataProvider, scope
|
||||
)
|
||||
)
|
||||
addIfNotNull(
|
||||
|
||||
+44
-1
@@ -27,7 +27,7 @@ class LLStubBasedLibrarySymbolProviderFactory(private val project: Project) : LL
|
||||
moduleDataProvider: SingleModuleDataProvider,
|
||||
firJavaFacade: FirJavaFacade,
|
||||
packagePartProvider: PackagePartProvider,
|
||||
scope: GlobalSearchScope
|
||||
scope: GlobalSearchScope,
|
||||
): List<FirSymbolProvider> {
|
||||
return buildList {
|
||||
//stub based provider here works over kotlin-only indices and thus provides only kotlin declarations
|
||||
@@ -38,4 +38,47 @@ class LLStubBasedLibrarySymbolProviderFactory(private val project: Project) : LL
|
||||
add(LLFirJavaSymbolProvider(session, moduleData, project, scope))
|
||||
}
|
||||
}
|
||||
|
||||
override fun createCommonLibrarySymbolProvider(
|
||||
session: FirSession,
|
||||
moduleData: LLFirModuleData,
|
||||
kotlinScopeProvider: FirKotlinScopeProvider,
|
||||
moduleDataProvider: SingleModuleDataProvider,
|
||||
packagePartProvider: PackagePartProvider,
|
||||
scope: GlobalSearchScope,
|
||||
): List<FirSymbolProvider> {
|
||||
return buildList {
|
||||
add(createStubBasedFirSymbolProviderForCommonMetadataFiles(project, scope, session, moduleDataProvider, kotlinScopeProvider))
|
||||
add(
|
||||
// klib metadata symbol provider
|
||||
createStubBasedFirSymbolProviderForKotlinNativeMetadataFiles(
|
||||
project, scope, session, moduleDataProvider, kotlinScopeProvider
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun createNativeLibrarySymbolProvider(
|
||||
session: FirSession,
|
||||
moduleData: LLFirModuleData,
|
||||
kotlinScopeProvider: FirKotlinScopeProvider,
|
||||
moduleDataProvider: SingleModuleDataProvider,
|
||||
scope: GlobalSearchScope,
|
||||
): List<FirSymbolProvider> {
|
||||
return listOf(
|
||||
createStubBasedFirSymbolProviderForKotlinNativeMetadataFiles(
|
||||
project, scope, session, moduleDataProvider, kotlinScopeProvider
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun createJsLibrarySymbolProvider(
|
||||
session: FirSession,
|
||||
moduleData: LLFirModuleData,
|
||||
kotlinScopeProvider: FirKotlinScopeProvider,
|
||||
moduleDataProvider: SingleModuleDataProvider,
|
||||
scope: GlobalSearchScope,
|
||||
): List<FirSymbolProvider> {
|
||||
return emptyList() // TODO(kirpichenkov)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user