[FIR] Use both context and code fragment imports
This commit is contained in:
+10
-2
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.fir.resolve.inference.FirInferenceSession
|
|||||||
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.withScopeCleanup
|
import org.jetbrains.kotlin.fir.resolve.transformers.withScopeCleanup
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
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.createImportingScopes
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope
|
||||||
@@ -529,9 +530,16 @@ class BodyResolveContext(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 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 baseWithLocalScope = towerDataContext.localScopes.fold(base) { acc, scope -> acc.addLocalScope(scope) }
|
||||||
|
|
||||||
val newContext = FirRegularTowerDataContexts(
|
val newContext = FirRegularTowerDataContexts(
|
||||||
|
|||||||
+1
-1
@@ -545,7 +545,7 @@ open class FirDeclarationsResolveTransformer(
|
|||||||
|
|
||||||
override fun transformCodeFragment(codeFragment: FirCodeFragment, data: ResolutionMode): FirCodeFragment {
|
override fun transformCodeFragment(codeFragment: FirCodeFragment, data: ResolutionMode): FirCodeFragment {
|
||||||
dataFlowAnalyzer.enterCodeFragment(codeFragment)
|
dataFlowAnalyzer.enterCodeFragment(codeFragment)
|
||||||
context.withScopesForCodeFragment(codeFragment) {
|
context.withScopesForCodeFragment(codeFragment, components) {
|
||||||
transformBlock(codeFragment.block, data)
|
transformBlock(codeFragment.block, data)
|
||||||
}
|
}
|
||||||
dataFlowAnalyzer.exitCodeFragment()
|
dataFlowAnalyzer.exitCodeFragment()
|
||||||
|
|||||||
@@ -27,16 +27,18 @@ fun createImportingScopes(
|
|||||||
useCaching: Boolean = true
|
useCaching: Boolean = true
|
||||||
): List<FirScope> = if (useCaching) {
|
): List<FirScope> = if (useCaching) {
|
||||||
scopeSession.getOrBuild(file, ALL_IMPORTS) {
|
scopeSession.getOrBuild(file, ALL_IMPORTS) {
|
||||||
ListStorageFirScope(doCreateImportingScopes(file, session, scopeSession))
|
ListStorageFirScope(computeImportingScopes(file, session, scopeSession))
|
||||||
}.result
|
}.result
|
||||||
} else {
|
} else {
|
||||||
doCreateImportingScopes(file, session, scopeSession)
|
computeImportingScopes(file, session, scopeSession)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doCreateImportingScopes(
|
internal fun computeImportingScopes(
|
||||||
file: FirFile,
|
file: FirFile,
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
scopeSession: ScopeSession
|
scopeSession: ScopeSession,
|
||||||
|
includeDefaultImports: Boolean = true,
|
||||||
|
includePackageImport: Boolean = true
|
||||||
): List<FirScope> {
|
): List<FirScope> {
|
||||||
file.lazyResolveToPhase(FirResolvePhase.IMPORTS)
|
file.lazyResolveToPhase(FirResolvePhase.IMPORTS)
|
||||||
val excludedImportNames =
|
val excludedImportNames =
|
||||||
@@ -47,38 +49,47 @@ private fun doCreateImportingScopes(
|
|||||||
if (it.parent() == file.packageFqName) it.shortName() else null
|
if (it.parent() == file.packageFqName) it.shortName() else null
|
||||||
}
|
}
|
||||||
|
|
||||||
return listOf(
|
return buildList {
|
||||||
FirDefaultStarImportingScope(
|
if (includeDefaultImports) {
|
||||||
scopeSession.getOrBuild(DefaultStarImportKey(DefaultImportPriority.HIGH, excludedImportNames), DEFAULT_STAR_IMPORT) {
|
this += FirDefaultStarImportingScope(
|
||||||
FirSingleLevelDefaultStarImportingScope(session, scopeSession, DefaultImportPriority.HIGH, excludedImportNames)
|
scopeSession.getOrBuild(DefaultStarImportKey(DefaultImportPriority.HIGH, excludedImportNames), DEFAULT_STAR_IMPORT) {
|
||||||
},
|
FirSingleLevelDefaultStarImportingScope(session, scopeSession, DefaultImportPriority.HIGH, excludedImportNames)
|
||||||
scopeSession.getOrBuild(DefaultStarImportKey(DefaultImportPriority.LOW, excludedImportNames), DEFAULT_STAR_IMPORT) {
|
},
|
||||||
FirSingleLevelDefaultStarImportingScope(session, scopeSession, DefaultImportPriority.LOW, excludedImportNames)
|
scopeSession.getOrBuild(DefaultStarImportKey(DefaultImportPriority.LOW, excludedImportNames), DEFAULT_STAR_IMPORT) {
|
||||||
},
|
FirSingleLevelDefaultStarImportingScope(session, scopeSession, DefaultImportPriority.LOW, excludedImportNames)
|
||||||
),
|
},
|
||||||
|
)
|
||||||
|
|
||||||
scopeSession.getOrBuild(DefaultImportPriority.KOTLIN_THROWS, DEFAULT_SIMPLE_IMPORT) {
|
this += scopeSession.getOrBuild(DefaultImportPriority.KOTLIN_THROWS, DEFAULT_SIMPLE_IMPORT) {
|
||||||
FirDefaultSimpleImportingScope(session, scopeSession, priority = DefaultImportPriority.KOTLIN_THROWS)
|
FirDefaultSimpleImportingScope(session, scopeSession, priority = DefaultImportPriority.KOTLIN_THROWS)
|
||||||
},
|
}
|
||||||
FirExplicitStarImportingScope(file.imports, session, scopeSession, excludedImportNames),
|
}
|
||||||
|
|
||||||
scopeSession.getOrBuild(DefaultImportPriority.LOW, DEFAULT_SIMPLE_IMPORT) {
|
this += FirExplicitStarImportingScope(file.imports, session, scopeSession, excludedImportNames)
|
||||||
FirDefaultSimpleImportingScope(session, scopeSession, priority = DefaultImportPriority.LOW)
|
|
||||||
},
|
if (includeDefaultImports) {
|
||||||
scopeSession.getOrBuild(DefaultImportPriority.HIGH, DEFAULT_SIMPLE_IMPORT) {
|
this += scopeSession.getOrBuild(DefaultImportPriority.LOW, DEFAULT_SIMPLE_IMPORT) {
|
||||||
FirDefaultSimpleImportingScope(session, scopeSession, priority = DefaultImportPriority.HIGH)
|
FirDefaultSimpleImportingScope(session, scopeSession, priority = DefaultImportPriority.LOW)
|
||||||
},
|
}
|
||||||
when {
|
this += scopeSession.getOrBuild(DefaultImportPriority.HIGH, DEFAULT_SIMPLE_IMPORT) {
|
||||||
excludedNamesInPackage.isEmpty() ->
|
FirDefaultSimpleImportingScope(session, scopeSession, priority = DefaultImportPriority.HIGH)
|
||||||
// Supposed to be the most common branch, so we cache it
|
}
|
||||||
scopeSession.getOrBuild(file.packageFqName, PACKAGE_MEMBER) {
|
}
|
||||||
FirPackageMemberScope(file.packageFqName, session, excludedNames = emptySet())
|
|
||||||
}
|
if (includePackageImport) {
|
||||||
else ->
|
this += when {
|
||||||
FirPackageMemberScope(file.packageFqName, session, excludedNames = excludedNamesInPackage)
|
excludedNamesInPackage.isEmpty() ->
|
||||||
},
|
// Supposed to be the most common branch, so we cache it
|
||||||
FirExplicitSimpleImportingScope(file.imports, session, scopeSession)
|
scopeSession.getOrBuild(file.packageFqName, PACKAGE_MEMBER) {
|
||||||
)
|
FirPackageMemberScope(file.packageFqName, session, excludedNames = emptySet())
|
||||||
|
}
|
||||||
|
else ->
|
||||||
|
FirPackageMemberScope(file.packageFqName, session, excludedNames = excludedNamesInPackage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO: explicit simple importing scope should have highest priority (higher than inner scopes added in process)
|
||||||
|
this += FirExplicitSimpleImportingScope(file.imports, session, scopeSession)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ListStorageFirScope(val result: List<FirScope>) : FirScope()
|
private class ListStorageFirScope(val result: List<FirScope>) : FirScope()
|
||||||
Reference in New Issue
Block a user