Skip to content

Commit 12fd864

Browse files
authored
Merge pull request swiftlang#30136 from rintaro/ide-completion-rdar59285399
[CodeCompletion] Primarily use getPossibleCallees() for calling signature completion
2 parents d47b802 + 78d0f6a commit 12fd864

8 files changed

+132
-73
lines changed

lib/IDE/CodeCompletion.cpp

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2399,8 +2399,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
23992399
return SemanticContextKind::OtherModule;
24002400
}
24012401

2402-
void addSubscriptCallPattern(const AnyFunctionType *AFT,
2403-
const SubscriptDecl *SD) {
2402+
void addSubscriptCallPattern(
2403+
const AnyFunctionType *AFT, const SubscriptDecl *SD,
2404+
const Optional<SemanticContextKind> SemanticContext = None) {
24042405
foundFunction(AFT);
24052406
auto genericSig =
24062407
SD->getInnermostDeclContext()->getGenericSignatureOfContext();
@@ -2410,7 +2411,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
24102411
CommandWordsPairs Pairs;
24112412
CodeCompletionResultBuilder Builder(
24122413
Sink, CodeCompletionResult::ResultKind::Declaration,
2413-
getSemanticContextKind(SD), expectedTypeContext);
2414+
SemanticContext ? *SemanticContext : getSemanticContextKind(SD),
2415+
expectedTypeContext);
24142416
Builder.setAssociatedDecl(SD);
24152417
setClangDeclKeywords(SD, Pairs, Builder);
24162418
if (!HaveLParen)
@@ -2429,8 +2431,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
24292431
addTypeAnnotation(Builder, AFT->getResult());
24302432
}
24312433

