Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions lib/AST/LookupVisibleDecls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -877,9 +877,23 @@ void swift::lookupVisibleDecls(VisibleDeclConsumer &Consumer,
LS = LS.withOnMetatype();
}

GenericParamList *GenericParams = DC->getGenericParamsOfContext();
// We don't look for generic parameters if we are in the context of a
// nominal type: they will be looked up anyways via `lookupVisibleMemberDecls`.
if (DC && !isa<NominalTypeDecl>(DC)) {
if (auto *decl = DC->getAsDeclOrDeclExtensionContext()) {
if (auto GC = decl->getAsGenericContext()) {
auto params = GC->getGenericParams();
namelookup::FindLocalVal(SM, Loc, Consumer).checkGenericParams(params);
}
}
}

if (auto *SE = dyn_cast<SubscriptDecl>(DC)) {
ExtendedType = SE->getDeclContext()->getSelfTypeInContext();
DC = DC->getParent();
BaseDecl = DC->getAsNominalTypeOrNominalTypeExtensionContext();
} else if (auto *AFD = dyn_cast<AbstractFunctionDecl>(DC)) {

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

if (BaseDecl && ExtendedType) {
if (BaseDecl && ExtendedType)
::lookupVisibleMemberDecls(ExtendedType, Consumer, DC, LS, Reason,
TypeResolver, nullptr);
}

// Check any generic parameters for something with the given name.
namelookup::FindLocalVal(SM, Loc, Consumer)
.checkGenericParams(GenericParams);

DC = DC->getParent();
Reason = DeclVisibilityKind::MemberOfOutsideNominal;
Expand Down
36 changes: 36 additions & 0 deletions test/IDE/complete_type.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@
// RUN: %FileCheck %s -check-prefix=WITH_GLOBAL_TYPES < %t.types.txt
// RUN: %FileCheck %s -check-prefix=GLOBAL_NEGATIVE < %t.types.txt

// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TYPE_IN_RETURN_GEN_PARAM_NO_DUP > %t.types.txt
// RUN: %FileCheck %s -check-prefix=TYPE_IN_RETURN_GEN_PARAM_NO_DUP < %t.types.txt

// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TYPE_IVAR_GEN_PARAM_NO_DUP > %t.types.txt
// RUN: %FileCheck %s -check-prefix=TYPE_IVAR_GEN_PARAM_NO_DUP < %t.types.txt

// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TYPE_IN_SUBSCR_GEN_PARAM_NO_DUP > %t.types.txt
// RUN: %FileCheck %s -check-prefix=TYPE_IN_SUBSCR_GEN_PARAM_NO_DUP < %t.types.txt

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

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

//===---
//===--- Test that we don't duplicate generic parameters.
//===---

struct GenericStruct<T> {
func foo() -> #^TYPE_IN_RETURN_GEN_PARAM_NO_DUP^#
}
class A<T> {
var foo: #^TYPE_IVAR_GEN_PARAM_NO_DUP^#

subscript(_ arg: Int) -> #^TYPE_IN_SUBSCR_GEN_PARAM_NO_DUP^#
}

// TYPE_IN_RETURN_GEN_PARAM_NO_DUP: Begin completions
// TYPE_IN_RETURN_GEN_PARAM_NO_DUP-DAG: Decl[GenericTypeParam]/CurrNominal: T[#T#]; name=T
// TYPE_IN_RETURN_GEN_PARAM_NO_DUP-NOT: Decl[GenericTypeParam]/Local: T[#T#]; name=T
// TYPE_IN_RETURN_GEN_PARAM_NO_DUP: End completions

// TYPE_IVAR_GEN_PARAM_NO_DUP: Begin completions
// TYPE_IVAR_GEN_PARAM_NO_DUP-DAG: Decl[GenericTypeParam]/CurrNominal: T[#T#]; name=T
// TYPE_IVAR_GEN_PARAM_NO_DUP-NOT: Decl[GenericTypeParam]/Local: T[#T#]; name=T
// TYPE_IVAR_GEN_PARAM_NO_DUP: End completions

// TYPE_IN_SUBSCR_GEN_PARAM_NO_DUP: Begin completions
// TYPE_IN_SUBSCR_GEN_PARAM_NO_DUP-DAG: Decl[GenericTypeParam]/CurrNominal: T[#T#]; name=T
// TYPE_IN_SUBSCR_GEN_PARAM_NO_DUP-NOT: Decl[GenericTypeParam]/Local: T[#T#]; name=T
// TYPE_IN_SUBSCR_GEN_PARAM_NO_DUP: End completions

//===---
//===--- Test that we can complete types in variable declarations.
//===---
Expand Down
2 changes: 1 addition & 1 deletion test/IDE/complete_type_subscript.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ struct G0<T> {
subscript(x: T) -> #^GEN_RETURN_0^# { return 0 }
}
// GEN_TOP_LEVEL_0: Keyword/None: Any[#Any#];
// GEN_TOP_LEVEL_0: Decl[GenericTypeParam]/Local: T[#T#];
// GEN_TOP_LEVEL_0: Decl[GenericTypeParam]/CurrNominal: T[#T#]; name=T
// GEN_TOP_LEVEL_0: Decl[Struct]/CurrModule: S0[#S0#];
// GEN_TOP_LEVEL_0: Decl[Struct]/OtherModule[Swift]: Int[#Int#];

Expand Down
11 changes: 6 additions & 5 deletions test/IDE/complete_where_clause.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=INIT_2 | %FileCheck %s -check-prefix=GEN_T_DOT
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ALIAS_1 | %FileCheck %s -check-prefix=GEN_T
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ALIAS_2 | %FileCheck %s -check-prefix=GEN_T_DOT
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=STRUCT_1 | %FileCheck %s -check-prefix=GEN_T
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=STRUCT_1 | %FileCheck %s -check-prefix=GEN_T_NOMINAL
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=STRUCT_2 | %FileCheck %s -check-prefix=GEN_T_DOT
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=STRUCT_3 | %FileCheck %s -check-prefix=GEN_T
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=STRUCT_3 | %FileCheck %s -check-prefix=GEN_T_NOMINAL
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=STRUCT_4 | %FileCheck %s -check-prefix=GEN_T_DOT
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CLASS_1 | %FileCheck %s -check-prefix=GEN_T
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CLASS_1 | %FileCheck %s -check-prefix=GEN_T_NOMINAL
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CLASS_2 | %FileCheck %s -check-prefix=GEN_T_DOT
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ENUM_1 | %FileCheck %s -check-prefix=GEN_T
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ENUM_1 | %FileCheck %s -check-prefix=GEN_T_NOMINAL
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ENUM_2 | %FileCheck %s -check-prefix=GEN_T_DOT
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ASSOC_1 | %FileCheck %s -check-prefix=P2
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ASSOC_2 | %FileCheck %s -check-prefix=U_DOT
Expand Down Expand Up @@ -68,7 +68,7 @@ protocol Assoc {
}

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

protocol P2 {
associatedtype T where #^ASSOC_1^#
Expand Down