while resolve 'equals' as a fake call do not throw away temporary trace

This commit is contained in:
Svetlana Isakova
2013-12-05 19:53:33 +04:00
parent 499783fbc6
commit 41f2fcbb40
7 changed files with 20 additions and 45 deletions
@@ -303,36 +303,6 @@ public class JetControlFlowProcessor {
} }
builder.bindLabel(afterElvis); builder.bindLabel(afterElvis);
} }
else if (operationType == JetTokens.EQEQ || operationType == JetTokens.EXCLEQ) {
// Equals is resolved on a fake argument, to ensure "Any?" in the signature, so we have to read the right argument manually
@SuppressWarnings("unchecked")
ResolvedCall<FunctionDescriptor> resolvedCall = (ResolvedCall<FunctionDescriptor>) getResolvedCall(operationReference);
if (resolvedCall != null && !resolvedCall.getValueArguments().isEmpty() && right != null) {
ResolvedCallImpl<FunctionDescriptor> fakeCall = ResolvedCallImpl.create(
ResolutionCandidate.create(
resolvedCall.getCandidateDescriptor(),
resolvedCall.getThisObject(),
resolvedCall.getReceiverArgument(),
resolvedCall.getExplicitReceiverKind(),
resolvedCall.isSafeCall()
),
new DelegatingBindingTrace(BindingContext.EMPTY, "Fake call for =="),
TracingStrategy.EMPTY,
MutableDataFlowInfoForArguments.WITHOUT_ARGUMENTS_CHECK
);
ValueParameterDescriptor parameterDescriptor = resolvedCall.getValueArguments().keySet().iterator().next();
fakeCall.recordValueArgument(
parameterDescriptor,
new ExpressionValueArgument(CallMaker.makeValueArgument(right))
);
fakeCall.setStatusToSuccess();
generateCall(expression, fakeCall);
}
else {
generateBothArguments(expression);
}
}
else { else {
if (!generateCall(operationReference)) { if (!generateCall(operationReference)) {
generateBothArguments(expression); generateBothArguments(expression);
@@ -61,6 +61,7 @@ import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.util.slicedmap.WritableSlice;
import org.jetbrains.jet.utils.ThrowingList; import org.jetbrains.jet.utils.ThrowingList;
import java.util.Collection; import java.util.Collection;
@@ -867,9 +868,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
ExpressionTypingContext context, ExpressionTypingContext context,
JetSimpleNameExpression operationSign, JetSimpleNameExpression operationSign,
JetExpression left, JetExpression left,
JetExpression right final JetExpression right
) { ) {
JetTypeInfo result;DataFlowInfo dataFlowInfo = context.dataFlowInfo; DataFlowInfo dataFlowInfo = context.dataFlowInfo;
if (right != null && left != null) { if (right != null && left != null) {
ExpressionReceiver receiver = ExpressionTypingUtils.safeGetExpressionReceiver(facade, left, context); ExpressionReceiver receiver = ExpressionTypingUtils.safeGetExpressionReceiver(facade, left, context);
@@ -883,16 +884,21 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
traceInterpretingRightAsNullableAny.record(EXPRESSION_TYPE, right, KotlinBuiltIns.getInstance().getNullableAnyType()); traceInterpretingRightAsNullableAny.record(EXPRESSION_TYPE, right, KotlinBuiltIns.getInstance().getNullableAnyType());
traceInterpretingRightAsNullableAny.record(PROCESSED, right); traceInterpretingRightAsNullableAny.record(PROCESSED, right);
Call call = CallMaker.makeCallWithExpressions(operationSign, receiver, null, operationSign, Collections.singletonList(right));
ExpressionTypingContext newContext = context.replaceBindingTrace(traceInterpretingRightAsNullableAny);
OverloadResolutionResults<FunctionDescriptor> resolutionResults = OverloadResolutionResults<FunctionDescriptor> resolutionResults =
resolveFakeCall(receiver, context.replaceBindingTrace(traceInterpretingRightAsNullableAny), newContext.resolveCallWithGivenName(call, operationSign, OperatorConventions.EQUALS);
Collections.singletonList(right), OperatorConventions.EQUALS);
traceInterpretingRightAsNullableAny.commit(new TraceEntryFilter() {
@Override
public boolean accept(@Nullable WritableSlice<?, ?> slice, Object key) {
return !(key == right && (slice == EXPRESSION_TYPE || slice == PROCESSED));
}
}, true);
dataFlowInfo = facade.getTypeInfo(right, contextWithDataFlow).getDataFlowInfo(); dataFlowInfo = facade.getTypeInfo(right, contextWithDataFlow).getDataFlowInfo();
if (resolutionResults.isSuccess()) { if (resolutionResults.isSuccess()) {
FunctionDescriptor equals = resolutionResults.getResultingCall().getResultingDescriptor(); FunctionDescriptor equals = resolutionResults.getResultingCall().getResultingDescriptor();
context.trace.record(REFERENCE_TARGET, operationSign, equals);
context.trace.record(RESOLVED_CALL, operationSign, resolutionResults.getResultingCall());
if (ensureBooleanResult(operationSign, OperatorConventions.EQUALS, equals.getReturnType(), context)) { if (ensureBooleanResult(operationSign, OperatorConventions.EQUALS, equals.getReturnType(), context)) {
ensureNonemptyIntersectionOfOperandTypes(expression, context); ensureNonemptyIntersectionOfOperandTypes(expression, context);
} }
@@ -906,8 +912,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
} }
} }
} }
result = JetTypeInfo.create(KotlinBuiltIns.getInstance().getBooleanType(), dataFlowInfo); return JetTypeInfo.create(KotlinBuiltIns.getInstance().getBooleanType(), dataFlowInfo);
return result;
} }
@NotNull @NotNull
@@ -304,7 +304,7 @@ L4 [start finally]:
mark(list != null) mark(list != null)
r(list) r(list)
r(null) r(null)
call(list != null, equals) call(!=, equals)
jf(L5) NEXT:[read (Unit), mark({ })] jf(L5) NEXT:[read (Unit), mark({ })]
mark({ }) mark({ })
read (Unit) read (Unit)
@@ -320,7 +320,7 @@ L3 [skipFinallyToErrorBlock]:
mark(list != null) mark(list != null)
r(list) r(list)
r(null) r(null)
call(list != null, equals) call(!=, equals)
jf(copy L5) NEXT:[read (Unit), mark({ })] jf(copy L5) NEXT:[read (Unit), mark({ })]
mark({ }) mark({ })
read (Unit) read (Unit)
+1 -1
View File
@@ -15,7 +15,7 @@ L0:
mark(a == b) mark(a == b)
r(a) r(a)
r(b) r(b)
call(a == b, equals) call(==, equals)
jf(L2) NEXT:[read (Unit), mark({ })] jf(L2) NEXT:[read (Unit), mark({ })]
mark({ }) mark({ })
read (Unit) read (Unit)
+1 -1
View File
@@ -14,7 +14,7 @@ L0:
mark(a != b) mark(a != b)
r(a) r(a)
r(b) r(b)
call(a != b, equals) call(!=, equals)
jf(L2) NEXT:[read (Unit), mark({})] jf(L2) NEXT:[read (Unit), mark({})]
mark({}) mark({})
read (Unit) read (Unit)
@@ -18,7 +18,7 @@ L0:
mark(toLong()) mark(toLong())
r(0) r(0)
call(toLong, toLong) call(toLong, toLong)
call(x == 0.toLong(), equals) call(==, equals)
jf(L2) NEXT:[read (Unit), r(sum)] jf(L2) NEXT:[read (Unit), r(sum)]
r(sum) r(sum)
ret(*) L1 NEXT:[<END>] ret(*) L1 NEXT:[<END>]
@@ -20,8 +20,8 @@ fun foo() {
bar(<!TYPE_MISMATCH!>x<!>) bar(<!TYPE_MISMATCH!>x<!>)
if (<!SENSELESS_COMPARISON!>x != null<!>) { if (<!SENSELESS_COMPARISON!>x != null<!>) {
bar(x) bar(x)
if (x == null) bar(x) if (<!SENSELESS_COMPARISON!>x == null<!>) bar(x)
if (x == null) bar(x) else bar(x) if (<!SENSELESS_COMPARISON!>x == null<!>) bar(x) else bar(x)
bar(bar(x) + bar(x)) bar(bar(x) + bar(x))
} else if (<!SENSELESS_COMPARISON!>x == null<!>) { } else if (<!SENSELESS_COMPARISON!>x == null<!>) {
bar(<!TYPE_MISMATCH!>x<!>) bar(<!TYPE_MISMATCH!>x<!>)