[LL FIR] ANNOTATIONS_ARGUMENTS_MAPPING: drop intermediate state with lazy arguments

This is safer because we can be sure that no one can
read an intermediate result with lazy expressions (related to KT-60387)

^KT-60552 Fixed
This commit is contained in:
Dmitrii Gridin
2023-07-25 19:54:26 +02:00
committed by Space Team
parent 65fec8dc19
commit 3518aa5898
2 changed files with 11 additions and 6 deletions
@@ -57,6 +57,10 @@ internal object FirLazyBodiesCalculator {
fun calculateLazyArgumentsForAnnotation(annotationCall: FirAnnotationCall, session: FirSession): FirArgumentList { fun calculateLazyArgumentsForAnnotation(annotationCall: FirAnnotationCall, session: FirSession): FirArgumentList {
require(needCalculatingAnnotationCall(annotationCall)) require(needCalculatingAnnotationCall(annotationCall))
return createArgumentsForAnnotation(annotationCall, session)
}
fun createArgumentsForAnnotation(annotationCall: FirAnnotationCall, session: FirSession): FirArgumentList {
val builder = PsiRawFirBuilder(session, baseScopeProvider = session.kotlinScopeProvider) val builder = PsiRawFirBuilder(session, baseScopeProvider = session.kotlinScopeProvider)
val ktAnnotationEntry = annotationCall.psi as KtAnnotationEntry val ktAnnotationEntry = annotationCall.psi as KtAnnotationEntry
builder.context.packageFqName = ktAnnotationEntry.containingKtFile.packageFqName builder.context.packageFqName = ktAnnotationEntry.containingKtFile.packageFqName
@@ -7,10 +7,9 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.transformers
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirResolveTarget import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirResolveTarget
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LLFirLockProvider import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LLFirLockProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.FirLazyBodiesCalculator.calculateAnnotations import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.FirLazyBodiesCalculator
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirSession import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkAnnotationArgumentsMappingIsResolved import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkAnnotationArgumentsMappingIsResolved
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.expressionGuard
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
@@ -62,7 +61,7 @@ private class LLFirAnnotationArgumentsMappingTargetResolver(
) )
override fun doLazyResolveUnderLock(target: FirElementWithResolveState) { override fun doLazyResolveUnderLock(target: FirElementWithResolveState) {
resolveWithKeeper(target, target.llFirSession, AnnotationArgumentMappingStateKeepers.DECLARATION, ::calculateAnnotations) { resolveWithKeeper(target, target.llFirSession, AnnotationArgumentMappingStateKeepers.DECLARATION) {
transformAnnotations(target) transformAnnotations(target)
} }
} }
@@ -81,19 +80,21 @@ internal object AnnotationArgumentMappingStateKeepers {
} }
} }
private val ANNOTATION_CALL: StateKeeper<FirAnnotationCall, FirSession> = stateKeeper { annotationCall, _ -> private val ANNOTATION_CALL: StateKeeper<FirAnnotationCall, FirSession> = stateKeeper { annotationCall, session ->
add(FirAnnotationCall::calleeReference, FirAnnotationCall::replaceCalleeReference) add(FirAnnotationCall::calleeReference, FirAnnotationCall::replaceCalleeReference)
val argumentList = annotationCall.argumentList val argumentList = annotationCall.argumentList
if (argumentList !is FirResolvedArgumentList && argumentList !is FirEmptyArgumentList) { if (argumentList !is FirResolvedArgumentList && argumentList !is FirEmptyArgumentList) {
add(FirAnnotationCall::argumentList, FirAnnotationCall::replaceArgumentList) { oldList -> add(FirAnnotationCall::argumentList, FirAnnotationCall::replaceArgumentList) { oldList ->
val newArguments = FirLazyBodiesCalculator.createArgumentsForAnnotation(annotationCall, session).arguments
buildArgumentList { buildArgumentList {
source = oldList.source source = oldList.source
for (argument in oldList.arguments) { for ((index, argument) in oldList.arguments.withIndex()) {
val replacement = when { val replacement = when {
argument is FirPropertyAccessExpression && argument.calleeReference.isError() -> argument argument is FirPropertyAccessExpression && argument.calleeReference.isError() -> argument
else -> expressionGuard(argument) else -> newArguments[index]
} }
arguments.add(replacement) arguments.add(replacement)
} }
} }