File: index_macros.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (294 lines) | stat: -rw-r--r-- 11,442 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
// REQUIRES: swift_swift_parser

// RUN: %empty-directory(%t)
// RUN: split-file --leading-lines %s %t

// Check that we index code expanded from macros, especially nested references
// (ie. calls within an added function).

// Create the plugin with various macros for testing
// RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(IndexMacros) -module-name=IndexMacros %t/IndexMacros.swift -g -no-toolchain-stdlib-rpath

// Check indexed symbols
// RUN: %target-swift-ide-test -print-indexed-symbols -source-filename %t/IndexTest.swift -load-plugin-library %t/%target-library-name(IndexMacros) -parse-as-library > %t/index.out
// RUN: %FileCheck %s --input-file %t/index.out

//--- IndexTest.swift
@freestanding(expression)
macro freestandingExpr<T>(arg: T) = #externalMacro(module: "IndexMacros", type: "FreestandingExprMacro")
// CHECK: [[@LINE-1]]:7 | macro/Swift | freestandingExpr(arg:) |  [[EXPR_USR:.*]] | Def

@freestanding(declaration, names: named(TestFree))
macro freestandingDecl<T>(arg: T) = #externalMacro(module: "IndexMacros", type: "FreestandingDeclMacro")
// CHECK: [[@LINE-1]]:7 | macro/Swift | freestandingDecl(arg:) |  [[DECL_USR:.*]] | Def

@attached(accessor)
macro Accessor() = #externalMacro(module: "IndexMacros", type: "SomeAccessorMacro")
// CHECK: [[@LINE-1]]:7 | macro/Swift | Accessor() |  [[ACCESSOR_USR:.*]] | Def

@attached(extension, conformances: TestProto)
macro Conformance() = #externalMacro(module: "IndexMacros", type: "SomeConformanceMacro")
// CHECK: [[@LINE-1]]:7 | macro/Swift | Conformance() |  [[CONFORMANCE_USR:.*]] | Def

@attached(member, names: named(memberFunc))
macro Member() = #externalMacro(module: "IndexMacros", type: "SomeMemberMacro")
// CHECK: [[@LINE-1]]:7 | macro/Swift | Member() |  [[MEMBER_USR:.*]] | Def

@attached(memberAttribute)
macro MemberAttribute() = #externalMacro(module: "IndexMacros", type: "SomeMemberAttributeMacro")
// CHECK: [[@LINE-1]]:7 | macro/Swift | MemberAttribute() |  [[MEMBER_ATTRIBUTE_USR:.*]] | Def

@attached(peer, names: named(TestPeer))
macro Peer<T>(arg: T) = #externalMacro(module: "IndexMacros", type: "SomePeerMacro")
// CHECK: [[@LINE-1]]:7 | macro/Swift | Peer(arg:) |  [[PEER_USR:.*]] | Def

@attached(peer, names: named(peerMember))
macro PeerMember() = #externalMacro(module: "IndexMacros", type: "SomePeerMemberMacro")
// CHECK: [[@LINE-1]]:7 | macro/Swift | PeerMember() |  [[PEER_MEMBER_USR:.*]] | Def

protocol TestProto {}
// CHECK: [[@LINE-1]]:10 | protocol/Swift | TestProto | [[PROTO_USR:.*]] | Def

func accessorLog() {}
// CHECK: [[@LINE-1]]:6 | function/Swift | accessorLog() | [[ACC_LOG_USR:.*]] | Def
func exprLog() {}
// CHECK: [[@LINE-1]]:6 | function/Swift | exprLog() | [[EXPR_LOG_USR:.*]] | Def
func freeLog() {}
// CHECK: [[@LINE-1]]:6 | function/Swift | freeLog() | [[FREE_LOG_USR:.*]] | Def
func memberLog() {}
// CHECK: [[@LINE-1]]:6 | function/Swift | memberLog() | [[MEMBER_LOG_USR:.*]] | Def
func peerLog() {}
// CHECK: [[@LINE-1]]:6 | function/Swift | peerLog() | [[PEER_LOG_USR:.*]] | Def

// CHECK: [[@LINE+2]]:8 | struct/Swift | AddOne | [[ADD_ONE_USR:.*]] | Def
@propertyWrapper
struct AddOne {
  var value: Int = 1
  var wrappedValue: Int {
    get { value }
    set { value = newValue + 1 }
  }
  init(wrappedValue: Int) {
    self.wrappedValue = wrappedValue
  }
}

// CHECK: [[@LINE+2]]:2 | macro/Swift | freestandingDecl(arg:) | [[DECL_USR]] | Ref
// CHECK: [[@LINE+1]]:19 | struct/Swift | Double | s:Sd | Ref
#freestandingDecl<Double>(arg: 1.0)
// Creates a `TestFree` struct with `freeFunc` calling `freeLog`
// CHECK: [[@LINE-2]]:1 | struct/Swift | TestFree | [[FREE_STRUCT_USR:.*]] | Def,Impl
// CHECK: [[@LINE-3]]:1 | instance-method/Swift | freeFunc() | [[FREE_FUNC_USR:.*]] | Def,Impl,RelChild
// CHECK-NEXT: RelChild | struct/Swift | TestFree | [[FREE_STRUCT_USR]]
// CHECK: [[@LINE-5]]:1 | function/Swift | freeLog() | [[FREE_LOG_USR]] | Ref,Call,Impl,RelCall,RelCont
// CHECK-NEXT: RelCall,RelCont | instance-method/Swift | freeFunc() | [[FREE_FUNC_USR]]

