Add assertion for variable as operator call.

This commit is contained in:
Stanislav Erokhin
2016-06-10 17:31:03 +03:00
parent 03241419bd
commit da01e4a57c
4 changed files with 22 additions and 10 deletions
@@ -301,7 +301,8 @@ public class CallResolver {
context.scope, calleeExpression, expectedType, context.dataFlowInfo, context.trace);
ExpressionReceiver expressionReceiver = ExpressionReceiver.Companion.create(calleeExpression, calleeType, context.trace.getBindingContext());
Call call = new CallTransformer.CallForImplicitInvoke(context.call.getExplicitReceiver(), expressionReceiver, context.call);
Call call = new CallTransformer.CallForImplicitInvoke(context.call.getExplicitReceiver(), expressionReceiver, context.call,
false);
TracingStrategyForInvoke tracingForInvoke = new TracingStrategyForInvoke(calleeExpression, call, calleeType);
return resolveCallForInvoke(context.replaceCall(call), tracingForInvoke);
}
@@ -94,11 +94,13 @@ public class CallTransformer {
private final Receiver explicitExtensionReceiver;
private final ExpressionReceiver calleeExpressionAsDispatchReceiver;
private final KtSimpleNameExpression fakeInvokeExpression;
public final boolean itIsVariableAsFunctionCall;
public CallForImplicitInvoke(
@Nullable Receiver explicitExtensionReceiver,
@NotNull ExpressionReceiver calleeExpressionAsDispatchReceiver,
@NotNull Call call
@NotNull Call call,
boolean functionCall
) {
super(call);
this.outerCall = call;
@@ -107,6 +109,7 @@ public class CallTransformer {
this.fakeInvokeExpression =
(KtSimpleNameExpression) KtPsiFactoryKt.KtPsiFactory(call.getCallElement())
.createExpression(OperatorNameConventions.INVOKE.asString());
itIsVariableAsFunctionCall = functionCall;
}
@Nullable
@@ -397,7 +397,7 @@ class NewResolutionOldInference(
// todo hacks
val functionCall = CallTransformer.CallForImplicitInvoke(
basicCallContext.call.explicitReceiver?.check { useExplicitReceiver },
variableReceiver, basicCallContext.call)
variableReceiver, basicCallContext.call, true)
val tracingForInvoke = TracingStrategyForInvoke(calleeExpression, functionCall, variableReceiver.type)
val basicCallResolutionContext = basicCallContext.replaceBindingTrace(variable.resolvedCall.trace)
.replaceCall(functionCall)
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,15 +25,16 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.calls.CallTransformer
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.util.OperatorNameConventions.PLUS
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.util.OperatorNameConventions.MINUS
import org.jetbrains.kotlin.util.OperatorNameConventions.UNARY_PLUS
import org.jetbrains.kotlin.util.OperatorNameConventions.PLUS
import org.jetbrains.kotlin.util.OperatorNameConventions.UNARY_MINUS
import org.jetbrains.kotlin.util.OperatorNameConventions.UNARY_PLUS
class OperatorValidator : SymbolUsageValidator {
@@ -59,6 +60,13 @@ class OperatorValidator : SymbolUsageValidator {
fun isArrayAccessExpression() = jetElement is KtArrayAccessExpression
if (resolvedCall is VariableAsFunctionResolvedCall && call is CallTransformer.CallForImplicitInvoke && call.itIsVariableAsFunctionCall) {
val outerCall = call.outerCall
if (isConventionCall(outerCall)) {
throw AssertionError("Illegal resolved call to variable with invoke for $outerCall. Variable: ${resolvedCall.variableCall.resultingDescriptor}")
}
}
if (isMultiDeclaration() || isInvokeCall()) {
if (!functionDescriptor.isOperator && call != null) {
report(call.callElement, functionDescriptor, trace)