FIR: refactor FirExpressionsResolveTransformer#transformAssignmentOperatorStatement
No logic change. This commit only rearrange stuff to make it cleaner
This commit is contained in:
committed by
TeamCityServer
parent
861f69822b
commit
c43faa2ada
+56
-43
@@ -25,15 +25,18 @@ import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.FirStubInferenceSession
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.InvocationKindTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.StoreReceiver
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.firClassLike
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.builder.*
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.visitors.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.buildAbstractResultingSubstitutor
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.jetbrains.kotlin.types.ConstantValueKind
|
||||
@@ -374,7 +377,8 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
||||
assignOperatorCall.transformSingle(this, ResolutionMode.ContextDependent)
|
||||
}
|
||||
val assignCallReference = resolvedAssignCall.calleeReference as? FirNamedReferenceWithCandidate
|
||||
val assignIsError = assignCallReference?.isError ?: true
|
||||
val assignIsResolvable = assignCallReference?.isError == false
|
||||
|
||||
// x = x + y
|
||||
val simpleOperatorName = FirOperationNameConventions.ASSIGNMENTS_TO_SIMPLE_OPERATOR.getValue(assignmentOperatorStatement.operation)
|
||||
val simpleOperatorCall = createFunctionCall(simpleOperatorName)
|
||||
@@ -382,57 +386,66 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
||||
simpleOperatorCall.transformSingle(this, ResolutionMode.ContextDependent)
|
||||
}
|
||||
val operatorCallReference = resolvedOperatorCall.calleeReference as? FirNamedReferenceWithCandidate
|
||||
val operatorIsError = operatorCallReference?.isError ?: true
|
||||
val operatorIsResolvable = operatorCallReference?.isError == false
|
||||
|
||||
val lhsReference = leftArgument.toResolvedCallableReference()
|
||||
val lhsSymbol = lhsReference?.resolvedSymbol as? FirVariableSymbol<*>
|
||||
val lhsVariable = lhsSymbol?.fir
|
||||
val lhsIsVar = lhsVariable?.isVar == true
|
||||
return when {
|
||||
operatorIsError || (!lhsIsVar && !assignIsError) -> {
|
||||
callCompleter.completeCall(resolvedAssignCall, noExpectedType)
|
||||
dataFlowAnalyzer.exitFunctionCall(resolvedAssignCall, callCompleted = true)
|
||||
resolvedAssignCall
|
||||
}
|
||||
assignIsError -> {
|
||||
callCompleter.completeCall(resolvedOperatorCall, lhsVariable?.returnTypeRef ?: noExpectedType)
|
||||
dataFlowAnalyzer.exitFunctionCall(resolvedOperatorCall, callCompleted = true)
|
||||
val assignment =
|
||||
buildVariableAssignment {
|
||||
source = assignmentOperatorStatement.source
|
||||
rValue = resolvedOperatorCall
|
||||
calleeReference = when {
|
||||
lhsIsVar -> lhsReference!!
|
||||
else -> buildErrorNamedReference {
|
||||
source = when (leftArgument) {
|
||||
is FirFunctionCall -> leftArgument.source
|
||||
is FirQualifiedAccess ->
|
||||
leftArgument.calleeReference.source
|
||||
else -> leftArgument.source
|
||||
}
|
||||
diagnostic = if (lhsSymbol == null) ConeVariableExpectedError() else ConeValReassignmentError(lhsSymbol)
|
||||
|
||||
fun chooseAssign(): FirStatement {
|
||||
callCompleter.completeCall(resolvedAssignCall, noExpectedType)
|
||||
dataFlowAnalyzer.exitFunctionCall(resolvedAssignCall, callCompleted = true)
|
||||
return resolvedAssignCall
|
||||
}
|
||||
|
||||
fun chooseOperator(): FirStatement {
|
||||
callCompleter.completeCall(resolvedOperatorCall, lhsVariable?.returnTypeRef ?: noExpectedType)
|
||||
dataFlowAnalyzer.exitFunctionCall(resolvedOperatorCall, callCompleted = true)
|
||||
val assignment =
|
||||
buildVariableAssignment {
|
||||
source = assignmentOperatorStatement.source
|
||||
rValue = resolvedOperatorCall
|
||||
calleeReference = when {
|
||||
lhsIsVar -> lhsReference!!
|
||||
else -> buildErrorNamedReference {
|
||||
source = when (leftArgument) {
|
||||
is FirFunctionCall -> leftArgument.source
|
||||
is FirQualifiedAccess ->
|
||||
leftArgument.calleeReference.source
|
||||
else -> leftArgument.source
|
||||
}
|
||||
}
|
||||
(leftArgument as? FirQualifiedAccess)?.let {
|
||||
dispatchReceiver = it.dispatchReceiver
|
||||
extensionReceiver = it.extensionReceiver
|
||||
diagnostic = if (lhsSymbol == null) ConeVariableExpectedError() else ConeValReassignmentError(lhsSymbol)
|
||||
}
|
||||
}
|
||||
assignment.transform(transformer, ResolutionMode.ContextIndependent)
|
||||
}
|
||||
else -> {
|
||||
val operatorCallSymbol = operatorCallReference?.candidateSymbol
|
||||
val assignmentCallSymbol = assignCallReference?.candidateSymbol
|
||||
|
||||
requireNotNull(operatorCallSymbol)
|
||||
requireNotNull(assignmentCallSymbol)
|
||||
|
||||
buildErrorExpression {
|
||||
source = assignmentOperatorStatement.source
|
||||
diagnostic = ConeOperatorAmbiguityError(listOf(operatorCallSymbol, assignmentCallSymbol))
|
||||
(leftArgument as? FirQualifiedAccess)?.let {
|
||||
dispatchReceiver = it.dispatchReceiver
|
||||
extensionReceiver = it.extensionReceiver
|
||||
}
|
||||
}
|
||||
return assignment.transform(transformer, ResolutionMode.ContextIndependent)
|
||||
}
|
||||
|
||||
fun reportAmbiguity(): FirStatement {
|
||||
val operatorCallSymbol = operatorCallReference?.candidateSymbol
|
||||
val assignmentCallSymbol = assignCallReference?.candidateSymbol
|
||||
|
||||
requireNotNull(operatorCallSymbol)
|
||||
requireNotNull(assignmentCallSymbol)
|
||||
|
||||
return buildErrorExpression {
|
||||
source = assignmentOperatorStatement.source
|
||||
diagnostic = ConeOperatorAmbiguityError(listOf(operatorCallSymbol, assignmentCallSymbol))
|
||||
}
|
||||
}
|
||||
|
||||
return when {
|
||||
assignIsResolvable && !lhsIsVar -> chooseAssign()
|
||||
!assignIsResolvable && !operatorIsResolvable -> chooseAssign()
|
||||
!assignIsResolvable && operatorIsResolvable -> chooseOperator()
|
||||
assignIsResolvable && !operatorIsResolvable -> chooseAssign()
|
||||
else -> reportAmbiguity()
|
||||
}
|
||||
}
|
||||
|
||||
override fun transformEqualityOperatorCall(
|
||||
|
||||
Reference in New Issue
Block a user