func testExpr() {
  // CHECK: [[@LINE+2]]:4 | macro/Swift | freestandingExpr(arg:) | [[EXPR_USR]] | Ref
  // CHECK: [[@LINE+1]]:21 | struct/Swift | Double | s:Sd | Ref
  #freestandingExpr<Double>(arg: 1.0)
  // CHECK: [[@LINE-1]]:3 | function/Swift | exprLog() | [[EXPR_LOG_USR]] | Ref,Call,Impl,RelCall,RelCont
  // CHECK-NEXT: RelCall,RelCont | function/Swift | testExpr()
}

// CHECK: [[@LINE+5]]:40 | macro/Swift | Peer(arg:) | [[PEER_USR]] | Ref
// CHECK: [[@LINE+4]]:45 | struct/Swift | Double | s:Sd | Ref
// CHECK: [[@LINE+3]]:23 | macro/Swift | MemberAttribute() | [[MEMBER_ATTRIBUTE_USR]] | Ref
// CHECK: [[@LINE+2]]:15 | macro/Swift | Member() | [[MEMBER_USR]] | Ref
// CHECK: [[@LINE+1]]:2 | macro/Swift | Conformance() | [[CONFORMANCE_USR]] | Ref
@Conformance @Member @MemberAttribute @Peer<Double>(arg: 1.0)
struct TestAttached {
  var attachedMember: Int

  @Accessor
  var attachedMemberAccessors: Int
}
// `MemberAttribute` adds `@AddOne` to attachedMember
// CHECK: [[@LINE-8]]:22 | struct/Swift | AddOne | [[ADD_ONE_USR]] | Ref,Impl,RelCont
// CHECK-NEXT: RelCont | instance-property/Swift | attachedMember

// `Accessor` adds getters/setters to `attachedMemberAccessors` that both call `accessorLog`
// CHECK: [[@LINE-8]]:3 | function/Swift | accessorLog() | [[ACC_LOG_USR]] | Ref,Call,Impl,RelCall,RelCont
// CHECK-NEXT: RelCall,RelCont | instance-method/acc-get/Swift | getter:attachedMemberAccessors

// `Member` adds a new member `memberFunc` that calls `memberLog`
// CHECK: [[@LINE-16]]:14 | instance-method/Swift | memberFunc() | [[MEMBER_FUNC_USR:.*]] | Def,Impl,RelChild
// CHECK: [[@LINE-17]]:14 | function/Swift | memberLog() | [[MEMBER_LOG_USR]] | Ref,Call,Impl,RelCall,RelCont
// CHECK-NEXT: RelCall,RelCont | instance-method/Swift | memberFunc() | [[MEMBER_FUNC_USR]]

// `Peer` adds a new inner type `TestPeer` that contains `peerFunc` with a call to `peerLog`
// CHECK: [[@LINE-21]]:39 | struct/Swift | TestPeer | [[PEER_STRUCT_USR:.*]] | Def,Impl
// CHECK: [[@LINE-22]]:39 | instance-method/Swift | peerFunc() | [[PEER_FUNC_USR:.*]] | Def,Impl,RelChild
// CHECK-NEXT: RelChild | struct/Swift | TestPeer | [[PEER_STRUCT_USR]]
// CHECK: [[@LINE-24]]:39 | function/Swift | peerLog() | [[PEER_LOG_USR]] | Ref,Call,Impl,RelCall,RelCont
// CHECK-NEXT: RelCall,RelCont | instance-method/Swift | peerFunc() | [[PEER_FUNC_USR]]

// CHECK: [[@LINE+1]]:8 | struct/Swift | Outer | [[OUTER_USR:.*]] | Def
struct Outer {
  // CHECK: [[@LINE+1]]:4 | macro/Swift | PeerMember() | [[PEER_MEMBER_USR]] | Ref
  @PeerMember
  var anyMember: Int
  // `PeerMember` adds a new `peerMember`
  // CHECK: [[@LINE-3]]:3 | instance-property/Swift | peerMember | {{.*}} | Def,Impl,RelChild
  // CHECK-NEXT: RelChild | struct/Swift | Outer | [[OUTER_USR]]

