FIR: Report UNSAFE_OPERATOR_CALL for augmented assignments (was

reporting UNSAFE_CALL).
This commit is contained in:
Mark Punzalan
2021-05-25 17:56:59 +00:00
committed by teamcityserver
parent ef923d4cfe
commit 32bb64a225
12 changed files with 93 additions and 12 deletions
@@ -19087,6 +19087,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/AssertNotNull.kt");
}
@Test
@TestMetadata("augmentedAssignment.kt")
public void testAugmentedAssignment() throws Exception {
runTest("compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/augmentedAssignment.kt");
}
@Test
@TestMetadata("dataFlowInfoAfterExclExcl.kt")
public void testDataFlowInfoAfterExclExcl() throws Exception {
@@ -19087,6 +19087,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/AssertNotNull.kt");
}
@Test
@TestMetadata("augmentedAssignment.kt")
public void testAugmentedAssignment() throws Exception {
runTest("compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/augmentedAssignment.kt");
}
@Test
@TestMetadata("dataFlowInfoAfterExclExcl.kt")
public void testDataFlowInfoAfterExclExcl() throws Exception {
@@ -100,11 +100,18 @@ private fun mapUnsafeCallError(
val receiverExpression = candidate.callInfo.explicitReceiver
val singleArgument = candidate.callInfo.argumentList.arguments.singleOrNull()
if (receiverExpression != null && singleArgument != null &&
source.elementType == KtNodeTypes.OPERATION_REFERENCE &&
(source.elementType == KtNodeTypes.OPERATION_REFERENCE || source.elementType == KtNodeTypes.BINARY_EXPRESSION) &&
(candidateFunction?.isOperator == true || candidateFunction?.isInfix == true)
) {
val operationToken = source.getChild(KtTokens.IDENTIFIER)
return if (operationToken != null) {
// For augmented assignment operations (e.g., `a += b`), the source is the entire binary expression (BINARY_EXPRESSION).
// TODO: No need to check for source.elementType == BINARY_EXPRESSION if we use operator as callee reference source
// (see FirExpressionsResolveTransformer.transformAssignmentOperatorStatement)
val operationSource = if (source.elementType == KtNodeTypes.BINARY_EXPRESSION) {
source.getChild(KtNodeTypes.OPERATION_REFERENCE)
} else {
source
}
return if (operationSource?.getChild(KtTokens.IDENTIFIER) != null) {
FirErrors.UNSAFE_INFIX_CALL.on(
source,
receiverExpression,
@@ -26,8 +26,6 @@ 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.substitution.substituteOrNull
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.resolve.transformers.*
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.fir.types.*
@@ -41,6 +39,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.ConstantValueKind
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : FirPartialBodyResolveTransformer(transformer) {
private inline val builtinTypes: BuiltinTypes get() = session.builtinTypes
@@ -372,6 +371,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
explicitReceiver = leftArgument
argumentList = buildUnaryArgumentList(rightArgument)
calleeReference = buildSimpleNamedReference {
// TODO: Use source of operator for callee reference source
source = assignmentOperatorStatement.source?.fakeElement(FirFakeSourceElementKind.DesugaredCompoundAssignment)
this.name = name
candidateSymbol = null