Resolve unaryPlus as plus with error.
This commit is contained in:
+41
-21
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
|
||||
import org.jetbrains.kotlin.resolve.calls.CallResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.CallTransformer
|
||||
import org.jetbrains.kotlin.resolve.calls.CandidateResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getUnaryPlusOrMinusOperatorFunctionName
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInfixCall
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.createLookupLocation
|
||||
@@ -71,27 +72,7 @@ class NewResolveOldInference(
|
||||
|
||||
val baseContext = Context(scopeTower, name, context, tracing)
|
||||
|
||||
val processor =
|
||||
when (kind) {
|
||||
CallResolver.ResolveKind.VARIABLE -> createVariableProcessor(baseContext, explicitReceiver)
|
||||
CallResolver.ResolveKind.FUNCTION -> createFunctionTowerProcessor(baseContext, explicitReceiver)
|
||||
CallResolver.ResolveKind.CALLABLE_REFERENCE -> CompositeScopeTowerProcessor(
|
||||
createFunctionProcessor(baseContext, explicitReceiver),
|
||||
createVariableProcessor(baseContext, explicitReceiver)
|
||||
)
|
||||
CallResolver.ResolveKind.INVOKE -> {
|
||||
// todo
|
||||
val call = (context.call as? CallTransformer.CallForImplicitInvoke).sure {
|
||||
"Call should be CallForImplicitInvoke, but it is: ${context.call}"
|
||||
}
|
||||
createProcessorWithReceiverValueOrEmpty(explicitReceiver) {
|
||||
createCallTowerProcessorForExplicitInvoke(baseContext, call.dispatchReceiver, it)
|
||||
}
|
||||
}
|
||||
CallResolver.ResolveKind.GIVEN_CANDIDATES -> {
|
||||
throw UnsupportedOperationException("Kind $kind unsupported yet")
|
||||
}
|
||||
}
|
||||
var processor = createResolveProcessor(kind, explicitReceiver, context, baseContext)
|
||||
|
||||
if (context.collectAllCandidates) {
|
||||
val allCandidates = towerResolver.collectAllCandidates(baseContext, processor)
|
||||
@@ -99,11 +80,47 @@ class NewResolveOldInference(
|
||||
result.allCandidates = allCandidates.map { it.resolvedCall as MutableResolvedCall<CallableDescriptor> }
|
||||
return result
|
||||
}
|
||||
// Temporary fix for code migration (unaryPlus()/unaryMinus())
|
||||
val unaryConventionName = getUnaryPlusOrMinusOperatorFunctionName(context.call)
|
||||
if (unaryConventionName != null) {
|
||||
val deprecatedName = if (name == OperatorNameConventions.UNARY_PLUS)
|
||||
OperatorNameConventions.PLUS
|
||||
else
|
||||
OperatorNameConventions.MINUS
|
||||
val otherBaseContext = Context(scopeTower, deprecatedName, context, tracing)
|
||||
processor = CompositeScopeTowerProcessor(processor, createResolveProcessor(kind, explicitReceiver, context, otherBaseContext))
|
||||
}
|
||||
|
||||
val candidates = towerResolver.runResolve(baseContext, processor, useOrder = kind != CallResolver.ResolveKind.CALLABLE_REFERENCE)
|
||||
return convertToOverloadResults(candidates, tracing, context)
|
||||
}
|
||||
|
||||
private fun createResolveProcessor(
|
||||
kind: CallResolver.ResolveKind,
|
||||
explicitReceiver : Receiver?,
|
||||
context: BasicCallResolutionContext,
|
||||
baseContext: Context)
|
||||
= when (kind) {
|
||||
CallResolver.ResolveKind.VARIABLE -> createVariableProcessor(baseContext, explicitReceiver)
|
||||
CallResolver.ResolveKind.FUNCTION -> createFunctionTowerProcessor(baseContext, explicitReceiver)
|
||||
CallResolver.ResolveKind.CALLABLE_REFERENCE -> CompositeScopeTowerProcessor(
|
||||
createFunctionProcessor(baseContext, explicitReceiver),
|
||||
createVariableProcessor(baseContext, explicitReceiver)
|
||||
)
|
||||
CallResolver.ResolveKind.INVOKE -> {
|
||||
// todo
|
||||
val call = (context.call as? CallTransformer.CallForImplicitInvoke).sure {
|
||||
"Call should be CallForImplicitInvoke, but it is: ${context.call}"
|
||||
}
|
||||
createProcessorWithReceiverValueOrEmpty(explicitReceiver) {
|
||||
createCallTowerProcessorForExplicitInvoke(baseContext, call.dispatchReceiver, it)
|
||||
}
|
||||
}
|
||||
CallResolver.ResolveKind.GIVEN_CANDIDATES -> {
|
||||
throw UnsupportedOperationException("Kind $kind unsupported yet")
|
||||
}
|
||||
}
|
||||
|
||||
private fun createProcessorWithReceiverValueOrEmpty(
|
||||
explicitReceiver: Receiver?,
|
||||
create: (ReceiverValue?) -> ScopeTowerProcessor<Candidate>
|
||||
@@ -219,6 +236,9 @@ class NewResolveOldInference(
|
||||
|
||||
private fun checkInfixAndOperator(call: Call, descriptor: CallableDescriptor): List<ResolutionDiagnostic> {
|
||||
if (descriptor !is FunctionDescriptor || ErrorUtils.isError(descriptor)) return emptyList()
|
||||
if (descriptor.name != name && (name == OperatorNameConventions.UNARY_PLUS || name == OperatorNameConventions.UNARY_MINUS)) {
|
||||
return listOf(DeprecatedUnaryPlusAsPlus)
|
||||
}
|
||||
|
||||
val conventionError = if (isConventionCall(call) && !descriptor.isOperator) InvokeConventionCallNoOperatorModifier else null
|
||||
val infixError = if (isInfixCall(call) && !descriptor.isInfix) InfixCallNoInfixModifier else null
|
||||
|
||||
@@ -101,4 +101,5 @@ object ExtensionWithStaticTypeWithDynamicReceiver: ResolutionDiagnostic(Resoluti
|
||||
object HiddenDescriptor: ResolutionDiagnostic(ResolutionCandidateApplicability.HIDDEN)
|
||||
|
||||
object InvokeConventionCallNoOperatorModifier : ResolutionDiagnostic(ResolutionCandidateApplicability.CONVENTION_ERROR)
|
||||
object InfixCallNoInfixModifier : ResolutionDiagnostic(ResolutionCandidateApplicability.CONVENTION_ERROR)
|
||||
object InfixCallNoInfixModifier : ResolutionDiagnostic(ResolutionCandidateApplicability.CONVENTION_ERROR)
|
||||
object DeprecatedUnaryPlusAsPlus : ResolutionDiagnostic(ResolutionCandidateApplicability.CONVENTION_ERROR)
|
||||
|
||||
@@ -15,7 +15,7 @@ operator fun String.unaryPlus(): Int = 0
|
||||
fun test() {
|
||||
requireInt(+ "")
|
||||
requireInt(+ Example())
|
||||
requireString(<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>+<!> ExampleDeprecated())
|
||||
requireString(<!DEPRECATED_UNARY_PLUS_MINUS!>+ ExampleDeprecated()<!>)
|
||||
}
|
||||
|
||||
fun requireInt(n: Int) {}
|
||||
@@ -26,7 +26,7 @@ class Example2 {
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun minus() = this
|
||||
|
||||
fun test() {
|
||||
<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>+<!>this
|
||||
<!UNRESOLVED_REFERENCE!>-<!>this
|
||||
<!DEPRECATED_UNARY_PLUS_MINUS!>+this<!>
|
||||
<!DEPRECATED_UNARY_PLUS_MINUS!>-this<!>
|
||||
}
|
||||
}
|
||||
Vendored
+1
-1
@@ -27,7 +27,7 @@ fun dynamic.test() {
|
||||
<!DEBUG_INFO_DYNAMIC!>this<!>()
|
||||
|
||||
C() + C()
|
||||
<!UNRESOLVED_REFERENCE!>+<!>C()
|
||||
<!DEPRECATED_UNARY_PLUS_MINUS!><!NO_VALUE_FOR_PARAMETER!>+<!>C()<!>
|
||||
|
||||
this <!DEBUG_INFO_DYNAMIC!>+<!> C()
|
||||
|
||||
|
||||
@@ -2,4 +2,5 @@ Function call (10: 17) A(0) + A(1) + 2
|
||||
Function call (11: 20) A(0) plus A(1) plus 2
|
||||
Function call (12: 20) A(0).plus(A(1).plus(2))
|
||||
Function call (15: 7) a += 1
|
||||
Function call (6: 30) fun plus(a: A): A = this + a.n
|
||||
Function call (6: 30) fun plus(a: A): A = this + a.n
|
||||
Unclassified usage (18: 5) +A(0)
|
||||
Reference in New Issue
Block a user