Analysis API: introduce Project Structure
This commit is contained in:
+1
-1
@@ -119,7 +119,7 @@ internal class KtSymbolByFirBuilder private constructor(
|
||||
|
||||
fun createPackageSymbolIfOneExists(packageFqName: FqName): KtFirPackageSymbol? {
|
||||
val exists =
|
||||
packageProvider.isPackageExists(packageFqName)
|
||||
packageProvider.doKotlinPackageExists(packageFqName)
|
||||
|| JavaPsiFacade.getInstance(project).findPackage(packageFqName.asString()) != null
|
||||
if (!exists) {
|
||||
return null
|
||||
|
||||
+1
-1
@@ -65,5 +65,5 @@ class KtPackage(
|
||||
) : PsiPackageImpl(manager, fqName.asString().replace('/', '.')) {
|
||||
override fun copy() = KtPackage(manager, fqName, scope)
|
||||
|
||||
override fun isValid(): Boolean = project.createPackageProvider(scope).isPackageExists(fqName)
|
||||
override fun isValid(): Boolean = project.createPackageProvider(scope).doKotlinPackageExists(fqName)
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ dependencies {
|
||||
implementation(project(":compiler:psi"))
|
||||
implementation(project(":compiler:frontend.java"))
|
||||
implementation(project(":core:compiler.common"))
|
||||
implementation(project(":analysis:project-structure"))
|
||||
implementation(intellijCoreDep()) { includeJars("intellij-core", rootProject = rootProject) }
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -9,11 +9,11 @@ import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.ModificationTracker
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
|
||||
|
||||
public abstract class KotlinModificationTrackerFactory {
|
||||
public abstract fun createProjectWideOutOfBlockModificationTracker(): ModificationTracker
|
||||
public abstract fun createModuleWithoutDependenciesOutOfBlockModificationTracker(moduleInfo: ModuleSourceInfoBase): ModificationTracker
|
||||
public abstract fun createModuleWithoutDependenciesOutOfBlockModificationTracker(module: KtSourceModule): ModificationTracker
|
||||
public abstract fun createLibrariesModificationTracker(): ModificationTracker
|
||||
|
||||
@TestOnly
|
||||
@@ -29,6 +29,6 @@ public fun Project.createLibrariesModificationTracker(): ModificationTracker =
|
||||
.createLibrariesModificationTracker()
|
||||
|
||||
|
||||
public fun ModuleSourceInfoBase.createModuleWithoutDependenciesOutOfBlockModificationTracker(project: Project): ModificationTracker =
|
||||
public fun KtSourceModule.createModuleWithoutDependenciesOutOfBlockModificationTracker(project: Project): ModificationTracker =
|
||||
ServiceManager.getService(project, KotlinModificationTrackerFactory::class.java)
|
||||
.createModuleWithoutDependenciesOutOfBlockModificationTracker(this)
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.analysis.providers
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
|
||||
public abstract class KotlinModuleInfoProvider {
|
||||
public abstract fun getModuleInfo(element: KtElement): ModuleInfo
|
||||
}
|
||||
|
||||
public fun KtElement.getModuleInfo(): ModuleInfo =
|
||||
ServiceManager.getService(project, KotlinModuleInfoProvider::class.java).getModuleInfo(this)
|
||||
+1
-1
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
public abstract class KotlinPackageProvider {
|
||||
public abstract fun isPackageExists(packageFqName: FqName): Boolean
|
||||
public abstract fun doKotlinPackageExists(packageFqName: FqName): Boolean
|
||||
public abstract fun getKotlinSubPackageFqNames(packageFqName: FqName): Set<Name>
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -8,21 +8,21 @@ package org.jetbrains.kotlin.analysis.providers.impl
|
||||
import com.intellij.openapi.util.ModificationTracker
|
||||
import com.intellij.openapi.util.SimpleModificationTracker
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinModificationTrackerFactory
|
||||
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
|
||||
|
||||
public class KotlinStaticModificationTrackerFactory : KotlinModificationTrackerFactory() {
|
||||
private val projectWide = SimpleModificationTracker()
|
||||
private val library = SimpleModificationTracker()
|
||||
private val forModule = mutableMapOf<ModuleSourceInfoBase, SimpleModificationTracker>()
|
||||
private val forModule = mutableMapOf<KtSourceModule, SimpleModificationTracker>()
|
||||
|
||||
override fun createProjectWideOutOfBlockModificationTracker(): ModificationTracker {
|
||||
return projectWide
|
||||
}
|
||||
|
||||
|
||||
override fun createModuleWithoutDependenciesOutOfBlockModificationTracker(moduleInfo: ModuleSourceInfoBase): ModificationTracker {
|
||||
return forModule.getOrPut(moduleInfo) { SimpleModificationTracker() }
|
||||
override fun createModuleWithoutDependenciesOutOfBlockModificationTracker(module: KtSourceModule): ModificationTracker {
|
||||
return forModule.getOrPut(module) { SimpleModificationTracker() }
|
||||
}
|
||||
|
||||
override fun createLibrariesModificationTracker(): ModificationTracker {
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ public class KotlinStaticPackageProvider(
|
||||
packages
|
||||
}
|
||||
|
||||
override fun isPackageExists(packageFqName: FqName): Boolean {
|
||||
override fun doKotlinPackageExists(packageFqName: FqName): Boolean {
|
||||
return packageFqName in packageToSubPackageNames
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ plugins {
|
||||
|
||||
dependencies {
|
||||
compile(project(":compiler:psi"))
|
||||
implementation(project(":analysis:project-structure"))
|
||||
compile(project(":compiler:fir:fir2ir"))
|
||||
compile(project(":compiler:fir:fir2ir:jvm-backend"))
|
||||
compile(project(":compiler:ir.serialization.common"))
|
||||
|
||||
+15
-15
@@ -9,15 +9,15 @@ import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.ProjectRootModificationTracker
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.analysis.providers.createProjectWideOutOfBlockModificationTracker
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirModuleResolveState
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.FirLazyDeclarationResolver
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.FirIdeSession
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.FirIdeSessionProviderStorage
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.*
|
||||
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.cachedValue
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.getValue
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
|
||||
import org.jetbrains.kotlin.analysis.providers.createProjectWideOutOfBlockModificationTracker
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
internal class FirIdeResolveStateService(project: Project) {
|
||||
@@ -28,29 +28,29 @@ internal class FirIdeResolveStateService(project: Project) {
|
||||
project.createProjectWideOutOfBlockModificationTracker(),
|
||||
ProjectRootModificationTracker.getInstance(project),
|
||||
) {
|
||||
ConcurrentHashMap<ModuleInfo, FirModuleResolveStateImpl>()
|
||||
ConcurrentHashMap<KtModule, FirModuleResolveStateImpl>()
|
||||
}
|
||||
|
||||
fun getResolveState(moduleInfo: ModuleInfo): FirModuleResolveStateImpl =
|
||||
stateCache.computeIfAbsent(moduleInfo) { createResolveStateFor(moduleInfo, sessionProviderStorage) }
|
||||
fun getResolveState(module: KtModule): FirModuleResolveStateImpl =
|
||||
stateCache.computeIfAbsent(module) { createResolveStateFor(module, sessionProviderStorage) }
|
||||
|
||||
companion object {
|
||||
fun getInstance(project: Project): FirIdeResolveStateService =
|
||||
ServiceManager.getService(project, FirIdeResolveStateService::class.java)
|
||||
|
||||
internal fun createResolveStateFor(
|
||||
moduleInfo: ModuleInfo,
|
||||
module: KtModule,
|
||||
sessionProviderStorage: FirIdeSessionProviderStorage,
|
||||
configureSession: (FirIdeSession.() -> Unit)? = null,
|
||||
): FirModuleResolveStateImpl {
|
||||
if (moduleInfo !is ModuleSourceInfoBase) {
|
||||
error("Creating FirModuleResolveState is not yet supported for $moduleInfo")
|
||||
if (module !is KtSourceModule) {
|
||||
error("Creating FirModuleResolveState is not yet supported for $module")
|
||||
}
|
||||
val sessionProvider = sessionProviderStorage.getSessionProvider(moduleInfo, configureSession)
|
||||
val sessionProvider = sessionProviderStorage.getSessionProvider(module, configureSession)
|
||||
val firFileBuilder = sessionProvider.rootModuleSession.firFileBuilder
|
||||
return FirModuleResolveStateImpl(
|
||||
sessionProviderStorage.project,
|
||||
moduleInfo,
|
||||
module,
|
||||
sessionProvider,
|
||||
firFileBuilder,
|
||||
FirLazyDeclarationResolver(firFileBuilder),
|
||||
@@ -61,12 +61,12 @@ internal class FirIdeResolveStateService(project: Project) {
|
||||
|
||||
@TestOnly
|
||||
fun createResolveStateForNoCaching(
|
||||
moduleInfo: ModuleInfo,
|
||||
module: KtModule,
|
||||
project: Project,
|
||||
configureSession: (FirIdeSession.() -> Unit)? = null,
|
||||
): FirModuleResolveState =
|
||||
FirIdeResolveStateService.createResolveStateFor(
|
||||
moduleInfo = moduleInfo,
|
||||
module = module,
|
||||
sessionProviderStorage = FirIdeSessionProviderStorage(project),
|
||||
configureSession = configureSession
|
||||
)
|
||||
|
||||
+10
-10
@@ -6,13 +6,6 @@
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.annotations.InternalForInline
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirModuleResolveState
|
||||
@@ -22,6 +15,13 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.KtToFirMap
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.ResolveType
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.containingKtFileIfAny
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.originalKtFile
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
@@ -34,12 +34,12 @@ internal class FirModuleResolveStateDepended(
|
||||
) : FirModuleResolveState() {
|
||||
|
||||
override val project: Project get() = originalState.project
|
||||
override val moduleInfo: ModuleInfo get() = originalState.moduleInfo
|
||||
override val module: KtModule get() = originalState.module
|
||||
override val rootModuleSession get() = originalState.rootModuleSession
|
||||
private val fileStructureCache get() = originalState.fileStructureCache
|
||||
|
||||
override fun getSessionFor(moduleInfo: ModuleInfo): FirSession =
|
||||
originalState.getSessionFor(moduleInfo)
|
||||
override fun getSessionFor(module: KtModule): FirSession =
|
||||
originalState.getSessionFor(module)
|
||||
|
||||
override fun getOrBuildFirFor(element: KtElement): FirElement? {
|
||||
val elementBuilder = originalState.elementBuilder
|
||||
|
||||
+10
-10
@@ -6,9 +6,6 @@
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analysis.providers.getModuleInfo
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
|
||||
@@ -37,11 +34,14 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.FirIdeSourcesSes
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.FirDeclarationForCompiledElementSearcher
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.findSourceNonLocalFirDeclaration
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.getElementTextInContext
|
||||
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.psi.*
|
||||
|
||||
internal class FirModuleResolveStateImpl(
|
||||
override val project: Project,
|
||||
override val moduleInfo: ModuleInfo,
|
||||
override val module: KtModule,
|
||||
private val sessionProvider: FirIdeSessionProvider,
|
||||
val firFileBuilder: FirFileBuilder,
|
||||
val firLazyDeclarationResolver: FirLazyDeclarationResolver,
|
||||
@@ -58,8 +58,8 @@ internal class FirModuleResolveStateImpl(
|
||||
val elementBuilder = FirElementBuilder()
|
||||
private val diagnosticsCollector = DiagnosticsCollector(fileStructureCache, rootModuleSession.cache)
|
||||
|
||||
override fun getSessionFor(moduleInfo: ModuleInfo): FirSession =
|
||||
sessionProvider.getSession(moduleInfo)!!
|
||||
override fun getSessionFor(module: KtModule): FirSession =
|
||||
sessionProvider.getSession(module)!!
|
||||
|
||||
override fun getOrBuildFirFor(element: KtElement): FirElement? =
|
||||
elementBuilder.getOrBuildFirFor(
|
||||
@@ -95,9 +95,9 @@ internal class FirModuleResolveStateImpl(
|
||||
* [ktDeclaration] should be either [KtDeclaration] or [KtLambdaExpression]
|
||||
*/
|
||||
private fun findSourceFirDeclarationByExpression(ktDeclaration: KtExpression): FirDeclaration {
|
||||
val moduleInfo = ktDeclaration.getModuleInfo() as? ModuleSourceInfoBase
|
||||
require(moduleInfo != null) {
|
||||
"Declaration should have ModuleSourceInfo, instead it had ${ktDeclaration.getModuleInfo()}"
|
||||
val module = ktDeclaration.getKtModule(project)
|
||||
require(module is KtSourceModule) {
|
||||
"Declaration should have ModuleSourceInfo, instead it had ${module::class}"
|
||||
}
|
||||
val nonLocalNamedDeclaration = ktDeclaration.getNonLocalContainingOrThisDeclaration()
|
||||
?: error("Declaration should have non-local container${ktDeclaration.getElementTextInContext()}")
|
||||
@@ -106,7 +106,7 @@ internal class FirModuleResolveStateImpl(
|
||||
return nonLocalNamedDeclaration.findSourceNonLocalFirDeclaration(
|
||||
firFileBuilder = firFileBuilder,
|
||||
firSymbolProvider = rootModuleSession.firIdeProvider.symbolProvider,
|
||||
moduleFileCache = sessionProvider.getModuleCache(moduleInfo)
|
||||
moduleFileCache = sessionProvider.getModuleCache(module)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -6,13 +6,13 @@
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.api
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.annotations.InternalForInline
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.ResolveType
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
@@ -23,9 +23,9 @@ abstract class FirModuleResolveState {
|
||||
|
||||
abstract val rootModuleSession: FirSession
|
||||
|
||||
abstract val moduleInfo: ModuleInfo
|
||||
abstract val module: KtModule
|
||||
|
||||
internal abstract fun getSessionFor(moduleInfo: ModuleInfo): FirSession
|
||||
internal abstract fun getSessionFor(module: KtModule): FirSession
|
||||
|
||||
/**
|
||||
* Build fully resolved FIR node for requested element.
|
||||
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.analysis.low.level.api.fir.api
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElementFinder
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider
|
||||
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
|
||||
import org.jetbrains.kotlin.fir.java.FirJavaElementFinder
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.FirIdeSourcesSession
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
|
||||
abstract class FirModuleResolveStateConfigurator {
|
||||
abstract fun createPackagePartsProvider(moduleInfo: ModuleSourceInfoBase, scope: GlobalSearchScope): PackagePartProvider
|
||||
|
||||
abstract fun createModuleDataProvider(moduleInfo: ModuleSourceInfoBase): ModuleDataProvider
|
||||
|
||||
abstract fun getLanguageVersionSettings(moduleInfo: ModuleSourceInfoBase): LanguageVersionSettings
|
||||
abstract fun getModuleSourceScope(moduleInfo: ModuleSourceInfoBase): GlobalSearchScope
|
||||
abstract fun createScopeForModuleLibraries(moduleInfo: ModuleSourceInfoBase): GlobalSearchScope
|
||||
abstract fun createSealedInheritorsProvider(): SealedClassInheritorsProvider
|
||||
|
||||
abstract fun configureSourceSession(session: FirSession)
|
||||
}
|
||||
|
||||
val Project.stateConfigurator: FirModuleResolveStateConfigurator
|
||||
get() = ServiceManager.getService(this, FirModuleResolveStateConfigurator::class.java)
|
||||
+7
-5
@@ -6,14 +6,14 @@
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.api
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analysis.providers.getModuleInfo
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.FirIdeResolveStateService
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.annotations.InternalForInline
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.ResolveType
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.getKtModule
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
@@ -23,13 +23,15 @@ import kotlin.reflect.KClass
|
||||
/**
|
||||
* Returns [FirModuleResolveState] which corresponds to containing module
|
||||
*/
|
||||
fun KtElement.getResolveState(): FirModuleResolveState =
|
||||
getModuleInfo().getResolveState(project)
|
||||
fun KtElement.getResolveState(): FirModuleResolveState {
|
||||
val project = project
|
||||
return getKtModule(project).getResolveState(project)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns [FirModuleResolveState] which corresponds to containing module
|
||||
*/
|
||||
fun ModuleInfo.getResolveState(project: Project): FirModuleResolveState =
|
||||
fun KtModule.getResolveState(project: Project): FirModuleResolveState =
|
||||
FirIdeResolveStateService.getInstance(project).getResolveState(this)
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.api
|
||||
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.analysis.providers.getModuleInfo
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
@@ -39,6 +38,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.util.getElementTextInCont
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.originalDeclaration
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.parentOfType
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.parentsOfType
|
||||
import org.jetbrains.kotlin.analysis.project.structure.getKtModule
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
||||
@@ -127,7 +127,7 @@ object LowLevelFirApiFacadeForResolveOnAir {
|
||||
file: KtFile,
|
||||
): FirTowerDataContext {
|
||||
require(file.isPhysical)
|
||||
val session = state.getSessionFor(file.getModuleInfo()) as FirIdeSourcesSession
|
||||
val session = state.getSessionFor(file.getKtModule(state.project)) as FirIdeSourcesSession
|
||||
|
||||
val firFile = session.firFileBuilder.buildRawFirFileWithCaching(
|
||||
ktFile = file,
|
||||
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.analysis.low.level.api.fir.api
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
|
||||
abstract class ModuleInfoProvider {
|
||||
|
||||
companion object {
|
||||
fun getInstance(project: Project): ModuleInfoProvider = ServiceManager.getService(project, ModuleInfoProvider::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.analysis.low.level.api.fir.api
|
||||
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.FirIdeModuleSession
|
||||
|
||||
/**
|
||||
* Returns a [GlobalSearchScope] declarations from which [FirSession] knows about
|
||||
*/
|
||||
val FirSession.searchScope: GlobalSearchScope
|
||||
get() {
|
||||
check(this is FirIdeModuleSession)
|
||||
return scope
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.analysis.low.level.api.fir.api.services
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||
|
||||
abstract class PackagePartProviderFactory {
|
||||
/**
|
||||
* Create a [PackagePartProvider] for a given scope. [PackagePartProvider] is responsible for searching sub packages in a library.
|
||||
*/
|
||||
abstract fun createPackagePartProviderForLibrary(scope: GlobalSearchScope): PackagePartProvider
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a [PackagePartProvider] for a given scope. [PackagePartProvider] is responsible for searching sub packages in a library.
|
||||
*/
|
||||
internal fun Project.createPackagePartProviderForLibrary(scope: GlobalSearchScope): PackagePartProvider =
|
||||
getService(PackagePartProviderFactory::class.java).createPackagePartProviderForLibrary(scope)
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.analysis.low.level.api.fir.api.services
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirSealedClassInheritorsProcessor
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||
|
||||
abstract class FirSealedClassInheritorsProcessorFactory {
|
||||
/**
|
||||
* Creates [SealedClassInheritorsProvider] for a module.
|
||||
* This function should crate a new [SealedClassInheritorsProvider] instance on every call.
|
||||
*/
|
||||
abstract fun createSealedClassInheritorsProvider(): SealedClassInheritorsProvider
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates [SealedClassInheritorsProvider] for a module.
|
||||
* This function should crate a new [SealedClassInheritorsProvider] instance on every call.
|
||||
*/
|
||||
internal fun Project.createSealedInheritorsProvider(): SealedClassInheritorsProvider =
|
||||
getService(FirSealedClassInheritorsProcessorFactory::class.java).createSealedClassInheritorsProvider()
|
||||
+3
-3
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics
|
||||
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.module
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.CheckersComponentInternal
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.*
|
||||
@@ -20,7 +21,6 @@ import org.jetbrains.kotlin.fir.analysis.jvm.checkers.JvmDeclarationCheckers
|
||||
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.JvmExpressionCheckers
|
||||
import org.jetbrains.kotlin.fir.analysis.jvm.diagnostics.FirJvmDefaultErrorMessages
|
||||
import org.jetbrains.kotlin.fir.moduleData
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.moduleSourceInfo
|
||||
import org.jetbrains.kotlin.platform.SimplePlatform
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatform
|
||||
|
||||
@@ -41,8 +41,8 @@ private object CheckersFactory {
|
||||
reporter: DiagnosticReporter,
|
||||
useExtendedCheckers: Boolean
|
||||
): List<AbstractDiagnosticCollectorComponent> {
|
||||
val moduleInfo = session.moduleData.moduleSourceInfo
|
||||
val platform = moduleInfo.platform.componentPlatforms.first()
|
||||
val module = session.moduleData.module
|
||||
val platform = module.platform.componentPlatforms.first()
|
||||
installPlatformSpecificErrorMessages(platform)
|
||||
val declarationCheckers = createDeclarationCheckers(useExtendedCheckers, platform)
|
||||
val expressionCheckers = createExpressionCheckers(useExtendedCheckers, platform)
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ import java.util.*
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
/**
|
||||
* Caches mapping [KtFile] -> [FirFile] of module [moduleInfo]
|
||||
* Caches mapping [KtFile] -> [FirFile] of module [KtModule]
|
||||
*/
|
||||
@ThreadSafe
|
||||
internal abstract class ModuleFileCache {
|
||||
|
||||
+4
-4
@@ -6,9 +6,11 @@
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.providers
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.FirFileBuilder
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinPackageProvider
|
||||
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.NoMutableState
|
||||
import org.jetbrains.kotlin.fir.ThreadSafeMutableState
|
||||
@@ -21,8 +23,6 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.FirFileBuilder
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -31,7 +31,7 @@ import org.jetbrains.kotlin.name.Name
|
||||
internal class FirIdeProvider(
|
||||
@Suppress("UNUSED_PARAMETER") project: Project,
|
||||
val session: FirSession,
|
||||
@Suppress("UNUSED_PARAMETER") moduleInfo: ModuleSourceInfoBase,
|
||||
@Suppress("UNUSED_PARAMETER") module: KtModule,
|
||||
val kotlinScopeProvider: FirKotlinScopeProvider,
|
||||
firFileBuilder: FirFileBuilder,
|
||||
val cache: ModuleFileCache,
|
||||
|
||||
+1
-1
@@ -86,5 +86,5 @@ internal class FirProviderHelper(
|
||||
}
|
||||
|
||||
fun getPackage(fqName: FqName): FqName? =
|
||||
fqName.takeIf(packageProvider::isPackageExists)
|
||||
fqName.takeIf(packageProvider::doKotlinPackageExists)
|
||||
}
|
||||
|
||||
+1
-3
@@ -7,7 +7,6 @@ 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.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.fir.BuiltinTypes
|
||||
import org.jetbrains.kotlin.fir.PrivateSessionConstructor
|
||||
|
||||
@@ -17,6 +16,5 @@ import org.jetbrains.kotlin.fir.PrivateSessionConstructor
|
||||
@OptIn(PrivateSessionConstructor::class)
|
||||
internal class FirIdeLibrariesSession @PrivateSessionConstructor constructor(
|
||||
override val project: Project,
|
||||
override val scope: GlobalSearchScope,
|
||||
builtinTypes: BuiltinTypes,
|
||||
) : FirIdeModuleSession(builtinTypes, Kind.Library)
|
||||
) : FirIdeSession(builtinTypes, Kind.Library)
|
||||
|
||||
+2
-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.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.fir.BuiltinTypes
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.PrivateSessionConstructor
|
||||
@@ -18,5 +19,5 @@ abstract class FirIdeSession(override val builtinTypes: BuiltinTypes, kind: Kind
|
||||
|
||||
@OptIn(PrivateSessionConstructor::class)
|
||||
abstract class FirIdeModuleSession(builtinTypes: BuiltinTypes, kind: Kind) : FirIdeSession(builtinTypes, kind) {
|
||||
abstract val scope: GlobalSearchScope
|
||||
abstract val module: KtModule
|
||||
}
|
||||
|
||||
+61
-48
@@ -6,9 +6,20 @@
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.FirPhaseRunner
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.IdeFirPhaseManager
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.IdeSessionComponents
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.createPackagePartProviderForLibrary
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.createSealedInheritorsProvider
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.FirFileBuilder
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCacheImpl
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.fir.caches.FirThreadSafeCachesFactory
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.FirLazyDeclarationResolver
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.*
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkCanceled
|
||||
import org.jetbrains.kotlin.analysis.project.structure.*
|
||||
import org.jetbrains.kotlin.analysis.providers.createDeclarationProvider
|
||||
import org.jetbrains.kotlin.analysis.providers.createPackageProvider
|
||||
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
@@ -16,6 +27,7 @@ import org.jetbrains.kotlin.fir.backend.jvm.FirJvmTypeMapper
|
||||
import org.jetbrains.kotlin.fir.caches.FirCachesFactory
|
||||
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
|
||||
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider
|
||||
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
|
||||
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.java.deserialization.KotlinDeserializedJvmSymbolsProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirDependenciesSymbolProvider
|
||||
@@ -26,58 +38,42 @@ import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCompositeSymbolProvide
|
||||
import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
|
||||
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirPhaseCheckingPhaseManager
|
||||
import org.jetbrains.kotlin.fir.symbols.FirPhaseManager
|
||||
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
||||
import org.jetbrains.kotlin.fir.session.*
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.*
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.FirPhaseRunner
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.IdeFirPhaseManager
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirModuleResolveStateConfigurator
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.stateConfigurator
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.FirFileBuilder
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCacheImpl
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.fir.caches.FirThreadSafeCachesFactory
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.FirLazyDeclarationResolver
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.*
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.FirIdeBuiltinsAndCloneableSessionProvider
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.FirIdeLibrariesSessionProvider
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.FirIdeProvider
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.FirModuleWithDependenciesSymbolProvider
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkCanceled
|
||||
import org.jetbrains.kotlin.fir.symbols.FirPhaseManager
|
||||
import org.jetbrains.kotlin.load.java.createJavaClassFinder
|
||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
||||
import java.nio.file.Path
|
||||
|
||||
@OptIn(PrivateSessionConstructor::class, SessionConfiguration::class)
|
||||
internal object FirIdeSessionFactory {
|
||||
fun createSourcesSession(
|
||||
project: Project,
|
||||
configurator: FirModuleResolveStateConfigurator,
|
||||
moduleInfo: ModuleSourceInfoBase,
|
||||
module: KtSourceModule,
|
||||
builtinsAndCloneableSession: FirIdeBuiltinsAndCloneableSession,
|
||||
firPhaseRunner: FirPhaseRunner,
|
||||
sessionInvalidator: FirSessionInvalidator,
|
||||
builtinTypes: BuiltinTypes,
|
||||
sessionsCache: MutableMap<ModuleSourceInfoBase, FirIdeSourcesSession>,
|
||||
sessionsCache: MutableMap<KtSourceModule, FirIdeSourcesSession>,
|
||||
isRootModule: Boolean,
|
||||
librariesCache: LibrariesCache,
|
||||
configureSession: (FirIdeSession.() -> Unit)? = null
|
||||
): FirIdeSourcesSession {
|
||||
sessionsCache[moduleInfo]?.let { return it }
|
||||
val languageVersionSettings = project.stateConfigurator.getLanguageVersionSettings(moduleInfo)
|
||||
sessionsCache[module]?.let { return it }
|
||||
val languageVersionSettings = module.languageVersionSettings
|
||||
val scopeProvider = FirKotlinScopeProvider(::wrapScopeWithJvmMapped)
|
||||
val firBuilder = FirFileBuilder(scopeProvider, firPhaseRunner)
|
||||
val searchScope = project.stateConfigurator.getModuleSourceScope(moduleInfo)
|
||||
val dependentModules = moduleInfo.dependenciesWithoutSelf()
|
||||
.filterIsInstanceTo<ModuleSourceInfoBase, MutableList<ModuleSourceInfoBase>>(mutableListOf())
|
||||
val session = FirIdeSourcesSession(dependentModules, project, searchScope, firBuilder, builtinTypes)
|
||||
sessionsCache[moduleInfo] = session
|
||||
val contentScope = module.contentScope
|
||||
val dependentModules = module.directRegularDependenciesOfType<KtSourceModule>()
|
||||
val session = FirIdeSourcesSession(module, project, firBuilder, builtinTypes)
|
||||
sessionsCache[module] = session
|
||||
|
||||
return session.apply session@{
|
||||
val moduleData = FirModuleInfoBasedModuleData(moduleInfo).apply { bindSession(this@session) }
|
||||
val moduleData = KtModuleBasedModuleData(module).apply { bindSession(this@session) }
|
||||
registerModuleData(moduleData)
|
||||
|
||||
val cache = ModuleFileCacheImpl(this)
|
||||
@@ -91,12 +87,12 @@ internal object FirIdeSessionFactory {
|
||||
val provider = FirIdeProvider(
|
||||
project,
|
||||
this,
|
||||
moduleInfo,
|
||||
module,
|
||||
scopeProvider,
|
||||
firFileBuilder,
|
||||
cache,
|
||||
project.createDeclarationProvider(searchScope),
|
||||
project.createPackageProvider(searchScope),
|
||||
project.createDeclarationProvider(contentScope),
|
||||
project.createPackageProvider(contentScope),
|
||||
)
|
||||
|
||||
register(FirProvider::class, provider)
|
||||
@@ -107,8 +103,8 @@ internal object FirIdeSessionFactory {
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
val dependentProviders = buildList {
|
||||
add(
|
||||
createLibrarySession(
|
||||
moduleInfo,
|
||||
createModuleLibrariesSession(
|
||||
module,
|
||||
project,
|
||||
builtinsAndCloneableSession,
|
||||
builtinTypes,
|
||||
@@ -121,7 +117,6 @@ internal object FirIdeSessionFactory {
|
||||
.mapTo(this) {
|
||||
createSourcesSession(
|
||||
project,
|
||||
configurator,
|
||||
it,
|
||||
builtinsAndCloneableSession,
|
||||
firPhaseRunner,
|
||||
@@ -129,7 +124,7 @@ internal object FirIdeSessionFactory {
|
||||
builtinTypes,
|
||||
sessionsCache,
|
||||
isRootModule = false,
|
||||
librariesCache,
|
||||
librariesCache = librariesCache,
|
||||
configureSession = configureSession,
|
||||
).symbolProvider
|
||||
}
|
||||
@@ -143,7 +138,7 @@ internal object FirIdeSessionFactory {
|
||||
this,
|
||||
providers = listOf(
|
||||
provider.symbolProvider,
|
||||
JavaSymbolProvider(this, moduleData, project.createJavaClassFinder(searchScope)),
|
||||
JavaSymbolProvider(this, moduleData, project.createJavaClassFinder(contentScope)),
|
||||
),
|
||||
dependencyProvider
|
||||
)
|
||||
@@ -159,23 +154,22 @@ internal object FirIdeSessionFactory {
|
||||
}
|
||||
}.configure()
|
||||
configureSession?.invoke(this)
|
||||
project.stateConfigurator.configureSourceSession(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun createLibrarySession(
|
||||
mainModuleInfo: ModuleSourceInfoBase,
|
||||
private fun createModuleLibrariesSession(
|
||||
sourceModule: KtSourceModule,
|
||||
project: Project,
|
||||
builtinsAndCloneableSession: FirIdeBuiltinsAndCloneableSession,
|
||||
builtinTypes: BuiltinTypes,
|
||||
librariesCache: LibrariesCache,
|
||||
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
||||
configureSession: (FirIdeSession.() -> Unit)?,
|
||||
): FirIdeLibrariesSession = librariesCache.cached(mainModuleInfo) {
|
||||
): FirIdeLibrariesSession = librariesCache.cached(sourceModule) {
|
||||
checkCanceled()
|
||||
val searchScope = project.stateConfigurator.createScopeForModuleLibraries(mainModuleInfo)
|
||||
FirIdeLibrariesSession(project, searchScope, builtinTypes).apply session@{
|
||||
registerModuleData(FirModuleInfoBasedModuleData(mainModuleInfo).apply { bindSession(this@session) })
|
||||
val searchScope = project.moduleScopeProvider.getModuleLibrariesScope(sourceModule)
|
||||
FirIdeLibrariesSession(project, builtinTypes).apply session@{
|
||||
registerModuleData(KtModuleBasedModuleData(sourceModule).apply { bindSession(this@session) })
|
||||
registerIdeComponents(project)
|
||||
register(FirPhaseManager::class, FirPhaseCheckingPhaseManager)
|
||||
registerCommonComponents(languageVersionSettings)
|
||||
@@ -184,11 +178,9 @@ internal object FirIdeSessionFactory {
|
||||
|
||||
val kotlinSymbolProvider = KotlinDeserializedJvmSymbolsProvider(
|
||||
this@session,
|
||||
moduleDataProvider = project.stateConfigurator.createModuleDataProvider(mainModuleInfo).apply {
|
||||
allModuleData.forEach { it.bindSession(this@session) }
|
||||
},
|
||||
moduleDataProvider = createModuleDataProvider(sourceModule, this),
|
||||
kotlinScopeProvider = FirKotlinScopeProvider(::wrapScopeWithJvmMapped),
|
||||
packagePartProvider = project.stateConfigurator.createPackagePartsProvider(mainModuleInfo, searchScope),
|
||||
packagePartProvider = project.createPackagePartProviderForLibrary(searchScope),
|
||||
kotlinClassFinder = VirtualFileFinderFactory.getInstance(project).create(searchScope),
|
||||
javaClassFinder = project.createJavaClassFinder(searchScope)
|
||||
)
|
||||
@@ -200,6 +192,21 @@ internal object FirIdeSessionFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private fun createModuleDataProvider(sourceModule: KtSourceModule, session: FirIdeSession): ModuleDataProvider {
|
||||
val dependencyList = DependencyListForCliModule.build(
|
||||
Name.special("<${sourceModule.moduleDescription}>"),
|
||||
sourceModule.platform,
|
||||
sourceModule.analyzerServices
|
||||
) {
|
||||
dependencies(sourceModule.directRegularDependencies.extractLibraryPaths())
|
||||
friendDependencies(sourceModule.directFriendDependencies.extractLibraryPaths())
|
||||
dependsOnDependencies(sourceModule.directRefinementDependencies.extractLibraryPaths())
|
||||
}
|
||||
return dependencyList.moduleDataProvider.apply {
|
||||
allModuleData.forEach { it.bindSession(session) }
|
||||
}
|
||||
}
|
||||
|
||||
fun createBuiltinsAndCloneableSession(
|
||||
project: Project,
|
||||
builtinTypes: BuiltinTypes,
|
||||
@@ -240,10 +247,16 @@ internal object FirIdeSessionFactory {
|
||||
private fun FirIdeSession.registerIdeComponents(project: Project) {
|
||||
register(IdeSessionComponents::class, IdeSessionComponents.create(this))
|
||||
register(FirCachesFactory::class, FirThreadSafeCachesFactory)
|
||||
register(SealedClassInheritorsProvider::class, project.stateConfigurator.createSealedInheritorsProvider())
|
||||
register(SealedClassInheritorsProvider::class, project.createSealedInheritorsProvider())
|
||||
}
|
||||
}
|
||||
|
||||
private fun List<KtModule>.extractLibraryPaths(): List<Path> =
|
||||
asSequence()
|
||||
.filterIsInstance<KtBinaryModule>()
|
||||
.flatMap { it.getBinaryRoots() }
|
||||
.toList()
|
||||
|
||||
@Deprecated(
|
||||
"This is a dirty hack used only for one usage (building fir for psi from stubs) and it should be removed after fix of that usage",
|
||||
level = DeprecationLevel.ERROR
|
||||
|
||||
+10
-10
@@ -6,26 +6,26 @@
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.annotations.Immutable
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
|
||||
import org.jetbrains.kotlin.fir.FirModuleData
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.FirSessionProvider
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.annotations.Immutable
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache
|
||||
|
||||
@Immutable
|
||||
class FirIdeSessionProvider internal constructor(
|
||||
val project: Project,
|
||||
internal val rootModuleSession: FirIdeSourcesSession,
|
||||
val sessions: Map<ModuleSourceInfoBase, FirIdeSession>
|
||||
val sessions: Map<KtSourceModule, FirIdeSession>
|
||||
) : FirSessionProvider() {
|
||||
override fun getSession(moduleData: FirModuleData): FirSession? =
|
||||
sessions[moduleData.moduleSourceInfo]
|
||||
sessions[moduleData.module]
|
||||
|
||||
fun getSession(moduleInfo: ModuleInfo): FirSession? =
|
||||
sessions[moduleInfo]
|
||||
fun getSession(module: KtModule): FirSession? =
|
||||
sessions[module]
|
||||
|
||||
internal fun getModuleCache(moduleSourceInfo: ModuleSourceInfoBase): ModuleFileCache =
|
||||
(sessions.getValue(moduleSourceInfo) as FirIdeSourcesSession).cache
|
||||
internal fun getModuleCache(module: KtSourceModule): ModuleFileCache =
|
||||
(sessions.getValue(module) as FirIdeSourcesSession).cache
|
||||
}
|
||||
|
||||
+18
-24
@@ -5,34 +5,30 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import kotlinx.collections.immutable.PersistentMap
|
||||
import kotlinx.collections.immutable.persistentMapOf
|
||||
import kotlinx.collections.immutable.toPersistentMap
|
||||
import org.jetbrains.kotlin.analysis.providers.createLibrariesModificationTracker
|
||||
import org.jetbrains.kotlin.analysis.providers.createModuleWithoutDependenciesOutOfBlockModificationTracker
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
|
||||
import org.jetbrains.kotlin.fir.BuiltinTypes
|
||||
import org.jetbrains.kotlin.fir.FirModuleData
|
||||
import org.jetbrains.kotlin.fir.moduleData
|
||||
import org.jetbrains.kotlin.fir.session.FirModuleInfoBasedModuleData
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirModuleResolveStateConfigurator
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.FirPhaseRunner
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.addValueFor
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.*
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.executeWithoutPCE
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
class FirIdeSessionProviderStorage(val project: Project) {
|
||||
private val sessionsCache = ConcurrentHashMap<ModuleSourceInfoBase, FromModuleViewSessionCache>()
|
||||
private val configurator = ServiceManager.getService(project, FirModuleResolveStateConfigurator::class.java)
|
||||
private val sessionsCache = ConcurrentHashMap<KtSourceModule, FromModuleViewSessionCache>()
|
||||
|
||||
private val librariesCache by cachedValue(project, project.createLibrariesModificationTracker()) { LibrariesCache() }
|
||||
|
||||
fun getSessionProvider(
|
||||
rootModule: ModuleSourceInfoBase,
|
||||
rootModule: KtSourceModule,
|
||||
configureSession: (FirIdeSession.() -> Unit)? = null
|
||||
): FirIdeSessionProvider {
|
||||
val firPhaseRunner = FirPhaseRunner()
|
||||
@@ -41,11 +37,10 @@ class FirIdeSessionProviderStorage(val project: Project) {
|
||||
val builtinsAndCloneableSession = FirIdeSessionFactory.createBuiltinsAndCloneableSession(project, builtinTypes)
|
||||
val cache = sessionsCache.getOrPut(rootModule) { FromModuleViewSessionCache(rootModule) }
|
||||
val (sessions, session) = cache.withMappings(project) { mappings ->
|
||||
val sessions = mutableMapOf<ModuleSourceInfoBase, FirIdeSourcesSession>().apply { putAll(mappings) }
|
||||
val sessions = mutableMapOf<KtSourceModule, FirIdeSourcesSession>().apply { putAll(mappings) }
|
||||
val session = executeWithoutPCE {
|
||||
FirIdeSessionFactory.createSourcesSession(
|
||||
project,
|
||||
configurator,
|
||||
rootModule,
|
||||
builtinsAndCloneableSession,
|
||||
firPhaseRunner,
|
||||
@@ -53,7 +48,7 @@ class FirIdeSessionProviderStorage(val project: Project) {
|
||||
builtinTypes,
|
||||
sessions,
|
||||
isRootModule = true,
|
||||
librariesCache,
|
||||
librariesCache = librariesCache,
|
||||
configureSession = configureSession,
|
||||
)
|
||||
}
|
||||
@@ -65,32 +60,32 @@ class FirIdeSessionProviderStorage(val project: Project) {
|
||||
}
|
||||
|
||||
private class FromModuleViewSessionCache(
|
||||
val root: ModuleSourceInfoBase,
|
||||
val root: KtSourceModule,
|
||||
) {
|
||||
@Volatile
|
||||
private var mappings: PersistentMap<ModuleSourceInfoBase, FirSessionWithModificationTracker> = persistentMapOf()
|
||||
private var mappings: PersistentMap<KtSourceModule, FirSessionWithModificationTracker> = persistentMapOf()
|
||||
|
||||
val sessionInvalidator: FirSessionInvalidator = FirSessionInvalidator { session ->
|
||||
mappings[session.moduleData.moduleSourceInfo]?.invalidate()
|
||||
mappings[session.moduleData.module]?.invalidate()
|
||||
}
|
||||
|
||||
|
||||
inline fun <R> withMappings(
|
||||
project: Project,
|
||||
action: (Map<ModuleSourceInfoBase, FirIdeSourcesSession>) -> Pair<Map<ModuleSourceInfoBase, FirIdeSourcesSession>, R>
|
||||
): Pair<Map<ModuleSourceInfoBase, FirIdeSourcesSession>, R> {
|
||||
action: (Map<KtSourceModule, FirIdeSourcesSession>) -> Pair<Map<KtSourceModule, FirIdeSourcesSession>, R>
|
||||
): Pair<Map<KtSourceModule, FirIdeSourcesSession>, R> {
|
||||
val (newMappings, result) = action(getSessions().mapValues { it.value })
|
||||
mappings = newMappings.mapValues { FirSessionWithModificationTracker(project, it.value) }.toPersistentMap()
|
||||
return newMappings to result
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
private fun getSessions(): Map<ModuleSourceInfoBase, FirIdeSourcesSession> = buildMap {
|
||||
private fun getSessions(): Map<KtSourceModule, FirIdeSourcesSession> = buildMap {
|
||||
val sessions = mappings.values
|
||||
val wasSessionInvalidated = sessions.associateWithTo(hashMapOf()) { false }
|
||||
|
||||
val reversedDependencies = sessions.reversedDependencies { session ->
|
||||
session.firSession.dependencies.mapNotNull { mappings[it] }
|
||||
session.firSession.module.directRegularDependencies.mapNotNull { mappings[it] }
|
||||
}
|
||||
|
||||
fun markAsInvalidWithDfs(session: FirSessionWithModificationTracker) {
|
||||
@@ -111,7 +106,7 @@ private class FromModuleViewSessionCache(
|
||||
}
|
||||
return wasSessionInvalidated.entries
|
||||
.mapNotNull { (session, wasInvalidated) -> session.takeUnless { wasInvalidated } }
|
||||
.associate { session -> session.firSession.moduleData.moduleSourceInfo to session.firSession }
|
||||
.associate { session -> session.firSession.moduleData.module to session.firSession }
|
||||
}
|
||||
|
||||
private fun <T> Collection<T>.reversedDependencies(getDependencies: (T) -> List<T>): Map<T, List<T>> {
|
||||
@@ -130,7 +125,7 @@ private class FirSessionWithModificationTracker(
|
||||
val firSession: FirIdeSourcesSession,
|
||||
) {
|
||||
private val modificationTracker =
|
||||
firSession.moduleData.moduleSourceInfo.createModuleWithoutDependenciesOutOfBlockModificationTracker(project)
|
||||
firSession.moduleData.module.createModuleWithoutDependenciesOutOfBlockModificationTracker(project)
|
||||
|
||||
private val timeStamp = modificationTracker.modificationCount
|
||||
|
||||
@@ -144,8 +139,7 @@ private class FirSessionWithModificationTracker(
|
||||
val isValid: Boolean get() = !isInvalidated && modificationTracker.modificationCount == timeStamp
|
||||
}
|
||||
|
||||
val FirModuleData.moduleSourceInfo: ModuleSourceInfoBase
|
||||
get() = moduleInfoUnsafe()
|
||||
internal val FirModuleData.module: KtSourceModule get() = moduleUnsafe()
|
||||
|
||||
inline fun <reified T : ModuleInfo> FirModuleData.moduleInfoUnsafe(): T = (this as FirModuleInfoBasedModuleData).moduleInfo as T
|
||||
inline fun <reified T : ModuleInfo> FirModuleData.moduleInfoSafe(): T? = (this as FirModuleInfoBasedModuleData).moduleInfo as? T
|
||||
internal inline fun <reified T : KtModule> FirModuleData.moduleUnsafe(): T = (this as KtModuleBasedModuleData).module as T
|
||||
internal inline fun <reified T : KtModule> FirModuleData.moduleInfoSafe(): T? = (this as KtModuleBasedModuleData).module as? T
|
||||
|
||||
+5
-5
@@ -7,17 +7,17 @@ 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.analyzer.ModuleSourceInfoBase
|
||||
import org.jetbrains.kotlin.fir.BuiltinTypes
|
||||
import org.jetbrains.kotlin.fir.PrivateSessionConstructor
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.FirFileBuilder
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.firIdeProvider
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
|
||||
import org.jetbrains.kotlin.fir.BuiltinTypes
|
||||
import org.jetbrains.kotlin.fir.PrivateSessionConstructor
|
||||
|
||||
@OptIn(PrivateSessionConstructor::class)
|
||||
internal class FirIdeSourcesSession @PrivateSessionConstructor constructor(
|
||||
val dependencies: List<ModuleSourceInfoBase>,
|
||||
override val module: KtSourceModule,
|
||||
override val project: Project,
|
||||
override val scope: GlobalSearchScope,
|
||||
val firFileBuilder: FirFileBuilder,
|
||||
builtinTypes: BuiltinTypes,
|
||||
) : FirIdeModuleSession(builtinTypes, Kind.Source) {
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.analysis.low.level.api.fir.sessions
|
||||
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.fir.FirModuleData
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||
|
||||
internal class KtModuleBasedModuleData(
|
||||
val module: KtModule,
|
||||
) : FirModuleData() {
|
||||
override val name: Name get() = Name.special("<${module.moduleDescription}>")
|
||||
|
||||
override val dependencies: List<FirModuleData> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
module.directRegularDependencies.map(::KtModuleBasedModuleData)
|
||||
}
|
||||
|
||||
override val dependsOnDependencies: List<FirModuleData> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
module.directRefinementDependencies.map(::KtModuleBasedModuleData)
|
||||
}
|
||||
|
||||
override val friendDependencies: List<FirModuleData> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
module.directRefinementDependencies.map(::KtModuleBasedModuleData)
|
||||
}
|
||||
|
||||
override val platform: TargetPlatform get() = module.platform
|
||||
|
||||
override val analyzerServices: PlatformDependentAnalyzerServices get() = module.analyzerServices
|
||||
}
|
||||
+8
-3
@@ -5,11 +5,16 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions
|
||||
|
||||
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
@JvmInline
|
||||
internal value class LibrariesCache(private val cache: ConcurrentHashMap<ModuleSourceInfoBase, FirIdeLibrariesSession> = ConcurrentHashMap()) {
|
||||
fun cached(moduleSourceInfo: ModuleSourceInfoBase, create: (ModuleSourceInfoBase) -> FirIdeLibrariesSession): FirIdeLibrariesSession =
|
||||
internal value class LibrariesCache(
|
||||
private val cache: ConcurrentHashMap<KtSourceModule, FirIdeLibrariesSession> = ConcurrentHashMap()
|
||||
) {
|
||||
fun cached(
|
||||
moduleSourceInfo: KtSourceModule,
|
||||
create: (KtSourceModule) -> FirIdeLibrariesSession
|
||||
): FirIdeLibrariesSession =
|
||||
cache.computeIfAbsent(moduleSourceInfo, create)
|
||||
}
|
||||
|
||||
-11
@@ -12,7 +12,6 @@ import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import com.intellij.psi.util.*
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.cfg.containingDeclarationForPseudocode
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
@@ -89,16 +88,6 @@ internal val FirDeclaration.containingKtFileIfAny: KtFile?
|
||||
get() = psi?.containingFile as? KtFile
|
||||
|
||||
|
||||
internal fun ModuleInfo.collectTransitiveDependenciesWithSelf(): List<ModuleInfo> {
|
||||
val result = mutableSetOf<ModuleInfo>()
|
||||
fun collect(module: ModuleInfo) {
|
||||
if (module in result) return
|
||||
result += module
|
||||
module.dependencies().forEach(::collect)
|
||||
}
|
||||
collect(this)
|
||||
return result.toList()
|
||||
}
|
||||
|
||||
internal fun KtDeclaration.isNonAnonymousClassOrObject() =
|
||||
this is KtClassOrObject
|
||||
|
||||
+120
-112
@@ -9,18 +9,28 @@ import com.intellij.mock.MockProject
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiElementFinder
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.search.ProjectScope
|
||||
import org.jetbrains.kotlin.analysis.api.InvalidWayOfUsingAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSessionProvider
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSessionProvider
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.FirIdeResolveStateService
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirSealedClassInheritorsProcessorFactory
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.PackagePartProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.createResolveStateForNoCaching
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.SealedClassInheritorsProviderTestImpl
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.FirLazyTransformerForIDE
|
||||
import org.jetbrains.kotlin.analysis.project.structure.*
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinModificationTrackerFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinModuleInfoProvider
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinPackageProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticDeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticModificationTrackerFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticPackageProviderFactory
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
|
||||
@@ -28,18 +38,7 @@ import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
||||
import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.DependencyListForCliModule
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider
|
||||
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
|
||||
import org.jetbrains.kotlin.fir.session.FirModuleInfoBasedModuleData
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.*
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.*
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.SealedClassInheritorsProviderTestImpl
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.FirLazyTransformerForIDE
|
||||
import org.jetbrains.kotlin.analysis.api.InvalidWayOfUsingAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSessionProvider
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSessionProvider
|
||||
import org.jetbrains.kotlin.light.classes.symbol.IDEKotlinAsJavaFirSupport
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -59,9 +58,13 @@ import org.jetbrains.kotlin.test.frontend.fir.getAnalyzerServices
|
||||
import org.jetbrains.kotlin.test.model.*
|
||||
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerTest
|
||||
import org.jetbrains.kotlin.test.services.*
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.TestInfo
|
||||
import java.io.File
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
|
||||
abstract class AbstractCompilerBasedTest : AbstractKotlinCompilerTest() {
|
||||
private var _disposable: Disposable? = null
|
||||
@@ -88,7 +91,7 @@ abstract class AbstractCompilerBasedTest : AbstractKotlinCompilerTest() {
|
||||
configureTest()
|
||||
defaultConfiguration(this)
|
||||
|
||||
useAdditionalService(::TestModuleInfoProvider)
|
||||
useAdditionalService(::TestKtModuleProvider)
|
||||
usePreAnalysisHandlers(::ModuleRegistrarPreAnalysisHandler.bind(disposable))
|
||||
}
|
||||
|
||||
@@ -103,8 +106,8 @@ abstract class AbstractCompilerBasedTest : AbstractKotlinCompilerTest() {
|
||||
get() = listOf(FirDiagnosticsDirectives)
|
||||
|
||||
override fun analyze(module: TestModule): FirOutputArtifact {
|
||||
val moduleInfoProvider = testServices.moduleInfoProvider
|
||||
val moduleInfo = moduleInfoProvider.getModuleInfo(module.name)
|
||||
val moduleInfoProvider = testServices.projectModuleProvider
|
||||
val moduleInfo = moduleInfoProvider.getModule(module.name)
|
||||
|
||||
val project = testServices.compilerConfigurationProvider.getProject(module)
|
||||
val resolveState = createResolveStateForNoCaching(moduleInfo, project)
|
||||
@@ -148,30 +151,32 @@ abstract class AbstractCompilerBasedTest : AbstractKotlinCompilerTest() {
|
||||
}
|
||||
|
||||
|
||||
class TestModuleInfoProvider(private val testServices: TestServices) : TestService {
|
||||
private val cache = mutableMapOf<String, TestModuleSourceInfo>()
|
||||
class TestProjectModuleProvider(
|
||||
private val testServices: TestServices
|
||||
) : TestService {
|
||||
private val cache = mutableMapOf<String, TestSourceProjectModule>()
|
||||
|
||||
fun registerModuleInfo(testModule: TestModule, ktFiles: Map<TestFile, KtFile>) {
|
||||
cache[testModule.name] = TestModuleSourceInfo(testModule, ktFiles, testServices)
|
||||
fun registerModuleInfo(project: Project, testModule: TestModule, ktFiles: Map<TestFile, KtFile>) {
|
||||
cache[testModule.name] = TestSourceProjectModule(project, testModule, ktFiles, testServices)
|
||||
}
|
||||
|
||||
fun getModuleInfoByKtFile(ktFile: KtFile): TestModuleSourceInfo =
|
||||
fun getModuleInfoByKtFile(ktFile: KtFile): TestSourceProjectModule =
|
||||
cache.values.first { moduleSourceInfo ->
|
||||
ktFile in moduleSourceInfo.ktFiles
|
||||
}
|
||||
|
||||
fun getModuleInfo(moduleName: String): TestModuleSourceInfo =
|
||||
fun getModule(moduleName: String): TestSourceProjectModule =
|
||||
cache.getValue(moduleName)
|
||||
}
|
||||
|
||||
val TestServices.moduleInfoProvider: TestModuleInfoProvider by TestServices.testServiceAccessor()
|
||||
val TestServices.projectModuleProvider: TestProjectModuleProvider by TestServices.testServiceAccessor()
|
||||
|
||||
class ModuleRegistrarPreAnalysisHandler(
|
||||
testServices: TestServices,
|
||||
private val parentDisposable: Disposable
|
||||
) : PreAnalysisHandler(testServices) {
|
||||
|
||||
private val moduleInfoProvider = testServices.moduleInfoProvider
|
||||
private val moduleInfoProvider = testServices.projectModuleProvider
|
||||
|
||||
override fun preprocessModuleStructure(moduleStructure: TestModuleStructure) {
|
||||
// todo rework after all modules will have the same Project instance
|
||||
@@ -184,42 +189,65 @@ class ModuleRegistrarPreAnalysisHandler(
|
||||
|
||||
ktFilesByModule.forEach { (testModule, ktFiles) ->
|
||||
val project = testServices.compilerConfigurationProvider.getProject(testModule)
|
||||
moduleInfoProvider.registerModuleInfo(testModule, ktFiles)
|
||||
|
||||
val configurator = FirModuleResolveStateConfiguratorForSingleModuleTestImpl(
|
||||
project,
|
||||
testServices,
|
||||
parentDisposable
|
||||
)
|
||||
(project as MockProject).registerTestServices(configurator, allKtFiles, testServices)
|
||||
moduleInfoProvider.registerModuleInfo(project, testModule, ktFiles)
|
||||
(project as MockProject).registerTestServices(testModule, allKtFiles, testServices)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TestModuleSourceInfo(
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
class TestSourceProjectModule(
|
||||
private val project: Project,
|
||||
val testModule: TestModule,
|
||||
val testFilesToKtFiles: Map<TestFile, KtFile>,
|
||||
testServices: TestServices,
|
||||
) : ModuleInfo, ModuleSourceInfoBase {
|
||||
private val moduleInfoProvider = testServices.moduleInfoProvider
|
||||
) : SourceProjectModule {
|
||||
private val moduleProvider = testServices.projectModuleProvider
|
||||
private val compilerConfigurationProvider = testServices.compilerConfigurationProvider
|
||||
private val configuration = compilerConfigurationProvider.getCompilerConfiguration(testModule)
|
||||
|
||||
|
||||
val ktFiles = testFilesToKtFiles.values.toSet()
|
||||
val moduleData = FirModuleInfoBasedModuleData(this)
|
||||
|
||||
override val name: Name
|
||||
get() = Name.identifier(testModule.name)
|
||||
override val name: Name get() = Name.identifier(testModule.name)
|
||||
|
||||
override fun dependencies(): List<ModuleInfo> =
|
||||
testModule.allDependencies
|
||||
.map { moduleInfoProvider.getModuleInfo(it.moduleName) }
|
||||
override val regularDependencies: List<ProjectModule> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
buildList {
|
||||
testModule.allDependencies.mapTo(this) { moduleProvider.getModule(it.moduleName) }
|
||||
addIfNotNull(
|
||||
libraryByRoots(
|
||||
(configuration.jvmModularRoots + configuration.jvmClasspathRoots).map(File::toPath)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
override val dependsOnDependencies: List<ProjectModule> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
testModule.dependsOnDependencies
|
||||
.map { moduleProvider.getModule(it.moduleName) }
|
||||
}
|
||||
override val friendDependencies: List<ProjectModule> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
buildList {
|
||||
testModule.friendDependencies.mapTo(this) { moduleProvider.getModule(it.moduleName) }
|
||||
addIfNotNull(
|
||||
libraryByRoots(configuration[JVMConfigurationKeys.FRIEND_PATHS].orEmpty().map(Paths::get))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override val expectedBy: List<ModuleInfo>
|
||||
get() = testModule.dependsOnDependencies
|
||||
.map { moduleInfoProvider.getModuleInfo(it.moduleName) }
|
||||
private fun libraryByRoots(roots: List<Path>): LibraryByRoots? {
|
||||
if (roots.isEmpty()) return null
|
||||
return LibraryByRoots(
|
||||
roots,
|
||||
this@TestSourceProjectModule,
|
||||
project
|
||||
)
|
||||
}
|
||||
|
||||
override fun modulesWhoseInternalsAreVisible(): Collection<ModuleInfo> =
|
||||
testModule.friendDependencies
|
||||
.map { moduleInfoProvider.getModuleInfo(it.moduleName) }
|
||||
override val searchScope: GlobalSearchScope =
|
||||
TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, testFilesToKtFiles.values)
|
||||
|
||||
override val languageVersionSettings: LanguageVersionSettings
|
||||
get() = testModule.languageVersionSettings
|
||||
|
||||
override val platform: TargetPlatform
|
||||
get() = testModule.targetPlatform
|
||||
@@ -228,72 +256,53 @@ class TestModuleSourceInfo(
|
||||
get() = testModule.targetPlatform.getAnalyzerServices()
|
||||
}
|
||||
|
||||
|
||||
class FirModuleResolveStateConfiguratorForSingleModuleTestImpl(
|
||||
private class LibraryByRoots(
|
||||
private val roots: List<Path>,
|
||||
private val sourceModule: SourceProjectModule,
|
||||
private val project: Project,
|
||||
testServices: TestServices,
|
||||
private val parentDisposable: Disposable,
|
||||
) : FirModuleResolveStateConfigurator() {
|
||||
private val compilerConfigurationProvider = testServices.compilerConfigurationProvider
|
||||
private val librariesScope = ProjectScope.getLibrariesScope(project)//todo incorrect?
|
||||
private val sealedClassInheritorsProvider = SealedClassInheritorsProviderTestImpl()
|
||||
|
||||
override fun createPackagePartsProvider(moduleInfo: ModuleSourceInfoBase, scope: GlobalSearchScope): PackagePartProvider {
|
||||
require(moduleInfo is TestModuleSourceInfo)
|
||||
val factory = compilerConfigurationProvider.getPackagePartProviderFactory(moduleInfo.testModule)
|
||||
return factory(scope)
|
||||
}
|
||||
|
||||
|
||||
override fun createModuleDataProvider(moduleInfo: ModuleSourceInfoBase): ModuleDataProvider {
|
||||
require(moduleInfo is TestModuleSourceInfo)
|
||||
val configuration = compilerConfigurationProvider.getCompilerConfiguration(moduleInfo.testModule)
|
||||
return DependencyListForCliModule.build(
|
||||
moduleInfo.name,
|
||||
moduleInfo.platform,
|
||||
moduleInfo.analyzerServices
|
||||
) {
|
||||
dependencies(configuration.jvmModularRoots.map { it.toPath() })
|
||||
dependencies(configuration.jvmClasspathRoots.map { it.toPath() })
|
||||
|
||||
friendDependencies(configuration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
|
||||
|
||||
sourceDependencies(moduleInfo.moduleData.dependencies)
|
||||
sourceFriendsDependencies(moduleInfo.moduleData.friendDependencies)
|
||||
sourceDependsOnDependencies(moduleInfo.moduleData.dependsOnDependencies)
|
||||
}.moduleDataProvider
|
||||
}
|
||||
|
||||
override fun getLanguageVersionSettings(moduleInfo: ModuleSourceInfoBase): LanguageVersionSettings {
|
||||
require(moduleInfo is TestModuleSourceInfo)
|
||||
return moduleInfo.testModule.languageVersionSettings
|
||||
}
|
||||
|
||||
override fun getModuleSourceScope(moduleInfo: ModuleSourceInfoBase): GlobalSearchScope {
|
||||
require(moduleInfo is TestModuleSourceInfo)
|
||||
return TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, moduleInfo.testFilesToKtFiles.values)
|
||||
}
|
||||
|
||||
override fun createScopeForModuleLibraries(moduleInfo: ModuleSourceInfoBase): GlobalSearchScope {
|
||||
return librariesScope
|
||||
}
|
||||
|
||||
override fun createSealedInheritorsProvider(): SealedClassInheritorsProvider {
|
||||
return sealedClassInheritorsProvider
|
||||
}
|
||||
|
||||
override fun configureSourceSession(session: FirSession) {
|
||||
}
|
||||
) : LibraryProjectModule {
|
||||
override val name: Name get() = Name.special("<Libraries>")
|
||||
override val regularDependencies: List<ProjectModule> get() = emptyList()
|
||||
override val dependsOnDependencies: List<ProjectModule> get() = emptyList()
|
||||
override val friendDependencies: List<ProjectModule> get() = emptyList()
|
||||
override val searchScope: GlobalSearchScope get() = ProjectScope.getLibrariesScope(project)
|
||||
override val platform: TargetPlatform get() = sourceModule.platform
|
||||
override val analyzerServices: PlatformDependentAnalyzerServices get() = sourceModule.analyzerServices
|
||||
override fun getBinaryRoots(): Collection<Path> = roots
|
||||
}
|
||||
|
||||
fun MockProject.registerTestServices(
|
||||
configurator: FirModuleResolveStateConfiguratorForSingleModuleTestImpl,
|
||||
testModule: TestModule,
|
||||
allKtFiles: List<KtFile>,
|
||||
testServices: TestServices,
|
||||
) {
|
||||
registerService(
|
||||
FirModuleResolveStateConfigurator::class.java,
|
||||
configurator
|
||||
PackagePartProviderFactory::class.java,
|
||||
object : PackagePartProviderFactory() {
|
||||
override fun createPackagePartProvider(scope: GlobalSearchScope): PackagePartProvider {
|
||||
val factory = testServices.compilerConfigurationProvider.getPackagePartProviderFactory(testModule)
|
||||
return factory(scope)
|
||||
}
|
||||
}
|
||||
)
|
||||
registerService(
|
||||
FirSealedClassInheritorsProcessorFactory::class.java,
|
||||
object : FirSealedClassInheritorsProcessorFactory() {
|
||||
override fun createSealedClassInheritorsProvider(): SealedClassInheritorsProvider {
|
||||
return SealedClassInheritorsProviderTestImpl()
|
||||
}
|
||||
}
|
||||
)
|
||||
registerService(
|
||||
ProjectModuleScopeProvider::class.java,
|
||||
object : ProjectModuleScopeProvider() {
|
||||
override fun getModuleLibrariesScope(sourceModule: SourceProjectModule): GlobalSearchScope {
|
||||
val libraries = sourceModule.dependenciesOfType<BinaryProjectModule>()
|
||||
val scopes = libraries.map { it.searchScope }.toList()
|
||||
if (scopes.isEmpty()) return GlobalSearchScope.EMPTY_SCOPE
|
||||
return GlobalSearchScope.union(scopes)
|
||||
}
|
||||
}
|
||||
)
|
||||
registerService(FirIdeResolveStateService::class.java)
|
||||
registerService(
|
||||
@@ -302,17 +311,16 @@ fun MockProject.registerTestServices(
|
||||
)
|
||||
registerService(KotlinDeclarationProviderFactory::class.java, KotlinStaticDeclarationProviderFactory(allKtFiles))
|
||||
registerService(KotlinPackageProviderFactory::class.java, KotlinStaticPackageProviderFactory(allKtFiles))
|
||||
registerService(KotlinModuleInfoProvider::class.java, TestKotlinModuleInfoProvider(testServices))
|
||||
registerService(ProjectStructureProvider::class.java, TestKotlinProjectStructureProvider(testServices))
|
||||
reRegisterJavaElementFinder(this)
|
||||
}
|
||||
|
||||
private class TestKotlinModuleInfoProvider(testServices: TestServices): KotlinModuleInfoProvider() {
|
||||
private val moduleInfoProvider = testServices.moduleInfoProvider
|
||||
override fun getModuleInfo(element: KtElement): ModuleInfo {
|
||||
val containingFile = element.containingKtFile
|
||||
private class TestKotlinProjectStructureProvider(testServices: TestServices) : ProjectStructureProvider() {
|
||||
private val moduleInfoProvider = testServices.projectModuleProvider
|
||||
override fun getProjectModuleForKtElement(element: PsiElement): ProjectModule {
|
||||
val containingFile = element.containingFile as KtFile
|
||||
return moduleInfoProvider.getModuleInfoByKtFile(containingFile)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@OptIn(InvalidWayOfUsingAnalysisSession::class)
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.analysis.low.level.api.fir.compiler.based
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.model.TestFile
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestService
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
class TestKtModuleProvider(
|
||||
private val testServices: TestServices
|
||||
) : TestService {
|
||||
private val cache = mutableMapOf<String, TestKtSourceModule>()
|
||||
|
||||
fun registerModuleInfo(project: Project, testModule: TestModule, ktFiles: Map<TestFile, KtFile>) {
|
||||
cache[testModule.name] = TestKtSourceModule(project, testModule, ktFiles, testServices)
|
||||
}
|
||||
|
||||
internal fun getModuleInfoByKtFile(ktFile: KtFile): TestKtSourceModule =
|
||||
cache.values.first { moduleSourceInfo ->
|
||||
ktFile in moduleSourceInfo.ktFiles
|
||||
}
|
||||
|
||||
internal fun getModule(moduleName: String): TestKtSourceModule =
|
||||
cache.getValue(moduleName)
|
||||
}
|
||||
|
||||
val TestServices.projectModuleProvider: TestKtModuleProvider by TestServices.testServiceAccessor()
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.analysis.low.level.api.fir.compiler.based
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.search.ProjectScope
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtLibrarySourceModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
|
||||
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
||||
import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||
import org.jetbrains.kotlin.test.frontend.fir.getAnalyzerServices
|
||||
import org.jetbrains.kotlin.test.model.TestFile
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import java.io.File
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
internal class TestKtSourceModule(
|
||||
override val project: Project,
|
||||
val testModule: TestModule,
|
||||
val testFilesToKtFiles: Map<TestFile, KtFile>,
|
||||
testServices: TestServices,
|
||||
) : KtSourceModule {
|
||||
private val moduleProvider = testServices.projectModuleProvider
|
||||
private val compilerConfigurationProvider = testServices.compilerConfigurationProvider
|
||||
private val configuration = compilerConfigurationProvider.getCompilerConfiguration(testModule)
|
||||
|
||||
val ktFiles = testFilesToKtFiles.values.toSet()
|
||||
|
||||
override val moduleName: String
|
||||
get() = testModule.name
|
||||
|
||||
override val directRegularDependencies: List<KtModule> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
buildList {
|
||||
testModule.allDependencies.mapTo(this) { moduleProvider.getModule(it.moduleName) }
|
||||
addIfNotNull(
|
||||
libraryByRoots(
|
||||
(configuration.jvmModularRoots + configuration.jvmClasspathRoots).map(File::toPath)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
override val directRefinementDependencies: List<KtModule> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
testModule.dependsOnDependencies
|
||||
.map { moduleProvider.getModule(it.moduleName) }
|
||||
}
|
||||
override val directFriendDependencies: List<KtModule> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
buildList {
|
||||
testModule.friendDependencies.mapTo(this) { moduleProvider.getModule(it.moduleName) }
|
||||
addIfNotNull(
|
||||
libraryByRoots(configuration[JVMConfigurationKeys.FRIEND_PATHS].orEmpty().map(Paths::get))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun libraryByRoots(roots: List<Path>): LibraryByRoots? {
|
||||
if (roots.isEmpty()) return null
|
||||
return LibraryByRoots(
|
||||
roots,
|
||||
this@TestKtSourceModule,
|
||||
project,
|
||||
)
|
||||
}
|
||||
|
||||
override val contentScope: GlobalSearchScope =
|
||||
TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, testFilesToKtFiles.values)
|
||||
|
||||
override val languageVersionSettings: LanguageVersionSettings
|
||||
get() = testModule.languageVersionSettings
|
||||
|
||||
override val platform: TargetPlatform
|
||||
get() = testModule.targetPlatform
|
||||
|
||||
override val analyzerServices: PlatformDependentAnalyzerServices
|
||||
get() = testModule.targetPlatform.getAnalyzerServices()
|
||||
}
|
||||
|
||||
private class LibraryByRoots(
|
||||
private val roots: List<Path>,
|
||||
private val sourceModule: KtSourceModule,
|
||||
override val project: Project,
|
||||
) : KtLibraryModule {
|
||||
override val libraryName: String get() = "Test Library"
|
||||
override val directRegularDependencies: List<KtModule> get() = emptyList()
|
||||
override val directRefinementDependencies: List<KtModule> get() = emptyList()
|
||||
override val directFriendDependencies: List<KtModule> get() = emptyList()
|
||||
override val contentScope: GlobalSearchScope get() = ProjectScope.getLibrariesScope(project)
|
||||
override val platform: TargetPlatform get() = sourceModule.platform
|
||||
override val analyzerServices: PlatformDependentAnalyzerServices get() = sourceModule.analyzerServices
|
||||
override fun getBinaryRoots(): Collection<Path> = roots
|
||||
override val librarySources: KtLibrarySourceModule? get() = null
|
||||
}
|
||||
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.analysis.low.level.api.fir.compiler.based
|
||||
|
||||
import com.intellij.mock.MockProject
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiElementFinder
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analysis.api.InvalidWayOfUsingAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSessionProvider
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSessionProvider
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.FirIdeResolveStateService
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.FirSealedClassInheritorsProcessorFactory
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.PackagePartProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.SealedClassInheritorsProviderTestImpl
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModuleScopeProvider
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModuleScopeProviderImpl
|
||||
import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinModificationTrackerFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinPackageProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticDeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticModificationTrackerFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticPackageProviderFactory
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider
|
||||
import org.jetbrains.kotlin.light.classes.symbol.IDEKotlinAsJavaFirSupport
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
|
||||
|
||||
fun MockProject.registerTestServices(
|
||||
testModule: TestModule,
|
||||
allKtFiles: List<KtFile>,
|
||||
testServices: TestServices,
|
||||
) {
|
||||
registerService(
|
||||
PackagePartProviderFactory::class.java,
|
||||
TestPackagePartProvider(testServices, testModule)
|
||||
)
|
||||
registerService(
|
||||
FirSealedClassInheritorsProcessorFactory::class.java,
|
||||
TestFirSealedClassInheritorsProcessorFactory()
|
||||
)
|
||||
registerService(KtModuleScopeProvider::class.java, KtModuleScopeProviderImpl())
|
||||
registerService(FirIdeResolveStateService::class.java)
|
||||
registerService(
|
||||
KotlinModificationTrackerFactory::class.java,
|
||||
KotlinStaticModificationTrackerFactory::class.java
|
||||
)
|
||||
registerService(KotlinDeclarationProviderFactory::class.java, KotlinStaticDeclarationProviderFactory(allKtFiles))
|
||||
registerService(KotlinPackageProviderFactory::class.java, KotlinStaticPackageProviderFactory(allKtFiles))
|
||||
registerService(ProjectStructureProvider::class.java, TestKotlinProjectStructureProvider(testServices))
|
||||
reRegisterJavaElementFinder(this)
|
||||
}
|
||||
|
||||
class TestFirSealedClassInheritorsProcessorFactory : FirSealedClassInheritorsProcessorFactory() {
|
||||
override fun createSealedClassInheritorsProvider(): SealedClassInheritorsProvider {
|
||||
return SealedClassInheritorsProviderTestImpl()
|
||||
}
|
||||
}
|
||||
|
||||
private class TestPackagePartProvider(
|
||||
private val testServices: TestServices,
|
||||
private val testModule: TestModule
|
||||
) : PackagePartProviderFactory() {
|
||||
override fun createPackagePartProviderForLibrary(scope: GlobalSearchScope): PackagePartProvider {
|
||||
val factory = testServices.compilerConfigurationProvider.getPackagePartProviderFactory(testModule)
|
||||
return factory(scope)
|
||||
}
|
||||
}
|
||||
|
||||
private class TestKotlinProjectStructureProvider(testServices: TestServices) : ProjectStructureProvider() {
|
||||
private val moduleInfoProvider = testServices.projectModuleProvider
|
||||
override fun getKtModuleForKtElement(element: PsiElement): KtModule {
|
||||
val containingFile = element.containingFile as KtFile
|
||||
return moduleInfoProvider.getModuleInfoByKtFile(containingFile)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(InvalidWayOfUsingAnalysisSession::class)
|
||||
private fun reRegisterJavaElementFinder(project: Project) {
|
||||
PsiElementFinder.EP.getPoint(project).unregisterExtension(JavaElementFinder::class.java)
|
||||
with(project as MockProject) {
|
||||
picoContainer.registerComponentInstance(
|
||||
KtAnalysisSessionProvider::class.qualifiedName,
|
||||
KtFirAnalysisSessionProvider(this)
|
||||
)
|
||||
picoContainer.unregisterComponent(KotlinAsJavaSupport::class.qualifiedName)
|
||||
picoContainer.registerComponentInstance(
|
||||
KotlinAsJavaSupport::class.qualifiedName,
|
||||
IDEKotlinAsJavaFirSupport(project)
|
||||
)
|
||||
}
|
||||
@Suppress("DEPRECATION")
|
||||
PsiElementFinder.EP.getPoint(project).registerExtension(JavaElementFinder(project))
|
||||
}
|
||||
+3
-2
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir
|
||||
|
||||
import com.intellij.openapi.module.ModuleManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analysis.providers.getModuleInfo
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirRenderer
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
@@ -19,6 +18,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFileSymbol
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirModuleResolveState
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.FirIdeSession
|
||||
import org.jetbrains.kotlin.analysis.project.structure.getKtModule
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
|
||||
internal fun Project.allModules() = ModuleManager.getInstance(this).modules.toList()
|
||||
@@ -43,6 +43,7 @@ internal inline fun <R> resolveWithClearCaches(
|
||||
noinline configureSession: FirIdeSession.() -> Unit = {},
|
||||
action: (FirModuleResolveState) -> R,
|
||||
): R {
|
||||
val resolveState = createResolveStateForNoCaching(context.getModuleInfo(), context.project, configureSession)
|
||||
val project = context.project
|
||||
val resolveState = createResolveStateForNoCaching(context.getKtModule(project), project, configureSession)
|
||||
return action(resolveState)
|
||||
}
|
||||
|
||||
+5
-7
@@ -10,12 +10,10 @@ import com.intellij.mock.MockProject
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.testFramework.TestDataFile
|
||||
import com.intellij.testFramework.TestDataPath
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinModuleInfoProvider
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based.ModuleRegistrarPreAnalysisHandler
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based.TestModuleInfoProvider
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based.moduleInfoProvider
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based.TestKtModuleProvider
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based.projectModuleProvider
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.TestInfrastructureInternals
|
||||
@@ -59,7 +57,7 @@ abstract class AbstractLowLevelApiTest : TestWithDisposable() {
|
||||
|
||||
useSourcePreprocessor(::ExpressionMarkersSourceFilePreprocessor)
|
||||
useAdditionalService { ExpressionMarkerProvider() }
|
||||
useAdditionalService(::TestModuleInfoProvider)
|
||||
useAdditionalService(::TestKtModuleProvider)
|
||||
usePreAnalysisHandlers(::ModuleRegistrarPreAnalysisHandler.bind(disposable))
|
||||
configureTest(this)
|
||||
|
||||
@@ -94,9 +92,9 @@ abstract class AbstractLowLevelApiTest : TestWithDisposable() {
|
||||
|
||||
val singleModule = moduleStructure.modules.single()
|
||||
val project = testServices.compilerConfigurationProvider.getProject(singleModule)
|
||||
val moduleInfoProvider = testServices.moduleInfoProvider
|
||||
val moduleInfoProvider = testServices.projectModuleProvider
|
||||
|
||||
val moduleInfo = moduleInfoProvider.getModuleInfo(singleModule.name)
|
||||
val moduleInfo = moduleInfoProvider.getModule(singleModule.name)
|
||||
|
||||
with(project as MockProject) {
|
||||
registerServicesForProject(this)
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
id("jps-compatible")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":core:compiler.common"))
|
||||
implementation(project(":compiler:util"))
|
||||
implementation(project(":compiler:psi"))
|
||||
implementation(intellijCoreDep()) { includeJars("intellij-core", rootProject = rootProject) }
|
||||
}
|
||||
|
||||
kotlin {
|
||||
explicitApi()
|
||||
}
|
||||
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
|
||||
kotlinOptions.freeCompilerArgs += "-opt-in=kotlin.ExperimentalStdlibApi"
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
}
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.analysis.project.structure
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||
import java.nio.file.Path
|
||||
|
||||
/**
|
||||
* Represents a module inside a project.
|
||||
*
|
||||
* [KtModule] is a Source Set (or considering a new project model naming a Fragment).
|
||||
* Some examples of a module: main source set, test source set, library, JDK.
|
||||
*
|
||||
*/
|
||||
public sealed interface KtModule {
|
||||
/**
|
||||
* A list of Regular dependencies. Regular dependency allows current module to see symbols from dependent module.
|
||||
* In a case for a source set, it can be other source set it depends on, library, or SDK.
|
||||
*
|
||||
* The dependencies list is non-transitive and should not include current module.
|
||||
*/
|
||||
public val directRegularDependencies: List<KtModule>
|
||||
|
||||
/**
|
||||
* Only for Kotlin MPP project.
|
||||
* A list of Refinement dependencies.
|
||||
* Refinement dependency express that the current module can provide actual declarations for expect declarations from dependent module,
|
||||
* as well as see internal symbols of dependent module.
|
||||
*
|
||||
* The dependencies list is non-transitive and should not include current module.
|
||||
*/
|
||||
public val directRefinementDependencies: List<KtModule>
|
||||
|
||||
/**
|
||||
* A list of Friend dependencies. Friend dependencies express that current module may see internal symbols of dependent module.
|
||||
*
|
||||
* The dependencies list is non-transitive and should not include current module.
|
||||
*/
|
||||
public val directFriendDependencies: List<KtModule>
|
||||
|
||||
/**
|
||||
* A [GlobalSearchScope] which belongs to a module content.
|
||||
*
|
||||
* Contract: `module.contentScope.contains(file) <=> file belongs to this module`
|
||||
*/
|
||||
public val contentScope: GlobalSearchScope
|
||||
|
||||
/**
|
||||
* A platform (e.g, JVM, JS, Native) current module represents.
|
||||
*
|
||||
* @see [TargetPlatform]
|
||||
*/
|
||||
public val platform: TargetPlatform
|
||||
|
||||
public val analyzerServices: PlatformDependentAnalyzerServices
|
||||
|
||||
/**
|
||||
* [Project] to which module belongs.
|
||||
* If current module depends on some other modules, all those modules should have the same [Project] as the current one.
|
||||
*/
|
||||
public val project: Project?
|
||||
|
||||
/**
|
||||
* Human-readable description of the module. E.g, "main sources of module 'analysis-api'"
|
||||
*/
|
||||
public val moduleDescription: String
|
||||
}
|
||||
|
||||
public sealed interface KtModuleWithProject : KtModule {
|
||||
override val project: Project
|
||||
}
|
||||
|
||||
/**
|
||||
* A module which consists of a set of source declarations inside a projects.
|
||||
*
|
||||
* Generally, a main or test Source Set.
|
||||
*/
|
||||
public interface KtSourceModule : KtModule, KtModuleWithProject {
|
||||
public val moduleName: String
|
||||
|
||||
override val moduleDescription: String
|
||||
get() = "Sources of $moduleName"
|
||||
|
||||
/**
|
||||
* A set of Kotlin settings, like API version, supported features and flags.
|
||||
*/
|
||||
public val languageVersionSettings: LanguageVersionSettings
|
||||
}
|
||||
|
||||
/**
|
||||
* A module which consists of binary declarations.
|
||||
*/
|
||||
public sealed interface KtBinaryModule : KtModule, KtModuleWithProject {
|
||||
/**
|
||||
* A list of binary files which forms a binary module. It can be a list of JARs, KLIBs, folders with .class files.
|
||||
* Should be consistent with [contentScope],
|
||||
* so (pseudo-Kotlin) `
|
||||
* ```
|
||||
* library.contentScope.contains(file) <=> library.getBinaryRoots().listRecursively().contains(file)
|
||||
* ```
|
||||
*/
|
||||
public fun getBinaryRoots(): Collection<Path>
|
||||
}
|
||||
|
||||
/**
|
||||
* A module which represents a binary library. E.g, JAR o KLIB.
|
||||
*/
|
||||
public interface KtLibraryModule : KtBinaryModule {
|
||||
public val libraryName: String
|
||||
|
||||
/**
|
||||
* A library source, if any. If current module is a binary JAR, then [librarySources] corresponds to the sources JAR.
|
||||
*/
|
||||
public val librarySources: KtLibrarySourceModule?
|
||||
|
||||
override val moduleDescription: String
|
||||
get() = "Library $libraryName"
|
||||
}
|
||||
|
||||
/**
|
||||
* A module which represent some SDK. E.g, Java JDK.
|
||||
*/
|
||||
public interface KtSdkModule : KtBinaryModule {
|
||||
public val sdkName: String
|
||||
|
||||
override val moduleDescription: String
|
||||
get() = "SDK $sdkName"
|
||||
}
|
||||
|
||||
/**
|
||||
* A sources for some [KtLibraryModule]
|
||||
*/
|
||||
public interface KtLibrarySourceModule : KtModuleWithProject {
|
||||
public val libraryName: String
|
||||
|
||||
/**
|
||||
* A library binary corresponding to the current library source.
|
||||
* If current module is a source JAR, then [binaryLibrary] is corresponds to the binaries JAR.
|
||||
*/
|
||||
public val binaryLibrary: KtLibraryModule
|
||||
|
||||
override val moduleDescription: String
|
||||
get() = "Library sourced of $libraryName"
|
||||
}
|
||||
|
||||
/**
|
||||
* A set of sources which lives outside project content root. E.g, testdata files or source files of some other project.
|
||||
*/
|
||||
public interface KtNotUnderContentRootModule : KtModule {
|
||||
override val project: Project?
|
||||
get() = null
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.analysis.project.structure
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
|
||||
public abstract class KtModuleScopeProvider {
|
||||
/**
|
||||
* Get a scope of binaries on which current source module depends.
|
||||
* Should be equivalent to
|
||||
*
|
||||
* ```
|
||||
* GlobalSearchScope.union(
|
||||
* sourceModule.allDependenciesOfType<KtBinaryModule>()
|
||||
* .map { it.contentScope }
|
||||
* )
|
||||
* ```
|
||||
* For the IDE there can be more optimal implementations.
|
||||
*
|
||||
* See [KtModuleScopeProviderImpl] a correct but non-optimal implementation.
|
||||
*/
|
||||
public abstract fun getModuleLibrariesScope(sourceModule: KtSourceModule): GlobalSearchScope
|
||||
}
|
||||
|
||||
public class KtModuleScopeProviderImpl : KtModuleScopeProvider() {
|
||||
override fun getModuleLibrariesScope(sourceModule: KtSourceModule): GlobalSearchScope {
|
||||
val scopes = sourceModule.allDirectDependenciesOfType<KtBinaryModule>()
|
||||
.map { it.contentScope }
|
||||
.toList()
|
||||
if (scopes.isEmpty()) return GlobalSearchScope.EMPTY_SCOPE
|
||||
return GlobalSearchScope.union(scopes)
|
||||
}
|
||||
}
|
||||
|
||||
public val Project.moduleScopeProvider: KtModuleScopeProvider
|
||||
get() = ServiceManager.getService(this, KtModuleScopeProvider::class.java)
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.analysis.project.structure
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
|
||||
public abstract class ProjectStructureProvider {
|
||||
/**
|
||||
* For a given [PsiElement] get a [KtModule] to which [PsiElement] belongs.
|
||||
*/
|
||||
public abstract fun getKtModuleForKtElement(element: PsiElement): KtModule
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given [PsiElement] get a [KtModule] to which [PsiElement] belongs.
|
||||
* @param project [Project] which contains current [PsiElement]. `PsiElement.project` may be a heavy operation as it includes PSI tree traversal. So, when a [Project] is already available, it is better to pass it explicitly
|
||||
*/
|
||||
public fun PsiElement.getKtModule(project: Project = this.project): KtModule =
|
||||
project.getService(ProjectStructureProvider::class.java)
|
||||
.getKtModuleForKtElement(this)
|
||||
|
||||
/**
|
||||
* For a given [PsiElement] get a [KtModule] to which [PsiElement] belongs.
|
||||
* @return [KtModule] of type [M] if `result <: M`, [java.lang.ClassCastException] otherwise
|
||||
* @param project [Project] which contains current [PsiElement]. `PsiElement.project` may be a heavy operation as it includes PSI tree traversal. So, when a [Project] is already available, it is better to pass it explicitly
|
||||
*/
|
||||
public inline fun <reified M : KtModule> PsiElement.getKtModuleOfType(project: Project = this.project): M =
|
||||
getKtModule(project) as M
|
||||
|
||||
/**
|
||||
* For a given [PsiElement] get a [KtModule] to which [PsiElement] belongs.
|
||||
* @return [KtModule] of type [M] if `result <: M`, `null` otherwise
|
||||
* @param project [Project] which contains current [PsiElement]. `PsiElement.project` may be a heavy operation as it includes PSI tree traversal. So, when a [Project] is already available, it is better to pass it explicitly
|
||||
*/
|
||||
public inline fun <reified M : KtModule> PsiElement.getKtModuleOfTypeSafe(project: Project = this.project): M? =
|
||||
getKtModule(project) as M?
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.analysis.project.structure
|
||||
|
||||
/**
|
||||
* A list of all modules current module can depend onwith regular dependency
|
||||
*
|
||||
* @see KtModule.directRegularDependencies
|
||||
*/
|
||||
public inline fun <reified M : KtModule> KtModule.directRegularDependenciesOfType(): Sequence<M> =
|
||||
directRegularDependencies.asSequence().filterIsInstance<M>()
|
||||
|
||||
/**
|
||||
* A list of all other modules current module can depend on.
|
||||
*
|
||||
* @see KtModule.directRegularDependencies
|
||||
* @see KtModule.directRefinementDependencies
|
||||
* @see KtModule.directFriendDependencies
|
||||
*/
|
||||
public fun KtModule.allDirectDependencies(): Sequence<KtModule> =
|
||||
sequence {
|
||||
yieldAll(directRegularDependencies)
|
||||
yieldAll(directRefinementDependencies)
|
||||
yieldAll(directFriendDependencies)
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of all other modules of type [M] current module can depend on.
|
||||
*
|
||||
* @see KtModule.directRegularDependencies
|
||||
* @see KtModule.directRefinementDependencies
|
||||
* @see KtModule.directFriendDependencies
|
||||
*/
|
||||
public inline fun <reified M : KtModule> KtModule.allDirectDependenciesOfType(): Sequence<M> =
|
||||
allDirectDependencies().filterIsInstance<M>()
|
||||
@@ -10,6 +10,7 @@ dependencies {
|
||||
implementation(project(":compiler:light-classes"))
|
||||
implementation(project(":analysis:analysis-api-providers"))
|
||||
implementation(project(":analysis:analysis-api"))
|
||||
implementation(project(":analysis:project-structure"))
|
||||
implementation(intellijCoreDep()) { includeJars("intellij-core", rootProject = rootProject) }
|
||||
}
|
||||
|
||||
|
||||
+8
-7
@@ -8,11 +8,12 @@ package org.jetbrains.kotlin.light.classes.symbol
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtBinaryModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtLibrarySourceModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtNotUnderContentRootModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.getKtModule
|
||||
import org.jetbrains.kotlin.analysis.providers.createDeclarationProvider
|
||||
import org.jetbrains.kotlin.analysis.providers.createPackageProvider
|
||||
import org.jetbrains.kotlin.analysis.providers.getModuleInfo
|
||||
import org.jetbrains.kotlin.analyzer.LibraryModuleSourceInfoBase
|
||||
import org.jetbrains.kotlin.analyzer.NonSourceModuleInfoBase
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.asJava.classes.KtFakeLightClass
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
@@ -68,15 +69,15 @@ class IDEKotlinAsJavaFirSupport(private val project: Project) : KotlinAsJavaSupp
|
||||
project.createDeclarationProvider(searchScope).getClassesByClassId(it)
|
||||
}.filter {
|
||||
//TODO Do not return LC came from LibrarySources
|
||||
when (it.getModuleInfo()) {
|
||||
is LibraryModuleSourceInfoBase -> it.containingKtFile.isCompiled
|
||||
is NonSourceModuleInfoBase -> false
|
||||
when (it.getKtModule(project)) {
|
||||
is KtLibrarySourceModule -> false
|
||||
is KtNotUnderContentRootModule -> false
|
||||
else -> true
|
||||
}
|
||||
}.toSet()
|
||||
|
||||
override fun packageExists(fqName: FqName, scope: GlobalSearchScope): Boolean =
|
||||
project.createPackageProvider(scope).isPackageExists(fqName)
|
||||
project.createPackageProvider(scope).doKotlinPackageExists(fqName)
|
||||
|
||||
override fun getSubPackages(fqn: FqName, scope: GlobalSearchScope): Collection<FqName> =
|
||||
project.createPackageProvider(scope)
|
||||
|
||||
@@ -319,6 +319,7 @@ extra["compilerArtifactsForIde"] = listOf(
|
||||
":prepare:ide-plugin-dependencies:high-level-api-fir-for-ide",
|
||||
":prepare:ide-plugin-dependencies:high-level-api-fir-tests-for-ide",
|
||||
":prepare:ide-plugin-dependencies:analysis-api-providers-for-ide",
|
||||
":prepare:ide-plugin-dependencies:analysis-project-structure-for-ide",
|
||||
":prepare:ide-plugin-dependencies:symbol-light-classes-for-ide",
|
||||
":prepare:ide-plugin-dependencies:kotlin-compiler-ir-for-ide",
|
||||
":prepare:ide-plugin-dependencies:kotlin-compiler-common-for-ide",
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
}
|
||||
|
||||
publishJarsForIde(listOf(":analysis:project-structure"))
|
||||
+3
-1
@@ -329,6 +329,7 @@ if (!buildProperties.inJpsBuildIdeaSync) {
|
||||
":prepare:ide-plugin-dependencies:high-level-api-fir-for-ide",
|
||||
":prepare:ide-plugin-dependencies:high-level-api-fir-tests-for-ide",
|
||||
":prepare:ide-plugin-dependencies:analysis-api-providers-for-ide",
|
||||
":prepare:ide-plugin-dependencies:analysis-project-structure-for-ide",
|
||||
":prepare:ide-plugin-dependencies:symbol-light-classes-for-ide",
|
||||
":prepare:ide-plugin-dependencies:kotlin-compiler-ir-for-ide",
|
||||
":prepare:ide-plugin-dependencies:kotlin-compiler-common-for-ide",
|
||||
@@ -449,7 +450,8 @@ include ":generators:analysis-api-generator",
|
||||
":analysis:analysis-api-fir",
|
||||
":analysis:analysis-api",
|
||||
":analysis:analysis-api-providers",
|
||||
":analysis:symbol-light-classes"
|
||||
":analysis:symbol-light-classes",
|
||||
":analysis:project-structure"
|
||||
|
||||
|
||||
if (buildProperties.inJpsBuildIdeaSync) {
|
||||
|
||||
Reference in New Issue
Block a user