@@ -70,11 +70,11 @@ extension ASTGenVisitor {
70
70
switch keyword {
71
71
case . selector:
72
72
let selectorExpr = self . generateObjCSelectorExpr ( freestandingMacroExpansion: node)
73
- return . generated( . expr( selectorExpr. asExpr ) )
73
+ return . generated( . expr( selectorExpr) )
74
74
75
75
case . keyPath:
76
76
let keypathExpr = self . generateObjCKeyPathExpr ( freestandingMacroExpansion: node)
77
- return . generated( . expr( keypathExpr. asExpr ) )
77
+ return . generated( . expr( keypathExpr) )
78
78
79
79
case . assert where ctx. langOptsHasFeature ( . StaticAssert) :
80
80
let assertStmtOpt = self . generatePoundAssertStmt ( freestandingMacroExpansion: node)
@@ -194,11 +194,98 @@ extension ASTGenVisitor {
194
194
)
195
195
}
196
196
197
- func generateObjCSelectorExpr( freestandingMacroExpansion node: some FreestandingMacroExpansionSyntax ) -> BridgedObjCSelectorExpr {
198
- fatalError ( " unimplemented (objc selector) " )
197
+ func generateObjCSelectorExpr( freestandingMacroExpansion node: some FreestandingMacroExpansionSyntax ) -> BridgedExpr {
198
+ var args = node. arguments [ ... ]
199
+ guard let arg = args. popFirst ( ) else {
200
+ // TODO: Diagnose
201
+ fatalError ( " expected an argument for #selector " )
202
+ // return ErrorExpr
203
+ }
204
+ let kind : BridgedObjCSelectorKind
205
+ switch arg. label? . rawText {
206
+ case nil : kind = . method
207
+ case " getter " : kind = . getter
208
+ case " setter " : kind = . setter
209
+ case _? :
210
+ // TODO: Diagnose
211
+ fatalError ( " unexpected argument label in #selector " )
212
+ // return ErrorExpr
213
+ }
214
+ let expr = self . generate ( expr: arg. expression)
215
+ guard args. isEmpty else {
216
+ // TODO: Diagnose
217
+ fatalError ( " unexpected argument in #selector " )
218
+ // return ErrorExpr
219
+ }
220
+ return BridgedObjCSelectorExpr . createParsed (
221
+ self . ctx,
222
+ kind: kind,
223
+ keywordLoc: self . generateSourceLoc ( node. pound) ,
224
+ lParenLoc: self . generateSourceLoc ( node. leftParen) ,
225
+ modifierLoc: self . generateSourceLoc ( arg. label) ,
226
+ subExpr: expr,
227
+ rParenLoc: self . generateSourceLoc ( node. rightParen)
228
+ ) . asExpr
199
229
}
200
230
201
- func generateObjCKeyPathExpr( freestandingMacroExpansion node: some FreestandingMacroExpansionSyntax ) -> BridgedKeyPathExpr {
202
- fatalError ( " unimplemented (objc keypath) " )
231
+ func generateObjCKeyPathExpr( freestandingMacroExpansion node: some FreestandingMacroExpansionSyntax ) -> BridgedExpr {
232
+
233
+ var names : [ BridgedDeclNameRef ] = [ ]
234
+ var nameLocs : [ BridgedDeclNameLoc ] = [ ]
235
+
236
+ func collectNames( expr node: ExprSyntax ) -> Bool {
237
+ if let declRefExpr = node. as ( DeclReferenceExprSyntax . self) {
238
+ let nameAndLoc = self . generateDeclNameRef ( declReferenceExpr: declRefExpr)
239
+ names. append ( nameAndLoc. name)
240
+ nameLocs. append ( nameAndLoc. loc)
241
+ return false
242
+ }
243
+ if let memberExpr = node. as ( MemberAccessExprSyntax . self) {
244
+ guard let base = memberExpr. base else {
245
+ // TODO: Diagnose
246
+ fatalError ( " unexpected expression in #keyPath " )
247
+ }
248
+ if collectNames ( expr: base) {
249
+ return true
250
+ }
251
+ let nameAndLoc = self . generateDeclNameRef ( declReferenceExpr: memberExpr. declName)
252
+ names. append ( nameAndLoc. name)
253
+ nameLocs. append ( nameAndLoc. loc)
254
+ return false
255
+ }
256
+ // TODO: Diagnose
257
+ fatalError ( " unexpected expression in #keyPath " )
258
+ // return true
259
+ }
260
+
261
+ var args = node. arguments [ ... ]
262
+ guard let arg = args. popFirst ( ) else {
263
+ // TODO: Diagnose
264
+ fatalError ( " expected an argument for #keyPath " )
265
+ // return ErrorExpr
266
+ }
267
+ guard arg. label == nil else {
268
+ // TODO: Diagnose
269
+ fatalError ( " unexpected argument label #keyPath " )
270
+
271
+ }
272
+ if /*hadError=*/collectNames ( expr: arg. expression) {
273
+ return BridgedErrorExpr . create ( self . ctx, loc: self . generateSourceRange ( node) ) . asExpr;
274
+ }
275
+
276
+ guard args. isEmpty else {
277
+ // TODO: Diagnose
278
+ fatalError ( " unexpected argument in #keyPath " )
279
+ // return ErrorExpr
280
+ }
281
+
282
+ return BridgedKeyPathExpr . createParsedPoundKeyPath (
283
+ self . ctx,
284
+ poundLoc: self . generateSourceLoc ( node. pound) ,
285
+ lParenLoc: self . generateSourceLoc ( node. leftParen) ,
286
+ names: names. lazy. bridgedArray ( in: self ) ,
287
+ nameLocs: nameLocs. lazy. bridgedArray ( in: self ) ,
288
+ rParenLoc: self . generateSourceLoc ( node. rightParen)
289
+ ) . asExpr
203
290
}
204
291
}
0 commit comments