'getNonMembersByName' instead of 'getExtensionsByName' not to throw out invocation of variables with members-extensions
This commit is contained in:
+38
@@ -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);
|
||||
}
|
||||
+23
-47
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user