@@ -70,11 +70,11 @@ extension ASTGenVisitor {
7070 switch keyword {
7171 case . selector:
7272 let selectorExpr = self . generateObjCSelectorExpr ( freestandingMacroExpansion: node)
73- return . generated( . expr( selectorExpr. asExpr ) )
73+ return . generated( . expr( selectorExpr) )
7474
7575 case . keyPath:
7676 let keypathExpr = self . generateObjCKeyPathExpr ( freestandingMacroExpansion: node)
77- return . generated( . expr( keypathExpr. asExpr ) )
77+ return . generated( . expr( keypathExpr) )
7878
7979 case . assert where ctx. langOptsHasFeature ( . StaticAssert) :
8080 let assertStmtOpt = self . generatePoundAssertStmt ( freestandingMacroExpansion: node)
@@ -119,6 +119,15 @@ extension ASTGenVisitor {
119119 // return
120120 }
121121
122+ guard
123+ node. genericArgumentClause == nil ,
124+ node. trailingClosure == nil ,
125+ node. additionalTrailingClosures. isEmpty
126+ else {
127+ // TODO: Diagnose.
128+ fatalError ( " #error/#warning with generic specialization " )
129+ }
130+
122131 guard node. arguments. count == 1 ,
123132 let arg = node. arguments. first,
124133 arg. label == nil ,
@@ -194,11 +203,115 @@ extension ASTGenVisitor {
194203 )
195204 }
196205
197- func generateObjCSelectorExpr( freestandingMacroExpansion node: some FreestandingMacroExpansionSyntax ) -> BridgedObjCSelectorExpr {
198- fatalError ( " unimplemented (objc selector) " )
206+ func generateObjCSelectorExpr( freestandingMacroExpansion node: some FreestandingMacroExpansionSyntax ) -> BridgedExpr {
207+ guard
208+ node. genericArgumentClause == nil ,
209+ node. trailingClosure == nil ,
210+ node. additionalTrailingClosures. isEmpty
211+ else {
212+ // TODO: Diagnose.
213+ fatalError ( " #selector with generic specialization " )
214+ }
215+
216+ var args = node. arguments [ ... ]
217+ guard let arg = args. popFirst ( ) else {
218+ // TODO: Diagnose
219+ fatalError ( " expected an argument for #selector " )
220+ // return ErrorExpr
221+ }
222+ let kind : BridgedObjCSelectorKind
223+ switch arg. label? . rawText {
224+ case nil : kind = . method
225+ case " getter " : kind = . getter
226+ case " setter " : kind = . setter
227+ case _? :
228+ // TODO: Diagnose
229+ fatalError ( " unexpected argument label in #selector " )
230+ // return ErrorExpr
231+ }
232+ let expr = self . generate ( expr: arg. expression)
233+ guard args. isEmpty else {
234+ // TODO: Diagnose
235+ fatalError ( " unexpected argument in #selector " )
236+ // return ErrorExpr
237+ }
238+ return BridgedObjCSelectorExpr . createParsed (
239+ self . ctx,
240+ kind: kind,
241+ keywordLoc: self . generateSourceLoc ( node. pound) ,
242+ lParenLoc: self . generateSourceLoc ( node. leftParen) ,
243+ modifierLoc: self . generateSourceLoc ( arg. label) ,
244+ subExpr: expr,
245+ rParenLoc: self . generateSourceLoc ( node. rightParen)
246+ ) . asExpr
199247 }
200248
201- func generateObjCKeyPathExpr( freestandingMacroExpansion node: some FreestandingMacroExpansionSyntax ) -> BridgedKeyPathExpr {
202- fatalError ( " unimplemented (objc keypath) " )
249+ func generateObjCKeyPathExpr( freestandingMacroExpansion node: some FreestandingMacroExpansionSyntax ) -> BridgedExpr {
250+ guard
251+ node. genericArgumentClause == nil ,
252+ node. trailingClosure == nil ,
253+ node. additionalTrailingClosures. isEmpty
254+ else {
255+ // TODO: Diagnose.
256+ fatalError ( " #keyPath with generic specialization " )
257+ }
258+
259+ var names : [ BridgedDeclNameRef ] = [ ]
260+ var nameLocs : [ BridgedDeclNameLoc ] = [ ]
261+
262+ func collectNames( expr node: ExprSyntax ) -> Bool {
263+ if let declRefExpr = node. as ( DeclReferenceExprSyntax . self) {
264+ let nameAndLoc = self . generateDeclNameRef ( declReferenceExpr: declRefExpr)
265+ names. append ( nameAndLoc. name)
266+ nameLocs. append ( nameAndLoc. loc)
267+ return false
268+ }
269+ if let memberExpr = node. as ( MemberAccessExprSyntax . self) {
270+ guard let base = memberExpr. base else {
271+ // TODO: Diagnose
272+ fatalError ( " unexpected expression in #keyPath " )
273+ }
274+ if collectNames ( expr: base) {
275+ return true
276+ }
277+ let nameAndLoc = self . generateDeclNameRef ( declReferenceExpr: memberExpr. declName)
278+ names. append ( nameAndLoc. name)
279+ nameLocs. append ( nameAndLoc. loc)
280+ return false
281+ }
282+ // TODO: Diagnose
283+ fatalError ( " unexpected expression in #keyPath " )
284+ // return true
285+ }
286+
287+ var args = node. arguments [ ... ]
288+ guard let arg = args. popFirst ( ) else {
289+ // TODO: Diagnose
290+ fatalError ( " expected an argument for #keyPath " )
291+ // return ErrorExpr
292+ }
293+ guard arg. label == nil else {
294+ // TODO: Diagnose
295+ fatalError ( " unexpected argument label #keyPath " )
296+
297+ }
298+ if /*hadError=*/collectNames ( expr: arg. expression) {
299+ return BridgedErrorExpr . create ( self . ctx, loc: self . generateSourceRange ( node) ) . asExpr;
300+ }
301+
302+ guard args. isEmpty else {
303+ // TODO: Diagnose
304+ fatalError ( " unexpected argument in #keyPath " )
305+ // return ErrorExpr
306+ }
307+
308+ return BridgedKeyPathExpr . createParsedPoundKeyPath (
309+ self . ctx,
310+ poundLoc: self . generateSourceLoc ( node. pound) ,
311+ lParenLoc: self . generateSourceLoc ( node. leftParen) ,
312+ names: names. lazy. bridgedArray ( in: self ) ,
313+ nameLocs: nameLocs. lazy. bridgedArray ( in: self ) ,
314+ rParenLoc: self . generateSourceLoc ( node. rightParen)
315+ ) . asExpr
203316 }
204317}
0 commit comments