Skip to content

Commit 815ae1f

Browse files
authored
Merge pull request #24987 from rintaro/ide-completion-defaultinit-rdar51037538
[CodeCompletion] Context type analysis for default argument initializer
2 parents 14930c8 + f94a6c0 commit 815ae1f

File tree

3 files changed

+47
-5
lines changed

3 files changed

+47
-5
lines changed

lib/IDE/ExprContextAnalysis.cpp

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,31 @@ class ExprContextAnalyzer {
713713
}
714714
}
715715

716+
void analyzeInitializer(Initializer *initDC) {
717+
switch (initDC->getInitializerKind()) {
718+
case swift::InitializerKind::PatternBinding: {
719+
auto initDC = cast<PatternBindingInitializer>(DC);
720+
auto PBD = initDC->getBinding();
721+
if (!PBD)
722+
break;
723+
auto pat = PBD->getPattern(initDC->getBindingIndex());
724+
if (pat->hasType())
725+
recordPossibleType(pat->getType());
726+
break;
727+
}
728+
case InitializerKind::DefaultArgument: {
729+
auto initDC = cast<DefaultArgumentInitializer>(DC);
730+
auto AFD = dyn_cast<AbstractFunctionDecl>(initDC->getParent());
731+
if (!AFD)
732+
return;
733+
auto param = AFD->getParameters()->get(initDC->getIndex());
734+
if (param->hasInterfaceType())
735+
recordPossibleType(AFD->mapTypeIntoContext(param->getInterfaceType()));
736+
break;
737+
}
738+
}
739+
}
740+
716741
/// Whether the given \c BraceStmt, which must be the body of a function or
717742
/// closure, should be treated as a single-expression return for the purposes
718743
/// of code-completion.
@@ -808,13 +833,17 @@ class ExprContextAnalyzer {
808833
return false;
809834
});
810835

811-
// For 'Initializer' context, we need to look into its parent because it
812-
// might constrain the initializer's type.
836+
// For 'Initializer' context, we need to look into its parent.
813837
auto analyzeDC = isa<Initializer>(DC) ? DC->getParent() : DC;
814838
analyzeDC->walkContext(Finder);
815839

816-
if (Finder.Ancestors.empty())
840+
if (Finder.Ancestors.empty()) {
841+
// There's no parent context in DC. But still, the parent of the
842+
// initializer might constrain the initializer's type.
843+
if (auto initDC = dyn_cast<Initializer>(DC))
844+
analyzeInitializer(initDC);
817845
return;
846+
}
818847

819848
auto &P = Finder.Ancestors.back();
820849
if (auto Parent = P.getAsExpr()) {

test/IDE/complete_default_arguments.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
// RUN: %FileCheck %s -check-prefix=NEGATIVE_DEFAULT_ARGS_9 < %t
1919
//
2020
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_ARG_INIT_1 | %FileCheck %s -check-prefix=DEFAULT_ARG_INIT
21-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_ARG_INIT_2 | %FileCheck %s -check-prefix=DEFAULT_ARG_INIT
21+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_ARG_INIT_2 | %FileCheck %s -check-prefix=DEFAULT_ARG_INIT_INTCONTEXT
2222
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_ARG_INIT_3 | %FileCheck %s -check-prefix=DEFAULT_ARG_INIT
23-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_ARG_INIT_4 | %FileCheck %s -check-prefix=DEFAULT_ARG_INIT
23+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_ARG_INIT_4 | %FileCheck %s -check-prefix=DEFAULT_ARG_INIT_INTCONTEXT
2424

2525
func freeFuncWithDefaultArgs1(
2626
_ a: Int, b: Int = 42, file: String = #file, line: Int = #line,
@@ -140,3 +140,7 @@ func testDefaultArgInit4(_ x: Int = #^DEFAULT_ARG_INIT_4^#) { }
140140
// DEFAULT_ARG_INIT: Begin completions
141141
// DEFAULT_ARG_INIT: Decl[GlobalVar]/CurrModule: globalVar[#Int#]{{; name=.+$}}
142142
// DEFAULT_ARG_INIT: End completions
143+
144+
// DEFAULT_ARG_INIT_INTCONTEXT: Begin completions
145+
// DEFAULT_ARG_INIT_INTCONTEXT: Decl[GlobalVar]/CurrModule/TypeRelation[Identical]: globalVar[#Int#]{{; name=.+$}}
146+
// DEFAULT_ARG_INIT_INTCONTEXT: End completions

test/IDE/complete_unresolved_members.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@
103103
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=GENERICPARAM_21 | %FileCheck %s -check-prefix=GENERICPARAM_1
104104

105105
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DECL_MEMBER_INIT_1 | %FileCheck %s -check-prefix=UNRESOLVED_3
106+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_ARG_1 | %FileCheck %s -check-prefix=UNRESOLVED_3
107+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_ARG_2 | %FileCheck %s -check-prefix=UNRESOLVED_3
108+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_ARG_3 | %FileCheck %s -check-prefix=UNRESOLVED_3
106109

107110
enum SomeEnum1 {
108111
case South
@@ -683,3 +686,9 @@ func testingGenericParam2<X>(obj: C<X>) {
683686
struct TestingStruct {
684687
var value: SomeEnum1 = .#^DECL_MEMBER_INIT_1^#
685688
}
689+
690+
func testDefaultArgument(arg: SomeEnum1 = .#^DEFAULT_ARG_1^#) {}
691+
class TestDefalutArg {
692+
func method(arg: SomeEnum1 = .#^DEFAULT_ARG_2^#) {}
693+
init(arg: SomeEnum1 = .#^DEFAULT_ARG_3^#) {}
694+
}

0 commit comments

Comments
 (0)