FIR checkers: report VAL_REASSIGNMENT for assignment operators

Currently VAL_REASSIGNMENT are only reported on direct assignments.
Reassignments in the form of, for example, `+=` are reported as
`VARIABLE_EXPECTED`, which differs from FE1.0.
This commit is contained in:
Tianyu Geng
2021-03-30 16:23:39 -07:00
committed by Mikhail Glukhikh
parent b87a943efd
commit fc8d0e3ee0
17 changed files with 57 additions and 38 deletions
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
@@ -59,6 +60,10 @@ class ConeVariableExpectedError : ConeDiagnostic() {
override val reason: String get() = "Variable expected"
}
class ConeValReassignmentError(val variable: FirVariableSymbol<*>) : ConeDiagnostic() {
override val reason: String get() = "Re-assigning a val variable"
}
class ConeTypeMismatchError(val expectedType: ConeKotlinType, val actualType: ConeKotlinType) : ConeDiagnostic() {
override val reason: String
get() = "Type mismatch. Expected: $expectedType, Actual: $actualType"
@@ -385,7 +385,8 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
val operatorIsError = operatorCallReference?.isError ?: true
val lhsReference = leftArgument.toResolvedCallableReference()
val lhsVariable = (lhsReference?.resolvedSymbol as? FirVariableSymbol<*>)?.fir
val lhsSymbol = lhsReference?.resolvedSymbol as? FirVariableSymbol<*>
val lhsVariable = lhsSymbol?.fir
val lhsIsVar = lhsVariable?.isVar == true
return when {
operatorIsError || (!lhsIsVar && !assignIsError) -> {
@@ -409,7 +410,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
leftArgument.calleeReference.source
else -> leftArgument.source
}
diagnostic = ConeVariableExpectedError()
diagnostic = if (lhsSymbol == null) ConeVariableExpectedError() else ConeValReassignmentError(lhsSymbol)
}
}
(leftArgument as? FirQualifiedAccess)?.let {