[FIR] Resolve operator calls to operator functions only
This commit is contained in:
committed by
TeamCityServer
parent
b1c8669b43
commit
e021e25d6c
+2
@@ -143,6 +143,8 @@ private fun mapInapplicableCandidateError(
|
|||||||
is UnsafeCall -> mapUnsafeCallError(diagnostic.candidate, rootCause, source, qualifiedAccessSource)
|
is UnsafeCall -> mapUnsafeCallError(diagnostic.candidate, rootCause, source, qualifiedAccessSource)
|
||||||
is ManyLambdaExpressionArguments -> FirErrors.MANY_LAMBDA_EXPRESSION_ARGUMENTS.on(rootCause.argument.source ?: source)
|
is ManyLambdaExpressionArguments -> FirErrors.MANY_LAMBDA_EXPRESSION_ARGUMENTS.on(rootCause.argument.source ?: source)
|
||||||
is InfixCallOfNonInfixFunction -> FirErrors.INFIX_MODIFIER_REQUIRED.on(source, rootCause.function)
|
is InfixCallOfNonInfixFunction -> FirErrors.INFIX_MODIFIER_REQUIRED.on(source, rootCause.function)
|
||||||
|
is OperatorCallOfNonOperatorFunction ->
|
||||||
|
FirErrors.OPERATOR_MODIFIER_REQUIRED.on(source, rootCause.function, rootCause.function.fir.name.asString())
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}.ifEmpty { listOf(FirErrors.INAPPLICABLE_CANDIDATE.on(source, diagnostic.candidate.symbol)) }
|
}.ifEmpty { listOf(FirErrors.INAPPLICABLE_CANDIDATE.on(source, diagnostic.candidate.symbol)) }
|
||||||
|
|||||||
@@ -1889,7 +1889,7 @@ open class RawFirBuilder(
|
|||||||
}
|
}
|
||||||
explicitReceiver = leftArgument
|
explicitReceiver = leftArgument
|
||||||
argumentList = buildUnaryArgumentList(rightArgument)
|
argumentList = buildUnaryArgumentList(rightArgument)
|
||||||
origin = if (conventionCallName != null) FirFunctionCallOrigin.REGULAR else FirFunctionCallOrigin.INFIX
|
origin = if (conventionCallName != null) FirFunctionCallOrigin.OPERATOR else FirFunctionCallOrigin.INFIX
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val firOperation = operationToken.toFirOperation()
|
val firOperation = operationToken.toFirOperation()
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
|
|||||||
CheckDispatchReceiver,
|
CheckDispatchReceiver,
|
||||||
CheckExtensionReceiver,
|
CheckExtensionReceiver,
|
||||||
CheckArguments,
|
CheckArguments,
|
||||||
CheckInfixCall,
|
CheckCallModifiers,
|
||||||
EagerResolveOfCallableReferences,
|
EagerResolveOfCallableReferences,
|
||||||
CheckLowPriorityInOverloadResolution,
|
CheckLowPriorityInOverloadResolution,
|
||||||
PostponedVariablesInitializerResolutionStage
|
PostponedVariablesInitializerResolutionStage
|
||||||
|
|||||||
+2
-1
@@ -104,4 +104,5 @@ class ManyLambdaExpressionArguments(
|
|||||||
val argument: FirExpression
|
val argument: FirExpression
|
||||||
) : ResolutionDiagnostic(INAPPLICABLE_ARGUMENTS_MAPPING_ERROR)
|
) : ResolutionDiagnostic(INAPPLICABLE_ARGUMENTS_MAPPING_ERROR)
|
||||||
|
|
||||||
class InfixCallOfNonInfixFunction(val function: FirNamedFunctionSymbol) : ResolutionDiagnostic(INAPPLICABLE_MODIFIER)
|
class InfixCallOfNonInfixFunction(val function: FirNamedFunctionSymbol) : ResolutionDiagnostic(INAPPLICABLE_MODIFIER)
|
||||||
|
class OperatorCallOfNonOperatorFunction(val function: FirNamedFunctionSymbol) : ResolutionDiagnostic(INAPPLICABLE_MODIFIER)
|
||||||
@@ -267,14 +267,15 @@ internal object PostponedVariablesInitializerResolutionStage : ResolutionStage()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal object CheckInfixCall : CheckerStage() {
|
internal object CheckCallModifiers : CheckerStage() {
|
||||||
override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) {
|
override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) {
|
||||||
if (callInfo.callSite is FirFunctionCall) {
|
if (callInfo.callSite is FirFunctionCall) {
|
||||||
if (callInfo.callSite.origin == FirFunctionCallOrigin.INFIX) {
|
val functionSymbol = candidate.symbol as? FirNamedFunctionSymbol ?: return
|
||||||
val functionSymbol = candidate.symbol as? FirNamedFunctionSymbol ?: return
|
when {
|
||||||
if (!functionSymbol.fir.isInfix) {
|
callInfo.callSite.origin == FirFunctionCallOrigin.INFIX && !functionSymbol.fir.isInfix ->
|
||||||
sink.reportDiagnostic(InfixCallOfNonInfixFunction(functionSymbol))
|
sink.reportDiagnostic(InfixCallOfNonInfixFunction(functionSymbol))
|
||||||
}
|
callInfo.callSite.origin == FirFunctionCallOrigin.OPERATOR && !functionSymbol.fir.isOperator ->
|
||||||
|
sink.reportDiagnostic(OperatorCallOfNonOperatorFunction(functionSymbol))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -49,9 +49,9 @@ fun test() {
|
|||||||
a == b
|
a == b
|
||||||
c != d
|
c != d
|
||||||
|
|
||||||
Example() + Example()
|
Example() <!OPERATOR_MODIFIER_REQUIRED!>+<!> Example()
|
||||||
|
|
||||||
a + b
|
a <!OPERATOR_MODIFIER_REQUIRED!>+<!> b
|
||||||
a - b
|
a - b
|
||||||
a[1]
|
a[1]
|
||||||
a["str"]
|
a["str"]
|
||||||
@@ -67,10 +67,10 @@ fun test() {
|
|||||||
c += d
|
c += d
|
||||||
c -= d
|
c -= d
|
||||||
|
|
||||||
a..b
|
a<!OPERATOR_MODIFIER_REQUIRED!>..<!>b
|
||||||
c..d
|
c..d
|
||||||
|
|
||||||
Example()..Example()
|
Example()<!OPERATOR_MODIFIER_REQUIRED!>..<!>Example()
|
||||||
Example2()..Example2()
|
Example2()..Example2()
|
||||||
|
|
||||||
a < b
|
a < b
|
||||||
@@ -109,7 +109,7 @@ class Anc2 : Anc()
|
|||||||
|
|
||||||
fun test2() {
|
fun test2() {
|
||||||
Anc() + Anc()
|
Anc() + Anc()
|
||||||
Anc() - Anc()
|
Anc() <!OPERATOR_MODIFIER_REQUIRED!>-<!> Anc()
|
||||||
Anc2() + Anc2()
|
Anc2() + Anc2()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-39
@@ -1,39 +0,0 @@
|
|||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
|
||||||
|
|
||||||
class Example
|
|
||||||
|
|
||||||
fun Example.plus(other: Example) = 0
|
|
||||||
operator infix fun Example.minus(other: Example) = 0
|
|
||||||
|
|
||||||
operator infix fun Example.times(other: Example) = 0
|
|
||||||
fun Example.div(other: Example) = 0
|
|
||||||
|
|
||||||
fun a() {
|
|
||||||
with (Example()) {
|
|
||||||
operator infix fun Example.plus(other: Example) = ""
|
|
||||||
fun Example.minus(other: Example) = ""
|
|
||||||
|
|
||||||
operator infix fun Example.times(other: Example) = ""
|
|
||||||
fun Example.div(other: Example) = ""
|
|
||||||
|
|
||||||
with (Example()) {
|
|
||||||
val a = Example()
|
|
||||||
val b = Example()
|
|
||||||
|
|
||||||
consumeString(a + b)
|
|
||||||
consumeInt(<!ARGUMENT_TYPE_MISMATCH!>a - b<!>)
|
|
||||||
|
|
||||||
consumeString(a plus b)
|
|
||||||
consumeInt(a minus b)
|
|
||||||
|
|
||||||
a * b
|
|
||||||
a / b
|
|
||||||
|
|
||||||
a times b
|
|
||||||
a <!INFIX_MODIFIER_REQUIRED!>div<!> b
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun consumeInt(i: Int) {}
|
|
||||||
fun consumeString(s: String) {}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
class Example
|
class Example
|
||||||
|
|||||||
-45
@@ -1,45 +0,0 @@
|
|||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER, -EXTENSION_SHADOWED_BY_MEMBER
|
|
||||||
|
|
||||||
class Example {
|
|
||||||
operator infix fun plus(other: Example) = 0
|
|
||||||
fun minus(other: Example) = 0
|
|
||||||
|
|
||||||
operator infix fun times(other: Example) = 0
|
|
||||||
fun div(other: Example) = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Example.plus(other: Example) = ""
|
|
||||||
operator infix fun Example.minus(other: Example) = ""
|
|
||||||
|
|
||||||
operator infix fun Example.times(other: Example) = ""
|
|
||||||
fun Example.div(other: Example) = ""
|
|
||||||
|
|
||||||
fun a() {
|
|
||||||
val a = Example()
|
|
||||||
val b = Example()
|
|
||||||
|
|
||||||
a + b
|
|
||||||
a - b
|
|
||||||
a * b
|
|
||||||
a / b
|
|
||||||
|
|
||||||
a plus b
|
|
||||||
a minus b
|
|
||||||
a times b
|
|
||||||
a <!INFIX_MODIFIER_REQUIRED!>div<!> b
|
|
||||||
|
|
||||||
with (Example()) {
|
|
||||||
consumeInt(this + a)
|
|
||||||
consumeString(<!ARGUMENT_TYPE_MISMATCH!>this - b<!>)
|
|
||||||
consumeInt(this * a)
|
|
||||||
consumeInt(this / b)
|
|
||||||
|
|
||||||
consumeInt(this plus a)
|
|
||||||
consumeString(this minus b)
|
|
||||||
consumeInt(this times a)
|
|
||||||
consumeInt(this <!INFIX_MODIFIER_REQUIRED!>div<!> b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun consumeInt(i: Int) {}
|
|
||||||
fun consumeString(s: String) {}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER, -EXTENSION_SHADOWED_BY_MEMBER
|
// !DIAGNOSTICS: -UNUSED_PARAMETER, -EXTENSION_SHADOWED_BY_MEMBER
|
||||||
|
|
||||||
class Example {
|
class Example {
|
||||||
|
|||||||
Reference in New Issue
Block a user