[FIR IDE] Fix invalid resolve for local declarations that could be fully replaced with new instance

+small optimisations for IMPORTS phase
This commit is contained in:
Igor Yakovlev
2021-08-13 14:35:03 +02:00
parent ed0bfabc51
commit 6360366ecc
8 changed files with 158 additions and 96 deletions
@@ -74,8 +74,8 @@ inline fun <R> KtDeclaration.withFirDeclaration(
action: (FirDeclaration) -> R action: (FirDeclaration) -> R
): R { ): R {
val firDeclaration = resolveState.findSourceFirDeclaration(this) val firDeclaration = resolveState.findSourceFirDeclaration(this)
firDeclaration.resolvedFirToType(resolveType, resolveState) val resolvedDeclaration = firDeclaration.resolvedFirToType(resolveType, resolveState)
return action(firDeclaration) return action(resolvedDeclaration)
} }
/** /**
@@ -124,8 +124,8 @@ fun <D : FirDeclaration, R> D.withFirDeclaration(
phase: FirResolvePhase = FirResolvePhase.RAW_FIR, phase: FirResolvePhase = FirResolvePhase.RAW_FIR,
action: (D) -> R, action: (D) -> R,
): R { ): R {
resolvedFirToPhase(phase, resolveState) val resolvedDeclaration = resolvedFirToPhase(phase, resolveState)
return action(this) return action(resolvedDeclaration)
} }
/** /**
@@ -137,8 +137,8 @@ fun <D : FirDeclaration, R> D.withFirDeclaration(
resolveState: FirModuleResolveState, resolveState: FirModuleResolveState,
action: (D) -> R, action: (D) -> R,
): R { ): R {
resolvedFirToType(type, resolveState) val resolvedDeclaration = resolvedFirToType(type, resolveState)
return action(this) return action(resolvedDeclaration)
} }
/** /**
@@ -116,17 +116,19 @@ internal class FileStructure private constructor(
moduleFileCache, moduleFileCache,
firFile firFile
) )
firLazyDeclarationResolver.lazyResolveDeclaration( val resolvedDeclaration = firLazyDeclarationResolver.lazyResolveDeclaration(
firDeclarationToResolve = firDeclaration, firDeclarationToResolve = firDeclaration,
moduleFileCache = moduleFileCache, moduleFileCache = moduleFileCache,
scopeSession = ScopeSession(), scopeSession = ScopeSession(),
toPhase = FirResolvePhase.BODY_RESOLVE, toPhase = FirResolvePhase.BODY_RESOLVE,
checkPCE = true, checkPCE = true,
) )
return FileElementFactory.createFileStructureElement(firDeclaration, declaration, firFile, moduleFileCache.firFileLockProvider) return FileElementFactory.createFileStructureElement(
// return moduleFileCache.firFileLockProvider.withReadLock(firFile) { firDeclaration = resolvedDeclaration,
// FileElementFactory.createFileStructureElement(firDeclaration, declaration, firFile, moduleFileCache.firFileLockProvider) ktDeclaration = declaration,
// } firFile = firFile,
firFileLockProvider = moduleFileCache.firFileLockProvider
)
} }
private fun createStructureElement(container: KtAnnotated): FileStructureElement = when (container) { private fun createStructureElement(container: KtAnnotated): FileStructureElement = when (container) {
@@ -140,13 +140,16 @@ internal class ReanalyzableFunctionStructureElement(
it.replaceResolvePhase(minOf(it.resolvePhase, upgradedPhase)) it.replaceResolvePhase(minOf(it.resolvePhase, upgradedPhase))
} }
firLazyDeclarationResolver.lazyResolveDeclaration( val resolvedDeclaration = firLazyDeclarationResolver.lazyResolveDeclaration(
firDeclarationToResolve = originalFunction, firDeclarationToResolve = originalFunction,
moduleFileCache = cache, moduleFileCache = cache,
scopeSession = ScopeSession(), scopeSession = ScopeSession(),
toPhase = FirResolvePhase.BODY_RESOLVE, toPhase = FirResolvePhase.BODY_RESOLVE,
checkPCE = true, checkPCE = true,
) )
check(resolvedDeclaration === originalFunction) {
"Reanalysed declaration not expected to be updated"
}
ReanalyzableFunctionStructureElement( ReanalyzableFunctionStructureElement(
firFile, firFile,
@@ -200,13 +203,16 @@ internal class ReanalyzablePropertyStructureElement(
replaceInitializerAndAccessorsAreResolved(false) replaceInitializerAndAccessorsAreResolved(false)
} }
firLazyDeclarationResolver.lazyResolveDeclaration( val resolvedDeclaration = firLazyDeclarationResolver.lazyResolveDeclaration(
firDeclarationToResolve = originalProperty, firDeclarationToResolve = originalProperty,
moduleFileCache = cache, moduleFileCache = cache,
scopeSession = ScopeSession(), scopeSession = ScopeSession(),
toPhase = FirResolvePhase.BODY_RESOLVE, toPhase = FirResolvePhase.BODY_RESOLVE,
checkPCE = true, checkPCE = true,
) )
check(resolvedDeclaration === originalProperty) {
"Reanalysed declaration not expected to be updated"
}
ReanalyzablePropertyStructureElement( ReanalyzablePropertyStructureElement(
firFile, firFile,
@@ -9,8 +9,6 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.runCustomResolveUnderLock
import org.jetbrains.kotlin.idea.fir.low.level.api.util.getContainingFile
enum class ResolveType { enum class ResolveType {
NoResolve, NoResolve,
@@ -28,40 +26,43 @@ enum class ResolveType {
// ResolveForSuperMembers, // ResolveForSuperMembers,
} }
internal fun FirLazyDeclarationResolver.lazyResolveDeclaration( internal fun <D : FirDeclaration> FirLazyDeclarationResolver.lazyResolveDeclaration(
firDeclaration: FirDeclaration, firDeclaration: D,
moduleFileCache: ModuleFileCache, moduleFileCache: ModuleFileCache,
toResolveType: ResolveType, toResolveType: ResolveType,
scopeSession: ScopeSession, scopeSession: ScopeSession,
checkPCE: Boolean = false, checkPCE: Boolean = false,
) { ): D {
when (toResolveType) { return when (toResolveType) {
ResolveType.NoResolve -> return ResolveType.NoResolve -> return firDeclaration
ResolveType.CallableReturnType -> { ResolveType.CallableReturnType -> {
require(firDeclaration is FirCallableDeclaration) { require(firDeclaration is FirCallableDeclaration) {
"CallableReturnType type cannot be applied to ${firDeclaration::class.qualifiedName}" "CallableReturnType type cannot be applied to ${firDeclaration::class.qualifiedName}"
} }
var currentDeclaration = firDeclaration as FirCallableDeclaration
if (firDeclaration.resolvePhase < FirResolvePhase.TYPES) { if (currentDeclaration.resolvePhase < FirResolvePhase.TYPES) {
if (firDeclaration.returnTypeRef is FirResolvedTypeRef) return if (currentDeclaration.returnTypeRef !is FirResolvedTypeRef) {
lazyResolveDeclaration( currentDeclaration = lazyResolveDeclaration(
firDeclarationToResolve = firDeclaration, firDeclarationToResolve = currentDeclaration,
moduleFileCache = moduleFileCache,
toPhase = FirResolvePhase.TYPES,
scopeSession = scopeSession,
checkPCE = checkPCE,
)
}
}
if (currentDeclaration.returnTypeRef !is FirResolvedTypeRef) {
currentDeclaration = lazyResolveDeclaration(
firDeclarationToResolve = currentDeclaration,
moduleFileCache = moduleFileCache, moduleFileCache = moduleFileCache,
toPhase = FirResolvePhase.TYPES, toPhase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE,
scopeSession = scopeSession, scopeSession = scopeSession,
checkPCE = checkPCE, checkPCE = checkPCE,
) )
} }
if (firDeclaration.returnTypeRef is FirResolvedTypeRef) return
lazyResolveDeclaration( check(currentDeclaration.returnTypeRef is FirResolvedTypeRef)
firDeclarationToResolve = firDeclaration, currentDeclaration as D
moduleFileCache = moduleFileCache,
toPhase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE,
scopeSession = scopeSession,
checkPCE = checkPCE,
)
check(firDeclaration.returnTypeRef is FirResolvedTypeRef)
} }
ResolveType.BodyResolveWithChildren, ResolveType.CallableBodyResolve -> { ResolveType.BodyResolveWithChildren, ResolveType.CallableBodyResolve -> {
require(firDeclaration is FirCallableDeclaration || toResolveType != ResolveType.CallableBodyResolve) { require(firDeclaration is FirCallableDeclaration || toResolveType != ResolveType.CallableBodyResolve) {
@@ -84,6 +85,7 @@ internal fun FirLazyDeclarationResolver.lazyResolveDeclaration(
scopeSession = scopeSession, scopeSession = scopeSession,
checkPCE = checkPCE checkPCE = checkPCE
) )
firDeclaration
} else { } else {
val toPhase = val toPhase =
if (toResolveType == ResolveType.AnnotationType) FirResolvePhase.TYPES else FirResolvePhase.ARGUMENTS_OF_ANNOTATIONS if (toResolveType == ResolveType.AnnotationType) FirResolvePhase.TYPES else FirResolvePhase.ARGUMENTS_OF_ANNOTATIONS
@@ -11,7 +11,9 @@ import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirAnnotationResolveStatus import org.jetbrains.kotlin.fir.expressions.FirAnnotationResolveStatus
import org.jetbrains.kotlin.fir.realPsi
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.transformers.FirImportResolveTransformer import org.jetbrains.kotlin.fir.resolve.transformers.FirImportResolveTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirTowerDataContextCollector import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirTowerDataContextCollector
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirDeclarationDesignationWithFile import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirDeclarationDesignationWithFile
@@ -25,6 +27,7 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.providers.firIdeProvider
import org.jetbrains.kotlin.idea.fir.low.level.api.transformers.FirFileAnnotationsResolveTransformer import org.jetbrains.kotlin.idea.fir.low.level.api.transformers.FirFileAnnotationsResolveTransformer
import org.jetbrains.kotlin.idea.fir.low.level.api.transformers.FirProviderInterceptorForIDE import org.jetbrains.kotlin.idea.fir.low.level.api.transformers.FirProviderInterceptorForIDE
import org.jetbrains.kotlin.idea.fir.low.level.api.transformers.LazyTransformerFactory import org.jetbrains.kotlin.idea.fir.low.level.api.transformers.LazyTransformerFactory
import org.jetbrains.kotlin.idea.fir.low.level.api.util.FirElementFinder
import org.jetbrains.kotlin.idea.fir.low.level.api.util.checkCanceled import org.jetbrains.kotlin.idea.fir.low.level.api.util.checkCanceled
import org.jetbrains.kotlin.idea.fir.low.level.api.util.findSourceNonLocalFirDeclaration import org.jetbrains.kotlin.idea.fir.low.level.api.util.findSourceNonLocalFirDeclaration
@@ -45,7 +48,6 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui
moduleFileCache.firFileLockProvider.runCustomResolveUnderLock(firFile, checkPCE) { moduleFileCache.firFileLockProvider.runCustomResolveUnderLock(firFile, checkPCE) {
resolveFileAnnotationsWithoutLock( resolveFileAnnotationsWithoutLock(
firFile = firFile, firFile = firFile,
moduleFileCache = moduleFileCache,
annotations = annotations, annotations = annotations,
scopeSession = scopeSession, scopeSession = scopeSession,
collector = collector collector = collector
@@ -59,20 +61,12 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui
*/ */
private fun resolveFileAnnotationsWithoutLock( private fun resolveFileAnnotationsWithoutLock(
firFile: FirFile, firFile: FirFile,
moduleFileCache: ModuleFileCache,
annotations: List<FirAnnotationCall>, annotations: List<FirAnnotationCall>,
scopeSession: ScopeSession, scopeSession: ScopeSession,
collector: FirTowerDataContextCollector? = null, collector: FirTowerDataContextCollector? = null,
) { ) {
if (firFile.resolvePhase < FirResolvePhase.IMPORTS) { if (firFile.resolvePhase < FirResolvePhase.IMPORTS) {
lazyResolveFileDeclarationWithoutLock( resolveFileToImportsWithoutLock(firFile, false)
firFile = firFile,
moduleFileCache = moduleFileCache,
toPhase = FirResolvePhase.IMPORTS,
scopeSession = scopeSession,
checkPCE = false,
collector = collector
)
} }
if (!annotations.all { it.resolveStatus == FirAnnotationResolveStatus.Resolved }) { if (!annotations.all { it.resolveStatus == FirAnnotationResolveStatus.Resolved }) {
@@ -84,7 +78,6 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui
firTowerDataContextCollector = collector, firTowerDataContextCollector = collector,
).transformDeclaration(firFileBuilder.firPhaseRunner) ).transformDeclaration(firFileBuilder.firPhaseRunner)
} }
} }
private fun FirDeclaration.isValidForResolve(): Boolean = when (origin) { private fun FirDeclaration.isValidForResolve(): Boolean = when (origin) {
@@ -124,6 +117,8 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui
checkPCE: Boolean = false, checkPCE: Boolean = false,
) { ) {
if (toPhase == FirResolvePhase.RAW_FIR) return if (toPhase == FirResolvePhase.RAW_FIR) return
resolveFileToImports(firFile, moduleFileCache, checkPCE)
if (toPhase == FirResolvePhase.IMPORTS) return
if (firFile.resolvePhase >= toPhase) return if (firFile.resolvePhase >= toPhase) return
moduleFileCache.firFileLockProvider.runCustomResolveUnderLock(firFile, checkPCE) { moduleFileCache.firFileLockProvider.runCustomResolveUnderLock(firFile, checkPCE) {
lazyResolveFileDeclarationWithoutLock( lazyResolveFileDeclarationWithoutLock(
@@ -136,6 +131,20 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui
} }
} }
private fun resolveFileToImports(firFile: FirFile, moduleFileCache: ModuleFileCache, checkPCE: Boolean) {
if (firFile.resolvePhase >= FirResolvePhase.IMPORTS) return
moduleFileCache.firFileLockProvider.runCustomResolveUnderLock(firFile, checkPCE) {
resolveFileToImportsWithoutLock(firFile, checkPCE)
}
}
private fun resolveFileToImportsWithoutLock(firFile: FirFile, checkPCE: Boolean) {
if (firFile.resolvePhase >= FirResolvePhase.IMPORTS) return
if (checkPCE) checkCanceled()
firFile.transform<FirElement, Any?>(FirImportResolveTransformer(firFile.moduleData.session), null)
firFile.replaceResolvePhase(FirResolvePhase.IMPORTS)
}
private fun lazyResolveFileDeclarationWithoutLock( private fun lazyResolveFileDeclarationWithoutLock(
firFile: FirFile, firFile: FirFile,
moduleFileCache: ModuleFileCache, moduleFileCache: ModuleFileCache,
@@ -145,16 +154,11 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui
collector: FirTowerDataContextCollector? = null, collector: FirTowerDataContextCollector? = null,
) { ) {
if (toPhase == FirResolvePhase.RAW_FIR) return if (toPhase == FirResolvePhase.RAW_FIR) return
val resolvePhase = firFile.resolvePhase resolveFileToImportsWithoutLock(firFile, checkPCE)
if (resolvePhase >= toPhase) return
if (resolvePhase == FirResolvePhase.RAW_FIR) {
firFile.transform<FirElement, Any?>(FirImportResolveTransformer(firFile.moduleData.session), null)
firFile.replaceResolvePhase(FirResolvePhase.IMPORTS)
}
if (checkPCE) checkCanceled()
if (toPhase == FirResolvePhase.IMPORTS) return if (toPhase == FirResolvePhase.IMPORTS) return
if (checkPCE) checkCanceled()
resolveFileAnnotationsWithoutLock(firFile, moduleFileCache, firFile.annotations, scopeSession, collector) resolveFileAnnotationsWithoutLock(firFile, firFile.annotations, scopeSession, collector)
val validForResolveDeclarations = firFile.declarations val validForResolveDeclarations = firFile.declarations
.filter { it.isValidForResolve() && it.resolvePhase < toPhase } .filter { it.isValidForResolve() && it.resolvePhase < toPhase }
@@ -196,23 +200,44 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui
} }
} }
private fun fastTrackForImportsPhase(
firDeclarationToResolve: FirDeclaration,
moduleFileCache: ModuleFileCache,
checkPCE: Boolean,
): Boolean {
val provider = firDeclarationToResolve.moduleData.session.firProvider
val firFile = when (firDeclarationToResolve) {
is FirFile -> firDeclarationToResolve
is FirCallableDeclaration -> provider.getFirCallableContainerFile(firDeclarationToResolve.symbol)
is FirClassLikeDeclaration -> provider.getFirClassifierContainerFile(firDeclarationToResolve.symbol)
else -> null
} ?: return false
resolveFileToImports(firFile, moduleFileCache, checkPCE)
return true
}
/** /**
* Run designated resolve only designation with fully resolved path (synchronized). * Run designated resolve only designation with fully resolved path (synchronized).
* Suitable for body resolve or/and on-air resolve. * Suitable for body resolve or/and on-air resolve.
* @see lazyResolveDeclaration for ordinary resolve * @see lazyResolveDeclaration for ordinary resolve
* @param firDeclarationToResolve target non-local declaration * @param firDeclarationToResolve target non-local declaration
*/ */
fun lazyResolveDeclaration( fun <D : FirDeclaration> lazyResolveDeclaration(
firDeclarationToResolve: FirDeclaration, firDeclarationToResolve: D,
moduleFileCache: ModuleFileCache, moduleFileCache: ModuleFileCache,
scopeSession: ScopeSession, scopeSession: ScopeSession,
toPhase: FirResolvePhase, toPhase: FirResolvePhase,
checkPCE: Boolean, checkPCE: Boolean,
skipLocalDeclaration: Boolean = false, skipLocalDeclaration: Boolean = false,
) { ): D {
if (toPhase == FirResolvePhase.RAW_FIR) return if (toPhase == FirResolvePhase.RAW_FIR) return firDeclarationToResolve
if (!firDeclarationToResolve.isValidForResolve()) return if (toPhase == FirResolvePhase.IMPORTS) {
if (firDeclarationToResolve.resolvePhase >= toPhase) return if (fastTrackForImportsPhase(firDeclarationToResolve, moduleFileCache, checkPCE)) {
return firDeclarationToResolve
}
}
if (!firDeclarationToResolve.isValidForResolve()) return firDeclarationToResolve
if (firDeclarationToResolve.resolvePhase >= toPhase) return firDeclarationToResolve
if (firDeclarationToResolve is FirFile) { if (firDeclarationToResolve is FirFile) {
lazyResolveFileDeclaration( lazyResolveFileDeclaration(
@@ -222,23 +247,25 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui
scopeSession = scopeSession, scopeSession = scopeSession,
checkPCE = checkPCE, checkPCE = checkPCE,
) )
return return firDeclarationToResolve
} }
val requestedDeclarationDesignation = firDeclarationToResolve.tryCollectDesignationWithFile() val requestedDeclarationDesignation = firDeclarationToResolve.tryCollectDesignationWithFile()
val designation: FirDeclarationDesignationWithFile val designation: FirDeclarationDesignationWithFile
val neededPhase: FirResolvePhase val neededPhase: FirResolvePhase
val isLocalDeclarationResolveRequested: Boolean
if (requestedDeclarationDesignation != null) { if (requestedDeclarationDesignation != null) {
designation = requestedDeclarationDesignation designation = requestedDeclarationDesignation
neededPhase = toPhase neededPhase = toPhase
isLocalDeclarationResolveRequested = false
} else { } else {
val possiblyLocalDeclaration = firDeclarationToResolve.getKtDeclarationForFirElement() val possiblyLocalDeclaration = firDeclarationToResolve.getKtDeclarationForFirElement()
val nonLocalDeclaration = possiblyLocalDeclaration.getNonLocalContainingOrThisDeclaration() val nonLocalDeclaration = possiblyLocalDeclaration.getNonLocalContainingOrThisDeclaration()
?: error("Container for local declaration cannot be null") ?: error("Container for local declaration cannot be null")
val isLocalDeclarationResolveRequested = possiblyLocalDeclaration != nonLocalDeclaration isLocalDeclarationResolveRequested = possiblyLocalDeclaration != nonLocalDeclaration
if (isLocalDeclarationResolveRequested && skipLocalDeclaration) return if (isLocalDeclarationResolveRequested && skipLocalDeclaration) return firDeclarationToResolve
val nonLocalFirDeclaration = nonLocalDeclaration.findSourceNonLocalFirDeclaration( val nonLocalFirDeclaration = nonLocalDeclaration.findSourceNonLocalFirDeclaration(
firFileBuilder, firFileBuilder,
@@ -248,14 +275,19 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui
neededPhase = if (isLocalDeclarationResolveRequested) FirResolvePhase.BODY_RESOLVE else toPhase neededPhase = if (isLocalDeclarationResolveRequested) FirResolvePhase.BODY_RESOLVE else toPhase
if (nonLocalFirDeclaration.resolvePhase >= neededPhase) return if (nonLocalFirDeclaration.resolvePhase >= neededPhase) return firDeclarationToResolve
if (!nonLocalFirDeclaration.isValidForResolve()) return if (!nonLocalFirDeclaration.isValidForResolve()) return firDeclarationToResolve
designation = nonLocalFirDeclaration.collectDesignationWithFile() designation = nonLocalFirDeclaration.collectDesignationWithFile()
} }
if (firDeclarationToResolve.resolvePhase >= toPhase) return if (designation.declaration.resolvePhase >= neededPhase) return firDeclarationToResolve
if (neededPhase == FirResolvePhase.IMPORTS) {
resolveFileToImports(designation.firFile, moduleFileCache, checkPCE)
return firDeclarationToResolve
}
moduleFileCache.firFileLockProvider.runCustomResolveUnderLock(designation.firFile, checkPCE) { moduleFileCache.firFileLockProvider.runCustomResolveUnderLock(designation.firFile, checkPCE) {
runLazyDesignatedResolveWithoutLock( runLazyDesignatedResolveWithoutLock(
designation = designation, designation = designation,
@@ -265,6 +297,31 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui
checkPCE = checkPCE, checkPCE = checkPCE,
) )
} }
if (!isLocalDeclarationResolveRequested) return firDeclarationToResolve
return remapDeclarationInContainerIfNeeded(firDeclarationToResolve, designation.declaration, toPhase)
}
private fun <D : FirDeclaration> remapDeclarationInContainerIfNeeded(
declarationToRemap: D,
firContainer: FirDeclaration,
firResolvePhase: FirResolvePhase
): D {
if (declarationToRemap.resolvePhase >= firResolvePhase) return declarationToRemap
val realPsi = declarationToRemap.realPsi
check(realPsi != null) {
"Cannot remap element without PSI"
}
val firDeclaration = FirElementFinder.findElementIn<FirDeclaration>(firContainer) {
it.realPsi == realPsi
} as? D
check(firDeclaration != null) {
"Containing declaration was resolved but local didn't found in it"
}
check(firDeclaration.resolvePhase >= firResolvePhase) {
"Found local declaration wasn't completely resolved"
}
return firDeclaration
} }
private fun runLazyDesignatedResolveWithoutLock( private fun runLazyDesignatedResolveWithoutLock(
@@ -275,19 +332,12 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui
checkPCE: Boolean, checkPCE: Boolean,
) { ) {
if (toPhase == FirResolvePhase.RAW_FIR) return if (toPhase == FirResolvePhase.RAW_FIR) return
resolveFileToImportsWithoutLock(designation.firFile, checkPCE)
if (toPhase == FirResolvePhase.IMPORTS) return
val declarationResolvePhase = designation.declaration.resolvePhase val declarationResolvePhase = designation.declaration.resolvePhase
if (declarationResolvePhase >= toPhase) return if (declarationResolvePhase >= toPhase) return
if (designation.firFile.resolvePhase == FirResolvePhase.RAW_FIR) {
lazyResolveFileDeclarationWithoutLock(
firFile = designation.firFile,
moduleFileCache = moduleFileCache,
toPhase = FirResolvePhase.IMPORTS,
scopeSession = scopeSession,
checkPCE = checkPCE
)
}
if (toPhase == FirResolvePhase.IMPORTS) return
var currentPhase = maxOf(declarationResolvePhase, FirResolvePhase.IMPORTS) var currentPhase = maxOf(declarationResolvePhase, FirResolvePhase.IMPORTS)
while (currentPhase < toPhase) { while (currentPhase < toPhase) {
@@ -315,9 +365,11 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui
onAirCreatedDeclaration: Boolean, onAirCreatedDeclaration: Boolean,
towerDataContextCollector: FirTowerDataContextCollector?, towerDataContextCollector: FirTowerDataContextCollector?,
) { ) {
val scopeSession = ScopeSession() resolveFileToImportsWithoutLock(designation.firFile, checkPCE)
var currentPhase = maxOf(designation.declaration.resolvePhase, FirResolvePhase.IMPORTS) var currentPhase = maxOf(designation.declaration.resolvePhase, FirResolvePhase.IMPORTS)
val scopeSession = ScopeSession()
val firProviderInterceptor = if (onAirCreatedDeclaration) { val firProviderInterceptor = if (onAirCreatedDeclaration) {
FirProviderInterceptorForIDE.createForFirElement( FirProviderInterceptorForIDE.createForFirElement(
session = designation.firFile.moduleData.session, session = designation.firFile.moduleData.session,
@@ -22,19 +22,19 @@ FILE: localDeclaration.kt
IMPORTS: IMPORTS:
FILE: localDeclaration.kt FILE: localDeclaration.kt
public final [STATUS] class A : R|kotlin/Any| { public? final? [RAW_FIR] class A : R|kotlin/Any| {
public [STATUS] [ContainingClassKey=A] constructor(): R|A| { public? [RAW_FIR] [ContainingClassKey=A] constructor(): R|A| {
super<R|kotlin/Any|>() super<R|kotlin/Any|>()
} }
public final [BODY_RESOLVE] fun x(): R|kotlin/Unit| { public? final? [RAW_FIR] fun x(): R|kotlin/Unit| {
local final [BODY_RESOLVE] [ContainingClassKey=A] class resolveMe : R|kotlin/Any| { local final? [RAW_FIR] [ContainingClassKey=A] class resolveMe : R|kotlin/Any| {
public [BODY_RESOLVE] [ContainingClassKey=resolveMe] constructor(): R|A.resolveMe| { public? [RAW_FIR] [ContainingClassKey=resolveMe] constructor(): R|A.resolveMe| {
super<R|kotlin/Any|>() super<R|kotlin/Any|>()
} }
public final [BODY_RESOLVE] val e: R|kotlin/Int| = Int(2) public? final? [RAW_FIR] val e: <implicit> = IntegerLiteral(2)
[BODY_RESOLVE] [ContainingClassKey=resolveMe] public get(): R|kotlin/Int| [TYPES] [ContainingClassKey=resolveMe] public? get(): <implicit>
} }
@@ -15,13 +15,13 @@ FILE: localFunction.kt
IMPORTS: IMPORTS:
FILE: localFunction.kt FILE: localFunction.kt
public final [STATUS] class A : R|kotlin/Any| { public? final? [RAW_FIR] class A : R|kotlin/Any| {
public [STATUS] [ContainingClassKey=A] constructor(): R|A| { public? [RAW_FIR] [ContainingClassKey=A] constructor(): R|A| {
super<R|kotlin/Any|>() super<R|kotlin/Any|>()
} }
public final [BODY_RESOLVE] fun x(): R|kotlin/Unit| { public? final? [RAW_FIR] fun x(): R|kotlin/Unit| {
local final [BODY_RESOLVE] fun resolveMe(): R|kotlin/Unit| { local final? [RAW_FIR] fun resolveMe(): R|kotlin/Unit| {
} }
} }
@@ -18,16 +18,16 @@ FILE: parameterOfLocalSetter.kt
IMPORTS: IMPORTS:
FILE: parameterOfLocalSetter.kt FILE: parameterOfLocalSetter.kt
public final [BODY_RESOLVE] fun ddd(): R|kotlin/Unit| { public? final? [RAW_FIR] fun ddd(): R|kotlin/Unit| {
local final [BODY_RESOLVE] class XX : R|kotlin/Any| { local final? [RAW_FIR] class XX : R|kotlin/Any| {
public [BODY_RESOLVE] [ContainingClassKey=XX] constructor(): R|XX| { public? [RAW_FIR] [ContainingClassKey=XX] constructor(): R|XX| {
super<R|kotlin/Any|>() super<R|kotlin/Any|>()
} }
public final [BODY_RESOLVE] var x: R|kotlin/Int| = Int(2) public? final? [RAW_FIR] var x: Int = IntegerLiteral(2)
[BODY_RESOLVE] [ContainingClassKey=XX] public get(): R|kotlin/Int| [TYPES] [ContainingClassKey=XX] public? get(): Int
[BODY_RESOLVE] [ContainingClassKey=XX] public set([BODY_RESOLVE] resolveMe: R|kotlin/Int|): R|kotlin/Unit| { [RAW_FIR] [ContainingClassKey=XX] public? set([RAW_FIR] resolveMe: Int): R|kotlin/Unit| {
^ Q|kotlin/Unit| ^ Unit#
} }
} }