Skip to content

Commit 713eb1a

Browse files
authored
Merge pull request swiftlang#16579 from AnthonyLatsis/dup-gen-param-completion-member-decl
[CodeCompletion][SR-7670] Duplicate generic param completions
2 parents f1076eb + dadcea6 commit 713eb1a

File tree

4 files changed

+60
-14
lines changed

4 files changed

+60
-14
lines changed

lib/AST/LookupVisibleDecls.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -876,9 +876,23 @@ void swift::lookupVisibleDecls(VisibleDeclConsumer &Consumer,
876876
LS = LS.withOnMetatype();
877877
}
878878

879-
GenericParamList *GenericParams = DC->getGenericParamsOfContext();
879+
// We don't look for generic parameters if we are in the context of a
880+
// nominal type: they will be looked up anyways via `lookupVisibleMemberDecls`.
881+
if (DC && !isa<NominalTypeDecl>(DC)) {
882+
if (auto *decl = DC->getAsDeclOrDeclExtensionContext()) {
883+
if (auto GC = decl->getAsGenericContext()) {
884+
auto params = GC->getGenericParams();
885+
namelookup::FindLocalVal(SM, Loc, Consumer).checkGenericParams(params);
886+
}
887+
}
888+
}
889+
890+
if (auto *SE = dyn_cast<SubscriptDecl>(DC)) {
891+
ExtendedType = SE->getDeclContext()->getSelfTypeInContext();
892+
DC = DC->getParent();
893+
BaseDecl = DC->getAsNominalTypeOrNominalTypeExtensionContext();
894+
} else if (auto *AFD = dyn_cast<AbstractFunctionDecl>(DC)) {
880895

881-
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(DC)) {
882896
// Look for local variables; normally, the parser resolves these
883897
// for us, but it can't do the right thing inside local types.
884898
// FIXME: when we can parse and typecheck the function body partially for
@@ -921,14 +935,9 @@ void swift::lookupVisibleDecls(VisibleDeclConsumer &Consumer,
921935
BaseDecl = ND;
922936
}
923937

924-
if (BaseDecl && ExtendedType) {
938+
if (BaseDecl && ExtendedType)
925939
::lookupVisibleMemberDecls(ExtendedType, Consumer, DC, LS, Reason,
926940
TypeResolver, nullptr);
927-
}
928-
929-
// Check any generic parameters for something with the given name.
930-
namelookup::FindLocalVal(SM, Loc, Consumer)
931-
.checkGenericParams(GenericParams);
932941

933942
DC = DC->getParent();
934943
Reason = DeclVisibilityKind::MemberOfOutsideNominal;

test/IDE/complete_type.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@
4545
// RUN: %FileCheck %s -check-prefix=WITH_GLOBAL_TYPES < %t.types.txt
4646
// RUN: %FileCheck %s -check-prefix=GLOBAL_NEGATIVE < %t.types.txt
4747

48+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TYPE_IN_RETURN_GEN_PARAM_NO_DUP > %t.types.txt
49+
// RUN: %FileCheck %s -check-prefix=TYPE_IN_RETURN_GEN_PARAM_NO_DUP < %t.types.txt
50+
51+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TYPE_IVAR_GEN_PARAM_NO_DUP > %t.types.txt
52+
// RUN: %FileCheck %s -check-prefix=TYPE_IVAR_GEN_PARAM_NO_DUP < %t.types.txt
53+
54+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TYPE_IN_SUBSCR_GEN_PARAM_NO_DUP > %t.types.txt
55+
// RUN: %FileCheck %s -check-prefix=TYPE_IN_SUBSCR_GEN_PARAM_NO_DUP < %t.types.txt
4856

4957
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TYPE_IN_LOCAL_VAR_IN_FREE_FUNC_1 > %t.types.txt
5058
// RUN: %FileCheck %s -check-prefix=WITH_GLOBAL_TYPES < %t.types.txt
@@ -573,6 +581,34 @@ struct TestTypeInConstructorParamGeneric3<
573581

574582
// No tests for destructors: destructors don't have parameters.
575583

584+
//===---
585+
//===--- Test that we don't duplicate generic parameters.
586+
//===---
587+
588+
struct GenericStruct<T> {
589+
func foo() -> #^TYPE_IN_RETURN_GEN_PARAM_NO_DUP^#
590+
}
591+
class A<T> {
592+
var foo: #^TYPE_IVAR_GEN_PARAM_NO_DUP^#
593+
594+
subscript(_ arg: Int) -> #^TYPE_IN_SUBSCR_GEN_PARAM_NO_DUP^#
595+
}
596+
597+
// TYPE_IN_RETURN_GEN_PARAM_NO_DUP: Begin completions
598+
// TYPE_IN_RETURN_GEN_PARAM_NO_DUP-DAG: Decl[GenericTypeParam]/CurrNominal: T[#T#]; name=T
599+
// TYPE_IN_RETURN_GEN_PARAM_NO_DUP-NOT: Decl[GenericTypeParam]/Local: T[#T#]; name=T
600+
// TYPE_IN_RETURN_GEN_PARAM_NO_DUP: End completions
601+
602+
// TYPE_IVAR_GEN_PARAM_NO_DUP: Begin completions
603+
// TYPE_IVAR_GEN_PARAM_NO_DUP-DAG: Decl[GenericTypeParam]/CurrNominal: T[#T#]; name=T
604+
// TYPE_IVAR_GEN_PARAM_NO_DUP-NOT: Decl[GenericTypeParam]/Local: T[#T#]; name=T
605+
// TYPE_IVAR_GEN_PARAM_NO_DUP: End completions
606+
607+
// TYPE_IN_SUBSCR_GEN_PARAM_NO_DUP: Begin completions
608+
// TYPE_IN_SUBSCR_GEN_PARAM_NO_DUP-DAG: Decl[GenericTypeParam]/CurrNominal: T[#T#]; name=T
609+
// TYPE_IN_SUBSCR_GEN_PARAM_NO_DUP-NOT: Decl[GenericTypeParam]/Local: T[#T#]; name=T
610+
// TYPE_IN_SUBSCR_GEN_PARAM_NO_DUP: End completions
611+
576612
//===---
577613
//===--- Test that we can complete types in variable declarations.
578614
//===---

test/IDE/complete_type_subscript.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ struct G0<T> {
3737
subscript(x: T) -> #^GEN_RETURN_0^# { return 0 }
3838
}
3939
// GEN_TOP_LEVEL_0: Keyword/None: Any[#Any#];
40-
// GEN_TOP_LEVEL_0: Decl[GenericTypeParam]/Local: T[#T#];
40+
// GEN_TOP_LEVEL_0: Decl[GenericTypeParam]/CurrNominal: T[#T#]; name=T
4141
// GEN_TOP_LEVEL_0: Decl[Struct]/CurrModule: S0[#S0#];
4242
// GEN_TOP_LEVEL_0: Decl[Struct]/OtherModule[Swift]: Int[#Int#];
4343

test/IDE/complete_where_clause.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@
1717
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=INIT_2 | %FileCheck %s -check-prefix=GEN_T_DOT
1818
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ALIAS_1 | %FileCheck %s -check-prefix=GEN_T
1919
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ALIAS_2 | %FileCheck %s -check-prefix=GEN_T_DOT
20-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=STRUCT_1 | %FileCheck %s -check-prefix=GEN_T
20+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=STRUCT_1 | %FileCheck %s -check-prefix=GEN_T_NOMINAL
2121
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=STRUCT_2 | %FileCheck %s -check-prefix=GEN_T_DOT
22-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=STRUCT_3 | %FileCheck %s -check-prefix=GEN_T
22+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=STRUCT_3 | %FileCheck %s -check-prefix=GEN_T_NOMINAL
2323
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=STRUCT_4 | %FileCheck %s -check-prefix=GEN_T_DOT
24-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CLASS_1 | %FileCheck %s -check-prefix=GEN_T
24+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CLASS_1 | %FileCheck %s -check-prefix=GEN_T_NOMINAL
2525
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CLASS_2 | %FileCheck %s -check-prefix=GEN_T_DOT
26-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ENUM_1 | %FileCheck %s -check-prefix=GEN_T
26+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ENUM_1 | %FileCheck %s -check-prefix=GEN_T_NOMINAL
2727
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ENUM_2 | %FileCheck %s -check-prefix=GEN_T_DOT
2828
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ASSOC_1 | %FileCheck %s -check-prefix=P2
2929
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ASSOC_2 | %FileCheck %s -check-prefix=U_DOT
@@ -68,7 +68,7 @@ protocol Assoc {
6868
}
6969

7070
func f1<T>(_: T) where #^FUNC_1^# {}
71-
// GEN_T: Decl[GenericTypeParam]/Local: T[#T#];
71+
// GEN_T: Decl[GenericTypeParam]/Local: T[#T#]; name=T
7272
func f2<T>(_: T) where T.#^FUNC_2^# {}
7373
// GEN_T_DOT: Begin completions
7474
// GEN_T_DOT-DAG: Keyword/None: Type[#T.Type#];
@@ -101,6 +101,7 @@ class C1<T> where #^CLASS_1^# {}
101101
class C2<T> where T.#^CLASS_2^# {}
102102
enum E1<T> where #^ENUM_1^# {}
103103
enum E2<T> where T.#^ENUM_2^# {}
104+
// GEN_T_NOMINAL: Decl[GenericTypeParam]/CurrNominal: T[#T#]; name=T
104105

105106
protocol P2 {
106107
associatedtype T where #^ASSOC_1^#

0 commit comments

Comments
 (0)