Call resolution refactoring (logic hasn't changed)
- interfaces MemberPrioritizer, ResolutionCandidate introduced - CallTransformationStrategy will be responsible for variable with 'invoke' method as function resolve
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.Call;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public final class CallResolutionContext<D extends CallableDescriptor> extends ResolutionContext {
|
||||
/*package*/ final ResolvedCallImpl<D> candidateCall;
|
||||
/*package*/ final TracingStrategy tracing;
|
||||
|
||||
public CallResolutionContext(@NotNull ResolvedCallImpl<D> candidateCall, @NotNull ResolutionTask<D> task, @NotNull BindingTrace trace, @NotNull TracingStrategy tracing, @NotNull Call call) {
|
||||
super(trace, task.scope, call, task.expectedType, task.dataFlowInfo);
|
||||
this.candidateCall = candidateCall;
|
||||
this.tracing = tracing;
|
||||
}
|
||||
|
||||
public CallResolutionContext(@NotNull ResolvedCallImpl<D> candidateCall, @NotNull ResolutionTask<D> task, @NotNull BindingTrace trace, @NotNull TracingStrategy tracing) {
|
||||
this(candidateCall, task, trace, tracing, task.call);
|
||||
}
|
||||
}
|
||||
@@ -102,16 +102,16 @@ public class CallResolver {
|
||||
if (referencedName == null) {
|
||||
return OverloadResolutionResultsImpl.nameNotFound();
|
||||
}
|
||||
TaskPrioritizer<VariableDescriptor> task_prioritizer;
|
||||
List<MemberPrioritizer<VariableDescriptor>> memberPrioritizers = Lists.newArrayList();
|
||||
if (nameExpression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER) {
|
||||
referencedName = referencedName.substring(1);
|
||||
task_prioritizer = TaskPrioritizers.PROPERTY_TASK_PRIORITIZER;
|
||||
memberPrioritizers.add(MemberPrioritizers.PROPERTY_TASK_PRIORITIZER);
|
||||
}
|
||||
else {
|
||||
task_prioritizer = TaskPrioritizers.VARIABLE_TASK_PRIORITIZER;
|
||||
memberPrioritizers.add(MemberPrioritizers.VARIABLE_TASK_PRIORITIZER);
|
||||
}
|
||||
List<ResolutionTask<VariableDescriptor>> prioritizedTasks = task_prioritizer.computePrioritizedTasks(context, referencedName, nameExpression);
|
||||
return doResolveCall(context, prioritizedTasks, nameExpression);
|
||||
List<ResolutionTask<VariableDescriptor>> prioritizedTasks = TaskPrioritizer.computePrioritizedTasks(context, referencedName, nameExpression, memberPrioritizers);
|
||||
return doResolveCall(context, prioritizedTasks, CallTransformationStrategy.PROPERTY_CALL_TRANSFORMATION_STRATEGY, nameExpression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -119,9 +119,9 @@ public class CallResolver {
|
||||
@NotNull BasicResolutionContext context,
|
||||
@NotNull final JetReferenceExpression functionReference,
|
||||
@NotNull String name) {
|
||||
List<ResolutionTask<FunctionDescriptor>> tasks = TaskPrioritizers.FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks(
|
||||
context, name, functionReference);
|
||||
return doResolveCall(context, tasks, functionReference);
|
||||
List<ResolutionTask<FunctionDescriptor>> tasks = TaskPrioritizer.computePrioritizedTasks(
|
||||
context, name, functionReference, Collections.singletonList(MemberPrioritizers.FUNCTION_TASK_PRIORITIZER));
|
||||
return doResolveCall(context, tasks, CallTransformationStrategy.FUNCTION_CALL_TRANSFORMATION_STRATEGY, functionReference);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -142,7 +142,7 @@ public class CallResolver {
|
||||
String name = expression.getReferencedName();
|
||||
if (name == null) return checkArgumentTypesAndFail(context);
|
||||
|
||||
prioritizedTasks = TaskPrioritizers.FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks(context, name, functionReference);
|
||||
prioritizedTasks = TaskPrioritizer.computePrioritizedTasks(context, name, functionReference, Collections.singletonList(MemberPrioritizers.FUNCTION_TASK_PRIORITIZER));
|
||||
ResolutionTask.DescriptorCheckStrategy abstractConstructorCheck = new ResolutionTask.DescriptorCheckStrategy() {
|
||||
@Override
|
||||
public <D extends CallableDescriptor> boolean performAdvancedChecks(D descriptor, BindingTrace trace, TracingStrategy tracing) {
|
||||
@@ -184,7 +184,7 @@ public class CallResolver {
|
||||
context.trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn));
|
||||
return checkArgumentTypesAndFail(context);
|
||||
}
|
||||
Collection<ResolvedCallImpl<FunctionDescriptor>> candidates = TaskPrioritizer.<FunctionDescriptor>convertWithImpliedThis(context.scope, Collections.<ReceiverDescriptor>singletonList(NO_RECEIVER), constructors);
|
||||
Collection<ResolutionCandidate<FunctionDescriptor>> candidates = TaskPrioritizer.<FunctionDescriptor>convertWithImpliedThis(context.scope, Collections.<ReceiverDescriptor>singletonList(NO_RECEIVER), constructors);
|
||||
prioritizedTasks.add(new ResolutionTask<FunctionDescriptor>(candidates, functionReference, context)); // !! DataFlowInfo.EMPTY
|
||||
}
|
||||
else {
|
||||
@@ -206,7 +206,7 @@ public class CallResolver {
|
||||
context.trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn));
|
||||
return checkArgumentTypesAndFail(context);
|
||||
}
|
||||
List<ResolvedCallImpl<FunctionDescriptor>> candidates = ResolvedCallImpl.<FunctionDescriptor>convertCollection(constructors);
|
||||
List<ResolutionCandidate<FunctionDescriptor>> candidates = ResolutionCandidate.<FunctionDescriptor>convertCollection(constructors);
|
||||
prioritizedTasks = Collections.singletonList(new ResolutionTask<FunctionDescriptor>(candidates, functionReference, context)); // !! DataFlowInfo.EMPTY
|
||||
}
|
||||
else if (calleeExpression != null) {
|
||||
@@ -223,15 +223,15 @@ public class CallResolver {
|
||||
|
||||
FunctionDescriptorImpl functionDescriptor = new ExpressionAsFunctionDescriptor(context.scope.getContainingDeclaration(), "[for expression " + calleeExpression.getText() + "]");
|
||||
FunctionDescriptorUtil.initializeFromFunctionType(functionDescriptor, calleeType, NO_RECEIVER);
|
||||
ResolvedCallImpl<FunctionDescriptor> resolvedCall = ResolvedCallImpl.<FunctionDescriptor>create(functionDescriptor);
|
||||
resolvedCall.setReceiverArgument(context.call.getExplicitReceiver());
|
||||
ResolutionCandidate<FunctionDescriptor> resolutionCandidate = ResolutionCandidate.<FunctionDescriptor>create(functionDescriptor);
|
||||
resolutionCandidate.setReceiverArgument(context.call.getExplicitReceiver());
|
||||
|
||||
// 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);
|
||||
|
||||
prioritizedTasks = Collections.singletonList(new ResolutionTask<FunctionDescriptor>(Collections.singleton(resolvedCall), functionReference, context));
|
||||
prioritizedTasks = Collections.singletonList(new ResolutionTask<FunctionDescriptor>(Collections.singleton(resolutionCandidate), functionReference, context));
|
||||
}
|
||||
else {
|
||||
// checkTypesWithNoCallee(trace, scope, call);
|
||||
@@ -239,7 +239,7 @@ public class CallResolver {
|
||||
}
|
||||
}
|
||||
|
||||
return doResolveCall(context, prioritizedTasks, functionReference);
|
||||
return doResolveCall(context, prioritizedTasks, CallTransformationStrategy.FUNCTION_CALL_TRANSFORMATION_STRATEGY, functionReference);
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> OverloadResolutionResults<D> checkArgumentTypesAndFail(BasicResolutionContext context) {
|
||||
@@ -251,6 +251,7 @@ public class CallResolver {
|
||||
private <D extends CallableDescriptor> OverloadResolutionResults<D> doResolveCall(
|
||||
@NotNull final BasicResolutionContext context,
|
||||
@NotNull final List<ResolutionTask<D>> prioritizedTasks, // high to low priority
|
||||
@NotNull CallTransformationStrategy<D, D> callTransformationStrategy,
|
||||
@NotNull final JetReferenceExpression reference) {
|
||||
|
||||
ResolutionDebugInfo.Data debugInfo = ResolutionDebugInfo.create();
|
||||
@@ -267,7 +268,7 @@ public class CallResolver {
|
||||
OverloadResolutionResultsImpl<D> resultsForFirstNonemptyCandidateSet = null;
|
||||
for (ResolutionTask<D> task : prioritizedTasks) {
|
||||
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace);
|
||||
OverloadResolutionResultsImpl<D> results = performResolutionGuardedForExtraFunctionLiteralArguments(task.withTrace(temporaryTrace));
|
||||
OverloadResolutionResultsImpl<D> results = performResolutionGuardedForExtraFunctionLiteralArguments(task.withTrace(temporaryTrace), callTransformationStrategy);
|
||||
if (results.isSuccess() || results.isAmbiguity()) {
|
||||
temporaryTrace.commit();
|
||||
|
||||
@@ -299,8 +300,9 @@ public class CallResolver {
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@NotNull
|
||||
private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> performResolutionGuardedForExtraFunctionLiteralArguments(ResolutionTask<D> task) {
|
||||
OverloadResolutionResultsImpl<D> results = performResolution(task);
|
||||
private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> performResolutionGuardedForExtraFunctionLiteralArguments(@NotNull ResolutionTask<D> task,
|
||||
@NotNull CallTransformationStrategy<D, D> callTransformationStrategy) {
|
||||
OverloadResolutionResultsImpl<D> results = performResolution(task, callTransformationStrategy);
|
||||
|
||||
// If resolution fails, we should check for some of the following situations:
|
||||
// class A {
|
||||
@@ -323,9 +325,9 @@ public class CallResolver {
|
||||
// We have some candidates that failed for some reason
|
||||
// And we have a suspect: the function literal argument
|
||||
// Now, we try to remove this argument and see if it helps
|
||||
Collection<ResolvedCallImpl<D>> newCandidates = Lists.newArrayList();
|
||||
for (ResolvedCallImpl<D> candidate : task.getCandidates()) {
|
||||
newCandidates.add(ResolvedCallImpl.create(candidate.getCandidateDescriptor()));
|
||||
Collection<ResolutionCandidate<D>> newCandidates = Lists.newArrayList();
|
||||
for (ResolutionCandidate<D> candidate : task.getCandidates()) {
|
||||
newCandidates.add(ResolutionCandidate.create(candidate.getDescriptor()));
|
||||
}
|
||||
ResolutionTask<D> newContext = new ResolutionTask<D>(newCandidates, task.reference, TemporaryBindingTrace.create(task.trace), task.scope, new DelegatingCall(task.call) {
|
||||
@NotNull
|
||||
@@ -334,7 +336,7 @@ public class CallResolver {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}, task.expectedType, task.dataFlowInfo);
|
||||
OverloadResolutionResultsImpl<D> resultsWithFunctionLiteralsStripped = performResolution(newContext);
|
||||
OverloadResolutionResultsImpl<D> resultsWithFunctionLiteralsStripped = performResolution(newContext, callTransformationStrategy);
|
||||
if (resultsWithFunctionLiteralsStripped.isSuccess() || resultsWithFunctionLiteralsStripped.isAmbiguity()) {
|
||||
task.tracing.danglingFunctionLiteralArgumentSuspected(task.trace, task.call.getFunctionLiteralArguments());
|
||||
}
|
||||
@@ -344,101 +346,23 @@ public class CallResolver {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> performResolution(ResolutionTask<D> task) {
|
||||
for (ResolvedCallImpl<D> candidateCall : task.getCandidates()) {
|
||||
D candidate = candidateCall.getCandidateDescriptor();
|
||||
private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> performResolution(@NotNull ResolutionTask<D> task,
|
||||
@NotNull CallTransformationStrategy<D, D> callTransformationStrategy) {
|
||||
|
||||
for (ResolutionCandidate<D> resolutionCandidate : task.getCandidates()) {
|
||||
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(task.trace);
|
||||
candidateCall.setTrace(temporaryTrace);
|
||||
CallResolutionContext<D> context = callTransformationStrategy.createCallContext(resolutionCandidate, task, temporaryTrace, task.tracing);
|
||||
performResolutionForCandidateCall(context, task, temporaryTrace);
|
||||
|
||||
CallResolutionContext<D> context = new CallResolutionContext<D>(candidateCall, task, temporaryTrace, task.tracing);
|
||||
|
||||
context.tracing.bindReference(context.trace, candidateCall);
|
||||
|
||||
if (ErrorUtils.isError(candidate)) {
|
||||
candidateCall.setStatus(SUCCESS);
|
||||
checkTypesWithNoCallee(context.toBasic());
|
||||
continue;
|
||||
Collection<ResolvedCallImpl<D>> calls = callTransformationStrategy.transformResultCall(context, this, task);
|
||||
for (ResolvedCallImpl<D> call : calls) {
|
||||
task.getResolvedCallMap().put(resolutionCandidate, call);
|
||||
}
|
||||
|
||||
if (!Visibilities.isVisible(candidate, context.scope.getContainingDeclaration())) {
|
||||
candidateCall.setStatus(OTHER_ERROR);
|
||||
context.tracing.invisibleMember(context.trace, candidate);
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean errorInArgumentMapping = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(context.call, context.tracing, candidateCall);
|
||||
if (errorInArgumentMapping) {
|
||||
candidateCall.setStatus(OTHER_ERROR);
|
||||
checkTypesWithNoCallee(context.toBasic());
|
||||
continue;
|
||||
}
|
||||
|
||||
List<JetTypeProjection> jetTypeArguments = context.call.getTypeArguments();
|
||||
if (jetTypeArguments.isEmpty()) {
|
||||
if (!candidate.getTypeParameters().isEmpty()) {
|
||||
candidateCall.setStatus(inferTypeArguments(context));
|
||||
}
|
||||
else {
|
||||
candidateCall.setStatus(checkAllValueArguments(context));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Explicit type arguments passed
|
||||
|
||||
List<JetType> typeArguments = new ArrayList<JetType>();
|
||||
for (JetTypeProjection projection : jetTypeArguments) {
|
||||
if (projection.getProjectionKind() != JetProjectionKind.NONE) {
|
||||
context.trace.report(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT.on(projection));
|
||||
}
|
||||
JetTypeReference typeReference = projection.getTypeReference();
|
||||
if (typeReference != null) {
|
||||
typeArguments.add(typeResolver.resolveType(context.scope, typeReference, context.trace, true));
|
||||
}
|
||||
else {
|
||||
typeArguments.add(ErrorUtils.createErrorType("Star projection in a call"));
|
||||
}
|
||||
}
|
||||
int expectedTypeArgumentCount = candidate.getTypeParameters().size();
|
||||
if (expectedTypeArgumentCount == jetTypeArguments.size()) {
|
||||
|
||||
checkGenericBoundsInAFunctionCall(jetTypeArguments, typeArguments, candidate, context.trace);
|
||||
|
||||
Map<TypeConstructor, TypeProjection> substitutionContext = FunctionDescriptorUtil.createSubstitutionContext((FunctionDescriptor) candidate, typeArguments);
|
||||
D substitutedDescriptor = (D) candidate.substitute(TypeSubstitutor.create(substitutionContext));
|
||||
|
||||
candidateCall.setResultingDescriptor(substitutedDescriptor);
|
||||
replaceValueParametersWithSubstitutedOnes(candidateCall, substitutedDescriptor);
|
||||
|
||||
List<TypeParameterDescriptor> typeParameters = candidateCall.getCandidateDescriptor().getTypeParameters();
|
||||
for (int i = 0; i < typeParameters.size(); i++) {
|
||||
TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
|
||||
candidateCall.recordTypeArgument(typeParameterDescriptor, typeArguments.get(i));
|
||||
}
|
||||
candidateCall.setStatus(checkAllValueArguments(context));
|
||||
}
|
||||
else {
|
||||
candidateCall.setStatus(OTHER_ERROR);
|
||||
context.tracing.wrongNumberOfTypeArguments(context.trace, expectedTypeArgumentCount);
|
||||
}
|
||||
}
|
||||
|
||||
task.performAdvancedChecks(candidate, context.trace, context.tracing);
|
||||
|
||||
// 'super' cannot be passed as an argument, for receiver arguments expression typer does not track this
|
||||
// See TaskPrioritizer for more
|
||||
JetSuperExpression superExpression = TaskPrioritizer.getReceiverSuper(candidateCall.getReceiverArgument());
|
||||
if (superExpression != null) {
|
||||
context.trace.report(SUPER_IS_NOT_AN_EXPRESSION.on(superExpression, superExpression.getText()));
|
||||
candidateCall.setStatus(OTHER_ERROR);
|
||||
}
|
||||
|
||||
recordAutoCastIfNecessary(candidateCall.getReceiverArgument(), candidateCall.getTrace());
|
||||
recordAutoCastIfNecessary(candidateCall.getThisObject(), candidateCall.getTrace());
|
||||
}
|
||||
|
||||
Set<ResolvedCallImpl<D>> successfulCandidates = Sets.newLinkedHashSet();
|
||||
Set<ResolvedCallImpl<D>> failedCandidates = Sets.newLinkedHashSet();
|
||||
for (ResolvedCallImpl<D> candidateCall : task.getCandidates()) {
|
||||
for (ResolvedCallImpl<D> candidateCall : task.getResolvedCallMap().values()) {
|
||||
ResolutionStatus status = candidateCall.getStatus();
|
||||
if (status.isSuccess()) {
|
||||
successfulCandidates.add(candidateCall);
|
||||
@@ -456,6 +380,99 @@ public class CallResolver {
|
||||
return results;
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> void performResolutionForCandidateCall(@NotNull CallResolutionContext<D> context,
|
||||
@NotNull ResolutionTask<D> task,
|
||||
@NotNull TemporaryBindingTrace temporaryTrace) {
|
||||
ResolvedCallImpl<D> candidateCall = context.candidateCall;
|
||||
|
||||
candidateCall.setTrace(temporaryTrace);
|
||||
D candidate = candidateCall.getCandidateDescriptor();
|
||||
|
||||
context.tracing.bindReference(context.trace, candidateCall);
|
||||
|
||||
if (ErrorUtils.isError(candidate)) {
|
||||
candidateCall.setStatus(SUCCESS);
|
||||
checkTypesWithNoCallee(context.toBasic());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Visibilities.isVisible(candidate, context.scope.getContainingDeclaration())) {
|
||||
candidateCall.setStatus(OTHER_ERROR);
|
||||
context.tracing.invisibleMember(context.trace, candidate);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean errorInArgumentMapping = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(context.call, context.tracing, candidateCall);
|
||||
if (errorInArgumentMapping) {
|
||||
candidateCall.setStatus(OTHER_ERROR);
|
||||
checkTypesWithNoCallee(context.toBasic());
|
||||
return;
|
||||
}
|
||||
|
||||
List<JetTypeProjection> jetTypeArguments = context.call.getTypeArguments();
|
||||
if (jetTypeArguments.isEmpty()) {
|
||||
if (!candidate.getTypeParameters().isEmpty()) {
|
||||
candidateCall.setStatus(inferTypeArguments(context));
|
||||
}
|
||||
else {
|
||||
candidateCall.setStatus(checkAllValueArguments(context));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Explicit type arguments passed
|
||||
|
||||
List<JetType> typeArguments = new ArrayList<JetType>();
|
||||
for (JetTypeProjection projection : jetTypeArguments) {
|
||||
if (projection.getProjectionKind() != JetProjectionKind.NONE) {
|
||||
context.trace.report(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT.on(projection));
|
||||
}
|
||||
JetTypeReference typeReference = projection.getTypeReference();
|
||||
if (typeReference != null) {
|
||||
typeArguments.add(typeResolver.resolveType(context.scope, typeReference, context.trace, true));
|
||||
}
|
||||
else {
|
||||
typeArguments.add(ErrorUtils.createErrorType("Star projection in a call"));
|
||||
}
|
||||
}
|
||||
int expectedTypeArgumentCount = candidate.getTypeParameters().size();
|
||||
if (expectedTypeArgumentCount == jetTypeArguments.size()) {
|
||||
|
||||
checkGenericBoundsInAFunctionCall(jetTypeArguments, typeArguments, candidate, context.trace);
|
||||
|
||||
Map<TypeConstructor, TypeProjection>
|
||||
substitutionContext = FunctionDescriptorUtil.createSubstitutionContext((FunctionDescriptor)candidate, typeArguments);
|
||||
D substitutedDescriptor = (D) candidate.substitute(TypeSubstitutor.create(substitutionContext));
|
||||
|
||||
candidateCall.setResultingDescriptor(substitutedDescriptor);
|
||||
replaceValueParametersWithSubstitutedOnes(candidateCall, substitutedDescriptor);
|
||||
|
||||
List<TypeParameterDescriptor> typeParameters = candidateCall.getCandidateDescriptor().getTypeParameters();
|
||||
for (int i = 0; i < typeParameters.size(); i++) {
|
||||
TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
|
||||
candidateCall.recordTypeArgument(typeParameterDescriptor, typeArguments.get(i));
|
||||
}
|
||||
candidateCall.setStatus(checkAllValueArguments(context));
|
||||
}
|
||||
else {
|
||||
candidateCall.setStatus(OTHER_ERROR);
|
||||
context.tracing.wrongNumberOfTypeArguments(context.trace, expectedTypeArgumentCount);
|
||||
}
|
||||
}
|
||||
|
||||
task.performAdvancedChecks(candidate, context.trace, context.tracing);
|
||||
|
||||
// 'super' cannot be passed as an argument, for receiver arguments expression typer does not track this
|
||||
// See TaskPrioritizer for more
|
||||
JetSuperExpression superExpression = TaskPrioritizer.getReceiverSuper(candidateCall.getReceiverArgument());
|
||||
if (superExpression != null) {
|
||||
context.trace.report(SUPER_IS_NOT_AN_EXPRESSION.on(superExpression, superExpression.getText()));
|
||||
candidateCall.setStatus(OTHER_ERROR);
|
||||
}
|
||||
|
||||
recordAutoCastIfNecessary(candidateCall.getReceiverArgument(), candidateCall.getTrace());
|
||||
recordAutoCastIfNecessary(candidateCall.getThisObject(), candidateCall.getTrace());
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> ResolutionStatus inferTypeArguments(CallResolutionContext<D> context) {
|
||||
ResolvedCallImpl<D> candidateCall = context.candidateCall;
|
||||
D candidate = candidateCall.getCandidateDescriptor();
|
||||
@@ -843,25 +860,26 @@ public class CallResolver {
|
||||
|
||||
@NotNull
|
||||
public OverloadResolutionResults<FunctionDescriptor> resolveExactSignature(@NotNull JetScope scope, @NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List<JetType> parameterTypes) {
|
||||
List<ResolvedCallImpl<FunctionDescriptor>> result = findCandidatesByExactSignature(scope, receiver, name, parameterTypes);
|
||||
List<ResolutionCandidate<FunctionDescriptor>> candidates = findCandidatesByExactSignature(scope, receiver, name, parameterTypes);
|
||||
|
||||
BindingTraceContext trace = new BindingTraceContext();
|
||||
TemporaryBindingTrace temporaryBindingTrace = TemporaryBindingTrace.create(trace);
|
||||
Set<ResolvedCallImpl<FunctionDescriptor>> candidates = Sets.newLinkedHashSet();
|
||||
for (ResolvedCallImpl<FunctionDescriptor> call : result) {
|
||||
Set<ResolvedCallImpl<FunctionDescriptor>> calls = Sets.newLinkedHashSet();
|
||||
for (ResolutionCandidate<FunctionDescriptor> candidate : candidates) {
|
||||
ResolvedCallImpl<FunctionDescriptor> call = ResolvedCallImpl.create(candidate);
|
||||
call.setTrace(temporaryBindingTrace);
|
||||
candidates.add(call);
|
||||
calls.add(call);
|
||||
}
|
||||
return computeResultAndReportErrors(trace, TracingStrategy.EMPTY, candidates, Collections.<ResolvedCallImpl<FunctionDescriptor>>emptySet());
|
||||
return computeResultAndReportErrors(trace, TracingStrategy.EMPTY, calls, Collections.<ResolvedCallImpl<FunctionDescriptor>>emptySet());
|
||||
}
|
||||
|
||||
private List<ResolvedCallImpl<FunctionDescriptor>> findCandidatesByExactSignature(JetScope scope, ReceiverDescriptor receiver,
|
||||
private List<ResolutionCandidate<FunctionDescriptor>> findCandidatesByExactSignature(JetScope scope, ReceiverDescriptor receiver,
|
||||
String name, List<JetType> parameterTypes) {
|
||||
List<ResolvedCallImpl<FunctionDescriptor>> result = Lists.newArrayList();
|
||||
List<ResolutionCandidate<FunctionDescriptor>> result = Lists.newArrayList();
|
||||
if (receiver.exists()) {
|
||||
Collection<ResolvedCallImpl<FunctionDescriptor>> extensionFunctionDescriptors = ResolvedCallImpl.convertCollection(scope.getFunctions(name));
|
||||
List<ResolvedCallImpl<FunctionDescriptor>> nonlocal = Lists.newArrayList();
|
||||
List<ResolvedCallImpl<FunctionDescriptor>> local = Lists.newArrayList();
|
||||
Collection<ResolutionCandidate<FunctionDescriptor>> extensionFunctionDescriptors = ResolutionCandidate.convertCollection(scope.getFunctions(name));
|
||||
List<ResolutionCandidate<FunctionDescriptor>> nonlocal = Lists.newArrayList();
|
||||
List<ResolutionCandidate<FunctionDescriptor>> local = Lists.newArrayList();
|
||||
TaskPrioritizer.splitLexicallyLocalDescriptors(extensionFunctionDescriptors, scope.getContainingDeclaration(), local, nonlocal);
|
||||
|
||||
|
||||
@@ -869,7 +887,7 @@ public class CallResolver {
|
||||
return result;
|
||||
}
|
||||
|
||||
Collection<ResolvedCallImpl<FunctionDescriptor>> functionDescriptors = ResolvedCallImpl.convertCollection(receiver.getType().getMemberScope().getFunctions(name));
|
||||
Collection<ResolutionCandidate<FunctionDescriptor>> functionDescriptors = ResolutionCandidate.convertCollection(receiver.getType().getMemberScope().getFunctions(name));
|
||||
if (lookupExactSignature(functionDescriptors, parameterTypes, result)) {
|
||||
return result;
|
||||
|
||||
@@ -878,16 +896,16 @@ public class CallResolver {
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
lookupExactSignature(ResolvedCallImpl.convertCollection(scope.getFunctions(name)), parameterTypes, result);
|
||||
lookupExactSignature(ResolutionCandidate.convertCollection(scope.getFunctions(name)), parameterTypes, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean lookupExactSignature(Collection<ResolvedCallImpl<FunctionDescriptor>> candidates, List<JetType> parameterTypes,
|
||||
List<ResolvedCallImpl<FunctionDescriptor>> result) {
|
||||
private static boolean lookupExactSignature(Collection<ResolutionCandidate<FunctionDescriptor>> candidates, List<JetType> parameterTypes,
|
||||
List<ResolutionCandidate<FunctionDescriptor>> result) {
|
||||
boolean found = false;
|
||||
for (ResolvedCallImpl<FunctionDescriptor> resolvedCall : candidates) {
|
||||
FunctionDescriptor functionDescriptor = resolvedCall.getResultingDescriptor();
|
||||
for (ResolutionCandidate<FunctionDescriptor> resolvedCall : candidates) {
|
||||
FunctionDescriptor functionDescriptor = resolvedCall.getDescriptor();
|
||||
if (functionDescriptor.getReceiverParameter().exists()) continue;
|
||||
if (!functionDescriptor.getTypeParameters().isEmpty()) continue;
|
||||
if (!checkValueParameters(functionDescriptor, parameterTypes)) continue;
|
||||
@@ -897,17 +915,17 @@ public class CallResolver {
|
||||
return found;
|
||||
}
|
||||
|
||||
private boolean findExtensionFunctions(Collection<ResolvedCallImpl<FunctionDescriptor>> candidates, ReceiverDescriptor receiver,
|
||||
List<JetType> parameterTypes, List<ResolvedCallImpl<FunctionDescriptor>> result) {
|
||||
private boolean findExtensionFunctions(Collection<ResolutionCandidate<FunctionDescriptor>> candidates, ReceiverDescriptor receiver,
|
||||
List<JetType> parameterTypes, List<ResolutionCandidate<FunctionDescriptor>> result) {
|
||||
boolean found = false;
|
||||
for (ResolvedCallImpl<FunctionDescriptor> resolvedCall : candidates) {
|
||||
FunctionDescriptor functionDescriptor = resolvedCall.getResultingDescriptor();
|
||||
for (ResolutionCandidate<FunctionDescriptor> candidate : candidates) {
|
||||
FunctionDescriptor functionDescriptor = candidate.getDescriptor();
|
||||
ReceiverDescriptor functionReceiver = functionDescriptor.getReceiverParameter();
|
||||
if (!functionReceiver.exists()) continue;
|
||||
if (!functionDescriptor.getTypeParameters().isEmpty()) continue;
|
||||
if (!typeChecker.isSubtypeOf(receiver.getType(), functionReceiver.getType())) continue;
|
||||
if (!checkValueParameters(functionDescriptor, parameterTypes))continue;
|
||||
result.add(resolvedCall);
|
||||
result.add(candidate);
|
||||
found = true;
|
||||
}
|
||||
return found;
|
||||
@@ -923,15 +941,4 @@ public class CallResolver {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static final class CallResolutionContext<D extends CallableDescriptor> extends ResolutionContext {
|
||||
/*package*/ final ResolvedCallImpl<D> candidateCall;
|
||||
/*package*/ final TracingStrategy tracing;
|
||||
|
||||
public CallResolutionContext(ResolvedCallImpl<D> candidateCall, ResolutionTask<D> task, BindingTrace trace, TracingStrategy tracing) {
|
||||
super(trace, task.scope, task.call, task.expectedType, task.dataFlowInfo);
|
||||
this.candidateCall = candidateCall;
|
||||
this.tracing = tracing;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public interface CallTransformationStrategy<D extends CallableDescriptor, R extends D> {
|
||||
|
||||
@NotNull
|
||||
CallResolutionContext<D> createCallContext(@NotNull ResolutionCandidate<D> candidate,
|
||||
@NotNull ResolutionTask<D> task,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull TracingStrategy tracing);
|
||||
|
||||
@NotNull
|
||||
Collection<ResolvedCallImpl<R>> transformResultCall(@NotNull CallResolutionContext<D> callResolutionContext,
|
||||
@NotNull CallResolver callResolver,
|
||||
@NotNull ResolutionTask<D> task);
|
||||
|
||||
CallTransformationStrategy<VariableDescriptor, VariableDescriptor>
|
||||
PROPERTY_CALL_TRANSFORMATION_STRATEGY = new CallTransformationStrategy<VariableDescriptor, VariableDescriptor>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public CallResolutionContext<VariableDescriptor> createCallContext(@NotNull ResolutionCandidate<VariableDescriptor> candidate,
|
||||
@NotNull ResolutionTask<VariableDescriptor> task, @NotNull BindingTrace trace, @NotNull TracingStrategy tracing) {
|
||||
ResolvedCallImpl<VariableDescriptor> candidateCall = ResolvedCallImpl.create(candidate);
|
||||
return new CallResolutionContext<VariableDescriptor>(candidateCall, task, trace, tracing);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<ResolvedCallImpl<VariableDescriptor>> transformResultCall(@NotNull CallResolutionContext<VariableDescriptor> context,
|
||||
@NotNull CallResolver callResolver, @NotNull ResolutionTask<VariableDescriptor> task) {
|
||||
return Collections.singleton(context.candidateCall);
|
||||
}
|
||||
};
|
||||
|
||||
CallTransformationStrategy<FunctionDescriptor, FunctionDescriptor>
|
||||
FUNCTION_CALL_TRANSFORMATION_STRATEGY = new CallTransformationStrategy<FunctionDescriptor, FunctionDescriptor>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public CallResolutionContext<FunctionDescriptor> createCallContext(@NotNull ResolutionCandidate<FunctionDescriptor> candidate,
|
||||
@NotNull ResolutionTask<FunctionDescriptor> task,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull TracingStrategy tracing) {
|
||||
if (candidate.getDescriptor() instanceof FunctionDescriptor) {
|
||||
return new CallResolutionContext<FunctionDescriptor>(ResolvedCallImpl.create(candidate), task, trace, tracing);
|
||||
}
|
||||
assert candidate.getDescriptor() instanceof VariableDescriptor;
|
||||
Call propertyCall = new DelegatingCall(task.call) {
|
||||
@Override
|
||||
public JetValueArgumentList getValueArgumentList() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetExpression> getFunctionLiteralArguments() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetTypeProjection> getTypeArguments() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetTypeArgumentList getTypeArgumentList() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
return new CallResolutionContext<FunctionDescriptor>(ResolvedCallImpl.create(candidate), task, trace, tracing, propertyCall);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<ResolvedCallImpl<FunctionDescriptor>> transformResultCall(@NotNull CallResolutionContext<FunctionDescriptor> context,
|
||||
@NotNull CallResolver callResolver, @NotNull ResolutionTask<FunctionDescriptor> task) {
|
||||
FunctionDescriptor descriptor = context.candidateCall.getCandidateDescriptor();
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
return Collections.singleton(context.candidateCall);
|
||||
}
|
||||
assert descriptor instanceof VariableDescriptor;
|
||||
BasicResolutionContext basicResolutionContext =
|
||||
BasicResolutionContext.create(context.trace, context.scope, task.call, context.expectedType, context.dataFlowInfo);
|
||||
OverloadResolutionResults<FunctionDescriptor> results =
|
||||
callResolver.resolveCallWithGivenName(basicResolutionContext, task.reference, "invoke");
|
||||
return ((OverloadResolutionResultsImpl<FunctionDescriptor>)results).getResultingCalls();
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public interface MemberPrioritizer<D extends CallableDescriptor> {
|
||||
@NotNull
|
||||
Collection<D> getNonExtensionsByName(JetScope scope, String name);
|
||||
|
||||
@NotNull
|
||||
Collection<D> getMembersByName(@NotNull JetType receiver, String name);
|
||||
|
||||
@NotNull
|
||||
Collection<D> getExtensionsByName(JetScope scope, String name);
|
||||
}
|
||||
+14
-13
@@ -34,14 +34,15 @@ import java.util.*;
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class TaskPrioritizers {
|
||||
public class MemberPrioritizers {
|
||||
|
||||
|
||||
/*package*/ static TaskPrioritizer<FunctionDescriptor> FUNCTION_TASK_PRIORITIZER = new TaskPrioritizer<FunctionDescriptor>() {
|
||||
/*package*/ static MemberPrioritizer<FunctionDescriptor> FUNCTION_TASK_PRIORITIZER = new MemberPrioritizer<FunctionDescriptor>() {
|
||||
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Collection<FunctionDescriptor> getNonExtensionsByName(JetScope scope, String name) {
|
||||
public Collection<FunctionDescriptor> getNonExtensionsByName(JetScope scope, String name) {
|
||||
Set<FunctionDescriptor> functions = Sets.newLinkedHashSet(scope.getFunctions(name));
|
||||
for (Iterator<FunctionDescriptor> iterator = functions.iterator(); iterator.hasNext(); ) {
|
||||
FunctionDescriptor functionDescriptor = iterator.next();
|
||||
@@ -57,7 +58,7 @@ public class TaskPrioritizers {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Collection<FunctionDescriptor> getMembersByName(@NotNull JetType receiverType, String name) {
|
||||
public Collection<FunctionDescriptor> getMembersByName(@NotNull JetType receiverType, String name) {
|
||||
JetScope receiverScope = receiverType.getMemberScope();
|
||||
Set<FunctionDescriptor> members = Sets.newHashSet(receiverScope.getFunctions(name));
|
||||
addConstructors(receiverScope, name, members);
|
||||
@@ -67,7 +68,7 @@ public class TaskPrioritizers {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Collection<FunctionDescriptor> getExtensionsByName(JetScope scope, String name) {
|
||||
public Collection<FunctionDescriptor> getExtensionsByName(JetScope scope, String name) {
|
||||
Set<FunctionDescriptor> extensionFunctions = Sets.newHashSet(scope.getFunctions(name));
|
||||
for (Iterator<FunctionDescriptor> iterator = extensionFunctions.iterator(); iterator.hasNext(); ) {
|
||||
FunctionDescriptor descriptor = iterator.next();
|
||||
@@ -104,11 +105,11 @@ public class TaskPrioritizers {
|
||||
}
|
||||
};
|
||||
|
||||
/*package*/ static TaskPrioritizer<VariableDescriptor> VARIABLE_TASK_PRIORITIZER = new TaskPrioritizer<VariableDescriptor>() {
|
||||
/*package*/ static MemberPrioritizer<VariableDescriptor> VARIABLE_TASK_PRIORITIZER = new MemberPrioritizer<VariableDescriptor>() {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Collection<VariableDescriptor> getNonExtensionsByName(JetScope scope, String name) {
|
||||
public Collection<VariableDescriptor> getNonExtensionsByName(JetScope scope, String name) {
|
||||
VariableDescriptor descriptor = scope.getLocalVariable(name);
|
||||
if (descriptor == null) {
|
||||
descriptor = DescriptorUtils.filterNonExtensionProperty(scope.getProperties(name));
|
||||
@@ -119,13 +120,13 @@ public class TaskPrioritizers {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Collection<VariableDescriptor> getMembersByName(@NotNull JetType receiverType, String name) {
|
||||
public Collection<VariableDescriptor> getMembersByName(@NotNull JetType receiverType, String name) {
|
||||
return receiverType.getMemberScope().getProperties(name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Collection<VariableDescriptor> getExtensionsByName(JetScope scope, String name) {
|
||||
public Collection<VariableDescriptor> getExtensionsByName(JetScope scope, String name) {
|
||||
return Collections2.filter(scope.getProperties(name), new Predicate<VariableDescriptor>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable VariableDescriptor variableDescriptor) {
|
||||
@@ -135,7 +136,7 @@ public class TaskPrioritizers {
|
||||
}
|
||||
};
|
||||
|
||||
/*package*/ static TaskPrioritizer<VariableDescriptor> PROPERTY_TASK_PRIORITIZER = new TaskPrioritizer<VariableDescriptor>() {
|
||||
/*package*/ static MemberPrioritizer<VariableDescriptor> PROPERTY_TASK_PRIORITIZER = new MemberPrioritizer<VariableDescriptor>() {
|
||||
private Collection<VariableDescriptor> filterProperties(Collection<? extends VariableDescriptor> variableDescriptors) {
|
||||
ArrayList<VariableDescriptor> properties = Lists.newArrayList();
|
||||
for (VariableDescriptor descriptor : variableDescriptors) {
|
||||
@@ -148,19 +149,19 @@ public class TaskPrioritizers {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Collection<VariableDescriptor> getNonExtensionsByName(JetScope scope, String name) {
|
||||
public Collection<VariableDescriptor> getNonExtensionsByName(JetScope scope, String name) {
|
||||
return filterProperties(VARIABLE_TASK_PRIORITIZER.getNonExtensionsByName(scope, name));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Collection<VariableDescriptor> getMembersByName(@NotNull JetType receiver, String name) {
|
||||
public Collection<VariableDescriptor> getMembersByName(@NotNull JetType receiver, String name) {
|
||||
return filterProperties(VARIABLE_TASK_PRIORITIZER.getMembersByName(receiver, name));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Collection<VariableDescriptor> getExtensionsByName(JetScope scope, String name) {
|
||||
public Collection<VariableDescriptor> getExtensionsByName(JetScope scope, String name) {
|
||||
return filterProperties(VARIABLE_TASK_PRIORITIZER.getExtensionsByName(scope, name));
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class ResolutionCandidate<D extends CallableDescriptor> {
|
||||
private final D candidateDescriptor;
|
||||
private ReceiverDescriptor thisObject = NO_RECEIVER; // receiver object of a method
|
||||
private ReceiverDescriptor receiverArgument = NO_RECEIVER; // receiver of an extension function
|
||||
|
||||
private ResolutionCandidate(@NotNull D descriptor) {
|
||||
candidateDescriptor = descriptor;
|
||||
}
|
||||
|
||||
public static <D extends CallableDescriptor> ResolutionCandidate<D> create(@NotNull D descriptor) {
|
||||
return new ResolutionCandidate<D>(descriptor);
|
||||
}
|
||||
|
||||
public void setThisObject(@NotNull ReceiverDescriptor thisObject) {
|
||||
this.thisObject = thisObject;
|
||||
}
|
||||
|
||||
public void setReceiverArgument(@NotNull ReceiverDescriptor receiverArgument) {
|
||||
this.receiverArgument = receiverArgument;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public D getDescriptor() {
|
||||
return candidateDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ReceiverDescriptor getThisObject() {
|
||||
return thisObject;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ReceiverDescriptor getReceiverArgument() {
|
||||
return receiverArgument;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <D extends CallableDescriptor> List<ResolutionCandidate<D>> convertCollection(@NotNull Collection<? extends D> descriptors) {
|
||||
List<ResolutionCandidate<D>> result = Lists.newArrayList();
|
||||
for (D descriptor : descriptors) {
|
||||
result.add(create(descriptor));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -39,10 +41,7 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.DANGLING_FUNCTION_LITERAL_ARGUMENT_SUSPECTED;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.AMBIGUOUS_REFERENCE_TARGET;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.RESOLVED_CALL;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
||||
|
||||
/**
|
||||
* Stores candidates for call resolution.
|
||||
@@ -50,26 +49,32 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.RESOLVED_CALL;
|
||||
* @author abreslav
|
||||
*/
|
||||
public class ResolutionTask<D extends CallableDescriptor> extends ResolutionContext {
|
||||
private final Collection<ResolvedCallImpl<D>> candidates;
|
||||
private final Collection<ResolutionCandidate<D>> candidates;
|
||||
private final Multimap<ResolutionCandidate<D>, ResolvedCallImpl<D>> resolvedCallMap = HashMultimap.create();
|
||||
/*package*/ final JetReferenceExpression reference;
|
||||
private DescriptorCheckStrategy checkingStrategy;
|
||||
|
||||
public ResolutionTask(@NotNull Collection<ResolvedCallImpl<D>> candidates, @NotNull JetReferenceExpression reference,
|
||||
public ResolutionTask(@NotNull Collection<ResolutionCandidate<D>> candidates, @NotNull JetReferenceExpression reference,
|
||||
BindingTrace trace, JetScope scope, Call call, JetType expectedType, DataFlowInfo dataFlowInfo) {
|
||||
super(trace, scope, call, expectedType, dataFlowInfo);
|
||||
this.candidates = candidates;
|
||||
this.reference = reference;
|
||||
}
|
||||
|
||||
public ResolutionTask(@NotNull Collection<ResolvedCallImpl<D>> candidates, @NotNull JetReferenceExpression reference, @NotNull BasicResolutionContext context) {
|
||||
public ResolutionTask(@NotNull Collection<ResolutionCandidate<D>> candidates, @NotNull JetReferenceExpression reference, @NotNull BasicResolutionContext context) {
|
||||
this(candidates, reference, context.trace, context.scope, context.call, context.expectedType, context.dataFlowInfo);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<ResolvedCallImpl<D>> getCandidates() {
|
||||
public Collection<ResolutionCandidate<D>> getCandidates() {
|
||||
return candidates;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Multimap<ResolutionCandidate<D>, ResolvedCallImpl<D>> getResolvedCallMap() {
|
||||
return resolvedCallMap;
|
||||
}
|
||||
|
||||
public void setCheckingStrategy(DescriptorCheckStrategy strategy) {
|
||||
checkingStrategy = strategy;
|
||||
}
|
||||
|
||||
+12
-12
@@ -34,35 +34,35 @@ import java.util.List;
|
||||
public class ResolutionTaskHolder<D extends CallableDescriptor> {
|
||||
private final JetReferenceExpression reference;
|
||||
private final BasicResolutionContext basicResolutionContext;
|
||||
private final Predicate<ResolvedCallImpl<D>> visibleStrategy;
|
||||
private final Predicate<ResolutionCandidate<D>> visibleStrategy;
|
||||
|
||||
private final Collection<Collection<ResolvedCallImpl<D>>> localExtensions = Sets.newLinkedHashSet();
|
||||
private final Collection<Collection<ResolvedCallImpl<D>>> members = Sets.newLinkedHashSet();
|
||||
private final Collection<Collection<ResolvedCallImpl<D>>> nonLocalExtensions = Sets.newLinkedHashSet();
|
||||
private final Collection<Collection<ResolutionCandidate<D>>> localExtensions = Sets.newLinkedHashSet();
|
||||
private final Collection<Collection<ResolutionCandidate<D>>> members = Sets.newLinkedHashSet();
|
||||
private final Collection<Collection<ResolutionCandidate<D>>> nonLocalExtensions = Sets.newLinkedHashSet();
|
||||
|
||||
private List<ResolutionTask<D>> tasks = null;
|
||||
|
||||
public ResolutionTaskHolder(@NotNull JetReferenceExpression reference,
|
||||
@NotNull BasicResolutionContext basicResolutionContext,
|
||||
@NotNull Predicate<ResolvedCallImpl<D>> visibleStrategy) {
|
||||
@NotNull Predicate<ResolutionCandidate<D>> visibleStrategy) {
|
||||
this.reference = reference;
|
||||
this.basicResolutionContext = basicResolutionContext;
|
||||
this.visibleStrategy = visibleStrategy;
|
||||
}
|
||||
|
||||
public void addLocalExtensions(@NotNull Collection<ResolvedCallImpl<D>> candidates) {
|
||||
public void addLocalExtensions(@NotNull Collection<ResolutionCandidate<D>> candidates) {
|
||||
if (!candidates.isEmpty()) {
|
||||
localExtensions.add(candidates);
|
||||
}
|
||||
}
|
||||
|
||||
public void addMembers(@NotNull Collection<ResolvedCallImpl<D>> candidates) {
|
||||
public void addMembers(@NotNull Collection<ResolutionCandidate<D>> candidates) {
|
||||
if (!candidates.isEmpty()) {
|
||||
members.add(candidates);
|
||||
}
|
||||
}
|
||||
|
||||
public void addNonLocalExtensions(@NotNull Collection<ResolvedCallImpl<D>> candidates) {
|
||||
public void addNonLocalExtensions(@NotNull Collection<ResolutionCandidate<D>> candidates) {
|
||||
if (!candidates.isEmpty()) {
|
||||
nonLocalExtensions.add(candidates);
|
||||
}
|
||||
@@ -71,7 +71,7 @@ public class ResolutionTaskHolder<D extends CallableDescriptor> {
|
||||
public List<ResolutionTask<D>> getTasks() {
|
||||
if (tasks == null) {
|
||||
tasks = Lists.newArrayList();
|
||||
List<Collection<ResolvedCallImpl<D>>> candidateList = Lists.newArrayList();
|
||||
List<Collection<ResolutionCandidate<D>>> candidateList = Lists.newArrayList();
|
||||
// If the call is of the form super.foo(), it can actually be only a member
|
||||
// But if there's no appropriate member, we would like to report that super cannot be a receiver for an extension
|
||||
// Thus, put members first
|
||||
@@ -85,9 +85,9 @@ public class ResolutionTaskHolder<D extends CallableDescriptor> {
|
||||
}
|
||||
candidateList.addAll(nonLocalExtensions);
|
||||
|
||||
for (Predicate<ResolvedCallImpl<D>> visibilityStrategy : Lists.newArrayList(visibleStrategy, Predicates.not(visibleStrategy))) {
|
||||
for (Collection<ResolvedCallImpl<D>> candidates : candidateList) {
|
||||
Collection<ResolvedCallImpl<D>> filteredCandidates = Collections2.filter(candidates, visibilityStrategy);
|
||||
for (Predicate<ResolutionCandidate<D>> visibilityStrategy : Lists.newArrayList(visibleStrategy, Predicates.not(visibleStrategy))) {
|
||||
for (Collection<ResolutionCandidate<D>> candidates : candidateList) {
|
||||
Collection<ResolutionCandidate<D>> filteredCandidates = Collections2.filter(candidates, visibilityStrategy);
|
||||
if (!filteredCandidates.isEmpty()) {
|
||||
tasks.add(new ResolutionTask<D>(filteredCandidates, reference, basicResolutionContext));
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.calls.ResolutionStatus.UNKNOWN_STATUS;
|
||||
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
@@ -55,23 +54,14 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements ResolvedC
|
||||
};
|
||||
|
||||
@NotNull
|
||||
public static <D extends CallableDescriptor> ResolvedCallImpl<D> create(@NotNull D descriptor) {
|
||||
return new ResolvedCallImpl<D>(descriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <D extends CallableDescriptor> List<ResolvedCallImpl<D>> convertCollection(@NotNull Collection<? extends D> descriptors) {
|
||||
List<ResolvedCallImpl<D>> result = Lists.newArrayList();
|
||||
for (D descriptor : descriptors) {
|
||||
result.add(create(descriptor));
|
||||
}
|
||||
return result;
|
||||
public static <D extends CallableDescriptor> ResolvedCallImpl<D> create(@NotNull ResolutionCandidate<D> candidate) {
|
||||
return new ResolvedCallImpl<D>(candidate.getDescriptor(), candidate.getThisObject(), candidate.getReceiverArgument());
|
||||
}
|
||||
|
||||
private final D candidateDescriptor;
|
||||
private D resultingDescriptor; // Probably substituted
|
||||
private ReceiverDescriptor thisObject = NO_RECEIVER; // receiver object of a method
|
||||
private ReceiverDescriptor receiverArgument = NO_RECEIVER; // receiver of an extension function
|
||||
private final ReceiverDescriptor thisObject; // receiver object of a method
|
||||
private final ReceiverDescriptor receiverArgument; // receiver of an extension function
|
||||
|
||||
private final Map<TypeParameterDescriptor, JetType> typeArguments = Maps.newLinkedHashMap();
|
||||
private final Map<ValueParameterDescriptor, JetType> autoCasts = Maps.newHashMap();
|
||||
@@ -80,8 +70,10 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements ResolvedC
|
||||
private TemporaryBindingTrace trace;
|
||||
private ResolutionStatus status = UNKNOWN_STATUS;
|
||||
|
||||
private ResolvedCallImpl(@NotNull D candidateDescriptor) {
|
||||
private ResolvedCallImpl(@NotNull D candidateDescriptor, @NotNull ReceiverDescriptor thisObject, @NotNull ReceiverDescriptor receiverArgument) {
|
||||
this.candidateDescriptor = candidateDescriptor;
|
||||
this.thisObject = thisObject;
|
||||
this.receiverArgument = receiverArgument;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -140,20 +132,12 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements ResolvedC
|
||||
return receiverArgument;
|
||||
}
|
||||
|
||||
public void setReceiverArgument(@NotNull ReceiverDescriptor receiverParameter) {
|
||||
this.receiverArgument = receiverParameter;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public ReceiverDescriptor getThisObject() {
|
||||
return thisObject;
|
||||
}
|
||||
|
||||
public void setThisObject(@NotNull ReceiverDescriptor thisObject) {
|
||||
this.thisObject = thisObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Map<ValueParameterDescriptor, ResolvedValueArgument> getValueArguments() {
|
||||
|
||||
@@ -31,7 +31,6 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.NamespaceType;
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||
|
||||
@@ -44,16 +43,16 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
/*package*/ abstract class TaskPrioritizer<D extends CallableDescriptor> {
|
||||
/*package*/ abstract class TaskPrioritizer {
|
||||
|
||||
public static <D extends CallableDescriptor> void splitLexicallyLocalDescriptors(
|
||||
@NotNull Collection<ResolvedCallImpl<D>> allDescriptors,
|
||||
@NotNull Collection<ResolutionCandidate<D>> allDescriptors,
|
||||
@NotNull DeclarationDescriptor containerOfTheCurrentLocality,
|
||||
@NotNull Collection<ResolvedCallImpl<D>> local,
|
||||
@NotNull Collection<ResolvedCallImpl<D>> nonlocal
|
||||
@NotNull Collection<ResolutionCandidate<D>> local,
|
||||
@NotNull Collection<ResolutionCandidate<D>> nonlocal
|
||||
) {
|
||||
for (ResolvedCallImpl<D> resolvedCall : allDescriptors) {
|
||||
if (DescriptorUtils.isLocal(containerOfTheCurrentLocality, resolvedCall.getCandidateDescriptor())) {
|
||||
for (ResolutionCandidate<D> resolvedCall : allDescriptors) {
|
||||
if (DescriptorUtils.isLocal(containerOfTheCurrentLocality, resolvedCall.getDescriptor())) {
|
||||
local.add(resolvedCall);
|
||||
}
|
||||
else {
|
||||
@@ -75,8 +74,8 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<ResolutionTask<D>> computePrioritizedTasks(@NotNull BasicResolutionContext context, @NotNull String name,
|
||||
@NotNull JetReferenceExpression functionReference) {
|
||||
public static <D extends CallableDescriptor> List<ResolutionTask<D>> computePrioritizedTasks(@NotNull BasicResolutionContext context, @NotNull String name,
|
||||
@NotNull JetReferenceExpression functionReference, @NotNull List<MemberPrioritizer<D>> memberPrioritizers) {
|
||||
ReceiverDescriptor explicitReceiver = context.call.getExplicitReceiver();
|
||||
final JetScope scope;
|
||||
if (explicitReceiver.exists() && explicitReceiver.getType() instanceof NamespaceType) {
|
||||
@@ -87,40 +86,41 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
||||
else {
|
||||
scope = context.scope;
|
||||
}
|
||||
final Predicate<ResolvedCallImpl<D>> visibleStrategy = new Predicate<ResolvedCallImpl<D>>() {
|
||||
final Predicate<ResolutionCandidate<D>> visibleStrategy = new Predicate<ResolutionCandidate<D>>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable ResolvedCallImpl<D> call) {
|
||||
public boolean apply(@Nullable ResolutionCandidate<D> call) {
|
||||
if (call == null) return false;
|
||||
D candidateDescriptor = call.getCandidateDescriptor();
|
||||
D candidateDescriptor = call.getDescriptor();
|
||||
if (ErrorUtils.isError(candidateDescriptor)) return true;
|
||||
return Visibilities.isVisible(candidateDescriptor, scope.getContainingDeclaration());
|
||||
}
|
||||
};
|
||||
|
||||
ResolutionTaskHolder<D> result = new ResolutionTaskHolder<D>(functionReference, context, visibleStrategy );
|
||||
doComputeTasks(scope, explicitReceiver, name, result, context);
|
||||
doComputeTasks(scope, explicitReceiver, name, result, context, memberPrioritizers);
|
||||
|
||||
return result.getTasks();
|
||||
}
|
||||
|
||||
private void doComputeTasks(@NotNull JetScope scope, @NotNull ReceiverDescriptor receiver,
|
||||
private static <D extends CallableDescriptor> void doComputeTasks(@NotNull JetScope scope, @NotNull ReceiverDescriptor receiver,
|
||||
@NotNull String name, @NotNull ResolutionTaskHolder<D> result,
|
||||
@NotNull BasicResolutionContext context) {
|
||||
@NotNull BasicResolutionContext context, @NotNull List<MemberPrioritizer<D>> memberPrioritizers) {
|
||||
MemberPrioritizer<D> memberPrioritizer = memberPrioritizers.get(0);
|
||||
AutoCastServiceImpl autoCastService = new AutoCastServiceImpl(context.dataFlowInfo, context.trace.getBindingContext());
|
||||
List<ReceiverDescriptor> implicitReceivers = Lists.newArrayList();
|
||||
scope.getImplicitReceiversHierarchy(implicitReceivers);
|
||||
if (receiver.exists()) {
|
||||
List<ReceiverDescriptor> variantsForExplicitReceiver = autoCastService.getVariantsForReceiver(receiver);
|
||||
|
||||
Collection<ResolvedCallImpl<D>> extensionFunctions = convertWithImpliedThis(scope, variantsForExplicitReceiver, getExtensionsByName(scope, name));
|
||||
List<ResolvedCallImpl<D>> nonlocals = Lists.newArrayList();
|
||||
List<ResolvedCallImpl<D>> locals = Lists.newArrayList();
|
||||
Collection<ResolutionCandidate<D>> extensionFunctions = convertWithImpliedThis(scope, variantsForExplicitReceiver, memberPrioritizer.getExtensionsByName(scope, name));
|
||||
List<ResolutionCandidate<D>> nonlocals = Lists.newArrayList();
|
||||
List<ResolutionCandidate<D>> locals = Lists.newArrayList();
|
||||
//noinspection unchecked,RedundantTypeArguments
|
||||
TaskPrioritizer.<D>splitLexicallyLocalDescriptors(extensionFunctions, scope.getContainingDeclaration(), locals, nonlocals);
|
||||
|
||||
Collection<ResolvedCallImpl<D>> members = Lists.newArrayList();
|
||||
Collection<ResolutionCandidate<D>> members = Lists.newArrayList();
|
||||
for (ReceiverDescriptor variant : variantsForExplicitReceiver) {
|
||||
Collection<D> membersForThisVariant = getMembersByName(variant.getType(), name);
|
||||
Collection<D> membersForThisVariant = memberPrioritizer.getMembersByName(variant.getType(), name);
|
||||
convertWithReceivers(membersForThisVariant, Collections.singletonList(variant), Collections.singletonList(NO_RECEIVER), members);
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
||||
result.addMembers(members);
|
||||
|
||||
for (ReceiverDescriptor implicitReceiver : implicitReceivers) {
|
||||
Collection<D> memberExtensions = getExtensionsByName(implicitReceiver.getType().getMemberScope(), name);
|
||||
Collection<D> memberExtensions = memberPrioritizer.getExtensionsByName(implicitReceiver.getType().getMemberScope(), name);
|
||||
List<ReceiverDescriptor> variantsForImplicitReceiver = autoCastService.getVariantsForReceiver(implicitReceiver);
|
||||
result.addNonLocalExtensions(convertWithReceivers(memberExtensions, variantsForImplicitReceiver, variantsForExplicitReceiver));
|
||||
}
|
||||
@@ -136,10 +136,10 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
||||
result.addNonLocalExtensions(nonlocals);
|
||||
}
|
||||
else {
|
||||
Collection<ResolvedCallImpl<D>> functions = convertWithImpliedThis(scope, Collections.singletonList(receiver), getNonExtensionsByName(scope, name));
|
||||
Collection<ResolutionCandidate<D>> functions = convertWithImpliedThis(scope, Collections.singletonList(receiver), memberPrioritizer.getNonExtensionsByName(scope, name));
|
||||
|
||||
List<ResolvedCallImpl<D>> nonlocals = Lists.newArrayList();
|
||||
List<ResolvedCallImpl<D>> locals = Lists.newArrayList();
|
||||
List<ResolutionCandidate<D>> nonlocals = Lists.newArrayList();
|
||||
List<ResolutionCandidate<D>> locals = Lists.newArrayList();
|
||||
//noinspection unchecked,RedundantTypeArguments
|
||||
TaskPrioritizer.<D>splitLexicallyLocalDescriptors(functions, scope.getContainingDeclaration(), locals, nonlocals);
|
||||
|
||||
@@ -147,22 +147,22 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
||||
result.addNonLocalExtensions(nonlocals);
|
||||
|
||||
for (ReceiverDescriptor implicitReceiver : implicitReceivers) {
|
||||
doComputeTasks(scope, implicitReceiver, name, result, context);
|
||||
doComputeTasks(scope, implicitReceiver, name, result, context, memberPrioritizers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<ResolvedCallImpl<D>> convertWithReceivers(Collection<D> descriptors, Iterable<ReceiverDescriptor> thisObjects, Iterable<ReceiverDescriptor> receiverParameters) {
|
||||
Collection<ResolvedCallImpl<D>> result = Lists.newArrayList();
|
||||
private static <D extends CallableDescriptor> Collection<ResolutionCandidate<D>> convertWithReceivers(Collection<D> descriptors, Iterable<ReceiverDescriptor> thisObjects, Iterable<ReceiverDescriptor> receiverParameters) {
|
||||
Collection<ResolutionCandidate<D>> result = Lists.newArrayList();
|
||||
convertWithReceivers(descriptors, thisObjects, receiverParameters, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void convertWithReceivers(Collection<D> descriptors, Iterable<ReceiverDescriptor> thisObjects, Iterable<ReceiverDescriptor> receiverParameters, Collection<ResolvedCallImpl<D>> result) {
|
||||
private static <D extends CallableDescriptor> void convertWithReceivers(Collection<D> descriptors, Iterable<ReceiverDescriptor> thisObjects, Iterable<ReceiverDescriptor> receiverParameters, Collection<ResolutionCandidate<D>> result) {
|
||||
for (ReceiverDescriptor thisObject : thisObjects) {
|
||||
for (ReceiverDescriptor receiverParameter : receiverParameters) {
|
||||
for (D extension : descriptors) {
|
||||
ResolvedCallImpl<D> resolvedCall = ResolvedCallImpl.create(extension);
|
||||
ResolutionCandidate<D> resolvedCall = ResolutionCandidate.create(extension);
|
||||
resolvedCall.setThisObject(thisObject);
|
||||
resolvedCall.setReceiverArgument(receiverParameter);
|
||||
result.add(resolvedCall);
|
||||
@@ -171,11 +171,11 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
||||
}
|
||||
}
|
||||
|
||||
public static <D extends CallableDescriptor> Collection<ResolvedCallImpl<D>> convertWithImpliedThis(JetScope scope, Iterable<ReceiverDescriptor> receiverParameters, Collection<? extends D> descriptors) {
|
||||
Collection<ResolvedCallImpl<D>> result = Lists.newArrayList();
|
||||
public static <D extends CallableDescriptor> Collection<ResolutionCandidate<D>> convertWithImpliedThis(JetScope scope, Iterable<ReceiverDescriptor> receiverParameters, Collection<? extends D> descriptors) {
|
||||
Collection<ResolutionCandidate<D>> result = Lists.newArrayList();
|
||||
for (ReceiverDescriptor receiverParameter : receiverParameters) {
|
||||
for (D descriptor : descriptors) {
|
||||
ResolvedCallImpl<D> resolvedCall = ResolvedCallImpl.create(descriptor);
|
||||
ResolutionCandidate<D> resolvedCall = ResolutionCandidate.create(descriptor);
|
||||
resolvedCall.setReceiverArgument(receiverParameter);
|
||||
if (setImpliedThis(scope, resolvedCall)) {
|
||||
result.add(resolvedCall);
|
||||
@@ -190,7 +190,7 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
||||
containingDeclaration = containingDeclaration.getContainingDeclaration();
|
||||
}
|
||||
if (containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.OBJECT) {
|
||||
ResolvedCallImpl<D> resolvedCall = ResolvedCallImpl.create(descriptor);
|
||||
ResolutionCandidate<D> resolvedCall = ResolutionCandidate.create(descriptor);
|
||||
resolvedCall.setThisObject(new ClassReceiver((ClassDescriptor) containingDeclaration));
|
||||
result.add(resolvedCall);
|
||||
}
|
||||
@@ -199,8 +199,8 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
||||
return result;
|
||||
}
|
||||
|
||||
private static <D extends CallableDescriptor> boolean setImpliedThis(@NotNull JetScope scope, ResolvedCallImpl<D> resolvedCall) {
|
||||
ReceiverDescriptor expectedThisObject = resolvedCall.getCandidateDescriptor().getExpectedThisObject();
|
||||
private static <D extends CallableDescriptor> boolean setImpliedThis(@NotNull JetScope scope, ResolutionCandidate<D> resolvedCall) {
|
||||
ReceiverDescriptor expectedThisObject = resolvedCall.getDescriptor().getExpectedThisObject();
|
||||
if (!expectedThisObject.exists()) return true;
|
||||
List<ReceiverDescriptor> receivers = Lists.newArrayList();
|
||||
scope.getImplicitReceiversHierarchy(receivers);
|
||||
@@ -213,13 +213,4 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected abstract Collection<D> getNonExtensionsByName(JetScope scope, String name);
|
||||
|
||||
@NotNull
|
||||
protected abstract Collection<D> getMembersByName(@NotNull JetType receiver, String name);
|
||||
|
||||
@NotNull
|
||||
protected abstract Collection<D> getExtensionsByName(JetScope scope, String name);
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ public class ResolveToolwindow extends JPanel implements Disposable {
|
||||
if (debugInfo != null) {
|
||||
List<? extends ResolutionTask<? extends CallableDescriptor>> resolutionTasks = debugInfo.get(TASKS);
|
||||
for (ResolutionTask<? extends CallableDescriptor> resolutionTask : resolutionTasks) {
|
||||
for (ResolvedCallImpl<? extends CallableDescriptor> resolvedCall : resolutionTask.getCandidates()) {
|
||||
for (ResolvedCallImpl<? extends CallableDescriptor> resolvedCall : resolutionTask.getResolvedCallMap().values()) {
|
||||
renderResolutionLogForCall(debugInfo, resolvedCall, result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.calls.ResolutionCandidate;
|
||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
@@ -103,7 +104,7 @@ public final class CallBuilder {
|
||||
private CallTranslator finish() {
|
||||
if (resolvedCall == null) {
|
||||
assert descriptor != null;
|
||||
resolvedCall = ResolvedCallImpl.create(descriptor);
|
||||
resolvedCall = ResolvedCallImpl.create(ResolutionCandidate.create(descriptor));
|
||||
}
|
||||
if (descriptor == null) {
|
||||
descriptor = resolvedCall.getCandidateDescriptor().getOriginal();
|
||||
|
||||
Reference in New Issue
Block a user