KT-768 Code completion for extension functions
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jet.lang.descriptors;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||
@@ -24,6 +25,7 @@ public interface CallableDescriptor extends DeclarationDescriptor {
|
||||
/**
|
||||
* Method may return null for not yet fully initialized object or if error occurred.
|
||||
*/
|
||||
@Nullable
|
||||
JetType getReturnType();
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -21,6 +21,7 @@ public interface DeclarationDescriptor extends Annotated, Named {
|
||||
@Nullable
|
||||
DeclarationDescriptor getContainingDeclaration();
|
||||
|
||||
@Nullable
|
||||
DeclarationDescriptor substitute(TypeSubstitutor substitutor);
|
||||
|
||||
<R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data);
|
||||
|
||||
@@ -2,14 +2,16 @@ package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Introduces a simple wrapper for internal scope.
|
||||
*
|
||||
* @author abreslav
|
||||
*/
|
||||
public abstract class AbstractScopeAdapter implements JetScope {
|
||||
|
||||
@@ -83,7 +83,7 @@ public class CallResolver {
|
||||
FunctionDescriptor functionDescriptor = resolveSimpleCallToFunctionDescriptor(trace, scope, call, expectedType);
|
||||
return functionDescriptor == null ? null : functionDescriptor.getReturnType();
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public ResolvedCall<FunctionDescriptor> resolveCallWithGivenName(
|
||||
@NotNull BindingTrace trace,
|
||||
@@ -92,7 +92,8 @@ public class CallResolver {
|
||||
@NotNull final JetReferenceExpression functionReference,
|
||||
@NotNull String name,
|
||||
@NotNull JetType expectedType) {
|
||||
List<ResolutionTask<FunctionDescriptor>> tasks = TaskPrioritizers.FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks(scope, call, name, trace.getBindingContext(), dataFlowInfo);
|
||||
List<ResolutionTask<FunctionDescriptor>> tasks = TaskPrioritizers.FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks(
|
||||
scope, call, name, trace.getBindingContext(), dataFlowInfo);
|
||||
return doResolveCall(trace, scope, call, expectedType, tasks, functionReference);
|
||||
}
|
||||
|
||||
@@ -403,7 +404,11 @@ public class CallResolver {
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@NotNull
|
||||
private <D extends CallableDescriptor> OverloadResolutionResults<D> performResolution(@NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull JetType expectedType, @NotNull ResolutionTask<D> task, @NotNull TracingStrategy tracing) {
|
||||
private <D extends CallableDescriptor> OverloadResolutionResults<D> performResolution(
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull JetScope scope, @NotNull JetType expectedType,
|
||||
@NotNull ResolutionTask<D> task, @NotNull TracingStrategy tracing
|
||||
) {
|
||||
for (ResolvedCallImpl<D> candidateCall : task.getCandidates()) {
|
||||
D candidate = candidateCall.getCandidateDescriptor();
|
||||
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace);
|
||||
|
||||
@@ -9,6 +9,8 @@ import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Stores candidates for call resolution.
|
||||
*
|
||||
* @author abreslav
|
||||
*/
|
||||
/*package*/ class ResolutionTask<D extends CallableDescriptor> {
|
||||
|
||||
@@ -17,8 +17,8 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||
import org.jetbrains.jet.lang.types.NamespaceType;
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -32,8 +32,11 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
||||
/*package*/ abstract class TaskPrioritizer<D extends CallableDescriptor> {
|
||||
|
||||
public static <D extends CallableDescriptor> void splitLexicallyLocalDescriptors(
|
||||
Collection<ResolvedCallImpl<D>> allDescriptors, DeclarationDescriptor containerOfTheCurrentLocality, Collection<ResolvedCallImpl<D>> local, Collection<ResolvedCallImpl<D>> nonlocal) {
|
||||
|
||||
@NotNull Collection<ResolvedCallImpl<D>> allDescriptors,
|
||||
@NotNull DeclarationDescriptor containerOfTheCurrentLocality,
|
||||
@NotNull Collection<ResolvedCallImpl<D>> local,
|
||||
@NotNull Collection<ResolvedCallImpl<D>> nonlocal
|
||||
) {
|
||||
for (ResolvedCallImpl<D> resolvedCall : allDescriptors) {
|
||||
if (DescriptorUtils.isLocal(containerOfTheCurrentLocality, resolvedCall.getCandidateDescriptor())) {
|
||||
local.add(resolvedCall);
|
||||
@@ -56,7 +59,9 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<ResolutionTask<D>> computePrioritizedTasks(@NotNull JetScope scope, @NotNull Call call, @NotNull String name, @NotNull BindingContext bindingContext, @NotNull DataFlowInfo dataFlowInfo) {
|
||||
@NotNull
|
||||
public List<ResolutionTask<D>> computePrioritizedTasks(@NotNull JetScope scope, @NotNull Call call, @NotNull String name,
|
||||
@NotNull BindingContext bindingContext, @NotNull DataFlowInfo dataFlowInfo) {
|
||||
List<ResolutionTask<D>> result = Lists.newArrayList();
|
||||
|
||||
ReceiverDescriptor explicitReceiver = call.getExplicitReceiver();
|
||||
@@ -68,7 +73,7 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private void doComputeTasks(JetScope scope, ReceiverDescriptor receiver, Call call, String name, List<ResolutionTask<D>> result, @NotNull AutoCastService autoCastService) {
|
||||
DataFlowInfo dataFlowInfo = autoCastService.getDataFlowInfo();
|
||||
List<ReceiverDescriptor> implicitReceivers = Lists.newArrayList();
|
||||
|
||||
+2
-15
@@ -50,20 +50,17 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
JetReferenceExpression nameReference = valueArgument.getArgumentName().getReferenceExpression();
|
||||
ValueParameterDescriptor valueParameterDescriptor = parameterByName.get(valueArgument.getArgumentName().getReferenceExpression().getReferencedName());
|
||||
if (valueParameterDescriptor == null) {
|
||||
// temporaryTrace.getErrorHandler().genericError(nameNode, "Cannot find a parameter with this name");
|
||||
temporaryTrace.report(NAMED_PARAMETER_NOT_FOUND.on(nameReference));
|
||||
error = true;
|
||||
}
|
||||
else {
|
||||
if (!usedParameters.add(valueParameterDescriptor)) {
|
||||
// temporaryTrace.getErrorHandler().genericError(nameNode, "An argument is already passed for this parameter");
|
||||
temporaryTrace.report(ARGUMENT_PASSED_TWICE.on(nameReference));
|
||||
}
|
||||
temporaryTrace.record(REFERENCE_TARGET, nameReference, valueParameterDescriptor);
|
||||
put(candidateCall, valueParameterDescriptor, valueArgument, varargs);
|
||||
}
|
||||
if (somePositioned) {
|
||||
// temporaryTrace.getErrorHandler().genericError(nameNode, "Mixing named and positioned arguments in not allowed");
|
||||
temporaryTrace.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(nameReference));
|
||||
error = true;
|
||||
}
|
||||
@@ -71,7 +68,6 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
else {
|
||||
somePositioned = true;
|
||||
if (someNamed) {
|
||||
// temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), "Mixing named and positioned arguments in not allowed");
|
||||
temporaryTrace.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(valueArgument.asElement()));
|
||||
error = true;
|
||||
}
|
||||
@@ -89,13 +85,11 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
usedParameters.add(valueParameterDescriptor);
|
||||
}
|
||||
else {
|
||||
// temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), getTooManyArgumentsMessage(candidate));
|
||||
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate));
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), getTooManyArgumentsMessage(candidate));
|
||||
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate));
|
||||
error = true;
|
||||
}
|
||||
@@ -108,7 +102,6 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
JetExpression possiblyLabeledFunctionLiteral = functionLiteralArguments.get(0);
|
||||
|
||||
if (valueParameters.isEmpty()) {
|
||||
// temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), getTooManyArgumentsMessage(candidate));
|
||||
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(possiblyLabeledFunctionLiteral, candidate));
|
||||
error = true;
|
||||
}
|
||||
@@ -124,13 +117,11 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
|
||||
ValueParameterDescriptor valueParameterDescriptor = valueParameters.get(valueParameters.size() - 1);
|
||||
if (valueParameterDescriptor.getVarargElementType() != null) {
|
||||
// temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), "Passing value as a vararg is only allowed inside a parenthesized argument list");
|
||||
temporaryTrace.report(VARARG_OUTSIDE_PARENTHESES.on(possiblyLabeledFunctionLiteral));
|
||||
error = true;
|
||||
}
|
||||
else {
|
||||
if (!usedParameters.add(valueParameterDescriptor)) {
|
||||
// temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), getTooManyArgumentsMessage(candidate));
|
||||
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(possiblyLabeledFunctionLiteral, candidate));
|
||||
error = true;
|
||||
}
|
||||
@@ -142,7 +133,6 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
|
||||
for (int i = 1; i < functionLiteralArguments.size(); i++) {
|
||||
JetExpression argument = functionLiteralArguments.get(i);
|
||||
// temporaryTrace.getErrorHandler().genericError(argument.getNode(), "Only one function literal is allowed outside a parenthesized argument list");
|
||||
temporaryTrace.report(MANY_FUNCTION_LITERAL_ARGUMENTS.on(argument));
|
||||
error = true;
|
||||
}
|
||||
@@ -176,7 +166,8 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
error = true;
|
||||
}
|
||||
|
||||
assert candidateCall.getThisObject().exists() == candidateCall.getResultingDescriptor().getExpectedThisObject().exists() : "Shouldn't happen because of TaskPrioritizer: " + candidateCall.getCandidateDescriptor();
|
||||
assert candidateCall.getThisObject().exists() == candidateCall.getResultingDescriptor().getExpectedThisObject().exists() :
|
||||
"Shouldn't happen because of TaskPrioritizer: " + candidateCall.getCandidateDescriptor();
|
||||
|
||||
return error;
|
||||
}
|
||||
@@ -196,8 +187,4 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
candidateCall.recordValueArgument(valueParameterDescriptor, argument);
|
||||
}
|
||||
}
|
||||
|
||||
// private static <Descriptor extends CallableDescriptor> String getTooManyArgumentsMessage(Descriptor candidate) {
|
||||
// return "Too many arguments for " + DescriptorRenderer.TEXT.render(candidate);
|
||||
// }
|
||||
}
|
||||
|
||||
+22
@@ -10,6 +10,28 @@ import java.util.Set;
|
||||
*/
|
||||
public interface ConstraintResolutionListener {
|
||||
|
||||
public static final ConstraintResolutionListener DO_NOTHING = new ConstraintResolutionListener() {
|
||||
@Override
|
||||
public void constraintsForUnknown(TypeParameterDescriptor typeParameterDescriptor, ConstraintSystemImpl.TypeValue typeValue) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void constraintsForKnownType(JetType type, ConstraintSystemImpl.TypeValue typeValue) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void done(ConstraintSystemSolution solution, Set<TypeParameterDescriptor> typeParameterDescriptors) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(Object message) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(Object message) {
|
||||
}
|
||||
};
|
||||
|
||||
void constraintsForUnknown(TypeParameterDescriptor typeParameterDescriptor, ConstraintSystemImpl.TypeValue typeValue);
|
||||
void constraintsForKnownType(JetType type, ConstraintSystemImpl.TypeValue typeValue);
|
||||
void done(ConstraintSystemSolution solution, Set<TypeParameterDescriptor> typeParameterDescriptors);
|
||||
|
||||
@@ -51,6 +51,11 @@ public interface JetScope {
|
||||
@Nullable
|
||||
PropertyDescriptor getPropertyByFieldReference(@NotNull String fieldName);
|
||||
|
||||
/**
|
||||
* All visible descriptors from current scope.
|
||||
*
|
||||
* @return All visible descriptors from current scope.
|
||||
*/
|
||||
@NotNull
|
||||
Collection<DeclarationDescriptor> getAllDescriptors();
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.jetbrains.jet.lang.resolve.scopes;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Nikolay Krasko
|
||||
*/
|
||||
public final class JetScopeUtils {
|
||||
private JetScopeUtils() {}
|
||||
|
||||
/**
|
||||
* Get receivers in order of locality, so that the closest (the most local) receiver goes first
|
||||
* A wrapper for {@link JetScope#getImplicitReceiversHierarchy(java.util.List)}
|
||||
*
|
||||
* @param scope Scope for getting receivers hierarchy.
|
||||
* @return receivers hierarchy.
|
||||
*/
|
||||
@NotNull
|
||||
public static Collection<ReceiverDescriptor> getImplicitReceiversHierarchy(@NotNull JetScope scope) {
|
||||
List<ReceiverDescriptor> descriptors = Lists.newArrayList();
|
||||
scope.getImplicitReceiversHierarchy(descriptors);
|
||||
return descriptors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all extension descriptors among visible descriptors for current scope.
|
||||
*
|
||||
* @param scope Scope for query extensions.
|
||||
* @return extension descriptors.
|
||||
*/
|
||||
public static Collection<CallableDescriptor> getAllExtensions(@NotNull JetScope scope) {
|
||||
final Set<CallableDescriptor> result = Sets.newHashSet();
|
||||
|
||||
for (DeclarationDescriptor descriptor : scope.getAllDescriptors()) {
|
||||
if (descriptor instanceof CallableDescriptor) {
|
||||
CallableDescriptor callDescriptor = (CallableDescriptor) descriptor;
|
||||
if (callDescriptor.getReceiverParameter().exists()) {
|
||||
result.add(callDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -12,9 +12,9 @@ import org.jetbrains.jet.lang.resolve.DescriptorResolver;
|
||||
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
||||
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
|
||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
|
||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
@@ -40,7 +40,8 @@ import java.util.Map;
|
||||
@NotNull JetType expectedType,
|
||||
@NotNull JetType expectedReturnType,
|
||||
boolean namespacesAllowed) {
|
||||
return new ExpressionTypingContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, scope, dataFlowInfo, expectedType, expectedReturnType, namespacesAllowed);
|
||||
return new ExpressionTypingContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists,
|
||||
labelResolver, trace, scope, dataFlowInfo, expectedType, expectedReturnType, namespacesAllowed);
|
||||
}
|
||||
|
||||
// @NotNull
|
||||
|
||||
Reference in New Issue
Block a user