提交 67dc9ba6 编写于 作者: N Nikolay Krasko

KT-1151 Code completion for not imported extension functions - ignore parameters

上级 0a669b9c
......@@ -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();
}
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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;
......
......@@ -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);
......
......@@ -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));
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;
return ControlStructureTypingVisitor.resolveFakeCallWithReceiverOnly(expressionReceiver, context, QualifiedNamesUtil.fqnToShortName(callableFQN));
// 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
\ No newline at end of file
// EXIST: helloWithParams
// NUMBER: 3
\ No newline at end of file
......@@ -3,5 +3,9 @@ package second
fun String.helloFun() {
}
fun String.helloWithParams(i : Int) : String {
return ""
}
fun String.helloFunPreventAutoInsert() {
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册