FIR: refactor FirExpressionsResolveTransformer#transformAssignmentOperatorStatement

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