From da3936ddd93e345890bbf9cfe18bf20fae94b4a0 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 4 Nov 2011 14:40:45 +0300 Subject: [PATCH] ResolvedCall recorder for the correct element --- .../jet/lang/resolve/calls/CallResolver.java | 21 ++++++++++++---- .../lang/resolve/calls/JetFakeReference.java | 24 +++++++++++++++++++ 2 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/JetFakeReference.java diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index 707d4d3c2df..608273bdc96 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -177,7 +177,7 @@ public class CallResolver { else if (calleeExpression != null) { // Here we handle the case where the callee expression must be something of type function, e.g. (foo.bar())(1, 2) ExpressionTypingServices typingServices = new ExpressionTypingServices(semanticServices, trace); - JetType calleeType = typingServices.safeGetType(scope, calleeExpression, NO_EXPECTED_TYPE);// We are actually expecting a function, but there seems to be no easy way of expressing this + JetType calleeType = typingServices.safeGetType(scope, calleeExpression, NO_EXPECTED_TYPE); // We are actually expecting a function, but there seems to be no easy way of expressing this if (!JetStandardClasses.isFunctionType(calleeType)) { checkTypesWithNoCallee(trace, scope, call); @@ -193,8 +193,11 @@ public class CallResolver { resolvedCall.setReceiverArgument(call.getExplicitReceiver()); prioritizedTasks = Collections.singletonList(new ResolutionTask( Collections.singleton(resolvedCall), call, dataFlowInfo)); - functionReference = new JetReferenceExpression(calleeExpression.getNode()) { - }; + + // strictly speaking, this is a hack: + // we need to pass a reference, but there's no reference in the PSI, + // so we wrap what we have into a fake reference and pass it on (unwrap on the other end) + functionReference = new JetFakeReference(calleeExpression); } else { checkTypesWithNoCallee(trace, scope, call); @@ -239,9 +242,17 @@ public class CallResolver { // trace.record(REFERENCE_TARGET, reference, variableAsFunctionDescriptor.getVariableDescriptor()); // } // else { - trace.record(REFERENCE_TARGET, reference, descriptor); // } - trace.record(RESOLVED_CALL, reference, resolvedCall); + if (reference instanceof JetFakeReference) { + // This means that the callable being invoked was represented by an expression + // rather than a reference expression + JetFakeReference fakeReference = (JetFakeReference) reference; + trace.record(RESOLVED_CALL, fakeReference.getActualElement(), resolvedCall); + } + else { + trace.record(RESOLVED_CALL, reference, resolvedCall); + trace.record(REFERENCE_TARGET, reference, descriptor); + } } @Override diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/JetFakeReference.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/JetFakeReference.java new file mode 100644 index 00000000000..73d372d2868 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/JetFakeReference.java @@ -0,0 +1,24 @@ +package org.jetbrains.jet.lang.resolve.calls; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetElement; +import org.jetbrains.jet.lang.psi.JetReferenceExpression; + +/** + * + * This class is used to wrap an expression that occurs in a reference position, such as a function literal, into a reference expression + * + * @author abreslav + */ +public class JetFakeReference extends JetReferenceExpression { + private final JetElement actualElement; + + public JetFakeReference(@NotNull JetElement actualElement) { + super(actualElement.getNode()); + this.actualElement = actualElement; + } + + public JetElement getActualElement() { + return actualElement; + } +}