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);
}
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 {
if (!generateCall(operationReference)) {
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.lang.KotlinBuiltIns;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.util.slicedmap.WritableSlice;
import org.jetbrains.jet.utils.ThrowingList;
import java.util.Collection;
@@ -867,9 +868,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
ExpressionTypingContext context,
JetSimpleNameExpression operationSign,
JetExpression left,
JetExpression right
final JetExpression right
) {
JetTypeInfo result;DataFlowInfo dataFlowInfo = context.dataFlowInfo;
DataFlowInfo dataFlowInfo = context.dataFlowInfo;
if (right != null && left != null) {
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(PROCESSED, right);
Call call = CallMaker.makeCallWithExpressions(operationSign, receiver, null, operationSign, Collections.singletonList(right));
ExpressionTypingContext newContext = context.replaceBindingTrace(traceInterpretingRightAsNullableAny);
OverloadResolutionResults<FunctionDescriptor> resolutionResults =
resolveFakeCall(receiver, context.replaceBindingTrace(traceInterpretingRightAsNullableAny),
Collections.singletonList(right), OperatorConventions.EQUALS);
newContext.resolveCallWithGivenName(call, operationSign, 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();
if (resolutionResults.isSuccess()) {
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)) {
ensureNonemptyIntersectionOfOperandTypes(expression, context);
}
@@ -906,8 +912,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
}
}
}
result = JetTypeInfo.create(KotlinBuiltIns.getInstance().getBooleanType(), dataFlowInfo);
return result;
return JetTypeInfo.create(KotlinBuiltIns.getInstance().getBooleanType(), dataFlowInfo);
}
@NotNull
@@ -304,7 +304,7 @@ L4 [start finally]:
mark(list != null)
r(list)
r(null)
call(list != null, equals)
call(!=, equals)
jf(L5) NEXT:[read (Unit), mark({ })]
mark({ })
read (Unit)
@@ -320,7 +320,7 @@ L3 [skipFinallyToErrorBlock]:
mark(list != null)
r(list)
r(null)
call(list != null, equals)
call(!=, equals)
jf(copy L5) NEXT:[read (Unit), mark({ })]
mark({ })
read (Unit)
+1 -1
View File
@@ -15,7 +15,7 @@ L0:
mark(a == b)
r(a)
r(b)
call(a == b, equals)
call(==, equals)
jf(L2) NEXT:[read (Unit), mark({ })]
mark({ })
read (Unit)
+1 -1
View File
@@ -14,7 +14,7 @@ L0:
mark(a != b)
r(a)
r(b)
call(a != b, equals)
call(!=, equals)
jf(L2) NEXT:[read (Unit), mark({})]
mark({})
read (Unit)
@@ -18,7 +18,7 @@ L0:
mark(toLong())
r(0)
call(toLong, toLong)
call(x == 0.toLong(), equals)
call(==, equals)
jf(L2) NEXT:[read (Unit), r(sum)]
r(sum)
ret(*) L1 NEXT:[<END>]
@@ -20,8 +20,8 @@ fun foo() {
bar(<!TYPE_MISMATCH!>x<!>)
if (<!SENSELESS_COMPARISON!>x != null<!>) {
bar(x)
if (x == null) bar(x)
if (x == null) bar(x) else bar(x)
if (<!SENSELESS_COMPARISON!>x == null<!>) bar(x)
if (<!SENSELESS_COMPARISON!>x == null<!>) bar(x) else bar(x)
bar(bar(x) + bar(x))
} else if (<!SENSELESS_COMPARISON!>x == null<!>) {
bar(<!TYPE_MISMATCH!>x<!>)