[LL FIR] rework lazy resolve, so it never resolves local declaration
No local declaration should be available until it's fully resolved
This commit is contained in:
+1
-1
@@ -78,7 +78,7 @@ internal class KtFirScopeProvider(
|
|||||||
body(firSymbol.fir)
|
body(firSymbol.fir)
|
||||||
}
|
}
|
||||||
is KtFirEnumEntrySymbol -> {
|
is KtFirEnumEntrySymbol -> {
|
||||||
firSymbol.lazyResolveToPhase(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE)
|
firSymbol.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE)
|
||||||
val initializer = firSymbol.fir.initializer ?: return null
|
val initializer = firSymbol.fir.initializer ?: return null
|
||||||
check(initializer is FirAnonymousObjectExpression) { "Unexpected enum entry initializer: ${initializer.javaClass}" }
|
check(initializer is FirAnonymousObjectExpression) { "Unexpected enum entry initializer: ${initializer.javaClass}" }
|
||||||
body(initializer.anonymousObject)
|
body(initializer.anonymousObject)
|
||||||
|
|||||||
+2
-9
@@ -11,22 +11,15 @@ import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment
|
|||||||
import org.jetbrains.kotlin.analysis.utils.errors.checkWithAttachmentBuilder
|
import org.jetbrains.kotlin.analysis.utils.errors.checkWithAttachmentBuilder
|
||||||
import org.jetbrains.kotlin.analysis.utils.errors.unexpectedElementError
|
import org.jetbrains.kotlin.analysis.utils.errors.unexpectedElementError
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.fir.FirElementWithResolvePhase
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.FirFileAnnotationsContainer
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
|
||||||
import org.jetbrains.kotlin.fir.containingClassLookupTag
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
||||||
|
import org.jetbrains.kotlin.fir.diagnostics.ConeDestructuringDeclarationsOnTopLevel
|
||||||
import org.jetbrains.kotlin.fir.java.javaSymbolProvider
|
import org.jetbrains.kotlin.fir.java.javaSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLookupTagWithFixedSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLookupTagWithFixedSymbol
|
||||||
import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment
|
|
||||||
import org.jetbrains.kotlin.analysis.utils.errors.checkWithAttachmentBuilder
|
|
||||||
import org.jetbrains.kotlin.fir.containingClass
|
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDestructuringDeclarationsOnTopLevel
|
|
||||||
import org.jetbrains.kotlin.fir.java.javaSymbolProvider
|
|
||||||
|
|
||||||
class FirDesignationWithFile(
|
class FirDesignationWithFile(
|
||||||
path: List<FirRegularClass>,
|
path: List<FirRegularClass>,
|
||||||
|
|||||||
+26
-88
@@ -7,9 +7,8 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignationWithFile
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignationWithFile
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDesignationWithFile
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.throwUnexpectedFirElementError
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.tryCollectDesignationWithFile
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.tryCollectDesignationWithFile
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.getNonLocalContainingOrThisDeclaration
|
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.runCustomResolveUnderLock
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.runCustomResolveUnderLock
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.llFirModuleData
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.llFirModuleData
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSessionInvalidator
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSessionInvalidator
|
||||||
@@ -17,12 +16,11 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirSession
|
|||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.LLFirFirProviderInterceptor
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.LLFirFirProviderInterceptor
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.LLFirLazyTransformerExecutor
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.LLFirLazyTransformerExecutor
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkCanceled
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkCanceled
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.findSourceNonLocalFirDeclaration
|
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.ktDeclaration
|
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirEntry
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirEntry
|
||||||
import org.jetbrains.kotlin.analysis.utils.errors.rethrowExceptionWithDetails
|
import org.jetbrains.kotlin.analysis.utils.errors.rethrowExceptionWithDetails
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.FirElementWithResolvePhase
|
import org.jetbrains.kotlin.fir.FirElementWithResolvePhase
|
||||||
|
import org.jetbrains.kotlin.fir.FirFileAnnotationsContainer
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
|
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
|
||||||
@@ -30,15 +28,9 @@ import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
|||||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.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.analysis.utils.errors.buildErrorWithAttachment
|
|
||||||
import org.jetbrains.kotlin.fir.psi
|
|
||||||
import org.jetbrains.kotlin.psi.*
|
|
||||||
import org.jetbrains.kotlin.util.SourceCodeAnalysisException
|
|
||||||
import org.jetbrains.kotlin.util.shouldIjPlatformExceptionBeRethrown
|
|
||||||
import org.jetbrains.kotlin.psi.KtClassBody
|
import org.jetbrains.kotlin.psi.KtClassBody
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtEnumEntry
|
import org.jetbrains.kotlin.psi.KtEnumEntry
|
||||||
import org.jetbrains.kotlin.psi.KtPrimaryConstructor
|
|
||||||
|
|
||||||
internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirModuleResolveComponents) {
|
internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirModuleResolveComponents) {
|
||||||
|
|
||||||
@@ -71,6 +63,12 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun FirElementWithResolvePhase.isValidForResolve() = when (this) {
|
||||||
|
is FirDeclaration -> isValidForResolve()
|
||||||
|
is FirFileAnnotationsContainer -> true
|
||||||
|
else -> throwUnexpectedFirElementError(this)
|
||||||
|
}
|
||||||
|
|
||||||
private fun lazyResolveFileDeclaration(
|
private fun lazyResolveFileDeclaration(
|
||||||
firFile: FirFile,
|
firFile: FirFile,
|
||||||
toPhase: FirResolvePhase,
|
toPhase: FirResolvePhase,
|
||||||
@@ -198,97 +196,37 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
|
|||||||
scopeSession: ScopeSession,
|
scopeSession: ScopeSession,
|
||||||
toPhase: FirResolvePhase,
|
toPhase: FirResolvePhase,
|
||||||
) {
|
) {
|
||||||
if (toPhase == FirResolvePhase.RAW_FIR) return
|
if (target.resolvePhase >= toPhase) return
|
||||||
if (toPhase == FirResolvePhase.IMPORTS) {
|
if (toPhase == FirResolvePhase.IMPORTS) {
|
||||||
if (fastTrackForImportsPhase(target)) {
|
if (fastTrackForImportsPhase(target)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
when (target) {
|
if (target is FirFile) {
|
||||||
is FirSyntheticPropertyAccessor -> {
|
lazyResolveFileDeclaration(target, toPhase, scopeSession)
|
||||||
lazyResolve(target.delegate, scopeSession, toPhase)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
is FirBackingField -> {
|
|
||||||
lazyResolve(target.propertySymbol.fir, scopeSession, toPhase)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
is FirFile -> {
|
|
||||||
lazyResolveFileDeclaration(target, toPhase, scopeSession)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
else -> {}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target is FirDeclaration && !target.isValidForResolve()) return
|
|
||||||
if (target.resolvePhase >= toPhase) return
|
|
||||||
|
|
||||||
val requestedDeclarationDesignation = target.tryCollectDesignationWithFile()
|
|
||||||
|
|
||||||
val designation: FirDesignationWithFile
|
|
||||||
val neededPhase: FirResolvePhase
|
|
||||||
|
|
||||||
if (target is FirDanglingModifierList) {
|
|
||||||
neededPhase = toPhase
|
|
||||||
val ktFile = target.psi?.containingFile as? KtFile
|
|
||||||
?: error("File for dangling modifier list cannot be null")
|
|
||||||
designation = FirDesignationWithFile(
|
|
||||||
emptyList(),
|
|
||||||
target,
|
|
||||||
moduleComponents.cache.getCachedFirFile(ktFile) ?: error("Fir file for dandling modifier list cannot be null")
|
|
||||||
)
|
|
||||||
} else if (requestedDeclarationDesignation != null) {
|
|
||||||
designation = requestedDeclarationDesignation
|
|
||||||
neededPhase = toPhase
|
|
||||||
} else {
|
|
||||||
val possiblyLocalDeclaration = (target as FirDeclaration).getKtDeclarationForFirElement()
|
|
||||||
val nonLocalDeclaration = possiblyLocalDeclaration.getNonLocalContainingOrThisDeclaration()
|
|
||||||
?: error("Container for local declaration cannot be null")
|
|
||||||
val isLocalDeclarationResolveRequested =
|
|
||||||
possiblyLocalDeclaration != nonLocalDeclaration
|
|
||||||
val isValueParameterInsidePrimaryConstructor = target is FirValueParameter
|
|
||||||
&& possiblyLocalDeclaration is KtPrimaryConstructor
|
|
||||||
|
|
||||||
val declarationToResolve: FirDeclaration
|
|
||||||
|
|
||||||
if (isLocalDeclarationResolveRequested && !isValueParameterInsidePrimaryConstructor) {
|
|
||||||
val enumEntry = possiblyLocalDeclaration.getContainingEnumEntryAsMemberOfEnumEntry() ?: return
|
|
||||||
|
|
||||||
declarationToResolve = enumEntry.findSourceNonLocalFirDeclaration(
|
|
||||||
moduleComponents.firFileBuilder,
|
|
||||||
target.moduleData.session.firProvider,
|
|
||||||
)
|
|
||||||
neededPhase = FirResolvePhase.BODY_RESOLVE
|
|
||||||
} else {
|
|
||||||
declarationToResolve = nonLocalDeclaration.findSourceNonLocalFirDeclaration(
|
|
||||||
moduleComponents.firFileBuilder,
|
|
||||||
target.moduleData.session.firProvider,
|
|
||||||
)
|
|
||||||
neededPhase = toPhase
|
|
||||||
}
|
|
||||||
|
|
||||||
if (declarationToResolve.resolvePhase >= neededPhase) return
|
|
||||||
if (!declarationToResolve.isValidForResolve()) return
|
|
||||||
|
|
||||||
designation = declarationToResolve.collectDesignationWithFile()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (designation.target.resolvePhase >= neededPhase) return
|
|
||||||
|
|
||||||
if (neededPhase == FirResolvePhase.IMPORTS) {
|
|
||||||
resolveFileToImports(designation.firFile)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val designation = declarationDesignationToResolve(target) ?: return
|
||||||
|
if (!designation.target.isValidForResolve()) return
|
||||||
|
if (designation.target.resolvePhase >= toPhase) return
|
||||||
|
|
||||||
moduleComponents.globalResolveComponents.lockProvider.runCustomResolveUnderLock(designation.firFile) {
|
moduleComponents.globalResolveComponents.lockProvider.runCustomResolveUnderLock(designation.firFile) {
|
||||||
runLazyDesignatedResolveWithoutLock(
|
runLazyDesignatedResolveWithoutLock(
|
||||||
designation = designation,
|
designation = designation,
|
||||||
scopeSession = scopeSession,
|
scopeSession = scopeSession,
|
||||||
toPhase = neededPhase,
|
toPhase = toPhase,
|
||||||
)
|
)
|
||||||
designation.target
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun declarationDesignationToResolve(target: FirElementWithResolvePhase): FirDesignationWithFile? {
|
||||||
|
return when (target) {
|
||||||
|
is FirPropertyAccessor -> declarationDesignationToResolve(target.propertySymbol.fir)
|
||||||
|
is FirBackingField -> declarationDesignationToResolve(target.propertySymbol.fir)
|
||||||
|
is FirTypeParameter -> declarationDesignationToResolve(target.containingDeclarationSymbol.fir)
|
||||||
|
is FirValueParameter -> declarationDesignationToResolve(target.containingFunctionSymbol.fir)
|
||||||
|
else -> target.tryCollectDesignationWithFile()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-2
@@ -5,11 +5,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.util
|
package org.jetbrains.kotlin.analysis.low.level.api.fir.util
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirResolvableSession
|
||||||
import org.jetbrains.kotlin.fir.FirElementWithResolvePhase
|
import org.jetbrains.kotlin.fir.FirElementWithResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.FirFileAnnotationsContainer
|
import org.jetbrains.kotlin.fir.FirFileAnnotationsContainer
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.fir.psi
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
fun FirElementWithResolvePhase.getContainingFile(): FirFile? {
|
fun FirElementWithResolvePhase.getContainingFile(): FirFile? {
|
||||||
val provider = moduleData.session.firProvider
|
val provider = moduleData.session.firProvider
|
||||||
@@ -21,7 +23,14 @@ fun FirElementWithResolvePhase.getContainingFile(): FirFile? {
|
|||||||
is FirValueParameter -> containingFunctionSymbol.fir.getContainingFile()
|
is FirValueParameter -> containingFunctionSymbol.fir.getContainingFile()
|
||||||
is FirCallableDeclaration -> provider.getFirCallableContainerFile(symbol)
|
is FirCallableDeclaration -> provider.getFirCallableContainerFile(symbol)
|
||||||
is FirClassLikeDeclaration -> provider.getFirClassifierContainerFile(symbol)
|
is FirClassLikeDeclaration -> provider.getFirClassifierContainerFile(symbol)
|
||||||
is FirDanglingModifierList -> null
|
is FirDanglingModifierList -> {
|
||||||
|
val ktFile = psi?.containingFile as? KtFile
|
||||||
|
?: error("File for dangling modifier list cannot be null")
|
||||||
|
val moduleComponents = llFirResolvableSession?.moduleComponents
|
||||||
|
?: error("LLFirResolvableModuleSession for dangling modifier list cannot be null")
|
||||||
|
moduleComponents.cache.getCachedFirFile(ktFile)
|
||||||
|
?: error("Fir file for dandling modifier list cannot be null")
|
||||||
|
}
|
||||||
else -> errorWithFirSpecificEntries("Unsupported declaration ${this::class.java}", fir = this)
|
else -> errorWithFirSpecificEntries("Unsupported declaration ${this::class.java}", fir = this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user