  // CHECK: [[@LINE+2]]:17 | macro/Swift | Member() | [[MEMBER_USR]] | Ref
  // CHECK: [[@LINE+1]]:4 | macro/Swift | Conformance() | [[CONFORMANCE_USR]] | Ref
  @Conformance @Member
  struct TestInner {}
}
// `Member` adds a new member `memberFunc` that calls `memberLog`
// CHECK: [[@LINE-4]]:16 | instance-method/Swift | memberFunc() | [[INNER_FUNC_USR:.*]] | Def,Impl
// CHECK-NEXT: RelChild | struct/Swift | TestInner
// CHECK: [[@LINE-6]]:16 | function/Swift | memberLog() | [[MEMBER_LOG_USR]] | Ref,Call,Impl,RelCall,RelCont
// CHECK-NEXT: RelCall,RelCont | instance-method/Swift | memberFunc() | [[INNER_FUNC_USR]]


// Expanded extensions are visited last

// `Conformance` adds `TestProto` as a conformance on an extension of `TestAttached`
// CHECK: [[@LINE-51]]:1 | extension/ext-struct/Swift | TestAttached | {{.*}} | Def,Impl
// CHECK: [[@LINE-52]]:1 | protocol/Swift | TestProto | [[PROTO_USR]] | Ref,Impl,RelBase
// CHECK-NEXT: RelBase | extension/ext-struct/Swift | TestAttached

// `Conformance` adds `TestProto` as a conformance on an extension of `TestInner`
// CHECK: [[@LINE-18]]:3 | extension/ext-struct/Swift | TestInner | {{.*}} | Def,Impl
// CHECK: [[@LINE-19]]:3 | protocol/Swift | TestProto | [[PROTO_USR]] | Ref,Impl,RelBase
// CHECK-NEXT: RelBase | extension/ext-struct/Swift | TestInner

//--- IndexMacros.swift
import SwiftSyntax
import SwiftSyntaxBuilder
import SwiftSyntaxMacros

public struct FreestandingExprMacro: ExpressionMacro {
  public static func expansion(
    of node: some FreestandingMacroExpansionSyntax,
    in context: some MacroExpansionContext
  ) -> ExprSyntax {
    return "exprLog()"
  }
}

public struct FreestandingDeclMacro: DeclarationMacro {
  public static func expansion(
    of node: some FreestandingMacroExpansionSyntax,
    in context: some MacroExpansionContext
  ) throws -> [DeclSyntax] {
    return ["""
      struct TestFree {
        func freeFunc() {
          freeLog()
        }
      }
      """]
  }
}

public struct SomeAccessorMacro: AccessorMacro {
  public static func expansion(
    of node: AttributeSyntax,
    providingAccessorsOf declaration: some DeclSyntaxProtocol,
    in context: some MacroExpansionContext
  ) throws -> [AccessorDeclSyntax] {
    return [
      """
        get {
          accessorLog()
          return 1
        }
      """,
      """
        set {
          accessorLog()
        }
      """,
    ]
  }
}

public struct SomeConformanceMacro: ExtensionMacro {
  public static func expansion(
    of node: AttributeSyntax,
    attachedTo: some DeclGroupSyntax,
    providingExtensionsOf type: some TypeSyntaxProtocol,
    conformingTo protocols: [TypeSyntax],
    in context: some MacroExpansionContext
  ) throws -> [ExtensionDeclSyntax] {
    let ext: DeclSyntax = "extension \(type.trimmed): TestProto {}"
    return [ext.cast(ExtensionDeclSyntax.self)]
  }
}

public struct SomeMemberMacro: MemberMacro {
  public static func expansion(
    of node: AttributeSyntax,
    providingMembersOf declaration: some DeclGroupSyntax,
    in context: some MacroExpansionContext
  ) throws -> [DeclSyntax] {
    let newFunc: DeclSyntax =
      """
      func memberFunc() {
        memberLog()
      }
      """
    return [
      newFunc,
    ]
  }
}

public struct SomeMemberAttributeMacro: MemberAttributeMacro {
  public static func expansion(
    of node: AttributeSyntax,
    attachedTo parent: some DeclGroupSyntax,
    providingAttributesFor member: some DeclSyntaxProtocol,
    in context: some MacroExpansionContext
  ) throws -> [AttributeSyntax] {
    guard let varDecl = member.as(VariableDeclSyntax.self),
      let binding = varDecl.bindings.first,
      let identifier = binding.pattern.as(IdentifierPatternSyntax.self)?.identifier.text,
      identifier == "attachedMember"
    else {
      return []
    }

    return [AttributeSyntax(
      attributeName: SimpleTypeIdentifierSyntax(
        name: .identifier("AddOne")
      )
    )]
  }
}

public struct SomePeerMacro: PeerMacro {
  public static func expansion(
    of node: AttributeSyntax,
    providingPeersOf declaration: some DeclSyntaxProtocol,
    in context: some MacroExpansionContext
  ) throws -> [DeclSyntax] {
    return [
      """
      struct TestPeer {
        func peerFunc() {
          peerLog()
        }
      }
      """
    ]
  }
}

public struct SomePeerMemberMacro: PeerMacro {
  public static func expansion(
    of node: AttributeSyntax,
    providingPeersOf declaration: some DeclSyntaxProtocol,
    in context: some MacroExpansionContext
  ) throws -> [DeclSyntax] {
    return [
      """
      var peerMember: Int
      """
    ]
  }
}