2432-
void addFunctionCallPattern(const AnyFunctionType *AFT,
2433-
const AbstractFunctionDecl *AFD = nullptr) {
2434+
void addFunctionCallPattern(
2435+
const AnyFunctionType *AFT, const AbstractFunctionDecl *AFD = nullptr,
2436+
const Optional<SemanticContextKind> SemanticContext = None) {
24342437
if (AFD) {
24352438
auto genericSig =
24362439
AFD->getInnermostDeclContext()->getGenericSignatureOfContext();
@@ -2446,7 +2449,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
24462449
Sink,
24472450
AFD ? CodeCompletionResult::ResultKind::Declaration
24482451
: CodeCompletionResult::ResultKind::Pattern,
2449-
getSemanticContextKind(AFD), expectedTypeContext);
2452+
SemanticContext ? *SemanticContext : getSemanticContextKind(AFD),
2453+
expectedTypeContext);
24502454
if (AFD) {
24512455
Builder.setAssociatedDecl(AFD);
24522456
setClangDeclKeywords(AFD, Pairs, Builder);
@@ -3243,11 +3247,11 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
32433247
return true;
32443248
}
32453249

3246-
bool tryFunctionCallCompletions(Type ExprType, const ValueDecl *VD) {
3250+
bool tryFunctionCallCompletions(Type ExprType, const ValueDecl *VD, Optional<SemanticContextKind> SemanticContext = None) {
32473251
ExprType = ExprType->getRValueType();
32483252
if (auto AFT = ExprType->getAs<AnyFunctionType>()) {
32493253
if (auto *AFD = dyn_cast_or_null<AbstractFunctionDecl>(VD)) {
3250-
addFunctionCallPattern(AFT, AFD);
3254+
addFunctionCallPattern(AFT, AFD, SemanticContext);
32513255
} else {
32523256
addFunctionCallPattern(AFT);
32533257
}
@@ -5407,12 +5411,13 @@ void CodeCompletionCallbacksImpl::doneParsing() {
54075411
ExprContextInfo ParentContextInfo(CurDeclContext, ParsedExpr);
54085412
Lookup.setExpectedTypes(ParentContextInfo.getPossibleTypes(),
54095413
ParentContextInfo.isSingleExpressionBody());
5410-
if (ExprType && ((*ExprType)->is<AnyFunctionType>() ||
5411-
(*ExprType)->is<AnyMetatypeType>())) {
5412-
Lookup.getValueExprCompletions(*ExprType, ReferencedDecl.getDecl());
5413-
} else {
5414+
if (!ContextInfo.getPossibleCallees().empty()) {
54145415
for (auto &typeAndDecl : ContextInfo.getPossibleCallees())
5415-
Lookup.tryFunctionCallCompletions(typeAndDecl.first, typeAndDecl.second);
5416+
Lookup.tryFunctionCallCompletions(typeAndDecl.Type, typeAndDecl.Decl,
5417+
typeAndDecl.SemanticContext);
5418+
} else if (ExprType && ((*ExprType)->is<AnyFunctionType>() ||
5419+
(*ExprType)->is<AnyMetatypeType>())) {
5420+
Lookup.getValueExprCompletions(*ExprType, ReferencedDecl.getDecl());
54165421
}
54175422
} else {
54185423
// Add argument labels, then fallthrough to get values.
@@ -5538,12 +5543,14 @@ void CodeCompletionCallbacksImpl::doneParsing() {
55385543
!ContextInfo.getPossibleCallees().empty()) {
55395544
Lookup.setHaveLParen(true);
55405545
for (auto &typeAndDecl : ContextInfo.getPossibleCallees()) {
5541-
if (auto SD = dyn_cast_or_null<SubscriptDecl>(typeAndDecl.second)) {
5542-
Lookup.addSubscriptCallPattern(typeAndDecl.first, SD);
5546+
if (auto SD = dyn_cast_or_null<SubscriptDecl>(typeAndDecl.Decl)) {
5547+
Lookup.addSubscriptCallPattern(typeAndDecl.Type, SD,
5548+
typeAndDecl.SemanticContext);
55435549
} else {
55445550
Lookup.addFunctionCallPattern(
5545-
typeAndDecl.first,
5546-
dyn_cast_or_null<AbstractFunctionDecl>(typeAndDecl.second));
5551+
typeAndDecl.Type,
5552+
dyn_cast_or_null<AbstractFunctionDecl>(typeAndDecl.Decl),
5553+
typeAndDecl.SemanticContext);
55475554
}
55485555
}
55495556
Lookup.setHaveLParen(false);

lib/IDE/ExprContextAnalysis.cpp

Lines changed: 72 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "swift/AST/Type.h"
2828
#include "swift/AST/Types.h"
2929
#include "swift/Basic/SourceManager.h"
30+
#include "swift/IDE/CodeCompletion.h"
3031
#include "swift/Sema/IDETypeChecking.h"
3132
#include "clang/AST/Attr.h"
3233
#include "clang/AST/Decl.h"
@@ -279,19 +280,21 @@ static void collectPossibleCalleesByQualifiedLookup(
279280
DeclContext &DC, Type baseTy, DeclNameRef name,
280281
SmallVectorImpl<FunctionTypeAndDecl> &candidates) {
281282
bool isOnMetaType = baseTy->is<AnyMetatypeType>();
283+
auto baseInstanceTy = baseTy->getMetatypeInstanceType();
282284

283285
SmallVector<ValueDecl *, 2> decls;
284-
if (!DC.lookupQualified(baseTy->getMetatypeInstanceType(),
286+
if (!DC.lookupQualified(baseInstanceTy,
285287
name.withoutArgumentLabels(),
286288
NL_QualifiedDefault | NL_ProtocolMembers,
287289
decls))
288290
return;
289291

292+
auto *baseNominal = baseInstanceTy->getAnyNominal();
290293
for (auto *VD : decls) {
291294
if ((!isa<AbstractFunctionDecl>(VD) && !isa<SubscriptDecl>(VD)) ||
292295
VD->shouldHideFromEditor())
293296
continue;
294-
if (!isMemberDeclApplied(&DC, baseTy->getMetatypeInstanceType(), VD))
297+
if (!isMemberDeclApplied(&DC, baseInstanceTy, VD))
295298
continue;
296299
Type declaredMemberType = VD->getInterfaceType();
297300
if (!declaredMemberType->is<AnyFunctionType>())
@@ -314,16 +317,15 @@ static void collectPossibleCalleesByQualifiedLookup(
314317
}
315318
}
316319

317-
auto subs = baseTy->getMetatypeInstanceType()->getMemberSubstitutionMap(
320+
auto subs = baseInstanceTy->getMemberSubstitutionMap(
318321
DC.getParentModule(), VD,
319322
VD->getInnermostDeclContext()->getGenericEnvironmentOfContext());
320323
auto fnType = declaredMemberType.subst(subs);
321324
if (!fnType)
322325
continue;
323326

324327
if (fnType->is<AnyFunctionType>()) {
325-
auto baseInstanceTy = baseTy->getMetatypeInstanceType();
326-
// If we are calling to typealias type,
328+
// If we are calling to typealias type,
327329
if (isa<SugarType>(baseInstanceTy.getPointer())) {
328330
auto canBaseTy = baseInstanceTy->getCanonicalType();
329331
fnType = fnType.transform([&](Type t) -> Type {
@@ -332,7 +334,13 @@ static void collectPossibleCalleesByQualifiedLookup(
332334
return t;
333335
});
334336
}
335-
candidates.emplace_back(fnType->castTo<AnyFunctionType>(), VD);
337+
auto semanticContext = SemanticContextKind::CurrentNominal;
338+
if (baseNominal &&
339+
VD->getDeclContext()->getSelfNominalTypeDecl() != baseNominal)
340+
semanticContext = SemanticContextKind::Super;
341+
342+
candidates.emplace_back(fnType->castTo<AnyFunctionType>(), VD,
343+
semanticContext);
336344
}
337345
}
338346
}
@@ -347,10 +355,16 @@ static void collectPossibleCalleesByQualifiedLookup(
347355
DC.getASTContext(), &DC, CompletionTypeCheckKind::Normal, baseExpr, ref);
348356
if (!baseTyOpt)
349357
return;
350-
auto baseTy = (*baseTyOpt)->getRValueType();
358+
359+
auto baseTy = (*baseTyOpt)->getWithoutSpecifierType();
351360
if (!baseTy->getMetatypeInstanceType()->mayHaveMembers())
352361
return;
353362

363+
// Use metatype for lookup 'super.init' if it's inside constructors.
364+
if (isa<SuperRefExpr>(baseExpr) && isa<ConstructorDecl>(DC) &&
365+
name == DeclNameRef::createConstructor())
366+
baseTy = MetatypeType::get(baseTy);
367+
354368
collectPossibleCalleesByQualifiedLookup(DC, baseTy, name, candidates);
355369
}
356370

@@ -360,24 +374,17 @@ static bool collectPossibleCalleesForApply(
360374
SmallVectorImpl<FunctionTypeAndDecl> &candidates) {
361375
auto *fnExpr = callExpr->getFn();
362376

363-
if (auto type = fnExpr->getType()) {
364-
if (!type->hasUnresolvedType() && !type->hasError()) {
365-
if (auto *funcType = type->getAs<AnyFunctionType>()) {
366-
auto refDecl = fnExpr->getReferencedDecl();
367-
if (!refDecl)
368-
if (auto apply = dyn_cast<ApplyExpr>(fnExpr))
369-
refDecl = apply->getFn()->getReferencedDecl();
370-
candidates.emplace_back(funcType, refDecl.getDecl());
371-
return true;
372-
}
373-
}
374-
}
375-
376377
if (auto *DRE = dyn_cast<DeclRefExpr>(fnExpr)) {
377378
if (auto *decl = DRE->getDecl()) {
378-
if (decl->hasInterfaceType())
379-
if (auto *funcType = decl->getInterfaceType()->getAs<AnyFunctionType>())
380-
candidates.emplace_back(funcType, decl);
379+
Type fnType = fnExpr->getType();
380+
if ((!fnType || fnType->hasError() || fnType->hasUnresolvedType()) &&
381+
decl->hasInterfaceType())
382+
fnType = decl->getInterfaceType();
383+
if (fnType) {
384+
fnType = fnType->getWithoutSpecifierType();
385+
if (auto *funcTy = fnType->getAs<AnyFunctionType>())
386+
candidates.emplace_back(funcTy, decl);
387+
}
381388
}
382389
} else if (auto *OSRE = dyn_cast<OverloadSetRefExpr>(fnExpr)) {
383390
for (auto *decl : OSRE->getDecls()) {
@@ -386,30 +393,49 @@ static bool collectPossibleCalleesForApply(
386393
candidates.emplace_back(funcType, decl);
387394
}
388395
} else if (auto *UDE = dyn_cast<UnresolvedDotExpr>(fnExpr)) {
389-
collectPossibleCalleesByQualifiedLookup(
390-
DC, UDE->getBase(), UDE->getName(), candidates);
396+
collectPossibleCalleesByQualifiedLookup(DC, UDE->getBase(), UDE->getName(),
397+
candidates);
391398
} else if (auto *DSCE = dyn_cast<DotSyntaxCallExpr>(fnExpr)) {
392399
if (auto *DRE = dyn_cast<DeclRefExpr>(DSCE->getFn())) {
393-
collectPossibleCalleesByQualifiedLookup(
394-
DC, DSCE->getArg(), DeclNameRef(DRE->getDecl()->getFullName()),
395-
candidates);
400+
collectPossibleCalleesByQualifiedLookup(
401+
DC, DSCE->getArg(), DeclNameRef(DRE->getDecl()->getFullName()),
402+
candidates);
396403
}
404+
} else if (auto CRCE = dyn_cast<ConstructorRefCallExpr>(fnExpr)) {
405+
collectPossibleCalleesByQualifiedLookup(
406+
DC, CRCE->getArg(), DeclNameRef::createConstructor(), candidates);
397407
}
398408

399-
if (candidates.empty()) {
400-
ConcreteDeclRef ref = nullptr;
401-
auto fnType = getTypeOfCompletionContextExpr(
402-
DC.getASTContext(), &DC, CompletionTypeCheckKind::Normal, fnExpr, ref);
403-
if (!fnType)
404-
return false;
409+
if (!candidates.empty())
410+
return true;
405411

406-
if (auto *AFT = (*fnType)->getAs<AnyFunctionType>()) {
407-
candidates.emplace_back(AFT, ref.getDecl());
408-
} else if (auto *AMT = (*fnType)->getAs<AnyMetatypeType>()) {
409-
auto baseTy = AMT->getInstanceType();
410-
if (baseTy->mayHaveMembers())
411-
collectPossibleCalleesByQualifiedLookup(
412-
DC, AMT, DeclNameRef::createConstructor(), candidates);
412+
ConcreteDeclRef refDecl = nullptr;
413+
Type fnType = fnExpr->getType();
414+
if (fnType) {
415+
refDecl = fnExpr->getReferencedDecl();
416+
if (!refDecl)
417+
if (auto apply = dyn_cast<ApplyExpr>(fnExpr))
418+
refDecl = apply->getFn()->getReferencedDecl();
419+
}
420+
if (!fnType) {
421+
auto fnTypeOpt = getTypeOfCompletionContextExpr(
422+
DC.getASTContext(), &DC, CompletionTypeCheckKind::Normal, fnExpr,
423+
refDecl);
424+
if (fnTypeOpt)
425+
fnType = *fnTypeOpt;
426+
}
427+
428+
if (!fnType || fnType->hasUnresolvedType() || fnType->hasError())
429+
return false;
430+
fnType = fnType->getWithoutSpecifierType();
431+
432+
if (auto *AFT = fnType->getAs<AnyFunctionType>()) {
433+
candidates.emplace_back(AFT, refDecl.getDecl());
434+
} else if (auto *AMT = fnType->getAs<AnyMetatypeType>()) {
435+
auto baseTy = AMT->getInstanceType();
436+
if (isa<TypeExpr>(fnExpr) && baseTy->mayHaveMembers()) {
437+
collectPossibleCalleesByQualifiedLookup(
438+
DC, AMT, DeclNameRef::createConstructor(), candidates);
413439
}
414440
}
415441

@@ -454,7 +480,7 @@ static bool collectPossibleCalleesForUnresolvedMember(
454480
members);
455481
for (auto member : members) {
456482
if (isReferenceableByImplicitMemberExpr(currModule, &DC, expectedTy,
457-
member.second))
483+
member.Decl))
458484
candidates.push_back(member);
459485
}
460486
}
@@ -549,12 +575,12 @@ class ExprContextAnalyzer {
549575
SmallPtrSet<Identifier, 4> seenNames;
550576
for (auto &typeAndDecl : Candidates) {
551577
DeclContext *memberDC = nullptr;
552-
if (typeAndDecl.second)
553-
memberDC = typeAndDecl.second->getInnermostDeclContext();
578+
if (typeAndDecl.Decl)
579+
memberDC = typeAndDecl.Decl->getInnermostDeclContext();
554580

555-
auto Params = typeAndDecl.first->getParams();
581+
auto Params = typeAndDecl.Type->getParams();
556582
ParameterList *paramList = nullptr;
557-
if (auto VD = typeAndDecl.second) {
583+
if (auto VD = typeAndDecl.Decl) {
558584
if (auto FD = dyn_cast<AbstractFunctionDecl>(VD))
559585
paramList = FD->getParameters();
560586
else if (auto SD = dyn_cast<SubscriptDecl>(VD))

lib/IDE/ExprContextAnalysis.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class ValueDecl;
2424
class AnyFunctionType;
2525

2626
namespace ide {
27+
enum class SemanticContextKind;
2728

2829
/// Type check parent contexts of the given decl context, and the body of the
2930
/// given context until \c Loc if the context is a function body.
@@ -37,7 +38,17 @@ Expr *findParsedExpr(const DeclContext *DC, SourceRange TargetRange);
3738
/// \p DC should be an \c AbstractFunctionDecl or an \c AbstractClosureExpr.
3839
Type getReturnTypeFromContext(const DeclContext *DC);
3940

40-
using FunctionTypeAndDecl = std::pair<AnyFunctionType *, ValueDecl *>;
41+
struct FunctionTypeAndDecl {
42+
AnyFunctionType *Type;
43+
ValueDecl *Decl;
44+
Optional<SemanticContextKind> SemanticContext;
45+
46+
FunctionTypeAndDecl(AnyFunctionType *Type, ValueDecl *Decl)
47+
: Type(Type), Decl(Decl) {}
48+
FunctionTypeAndDecl(AnyFunctionType *Type, ValueDecl *Decl,
49+
SemanticContextKind SemanticContext)
50+
: Type(Type), Decl(Decl), SemanticContext(SemanticContext) {}
51+
};
4152

4253
/// Given an expression and its decl context, the analyzer tries to figure out
4354
/// the expected type of the expression by analyzing its context.

test/IDE/complete_at_top_level.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ func resyncParserB14() {}
470470
var stringInterp = "\(#^STRING_INTERP_3^#)"
471471
_ = "" + "\(#^STRING_INTERP_4^#)" + ""
472472
// STRING_INTERP: Begin completions
473-
// STRING_INTERP-DAG: Decl[InstanceMethod]/CurrNominal: ['(']{#(value): _#}[')'][#Void#]; name=value: _
473+
// STRING_INTERP-DAG: Decl[InstanceMethod]/CurrNominal: ['(']{#(value): T#}[')'][#Void#];
474474
// STRING_INTERP-DAG: Decl[Struct]/CurrModule: FooStruct[#FooStruct#];
475475
// STRING_INTERP-DAG: Decl[FreeFunction]/CurrModule/NotRecommended/TypeRelation[Invalid]: fooFunc1()[#Void#];
476476
// STRING_INTERP-DAG: Decl[FreeFunction]/CurrModule: optStr()[#String?#];

test/IDE/complete_call_arg.swift

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393

9494
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ARCHETYPE_GENERIC_1 | %FileCheck %s -check-prefix=ARCHETYPE_GENERIC_1
9595
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=PARAM_WITH_ERROR_AUTOCLOSURE| %FileCheck %s -check-prefix=PARAM_WITH_ERROR_AUTOCLOSURE
96+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TYPECHECKED_OVERLOADED | %FileCheck %s -check-prefix=TYPECHECKED_OVERLOADED
9697

9798
var i1 = 1
9899
var i2 = 2
@@ -737,7 +738,7 @@ struct Wrap<T> {
737738
func testGenricMethodOnGenericOfArchetype<Wrapped>(value: Wrap<Wrapped>) {
738739
value.method(#^ARCHETYPE_GENERIC_1^#)
739740
// ARCHETYPE_GENERIC_1: Begin completions
740-
// ARCHETYPE_GENERIC_1: Decl[InstanceMethod]/CurrNominal: ['(']{#(fn): (Wrapped) -> _##(Wrapped) -> _#}[')'][#Wrap<_>#];
741+
// ARCHETYPE_GENERIC_1: Decl[InstanceMethod]/CurrNominal: ['(']{#(fn): (Wrapped) -> U##(Wrapped) -> U#}[')'][#Wrap<U>#];
741742
}
742743

743744
struct TestHasErrorAutoclosureParam {
@@ -751,3 +752,17 @@ struct TestHasErrorAutoclosureParam {
751752
// PARAM_WITH_ERROR_AUTOCLOSURE: End completions
752753
}
753754
}
755+
756+
struct MyType {
757+
func overloaded() {}
758+
func overloaded(_ int: Int) {}
759+
func overloaded(name: String, value: String) {}
760+
}
761+
func testTypecheckedOverloaded(value: MyType) {
762+
value.overloaded(#^TYPECHECKED_OVERLOADED^#)
763+
// TYPECHECKED_OVERLOADED: Begin completions
764+
// TYPECHECKED_OVERLOADED-DAG: Decl[InstanceMethod]/CurrNominal: ['('][')'][#Void#];
765+
// TYPECHECKED_OVERLOADED-DAG: Decl[InstanceMethod]/CurrNominal: ['(']{#(int): Int#}[')'][#Void#];
766+
// TYPECHECKED_OVERLOADED-DAG: Decl[InstanceMethod]/CurrNominal: ['(']{#name: String#}, {#value: String#}[')'][#Void#];
767+
// TYPECHECKED_OVERLOADED: End completions
768+
}

0 commit comments

Comments
 (0)