[LL FIR] rework lazy annotation resolve for file to remove hacks
The previous solution blocked implementation of parallel resolve
This commit is contained in:
+2
-2
@@ -18,8 +18,8 @@ internal class LLFirLazyDeclarationResolver : FirLazyDeclarationResolver() {
|
||||
val session = fir.moduleData.session
|
||||
if (session !is LLFirResolvableModuleSession) return
|
||||
val moduleComponents = session.moduleComponents
|
||||
moduleComponents.firModuleLazyDeclarationResolver.lazyResolveDeclaration(
|
||||
firDeclarationToResolve = fir,
|
||||
moduleComponents.firModuleLazyDeclarationResolver.lazyResolve(
|
||||
target = fir,
|
||||
scopeSession = moduleComponents.scopeSessionProvider.getScopeSession(),
|
||||
toPhase = toPhase,
|
||||
checkPCE = true,
|
||||
|
||||
+12
-12
@@ -62,19 +62,19 @@ private fun FirRegularClass.collectForNonLocal(): List<FirDeclaration> {
|
||||
return designation
|
||||
}
|
||||
|
||||
private fun collectDesignationPath(resolvable: FirElementWithResolvePhase): List<FirDeclaration>? {
|
||||
val containingClass = when (resolvable) {
|
||||
private fun collectDesignationPath(target: FirElementWithResolvePhase): List<FirDeclaration>? {
|
||||
val containingClass = when (target) {
|
||||
is FirCallableDeclaration -> {
|
||||
if (resolvable !is FirConstructor && resolvable.symbol.callableId.isLocal) return null
|
||||
if ((resolvable as? FirCallableDeclaration)?.status?.visibility == Visibilities.Local) return null
|
||||
when (resolvable) {
|
||||
if (target !is FirConstructor && target.symbol.callableId.isLocal) return null
|
||||
if ((target as? FirCallableDeclaration)?.status?.visibility == Visibilities.Local) return null
|
||||
when (target) {
|
||||
is FirSimpleFunction, is FirProperty, is FirField, is FirConstructor, is FirEnumEntry, is FirPropertyAccessor -> {
|
||||
val klass = resolvable.containingClassLookupTag() ?: return emptyList()
|
||||
val klass = target.containingClassLookupTag() ?: return emptyList()
|
||||
if (klass.classId.isLocal) return null
|
||||
klass.toFirRegularClassFromSameSession(resolvable.moduleData.session)
|
||||
klass.toFirRegularClassFromSameSession(target.moduleData.session)
|
||||
}
|
||||
is FirErrorProperty -> {
|
||||
return if (resolvable.diagnostic == ConeDestructuringDeclarationsOnTopLevel) {
|
||||
return if (target.diagnostic == ConeDestructuringDeclarationsOnTopLevel) {
|
||||
emptyList()
|
||||
} else {
|
||||
null
|
||||
@@ -84,10 +84,10 @@ private fun collectDesignationPath(resolvable: FirElementWithResolvePhase): List
|
||||
}
|
||||
}
|
||||
is FirClassLikeDeclaration -> {
|
||||
if (resolvable.isLocal) return null
|
||||
val outerClassId = resolvable.symbol.classId.outerClassId
|
||||
outerClassId?.let(resolvable.moduleData.session.firProvider::getFirClassifierByFqName)
|
||||
?: outerClassId?.let(resolvable.moduleData.session.javaSymbolProvider::getClassLikeSymbolByClassId)?.fir
|
||||
if (target.isLocal) return null
|
||||
val outerClassId = target.symbol.classId.outerClassId
|
||||
outerClassId?.let(target.moduleData.session.firProvider::getFirClassifierByFqName)
|
||||
?: outerClassId?.let(target.moduleData.session.javaSymbolProvider::getClassLikeSymbolByClassId)?.fir
|
||||
}
|
||||
else -> return null
|
||||
} ?: return emptyList()
|
||||
|
||||
+10
-5
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.analysis.utils.printer.getElementTextInContext
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.parentOfType
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.parentsOfType
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.builder.buildFileAnnotationsContainer
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.realPsi
|
||||
@@ -188,18 +189,22 @@ object LowLevelFirApiFacadeForResolveOnAir {
|
||||
fileAnnotation = annotationEntry,
|
||||
replacement = replacement
|
||||
)
|
||||
val fileAnnotationsContainer = buildFileAnnotationsContainer {
|
||||
moduleData = firFile.moduleData
|
||||
containingFileSymbol = firFile.symbol
|
||||
annotations += annotationCall
|
||||
}
|
||||
val llFirResolvableSession = firFile.llFirResolvableSession
|
||||
?: buildErrorWithAttachment("FirFile session expected to be a resolvable session but was ${firFile.llFirSession::class.java}") {
|
||||
withEntry("firSession", firFile.llFirSession) { it.toString() }
|
||||
}
|
||||
val declarationResolver = llFirResolvableSession.moduleComponents.firModuleLazyDeclarationResolver
|
||||
|
||||
declarationResolver.resolveFileAnnotations(
|
||||
firFile = firFile,
|
||||
annotations = listOf(annotationCall),
|
||||
scopeSession = ScopeSession(),
|
||||
declarationResolver.runLazyDesignatedOnAirResolveToBodyWithoutLock(
|
||||
FirDesignationWithFile(path = emptyList(), target = fileAnnotationsContainer, firFile),
|
||||
checkPCE = true,
|
||||
collector = collector
|
||||
onAirCreatedDeclaration = true,
|
||||
collector
|
||||
)
|
||||
|
||||
return annotationCall
|
||||
|
||||
+5
-4
@@ -49,7 +49,7 @@ internal class FileStructure private constructor(
|
||||
when {
|
||||
structureElement == null -> createStructureElement(declaration)
|
||||
structureElement is ReanalyzableStructureElement<KtDeclaration, *> && !structureElement.isUpToDate() -> {
|
||||
structureElement.reanalyze(newKtDeclaration = declaration as KtDeclaration,)
|
||||
structureElement.reanalyze(newKtDeclaration = declaration as KtDeclaration)
|
||||
}
|
||||
else -> structureElement
|
||||
}
|
||||
@@ -115,12 +115,13 @@ internal class FileStructure private constructor(
|
||||
private fun createStructureElement(container: KtAnnotated): FileStructureElement = when (container) {
|
||||
is KtFile -> {
|
||||
val firFile = moduleComponents.firFileBuilder.buildRawFirFileWithCaching(ktFile)
|
||||
moduleComponents.firModuleLazyDeclarationResolver.resolveFileAnnotations(
|
||||
firFile = firFile,
|
||||
annotations = firFile.annotations,
|
||||
moduleComponents.firModuleLazyDeclarationResolver.lazyResolve(
|
||||
target = firFile.annotationsContainer,
|
||||
scopeSession = moduleComponents.scopeSessionProvider.getScopeSession(),
|
||||
FirResolvePhase.BODY_RESOLVE,
|
||||
checkPCE = true
|
||||
)
|
||||
|
||||
RootStructureElement(firFile, container, moduleComponents)
|
||||
}
|
||||
is KtDeclaration -> createDeclarationStructure(container)
|
||||
|
||||
+38
-90
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.runCustomRes
|
||||
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.llFirSession
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.LLFirFileAnnotationsResolveTransformer
|
||||
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.util.checkCanceled
|
||||
@@ -22,10 +21,10 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.util.findSourceNonLocalFi
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirEntry
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirElementWithResolvePhase
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirImportResolveTransformer
|
||||
@@ -38,57 +37,6 @@ import org.jetbrains.kotlin.util.SourceCodeAnalysisException
|
||||
import org.jetbrains.kotlin.util.shouldIjPlatformExceptionBeRethrown
|
||||
|
||||
internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirModuleResolveComponents) {
|
||||
/**
|
||||
* Fully resolve file annotations (synchronized)
|
||||
* @see resolveFileAnnotationsWithoutLock not synchronized
|
||||
*/
|
||||
fun resolveFileAnnotations(
|
||||
firFile: FirFile,
|
||||
annotations: List<FirAnnotation>,
|
||||
scopeSession: ScopeSession,
|
||||
checkPCE: Boolean,
|
||||
collector: FirTowerDataContextCollector? = null,
|
||||
) {
|
||||
val fromPhase = firFile.resolvePhase
|
||||
try {
|
||||
if (firFile.resolvePhase >= FirResolvePhase.IMPORTS && annotations.all { it.resolved }) return
|
||||
moduleComponents.globalResolveComponents.lockProvider.runCustomResolveUnderLock(firFile, checkPCE) {
|
||||
resolveFileAnnotationsWithoutLock(
|
||||
firFile = firFile,
|
||||
annotations = annotations,
|
||||
scopeSession = scopeSession,
|
||||
collector = collector
|
||||
)
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
handleExceptionFromResolve(e, moduleComponents.sessionInvalidator, firFile, fromPhase, toPhase = null)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fully resolve file annotations (not synchronized)
|
||||
* @see resolveFileAnnotations synchronized version
|
||||
*/
|
||||
private fun resolveFileAnnotationsWithoutLock(
|
||||
firFile: FirFile,
|
||||
annotations: List<FirAnnotation>,
|
||||
scopeSession: ScopeSession,
|
||||
collector: FirTowerDataContextCollector? = null,
|
||||
) {
|
||||
if (firFile.resolvePhase < FirResolvePhase.IMPORTS) {
|
||||
resolveFileToImportsWithoutLock(firFile, false)
|
||||
}
|
||||
|
||||
if (!annotations.all { it.resolved }) {
|
||||
LLFirFileAnnotationsResolveTransformer(
|
||||
firFile = firFile,
|
||||
annotations = annotations,
|
||||
session = firFile.moduleData.session,
|
||||
scopeSession = scopeSession,
|
||||
firTowerDataContextCollector = collector,
|
||||
).transformDeclaration(moduleComponents.globalResolveComponents.phaseRunner)
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirDeclaration.isValidForResolve(): Boolean = when (origin) {
|
||||
is FirDeclarationOrigin.Source,
|
||||
@@ -173,10 +121,11 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
|
||||
if (toPhase == FirResolvePhase.IMPORTS) return
|
||||
if (checkPCE) checkCanceled()
|
||||
|
||||
resolveFileAnnotationsWithoutLock(firFile, firFile.annotations, scopeSession, collector)
|
||||
val validForResolveDeclarations = buildList {
|
||||
add(firFile.annotationsContainer)
|
||||
firFile.declarations.filterTo(this) { it.isValidForResolve() }
|
||||
}.filter { it.resolvePhase < toPhase }
|
||||
|
||||
val validForResolveDeclarations = firFile.declarations
|
||||
.filter { it.isValidForResolve() && it.resolvePhase < toPhase }
|
||||
|
||||
if (validForResolveDeclarations.isEmpty()) return
|
||||
val designations = validForResolveDeclarations.map {
|
||||
@@ -213,14 +162,14 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
|
||||
}
|
||||
|
||||
private fun fastTrackForImportsPhase(
|
||||
firDeclarationToResolve: FirDeclaration,
|
||||
target: FirElementWithResolvePhase,
|
||||
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)
|
||||
val provider = target.moduleData.session.firProvider
|
||||
val firFile = when (target) {
|
||||
is FirFile -> target
|
||||
is FirCallableDeclaration -> provider.getFirCallableContainerFile(target.symbol)
|
||||
is FirClassLikeDeclaration -> provider.getFirClassifierContainerFile(target.symbol)
|
||||
else -> null
|
||||
} ?: return false
|
||||
resolveFileToImports(firFile, checkPCE)
|
||||
@@ -230,58 +179,57 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
|
||||
/**
|
||||
* Run designated resolve only designation with fully resolved path (synchronized).
|
||||
* Suitable for body resolve or/and on-air resolve.
|
||||
* @see lazyResolveDeclaration for ordinary resolve
|
||||
* @param firDeclarationToResolve target non-local declaration
|
||||
* @see lazyResolve for ordinary resolve
|
||||
* @param target target non-local declaration
|
||||
*/
|
||||
fun lazyResolveDeclaration(
|
||||
firDeclarationToResolve: FirDeclaration,
|
||||
fun lazyResolve(
|
||||
target: FirElementWithResolvePhase,
|
||||
scopeSession: ScopeSession,
|
||||
toPhase: FirResolvePhase,
|
||||
checkPCE: Boolean,
|
||||
) {
|
||||
val fromPhase = firDeclarationToResolve.resolvePhase
|
||||
val fromPhase = target.resolvePhase
|
||||
try {
|
||||
doLazyResolveDeclaration(firDeclarationToResolve, scopeSession, toPhase, checkPCE)
|
||||
doLazyResolve(target, scopeSession, toPhase, checkPCE)
|
||||
} catch (e: Throwable) {
|
||||
handleExceptionFromResolve(e, moduleComponents.sessionInvalidator, firDeclarationToResolve, fromPhase, toPhase)
|
||||
handleExceptionFromResolve(e, moduleComponents.sessionInvalidator, target, fromPhase, toPhase)
|
||||
}
|
||||
}
|
||||
|
||||
private fun doLazyResolveDeclaration(
|
||||
firDeclarationToResolve: FirDeclaration,
|
||||
private fun doLazyResolve(
|
||||
target: FirElementWithResolvePhase,
|
||||
scopeSession: ScopeSession,
|
||||
toPhase: FirResolvePhase,
|
||||
checkPCE: Boolean,
|
||||
) {
|
||||
if (toPhase == FirResolvePhase.RAW_FIR) return
|
||||
if (toPhase == FirResolvePhase.IMPORTS) {
|
||||
if (fastTrackForImportsPhase(firDeclarationToResolve, checkPCE)) {
|
||||
if (fastTrackForImportsPhase(target, checkPCE)) {
|
||||
return
|
||||
}
|
||||
}
|
||||
when (firDeclarationToResolve) {
|
||||
when (target) {
|
||||
is FirSyntheticPropertyAccessor -> {
|
||||
lazyResolveDeclaration(firDeclarationToResolve.delegate, scopeSession, toPhase, checkPCE,)
|
||||
lazyResolve(target.delegate, scopeSession, toPhase, checkPCE,)
|
||||
return
|
||||
}
|
||||
|
||||
is FirBackingField -> {
|
||||
lazyResolveDeclaration(firDeclarationToResolve.propertySymbol.fir, scopeSession, toPhase, checkPCE,)
|
||||
lazyResolve(target.propertySymbol.fir, scopeSession, toPhase, checkPCE,)
|
||||
return
|
||||
}
|
||||
|
||||
is FirFile -> {
|
||||
lazyResolveFileDeclaration(firDeclarationToResolve, toPhase, scopeSession, checkPCE = checkPCE)
|
||||
lazyResolveFileDeclaration(target, toPhase, scopeSession, checkPCE = checkPCE)
|
||||
return
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
|
||||
if (!firDeclarationToResolve.isValidForResolve()) return
|
||||
if (firDeclarationToResolve.resolvePhase >= toPhase) return
|
||||
if (target is FirDeclaration && !target.isValidForResolve()) return
|
||||
if (target.resolvePhase >= toPhase) return
|
||||
|
||||
|
||||
val requestedDeclarationDesignation = firDeclarationToResolve.tryCollectDesignationWithFile()
|
||||
val requestedDeclarationDesignation = target.tryCollectDesignationWithFile()
|
||||
|
||||
val designation: FirDesignationWithFile
|
||||
val neededPhase: FirResolvePhase
|
||||
@@ -290,12 +238,12 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
|
||||
designation = requestedDeclarationDesignation
|
||||
neededPhase = toPhase
|
||||
} else {
|
||||
val possiblyLocalDeclaration = firDeclarationToResolve.getKtDeclarationForFirElement()
|
||||
val possiblyLocalDeclaration = (target as FirDeclaration).getKtDeclarationForFirElement()
|
||||
val nonLocalDeclaration = possiblyLocalDeclaration.getNonLocalContainingOrThisDeclaration()
|
||||
?: error("Container for local declaration cannot be null")
|
||||
val isLocalDeclarationResolveRequested =
|
||||
possiblyLocalDeclaration != nonLocalDeclaration
|
||||
val isValueParameterInsidePrimaryConstructor = firDeclarationToResolve is FirValueParameter
|
||||
val isValueParameterInsidePrimaryConstructor = target is FirValueParameter
|
||||
&& possiblyLocalDeclaration is KtPrimaryConstructor
|
||||
|
||||
val declarationToResolve: FirDeclaration
|
||||
@@ -305,13 +253,13 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
|
||||
|
||||
declarationToResolve = enumEntry.findSourceNonLocalFirDeclaration(
|
||||
moduleComponents.firFileBuilder,
|
||||
firDeclarationToResolve.moduleData.session.firProvider,
|
||||
target.moduleData.session.firProvider,
|
||||
)
|
||||
neededPhase = FirResolvePhase.BODY_RESOLVE
|
||||
} else {
|
||||
declarationToResolve = nonLocalDeclaration.findSourceNonLocalFirDeclaration(
|
||||
moduleComponents.firFileBuilder,
|
||||
firDeclarationToResolve.moduleData.session.firProvider,
|
||||
target.moduleData.session.firProvider,
|
||||
)
|
||||
neededPhase = toPhase
|
||||
}
|
||||
@@ -413,7 +361,7 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
|
||||
private fun handleExceptionFromResolve(
|
||||
e: Throwable,
|
||||
sessionInvalidator: LLFirSessionInvalidator,
|
||||
firDeclarationToResolve: FirDeclaration,
|
||||
firDeclarationToResolve: FirElementWithResolvePhase,
|
||||
fromPhase: FirResolvePhase,
|
||||
toPhase: FirResolvePhase?
|
||||
): Nothing {
|
||||
@@ -425,11 +373,11 @@ private fun handleExceptionFromResolve(
|
||||
appendLine("Error while resolving ${firDeclarationToResolve::class.java.name} ")
|
||||
appendLine("from $fromPhase to $toPhase")
|
||||
appendLine("current declaration phase ${firDeclarationToResolve.resolvePhase}")
|
||||
appendLine("declaration origin: ${firDeclarationToResolve.origin}")
|
||||
appendLine("declaration session: ${firDeclarationToResolve.llFirSession::class}")
|
||||
appendLine("declaration module data: ${moduleData::class}")
|
||||
appendLine("declaration KtModule: ${moduleData.ktModule::class}")
|
||||
appendLine("declaration platform: ${moduleData.ktModule.platform}")
|
||||
appendLine("origin: ${(firDeclarationToResolve as? FirDeclaration)?.origin}")
|
||||
appendLine("session: ${firDeclarationToResolve.llFirSession::class}")
|
||||
appendLine("module data: ${moduleData::class}")
|
||||
appendLine("KtModule: ${moduleData.ktModule::class}")
|
||||
appendLine("platform: ${moduleData.ktModule.platform}")
|
||||
},
|
||||
cause = if (e is SourceCodeAnalysisException) e.cause else e,
|
||||
) {
|
||||
|
||||
+6
-6
@@ -48,14 +48,14 @@ internal class LLFirDesignatedAnnotationArgumentsMappingTransformer(
|
||||
checkIsResolved(designation.target)
|
||||
}
|
||||
|
||||
override fun checkIsResolved(resolvable: FirElementWithResolvePhase) {
|
||||
resolvable.checkPhase(FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING)
|
||||
if (resolvable !is FirAnnotationContainer) return
|
||||
for (annotation in resolvable.annotations) {
|
||||
override fun checkIsResolved(target: FirElementWithResolvePhase) {
|
||||
target.checkPhase(FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING)
|
||||
if (target !is FirAnnotationContainer) return
|
||||
for (annotation in target.annotations) {
|
||||
if (annotation is FirAnnotationCall) {
|
||||
checkAnnotationArgumentsMappingIsResolved(annotation, resolvable)
|
||||
checkAnnotationArgumentsMappingIsResolved(annotation, target)
|
||||
}
|
||||
}
|
||||
checkNestedDeclarationsAreResolved(resolvable)
|
||||
checkNestedDeclarationsAreResolved(target)
|
||||
}
|
||||
}
|
||||
|
||||
+8
-7
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignationWithFil
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkPhase
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkTypeRefIsResolved
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirEntry
|
||||
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
||||
import org.jetbrains.kotlin.fir.FirElementWithResolvePhase
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
@@ -66,23 +67,23 @@ internal class LLFirDesignatedAnnotationArgumentsResolveTransformer(
|
||||
checkIsResolved(designation.target)
|
||||
}
|
||||
|
||||
override fun checkIsResolved(resolvable: FirElementWithResolvePhase) {
|
||||
if (resolvable !is FirDeclaration) return
|
||||
val unresolvedAnnotation = resolvable.annotations.firstOrNull { it.annotationTypeRef !is FirResolvedTypeRef }
|
||||
override fun checkIsResolved(target: FirElementWithResolvePhase) {
|
||||
if (target !is FirAnnotationContainer) return
|
||||
val unresolvedAnnotation = target.annotations.firstOrNull { it.annotationTypeRef !is FirResolvedTypeRef }
|
||||
check(unresolvedAnnotation == null) {
|
||||
"Unexpected annotationTypeRef annotation, expected resolvedType but actual ${unresolvedAnnotation?.annotationTypeRef}"
|
||||
}
|
||||
resolvable.checkPhase(FirResolvePhase.ARGUMENTS_OF_ANNOTATIONS)
|
||||
target.checkPhase(FirResolvePhase.ARGUMENTS_OF_ANNOTATIONS)
|
||||
|
||||
for (annotation in resolvable.annotations) {
|
||||
for (annotation in target.annotations) {
|
||||
for (argument in annotation.argumentMapping.mapping.values) {
|
||||
checkTypeRefIsResolved(argument.typeRef, "annotation argument", resolvable) {
|
||||
checkTypeRefIsResolved(argument.typeRef, "annotation argument", target) {
|
||||
withFirEntry("firAnnotation", annotation)
|
||||
withFirEntry("firArgument", argument)
|
||||
}
|
||||
}
|
||||
}
|
||||
checkNestedDeclarationsAreResolved(resolvable)
|
||||
checkNestedDeclarationsAreResolved(target)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -57,8 +57,8 @@ internal class LLFirDesignatedAnnotationsResolveTransformed(
|
||||
checkIsResolved(designation.target)
|
||||
}
|
||||
|
||||
override fun checkIsResolved(resolvable: FirElementWithResolvePhase) {
|
||||
resolvable.checkPhase(FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS)
|
||||
override fun checkIsResolved(target: FirElementWithResolvePhase) {
|
||||
target.checkPhase(FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS)
|
||||
// todo add proper check that COMPILER_REQUIRED_ANNOTATIONS are resolved
|
||||
// checkNestedDeclarationsAreResolved(declaration)
|
||||
}
|
||||
|
||||
+3
-3
@@ -64,9 +64,9 @@ internal class LLFirDesignatedBodyResolveTransformer(
|
||||
checkIsResolved(designation.target)
|
||||
}
|
||||
|
||||
override fun checkIsResolved(resolvable: FirElementWithResolvePhase) {
|
||||
resolvable.checkPhase(FirResolvePhase.BODY_RESOLVE)
|
||||
checkNestedDeclarationsAreResolved(resolvable)
|
||||
override fun checkIsResolved(target: FirElementWithResolvePhase) {
|
||||
target.checkPhase(FirResolvePhase.BODY_RESOLVE)
|
||||
checkNestedDeclarationsAreResolved(target)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -57,11 +57,11 @@ internal class LLFirDesignatedContractsResolveTransformer(
|
||||
checkIsResolved(designation.target)
|
||||
}
|
||||
|
||||
override fun checkIsResolved(resolvable: FirElementWithResolvePhase) {
|
||||
resolvable.checkPhase(FirResolvePhase.CONTRACTS)
|
||||
if (resolvable is FirContractDescriptionOwner) {
|
||||
override fun checkIsResolved(target: FirElementWithResolvePhase) {
|
||||
target.checkPhase(FirResolvePhase.CONTRACTS)
|
||||
if (target is FirContractDescriptionOwner) {
|
||||
// TODO checkContractDescriptionIsResolved(declaration)
|
||||
}
|
||||
checkNestedDeclarationsAreResolved(resolvable)
|
||||
checkNestedDeclarationsAreResolved(target)
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -52,10 +52,10 @@ internal class LLFirDesignatedExpectActualMatcherTransformer(
|
||||
checkIsResolved(designation.target)
|
||||
}
|
||||
|
||||
override fun checkIsResolved(resolvable: FirElementWithResolvePhase) {
|
||||
resolvable.checkPhase(FirResolvePhase.EXPECT_ACTUAL_MATCHING)
|
||||
override fun checkIsResolved(target: FirElementWithResolvePhase) {
|
||||
target.checkPhase(FirResolvePhase.EXPECT_ACTUAL_MATCHING)
|
||||
// TODO check if expect-actual matching is present
|
||||
checkNestedDeclarationsAreResolved(resolvable)
|
||||
checkNestedDeclarationsAreResolved(target)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -30,7 +30,7 @@ internal class LLFirDesignatedGeneratedCompanionObjectResolveTransformer(
|
||||
checkIsResolved(designation.target)
|
||||
}
|
||||
|
||||
override fun checkIsResolved(resolvable: FirElementWithResolvePhase) {
|
||||
check(resolvable.resolvePhase >= FirResolvePhase.COMPANION_GENERATION)
|
||||
override fun checkIsResolved(target: FirElementWithResolvePhase) {
|
||||
check(target.resolvePhase >= FirResolvePhase.COMPANION_GENERATION)
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -64,11 +64,11 @@ internal class LLFirDesignatedImplicitTypesTransformer(
|
||||
checkIsResolved(designation.target)
|
||||
}
|
||||
|
||||
override fun checkIsResolved(resolvable: FirElementWithResolvePhase) {
|
||||
resolvable.checkPhase(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE)
|
||||
if (resolvable is FirCallableDeclaration) {
|
||||
checkReturnTypeRefIsResolved(resolvable)
|
||||
override fun checkIsResolved(target: FirElementWithResolvePhase) {
|
||||
target.checkPhase(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE)
|
||||
if (target is FirCallableDeclaration) {
|
||||
checkReturnTypeRefIsResolved(target)
|
||||
}
|
||||
checkNestedDeclarationsAreResolved(resolvable)
|
||||
checkNestedDeclarationsAreResolved(target)
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -51,13 +51,13 @@ internal class LLFirDesignatedStatusResolveTransformer(
|
||||
checkIsResolved(designation.target)
|
||||
}
|
||||
|
||||
override fun checkIsResolved(resolvable: FirElementWithResolvePhase) {
|
||||
if (resolvable !is FirAnonymousInitializer) {
|
||||
resolvable.checkPhase(FirResolvePhase.STATUS)
|
||||
override fun checkIsResolved(target: FirElementWithResolvePhase) {
|
||||
if (target !is FirAnonymousInitializer) {
|
||||
target.checkPhase(FirResolvePhase.STATUS)
|
||||
}
|
||||
if (resolvable is FirMemberDeclaration) {
|
||||
checkDeclarationStatusIsResolved(resolvable)
|
||||
if (target is FirMemberDeclaration) {
|
||||
checkDeclarationStatusIsResolved(target)
|
||||
}
|
||||
checkNestedDeclarationsAreResolved(resolvable)
|
||||
checkNestedDeclarationsAreResolved(target)
|
||||
}
|
||||
}
|
||||
|
||||
+7
-7
@@ -153,21 +153,21 @@ internal class LLFirDesignatedSupertypeResolverTransformer(
|
||||
checkIsResolved(designation.target)
|
||||
}
|
||||
|
||||
override fun checkIsResolved(resolvable: FirElementWithResolvePhase) {
|
||||
resolvable.checkPhase(FirResolvePhase.SUPER_TYPES)
|
||||
when (resolvable) {
|
||||
override fun checkIsResolved(target: FirElementWithResolvePhase) {
|
||||
target.checkPhase(FirResolvePhase.SUPER_TYPES)
|
||||
when (target) {
|
||||
is FirClass -> {
|
||||
for (superTypeRef in resolvable.superTypeRefs) {
|
||||
checkTypeRefIsResolved(superTypeRef, "class super type", resolvable)
|
||||
for (superTypeRef in target.superTypeRefs) {
|
||||
checkTypeRefIsResolved(superTypeRef, "class super type", target)
|
||||
}
|
||||
}
|
||||
|
||||
is FirTypeAlias -> {
|
||||
checkTypeRefIsResolved(resolvable.expandedTypeRef, typeRefName = "type alias expanded type", resolvable)
|
||||
checkTypeRefIsResolved(target.expandedTypeRef, typeRefName = "type alias expanded type", target)
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
checkNestedDeclarationsAreResolved(resolvable)
|
||||
checkNestedDeclarationsAreResolved(target)
|
||||
}
|
||||
}
|
||||
|
||||
+9
-9
@@ -53,23 +53,23 @@ internal class LLFirDesignatedTypeResolverTransformer(
|
||||
(designation.target as? FirDeclaration)?.let { checkClassMembersAreResolved(it) }
|
||||
}
|
||||
|
||||
override fun checkIsResolved(resolvable: FirElementWithResolvePhase) {
|
||||
resolvable.checkPhase(FirResolvePhase.TYPES)
|
||||
when (resolvable) {
|
||||
override fun checkIsResolved(target: FirElementWithResolvePhase) {
|
||||
target.checkPhase(FirResolvePhase.TYPES)
|
||||
when (target) {
|
||||
is FirCallableDeclaration -> {
|
||||
checkReturnTypeRefIsResolved(resolvable, acceptImplicitTypeRef = true)
|
||||
checkReceiverTypeRefIsResolved(resolvable)
|
||||
checkReturnTypeRefIsResolved(target, acceptImplicitTypeRef = true)
|
||||
checkReceiverTypeRefIsResolved(target)
|
||||
}
|
||||
|
||||
is FirTypeParameter -> {
|
||||
for (bound in resolvable.bounds) {
|
||||
checkTypeRefIsResolved(bound, "type parameter bound", resolvable)
|
||||
for (bound in target.bounds) {
|
||||
checkTypeRefIsResolved(bound, "type parameter bound", target)
|
||||
}
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
checkNestedDeclarationsAreResolved(resolvable)
|
||||
(resolvable as? FirDeclaration)?.let { checkTypeParametersAreResolved(it) }
|
||||
checkNestedDeclarationsAreResolved(target)
|
||||
(target as? FirDeclaration)?.let { checkTypeParametersAreResolved(it) }
|
||||
}
|
||||
}
|
||||
|
||||
-60
@@ -1,60 +0,0 @@
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.transformers
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.declarations.resolved
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirTowerDataContextCollector
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.ImplicitBodyResolveComputationSession
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.createReturnTypeCalculatorForIDE
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirPhaseRunner
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.LLFirDesignatedImpliciteTypesBodyResolveTransformerForReturnTypeCalculator
|
||||
import org.jetbrains.kotlin.fir.FirElementWithResolvePhase
|
||||
|
||||
internal class LLFirFileAnnotationsResolveTransformer(
|
||||
private val firFile: FirFile,
|
||||
private val annotations: List<FirAnnotation>,
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
implicitBodyResolveComputationSession: ImplicitBodyResolveComputationSession = ImplicitBodyResolveComputationSession(),
|
||||
firTowerDataContextCollector: FirTowerDataContextCollector? = null,
|
||||
) : FirBodyResolveTransformer(
|
||||
session = session,
|
||||
phase = FirResolvePhase.BODY_RESOLVE,
|
||||
implicitTypeOnly = false,
|
||||
scopeSession = scopeSession,
|
||||
returnTypeCalculator = createReturnTypeCalculatorForIDE(
|
||||
scopeSession,
|
||||
implicitBodyResolveComputationSession,
|
||||
::LLFirDesignatedImpliciteTypesBodyResolveTransformerForReturnTypeCalculator
|
||||
),
|
||||
firTowerDataContextCollector = firTowerDataContextCollector
|
||||
), LLFirLazyTransformer {
|
||||
|
||||
override fun transformDeclarationContent(declaration: FirDeclaration, data: ResolutionMode): FirDeclaration {
|
||||
require(declaration is FirFile) { "Unexpected declaration ${declaration::class.simpleName}" }
|
||||
annotations.forEach {
|
||||
if (!it.resolved) {
|
||||
it.visitNoTransform(this, data)
|
||||
}
|
||||
}
|
||||
return declaration
|
||||
}
|
||||
|
||||
override fun transformDeclaration(phaseRunner: LLFirPhaseRunner) {
|
||||
if (annotations.all { it.resolved }) return
|
||||
check(firFile.resolvePhase >= FirResolvePhase.IMPORTS) { "Invalid file resolve phase ${firFile.resolvePhase}" }
|
||||
|
||||
firFile.accept(this, ResolutionMode.ContextDependent)
|
||||
check(annotations.all { it.resolved }) {
|
||||
"Annotation was not resolved"
|
||||
}
|
||||
}
|
||||
|
||||
override fun checkIsResolved(resolvable: FirElementWithResolvePhase) = error("Not implemented")
|
||||
}
|
||||
+8
-8
@@ -16,13 +16,13 @@ import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
internal interface LLFirLazyTransformer {
|
||||
fun transformDeclaration(phaseRunner: LLFirPhaseRunner)
|
||||
|
||||
fun checkIsResolved(resolvable: FirElementWithResolvePhase)
|
||||
fun checkIsResolved(target: FirElementWithResolvePhase)
|
||||
|
||||
fun checkNestedDeclarationsAreResolved(resolvable: FirElementWithResolvePhase) {
|
||||
if (resolvable !is FirDeclaration) return
|
||||
checkFunctionParametersAreResolved(resolvable)
|
||||
checkPropertyAccessorsAreResolved(resolvable)
|
||||
checkClassMembersAreResolved(resolvable)
|
||||
fun checkNestedDeclarationsAreResolved(target: FirElementWithResolvePhase) {
|
||||
if (target !is FirDeclaration) return
|
||||
checkFunctionParametersAreResolved(target)
|
||||
checkPropertyAccessorsAreResolved(target)
|
||||
checkClassMembersAreResolved(target)
|
||||
}
|
||||
|
||||
fun checkClassMembersAreResolved(declaration: FirDeclaration) {
|
||||
@@ -63,7 +63,7 @@ internal interface LLFirLazyTransformer {
|
||||
companion object {
|
||||
private object WholeTreePhaseUpdater : FirVisitor<Unit, FirResolvePhase>() {
|
||||
override fun visitElement(element: FirElement, data: FirResolvePhase) {
|
||||
if (element is FirDeclaration) {
|
||||
if (element is FirElementWithResolvePhase) {
|
||||
if (element.resolvePhase >= data && element !is FirDefaultPropertyAccessor) return
|
||||
element.replaceResolvePhase(data)
|
||||
}
|
||||
@@ -114,7 +114,7 @@ internal interface LLFirLazyTransformer {
|
||||
|
||||
val DUMMY = object : LLFirLazyTransformer {
|
||||
override fun transformDeclaration(phaseRunner: LLFirPhaseRunner) = Unit
|
||||
override fun checkIsResolved(resolvable: FirElementWithResolvePhase) = error("Not implemented")
|
||||
override fun checkIsResolved(target: FirElementWithResolvePhase) = error("Not implemented")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -7,9 +7,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.util
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirElementWithResolvePhase
|
||||
import org.jetbrains.kotlin.fir.FirFileAnnotationsContainer
|
||||
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||
|
||||
fun FirElementWithResolvePhase.getContainingFile(): FirFile? {
|
||||
@@ -17,6 +15,9 @@ fun FirElementWithResolvePhase.getContainingFile(): FirFile? {
|
||||
return when (this) {
|
||||
is FirFile -> this
|
||||
is FirFileAnnotationsContainer -> containingFileSymbol.fir
|
||||
is FirTypeParameter -> containingDeclarationSymbol.fir.getContainingFile()
|
||||
is FirPropertyAccessor -> propertySymbol.fir.getContainingFile()
|
||||
is FirValueParameter -> containingFunctionSymbol.fir.getContainingFile()
|
||||
is FirCallableDeclaration -> provider.getFirCallableContainerFile(symbol)
|
||||
is FirClassLikeDeclaration -> provider.getFirClassifierContainerFile(symbol)
|
||||
else -> errorWithFirSpecificEntries("Unsupported declaration ${this::class.java}", fir = this)
|
||||
|
||||
+3
-2
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.util
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.ExceptionAttachmentBuilder
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.checkWithAttachmentBuilder
|
||||
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
||||
import org.jetbrains.kotlin.fir.FirElementWithResolvePhase
|
||||
import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription
|
||||
import org.jetbrains.kotlin.fir.contracts.impl.FirEmptyContractDescription
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
@@ -20,7 +21,7 @@ import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
internal inline fun checkTypeRefIsResolved(
|
||||
typeRef: FirTypeRef,
|
||||
typeRefName: String,
|
||||
owner: FirDeclaration,
|
||||
owner: FirElementWithResolvePhase,
|
||||
acceptImplicitTypeRef: Boolean = false,
|
||||
extraAttachment: ExceptionAttachmentBuilder.() -> Unit = {}
|
||||
) {
|
||||
@@ -32,7 +33,7 @@ internal inline fun checkTypeRefIsResolved(
|
||||
if (acceptImplicitTypeRef) {
|
||||
append(" or ${FirImplicitTypeRef::class.simpleName}")
|
||||
}
|
||||
append(" for $typeRefName of ${owner::class.simpleName}(${owner.origin}) but ${typeRef::class.simpleName} found")
|
||||
append(" for $typeRefName of ${owner::class.simpleName}(${(owner as? FirDeclaration)?.origin}) but ${typeRef::class.simpleName} found")
|
||||
}
|
||||
}
|
||||
) {
|
||||
|
||||
Reference in New Issue
Block a user