check incomplete equality

This commit is contained in:
Svetlana Isakova
2013-12-24 21:24:37 +04:00
parent 80183c88cf
commit aca21f78d5
3 changed files with 48 additions and 38 deletions
@@ -871,54 +871,56 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
final JetExpression right
) {
DataFlowInfo dataFlowInfo = context.dataFlowInfo;
if (right != null && left != null) {
ExpressionReceiver receiver = ExpressionTypingUtils.safeGetExpressionReceiver(facade, left, context);
if (right == null || left == null) {
ExpressionTypingUtils.getTypeInfoOrNullType(right, context, facade);
ExpressionTypingUtils.getTypeInfoOrNullType(left, context, facade);
return JetTypeInfo.create(KotlinBuiltIns.getInstance().getBooleanType(), dataFlowInfo);
}
ExpressionReceiver receiver = ExpressionTypingUtils.safeGetExpressionReceiver(facade, left, context);
JetTypeInfo leftTypeInfo = getTypeInfoOrNullType(left, context, facade);
JetTypeInfo leftTypeInfo = getTypeInfoOrNullType(left, context, facade);
dataFlowInfo = leftTypeInfo.getDataFlowInfo();
ExpressionTypingContext contextWithDataFlow = context.replaceDataFlowInfo(dataFlowInfo);
dataFlowInfo = leftTypeInfo.getDataFlowInfo();
ExpressionTypingContext contextWithDataFlow = context.replaceDataFlowInfo(dataFlowInfo);
TemporaryBindingTrace traceInterpretingRightAsNullableAny = TemporaryBindingTrace.create(
context.trace, "trace to resolve 'equals(Any?)' interpreting as of type Any? an expression:" + right);
traceInterpretingRightAsNullableAny.record(EXPRESSION_TYPE, right, KotlinBuiltIns.getInstance().getNullableAnyType());
traceInterpretingRightAsNullableAny.record(PROCESSED, right);
TemporaryBindingTrace traceInterpretingRightAsNullableAny = TemporaryBindingTrace.create(
context.trace, "trace to resolve 'equals(Any?)' interpreting as of type Any? an expression:" + right);
traceInterpretingRightAsNullableAny.record(EXPRESSION_TYPE, right, KotlinBuiltIns.getInstance().getNullableAnyType());
traceInterpretingRightAsNullableAny.record(PROCESSED, right);
Call call = CallMaker.makeCallWithExpressions(operationSign, receiver, null, operationSign, Collections.singletonList(right));
ExpressionTypingContext newContext = context.replaceBindingTrace(traceInterpretingRightAsNullableAny);
OverloadResolutionResults<FunctionDescriptor> resolutionResults =
newContext.resolveCallWithGivenName(call, operationSign, OperatorConventions.EQUALS);
Call call = CallMaker.makeCallWithExpressions(operationSign, receiver, null, operationSign, Collections.singletonList(right));
ExpressionTypingContext newContext = context.replaceBindingTrace(traceInterpretingRightAsNullableAny);
OverloadResolutionResults<FunctionDescriptor> resolutionResults =
newContext.resolveCallWithGivenName(call, operationSign, OperatorConventions.EQUALS);
traceInterpretingRightAsNullableAny.commit(new TraceEntryFilter() {
@Override
public boolean accept(@Nullable WritableSlice<?, ?> slice, Object key) {
traceInterpretingRightAsNullableAny.commit(new TraceEntryFilter() {
@Override
public boolean accept(@Nullable WritableSlice<?, ?> slice, Object key) {
// the type of the right expression isn't 'Any?' actually
if (key == right && (slice == EXPRESSION_TYPE || slice == PROCESSED)) return false;
// the type of the right expression isn't 'Any?' actually
if (key == right && (slice == EXPRESSION_TYPE || slice == PROCESSED)) return false;
// a hack due to KT-678
// without this line an autocast is reported on the receiver (if it was previously checked for not-null)
// with not-null check the resolution result changes from 'fun Any?.equals' to 'equals' member
if (key == left && slice == AUTOCAST) return false;
// a hack due to KT-678
// without this line an autocast is reported on the receiver (if it was previously checked for not-null)
// with not-null check the resolution result changes from 'fun Any?.equals' to 'equals' member
if (key == left && slice == AUTOCAST) return false;
return true;
}
}, true);
dataFlowInfo = facade.getTypeInfo(right, contextWithDataFlow).getDataFlowInfo();
return true;
}
}, true);
dataFlowInfo = facade.getTypeInfo(right, contextWithDataFlow).getDataFlowInfo();
if (resolutionResults.isSuccess()) {
FunctionDescriptor equals = resolutionResults.getResultingCall().getResultingDescriptor();
if (ensureBooleanResult(operationSign, OperatorConventions.EQUALS, equals.getReturnType(), context)) {
ensureNonemptyIntersectionOfOperandTypes(expression, context);
}
if (resolutionResults.isSuccess()) {
FunctionDescriptor equals = resolutionResults.getResultingCall().getResultingDescriptor();
if (ensureBooleanResult(operationSign, OperatorConventions.EQUALS, equals.getReturnType(), context)) {
ensureNonemptyIntersectionOfOperandTypes(expression, context);
}
}
else {
if (resolutionResults.isAmbiguity()) {
context.trace.report(OVERLOAD_RESOLUTION_AMBIGUITY.on(operationSign, resolutionResults.getResultingCalls()));
}
else {
if (resolutionResults.isAmbiguity()) {
context.trace.report(OVERLOAD_RESOLUTION_AMBIGUITY.on(operationSign, resolutionResults.getResultingCalls()));
}
else {
context.trace.report(EQUALS_MISSING.on(operationSign));
}
context.trace.report(EQUALS_MISSING.on(operationSign));
}
}
return JetTypeInfo.create(KotlinBuiltIns.getInstance().getBooleanType(), dataFlowInfo);
@@ -0,0 +1,3 @@
package a
fun foo(a: Any) = a <!DEBUG_INFO_MISSING_UNRESOLVED!>==<!SYNTAX!><!><!>
@@ -3326,6 +3326,11 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest("compiler/testData/diagnostics/tests/incompleteCode/incompleteAssignment.kt");
}
@TestMetadata("incompleteEquals.kt")
public void testIncompleteEquals() throws Exception {
doTest("compiler/testData/diagnostics/tests/incompleteCode/incompleteEquals.kt");
}
@TestMetadata("kt1955.kt")
public void testKt1955() throws Exception {
doTest("compiler/testData/diagnostics/tests/incompleteCode/kt1955.kt");