'getNonMembersByName' instead of 'getExtensionsByName' not to throw out invocation of variables with members-extensions

This commit is contained in:
Svetlana Isakova
2012-04-30 15:26:28 +04:00
parent aeed586fba
commit 2fa8fd50fc
3 changed files with 82 additions and 63 deletions
@@ -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 CallableDescriptorCollector<D extends CallableDescriptor> {
@NotNull
Collection<D> getNonExtensionsByName(JetScope scope, String name);
@NotNull
Collection<D> getMembersByName(@NotNull JetType receiver, String name);
@NotNull
Collection<D> getNonMembersByName(JetScope scope, String name);
}
@@ -26,7 +26,6 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.lang.types.JetType;
import java.util.*;
@@ -34,11 +33,9 @@ import java.util.*;
/**
* @author abreslav
*/
public class MemberPrioritizers {
/*package*/ static MemberPrioritizer<FunctionDescriptor> FUNCTION_TASK_PRIORITIZER = new MemberPrioritizer<FunctionDescriptor>() {
public class CallableDescriptorCollectors {
/*package*/ static CallableDescriptorCollector<FunctionDescriptor> FUNCTIONS = new CallableDescriptorCollector<FunctionDescriptor>() {
@NotNull
@Override
@@ -51,8 +48,6 @@ public class MemberPrioritizers {
}
}
addConstructors(scope, name, functions);
addVariableAsFunction(scope, name, functions, false);
return functions;
}
@@ -62,22 +57,13 @@ public class MemberPrioritizers {
JetScope receiverScope = receiverType.getMemberScope();
Set<FunctionDescriptor> members = Sets.newHashSet(receiverScope.getFunctions(name));
addConstructors(receiverScope, name, members);
addVariableAsFunction(receiverScope, name, members, false);
return members;
}
@NotNull
@Override
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();
if (!descriptor.getReceiverParameter().exists()) {
iterator.remove();
}
}
addVariableAsFunction(scope, name, extensionFunctions, true);
return extensionFunctions;
public Collection<FunctionDescriptor> getNonMembersByName(JetScope scope, String name) {
return scope.getFunctions(name);
}
private void addConstructors(JetScope scope, String name, Collection<FunctionDescriptor> functions) {
@@ -87,25 +73,9 @@ public class MemberPrioritizers {
functions.addAll(classDescriptor.getConstructors());
}
}
private void addVariableAsFunction(JetScope scope, String name, Set<FunctionDescriptor> functions, boolean receiverNeeded) {
VariableDescriptor variable = scope.getLocalVariable(name);
if (variable == null) {
variable = DescriptorUtils.filterNonExtensionProperty(scope.getProperties(name));
}
if (variable != null) {
JetType outType = variable.getType();
if (outType != null && JetStandardClasses.isFunctionType(outType)) {
VariableAsFunctionDescriptor functionDescriptor = VariableAsFunctionDescriptor.create(variable);
if ((functionDescriptor.getReceiverParameter().exists()) == receiverNeeded) {
functions.add(functionDescriptor);
}
}
}
}
};
/*package*/ static MemberPrioritizer<VariableDescriptor> VARIABLE_TASK_PRIORITIZER = new MemberPrioritizer<VariableDescriptor>() {
/*package*/ static CallableDescriptorCollector<VariableDescriptor> VARIABLES = new CallableDescriptorCollector<VariableDescriptor>() {
@NotNull
@Override
@@ -126,17 +96,19 @@ public class MemberPrioritizers {
@NotNull
@Override
public Collection<VariableDescriptor> getExtensionsByName(JetScope scope, String name) {
return Collections2.filter(scope.getProperties(name), new Predicate<VariableDescriptor>() {
@Override
public boolean apply(@Nullable VariableDescriptor variableDescriptor) {
return (variableDescriptor != null) && variableDescriptor.getReceiverParameter().exists();
}
});
public Collection<VariableDescriptor> getNonMembersByName(JetScope scope, String name) {
Collection<VariableDescriptor> result = Sets.newLinkedHashSet();
VariableDescriptor localVariable = scope.getLocalVariable(name);
if (localVariable != null) {
result.add(localVariable);
}
result.addAll(scope.getProperties(name));
return result;
}
};
/*package*/ static MemberPrioritizer<VariableDescriptor> PROPERTY_TASK_PRIORITIZER = new MemberPrioritizer<VariableDescriptor>() {
/*package*/ static CallableDescriptorCollector<VariableDescriptor> PROPERTIES = new CallableDescriptorCollector<VariableDescriptor>() {
private Collection<VariableDescriptor> filterProperties(Collection<? extends VariableDescriptor> variableDescriptors) {
ArrayList<VariableDescriptor> properties = Lists.newArrayList();
for (VariableDescriptor descriptor : variableDescriptors) {
@@ -150,19 +122,23 @@ public class MemberPrioritizers {
@NotNull
@Override
public Collection<VariableDescriptor> getNonExtensionsByName(JetScope scope, String name) {
return filterProperties(VARIABLE_TASK_PRIORITIZER.getNonExtensionsByName(scope, name));
return filterProperties(VARIABLES.getNonExtensionsByName(scope, name));
}
@NotNull
@Override
public Collection<VariableDescriptor> getMembersByName(@NotNull JetType receiver, String name) {
return filterProperties(VARIABLE_TASK_PRIORITIZER.getMembersByName(receiver, name));
return filterProperties(VARIABLES.getMembersByName(receiver, name));
}
@NotNull
@Override
public Collection<VariableDescriptor> getExtensionsByName(JetScope scope, String name) {
return filterProperties(VARIABLE_TASK_PRIORITIZER.getExtensionsByName(scope, name));
public Collection<VariableDescriptor> getNonMembersByName(JetScope scope, String name) {
return filterProperties(VARIABLES.getNonMembersByName(scope, name));
}
};
/*package*/ static List<CallableDescriptorCollector<? extends CallableDescriptor>> FUNCTIONS_AND_VARIABLES = Lists.newArrayList(
FUNCTIONS, VARIABLES);
}
@@ -74,8 +74,8 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
}
@NotNull
public static <D extends CallableDescriptor> List<ResolutionTask<D>> computePrioritizedTasks(@NotNull BasicResolutionContext context, @NotNull String name,
@NotNull JetReferenceExpression functionReference, @NotNull List<MemberPrioritizer<D>> memberPrioritizers) {
public static <D extends CallableDescriptor, F extends D> List<ResolutionTask<D, F>> computePrioritizedTasks(@NotNull BasicResolutionContext context, @NotNull String name,
@NotNull JetReferenceExpression functionReference, @NotNull List<CallableDescriptorCollector<? extends D>> callableDescriptorCollectors) {
ReceiverDescriptor explicitReceiver = context.call.getExplicitReceiver();
final JetScope scope;
if (explicitReceiver.exists() && explicitReceiver.getType() instanceof NamespaceType) {
@@ -96,23 +96,26 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
}
};
ResolutionTaskHolder<D> result = new ResolutionTaskHolder<D>(functionReference, context, visibleStrategy );
doComputeTasks(scope, explicitReceiver, name, result, context, memberPrioritizers);
ResolutionTaskHolder<D, F> result = new ResolutionTaskHolder<D, F>(functionReference, context, visibleStrategy );
for (CallableDescriptorCollector<? extends D> callableDescriptorCollector : callableDescriptorCollectors) {
doComputeTasks(scope, explicitReceiver, name, result, context, callableDescriptorCollector);
}
return result.getTasks();
}
private static <D extends CallableDescriptor> void doComputeTasks(@NotNull JetScope scope, @NotNull ReceiverDescriptor receiver,
@NotNull String name, @NotNull ResolutionTaskHolder<D> result,
@NotNull BasicResolutionContext context, @NotNull List<MemberPrioritizer<D>> memberPrioritizers) {
MemberPrioritizer<D> memberPrioritizer = memberPrioritizers.get(0);
private static <D extends CallableDescriptor, F extends D> void doComputeTasks(@NotNull JetScope scope, @NotNull ReceiverDescriptor receiver,
@NotNull String name, @NotNull ResolutionTaskHolder<D, F> result,
@NotNull BasicResolutionContext context, @NotNull CallableDescriptorCollector<? extends D> callableDescriptorCollector) {
AutoCastServiceImpl autoCastService = new AutoCastServiceImpl(context.dataFlowInfo, context.trace.getBindingContext());
List<ReceiverDescriptor> implicitReceivers = Lists.newArrayList();
scope.getImplicitReceiversHierarchy(implicitReceivers);
if (context.call.getThisObject().exists()) {
implicitReceivers.add(context.call.getThisObject());
}
if (receiver.exists()) {
List<ReceiverDescriptor> variantsForExplicitReceiver = autoCastService.getVariantsForReceiver(receiver);
Collection<ResolutionCandidate<D>> extensionFunctions = convertWithImpliedThis(scope, variantsForExplicitReceiver, memberPrioritizer.getExtensionsByName(scope, name));
Collection<ResolutionCandidate<D>> extensionFunctions = convertWithImpliedThis(scope, variantsForExplicitReceiver, callableDescriptorCollector.getNonMembersByName(scope, name));
List<ResolutionCandidate<D>> nonlocals = Lists.newArrayList();
List<ResolutionCandidate<D>> locals = Lists.newArrayList();
//noinspection unchecked,RedundantTypeArguments
@@ -120,7 +123,7 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
Collection<ResolutionCandidate<D>> members = Lists.newArrayList();
for (ReceiverDescriptor variant : variantsForExplicitReceiver) {
Collection<D> membersForThisVariant = memberPrioritizer.getMembersByName(variant.getType(), name);
Collection<? extends D> membersForThisVariant = callableDescriptorCollector.getMembersByName(variant.getType(), name);
convertWithReceivers(membersForThisVariant, Collections.singletonList(variant), Collections.singletonList(NO_RECEIVER), members);
}
@@ -128,7 +131,8 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
result.addMembers(members);
for (ReceiverDescriptor implicitReceiver : implicitReceivers) {
Collection<D> memberExtensions = memberPrioritizer.getExtensionsByName(implicitReceiver.getType().getMemberScope(), name);
Collection<? extends D> memberExtensions = callableDescriptorCollector.getNonMembersByName(
implicitReceiver.getType().getMemberScope(), name);
List<ReceiverDescriptor> variantsForImplicitReceiver = autoCastService.getVariantsForReceiver(implicitReceiver);
result.addNonLocalExtensions(convertWithReceivers(memberExtensions, variantsForImplicitReceiver, variantsForExplicitReceiver));
}
@@ -136,7 +140,8 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
result.addNonLocalExtensions(nonlocals);
}
else {
Collection<ResolutionCandidate<D>> functions = convertWithImpliedThis(scope, Collections.singletonList(receiver), memberPrioritizer.getNonExtensionsByName(scope, name));
Collection<ResolutionCandidate<D>> functions = convertWithImpliedThis(scope, Collections.singletonList(receiver), callableDescriptorCollector
.getNonExtensionsByName(scope, name));
List<ResolutionCandidate<D>> nonlocals = Lists.newArrayList();
List<ResolutionCandidate<D>> locals = Lists.newArrayList();
@@ -147,18 +152,18 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
result.addNonLocalExtensions(nonlocals);
for (ReceiverDescriptor implicitReceiver : implicitReceivers) {
doComputeTasks(scope, implicitReceiver, name, result, context, memberPrioritizers);
doComputeTasks(scope, implicitReceiver, name, result, context, callableDescriptorCollector);
}
}
}
private static <D extends CallableDescriptor> Collection<ResolutionCandidate<D>> convertWithReceivers(Collection<D> descriptors, Iterable<ReceiverDescriptor> thisObjects, Iterable<ReceiverDescriptor> receiverParameters) {
private static <D extends CallableDescriptor> Collection<ResolutionCandidate<D>> convertWithReceivers(Collection<? extends D> descriptors, Iterable<ReceiverDescriptor> thisObjects, Iterable<ReceiverDescriptor> receiverParameters) {
Collection<ResolutionCandidate<D>> result = Lists.newArrayList();
convertWithReceivers(descriptors, thisObjects, receiverParameters, result);
return result;
}
private static <D extends CallableDescriptor> void convertWithReceivers(Collection<D> descriptors, Iterable<ReceiverDescriptor> thisObjects, Iterable<ReceiverDescriptor> receiverParameters, Collection<ResolutionCandidate<D>> result) {
private static <D extends CallableDescriptor> void convertWithReceivers(Collection<? extends D> descriptors, Iterable<ReceiverDescriptor> thisObjects, Iterable<ReceiverDescriptor> receiverParameters, Collection<ResolutionCandidate<D>> result) {
for (ReceiverDescriptor thisObject : thisObjects) {
for (ReceiverDescriptor receiverParameter : receiverParameters) {
for (D extension : descriptors) {