Convert TaskPrioritizer to kotlin.

This commit is contained in:
Stanislav Erokhin
2014-12-01 21:17:42 +03:00
parent f31ea8bd0e
commit 09250c89ed
3 changed files with 324 additions and 384 deletions
@@ -263,7 +263,7 @@ public class CallResolver {
return checkArgumentTypesAndFail(context);
}
Collection<ResolutionCandidate<CallableDescriptor>> candidates =
TaskPrioritizer.<CallableDescriptor>convertWithImpliedThisAndNoReceiver(
taskPrioritizer.<CallableDescriptor>convertWithImpliedThisAndNoReceiver(
context.scope, constructors, context.call);
prioritizedTasks = taskPrioritizer.<CallableDescriptor, FunctionDescriptor>computePrioritizedTasksFromCandidates(
context, candidates, TracingStrategyImpl.create(functionReference, context.call));
@@ -38,7 +38,6 @@ import org.jetbrains.jet.lang.resolve.calls.smartcasts.DataFlowValue;
import org.jetbrains.jet.lang.resolve.calls.smartcasts.DataFlowValueFactory;
import org.jetbrains.jet.lang.resolve.calls.smartcasts.SmartCastUtils;
import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionTask;
import org.jetbrains.jet.lang.resolve.calls.tasks.TaskPrioritizer;
import org.jetbrains.jet.lang.resolve.calls.util.FakeCallableDescriptorForObject;
import org.jetbrains.jet.lang.resolve.lazy.ForceResolveUtil;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
@@ -163,7 +162,7 @@ public class CandidateResolver {
// '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.getExtensionReceiver());
JetSuperExpression superExpression = getReceiverSuper(candidateCall.getExtensionReceiver());
if (superExpression != null) {
context.trace.report(SUPER_IS_NOT_AN_EXPRESSION.on(superExpression, superExpression.getText()));
candidateCall.addStatus(OTHER_ERROR);
@@ -205,6 +204,18 @@ public class CandidateResolver {
return DescriptorResolver.checkHasOuterClassInstance(context.scope, context.trace, context.call.getCallElement(), candidateThis);
}
@Nullable
private static JetSuperExpression getReceiverSuper(@NotNull ReceiverValue receiver) {
if (receiver instanceof ExpressionReceiver) {
ExpressionReceiver expressionReceiver = (ExpressionReceiver) receiver;
JetExpression expression = expressionReceiver.getExpression();
if (expression instanceof JetSuperExpression) {
return (JetSuperExpression) expression;
}
}
return null;
}
@Nullable
private static ClassDescriptor getDeclaringClass(@NotNull CallableDescriptor candidate) {
ReceiverParameterDescriptor expectedThis = candidate.getDispatchReceiverParameter();
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
* 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.
@@ -14,310 +14,270 @@
* limitations under the License.
*/
package org.jetbrains.jet.lang.resolve.calls.tasks;
package org.jetbrains.jet.lang.resolve.calls.tasks
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.intellij.openapi.progress.ProgressIndicatorProvider;
import kotlin.Function0;
import kotlin.Function1;
import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.Call;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetSuperExpression;
import org.jetbrains.jet.lang.resolve.calls.context.BasicCallResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.smartcasts.SmartCastUtils;
import org.jetbrains.jet.lang.resolve.calls.tasks.collectors.CallableDescriptorCollector;
import org.jetbrains.jet.lang.resolve.calls.tasks.collectors.CallableDescriptorCollectors;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.JetScopeUtils;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.QualifierReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypesPackage;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils;
import org.jetbrains.jet.storage.StorageManager;
import com.google.common.collect.Lists
import com.google.common.collect.Sets
import com.intellij.openapi.progress.ProgressIndicatorProvider
import kotlin.Function0
import kotlin.Function1
import org.jetbrains.jet.lang.descriptors.*
import org.jetbrains.jet.lang.psi.Call
import org.jetbrains.jet.lang.psi.JetExpression
import org.jetbrains.jet.lang.psi.JetSuperExpression
import org.jetbrains.jet.lang.resolve.calls.context.BasicCallResolutionContext
import org.jetbrains.jet.lang.resolve.calls.smartcasts.SmartCastUtils
import org.jetbrains.jet.lang.resolve.calls.tasks.collectors.CallableDescriptorCollector
import org.jetbrains.jet.lang.resolve.calls.tasks.collectors.CallableDescriptorCollectors
import org.jetbrains.jet.lang.resolve.name.Name
import org.jetbrains.jet.lang.resolve.scopes.JetScope
import org.jetbrains.jet.lang.resolve.scopes.JetScopeUtils
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.jet.lang.resolve.scopes.receivers.QualifierReceiver
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.jet.lang.types.ErrorUtils
import org.jetbrains.jet.lang.types.JetType
import org.jetbrains.jet.lang.types.*
import org.jetbrains.jet.lang.types.checker.JetTypeChecker
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils
import org.jetbrains.jet.storage.StorageManager
import org.jetbrains.jet.lang.resolve.calls.context.ResolutionContext
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.ArrayList
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.isOrOverridesSynthesized;
import static org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind.*;
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.isOrOverridesSynthesized
import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind.*
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER
public class TaskPrioritizer {
public class TaskPrioritizer(private val storageManager: StorageManager) {
@NotNull
private final StorageManager storageManager;
public TaskPrioritizer(@NotNull StorageManager manager) {
storageManager = manager;
}
public static <D extends CallableDescriptor> void splitLexicallyLocalDescriptors(
@NotNull Collection<ResolutionCandidate<D>> allDescriptors,
@NotNull DeclarationDescriptor containerOfTheCurrentLocality,
@NotNull Collection<ResolutionCandidate<D>> local,
@NotNull Collection<ResolutionCandidate<D>> nonlocal
public fun <D : CallableDescriptor> splitLexicallyLocalDescriptors(
allDescriptors: Collection<ResolutionCandidate<D>>,
containerOfTheCurrentLocality: DeclarationDescriptor,
local: MutableCollection<ResolutionCandidate<D>>,
nonlocal: MutableCollection<ResolutionCandidate<D>>
) {
for (ResolutionCandidate<D> resolvedCall : allDescriptors) {
for (resolvedCall in allDescriptors) {
if (ExpressionTypingUtils.isLocal(containerOfTheCurrentLocality, resolvedCall.getDescriptor())) {
local.add(resolvedCall);
local.add(resolvedCall)
}
else {
nonlocal.add(resolvedCall);
nonlocal.add(resolvedCall)
}
}
}
@Nullable
public static JetSuperExpression getReceiverSuper(@NotNull ReceiverValue receiver) {
if (receiver instanceof ExpressionReceiver) {
ExpressionReceiver expressionReceiver = (ExpressionReceiver) receiver;
JetExpression expression = expressionReceiver.getExpression();
if (expression instanceof JetSuperExpression) {
return (JetSuperExpression) expression;
}
}
return null;
}
public fun <D : CallableDescriptor, F : D> computePrioritizedTasks(
context: BasicCallResolutionContext,
name: Name,
tracing: TracingStrategy,
callableDescriptorCollectors: CallableDescriptorCollectors<D>
): List<ResolutionTask<D, F>> {
val explicitReceiver = context.call.getExplicitReceiver()
val result = ResolutionTaskHolder<D, F>(storageManager, context, MyPriorityProvider<D>(context), tracing)
val taskPrioritizerContext = TaskPrioritizerContext(name, result, context, context.scope, callableDescriptorCollectors)
@NotNull
public <D extends CallableDescriptor, F extends D> List<ResolutionTask<D, F>> computePrioritizedTasks(
@NotNull BasicCallResolutionContext context,
@NotNull Name name,
@NotNull TracingStrategy tracing,
@NotNull CallableDescriptorCollectors<D> callableDescriptorCollectors
) {
ReceiverValue explicitReceiver = context.call.getExplicitReceiver();
ResolutionTaskHolder<D, F> result =
new ResolutionTaskHolder<D, F>(storageManager, context, new MyPriorityProvider<D>(context), tracing);
TaskPrioritizerContext<D, F> taskPrioritizerContext =
new TaskPrioritizerContext<D, F>(name, result, context, context.scope, callableDescriptorCollectors);
if (explicitReceiver instanceof QualifierReceiver) {
QualifierReceiver qualifierReceiver = (QualifierReceiver) explicitReceiver;
doComputeTasks(NO_RECEIVER, taskPrioritizerContext.replaceScope(qualifierReceiver.getNestedClassesAndPackageMembersScope()));
ReceiverValue classObjectReceiver = qualifierReceiver.getClassObjectReceiver();
if (explicitReceiver is QualifierReceiver) {
val qualifierReceiver = explicitReceiver : QualifierReceiver
doComputeTasks(NO_RECEIVER, taskPrioritizerContext.replaceScope(qualifierReceiver.getNestedClassesAndPackageMembersScope()))
val classObjectReceiver = qualifierReceiver.getClassObjectReceiver()
if (classObjectReceiver.exists()) {
doComputeTasks(classObjectReceiver, taskPrioritizerContext);
doComputeTasks(classObjectReceiver, taskPrioritizerContext)
}
}
else {
doComputeTasks(explicitReceiver, taskPrioritizerContext);
doComputeTasks(explicitReceiver, taskPrioritizerContext)
}
return result.getTasks();
return result.getTasks()
}
private static <D extends CallableDescriptor, F extends D> void doComputeTasks(
@NotNull ReceiverValue receiver,
@NotNull TaskPrioritizerContext<D, F> c
) {
ProgressIndicatorProvider.checkCanceled();
private fun <D : CallableDescriptor, F : D> doComputeTasks(receiver: ReceiverValue, c: TaskPrioritizerContext<D, F>) {
ProgressIndicatorProvider.checkCanceled()
boolean resolveInvoke = c.context.call.getDispatchReceiver().exists();
val resolveInvoke = c.context.call.getDispatchReceiver().exists()
if (resolveInvoke) {
addCandidatesForInvoke(receiver, c);
return;
addCandidatesForInvoke(receiver, c)
return
}
Collection<ReceiverValue> implicitReceivers = Sets.newLinkedHashSet(JetScopeUtils.getImplicitReceiversHierarchyValues(c.scope));
val implicitReceivers = Sets.newLinkedHashSet<ReceiverValue>(JetScopeUtils.getImplicitReceiversHierarchyValues(c.scope))
if (receiver.exists()) {
addCandidatesForExplicitReceiver(receiver, implicitReceivers, c, /*isExplicit=*/true);
addMembers(receiver, c, /*static=*/true, /*isExplicit=*/true);
return;
addCandidatesForExplicitReceiver(receiver, implicitReceivers, c, isExplicit = true)
addMembers(receiver, c, staticMembers = true, isExplicit = true)
return
}
addCandidatesForNoReceiver(implicitReceivers, c);
addCandidatesForNoReceiver(implicitReceivers, c)
}
private static <D extends CallableDescriptor, F extends D> void addCandidatesForExplicitReceiver(
@NotNull ReceiverValue explicitReceiver,
@NotNull Collection<ReceiverValue> implicitReceivers,
@NotNull TaskPrioritizerContext<D, F> c,
boolean isExplicit
private fun <D : CallableDescriptor, F : D> addCandidatesForExplicitReceiver(
explicitReceiver: ReceiverValue,
implicitReceivers: Collection<ReceiverValue>,
c: TaskPrioritizerContext<D, F>,
isExplicit: Boolean
) {
addMembers(explicitReceiver, c, /*static=*/false, isExplicit);
addMembers(explicitReceiver, c, staticMembers = false, isExplicit = isExplicit)
if (TypesPackage.isDynamic(explicitReceiver.getType())) {
addCandidatesForDynamicReceiver(explicitReceiver, implicitReceivers, c, isExplicit);
if (explicitReceiver.getType().isDynamic()) {
addCandidatesForDynamicReceiver(explicitReceiver, implicitReceivers, c, isExplicit)
}
else {
addExtensionCandidates(explicitReceiver, implicitReceivers, c, isExplicit);
addExtensionCandidates(explicitReceiver, implicitReceivers, c, isExplicit)
}
}
private static <D extends CallableDescriptor, F extends D> void addExtensionCandidates(
@NotNull final ReceiverValue explicitReceiver,
@NotNull Collection<ReceiverValue> implicitReceivers,
@NotNull final TaskPrioritizerContext<D, F> c,
final boolean isExplicit
private fun <D : CallableDescriptor, F : D> addExtensionCandidates(
explicitReceiver: ReceiverValue,
implicitReceivers: Collection<ReceiverValue>,
c: TaskPrioritizerContext<D, F>,
isExplicit: Boolean
) {
for (final CallableDescriptorCollector<D> callableDescriptorCollector : c.callableDescriptorCollectors) {
for (callableDescriptorCollector in c.callableDescriptorCollectors) {
//member extensions
for (ReceiverValue implicitReceiver : implicitReceivers) {
addMemberExtensionCandidates(implicitReceiver, explicitReceiver,
callableDescriptorCollector, c, createKind(EXTENSION_RECEIVER, isExplicit));
for (implicitReceiver in implicitReceivers) {
addMemberExtensionCandidates(
implicitReceiver,
explicitReceiver,
callableDescriptorCollector,
c,
createKind(EXTENSION_RECEIVER, isExplicit)
)
}
//extensions
c.result.addCandidates(new Function0<Collection<? extends ResolutionCandidate<D>>>() {
@Override
public Collection<? extends ResolutionCandidate<D>> invoke() {
return convertWithImpliedThis(
c.scope, explicitReceiver, callableDescriptorCollector.getExtensionsByName(c.scope, c.name, c.context.trace),
createKind(EXTENSION_RECEIVER, isExplicit), c.context.call);
}
});
}
}
private static <D extends CallableDescriptor, F extends D> void addMembers(
final ReceiverValue explicitReceiver,
final TaskPrioritizerContext<D, F> c,
final boolean staticMembers,
final boolean isExplicit
) {
for (final CallableDescriptorCollector<D> callableDescriptorCollector : c.callableDescriptorCollectors) {
c.result.addCandidates(new Function0<Collection<? extends ResolutionCandidate<D>>>() {
@Override
public Collection<? extends ResolutionCandidate<D>> invoke() {
List<JetType> variantsForExplicitReceiver = SmartCastUtils.getSmartCastVariants(explicitReceiver, c.context);
Collection<ResolutionCandidate<D>> members = Lists.newArrayList();
for (JetType type : variantsForExplicitReceiver) {
Collection<D> membersForThisVariant =
staticMembers
? callableDescriptorCollector.getStaticMembersByName(type, c.name, c.context.trace)
: callableDescriptorCollector.getMembersByName(type, c.name, c.context.trace);
convertWithReceivers(membersForThisVariant, explicitReceiver,
NO_RECEIVER, members, createKind(DISPATCH_RECEIVER, isExplicit), c.context.call);
}
return members;
}
});
}
}
private static <D extends CallableDescriptor, F extends D> void addCandidatesForDynamicReceiver(
@NotNull final ReceiverValue explicitReceiver,
@NotNull Collection<ReceiverValue> implicitReceivers,
@NotNull final TaskPrioritizerContext<D, F> c,
boolean isExplicit
) {
TaskPrioritizerContext<D, F> onlyDynamicReceivers = c.replaceCollectors(TasksPackage.onlyDynamicReceivers(c.callableDescriptorCollectors));
addExtensionCandidates(explicitReceiver, implicitReceivers, onlyDynamicReceivers, isExplicit);
c.result.addCandidates(
new Function0<Collection<? extends ResolutionCandidate<D>>>() {
@Override
public Collection<? extends ResolutionCandidate<D>> invoke() {
JetScope dynamicScope = DynamicCallableDescriptors.createDynamicDescriptorScope(
c.context.call,
c.scope.getContainingDeclaration()
);
Collection<D> dynamicDescriptors = new ArrayList<D>();
for (CallableDescriptorCollector<D> collector : c.callableDescriptorCollectors) {
dynamicDescriptors.addAll(collector.getNonExtensionsByName(dynamicScope, c.name, c.context.trace));
}
return KotlinPackage.map(
dynamicDescriptors,
new Function1<D, ResolutionCandidate<D>>() {
@Override
public ResolutionCandidate<D> invoke(D dynamicDescriptor) {
ResolutionCandidate<D> dynamicCandidate = ResolutionCandidate.create(
c.context.call,
dynamicDescriptor
);
dynamicCandidate.setDispatchReceiver(explicitReceiver);
dynamicCandidate.setExplicitReceiverKind(DISPATCH_RECEIVER);
return dynamicCandidate;
}
}
);
}
}
);
}
private static ExplicitReceiverKind createKind(ExplicitReceiverKind kind, boolean isExplicit) {
if (isExplicit) return kind;
return ExplicitReceiverKind.NO_EXPLICIT_RECEIVER;
}
private static <D extends CallableDescriptor, F extends D> void addMemberExtensionCandidates(
@NotNull final ReceiverValue dispatchReceiver,
@NotNull final ReceiverValue receiverParameter,
@NotNull final CallableDescriptorCollector<D> callableDescriptorCollector,
@NotNull final TaskPrioritizerContext<D, F> c,
@NotNull final ExplicitReceiverKind receiverKind
) {
c.result.addCandidates(new Function0<Collection<? extends ResolutionCandidate<D>>>() {
@Override
public Collection<? extends ResolutionCandidate<D>> invoke() {
Collection<D> memberExtensions = callableDescriptorCollector.getExtensionsByName(
dispatchReceiver.getType().getMemberScope(), c.name, c.context.trace);
return convertWithReceivers(
memberExtensions, dispatchReceiver, receiverParameter, receiverKind, c.context.call);
c.result.addCandidates {
convertWithImpliedThis(
c.scope,
explicitReceiver,
callableDescriptorCollector.getExtensionsByName(c.scope, c.name, c.context.trace),
createKind(EXTENSION_RECEIVER, isExplicit),
c.context.call
)
}
});
}
}
private static <D extends CallableDescriptor, F extends D> void addCandidatesForNoReceiver(
@NotNull Collection<ReceiverValue> implicitReceivers,
@NotNull TaskPrioritizerContext<D, F> c
private fun <D : CallableDescriptor, F : D> addMembers(
explicitReceiver: ReceiverValue,
c: TaskPrioritizerContext<D, F>,
staticMembers: Boolean,
isExplicit: Boolean
) {
List<Collection<ResolutionCandidate<D>>> localsList = Lists.newArrayList();
List<Collection<ResolutionCandidate<D>>> nonlocalsList = Lists.newArrayList();
for (CallableDescriptorCollector<D> callableDescriptorCollector : c.callableDescriptorCollectors) {
for (callableDescriptorCollector in c.callableDescriptorCollectors) {
c.result.addCandidates {
val variantsForExplicitReceiver = SmartCastUtils.getSmartCastVariants(explicitReceiver, c.context as ResolutionContext<*>) //workaround KT-1969
val members = Lists.newArrayList<ResolutionCandidate<D>>()
for (type in variantsForExplicitReceiver) {
val membersForThisVariant = if (staticMembers) {
callableDescriptorCollector.getStaticMembersByName(type, c.name, c.context.trace)
}
else {
callableDescriptorCollector.getMembersByName(type, c.name, c.context.trace)
}
convertWithReceivers(
membersForThisVariant,
explicitReceiver,
NO_RECEIVER,
members,
createKind(DISPATCH_RECEIVER, isExplicit),
c.context.call
)
}
members
}
}
}
Collection<ResolutionCandidate<D>> members = convertWithImpliedThisAndNoReceiver(
c.scope, callableDescriptorCollector.getNonExtensionsByName(c.scope, c.name, c.context.trace), c.context.call);
private fun <D : CallableDescriptor, F : D> addCandidatesForDynamicReceiver(
explicitReceiver: ReceiverValue,
implicitReceivers: Collection<ReceiverValue>,
c: TaskPrioritizerContext<D, F>,
isExplicit: Boolean
) {
val onlyDynamicReceivers = c.replaceCollectors(c.callableDescriptorCollectors.onlyDynamicReceivers<D>())
addExtensionCandidates(explicitReceiver, implicitReceivers, onlyDynamicReceivers, isExplicit)
List<ResolutionCandidate<D>> nonlocals = Lists.newArrayList();
List<ResolutionCandidate<D>> locals = Lists.newArrayList();
c.result.addCandidates {
val dynamicScope = DynamicCallableDescriptors.createDynamicDescriptorScope(c.context.call, c.scope.getContainingDeclaration())
val dynamicDescriptors = ArrayList<D>()
for (collector in c.callableDescriptorCollectors) {
dynamicDescriptors.addAll(collector.getNonExtensionsByName(dynamicScope, c.name, c.context.trace))
}
dynamicDescriptors.map {
val dynamicCandidate = ResolutionCandidate.create<D>(c.context.call, it)
dynamicCandidate.setDispatchReceiver(explicitReceiver)
dynamicCandidate.setExplicitReceiverKind(DISPATCH_RECEIVER)
dynamicCandidate
}
}
}
private fun createKind(kind: ExplicitReceiverKind, isExplicit: Boolean): ExplicitReceiverKind {
if (isExplicit) return kind
return ExplicitReceiverKind.NO_EXPLICIT_RECEIVER
}
private fun <D : CallableDescriptor, F : D> addMemberExtensionCandidates(
dispatchReceiver: ReceiverValue,
receiverParameter: ReceiverValue,
callableDescriptorCollector: CallableDescriptorCollector<D>,
c: TaskPrioritizerContext<D, F>,
receiverKind: ExplicitReceiverKind
) {
c.result.addCandidates {
val memberExtensions =
callableDescriptorCollector.getExtensionsByName(dispatchReceiver.getType().getMemberScope(), c.name, c.context.trace)
convertWithReceivers(memberExtensions, dispatchReceiver, receiverParameter, receiverKind, c.context.call)
}
}
private fun <D : CallableDescriptor, F : D> addCandidatesForNoReceiver(
implicitReceivers: Collection<ReceiverValue>,
c: TaskPrioritizerContext<D, F>
) {
val localsList = Lists.newArrayList<Collection<ResolutionCandidate<D>>>()
val nonlocalsList = Lists.newArrayList<Collection<ResolutionCandidate<D>>>()
for (callableDescriptorCollector in c.callableDescriptorCollectors) {
val members = convertWithImpliedThisAndNoReceiver(
c.scope,
callableDescriptorCollector.getNonExtensionsByName(c.scope, c.name, c.context.trace),
c.context.call
)
val nonlocals = Lists.newArrayList<ResolutionCandidate<D>>()
val locals = Lists.newArrayList<ResolutionCandidate<D>>()
//noinspection unchecked,RedundantTypeArguments
TaskPrioritizer.<D>splitLexicallyLocalDescriptors(members, c.scope.getContainingDeclaration(), locals, nonlocals);
splitLexicallyLocalDescriptors(members, c.scope.getContainingDeclaration(), locals, nonlocals)
localsList.add(locals);
nonlocalsList.add(nonlocals);
localsList.add(locals)
nonlocalsList.add(nonlocals)
}
//locals
c.result.addCandidates(localsList);
c.result.addCandidates(localsList)
//try all implicit receivers as explicit
for (ReceiverValue implicitReceiver : implicitReceivers) {
addCandidatesForExplicitReceiver(implicitReceiver, implicitReceivers, c, /*isExplicit=*/false);
for (implicitReceiver in implicitReceivers) {
addCandidatesForExplicitReceiver(implicitReceiver, implicitReceivers, c, isExplicit = false)
}
//nonlocals
c.result.addCandidates(nonlocalsList);
c.result.addCandidates(nonlocalsList)
//static (only for better error reporting)
for (ReceiverValue implicitReceiver : implicitReceivers) {
addMembers(implicitReceiver, c, /*static=*/true, /*isExplicit=*/false);
for (implicitReceiver in implicitReceivers) {
addMembers(implicitReceiver, c, staticMembers = true, isExplicit = false)
}
}
private static <D extends CallableDescriptor, F extends D> void addCandidatesForInvoke(
@NotNull ReceiverValue explicitReceiver,
@NotNull TaskPrioritizerContext<D, F> c
) {
List<ReceiverValue> implicitReceivers = JetScopeUtils.getImplicitReceiversHierarchyValues(c.scope);
private fun <D : CallableDescriptor, F : D> addCandidatesForInvoke(explicitReceiver: ReceiverValue, c: TaskPrioritizerContext<D, F>) {
val implicitReceivers = JetScopeUtils.getImplicitReceiversHierarchyValues(c.scope)
// For 'a.foo()' where foo has function type,
// a is explicitReceiver, foo is variableReceiver.
ReceiverValue variableReceiver = c.context.call.getDispatchReceiver();
assert variableReceiver.exists() : "'Invoke' call hasn't got variable receiver";
val variableReceiver = c.context.call.getDispatchReceiver()
assert(variableReceiver.exists(), "'Invoke' call hasn't got variable receiver")
// For invocation a.foo() explicit receiver 'a'
// can be a receiver for 'foo' variable
@@ -325,7 +285,7 @@ public class TaskPrioritizer {
// (1) a.foo + foo.invoke()
if (!explicitReceiver.exists()) {
addCandidatesForExplicitReceiver(variableReceiver, implicitReceivers, c, /*isExplicit=*/true);
addCandidatesForExplicitReceiver(variableReceiver, implicitReceivers, c, isExplicit = true)
}
// (2) foo + a.invoke()
@@ -336,176 +296,145 @@ public class TaskPrioritizer {
if (explicitReceiver.exists()) {
//a.foo()
addCandidatesWhenInvokeIsMemberAndExtensionToExplicitReceiver(variableReceiver, explicitReceiver, c, BOTH_RECEIVERS);
return;
addCandidatesWhenInvokeIsMemberAndExtensionToExplicitReceiver(variableReceiver, explicitReceiver, c, BOTH_RECEIVERS)
return
}
// with (a) { foo() }
for (ReceiverValue implicitReceiver : implicitReceivers) {
addCandidatesWhenInvokeIsMemberAndExtensionToExplicitReceiver(variableReceiver, implicitReceiver, c, DISPATCH_RECEIVER);
for (implicitReceiver in implicitReceivers) {
addCandidatesWhenInvokeIsMemberAndExtensionToExplicitReceiver(variableReceiver, implicitReceiver, c, DISPATCH_RECEIVER)
}
}
private static <D extends CallableDescriptor, F extends D> void addCandidatesWhenInvokeIsMemberAndExtensionToExplicitReceiver(
@NotNull ReceiverValue dispatchReceiver,
@NotNull ReceiverValue receiverParameter,
@NotNull TaskPrioritizerContext<D, F> c,
@NotNull ExplicitReceiverKind receiverKind
private fun <D : CallableDescriptor, F : D> addCandidatesWhenInvokeIsMemberAndExtensionToExplicitReceiver(
dispatchReceiver: ReceiverValue,
receiverParameter: ReceiverValue,
c: TaskPrioritizerContext<D, F>,
receiverKind: ExplicitReceiverKind
) {
for (CallableDescriptorCollector<D> callableDescriptorCollector : c.callableDescriptorCollectors) {
addMemberExtensionCandidates(dispatchReceiver, receiverParameter, callableDescriptorCollector, c, receiverKind);
for (callableDescriptorCollector in c.callableDescriptorCollectors) {
addMemberExtensionCandidates(dispatchReceiver, receiverParameter, callableDescriptorCollector, c, receiverKind)
}
}
private static <D extends CallableDescriptor> Collection<ResolutionCandidate<D>> convertWithReceivers(
@NotNull Collection<D> descriptors,
@NotNull ReceiverValue dispatchReceiver,
@NotNull ReceiverValue extensionReceiver,
@NotNull ExplicitReceiverKind explicitReceiverKind,
@NotNull Call call
) {
Collection<ResolutionCandidate<D>> result = Lists.newArrayList();
convertWithReceivers(descriptors, dispatchReceiver, extensionReceiver, result, explicitReceiverKind, call);
return result;
private fun <D : CallableDescriptor> convertWithReceivers(
descriptors: Collection<D>,
dispatchReceiver: ReceiverValue,
extensionReceiver: ReceiverValue,
explicitReceiverKind: ExplicitReceiverKind,
call: Call
): Collection<ResolutionCandidate<D>> {
val result = Lists.newArrayList<ResolutionCandidate<D>>()
convertWithReceivers(descriptors, dispatchReceiver, extensionReceiver, result, explicitReceiverKind, call)
return result
}
private static <D extends CallableDescriptor> void convertWithReceivers(
@NotNull Collection<D> descriptors,
@NotNull ReceiverValue dispatchReceiver,
@NotNull ReceiverValue extensionReceiver,
@NotNull Collection<ResolutionCandidate<D>> result,
@NotNull ExplicitReceiverKind explicitReceiverKind,
@NotNull Call call
private fun <D : CallableDescriptor> convertWithReceivers(
descriptors: Collection<D>,
dispatchReceiver: ReceiverValue,
extensionReceiver: ReceiverValue,
result: MutableCollection<ResolutionCandidate<D>>,
explicitReceiverKind: ExplicitReceiverKind,
call: Call
) {
for (D descriptor : descriptors) {
ResolutionCandidate<D> candidate = ResolutionCandidate.create(call, descriptor);
candidate.setDispatchReceiver(dispatchReceiver);
candidate.setExtensionReceiver(extensionReceiver);
candidate.setExplicitReceiverKind(explicitReceiverKind);
result.add(candidate);
for (descriptor in descriptors) {
val candidate = ResolutionCandidate.create<D>(call, descriptor)
candidate.setDispatchReceiver(dispatchReceiver)
candidate.setExtensionReceiver(extensionReceiver)
candidate.setExplicitReceiverKind(explicitReceiverKind)
result.add(candidate)
}
}
public static <D extends CallableDescriptor> Collection<ResolutionCandidate<D>> convertWithImpliedThisAndNoReceiver(
@NotNull JetScope scope,
@NotNull Collection<? extends D> descriptors,
@NotNull Call call
) {
return convertWithImpliedThis(scope, NO_RECEIVER, descriptors, NO_EXPLICIT_RECEIVER, call);
public fun <D : CallableDescriptor> convertWithImpliedThisAndNoReceiver(
scope: JetScope,
descriptors: Collection<D>,
call: Call
): Collection<ResolutionCandidate<D>> {
return convertWithImpliedThis(scope, NO_RECEIVER, descriptors, NO_EXPLICIT_RECEIVER, call)
}
public static <D extends CallableDescriptor> Collection<ResolutionCandidate<D>> convertWithImpliedThis(
@NotNull JetScope scope,
@NotNull ReceiverValue receiverParameter,
@NotNull Collection<? extends D> descriptors,
@NotNull ExplicitReceiverKind receiverKind,
@NotNull Call call
) {
Collection<ResolutionCandidate<D>> result = Lists.newArrayList();
for (D descriptor : descriptors) {
ResolutionCandidate<D> candidate = ResolutionCandidate.create(call, descriptor);
candidate.setExtensionReceiver(receiverParameter);
candidate.setExplicitReceiverKind(receiverKind);
public fun <D : CallableDescriptor> convertWithImpliedThis(
scope: JetScope,
receiverParameter: ReceiverValue,
descriptors: Collection<D>,
receiverKind: ExplicitReceiverKind,
call: Call
): Collection<ResolutionCandidate<D>> {
val result = Lists.newArrayList<ResolutionCandidate<D>>()
for (descriptor in descriptors) {
val candidate = ResolutionCandidate.create<D>(call, descriptor)
candidate.setExtensionReceiver(receiverParameter)
candidate.setExplicitReceiverKind(receiverKind)
if (setImpliedThis(scope, candidate)) {
result.add(candidate);
result.add(candidate)
}
}
return result;
return result
}
private static <D extends CallableDescriptor> boolean setImpliedThis(
@NotNull JetScope scope,
@NotNull ResolutionCandidate<D> candidate
) {
ReceiverParameterDescriptor dispatchReceiver = candidate.getDescriptor().getDispatchReceiverParameter();
if (dispatchReceiver == null) return true;
List<ReceiverParameterDescriptor> receivers = scope.getImplicitReceiversHierarchy();
for (ReceiverParameterDescriptor receiver : receivers) {
private fun <D : CallableDescriptor> setImpliedThis(
scope: JetScope,
candidate: ResolutionCandidate<D>
): Boolean {
val dispatchReceiver = candidate.getDescriptor().getDispatchReceiverParameter()
if (dispatchReceiver == null) return true
val receivers = scope.getImplicitReceiversHierarchy()
for (receiver in receivers) {
if (JetTypeChecker.DEFAULT.isSubtypeOf(receiver.getType(), dispatchReceiver.getType())) {
// TODO : Smartcasts & nullability
candidate.setDispatchReceiver(dispatchReceiver.getValue());
return true;
candidate.setDispatchReceiver(dispatchReceiver.getValue())
return true
}
}
return false;
return false
}
public <D extends CallableDescriptor, F extends D> List<ResolutionTask<D, F>> computePrioritizedTasksFromCandidates(
@NotNull BasicCallResolutionContext context,
@NotNull final Collection<ResolutionCandidate<D>> candidates,
@NotNull TracingStrategy tracing
public fun <D : CallableDescriptor, F : D> computePrioritizedTasksFromCandidates(
context: BasicCallResolutionContext,
candidates: Collection<ResolutionCandidate<D>>,
tracing: TracingStrategy
): List<ResolutionTask<D, F>> {
val result = ResolutionTaskHolder<D, F>(storageManager, context, MyPriorityProvider<D>(context), tracing)
result.addCandidates {
candidates
}
return result.getTasks()
}
private class MyPriorityProvider<D : CallableDescriptor>(private val context: BasicCallResolutionContext) :
ResolutionTaskHolder.PriorityProvider<ResolutionCandidate<D>> {
override fun getPriority(candidate: ResolutionCandidate<D>)
= (if (isVisible(candidate)) 2 else 0) + (if (isSynthesized(candidate)) 0 else 1)
override fun getMaxPriority() = 3
private fun isVisible(call: ResolutionCandidate<D>?): Boolean {
if (call == null) return false
val candidateDescriptor = call.getDescriptor()
if (ErrorUtils.isError(candidateDescriptor)) return true
return Visibilities.isVisible(candidateDescriptor, context.scope.getContainingDeclaration())
}
private fun isSynthesized(call: ResolutionCandidate<D>): Boolean {
val descriptor = call.getDescriptor()
return descriptor is CallableMemberDescriptor && isOrOverridesSynthesized(descriptor : CallableMemberDescriptor)
}
}
private class TaskPrioritizerContext<D : CallableDescriptor, F : D>(
val name: Name,
val result: ResolutionTaskHolder<D, F>,
val context: BasicCallResolutionContext,
val scope: JetScope,
val callableDescriptorCollectors: CallableDescriptorCollectors<D>
) {
ResolutionTaskHolder<D, F> result = new ResolutionTaskHolder<D, F>(
storageManager, context, new MyPriorityProvider<D>(context), tracing);
result.addCandidates(new Function0<Collection<? extends ResolutionCandidate<D>>>() {
@Override
public Collection<? extends ResolutionCandidate<D>> invoke() {
return candidates;
}
});
return result.getTasks();
}
private static class MyPriorityProvider<D extends CallableDescriptor>
implements ResolutionTaskHolder.PriorityProvider<ResolutionCandidate<D>> {
private final BasicCallResolutionContext context;
public MyPriorityProvider(BasicCallResolutionContext context) {
this.context = context;
fun replaceScope(newScope: JetScope): TaskPrioritizerContext<D, F> {
return TaskPrioritizerContext(name, result, context, newScope, callableDescriptorCollectors)
}
@Override
public int getPriority(ResolutionCandidate<D> call) {
return (isVisible(call) ? 2 : 0) + (isSynthesized(call) ? 0 : 1);
fun replaceCollectors(newCollectors: CallableDescriptorCollectors<D>): TaskPrioritizerContext<D, F> {
return TaskPrioritizerContext(name, result, context, scope, newCollectors)
}
@Override
public int getMaxPriority() {
return 3;
}
private boolean isVisible(ResolutionCandidate<D> call) {
if (call == null) return false;
D candidateDescriptor = call.getDescriptor();
if (ErrorUtils.isError(candidateDescriptor)) return true;
return Visibilities.isVisible(candidateDescriptor, context.scope.getContainingDeclaration());
}
private boolean isSynthesized(ResolutionCandidate<D> call) {
D descriptor = call.getDescriptor();
return descriptor instanceof CallableMemberDescriptor &&
isOrOverridesSynthesized((CallableMemberDescriptor) descriptor);
}
}
private static class TaskPrioritizerContext<D extends CallableDescriptor, F extends D> {
@NotNull public final Name name;
@NotNull public final ResolutionTaskHolder<D, F> result;
@NotNull public final BasicCallResolutionContext context;
@NotNull public final JetScope scope;
@NotNull public final CallableDescriptorCollectors<D> callableDescriptorCollectors;
private TaskPrioritizerContext(
@NotNull Name name,
@NotNull ResolutionTaskHolder<D, F> result,
@NotNull BasicCallResolutionContext context,
@NotNull JetScope scope,
@NotNull CallableDescriptorCollectors<D> callableDescriptorCollectors
) {
this.name = name;
this.result = result;
this.context = context;
this.scope = scope;
this.callableDescriptorCollectors = callableDescriptorCollectors;
}
private TaskPrioritizerContext<D, F> replaceScope(JetScope newScope) {
return new TaskPrioritizerContext<D, F>(name, result, context, newScope, callableDescriptorCollectors);
}
private TaskPrioritizerContext<D, F> replaceCollectors(CallableDescriptorCollectors<D> newCollectors) {
return new TaskPrioritizerContext<D, F>(name, result, context, scope, newCollectors);
}
}
}