|
| 1 | +// RUN: %empty-directory(%t) |
| 2 | +// RUN: mkdir -p %t/mods |
| 3 | +// RUN: split-file --leading-lines %s %t |
| 4 | + |
| 5 | +// RUN: %target-swift-frontend -module-name Foo -emit-module -emit-module-path %t/mods/Foo.swiftmodule -emit-module-doc -emit-module-doc-path %t/mods/Foo.swiftdoc -group-info-path %t/group.json %t/Foo.swift |
| 6 | +// RUN: %target-swift-frontend -module-name Bar -emit-module -emit-module-path %t/mods/Bar.swiftmodule -emit-module-doc -emit-module-doc-path %t/mods/Bar.swiftdoc -I%t/mods %t/Bar.swift |
| 7 | + |
| 8 | +//--- group.json |
| 9 | +{ |
| 10 | + "TestGroup": [ |
| 11 | + "Foo.swift", |
| 12 | + ] |
| 13 | +} |
| 14 | + |
| 15 | +//--- Foo.swift |
| 16 | +public protocol FooProto { |
| 17 | + associatedtype T |
| 18 | +} |
| 19 | + |
| 20 | +public extension FooProto { |
| 21 | + func fooExt() {} |
| 22 | +} |
| 23 | + |
| 24 | +public extension FooProto { |
| 25 | + func fooExt2() {} |
| 26 | +} |
| 27 | + |
| 28 | +public extension FooProto where T == Int { |
| 29 | + func fooIntExt() {} |
| 30 | +} |
| 31 | + |
| 32 | +public struct FooStruct: FooProto { |
| 33 | + public typealias T = Int |
| 34 | + public func foo() {} |
| 35 | +} |
| 36 | + |
| 37 | +//--- Bar.swift |
| 38 | +import Foo |
| 39 | + |
| 40 | +public extension FooProto { |
| 41 | + func barExt() {} |
| 42 | +} |
| 43 | + |
| 44 | +public extension FooProto where T == Int { |
| 45 | + func barIntExt() {} |
| 46 | +} |
| 47 | + |
| 48 | +//--- Baz.swift |
| 49 | +import Foo |
| 50 | +import Bar |
| 51 | + |
| 52 | +// The generated interface for Foo will contain all the extensions as well |
| 53 | +// as the "synthesized extension" on FooStruct itself, ie. the extension |
| 54 | +// functions are added to FooStruct as if they were written there in the source. |
| 55 | +// |
| 56 | +// We prefer jumping to these declarations rather than the one in the extension, |
| 57 | +// but also have to be careful not to attempt to do so for extensions outside |
| 58 | +// of the original module - these will *not* have "synthesized extensions" |
| 59 | +// in their generated interface. |
| 60 | +func test(f: FooStruct) { |
| 61 | + // RUN: %sourcekitd-test -req=cursor -pos=%(line+1):5 %t/Baz.swift -- %t/Baz.swift -I %t/mods -target %target-triple | %FileCheck --check-prefix=CHECK-EXT %t/Baz.swift |
| 62 | + f.fooExt() |
| 63 | + // CHECK-EXT: 3Foo0A5ProtoPAAE6fooExtyyF::SYNTHESIZED::s:3Foo0A6StructV |
| 64 | + // CHECK-EXT: <Group>TestGroup</Group> |
| 65 | + |
| 66 | + // RUN: %sourcekitd-test -req=cursor -pos=%(line+1):5 %t/Baz.swift -- %t/Baz.swift -I %t/mods -target %target-triple | %FileCheck --check-prefix=CHECK-EXT2 %t/Baz.swift |
| 67 | + f.fooExt2() |
| 68 | + // CHECK-EXT2: s:3Foo0A5ProtoPAAE7fooExt2yyF::SYNTHESIZED::s:3Foo0A6StructV |
| 69 | + // CHECK-EXT2: <Group>TestGroup</Group> |
| 70 | + |
| 71 | + // RUN: %sourcekitd-test -req=cursor -pos=%(line+1):5 %t/Baz.swift -- %t/Baz.swift -I %t/mods -target %target-triple | %FileCheck --check-prefix=CHECK-INTEXT %t/Baz.swift |
| 72 | + f.fooIntExt() |
| 73 | + // CHECK-INTEXT: s:3Foo0A5ProtoPAASi1TRtzrlE9fooIntExtyyF::SYNTHESIZED::s:3Foo0A6StructV |
| 74 | + // CHECK-INTEXT: <Group>TestGroup</Group> |
| 75 | + |
| 76 | + // RUN: %sourcekitd-test -req=cursor -pos=%(line+1):5 %t/Baz.swift -- %t/Baz.swift -I %t/mods -target %target-triple | %FileCheck --check-prefix=CHECK-BAREXT %t/Baz.swift |
| 77 | + f.barExt() |
| 78 | + // CHECK-BAREXT: s:3Foo0A5ProtoP3BarE6barExtyyF |
| 79 | + // CHECK-BAREXT-NOT: <Group>TestGroup</Group> |
| 80 | + |
| 81 | + // RUN: %sourcekitd-test -req=cursor -pos=%(line+1):5 %t/Baz.swift -- %t/Baz.swift -I %t/mods -target %target-triple | %FileCheck --check-prefix=CHECK-BARINTEXT %t/Baz.swift |
| 82 | + f.barIntExt() |
| 83 | + // CHECK-BARINTEXT: s:3Foo0A5ProtoP3BarSi1TRtzrlE9barIntExtyyF |
| 84 | + // CHECK-BARINTEXT-NOT: <Group>TestGroup</Group> |
| 85 | +} |
0 commit comments