Refactoring: separated VariableAsFunctionResolvedCall interface and implementation

This commit is contained in:
Svetlana Isakova
2014-04-23 16:22:37 +04:00
parent cdd88cdaa7
commit 703e4d7c4e
9 changed files with 71 additions and 176 deletions
@@ -33,7 +33,7 @@ import org.jetbrains.jet.lang.resolve.calls.context.CallCandidateResolutionConte
import org.jetbrains.jet.lang.resolve.calls.context.ContextDependency;
import org.jetbrains.jet.lang.resolve.calls.model.MutableResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl;
import org.jetbrains.jet.lang.resolve.calls.model.VariableAsFunctionResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.model.VariableAsFunctionResolvedCallImpl;
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl;
import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind;
@@ -215,7 +215,7 @@ public class CallTransformer<D extends CallableDescriptor, F extends D> {
return Collections2.transform(calls, new Function<MutableResolvedCall<FunctionDescriptor>, MutableResolvedCall<FunctionDescriptor>>() {
@Override
public MutableResolvedCall<FunctionDescriptor> apply(MutableResolvedCall<FunctionDescriptor> functionResolvedCall) {
return new VariableAsFunctionResolvedCall(functionResolvedCall, variableResolvedCall);
return new VariableAsFunctionResolvedCallImpl(functionResolvedCall, variableResolvedCall);
}
});
}
@@ -36,6 +36,7 @@ public interface MutableResolvedCall<D extends CallableDescriptor> extends Resol
boolean isDirty();
@NotNull
DelegatingBindingTrace getTrace();
/**
@@ -1,165 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.resolve.calls.model;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.psi.Call;
import org.jetbrains.jet.lang.psi.ValueArgument;
import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace;
import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind;
import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.JetType;
import java.util.List;
import java.util.Map;
public class VariableAsFunctionResolvedCall implements MutableResolvedCall<FunctionDescriptor> {
private final MutableResolvedCall<FunctionDescriptor> functionCall;
private final MutableResolvedCall<VariableDescriptor> variableCall;
public VariableAsFunctionResolvedCall(@NotNull MutableResolvedCall<FunctionDescriptor> functionCall,
@NotNull MutableResolvedCall<VariableDescriptor> variableCall) {
this.functionCall = functionCall;
this.variableCall = variableCall;
}
@NotNull
public MutableResolvedCall<FunctionDescriptor> getFunctionCall() {
return functionCall;
}
@NotNull
public MutableResolvedCall<VariableDescriptor> getVariableCall() {
return variableCall;
}
@NotNull
@Override
public Call getCall() {
return variableCall.getCall();
}
@NotNull
@Override
public FunctionDescriptor getCandidateDescriptor() {
return functionCall.getResultingDescriptor();
}
@NotNull
@Override
public FunctionDescriptor getResultingDescriptor() {
return functionCall.getResultingDescriptor();
}
@NotNull
@Override
public ReceiverValue getReceiverArgument() {
return variableCall.getReceiverArgument();
}
@NotNull
@Override
public ReceiverValue getThisObject() {
return variableCall.getThisObject();
}
@NotNull
@Override
public ExplicitReceiverKind getExplicitReceiverKind() {
return variableCall.getExplicitReceiverKind();
}
@NotNull
@Override
public Map<ValueParameterDescriptor, ResolvedValueArgument> getValueArguments() {
return functionCall.getValueArguments();
}
@Nullable
@Override
public List<ResolvedValueArgument> getValueArgumentsByIndex() {
return functionCall.getValueArgumentsByIndex();
}
@NotNull
@Override
public ArgumentMapping getArgumentMapping(@NotNull ValueArgument valueArgument) {
return functionCall.getArgumentMapping(valueArgument);
}
@NotNull
@Override
public Map<TypeParameterDescriptor, JetType> getTypeArguments() {
return functionCall.getTypeArguments();
}
@NotNull
@Override
public ResolutionStatus getStatus() {
return variableCall.getStatus().combine(functionCall.getStatus());
}
@Override
public boolean isDirty() {
return functionCall.isDirty();
}
@Override
public DelegatingBindingTrace getTrace() {
//functionCall.trace is temporary trace above variableCall.trace and is committed already
return variableCall.getTrace();
}
@Override
public boolean isSafeCall() {
return variableCall.isSafeCall() || functionCall.isSafeCall();
}
@Override
public boolean hasIncompleteTypeParameters() {
return variableCall.hasIncompleteTypeParameters();
}
@NotNull
@Override
public ResolvedCallImpl<FunctionDescriptor> getCallToCompleteTypeArgumentInference() {
return functionCall.getCallToCompleteTypeArgumentInference();
}
@NotNull
@Override
public DataFlowInfoForArguments getDataFlowInfoForArguments() {
return functionCall.getDataFlowInfoForArguments();
}
@Override
public void markCallAsCompleted() {
functionCall.markCallAsCompleted();
variableCall.markCallAsCompleted();
}
@Override
public boolean isCompleted() {
return functionCall.isCompleted() && variableCall.isCompleted();
}
}
@@ -0,0 +1,55 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.resolve.calls.model
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor
import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor
import org.jetbrains.jet.lang.descriptors.VariableDescriptor
import org.jetbrains.jet.lang.psi.Call
import org.jetbrains.jet.lang.psi.ValueArgument
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor
import org.jetbrains.jet.lang.types.JetType
import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus
import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace
public trait VariableAsFunctionResolvedCall {
public val functionCall: ResolvedCall<FunctionDescriptor>
public val variableCall: ResolvedCall<VariableDescriptor>
}
class VariableAsFunctionResolvedCallImpl(
public override val functionCall: MutableResolvedCall<FunctionDescriptor>,
public override val variableCall: MutableResolvedCall<VariableDescriptor>
) : VariableAsFunctionResolvedCall, MutableResolvedCall<FunctionDescriptor> by functionCall {
override fun markCallAsCompleted() {
functionCall.markCallAsCompleted()
variableCall.markCallAsCompleted()
}
override fun isCompleted(): Boolean = functionCall.isCompleted() && variableCall.isCompleted()
override fun getStatus(): ResolutionStatus = variableCall.getStatus().combine(functionCall.getStatus())
override fun getTrace(): DelegatingBindingTrace {
//functionCall.trace is temporary trace above variableCall.trace and is committed already
return variableCall.getTrace()
}
}
@@ -24,6 +24,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.OverrideResolver;
import org.jetbrains.jet.lang.resolve.calls.model.MutableResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.model.VariableAsFunctionResolvedCall;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
@@ -89,7 +90,7 @@ public class OverloadingConflictResolver {
if (!isInvoke) return false;
assert otherCall instanceof VariableAsFunctionResolvedCall : "'invoke' candidate goes with usual one: " + candidateCall + otherCall;
MutableResolvedCall<VariableDescriptor> otherVariableCall = ((VariableAsFunctionResolvedCall) otherCall).getVariableCall();
ResolvedCall<VariableDescriptor> otherVariableCall = ((VariableAsFunctionResolvedCall) otherCall).getVariableCall();
if (definitelyNotMaximallySpecific(variable, otherVariableCall.getResultingDescriptor(), discriminateGenericDescriptors)) {
return false;
}
@@ -16,6 +16,8 @@
package org.jetbrains.jet.lang.resolve.calls.results;
import org.jetbrains.annotations.NotNull;
import java.util.EnumSet;
public enum ResolutionStatus {
@@ -55,6 +57,7 @@ public enum ResolutionStatus {
return success;
}
@NotNull
public ResolutionStatus combine(ResolutionStatus other) {
if (this == UNKNOWN_STATUS) return other;
if (SUCCESS.among(this, other)) {
@@ -80,8 +80,8 @@ public abstract class AbstractResolvedCallsTest() : JetLiteFixture() {
}
if (resolvedCall is VariableAsFunctionResolvedCall) {
tryCall(resolvedCall.getFunctionCall(), "invoke")
tryCall(resolvedCall.getVariableCall())
tryCall(resolvedCall.functionCall, "invoke")
tryCall(resolvedCall.variableCall)
}
else {
tryCall(resolvedCall)
@@ -23,7 +23,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.model.VariableAsFunctionResolvedCall;
import org.jetbrains.jet.lexer.JetTokens;
@@ -53,7 +52,8 @@ class JetInvokeFunctionReference extends JetSimpleReference<JetCallExpression> i
JetExpression calleeExpression = getExpression().getCalleeExpression();
ResolvedCall<?> resolvedCall = context.get(RESOLVED_CALL, calleeExpression);
if (resolvedCall instanceof VariableAsFunctionResolvedCall) {
return Collections.<DeclarationDescriptor>singleton(((VariableAsFunctionResolvedCall) resolvedCall).getCandidateDescriptor());
return Collections.<DeclarationDescriptor>singleton(
((VariableAsFunctionResolvedCall) resolvedCall).getFunctionCall().getCandidateDescriptor());
}
Call call = context.get(CALL, calleeExpression);
if (call != null && resolvedCall != null && call.getCallType() == Call.CallType.INVOKE) {
@@ -85,16 +85,16 @@ private fun translateCall(context: TranslationContext,
): JsExpression {
if (resolvedCall is VariableAsFunctionResolvedCall) {
assert(explicitReceivers.receiverObject == null, "VariableAsFunctionResolvedCall must have one receiver")
val variableCall = resolvedCall.getVariableCall()
val variableCall = resolvedCall.variableCall
if (variableCall.expectedReceivers()) {
val newReceiver = CallTranslator.translateGet(context, variableCall, explicitReceivers.receiverOrThisObject)
return translateFunctionCall(context, resolvedCall.getFunctionCall(), ExplicitReceivers(newReceiver))
return translateFunctionCall(context, resolvedCall.functionCall, ExplicitReceivers(newReceiver))
} else {
val thisObject = CallTranslator.translateGet(context, variableCall, null)
if (explicitReceivers.receiverOrThisObject == null)
return translateFunctionCall(context, resolvedCall.getFunctionCall(), ExplicitReceivers(thisObject))
return translateFunctionCall(context, resolvedCall.functionCall, ExplicitReceivers(thisObject))
else
return translateFunctionCall(context, resolvedCall.getFunctionCall(), ExplicitReceivers(thisObject, explicitReceivers.receiverOrThisObject))
return translateFunctionCall(context, resolvedCall.functionCall, ExplicitReceivers(thisObject, explicitReceivers.receiverOrThisObject))
}
}