From b1c8669b431c702ecff1d179eb30d5e5b56d51bb Mon Sep 17 00:00:00 2001 From: Andrey Zinovyev Date: Fri, 14 May 2021 15:22:43 +0300 Subject: [PATCH] [FIR] Resolve infix calls to infix functions only Implements INFIX_MODIFIER_REQUIRED diagnostics --- .../diagnostics/FirDiagnosticsList.kt | 3 ++ .../fir/analysis/diagnostics/FirErrors.kt | 1 + .../FirInlineDeclarationChecker.kt | 8 +++-- .../diagnostics/FirDefaultErrorMessages.kt | 2 ++ .../coneDiagnosticToFirDiagnostic.kt | 1 + .../fir/checkers/CommonExpressionCheckers.kt | 2 +- .../kotlin/fir/builder/RawFirBuilder.kt | 1 + .../jetbrains/kotlin/fir/FirCallResolver.kt | 21 +++++++++--- .../kotlin/fir/resolve/calls/CallKind.kt | 1 + .../fir/resolve/calls/ResolutionDiagnostic.kt | 5 ++- .../fir/resolve/calls/ResolutionStages.kt | 18 +++++++++-- .../fir/scopes/impl/FirIntegerOperatorCall.kt | 2 ++ .../fir/expressions/FirComponentCall.kt | 1 + .../kotlin/fir/expressions/FirFunctionCall.kt | 1 + .../fir/expressions/FirImplicitInvokeCall.kt | 1 + .../builder/FirAbstractFunctionCallBuilder.kt | 2 ++ .../builder/FirComponentCallBuilder.kt | 1 + .../builder/FirFunctionCallBuilder.kt | 3 ++ .../builder/FirImplicitInvokeCallBuilder.kt | 8 +++++ .../expressions/impl/FirComponentCallImpl.kt | 2 ++ .../expressions/impl/FirFunctionCallImpl.kt | 2 ++ .../impl/FirImplicitInvokeCallImpl.kt | 2 ++ .../fir/expressions/FirFunctionCallOrigin.kt | 10 ++++++ .../fir/tree/generator/BuilderConfigurator.kt | 7 +++- .../generator/ImplementationConfigurator.kt | 12 +++++++ .../fir/tree/generator/NodeConfigurator.kt | 1 + .../kotlin/fir/tree/generator/Types.kt | 2 ++ .../calls/tower/CandidateApplicability.kt | 1 + .../infixFunctionOverBuiltinMember.kt | 1 - .../testData/diagnostics/tests/Infix.fir.kt | 10 +++--- .../tests/NumberPrefixAndSuffix.fir.kt | 2 +- .../infixFunOverBuiltinMemberInConst.fir.kt | 10 ------ .../infixFunOverBuiltinMemberInConst.kt | 1 + .../numberBinaryOperationsInfixCall.fir.kt | 32 +++++++++---------- .../diagnostics/tests/inline/capture.fir.kt | 4 +-- .../diagnostics/tests/inline/invoke.fir.kt | 26 --------------- .../diagnostics/tests/inline/invoke.kt | 1 + .../tests/inline/parenthesized.fir.kt | 6 ++-- .../diagnostics/tests/inline/sam.fir.kt | 10 +++--- .../operatorInfix/LocalFunctions.fir.kt | 4 +-- .../operatorInfix/MemberFunctions.fir.kt | 6 ++-- .../modifiers/operatorInfix/Simple.fir.kt | 2 +- .../nullabilityWarnings/arithmetic.fir.kt | 12 +++---- .../diagnostics/KtFirDataClassConverters.kt | 7 ++++ .../api/fir/diagnostics/KtFirDiagnostics.kt | 5 +++ .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 8 +++++ 46 files changed, 174 insertions(+), 94 deletions(-) create mode 100644 compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirFunctionCallOrigin.kt delete mode 100644 compiler/testData/diagnostics/tests/evaluate/infixFunOverBuiltinMemberInConst.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/inline/invoke.fir.kt diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index 75e79d7a297..463aee873b9 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -233,6 +233,9 @@ object DIAGNOSTICS_LIST : DiagnosticList() { parameter("functionSymbol") parameter("name") } + val INFIX_MODIFIER_REQUIRED by error { + parameter("functionSymbol") + } } val INLINE_CLASSES by object : DiagnosticGroup("Inline classes") { diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 06a6588b0b8..9f7935aaac1 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -209,6 +209,7 @@ object FirErrors { val REDUNDANT_OPEN_IN_INTERFACE by warning0(SourceElementPositioningStrategies.OPEN_MODIFIER) val WRONG_MODIFIER_TARGET by error2() val OPERATOR_MODIFIER_REQUIRED by error2() + val INFIX_MODIFIER_REQUIRED by error1() // Inline classes val INLINE_CLASS_NOT_TOP_LEVEL by error0(SourceElementPositioningStrategies.INLINE_OR_VALUE_MODIFIER) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt index 8252ca59240..53e1ff61a17 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt @@ -82,9 +82,11 @@ object FirInlineDeclarationChecker : FirMemberDeclarationChecker() { override fun visitFunctionCall(functionCall: FirFunctionCall, data: CheckerContext) { val targetSymbol = functionCall.toResolvedCallableSymbol() - checkReceiversOfQualifiedAccessExpression(functionCall, targetSymbol, data) - checkArgumentsOfCall(functionCall, targetSymbol, data) - checkQualifiedAccess(functionCall, targetSymbol, data) + if (targetSymbol != null) { + checkReceiversOfQualifiedAccessExpression(functionCall, targetSymbol, data) + checkArgumentsOfCall(functionCall, targetSymbol, data) + checkQualifiedAccess(functionCall, targetSymbol, data) + } } override fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression, data: CheckerContext) { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index ef0fbdebca3..9a98a1f4b5c 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -154,6 +154,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INCOMPATIBLE_MODI import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INCOMPATIBLE_TYPES import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INCOMPATIBLE_TYPES_WARNING import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INFERENCE_ERROR +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INFIX_MODIFIER_REQUIRED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INITIALIZER_TYPE_MISMATCH import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_CLASS_CANNOT_BE_RECURSIVE @@ -539,6 +540,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { map.put(INCOMPATIBLE_MODIFIERS, "Modifier ''{0}'' is incompatible with ''{1}''", TO_STRING, TO_STRING) map.put(REDUNDANT_OPEN_IN_INTERFACE, "Modifier 'open' is redundant for abstract interface members") map.put(WRONG_MODIFIER_TARGET, "Modifier ''{0}'' is not applicable to ''{1}''", TO_STRING, TO_STRING) + map.put(INFIX_MODIFIER_REQUIRED, "''infix'' modifier is required on ''{0}''", TO_STRING) // Classes and interfaces map.put(SUPERTYPE_NOT_INITIALIZED, "This type has a constructor, and thus must be initialized here") diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt index 1822a54e13d..91202984cdd 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt @@ -142,6 +142,7 @@ private fun mapInapplicableCandidateError( ) is UnsafeCall -> mapUnsafeCallError(diagnostic.candidate, rootCause, source, qualifiedAccessSource) is ManyLambdaExpressionArguments -> FirErrors.MANY_LAMBDA_EXPRESSION_ARGUMENTS.on(rootCause.argument.source ?: source) + is InfixCallOfNonInfixFunction -> FirErrors.INFIX_MODIFIER_REQUIRED.on(source, rootCause.function) else -> null } }.ifEmpty { listOf(FirErrors.INAPPLICABLE_CANDIDATE.on(source, diagnostic.candidate.symbol)) } diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonExpressionCheckers.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonExpressionCheckers.kt index b1a56680bc1..9e2e724726f 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonExpressionCheckers.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonExpressionCheckers.kt @@ -41,7 +41,7 @@ object CommonExpressionCheckers : ExpressionCheckers() { get() = setOf( FirConventionFunctionCallChecker, FirDivisionByZeroChecker, - FirConstructorCallChecker + FirConstructorCallChecker, ) override val tryExpressionCheckers: Set diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index a85ca672102..ffdcb28deb0 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -1889,6 +1889,7 @@ open class RawFirBuilder( } explicitReceiver = leftArgument argumentList = buildUnaryArgumentList(rightArgument) + origin = if (conventionCallName != null) FirFunctionCallOrigin.REGULAR else FirFunctionCallOrigin.INFIX } } else { val firOperation = operationToken.toFirOperation() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt index 920485dbf72..8616b412380 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -153,15 +153,28 @@ class FirCallResolver( towerResolver.reset() val result = towerResolver.runResolver(info, transformer.resolutionContext) val bestCandidates = result.bestCandidates() - var reducedCandidates = if (!result.currentApplicability.isSuccess) { - bestCandidates.toSet() - } else { + + fun chooseMostSpecific(): Set { val onSuperReference = (explicitReceiver as? FirQualifiedAccessExpression)?.calleeReference is FirSuperReference - conflictResolver.chooseMaximallySpecificCandidates( + return conflictResolver.chooseMaximallySpecificCandidates( bestCandidates, discriminateGenerics = true, discriminateAbstracts = onSuperReference ) } + var reducedCandidates = if (!result.currentApplicability.isSuccess) { + val distinctApplicabilities = bestCandidates.flatMapTo(mutableSetOf()) { candidate -> + candidate.diagnostics.map { it.applicability } + } + //if all candidates have the same kind on inApplicability - try to choose the most specific one + if (distinctApplicabilities.size == 1 && distinctApplicabilities.single() > CandidateApplicability.INAPPLICABLE) { + chooseMostSpecific() + } else { + bestCandidates.toSet() + } + } else { + chooseMostSpecific() + } + reducedCandidates = overloadByLambdaReturnTypeResolver.reduceCandidates(qualifiedAccess, bestCandidates, reducedCandidates) return ResolutionResult(info, result.currentApplicability, reducedCandidates) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallKind.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallKind.kt index a889ced98dd..6c3795b45c1 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallKind.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallKind.kt @@ -39,6 +39,7 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) { CheckDispatchReceiver, CheckExtensionReceiver, CheckArguments, + CheckInfixCall, EagerResolveOfCallableReferences, CheckLowPriorityInOverloadResolution, PostponedVariablesInitializerResolutionStage diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt index 71e8b0de09c..ba95b3fc2bb 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.declarations.FirFunction import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression +import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability @@ -101,4 +102,6 @@ class NullForNotNullType( class ManyLambdaExpressionArguments( val argument: FirExpression -) : ResolutionDiagnostic(INAPPLICABLE_ARGUMENTS_MAPPING_ERROR) \ No newline at end of file +) : ResolutionDiagnostic(INAPPLICABLE_ARGUMENTS_MAPPING_ERROR) + +class InfixCallOfNonInfixFunction(val function: FirNamedFunctionSymbol) : ResolutionDiagnostic(INAPPLICABLE_MODIFIER) \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt index f60f8f82fce..80dee4a7d80 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt @@ -9,15 +9,14 @@ import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.fir.FirSymbolOwner import org.jetbrains.kotlin.fir.FirVisibilityChecker import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.expressions.FirExpression -import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression -import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier +import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.references.FirSuperReference import org.jetbrains.kotlin.fir.resolve.inference.* import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.symbols.SyntheticSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.types.* @@ -267,3 +266,16 @@ internal object PostponedVariablesInitializerResolutionStage : ResolutionStage() } } } + +internal object CheckInfixCall : CheckerStage() { + override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) { + if (callInfo.callSite is FirFunctionCall) { + if (callInfo.callSite.origin == FirFunctionCallOrigin.INFIX) { + val functionSymbol = candidate.symbol as? FirNamedFunctionSymbol ?: return + if (!functionSymbol.fir.isInfix) { + sink.reportDiagnostic(InfixCallOfNonInfixFunction(functionSymbol)) + } + } + } + } +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerOperatorCall.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerOperatorCall.kt index 8ea5ceb5ad4..423aaf602aa 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerOperatorCall.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerOperatorCall.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.builder.FirBuilderDsl import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirArgumentList import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.expressions.FirFunctionCallOrigin import org.jetbrains.kotlin.fir.expressions.builder.FirCallBuilder import org.jetbrains.kotlin.fir.expressions.builder.FirExpressionBuilder import org.jetbrains.kotlin.fir.expressions.builder.FirQualifiedAccessBuilder @@ -43,6 +44,7 @@ class FirIntegerOperatorCall @FirImplementationDetail constructor( extensionReceiver, argumentList, calleeReference, + FirFunctionCallOrigin.OPERATOR ) @FirBuilderDsl diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirComponentCall.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirComponentCall.kt index 5f07c05c2c5..f4eefe07757 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirComponentCall.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirComponentCall.kt @@ -28,6 +28,7 @@ abstract class FirComponentCall : FirFunctionCall() { abstract override val extensionReceiver: FirExpression abstract override val argumentList: FirArgumentList abstract override val calleeReference: FirNamedReference + abstract override val origin: FirFunctionCallOrigin abstract override val explicitReceiver: FirExpression abstract val componentIndex: Int diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirFunctionCall.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirFunctionCall.kt index dc14079ac90..e52460a7162 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirFunctionCall.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirFunctionCall.kt @@ -29,6 +29,7 @@ abstract class FirFunctionCall : FirQualifiedAccessExpression(), FirCall { abstract override val extensionReceiver: FirExpression abstract override val argumentList: FirArgumentList abstract override val calleeReference: FirNamedReference + abstract val origin: FirFunctionCallOrigin override fun accept(visitor: FirVisitor, data: D): R = visitor.visitFunctionCall(this, data) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirImplicitInvokeCall.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirImplicitInvokeCall.kt index 1711d309d4d..f2b8eb07658 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirImplicitInvokeCall.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirImplicitInvokeCall.kt @@ -29,6 +29,7 @@ abstract class FirImplicitInvokeCall : FirFunctionCall() { abstract override val extensionReceiver: FirExpression abstract override val argumentList: FirArgumentList abstract override val calleeReference: FirNamedReference + abstract override val origin: FirFunctionCallOrigin override fun accept(visitor: FirVisitor, data: D): R = visitor.visitImplicitInvokeCall(this, data) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirAbstractFunctionCallBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirAbstractFunctionCallBuilder.kt index 4c05246c5a6..2f2c029fead 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirAbstractFunctionCallBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirAbstractFunctionCallBuilder.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirArgumentList import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirFunctionCall +import org.jetbrains.kotlin.fir.expressions.FirFunctionCallOrigin import org.jetbrains.kotlin.fir.expressions.builder.FirCallBuilder import org.jetbrains.kotlin.fir.expressions.builder.FirQualifiedAccessBuilder import org.jetbrains.kotlin.fir.references.FirNamedReference @@ -34,5 +35,6 @@ interface FirAbstractFunctionCallBuilder : FirQualifiedAccessBuilder, FirCallBui abstract override var argumentList: FirArgumentList abstract var typeRef: FirTypeRef abstract var calleeReference: FirNamedReference + abstract var origin: FirFunctionCallOrigin override fun build(): FirFunctionCall } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirComponentCallBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirComponentCallBuilder.kt index be9f371378d..cd30c70ab7a 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirComponentCallBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirComponentCallBuilder.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.expressions.FirArgumentList import org.jetbrains.kotlin.fir.expressions.FirComponentCall import org.jetbrains.kotlin.fir.expressions.FirEmptyArgumentList import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.expressions.FirFunctionCallOrigin import org.jetbrains.kotlin.fir.expressions.builder.FirCallBuilder import org.jetbrains.kotlin.fir.expressions.builder.FirExpressionBuilder import org.jetbrains.kotlin.fir.expressions.impl.FirComponentCallImpl diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirFunctionCallBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirFunctionCallBuilder.kt index 37482a911f4..e98836f0866 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirFunctionCallBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirFunctionCallBuilder.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.expressions.FirArgumentList import org.jetbrains.kotlin.fir.expressions.FirEmptyArgumentList import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirFunctionCall +import org.jetbrains.kotlin.fir.expressions.FirFunctionCallOrigin import org.jetbrains.kotlin.fir.expressions.builder.FirAbstractFunctionCallBuilder import org.jetbrains.kotlin.fir.expressions.builder.FirExpressionBuilder import org.jetbrains.kotlin.fir.expressions.impl.FirFunctionCallImpl @@ -42,6 +43,7 @@ open class FirFunctionCallBuilder : FirAbstractFunctionCallBuilder, FirAnnotatio override var extensionReceiver: FirExpression = FirNoReceiverExpression override var argumentList: FirArgumentList = FirEmptyArgumentList override lateinit var calleeReference: FirNamedReference + override var origin: FirFunctionCallOrigin = FirFunctionCallOrigin.REGULAR @OptIn(FirImplementationDetail::class) override fun build(): FirFunctionCall { @@ -55,6 +57,7 @@ open class FirFunctionCallBuilder : FirAbstractFunctionCallBuilder, FirAnnotatio extensionReceiver, argumentList, calleeReference, + origin, ) } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirImplicitInvokeCallBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirImplicitInvokeCallBuilder.kt index c9790ae850b..9c7c164f27d 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirImplicitInvokeCallBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirImplicitInvokeCallBuilder.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirArgumentList import org.jetbrains.kotlin.fir.expressions.FirEmptyArgumentList import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.expressions.FirFunctionCallOrigin import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall import org.jetbrains.kotlin.fir.expressions.builder.FirAbstractFunctionCallBuilder import org.jetbrains.kotlin.fir.expressions.builder.FirExpressionBuilder @@ -62,6 +63,13 @@ open class FirImplicitInvokeCallBuilder : FirAbstractFunctionCallBuilder, FirAnn set(_) { throw IllegalStateException() } + + @Deprecated("Modification of 'origin' has no impact for FirImplicitInvokeCallBuilder", level = DeprecationLevel.HIDDEN) + override var origin: FirFunctionCallOrigin + get() = throw IllegalStateException() + set(_) { + throw IllegalStateException() + } } @OptIn(ExperimentalContracts::class) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirComponentCallImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirComponentCallImpl.kt index e5453f2cafe..a88240ebb9d 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirComponentCallImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirComponentCallImpl.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirArgumentList import org.jetbrains.kotlin.fir.expressions.FirComponentCall import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.expressions.FirFunctionCallOrigin import org.jetbrains.kotlin.fir.references.FirNamedReference import org.jetbrains.kotlin.fir.references.FirReference import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference @@ -38,6 +39,7 @@ internal class FirComponentCallImpl( ) : FirComponentCall() { override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null) override var calleeReference: FirNamedReference = FirSimpleNamedReference(source, Name.identifier("component$componentIndex"), null) + override val origin: FirFunctionCallOrigin = FirFunctionCallOrigin.REGULAR override fun acceptChildren(visitor: FirVisitor, data: D) { typeRef.accept(visitor, data) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirFunctionCallImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirFunctionCallImpl.kt index c2b367562f9..df0bb963cd5 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirFunctionCallImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirFunctionCallImpl.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirArgumentList import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirFunctionCall +import org.jetbrains.kotlin.fir.expressions.FirFunctionCallOrigin import org.jetbrains.kotlin.fir.references.FirNamedReference import org.jetbrains.kotlin.fir.references.FirReference import org.jetbrains.kotlin.fir.types.FirTypeProjection @@ -32,6 +33,7 @@ open class FirFunctionCallImpl @FirImplementationDetail constructor( override var extensionReceiver: FirExpression, override var argumentList: FirArgumentList, override var calleeReference: FirNamedReference, + override val origin: FirFunctionCallOrigin, ) : FirFunctionCall() { override fun acceptChildren(visitor: FirVisitor, data: D) { typeRef.accept(visitor, data) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirImplicitInvokeCallImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirImplicitInvokeCallImpl.kt index 1afc3883d51..f62c1fea9b1 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirImplicitInvokeCallImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirImplicitInvokeCallImpl.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirArgumentList import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.expressions.FirFunctionCallOrigin import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall import org.jetbrains.kotlin.fir.references.FirNamedReference import org.jetbrains.kotlin.fir.references.FirReference @@ -34,6 +35,7 @@ internal class FirImplicitInvokeCallImpl( override var calleeReference: FirNamedReference, ) : FirImplicitInvokeCall() { override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null) + override val origin: FirFunctionCallOrigin = FirFunctionCallOrigin.REGULAR override fun acceptChildren(visitor: FirVisitor, data: D) { typeRef.accept(visitor, data) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirFunctionCallOrigin.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirFunctionCallOrigin.kt new file mode 100644 index 00000000000..d9793578e24 --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirFunctionCallOrigin.kt @@ -0,0 +1,10 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.expressions + +enum class FirFunctionCallOrigin { + REGULAR, INFIX, OPERATOR +} \ No newline at end of file diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt index f0bc0ff77d6..630221fcd21 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt @@ -176,7 +176,12 @@ object BuilderConfigurator : AbstractBuilderConfigurator(FirTree useTypes(emptyArgumentListType) } - builder(functionCall, init = configurationForFunctionCallBuilder) + builder(functionCall) { + configurationForFunctionCallBuilder() + default("origin") { + value = "FirFunctionCallOrigin.REGULAR" + } + } builder(implicitInvokeCall, init = configurationForFunctionCallBuilder) builder(qualifiedAccessExpression) { diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt index 935edf0f0ad..87fcb2e69f4 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt @@ -153,6 +153,18 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() kind = OpenClass } + fun ImplementationContext.defaultFunctionOrigin() { + default("origin", "FirFunctionCallOrigin.REGULAR") + } + + impl(implicitInvokeCall) { + defaultFunctionOrigin() + } + + impl(componentCall) { + defaultFunctionOrigin() + } + impl(qualifiedAccessExpression) noImpl(expressionWithSmartcast) diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt index 46cd6765349..03bf0c8fbd7 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt @@ -207,6 +207,7 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild functionCall.configure { +field("calleeReference", namedReference) + +field("origin", functionCallOrigin) } comparisonExpression.configure { diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt index d8c7ef82a3e..807b29ee159 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt @@ -86,3 +86,5 @@ val annotationResolveStatusType = generatedType("expressions", "FirAnnotationRes val exhaustivenessStatusType = generatedType("expressions", "ExhaustivenessStatus") val callableReferenceMappedArgumentsType = type("fir.resolve.calls", "CallableReferenceMappedArguments") + +val functionCallOrigin = type("fir.expressions", "FirFunctionCallOrigin") diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/tower/CandidateApplicability.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/tower/CandidateApplicability.kt index 32c0a63006f..d6c6dc02548 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/tower/CandidateApplicability.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/tower/CandidateApplicability.kt @@ -11,6 +11,7 @@ enum class CandidateApplicability { INAPPLICABLE_WRONG_RECEIVER, // receiver not matched INAPPLICABLE_ARGUMENTS_MAPPING_ERROR, // arguments not mapped to parameters (i.e. different size of arguments and parameters) INAPPLICABLE, // arguments have wrong types + INAPPLICABLE_MODIFIER, // no expected modifier (eg infix call on non-infix function) IMPOSSIBLE_TO_GENERATE, // access to outer class from nested RUNTIME_ERROR, // problems with visibility UNSAFE_CALL, // receiver nullability doesn't match diff --git a/compiler/testData/codegen/box/operatorConventions/infixFunctionOverBuiltinMember.kt b/compiler/testData/codegen/box/operatorConventions/infixFunctionOverBuiltinMember.kt index f8a7328ef43..d4ec1d41d6a 100644 --- a/compiler/testData/codegen/box/operatorConventions/infixFunctionOverBuiltinMember.kt +++ b/compiler/testData/codegen/box/operatorConventions/infixFunctionOverBuiltinMember.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR infix fun Int.rem(other: Int) = 10 infix operator fun Int.minus(other: Int): Int = 20 diff --git a/compiler/testData/diagnostics/tests/Infix.fir.kt b/compiler/testData/diagnostics/tests/Infix.fir.kt index 97bccdbf03c..152301dc0ad 100644 --- a/compiler/testData/diagnostics/tests/Infix.fir.kt +++ b/compiler/testData/diagnostics/tests/Infix.fir.kt @@ -18,21 +18,21 @@ fun Example.withLambda(f: () -> Unit) = Pair(this, f) fun test() { Example() to Example() - Example() toNonInfix Example() + Example() toNonInfix Example() Example().toNonInfix(Example()) val a = Example() val b = Example() a toExt b - a toExtNonInfix b + a toExtNonInfix b a.toExtNonInfix(b) a toExtWithExtraParams b - a toExtNonInfixWithExtraParams b + a toExtNonInfixWithExtraParams b a toExtDefaultValues b - a toExtNonInfixDefaultValues b + a toExtNonInfixDefaultValues b - a withLambda { } + a withLambda { } } diff --git a/compiler/testData/diagnostics/tests/NumberPrefixAndSuffix.fir.kt b/compiler/testData/diagnostics/tests/NumberPrefixAndSuffix.fir.kt index fc1b01a4940..5f1c5b78fb4 100644 --- a/compiler/testData/diagnostics/tests/NumberPrefixAndSuffix.fir.kt +++ b/compiler/testData/diagnostics/tests/NumberPrefixAndSuffix.fir.kt @@ -12,7 +12,7 @@ fun test(a: Any) { 1ffoo a 1doo a 1ddoo a - 1contains a + 1contains a 1Lfoo a 1Loo a diff --git a/compiler/testData/diagnostics/tests/evaluate/infixFunOverBuiltinMemberInConst.fir.kt b/compiler/testData/diagnostics/tests/evaluate/infixFunOverBuiltinMemberInConst.fir.kt deleted file mode 100644 index d9361ac8aff..00000000000 --- a/compiler/testData/diagnostics/tests/evaluate/infixFunOverBuiltinMemberInConst.fir.kt +++ /dev/null @@ -1,10 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_VARIABLE, -UNUSED_PARAMETER - -infix fun Int.rem(other: Int) = 10 -infix operator fun Int.minus(other: Int): Int = 20 - -const val a1 = (-5) rem 2 -const val a2 = (-5).rem(2) - -const val b1 = 5 minus 3 -const val b2 = 5.minus(3) diff --git a/compiler/testData/diagnostics/tests/evaluate/infixFunOverBuiltinMemberInConst.kt b/compiler/testData/diagnostics/tests/evaluate/infixFunOverBuiltinMemberInConst.kt index 518cae9fd6a..e9548911849 100644 --- a/compiler/testData/diagnostics/tests/evaluate/infixFunOverBuiltinMemberInConst.kt +++ b/compiler/testData/diagnostics/tests/evaluate/infixFunOverBuiltinMemberInConst.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_VARIABLE, -UNUSED_PARAMETER infix fun Int.rem(other: Int) = 10 diff --git a/compiler/testData/diagnostics/tests/evaluate/numberBinaryOperationsInfixCall.fir.kt b/compiler/testData/diagnostics/tests/evaluate/numberBinaryOperationsInfixCall.fir.kt index b59f24a8b8a..edf600dc9dc 100644 --- a/compiler/testData/diagnostics/tests/evaluate/numberBinaryOperationsInfixCall.fir.kt +++ b/compiler/testData/diagnostics/tests/evaluate/numberBinaryOperationsInfixCall.fir.kt @@ -4,23 +4,23 @@ fun fooByte(p: Byte) = p fun fooShort(p: Short) = p fun test() { - fooInt(1 plus 1) - fooByte(1 plus 1) - fooLong(1 plus 1) - fooShort(1 plus 1) + fooInt(1 plus 1) + fooByte(1 plus 1) + fooLong(1 plus 1) + fooShort(1 plus 1) - fooInt(1 times 1) - fooByte(1 times 1) - fooLong(1 times 1) - fooShort(1 times 1) + fooInt(1 times 1) + fooByte(1 times 1) + fooLong(1 times 1) + fooShort(1 times 1) - fooInt(1 div 1) - fooByte(1 div 1) - fooLong(1 div 1) - fooShort(1 div 1) + fooInt(1 div 1) + fooByte(1 div 1) + fooLong(1 div 1) + fooShort(1 div 1) - fooInt(1 rem 1) - fooByte(1 rem 1) - fooLong(1 rem 1) - fooShort(1 rem 1) + fooInt(1 rem 1) + fooByte(1 rem 1) + fooLong(1 rem 1) + fooShort(1 rem 1) } diff --git a/compiler/testData/diagnostics/tests/inline/capture.fir.kt b/compiler/testData/diagnostics/tests/inline/capture.fir.kt index d495c98e005..565b4c4b5d7 100644 --- a/compiler/testData/diagnostics/tests/inline/capture.fir.kt +++ b/compiler/testData/diagnostics/tests/inline/capture.fir.kt @@ -25,7 +25,7 @@ inline fun inlineFunWithInvoke(s: (p: Int) -> Unit) { { s(11) s.invoke(11) - s invoke 11 + s invoke 11 }() } @@ -33,7 +33,7 @@ inline fun inlineFunWithInvokeNonInline(noinline s: (p: Int) -> Unit) { { s(11) s.invoke(11) - s invoke 11 + s invoke 11 }() } diff --git a/compiler/testData/diagnostics/tests/inline/invoke.fir.kt b/compiler/testData/diagnostics/tests/inline/invoke.fir.kt deleted file mode 100644 index 0519b58bddf..00000000000 --- a/compiler/testData/diagnostics/tests/inline/invoke.fir.kt +++ /dev/null @@ -1,26 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE - -inline fun inlineFunWithInvoke(s: (p: Int) -> Unit, ext: Int.(p: Int) -> Unit) { - s(11) - s.invoke(11) - s invoke 11 - - 11.ext(11) - 11 ext 11 -} - -inline fun inlineFunWithInvokeNonInline(noinline s: (p: Int) -> Unit, ext: Int.(p: Int) -> Unit) { - s(11) - s.invoke(11) - s invoke 11 - - 11.ext(11) - 11 ext 11 -} - -inline fun Function1.inlineExt() { - invoke(11) - this.invoke(11) - this invoke 11 - this(11) -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inline/invoke.kt b/compiler/testData/diagnostics/tests/inline/invoke.kt index d76a596549e..66f6b734d63 100644 --- a/compiler/testData/diagnostics/tests/inline/invoke.kt +++ b/compiler/testData/diagnostics/tests/inline/invoke.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE inline fun inlineFunWithInvoke(s: (p: Int) -> Unit, ext: Int.(p: Int) -> Unit) { diff --git a/compiler/testData/diagnostics/tests/inline/parenthesized.fir.kt b/compiler/testData/diagnostics/tests/inline/parenthesized.fir.kt index 4d1b9fb6558..b47a36e944e 100644 --- a/compiler/testData/diagnostics/tests/inline/parenthesized.fir.kt +++ b/compiler/testData/diagnostics/tests/inline/parenthesized.fir.kt @@ -3,13 +3,13 @@ inline fun inlineFunWithInvoke(s: (p: Int) -> Unit) { (s)(11) (s).invoke(11) - (s) invoke 11 + (s) invoke 11 (s) } inline fun Function1.inlineExt() { (this).invoke(11) - (this) invoke 11 + (this) invoke 11 (this)(11) (this) } @@ -17,7 +17,7 @@ inline fun Function1.inlineExt() { inline fun inlineFunWithInvoke2(s: (p: Int) -> Unit) { (((s)))(11) (((s))).invoke(11) - (((s))) invoke 11 + (((s))) invoke 11 (((s))) } diff --git a/compiler/testData/diagnostics/tests/inline/sam.fir.kt b/compiler/testData/diagnostics/tests/inline/sam.fir.kt index 93919977c99..1a48eac4885 100644 --- a/compiler/testData/diagnostics/tests/inline/sam.fir.kt +++ b/compiler/testData/diagnostics/tests/inline/sam.fir.kt @@ -17,10 +17,10 @@ inline fun inlineFunWithInvoke(s: (p: Int) -> Unit, ext: Int.(p: Int) -> Unit) { Test().test(){ s(11) s.invoke(11) - s invoke 11 + s invoke 11 11.ext(11) - 11 ext 11 + 11 ext 11 s ext @@ -32,10 +32,10 @@ inline fun inlineFunWithInvokeNonInline(noinline s: (p: Int) -> Unit, ext: Int.( Test().test(){ s(11) s.invoke(11) - s invoke 11 + s invoke 11 11.ext(11) - 11 ext 11 + 11 ext 11 s ext @@ -48,7 +48,7 @@ inline fun Function1.inlineExt() { Test().test(){ invoke(11) this.invoke(11) - this invoke 11 + this invoke 11 this(11) this diff --git a/compiler/testData/diagnostics/tests/modifiers/operatorInfix/LocalFunctions.fir.kt b/compiler/testData/diagnostics/tests/modifiers/operatorInfix/LocalFunctions.fir.kt index dd32cd0f96d..13e84d7c392 100644 --- a/compiler/testData/diagnostics/tests/modifiers/operatorInfix/LocalFunctions.fir.kt +++ b/compiler/testData/diagnostics/tests/modifiers/operatorInfix/LocalFunctions.fir.kt @@ -24,13 +24,13 @@ fun a() { consumeInt(a - b) consumeString(a plus b) - consumeInt(a minus b) + consumeInt(a minus b) a * b a / b a times b - a div b + a div b } } } diff --git a/compiler/testData/diagnostics/tests/modifiers/operatorInfix/MemberFunctions.fir.kt b/compiler/testData/diagnostics/tests/modifiers/operatorInfix/MemberFunctions.fir.kt index 03a213f7177..8cfe751b8df 100644 --- a/compiler/testData/diagnostics/tests/modifiers/operatorInfix/MemberFunctions.fir.kt +++ b/compiler/testData/diagnostics/tests/modifiers/operatorInfix/MemberFunctions.fir.kt @@ -26,7 +26,7 @@ fun a() { a plus b a minus b a times b - a div b + a div b with (Example()) { consumeInt(this + a) @@ -35,9 +35,9 @@ fun a() { consumeInt(this / b) consumeInt(this plus a) - consumeString(this minus b) + consumeString(this minus b) consumeInt(this times a) - consumeInt(this div b) + consumeInt(this div b) } } diff --git a/compiler/testData/diagnostics/tests/modifiers/operatorInfix/Simple.fir.kt b/compiler/testData/diagnostics/tests/modifiers/operatorInfix/Simple.fir.kt index b52086ac493..4ac6682ba1d 100644 --- a/compiler/testData/diagnostics/tests/modifiers/operatorInfix/Simple.fir.kt +++ b/compiler/testData/diagnostics/tests/modifiers/operatorInfix/Simple.fir.kt @@ -37,7 +37,7 @@ fun test() { consumeExample2(++a) - consumeString(a plus b) + consumeString(a plus b) } fun consumeInt(i: Int) {} diff --git a/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/arithmetic.fir.kt b/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/arithmetic.fir.kt index a2cf8835ddb..18c9e60b888 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/arithmetic.fir.kt +++ b/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/arithmetic.fir.kt @@ -41,13 +41,13 @@ fun test() { platformN + 1 platformJ + 1 - 1 plus platformNN - 1 plus platformN - 1 plus platformJ + 1 plus platformNN + 1 plus platformN + 1 plus platformJ - platformNN plus 1 - platformN plus 1 - platformJ plus 1 + platformNN plus 1 + platformN plus 1 + platformJ plus 1 platformNN += 1 platformN += 1 diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt index 19666ef9df3..73b48ef58e7 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -813,6 +813,13 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.INFIX_MODIFIER_REQUIRED) { firDiagnostic -> + InfixModifierRequiredImpl( + firSymbolBuilder.functionLikeBuilder.buildFunctionSymbol(firDiagnostic.a.fir), + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } add(FirErrors.INLINE_CLASS_NOT_TOP_LEVEL) { firDiagnostic -> InlineClassNotTopLevelImpl( firDiagnostic as FirPsiDiagnostic<*>, diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt index 92afb22279d..1288bb6ba30 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt @@ -586,6 +586,11 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { abstract val name: String } + abstract class InfixModifierRequired : KtFirDiagnostic() { + override val diagnosticClass get() = InfixModifierRequired::class + abstract val functionSymbol: KtFunctionLikeSymbol + } + abstract class InlineClassNotTopLevel : KtFirDiagnostic() { override val diagnosticClass get() = InlineClassNotTopLevel::class } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index 1e2e45ab631..6437052af1d 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -938,6 +938,14 @@ internal class OperatorModifierRequiredImpl( override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) } +internal class InfixModifierRequiredImpl( + override val functionSymbol: KtFunctionLikeSymbol, + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.InfixModifierRequired(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + internal class InlineClassNotTopLevelImpl( firDiagnostic: FirPsiDiagnostic<*>, override val token: ValidityToken,