KT-1151 Code completion for not imported extension functions - ignore parameters
This commit is contained in:
@@ -25,29 +25,21 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetImportDirective;
|
||||
import org.jetbrains.jet.lang.psi.JetNamespaceHeader;
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintResolutionListener;
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl;
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemSolution;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
||||
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.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.NamespaceType;
|
||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||
import org.jetbrains.jet.lang.types.Variance;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintType.RECEIVER;
|
||||
|
||||
/**
|
||||
* @author Nikolay Krasko, Alefas
|
||||
*/
|
||||
@@ -146,7 +138,9 @@ public final class TipsManager {
|
||||
return false;
|
||||
}
|
||||
for (ReceiverDescriptor receiverDescriptor : result) {
|
||||
if (checkReceiverResolution(receiverDescriptor, callableDescriptor)) return false;
|
||||
if (CallResolver.checkIsExtensionCallable(receiverDescriptor, callableDescriptor)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -183,51 +177,51 @@ public final class TipsManager {
|
||||
new Predicate<CallableDescriptor>() {
|
||||
@Override
|
||||
public boolean apply(CallableDescriptor callableDescriptor) {
|
||||
return checkReceiverResolution(receiverDescriptor, callableDescriptor);
|
||||
return CallResolver.checkIsExtensionCallable(receiverDescriptor, callableDescriptor);
|
||||
}
|
||||
}));
|
||||
|
||||
return descriptorsSet;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if receiver declaration could be resolved to call expected receiver.
|
||||
*/
|
||||
private static boolean checkReceiverResolution (
|
||||
@NotNull ReceiverDescriptor expectedReceiver,
|
||||
@NotNull CallableDescriptor receiverArgument
|
||||
) {
|
||||
JetType type = expectedReceiver.getType();
|
||||
if (checkReceiverResolution(expectedReceiver, type, receiverArgument)) return true;
|
||||
if (type.isNullable()) {
|
||||
JetType notNullableType = TypeUtils.makeNotNullable(type);
|
||||
if (checkReceiverResolution(expectedReceiver, notNullableType, receiverArgument)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean checkReceiverResolution (
|
||||
@NotNull ReceiverDescriptor expectedReceiver,
|
||||
@NotNull JetType receiverType,
|
||||
@NotNull CallableDescriptor receiverArgument
|
||||
) {
|
||||
ConstraintSystem constraintSystem = new ConstraintSystemImpl(ConstraintResolutionListener.DO_NOTHING);
|
||||
for (TypeParameterDescriptor typeParameterDescriptor : receiverArgument.getTypeParameters()) {
|
||||
constraintSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT);
|
||||
}
|
||||
|
||||
ReceiverDescriptor receiverParameter = receiverArgument.getReceiverParameter();
|
||||
if (expectedReceiver.exists() && receiverParameter.exists()) {
|
||||
constraintSystem.addSubtypingConstraint(
|
||||
RECEIVER.assertSubtyping(receiverType, receiverParameter.getType()));
|
||||
}
|
||||
else if (expectedReceiver.exists() || receiverParameter.exists()) {
|
||||
// Only one of receivers exist
|
||||
return false;
|
||||
}
|
||||
|
||||
ConstraintSystemSolution solution = constraintSystem.solve();
|
||||
return solution.getStatus().isSuccessful();
|
||||
}
|
||||
// /*
|
||||
// * Checks if receiver declaration could be resolved to call expected receiver.
|
||||
// */
|
||||
// private static boolean checkReceiverResolution (
|
||||
// @NotNull ReceiverDescriptor expectedReceiver,
|
||||
// @NotNull CallableDescriptor receiverArgument
|
||||
// ) {
|
||||
// JetType type = expectedReceiver.getType();
|
||||
// if (checkReceiverResolution(expectedReceiver, type, receiverArgument)) return true;
|
||||
// if (type.isNullable()) {
|
||||
// JetType notNullableType = TypeUtils.makeNotNullable(type);
|
||||
// if (checkReceiverResolution(expectedReceiver, notNullableType, receiverArgument)) return true;
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// private static boolean checkReceiverResolution (
|
||||
// @NotNull ReceiverDescriptor expectedReceiver,
|
||||
// @NotNull JetType receiverType,
|
||||
// @NotNull CallableDescriptor receiverArgument
|
||||
// ) {
|
||||
// ConstraintSystem constraintSystem = new ConstraintSystemImpl(ConstraintResolutionListener.DO_NOTHING);
|
||||
// for (TypeParameterDescriptor typeParameterDescriptor : receiverArgument.getTypeParameters()) {
|
||||
// constraintSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT);
|
||||
// }
|
||||
//
|
||||
// ReceiverDescriptor receiverParameter = receiverArgument.getReceiverParameter();
|
||||
// if (expectedReceiver.exists() && receiverParameter.exists()) {
|
||||
// constraintSystem.addSubtypingConstraint(
|
||||
// RECEIVER.assertSubtyping(receiverType, receiverParameter.getType()));
|
||||
// }
|
||||
// else if (expectedReceiver.exists() || receiverParameter.exists()) {
|
||||
// // Only one of receivers exist
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// ConstraintSystemSolution solution = constraintSystem.solve();
|
||||
// return solution.getStatus().isSuccessful();
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -140,7 +140,9 @@ public class CallMaker {
|
||||
}
|
||||
}
|
||||
|
||||
public static Call makeCallWithExpressions(@NotNull JetElement callElement, @NotNull ReceiverDescriptor explicitReceiver, @Nullable ASTNode callOperationNode, @NotNull JetExpression calleeExpression, @NotNull List<JetExpression> argumentExpressions) {
|
||||
public static Call makeCallWithExpressions(@NotNull JetElement callElement, @NotNull ReceiverDescriptor explicitReceiver,
|
||||
@Nullable ASTNode callOperationNode, @NotNull JetExpression calleeExpression,
|
||||
@NotNull List<JetExpression> argumentExpressions) {
|
||||
List<ValueArgument> arguments = Lists.newArrayList();
|
||||
for (JetExpression argumentExpression : argumentExpressions) {
|
||||
arguments.add(makeValueArgument(argumentExpression, calleeExpression));
|
||||
|
||||
@@ -113,6 +113,39 @@ public class CallResolver {
|
||||
return doResolveCall(trace, scope, call, expectedType, tasks, functionReference);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all function from the given scope with the given name and check is they could be satisfied for call on given
|
||||
* receiver.
|
||||
*
|
||||
* @param trace
|
||||
* @param scope
|
||||
* @param call
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public List<FunctionDescriptor> resolveCallsByReceiver(
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull JetScope scope,
|
||||
@NotNull final Call call,
|
||||
@NotNull String name) {
|
||||
|
||||
List<ResolutionTask<FunctionDescriptor>> tasks = TaskPrioritizers.FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks(
|
||||
scope, call, name, trace.getBindingContext(), dataFlowInfo);
|
||||
|
||||
ArrayList<FunctionDescriptor> functionDescriptors = new ArrayList<FunctionDescriptor>();
|
||||
|
||||
for (ResolutionTask<FunctionDescriptor> task : tasks) {
|
||||
Collection<ResolvedCallImpl<FunctionDescriptor>> candidates = task.getCandidates();
|
||||
for (ResolvedCallImpl<FunctionDescriptor> candidate : candidates) {
|
||||
if (checkIsExtensionCallable(call.getExplicitReceiver(), candidate.getCandidateDescriptor())) {
|
||||
functionDescriptors.add(candidate.getCandidateDescriptor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return functionDescriptors;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private OverloadResolutionResults<FunctionDescriptor> resolveSimpleCallToFunctionDescriptor(
|
||||
@NotNull BindingTrace trace,
|
||||
@@ -366,7 +399,11 @@ public class CallResolver {
|
||||
if (callElement instanceof JetBinaryExpression) {
|
||||
JetBinaryExpression binaryExpression = (JetBinaryExpression) callElement;
|
||||
JetSimpleNameExpression operationReference = binaryExpression.getOperationReference();
|
||||
String operationString = operationReference.getReferencedNameElementType() == JetTokens.IDENTIFIER ? operationReference.getText() : OperatorConventions.getNameForOperationSymbol((JetToken) operationReference.getReferencedNameElementType());
|
||||
|
||||
String operationString = operationReference.getReferencedNameElementType() == JetTokens.IDENTIFIER ?
|
||||
operationReference.getText() :
|
||||
OperatorConventions.getNameForOperationSymbol((JetToken) operationReference.getReferencedNameElementType());
|
||||
|
||||
JetExpression right = binaryExpression.getRight();
|
||||
if (right != null) {
|
||||
trace.report(UNSAFE_INFIX_CALL.on(reference, binaryExpression.getLeft().getText(), operationString, right.getText()));
|
||||
@@ -433,6 +470,7 @@ public class CallResolver {
|
||||
@NotNull ResolutionTask<D> task, @NotNull TracingStrategy tracing
|
||||
) {
|
||||
OverloadResolutionResultsImpl<D> results = performResolution(trace, scope, expectedType, task, tracing);
|
||||
|
||||
// If resolution fails, we should check for some of the following situations:
|
||||
// class A {
|
||||
// val foo = Bar() // The following is intended to be an anonymous initializer,
|
||||
@@ -448,7 +486,8 @@ public class CallResolver {
|
||||
// {...} // intended to be a returned from the outer literal
|
||||
// }
|
||||
// }
|
||||
EnumSet<OverloadResolutionResults.Code> someFailed = EnumSet.of(OverloadResolutionResults.Code.MANY_FAILED_CANDIDATES, OverloadResolutionResults.Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH);
|
||||
EnumSet<OverloadResolutionResults.Code> someFailed = EnumSet.of(OverloadResolutionResults.Code.MANY_FAILED_CANDIDATES,
|
||||
OverloadResolutionResults.Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH);
|
||||
if (someFailed.contains(results.getResultCode()) && !task.getCall().getFunctionLiteralArguments().isEmpty()) {
|
||||
// We have some candidates that failed for some reason
|
||||
// And we have a suspect: the function literal argument
|
||||
@@ -658,7 +697,7 @@ public class CallResolver {
|
||||
return results;
|
||||
}
|
||||
|
||||
private JetType getEffectiveExpectedType(ValueParameterDescriptor valueParameterDescriptor) {
|
||||
private static JetType getEffectiveExpectedType(ValueParameterDescriptor valueParameterDescriptor) {
|
||||
JetType effectiveExpectedType = valueParameterDescriptor.getVarargElementType();
|
||||
if (effectiveExpectedType == null) {
|
||||
effectiveExpectedType = valueParameterDescriptor.getType();
|
||||
@@ -666,7 +705,7 @@ public class CallResolver {
|
||||
return effectiveExpectedType;
|
||||
}
|
||||
|
||||
private void recordAutoCastIfNecessary(ReceiverDescriptor receiver, BindingTrace trace) {
|
||||
private static void recordAutoCastIfNecessary(ReceiverDescriptor receiver, BindingTrace trace) {
|
||||
if (receiver instanceof AutoCastReceiver) {
|
||||
AutoCastReceiver autoCastReceiver = (AutoCastReceiver) receiver;
|
||||
ReceiverDescriptor original = autoCastReceiver.getOriginal();
|
||||
@@ -703,7 +742,9 @@ public class CallResolver {
|
||||
}
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> void replaceValueParametersWithSubstitutedOnes(ResolvedCallImpl<D> candidateCall, @NotNull D substitutedDescriptor) {
|
||||
private static <D extends CallableDescriptor> void replaceValueParametersWithSubstitutedOnes(
|
||||
ResolvedCallImpl<D> candidateCall, @NotNull D substitutedDescriptor) {
|
||||
|
||||
Map<ValueParameterDescriptor, ValueParameterDescriptor> parameterMap = Maps.newHashMap();
|
||||
for (ValueParameterDescriptor valueParameterDescriptor : substitutedDescriptor.getValueParameters()) {
|
||||
parameterMap.put(valueParameterDescriptor.getOriginal(), valueParameterDescriptor);
|
||||
@@ -726,7 +767,9 @@ public class CallResolver {
|
||||
return result;
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> ResolutionStatus checkReceiver(TracingStrategy tracing, ResolvedCallImpl<D> candidateCall, ReceiverDescriptor receiverParameter, ReceiverDescriptor receiverArgument, ResolutionTask<D> task) {
|
||||
private <D extends CallableDescriptor> ResolutionStatus checkReceiver(TracingStrategy tracing, ResolvedCallImpl<D> candidateCall,
|
||||
ReceiverDescriptor receiverParameter, ReceiverDescriptor receiverArgument,
|
||||
ResolutionTask<D> task) {
|
||||
ResolutionStatus result = SUCCESS;
|
||||
if (receiverParameter.exists() && receiverArgument.exists()) {
|
||||
ASTNode callOperationNode = task.getCall().getCallOperationNode();
|
||||
@@ -841,6 +884,7 @@ public class CallResolver {
|
||||
return OverloadResolutionResultsImpl.manyFailedCandidates(results.getResultingCalls());
|
||||
}
|
||||
}
|
||||
|
||||
assert false : "Should not be reachable, cause every status must belong to some level";
|
||||
|
||||
Set<ResolvedCallImpl<D>> noOverrides = OverridingUtil.filterOverrides(failedCandidates, MAP_TO_CANDIDATE);
|
||||
@@ -849,8 +893,10 @@ public class CallResolver {
|
||||
tracing.recordAmbiguity(trace, noOverrides);
|
||||
return OverloadResolutionResultsImpl.manyFailedCandidates(noOverrides);
|
||||
}
|
||||
|
||||
failedCandidates = noOverrides;
|
||||
}
|
||||
|
||||
ResolvedCallImpl<D> failed = failedCandidates.iterator().next();
|
||||
failed.getTrace().commit();
|
||||
return OverloadResolutionResultsImpl.singleFailedCandidate(failed);
|
||||
@@ -861,7 +907,7 @@ public class CallResolver {
|
||||
}
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> boolean allClean(Collection<ResolvedCallImpl<D>> results) {
|
||||
private static <D extends CallableDescriptor> boolean allClean(Collection<ResolvedCallImpl<D>> results) {
|
||||
for (ResolvedCallImpl<D> result : results) {
|
||||
if (result.isDirty()) return false;
|
||||
}
|
||||
@@ -939,7 +985,8 @@ public class CallResolver {
|
||||
return computeResultAndReportErrors(trace, TracingStrategy.EMPTY, candidates, Collections.<ResolvedCallImpl<FunctionDescriptor>>emptySet());
|
||||
}
|
||||
|
||||
private List<ResolvedCallImpl<FunctionDescriptor>> findCandidatesByExactSignature(JetScope scope, ReceiverDescriptor receiver, String name, List<JetType> parameterTypes) {
|
||||
private List<ResolvedCallImpl<FunctionDescriptor>> findCandidatesByExactSignature(JetScope scope, ReceiverDescriptor receiver,
|
||||
String name, List<JetType> parameterTypes) {
|
||||
List<ResolvedCallImpl<FunctionDescriptor>> result = Lists.newArrayList();
|
||||
if (receiver.exists()) {
|
||||
Collection<ResolvedCallImpl<FunctionDescriptor>> extensionFunctionDescriptors = ResolvedCallImpl.convertCollection(scope.getFunctions(name));
|
||||
@@ -966,7 +1013,8 @@ public class CallResolver {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean lookupExactSignature(Collection<ResolvedCallImpl<FunctionDescriptor>> candidates, List<JetType> parameterTypes, List<ResolvedCallImpl<FunctionDescriptor>> result) {
|
||||
private static boolean lookupExactSignature(Collection<ResolvedCallImpl<FunctionDescriptor>> candidates, List<JetType> parameterTypes,
|
||||
List<ResolvedCallImpl<FunctionDescriptor>> result) {
|
||||
boolean found = false;
|
||||
for (ResolvedCallImpl<FunctionDescriptor> resolvedCall : candidates) {
|
||||
FunctionDescriptor functionDescriptor = resolvedCall.getResultingDescriptor();
|
||||
@@ -979,7 +1027,8 @@ 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<ResolvedCallImpl<FunctionDescriptor>> candidates, ReceiverDescriptor receiver,
|
||||
List<JetType> parameterTypes, List<ResolvedCallImpl<FunctionDescriptor>> result) {
|
||||
boolean found = false;
|
||||
for (ResolvedCallImpl<FunctionDescriptor> resolvedCall : candidates) {
|
||||
FunctionDescriptor functionDescriptor = resolvedCall.getResultingDescriptor();
|
||||
@@ -994,7 +1043,7 @@ public class CallResolver {
|
||||
return found;
|
||||
}
|
||||
|
||||
private boolean checkValueParameters(@NotNull FunctionDescriptor functionDescriptor, @NotNull List<JetType> parameterTypes) {
|
||||
private static boolean checkValueParameters(@NotNull FunctionDescriptor functionDescriptor, @NotNull List<JetType> parameterTypes) {
|
||||
List<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters();
|
||||
if (valueParameters.size() != parameterTypes.size()) return false;
|
||||
for (int i = 0; i < valueParameters.size(); i++) {
|
||||
@@ -1004,4 +1053,44 @@ public class CallResolver {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if receiver declaration could be resolved to call expected receiver.
|
||||
*/
|
||||
public static boolean checkIsExtensionCallable (
|
||||
@NotNull ReceiverDescriptor expectedReceiver,
|
||||
@NotNull CallableDescriptor receiverArgument
|
||||
) {
|
||||
JetType type = expectedReceiver.getType();
|
||||
if (checkReceiverResolution(expectedReceiver, type, receiverArgument)) return true;
|
||||
if (type.isNullable()) {
|
||||
JetType notNullableType = TypeUtils.makeNotNullable(type);
|
||||
if (checkReceiverResolution(expectedReceiver, notNullableType, receiverArgument)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean checkReceiverResolution (
|
||||
@NotNull ReceiverDescriptor expectedReceiver,
|
||||
@NotNull JetType receiverType,
|
||||
@NotNull CallableDescriptor receiverArgument
|
||||
) {
|
||||
ConstraintSystem constraintSystem = new ConstraintSystemImpl(ConstraintResolutionListener.DO_NOTHING);
|
||||
for (TypeParameterDescriptor typeParameterDescriptor : receiverArgument.getTypeParameters()) {
|
||||
constraintSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT);
|
||||
}
|
||||
|
||||
ReceiverDescriptor receiverParameter = receiverArgument.getReceiverParameter();
|
||||
if (expectedReceiver.exists() && receiverParameter.exists()) {
|
||||
constraintSystem.addSubtypingConstraint(
|
||||
RECEIVER.assertSubtyping(receiverType, receiverParameter.getType()));
|
||||
}
|
||||
else if (expectedReceiver.exists() || receiverParameter.exists()) {
|
||||
// Only one of receivers exist
|
||||
return false;
|
||||
}
|
||||
|
||||
ConstraintSystemSolution solution = constraintSystem.solve();
|
||||
return solution.getStatus().isSuccessful();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,8 +84,8 @@ public class DelegatingCall implements Call {
|
||||
return delegate.getTypeArgumentList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@Nullable
|
||||
public PsiElement getCallElement() {
|
||||
return delegate.getCallElement();
|
||||
}
|
||||
|
||||
+1
-1
@@ -168,7 +168,7 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
candidateCall.recordValueArgument(valueParameter, new VarargValueArgument());
|
||||
}
|
||||
else {
|
||||
// tracing.reportWrongValueArguments(temporaryTrace, "No value passed for parameter " + valueParameter.getName());
|
||||
// tracing.reportWrongValueArguments(temporaryTrace, "No value passed for parameter " + valueParameter.getName());
|
||||
tracing.noValueForParameter(temporaryTrace, valueParameter);
|
||||
error = true;
|
||||
}
|
||||
|
||||
+3
-1
@@ -22,6 +22,8 @@ import org.jetbrains.jet.lang.types.JetType;
|
||||
import java.text.MessageFormat;
|
||||
|
||||
/**
|
||||
* A specific type for subtype constraint of types.
|
||||
*
|
||||
* @author abreslav
|
||||
*/
|
||||
public enum ConstraintType implements Comparable<ConstraintType> {
|
||||
@@ -33,7 +35,7 @@ public enum ConstraintType implements Comparable<ConstraintType> {
|
||||
EXPECTED_TYPE("Resulting type is {0} but {1} was expected"),
|
||||
PARAMETER_BOUND("Type parameter bound is not satisfied: {0} is not a subtype of {1}");
|
||||
|
||||
private final String errorMessageTemplate; // {0} is subtype, {1} is supertye
|
||||
private final String errorMessageTemplate; // {0} is subtype, {1} is supertype
|
||||
|
||||
private ConstraintType(@NotNull String errorMessageTemplate) {
|
||||
this.errorMessageTemplate = errorMessageTemplate;
|
||||
|
||||
+10
-1
@@ -347,13 +347,22 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static OverloadResolutionResults<FunctionDescriptor> resolveFakeCall(ExpressionReceiver receiver, ExpressionTypingContext context, String name) {
|
||||
public static OverloadResolutionResults<FunctionDescriptor> resolveFakeCall(ExpressionReceiver receiver,
|
||||
ExpressionTypingContext context, String name) {
|
||||
JetReferenceExpression fake = JetPsiFactory.createSimpleName(context.getProject(), "fake");
|
||||
BindingTrace fakeTrace = new BindingTraceContext();
|
||||
Call call = CallMaker.makeCall(fake, receiver, null, fake, Collections.<ValueArgument>emptyList());
|
||||
return context.replaceBindingTrace(fakeTrace).resolveCallWithGivenName(call, fake, name);
|
||||
}
|
||||
|
||||
public static List<FunctionDescriptor> resolveFakeCallWithReceiverOnly(ExpressionReceiver receiver,
|
||||
ExpressionTypingContext context, String name) {
|
||||
JetReferenceExpression fake = JetPsiFactory.createSimpleName(context.getProject(), "fake");
|
||||
BindingTrace fakeTrace = new BindingTraceContext();
|
||||
Call call = CallMaker.makeCall(fake, receiver, null, fake, Collections.<ValueArgument>emptyList());
|
||||
return context.replaceBindingTrace(fakeTrace).resolveForReceiverOnly(call, fake, name);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static FunctionDescriptor checkHasNextFunctionSupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, ExpressionTypingContext context) {
|
||||
OverloadResolutionResults<FunctionDescriptor> hasNextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "hasNext", Collections.<JetType>emptyList());
|
||||
|
||||
@@ -42,6 +42,9 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.AUTOCAST;
|
||||
* @author abreslav
|
||||
*/
|
||||
public class DataFlowUtils {
|
||||
private DataFlowUtils() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static DataFlowInfo extractDataFlowInfoFromCondition(@Nullable JetExpression condition, final boolean conditionValue, @Nullable final WritableScope scopeToExtend, final ExpressionTypingContext context) {
|
||||
if (condition == null) return context.dataFlowInfo;
|
||||
|
||||
+6
@@ -204,6 +204,12 @@ import java.util.Map;
|
||||
// return results == null ? null : results.getResultingDescriptor();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<FunctionDescriptor> resolveForReceiverOnly(@NotNull Call call, @NotNull JetReferenceExpression functionReference, @NotNull String name) {
|
||||
return getCallResolver().resolveCallsByReceiver(trace, scope, call, name);
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public FunctionDescriptor resolveCall(@NotNull ReceiverDescriptor receiver, @Nullable ASTNode callOperationNode, @NotNull JetCallExpression callExpression) {
|
||||
OverloadResolutionResults<FunctionDescriptor> results = getCallResolver().resolveCall(trace, scope, CallMaker.makeCall(receiver, callOperationNode, callExpression), expectedType);
|
||||
|
||||
+21
-20
@@ -29,8 +29,6 @@ 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.*;
|
||||
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.scopes.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||
@@ -39,7 +37,6 @@ import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||
import org.jetbrains.jet.util.QualifiedNamesUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
@@ -167,15 +164,15 @@ public class ExpressionTypingUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that function with the given qualified name can be resolved in given scope for given receiver
|
||||
* Check that function or property with the given qualified name can be resolved in given scope for given receiver
|
||||
*
|
||||
* @param functionFQN
|
||||
* @param callableFQN
|
||||
* @param project
|
||||
* @param scope
|
||||
* @return
|
||||
*/
|
||||
public static ArrayList<FunctionDescriptor> canCallBeResolved(
|
||||
@NotNull String functionFQN,
|
||||
public static List<FunctionDescriptor> canFindSuitableCall(
|
||||
@NotNull String callableFQN,
|
||||
@NotNull Project project,
|
||||
@NotNull JetExpression receiverExpression,
|
||||
@NotNull JetType receiverType,
|
||||
@@ -184,7 +181,7 @@ public class ExpressionTypingUtils {
|
||||
WritableScopeWithImports writableScopeWithImports = new WritableScopeImpl(
|
||||
scope, scope.getContainingDeclaration(), RedeclarationHandler.DO_NOTHING);
|
||||
|
||||
JetImportDirective importDirective = JetPsiFactory.createImportDirective(project, functionFQN);
|
||||
JetImportDirective importDirective = JetPsiFactory.createImportDirective(project, callableFQN);
|
||||
|
||||
ExpressionReceiver expressionReceiver = new ExpressionReceiver(receiverExpression, receiverType);
|
||||
|
||||
@@ -209,19 +206,23 @@ public class ExpressionTypingUtils {
|
||||
|
||||
writableScopeWithImports.changeLockLevel(WritableScope.LockLevel.READING);
|
||||
|
||||
OverloadResolutionResults<FunctionDescriptor> resolutionResult =
|
||||
ControlStructureTypingVisitor.resolveFakeCall(expressionReceiver, context, QualifiedNamesUtil.fqnToShortName(functionFQN));
|
||||
return ControlStructureTypingVisitor.resolveFakeCallWithReceiverOnly(expressionReceiver, context, QualifiedNamesUtil.fqnToShortName(callableFQN));
|
||||
|
||||
if (!resolutionResult.isSuccess()) {
|
||||
return new ArrayList<FunctionDescriptor>();
|
||||
}
|
||||
|
||||
ArrayList<FunctionDescriptor> resolvedDescriptors = new ArrayList<FunctionDescriptor>();
|
||||
|
||||
for (ResolvedCall<? extends FunctionDescriptor> resolvedCall : resolutionResult.getResultingCalls()) {
|
||||
resolvedDescriptors.add(resolvedCall.getCandidateDescriptor());
|
||||
}
|
||||
|
||||
return resolvedDescriptors;
|
||||
// OverloadResolutionResults.Code resultCode = resolutionResult.getResultCode();
|
||||
// if (resultCode == OverloadResolutionResults.Code.SUCCESS ||
|
||||
// resultCode == OverloadResolutionResults.Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH ||
|
||||
// resultCode == OverloadResolutionResults.Code.MANY_FAILED_CANDIDATES) {
|
||||
//
|
||||
// ArrayList<FunctionDescriptor> resolvedDescriptors = new ArrayList<FunctionDescriptor>();
|
||||
//
|
||||
// for (ResolvedCall<? extends FunctionDescriptor> resolvedCall : resolutionResult.getResultingCalls()) {
|
||||
// resolvedDescriptors.add(resolvedCall.getCandidateDescriptor());
|
||||
// }
|
||||
//
|
||||
// return resolvedDescriptors;
|
||||
// }
|
||||
//
|
||||
// return new ArrayList<FunctionDescriptor>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ public class JetCompletionContributor extends CompletionContributor {
|
||||
for (String functionFQN : functionFQNs) {
|
||||
// System.out.println(functionFQN);
|
||||
|
||||
List<FunctionDescriptor> functionDescriptors = ExpressionTypingUtils.canCallBeResolved(
|
||||
List<FunctionDescriptor> functionDescriptors = ExpressionTypingUtils.canFindSuitableCall(
|
||||
functionFQN, position.getProject(), receiverExpression, expressionType, scope);
|
||||
|
||||
// System.out.println(!functionDescriptors.isEmpty());
|
||||
|
||||
@@ -7,4 +7,5 @@ fun firstFun() {
|
||||
|
||||
// EXIST: helloFun
|
||||
// EXIST: helloFunPreventAutoInsert
|
||||
// NUMBER: 2
|
||||
// EXIST: helloWithParams
|
||||
// NUMBER: 3
|
||||
@@ -3,5 +3,9 @@ package second
|
||||
fun String.helloFun() {
|
||||
}
|
||||
|
||||
fun String.helloWithParams(i : Int) : String {
|
||||
return ""
|
||||
}
|
||||
|
||||
fun String.helloFunPreventAutoInsert() {
|
||||
}
|
||||
Reference in New Issue
Block a user