@@ -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)
@@ -194,11 +194,98 @@ extension ASTGenVisitor {
194194 )
195195 }
196196
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
199229 }
200230
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
203290 }
204291}
0 commit comments