[FE] Merge context and own imports on 'FirCodeFragment' analysis
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt
index 5a34e8a..533a2d8 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt
@@ -27,6 +27,7 @@
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
import org.jetbrains.kotlin.fir.resolve.transformers.withScopeCleanup
import org.jetbrains.kotlin.fir.scopes.FirScope
+import org.jetbrains.kotlin.fir.scopes.computeImportingScopes
import org.jetbrains.kotlin.fir.scopes.createImportingScopes
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope
@@ -529,9 +530,16 @@
}
}
- fun <T> withScopesForCodeFragment(codeFragment: FirCodeFragment, f: () -> T): T {
+ fun <T> withScopesForCodeFragment(codeFragment: FirCodeFragment, holder: SessionHolder, f: () -> T): T {
val towerDataContext = codeFragment.towerDataContext ?: error("Context is not set for a code fragment")
- val base = towerDataContext.addNonLocalTowerDataElements(towerDataContext.nonLocalTowerDataElements)
+
+ val fragmentImportTowerDataElements = computeImportingScopes(file, holder.session, holder.scopeSession)
+ .map { it.asTowerDataElement(isLocal = false) }
+
+ val base = towerDataContext
+ .addNonLocalTowerDataElements(towerDataContext.nonLocalTowerDataElements)
+ .addNonLocalTowerDataElements(fragmentImportTowerDataElements)
+
val baseWithLocalScope = towerDataContext.localScopes.fold(base) { acc, scope -> acc.addLocalScope(scope) }
val newContext = FirRegularTowerDataContexts(
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt
index 58a7131..b566621 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt
@@ -560,7 +560,7 @@
override fun transformCodeFragment(codeFragment: FirCodeFragment, data: ResolutionMode): FirCodeFragment {
dataFlowAnalyzer.enterCodeFragment(codeFragment)
- context.withScopesForCodeFragment(codeFragment) {
+ context.withScopesForCodeFragment(codeFragment, components) {
transformBlock(codeFragment.block, data)
}
dataFlowAnalyzer.exitCodeFragment()
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/ImportingScopes.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/ImportingScopes.kt
index e07fdb6..349b61d 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/ImportingScopes.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/ImportingScopes.kt
@@ -28,44 +28,61 @@
useCaching: Boolean = true
): List<FirScope> = if (useCaching) {
scopeSession.getOrBuild(file, ALL_IMPORTS) {
- ListStorageFirScope(doCreateImportingScopes(file, session, scopeSession))
+ ListStorageFirScope(computeImportingScopes(file, session, scopeSession))
}.result
} else {
- doCreateImportingScopes(file, session, scopeSession)
+ computeImportingScopes(file, session, scopeSession)
}
-private fun doCreateImportingScopes(
+internal fun computeImportingScopes(
file: FirFile,
session: FirSession,
- scopeSession: ScopeSession
+ scopeSession: ScopeSession,
+ includeDefaultImports: Boolean = true,
+ includePackageImport: Boolean = true
): List<FirScope> {
file.lazyResolveToPhase(FirResolvePhase.IMPORTS)
- val excludedImportNames =
- file.imports.filter { it.aliasName != null }.mapNotNullTo(hashSetOf()) { it.importedFqName }.ifEmpty { emptySet() }
- return listOf(
- scopeSession.getOrBuild(DefaultStarImportKey(DefaultImportPriority.LOW, excludedImportNames), DEFAULT_STAR_IMPORT) {
- FirDefaultStarImportingScope(session, scopeSession, DefaultImportPriority.LOW, excludedImportNames)
- },
- scopeSession.getOrBuild(DefaultStarImportKey(DefaultImportPriority.HIGH, excludedImportNames), DEFAULT_STAR_IMPORT) {
- FirDefaultStarImportingScope(session, scopeSession, DefaultImportPriority.HIGH, excludedImportNames)
- },
- scopeSession.getOrBuild(DefaultImportPriority.KOTLIN_THROWS, DEFAULT_SIMPLE_IMPORT) {
- FirDefaultSimpleImportingScope(session, scopeSession, priority = DefaultImportPriority.KOTLIN_THROWS)
- },
- FirExplicitStarImportingScope(file.imports, session, scopeSession, excludedImportNames),
- scopeSession.getOrBuild(DefaultImportPriority.LOW, DEFAULT_SIMPLE_IMPORT) {
- FirDefaultSimpleImportingScope(session, scopeSession, priority = DefaultImportPriority.LOW)
- },
- scopeSession.getOrBuild(DefaultImportPriority.HIGH, DEFAULT_SIMPLE_IMPORT) {
- FirDefaultSimpleImportingScope(session, scopeSession, priority = DefaultImportPriority.HIGH)
- },
- scopeSession.getOrBuild(file.packageFqName, PACKAGE_MEMBER) {
- FirPackageMemberScope(file.packageFqName, session)
- },
+ val excludedImportNames = file.imports
+ .filter { it.aliasName != null }
+ .mapNotNullTo(hashSetOf()) { it.importedFqName }
+ .ifEmpty { emptySet() }
+
+ return buildList {
+ if (includeDefaultImports) {
+ this += scopeSession.getOrBuild(DefaultStarImportKey(DefaultImportPriority.LOW, excludedImportNames), DEFAULT_STAR_IMPORT) {
+ FirDefaultStarImportingScope(session, scopeSession, DefaultImportPriority.LOW, excludedImportNames)
+ }
+
+ this += scopeSession.getOrBuild(DefaultStarImportKey(DefaultImportPriority.HIGH, excludedImportNames), DEFAULT_STAR_IMPORT) {
+ FirDefaultStarImportingScope(session, scopeSession, DefaultImportPriority.HIGH, excludedImportNames)
+ }
+
+ this += scopeSession.getOrBuild(DefaultImportPriority.KOTLIN_THROWS, DEFAULT_SIMPLE_IMPORT) {
+ FirDefaultSimpleImportingScope(session, scopeSession, priority = DefaultImportPriority.KOTLIN_THROWS)
+ }
+ }
+
+ this += FirExplicitStarImportingScope(file.imports, session, scopeSession, excludedImportNames)
+
+ if (includeDefaultImports) {
+ this += scopeSession.getOrBuild(DefaultImportPriority.LOW, DEFAULT_SIMPLE_IMPORT) {
+ FirDefaultSimpleImportingScope(session, scopeSession, priority = DefaultImportPriority.LOW)
+ }
+ this += scopeSession.getOrBuild(DefaultImportPriority.HIGH, DEFAULT_SIMPLE_IMPORT) {
+ FirDefaultSimpleImportingScope(session, scopeSession, priority = DefaultImportPriority.HIGH)
+ }
+ }
+
+ if (includePackageImport) {
+ this += scopeSession.getOrBuild(file.packageFqName, PACKAGE_MEMBER) {
+ FirPackageMemberScope(file.packageFqName, session)
+ }
+ }
+
// TODO: explicit simple importing scope should have highest priority (higher than inner scopes added in process)
- FirExplicitSimpleImportingScope(file.imports, session, scopeSession)
- )
+ this += FirExplicitSimpleImportingScope(file.imports, session, scopeSession)
+ }
}
private class ListStorageFirScope(val result: List<FirScope>) : FirScope()