[LL API] Analyze code fragment in a separate 'FirSession'
Before, `KtCodeFragment`/`FirCodeFragment` was analyzed as a part of its context `KtModule`. This has the following complications: - In non-source sessions, diagnostic reporting is globally disabled. For code fragments, however, checking the code before passing it to the backend is essential. - Special treatment for call ambiguities in libraries (`LLLibraryScopeAwareCallConflictResolverFactory`) becomes complicated as the conflict resolver has to be applied to a library module. - `KtCodeFragment`s usually have a shorter lifetime than their own context. Caching may potentially be implemented differently for them. ^KT-61783 Fixed
This commit is contained in:
+11
@@ -8,7 +8,9 @@ package org.jetbrains.kotlin.analysis.api.standalone.base.project.structure
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFileSystemItem
|
||||
import org.jetbrains.kotlin.analysis.project.structure.*
|
||||
import org.jetbrains.kotlin.analysis.project.structure.impl.KtCodeFragmentModuleImpl
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.psi.KtCodeFragment
|
||||
import org.jetbrains.kotlin.psi.psiUtil.contains
|
||||
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
|
||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
||||
@@ -23,6 +25,15 @@ class KtStaticModuleProvider(
|
||||
// Unwrap context-dependent file copies coming from dependent sessions
|
||||
val containingPsiFile = element.containingFile.originalFile
|
||||
|
||||
if (containingPsiFile is KtCodeFragment) {
|
||||
val contextElement = containingPsiFile.context
|
||||
?: throw KotlinExceptionWithAttachments("Context not found for a code fragment")
|
||||
.withAttachment("codeFragment.kt", containingPsiFile.text)
|
||||
|
||||
val contextModule = getModule(contextElement, contextualModule)
|
||||
return KtCodeFragmentModuleImpl(containingPsiFile, contextModule)
|
||||
}
|
||||
|
||||
val containingVirtualFile = containingPsiFile.virtualFile
|
||||
if (containingVirtualFile.extension == BuiltInSerializerProtocol.BUILTINS_FILE_EXTENSION) {
|
||||
return builtinsModule
|
||||
|
||||
+1
-1
@@ -9,4 +9,4 @@ MODULE_FRAGMENT
|
||||
EXPRESSION_BODY
|
||||
BLOCK type=kotlin.Unit origin=null
|
||||
CALL 'public final fun call (): kotlin.Unit declared in <root>.Foo' type=kotlin.Unit origin=null
|
||||
$this: GET_OBJECT 'CLASS OBJECT name:Foo modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.Foo
|
||||
$this: GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Foo modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.Foo
|
||||
|
||||
+1
@@ -1 +1,2 @@
|
||||
@Suppress("INVISIBLE_SETTER")
|
||||
a = "bar"
|
||||
+24
-3
@@ -43,17 +43,27 @@ class LLFirResolveSessionService(project: Project) {
|
||||
private fun create(module: KtModule, factory: (KtModule) -> LLFirSession): LLFirResolvableResolveSession {
|
||||
val moduleProvider = LLModuleProvider(module)
|
||||
val sessionProvider = LLSessionProvider(module, factory)
|
||||
val moduleKindProvider = createModuleKindProvider(module)
|
||||
val moduleKindProvider = createModuleKindProvider(module, moduleProvider)
|
||||
val diagnosticProvider = createDiagnosticProvider(moduleProvider, sessionProvider)
|
||||
|
||||
return LLFirResolvableResolveSession(moduleProvider, moduleKindProvider, sessionProvider, diagnosticProvider)
|
||||
}
|
||||
|
||||
private fun createModuleKindProvider(module: KtModule): LLModuleKindProvider {
|
||||
private fun createModuleKindProvider(module: KtModule, moduleProvider: LLModuleProvider): LLModuleKindProvider {
|
||||
return when (module) {
|
||||
is KtSourceModule -> LLSourceModuleKindProvider
|
||||
is KtLibraryModule, is KtLibrarySourceModule -> LLLibraryModuleKindProvider(module)
|
||||
is KtScriptModule -> LLScriptModuleKindProvider(module)
|
||||
is KtCodeFragmentModule -> {
|
||||
val contextElement = module.codeFragment.context
|
||||
if (contextElement != null) {
|
||||
val contextModule = moduleProvider.getModule(contextElement)
|
||||
val contextModuleKindProvider = createModuleKindProvider(contextModule, moduleProvider)
|
||||
LLCodeFragmentKindProvider(contextModuleKindProvider)
|
||||
} else {
|
||||
LLSimpleResolvableModuleKindProvider(module)
|
||||
}
|
||||
}
|
||||
is KtNotUnderContentRootModule -> LLSimpleResolvableModuleKindProvider(module)
|
||||
else -> {
|
||||
errorWithFirSpecificEntries("Unexpected ${module::class.java}") {
|
||||
@@ -65,7 +75,9 @@ class LLFirResolveSessionService(project: Project) {
|
||||
|
||||
private fun createDiagnosticProvider(moduleProvider: LLModuleProvider, sessionProvider: LLSessionProvider): LLDiagnosticProvider {
|
||||
return when (moduleProvider.useSiteModule) {
|
||||
is KtSourceModule, is KtScriptModule -> LLSourceDiagnosticProvider(moduleProvider, sessionProvider)
|
||||
is KtSourceModule,
|
||||
is KtScriptModule,
|
||||
is KtCodeFragmentModule -> LLSourceDiagnosticProvider(moduleProvider, sessionProvider)
|
||||
else -> LLEmptyDiagnosticProvider
|
||||
}
|
||||
}
|
||||
@@ -101,4 +113,13 @@ private class LLScriptModuleKindProvider(private val useSiteModule: KtModule) :
|
||||
else -> unexpectedElementError("module", module)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class LLCodeFragmentKindProvider(private val delegate: LLModuleKindProvider) : LLModuleKindProvider {
|
||||
override fun getKind(module: KtModule): KtModuleKind {
|
||||
return when (module) {
|
||||
is KtCodeFragmentModule -> KtModuleKind.RESOLVABLE_MODULE
|
||||
else -> delegate.getKind(module)
|
||||
}
|
||||
}
|
||||
}
|
||||
+108
-21
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirLazyDeclarationResol
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.*
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.*
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolver.LLLibraryScopeAwareCallConflictResolverFactory
|
||||
import org.jetbrains.kotlin.analysis.project.structure.*
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinAnchorModuleProvider
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider
|
||||
@@ -31,9 +32,13 @@ import org.jetbrains.kotlin.fir.analysis.extensions.additionalCheckers
|
||||
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmTypeMapper
|
||||
import org.jetbrains.kotlin.fir.extensions.*
|
||||
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.callConflictResolverFactory
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.DEPENDENCIES_SYMBOL_PROVIDER_QUALIFIED_KEY
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.dependenciesSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirExtensionSyntheticFunctionInterfaceProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
|
||||
@@ -41,6 +46,8 @@ import org.jetbrains.kotlin.fir.resolve.transformers.FirDummyCompilerLazyDeclara
|
||||
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
||||
import org.jetbrains.kotlin.fir.session.*
|
||||
import org.jetbrains.kotlin.fir.symbols.FirLazyDeclarationResolver
|
||||
import org.jetbrains.kotlin.platform.has
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatform
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
||||
@@ -128,7 +135,7 @@ internal abstract class LLFirAbstractSessionFactory(protected val project: Proje
|
||||
|
||||
val dependencyProvider = LLFirDependenciesSymbolProvider(this) {
|
||||
buildList {
|
||||
addDependencySymbolProvidersTo(session, collectSourceModuleDependencies(module), this)
|
||||
addMerged(collectDependencySymbolProviders(module))
|
||||
add(builtinsSession.symbolProvider)
|
||||
}
|
||||
}
|
||||
@@ -282,7 +289,7 @@ internal abstract class LLFirAbstractSessionFactory(protected val project: Proje
|
||||
|
||||
val dependencyProvider = LLFirDependenciesSymbolProvider(this) {
|
||||
buildList {
|
||||
addDependencySymbolProvidersTo(session, collectSourceModuleDependencies(module), this)
|
||||
addMerged(collectDependencySymbolProviders(module))
|
||||
add(builtinsSession.symbolProvider)
|
||||
}
|
||||
}
|
||||
@@ -450,6 +457,87 @@ internal abstract class LLFirAbstractSessionFactory(protected val project: Proje
|
||||
}
|
||||
}
|
||||
|
||||
fun createCodeFragmentSession(module: KtCodeFragmentModule, contextSession: LLFirSession): LLFirSession {
|
||||
val platform = module.platform
|
||||
require(platform.has<JvmPlatform>())
|
||||
|
||||
val builtinsSession = LLFirBuiltinsSessionFactory.getInstance(project).getBuiltinsSession(platform)
|
||||
val languageVersionSettings = wrapLanguageVersionSettings(contextSession.languageVersionSettings)
|
||||
val scopeProvider = FirKotlinScopeProvider(::wrapScopeWithJvmMapped)
|
||||
|
||||
val components = LLFirModuleResolveComponents(module, globalResolveComponents, scopeProvider)
|
||||
|
||||
val session = LLFirCodeFragmentSession(module, components, builtinsSession.builtinTypes)
|
||||
components.session = session
|
||||
|
||||
val moduleData = createModuleData(session)
|
||||
|
||||
return session.apply {
|
||||
registerModuleData(moduleData)
|
||||
register(FirKotlinScopeProvider::class, scopeProvider)
|
||||
|
||||
registerIdeComponents(project)
|
||||
registerCommonComponents(languageVersionSettings)
|
||||
registerResolveComponents()
|
||||
|
||||
val firProvider = LLFirProvider(
|
||||
this,
|
||||
components,
|
||||
canContainKotlinPackage = true,
|
||||
) { scope ->
|
||||
scope.createScopedDeclarationProviderForFile(module.codeFragment)
|
||||
}
|
||||
|
||||
register(FirProvider::class, firProvider)
|
||||
register(FirLazyDeclarationResolver::class, LLFirLazyDeclarationResolver())
|
||||
|
||||
registerCommonComponentsAfterExtensionsAreConfigured()
|
||||
|
||||
val dependencyProvider = LLFirDependenciesSymbolProvider(this) {
|
||||
buildList {
|
||||
addMerged(computeFlattenedSymbolProviders(listOf(contextSession)))
|
||||
add(contextSession.dependenciesSymbolProvider) // Add the context module dependency symbol provider as is
|
||||
add(builtinsSession.symbolProvider)
|
||||
}
|
||||
}
|
||||
|
||||
register(DEPENDENCIES_SYMBOL_PROVIDER_QUALIFIED_KEY, dependencyProvider)
|
||||
register(LLFirFirClassByPsiClassProvider::class, LLFirFirClassByPsiClassProvider(this))
|
||||
|
||||
LLFirSessionConfigurator.configure(this)
|
||||
|
||||
extensionService.additionalCheckers.forEach(session.checkersComponent::register)
|
||||
|
||||
register(FirPredicateBasedProvider::class, FirEmptyPredicateBasedProvider)
|
||||
register(FirRegisteredPluginAnnotations::class, FirRegisteredPluginAnnotationsImpl(this))
|
||||
|
||||
registerJavaComponents(JavaModuleResolver.getInstance(project))
|
||||
|
||||
val javaSymbolProvider = LLFirJavaSymbolProvider(this, moduleData, project, firProvider.searchScope)
|
||||
register(JavaSymbolProvider::class, javaSymbolProvider)
|
||||
|
||||
val syntheticFunctionInterfaceProvider = FirExtensionSyntheticFunctionInterfaceProvider
|
||||
.createIfNeeded(this, moduleData, scopeProvider)
|
||||
|
||||
register(
|
||||
FirSymbolProvider::class,
|
||||
LLFirModuleWithDependenciesSymbolProvider(
|
||||
this,
|
||||
providers = listOfNotNull(
|
||||
firProvider.symbolProvider,
|
||||
syntheticFunctionInterfaceProvider,
|
||||
javaSymbolProvider
|
||||
),
|
||||
dependencyProvider
|
||||
)
|
||||
)
|
||||
|
||||
register(FirJvmTypeMapper::class, FirJvmTypeMapper(this))
|
||||
|
||||
register(ConeCallConflictResolverFactory::class, LLLibraryScopeAwareCallConflictResolverFactory(callConflictResolverFactory))
|
||||
}
|
||||
}
|
||||
|
||||
private fun wrapLanguageVersionSettings(original: LanguageVersionSettings): LanguageVersionSettings {
|
||||
return object : LanguageVersionSettings by original {
|
||||
override fun getFeatureSupport(feature: LanguageFeature): LanguageFeature.State {
|
||||
@@ -468,7 +556,7 @@ internal abstract class LLFirAbstractSessionFactory(protected val project: Proje
|
||||
}
|
||||
}
|
||||
|
||||
private fun collectSourceModuleDependencies(module: KtModule): List<LLFirSession> {
|
||||
private fun collectDependencySymbolProviders(module: KtModule): List<FirSymbolProvider> {
|
||||
val llFirSessionCache = LLFirSessionCache.getInstance(project)
|
||||
|
||||
fun getOrCreateSessionForDependency(dependency: KtModule): LLFirSession? = when (dependency) {
|
||||
@@ -478,6 +566,7 @@ internal abstract class LLFirAbstractSessionFactory(protected val project: Proje
|
||||
|
||||
is KtScriptModule,
|
||||
is KtScriptDependencyModule,
|
||||
is KtCodeFragmentModule,
|
||||
is KtNotUnderContentRootModule,
|
||||
is KtLibrarySourceModule,
|
||||
-> {
|
||||
@@ -496,7 +585,17 @@ internal abstract class LLFirAbstractSessionFactory(protected val project: Proje
|
||||
addAll(module.transitiveDependsOnDependencies)
|
||||
}
|
||||
|
||||
return dependencyModules.mapNotNull(::getOrCreateSessionForDependency)
|
||||
val dependencySessions = dependencyModules.mapNotNull(::getOrCreateSessionForDependency)
|
||||
return computeFlattenedSymbolProviders(dependencySessions)
|
||||
}
|
||||
|
||||
private fun computeFlattenedSymbolProviders(dependencySessions: List<LLFirSession>): List<FirSymbolProvider> {
|
||||
return dependencySessions.flatMap { session ->
|
||||
when (val dependencyProvider = session.symbolProvider) {
|
||||
is LLFirModuleWithDependenciesSymbolProvider -> dependencyProvider.providers
|
||||
else -> listOf(dependencyProvider)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createModuleData(session: LLFirSession): LLFirModuleData {
|
||||
@@ -504,24 +603,12 @@ internal abstract class LLFirAbstractSessionFactory(protected val project: Proje
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds dependency symbol providers from [dependencies] to [destination]. The function might combine, reorder, or exclude specific
|
||||
* symbol providers for optimization.
|
||||
* Merges dependency symbol providers of the same kind, and adds the result to the receiver [MutableList].
|
||||
* See [mergeDependencySymbolProvidersInto] for more information on symbol provider merging.
|
||||
*/
|
||||
private fun addDependencySymbolProvidersTo(
|
||||
session: LLFirSession,
|
||||
dependencies: List<LLFirSession>,
|
||||
destination: MutableList<FirSymbolProvider>,
|
||||
) {
|
||||
val dependencyProviders = buildList {
|
||||
dependencies.forEach { session ->
|
||||
when (val dependencyProvider = session.symbolProvider) {
|
||||
is LLFirModuleWithDependenciesSymbolProvider -> addAll(dependencyProvider.providers)
|
||||
else -> add(dependencyProvider)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencyProviders.mergeDependencySymbolProvidersInto(session, destination)
|
||||
context(LLFirSession)
|
||||
private fun MutableList<FirSymbolProvider>.addMerged(dependencies: List<FirSymbolProvider>) {
|
||||
dependencies.mergeDependencySymbolProvidersInto(this@LLFirSession, this)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.low.level.api.fir.LLFirModuleResolveComponents
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtCodeFragmentModule
|
||||
import org.jetbrains.kotlin.fir.BuiltinTypes
|
||||
import org.jetbrains.kotlin.fir.PrivateSessionConstructor
|
||||
|
||||
internal class LLFirCodeFragmentSession @PrivateSessionConstructor constructor(
|
||||
ktModule: KtCodeFragmentModule,
|
||||
override val moduleComponents: LLFirModuleResolveComponents,
|
||||
builtinTypes: BuiltinTypes,
|
||||
) : LLFirResolvableModuleSession(ktModule, builtinTypes)
|
||||
+6
@@ -146,6 +146,12 @@ class LLFirSessionCache(private val project: Project) {
|
||||
is KtLibraryModule, is KtLibrarySourceModule -> sessionFactory.createLibrarySession(module)
|
||||
is KtSdkModule -> sessionFactory.createBinaryLibrarySession(module)
|
||||
is KtScriptModule -> sessionFactory.createScriptSession(module)
|
||||
is KtCodeFragmentModule -> {
|
||||
// 'KtCodeFragment' context must have an analyzable session, so we can properly compile code against it.
|
||||
// 'KtCodeFragmentModule' is always a leaf module, there might not be a circular reference.
|
||||
val contextSession = getSession(module.contextModule, preferBinary = false)
|
||||
sessionFactory.createCodeFragmentSession(module, contextSession)
|
||||
}
|
||||
is KtNotUnderContentRootModule -> sessionFactory.createNotUnderContentRootResolvableSession(module)
|
||||
else -> error("Unexpected module kind: ${module::class.simpleName}")
|
||||
}
|
||||
|
||||
+5
-1
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.transformers
|
||||
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignationWithFile
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getFirResolveSession
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getModule
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirResolveTarget
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.throwUnexpectedFirElementError
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.compile.codeFragmentScopeProvider
|
||||
@@ -38,6 +39,7 @@ import org.jetbrains.kotlin.fir.references.builder.buildExplicitSuperReference
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildExplicitThisReference
|
||||
import org.jetbrains.kotlin.fir.resolve.FirCodeFragmentContext
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.SessionHolderImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.dfa.FirControlFlowGraphReferenceImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.codeFragmentContext
|
||||
import org.jetbrains.kotlin.fir.resolve.dfa.RealVariable
|
||||
@@ -219,9 +221,11 @@ private class LLFirBodyTargetResolver(
|
||||
val contextKtFile = contextPsiElement?.containingFile as? KtFile
|
||||
|
||||
firCodeFragment.codeFragmentContext = if (contextKtFile != null) {
|
||||
val contextModule = resolveSession.getModule(contextKtFile)
|
||||
val contextSession = resolveSession.sessionProvider.getResolvableSession(contextModule)
|
||||
val contextFirFile = resolveSession.getOrBuildFirFile(contextKtFile)
|
||||
val sessionHolder = transformer.components
|
||||
|
||||
val sessionHolder = SessionHolderImpl(contextSession, contextSession.getScopeSession())
|
||||
val elementContext = ContextCollector.process(contextFirFile, sessionHolder, contextPsiElement)
|
||||
?: errorWithAttachment("Cannot find enclosing context for ${contextPsiElement::class}") {
|
||||
withPsiEntry("contextPsiElement", contextPsiElement)
|
||||
|
||||
+19
@@ -10,6 +10,7 @@ import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.psi.KtCodeFragment
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||
import java.nio.file.Path
|
||||
@@ -214,6 +215,24 @@ public interface KtScriptDependencyModule : KtModule {
|
||||
public val file: KtFile?
|
||||
}
|
||||
|
||||
/**
|
||||
* A module for a Kotlin code fragment – a piece of code analyzed against a specific context element.
|
||||
*/
|
||||
public interface KtCodeFragmentModule : KtModule {
|
||||
/**
|
||||
* A code fragment PSI.
|
||||
*/
|
||||
public val codeFragment: KtCodeFragment
|
||||
|
||||
/**
|
||||
* Module of the context element.
|
||||
*/
|
||||
public val contextModule: KtModule
|
||||
|
||||
override val moduleDescription: String
|
||||
get() = "Code fragment"
|
||||
}
|
||||
|
||||
/**
|
||||
* A set of sources which live outside the project content root. E.g, testdata files or source files of some other project.
|
||||
*/
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.impl
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtCodeFragmentModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.psi.KtCodeFragment
|
||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||
import java.util.Objects
|
||||
|
||||
public class KtCodeFragmentModuleImpl(
|
||||
override val codeFragment: KtCodeFragment,
|
||||
override val contextModule: KtModule
|
||||
) : KtCodeFragmentModule {
|
||||
override val project: Project
|
||||
get() = contextModule.project
|
||||
|
||||
override val platform: TargetPlatform
|
||||
get() = contextModule.platform
|
||||
|
||||
override val analyzerServices: PlatformDependentAnalyzerServices
|
||||
get() = contextModule.analyzerServices
|
||||
|
||||
override val contentScope: GlobalSearchScope
|
||||
get() = GlobalSearchScope.fileScope(codeFragment)
|
||||
|
||||
override val directRegularDependencies: List<KtModule>
|
||||
get() = contextModule.directRegularDependencies
|
||||
|
||||
override val directDependsOnDependencies: List<KtModule>
|
||||
get() = contextModule.directDependsOnDependencies
|
||||
|
||||
override val directFriendDependencies: List<KtModule>
|
||||
get() = listOf(contextModule) + contextModule.directFriendDependencies
|
||||
|
||||
override val transitiveDependsOnDependencies: List<KtModule>
|
||||
get() = contextModule.transitiveDependsOnDependencies
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
|
||||
if (other is KtCodeFragmentModuleImpl) {
|
||||
return codeFragment == other.codeFragment && contextModule == other.contextModule
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return Objects.hash(codeFragment, contextModule)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user