// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testMembersPostfix1 | %FileCheck %s -check-prefix=testMembersPostfix1 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testMembersDot1 | %FileCheck %s -check-prefix=testMembersDot1 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testMembersDot2 | %FileCheck %s -check-prefix=testMembersDot2 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testMultipleSubscript1 | %FileCheck %s -check-prefix=testMultipleSubscript1 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testInherit1 | %FileCheck %s -check-prefix=testInherit1 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testInherit2 | %FileCheck %s -check-prefix=testInherit2 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testShadow1 | %FileCheck %s -check-prefix=testShadow1 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testGeneric1 | %FileCheck %s -check-prefix=testGeneric1 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testGenericUnderconstrained1 | %FileCheck %s -check-prefix=testGenericUnderconstrained1 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testExistential1 | %FileCheck %s -check-prefix=testGenericUnderconstrained1 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testExistential2 | %FileCheck %s -check-prefix=testExistential2 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testProtocolConform1 | %FileCheck %s -check-prefix=testProtocolConform1 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OnSelf1 | %FileCheck %s -check-prefix=OnSelf1 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testSelfExtension1 | %FileCheck %s -check-prefix=testSelfExtension1 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testInvalid1 | %FileCheck %s -check-prefix=testInvalid1 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testInvalid2 | %FileCheck %s -check-prefix=testInvalid2 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testInvalid3 | %FileCheck %s -check-prefix=testInvalid3 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testInvalid4 | %FileCheck %s -check-prefix=testInvalid4 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testGenericRoot1 | %FileCheck %s -check-prefix=testGenericRoot1 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testGenericResult1 | %FileCheck %s -check-prefix=testGenericResult1 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testAnyObjectRoot1 | %FileCheck %s -check-prefix=testAnyObjectRoot1 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testNested1 | %FileCheck %s -check-prefix=testNested1 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testNested2 | %FileCheck %s -check-prefix=testNested2 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testCycle1 | %FileCheck %s -check-prefix=testCycle1 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testCycle2 | %FileCheck %s -check-prefix=testCycle2 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=testSubscriptOnProtocolExt | %FileCheck %s -check-prefix=testSubscriptOnProtocolExt struct Point { var x: Int var y: Int } struct Rectangle { var topLeft: Point var bottomRight: Point } @dynamicMemberLookup struct Lens { var obj: T init(_ obj: T) { self.obj = obj } subscript(dynamicMember member: WritableKeyPath) -> Lens { get { return Lens(obj[keyPath: member]) } set { obj[keyPath: member] = newValue.obj } } } func testMembersPostfix1(r: Lens) { r#^testMembersPostfix1^# } // testMembersPostfix1: Begin completions // testMembersPostfix1-DAG: Decl[Subscript]/CurrNominal: [{#dynamicMember: WritableKeyPath#}][#Lens#]; // testMembersPostfix1-DAG: Decl[InstanceVar]/CurrNominal: .topLeft[#Lens#]; // testMembersPostfix1-DAG: Decl[InstanceVar]/CurrNominal: .bottomRight[#Lens#]; // testMembersPostfix1: End completions func testMembersDot1(r: Lens) { r.#^testMembersDot1^# } // testMembersDot1: Begin completions // testMembersDot1-DAG: Decl[InstanceVar]/CurrNominal: topLeft[#Lens#]; // testMembersDot1-DAG: Decl[InstanceVar]/CurrNominal: bottomRight[#Lens#]; // testMembersDot1: End completions func testMembersDot2(r: Lens) { r.topLeft.#^testMembersDot2^# } // testMembersDot2: Begin completions // testMembersDot2-DAG: Decl[InstanceVar]/CurrNominal: x[#Lens#]; // testMembersDot2-DAG: Decl[InstanceVar]/CurrNominal: y[#Lens#]; // testMembersDot2: End completions @dynamicMemberLookup struct MultipleSubscript { subscript(dynamicMember member: KeyPath) -> U { return Point(x: 1, y: 2)[keyPath: member] } subscript(dynamicMember member: KeyPath) -> U { return Rectangle(topLeft: Point(x: 0, y: 0), bottomRight: Point(x: 1, y: 1))[keyPath: member] } } func testMultipleSubscript1(r: MultipleSubscript) { r.#^testMultipleSubscript1^# } // testMultipleSubscript1: Begin completions // testMultipleSubscript1-DAG: Decl[InstanceVar]/CurrNominal: x[#Int#]; // testMultipleSubscript1-DAG: Decl[InstanceVar]/CurrNominal: y[#Int#]; // testMultipleSubscript1-DAG: Decl[InstanceVar]/CurrNominal: topLeft[#Point#]; // testMultipleSubscript1-DAG: Decl[InstanceVar]/CurrNominal: bottomRight[#Point#]; // testMultipleSubscript1: End completions @dynamicMemberLookup class Base { var t: T init(_ t: T) { self.t = t } subscript(dynamicMember member: KeyPath) -> U { return t[keyPath: member] } } class Inherit1: Base {} func testInherit1(r: Inherit1) { r.#^testInherit1^# } // testInherit1: Begin completions // testInherit1-DAG: Decl[InstanceVar]/CurrNominal: x[#Int#]; // testInherit1-DAG: Decl[InstanceVar]/CurrNominal: y[#Int#]; // testInherit1: End completions class Inherit2: Base { var u: U init(_ t: T, _ u: U) { super.init(t); self.u = u } subscript(dynamicMember member: KeyPath) -> V { return u[keyPath: member] } } func testInherit2(r: Inherit2) { r.#^testInherit2^# } // testInherit2: Begin completions // testInherit2-DAG: Decl[InstanceVar]/CurrNominal: x[#Int#]; // testInherit2-DAG: Decl[InstanceVar]/CurrNominal: y[#Int#]; // testInherit2-DAG: Decl[InstanceVar]/CurrNominal: topLeft[#Point#]; // testInherit2-DAG: Decl[InstanceVar]/CurrNominal: bottomRight[#Point#]; // testInherit2: End completions class Shadow1: Base { var x: String = "" } func testShadow1(r: Shadow1) { r.#^testShadow1^# } // testShadow1-NOT: x[#Int#]; // testShadow1: Decl[InstanceVar]/CurrNominal: y[#Int#]; // testShadow1-NOT: x[#Int#]; // testShadow1: Decl[InstanceVar]/CurrNominal: x[#String#]; @dynamicMemberLookup protocol P { associatedtype T subscript(dynamicMember member: KeyPath) -> U } func testGeneric1(r: G) where G.T == Point { r.#^testGeneric1^# } // testGeneric1: Begin completions // testGeneric1-DAG: Decl[InstanceVar]/CurrNominal: x[#Int#]; // testGeneric1-DAG: Decl[InstanceVar]/CurrNominal: y[#Int#]; // testGeneric1: End completions func testGenericUnderconstrained1(r: G) { r.#^testGenericUnderconstrained1^# } // testGenericUnderconstrained1-NOT: CurrNominal // testGenericUnderconstrained1: Keyword[self]/CurrNominal: self[#{{[GP]}}#]; // testGenericUnderconstrained1-NOT: CurrNominal func testExistential1(r: P) { r.#^testExistential1^# } @dynamicMemberLookup protocol E { subscript(dynamicMember member: KeyPath) -> U } func testExistential2(r: E) { r.#^testExistential2^# } // testExistential2: Begin completions // testExistential2-DAG: Decl[InstanceVar]/CurrNominal: x[#Int#]; // testExistential2-DAG: Decl[InstanceVar]/CurrNominal: y[#Int#]; // testExistential2: End completions struct WithP: P { var t: T init(t: T) { self.t = t } subscript(dynamicMember member: KeyPath) -> U { return t[keyPath: member] } } func testProtocolConform1(r: WithP) { r.#^testProtocolConform1^# } // testProtocolConform1: Begin completions // testProtocolConform1-DAG: Decl[InstanceVar]/CurrNominal: x[#Int#]; // testProtocolConform1-DAG: Decl[InstanceVar]/CurrNominal: y[#Int#]; // testProtocolConform1: End completions @dynamicMemberLookup struct OnSelf { subscript(dynamicMember member: KeyPath) -> U { return Point(x: 0, y: 1)[keyPath: member] } func test() { self.#^OnSelf1^# } } // OnSelf1: Begin completions // OnSelf1-DAG: Decl[InstanceMethod]/CurrNominal: test()[#Void#]; // OnSelf1-DAG: Decl[InstanceVar]/CurrNominal: x[#Int#]; // OnSelf1-DAG: Decl[InstanceVar]/CurrNominal: y[#Int#]; // OnSelf1: End completions protocol HalfRect { var topLeft: Point } extension Lens where T: HalfRect { func testSelfExtension1() { self.#^testSelfExtension1^# } } // testSelfExtension1-NOT: bottomRight // testSelfExtension1: Decl[InstanceVar]/CurrNominal: topLeft[#Lens#]; // testSelfExtension1-NOT: bottomRight struct Invalid1 { subscript(dynamicMember member: KeyPath) -> U { return Point(x: 0, y: 1)[keyPath: member] } } func testInvalid1(r: Invalid1) { r.#^testInvalid1^# } // testInvalid1-NOT: topLeft @dynamicMemberLookup struct Invalid2 { subscript(dynamicMember: KeyPath) -> U { return Point(x: 0, y: 1)[keyPath: dynamicMember] } } func testInvalid2(r: Invalid2) { r.#^testInvalid2^# } // testInvalid2-NOT: topLeft @dynamicMemberLookup struct Invalid3 { subscript(dynamicMember member: Rectangle) -> U { return Point(x: 0, y: 1)[keyPath: member] } } func testInvalid3(r: Invalid3) { r.#^testInvalid3^# } // testInvalid3-NOT: topLeft struct NotKeyPath {} @dynamicMemberLookup struct Invalid4 { subscript(dynamicMember member: NotKeyPath) -> U { return Point(x: 0, y: 1)[keyPath: member] } } func testInvalid4(r: Invalid4) { r.#^testInvalid4^# } // testInvalid4-NOT: topLeft struct Gen1 { var foo: T } @dynamicMemberLookup struct GenericRoot { subscript(dynamicMember member: KeyPath, U>) -> Int { return 1 } } func testGenericRoot1(r: GenericRoot) { r.#^testGenericRoot1^# } // testGenericRoot1: Decl[InstanceVar]/CurrNominal: foo[#Int#]; @dynamicMemberLookup struct GenericResult { subscript(dynamicMember member: KeyPath>) -> GenericResult { fatalError() } } struct BoxedCircle { var center: Gen1 var radius: Gen1 } func testGenericResult1(r: GenericResult) { r.#^testGenericResult1^# } // testGenericResult1: Begin completions // FIXME: the type should be 'GenericResult' // testGenericResult1-DAG: Decl[InstanceVar]/CurrNominal: center[#Gen1#]; name=center // testGenericResult1-DAG: Decl[InstanceVar]/CurrNominal: radius[#Gen1#]; name=radius // testGenericResult1: End completions class C { var someUniqueName: Int = 0 } @dynamicMemberLookup struct AnyObjectRoot { subscript(dynamicMember member: KeyPath) -> Int { return 1 } } func testAnyObjectRoot1(r: AnyObjectRoot) { r.#^testAnyObjectRoot1^# } // Do not do find via AnyObject dynamic lookup. // testAnyObjectRoot1-NOT: someUniqueName func testNested1(r: Lens>) { r.#^testNested1^# // testNested1: Begin completions // FIXME: The type should be 'Lens>' // testNested1-DAG: Decl[InstanceVar]/CurrNominal: x[#Lens#]; // testNested1-DAG: Decl[InstanceVar]/CurrNominal: y[#Lens#]; // testNested1: End completions } func testNested2(r: Lens>>) { r.#^testNested2^# // testNested2: Begin completions // FIXME: The type should be 'Lens>>' // testNested2-DAG: Decl[InstanceVar]/CurrNominal: x[#Lens#]; // testNested2-DAG: Decl[InstanceVar]/CurrNominal: y[#Lens#]; // testNested2: End completions } @dynamicMemberLookup struct Recurse { var obj: T init(_ obj: T) { self.obj = obj } subscript(dynamicMember member: KeyPath, U>) -> Int { return 1 } } func testCycle1(r: Recurse) { r.#^testCycle1^# // testCycle1: Begin completions // testCycle1-NOT: x[#Int#] } @dynamicMemberLookup struct CycleA { var fromA: Int subscript(dynamicMember member: KeyPath, U>) -> Int { return 1 } } @dynamicMemberLookup struct CycleB { var fromB: Int subscript(dynamicMember member: KeyPath, U>) -> Int { return 1 } } @dynamicMemberLookup struct CycleC { var fromC: Int subscript(dynamicMember member: KeyPath, U>) -> Int { return 1 } } func testCycle2(r: CycleA) { r.#^testCycle2^# // testCycle2: Begin completions } protocol DynamicLookupProto { associatedtype Content } extension DynamicLookupProto { subscript(dynamicMember key: KeyPath) -> T { fatalError() } } @dynamicMemberLookup struct DynamicLookupConcrete : DynamicLookupProto { typealias Content = Point } func testSubscriptOnProtocolExtension(dyn: DynamicLookupConcrete) { dyn.#^testSubscriptOnProtocolExt^# // testSubscriptOnProtocolExt: Begin completions // testSubscriptOnProtocolExt: Keyword[self]/CurrNominal: self[#DynamicLookupConcrete#]; // testSubscriptOnProtocolExt: Decl[InstanceVar]/CurrNominal: x[#Int#]; // testSubscriptOnProtocolExt: Decl[InstanceVar]/CurrNominal: y[#Int#]; // testSubscriptOnProtocolExt: End completions }