KT-5488 Invalid ambiguity between plus and plusAssign
#KT-5488 Fixed
This commit is contained in:
+18
-8
@@ -837,33 +837,43 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
return !context.dataFlowInfo.getNullability(dataFlowValue).canBeNull();
|
||||
}
|
||||
|
||||
public static void checkLValue(@NotNull BindingTrace trace, @NotNull JetExpression expression) {
|
||||
checkLValue(trace, expression, false);
|
||||
/**
|
||||
* @return {@code true} iff expression can be assigned to
|
||||
*/
|
||||
public static boolean checkLValue(@NotNull BindingTrace trace, @NotNull JetExpression expression) {
|
||||
return checkLValue(trace, expression, false);
|
||||
}
|
||||
|
||||
private static void checkLValue(@NotNull BindingTrace trace, @NotNull JetExpression expressionWithParenthesis, boolean canBeThis) {
|
||||
private static boolean checkLValue(@NotNull BindingTrace trace, @NotNull JetExpression expressionWithParenthesis, boolean canBeThis) {
|
||||
JetExpression expression = JetPsiUtil.deparenthesize(expressionWithParenthesis);
|
||||
if (expression instanceof JetArrayAccessExpression) {
|
||||
JetExpression arrayExpression = ((JetArrayAccessExpression) expression).getArrayExpression();
|
||||
if (arrayExpression != null) {
|
||||
checkLValue(trace, arrayExpression, true);
|
||||
}
|
||||
return;
|
||||
if (arrayExpression == null) return false;
|
||||
|
||||
return checkLValue(trace, arrayExpression, true);
|
||||
}
|
||||
if (canBeThis && expression instanceof JetThisExpression) return;
|
||||
if (canBeThis && expression instanceof JetThisExpression) return true;
|
||||
VariableDescriptor variable = BindingContextUtils.extractVariableDescriptorIfAny(trace.getBindingContext(), expression, true);
|
||||
|
||||
boolean result = true;
|
||||
JetExpression reportOn = expression != null ? expression : expressionWithParenthesis;
|
||||
if (variable instanceof PropertyDescriptor) {
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) variable;
|
||||
if (propertyDescriptor.isSetterProjectedOut()) {
|
||||
trace.report(SETTER_PROJECTED_OUT.on(reportOn, propertyDescriptor));
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (variable == null) {
|
||||
trace.report(VARIABLE_EXPECTED.on(reportOn));
|
||||
result = false;
|
||||
}
|
||||
else if (!variable.isVar()) {
|
||||
result = false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+17
-7
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.resolve.TemporaryBindingTrace;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
|
||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsImpl;
|
||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsUtil;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue;
|
||||
@@ -276,15 +277,24 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
||||
JetType assignmentOperationType = OverloadResolutionResultsUtil.getResultingType(assignmentOperationDescriptors,
|
||||
context.contextDependency);
|
||||
|
||||
// Check for '+'
|
||||
Name counterpartName = OperatorConventions.BINARY_OPERATION_NAMES.get(OperatorConventions.ASSIGNMENT_OPERATION_COUNTERPARTS.get(operationType));
|
||||
OverloadResolutionResults<FunctionDescriptor> binaryOperationDescriptors;
|
||||
JetType binaryOperationType;
|
||||
TemporaryTraceAndCache temporaryForBinaryOperation = TemporaryTraceAndCache.create(
|
||||
context, "trace to check binary operation like '+' for", expression);
|
||||
OverloadResolutionResults<FunctionDescriptor> binaryOperationDescriptors = components.callResolver.resolveBinaryCall(
|
||||
context.replaceTraceAndCache(temporaryForBinaryOperation).replaceScope(scope),
|
||||
receiver, expression, counterpartName
|
||||
);
|
||||
JetType binaryOperationType = OverloadResolutionResultsUtil.getResultingType(binaryOperationDescriptors, context.contextDependency);
|
||||
boolean lhsAssignable = BasicExpressionTypingVisitor.checkLValue(TemporaryBindingTrace.create(context.trace, "Trace for checking assignability"), left);
|
||||
if (assignmentOperationType == null || lhsAssignable) {
|
||||
// Check for '+'
|
||||
Name counterpartName = OperatorConventions.BINARY_OPERATION_NAMES.get(OperatorConventions.ASSIGNMENT_OPERATION_COUNTERPARTS.get(operationType));
|
||||
binaryOperationDescriptors = components.callResolver.resolveBinaryCall(
|
||||
context.replaceTraceAndCache(temporaryForBinaryOperation).replaceScope(scope),
|
||||
receiver, expression, counterpartName
|
||||
);
|
||||
binaryOperationType = OverloadResolutionResultsUtil.getResultingType(binaryOperationDescriptors, context.contextDependency);
|
||||
}
|
||||
else {
|
||||
binaryOperationDescriptors = OverloadResolutionResultsImpl.nameNotFound();
|
||||
binaryOperationType = null;
|
||||
}
|
||||
|
||||
JetType type = assignmentOperationType != null ? assignmentOperationType : binaryOperationType;
|
||||
if (assignmentOperationDescriptors.isSuccess() && binaryOperationDescriptors.isSuccess()) {
|
||||
|
||||
Reference in New Issue
Block a user