@@ -19,20 +19,12 @@ import SwiftIfConfig
1919@_spi ( RawSyntax) @_spi ( Compiler) import SwiftSyntax
2020
2121extension ASTGenVisitor {
22- /// E.g.:
23- /// ```
24- /// @available(macOS 10.12, iOS 13, *)
25- /// @available(macOS, introduced: 10.12)
26- /// ```
27- func generateAvailableAttr( attribute node: AttributeSyntax ) -> [ BridgedAvailableAttr ] {
28- guard let args = node. arguments else {
29- self . diagnose ( . expectedArgumentsInAttribute( node) )
30- return [ ]
31- }
32- guard let args = args. as ( AvailabilityArgumentListSyntax . self) else {
33- // TODO: Diagnose.
34- return [ ]
35- }
22+ /// Implementation detail for `generateAvailableAttr(attribute:)` and `generateSpecializeAttr(attribute:)`.
23+ func generateAvailableAttr(
24+ atLoc: BridgedSourceLoc ,
25+ range: BridgedSourceRange ,
26+ args: AvailabilityArgumentListSyntax
27+ ) -> [ BridgedAvailableAttr ] {
3628
3729 // Check if this is "shorthand" syntax.
3830 if let firstArg = args. first? . argument {
@@ -48,17 +40,20 @@ extension ASTGenVisitor {
4840 isShorthand = false
4941 }
5042 if isShorthand {
51- return self . generateAvailableAttrShorthand ( attribute : node )
43+ return self . generateAvailableAttrShorthand ( atLoc : atLoc , range : range , args : args )
5244 }
5345 }
5446
5547 // E.g.
5648 // @available(macOS, introduced: 10.12, deprecated: 11.2)
5749 // @available(*, unavailable, message: "out of service")
58- if let generated = self . generateAvailableAttrExtended ( attribute: node) {
59- return [ generated]
50+ let attr = self . generateAvailableAttrExtended ( atLoc: atLoc, range: range, args: args)
51+
52+ if let attr {
53+ return [ attr]
54+ } else {
55+ return [ ]
6056 }
61- return [ ]
6257 }
6358
6459 func generate( versionTuple node: VersionTupleSyntax ? ) -> VersionTuple ? {
@@ -68,13 +63,12 @@ extension ASTGenVisitor {
6863 return tuple
6964 }
7065
71- func generateAvailableAttrShorthand( attribute node: AttributeSyntax ) -> [ BridgedAvailableAttr ] {
72- let atLoc = self . generateSourceLoc ( node. atSign)
73- let range = self . generateAttrSourceRange ( node)
74- let specs = self . generateAvailabilitySpecList (
75- args: node. arguments!. cast ( AvailabilityArgumentListSyntax . self) ,
76- context: . availableAttr
77- )
66+ func generateAvailableAttrShorthand(
67+ atLoc: BridgedSourceLoc ,
68+ range: BridgedSourceRange ,
69+ args: AvailabilityArgumentListSyntax
70+ ) -> [ BridgedAvailableAttr ] {
71+ let specs = self . generateAvailabilitySpecList ( args: args, context: . availableAttr)
7872
7973 var result : [ BridgedAvailableAttr ] = [ ]
8074 for spec in specs {
@@ -103,8 +97,12 @@ extension ASTGenVisitor {
10397 return result
10498 }
10599
106- func generateAvailableAttrExtended( attribute node: AttributeSyntax ) -> BridgedAvailableAttr ? {
107- var args = node. arguments!. cast ( AvailabilityArgumentListSyntax . self) [ ... ]
100+ func generateAvailableAttrExtended(
101+ atLoc: BridgedSourceLoc ,
102+ range: BridgedSourceRange ,
103+ args: AvailabilityArgumentListSyntax
104+ ) -> BridgedAvailableAttr ? {
105+ var args = args [ ... ]
108106
109107 // The platfrom.
110108 guard let platformToken = args. popFirst ( ) ? . argument. as ( TokenSyntax . self) else {
@@ -234,8 +232,8 @@ extension ASTGenVisitor {
234232
235233 return BridgedAvailableAttr . createParsed (
236234 self . ctx,
237- atLoc: self . generateSourceLoc ( node . atSign ) ,
238- range: self . generateAttrSourceRange ( node ) ,
235+ atLoc: atLoc ,
236+ range: range ,
239237 domainString: platformStr. bridged,
240238 domainLoc: platformLoc,
241239 kind: attrKind,
@@ -274,6 +272,8 @@ extension ASTGenVisitor {
274272
275273 enum AvailabilitySpecListContext {
276274 case availableAttr
275+ case poundAvailable
276+ case poundUnavailable
277277 case macro
278278 }
279279
@@ -362,6 +362,76 @@ extension ASTGenVisitor {
362362
363363 return result
364364 }
365+
366+ typealias GeneratedPlatformVersion = ( platform: BridgedPlatformKind , version: BridgedVersionTuple )
367+
368+ func generate( platformVersionList node: PlatformVersionItemListSyntax ) -> [ GeneratedPlatformVersion ] {
369+ var result : [ GeneratedPlatformVersion ] = [ ]
370+
371+ for element in node {
372+ let platformVersionNode = element. platformVersion
373+ let platformName = platformVersionNode. platform. rawText
374+ let version = self . generate ( versionTuple: platformVersionNode. version) ? . bridged ?? BridgedVersionTuple ( )
375+
376+ // If the name is a platform name, use it.
377+ let platform = BridgedPlatformKind ( from: platformName. bridged)
378+ if platform != . none {
379+ result. append ( ( platform: platform, version: version) )
380+ continue
381+ }
382+
383+ // If there's matching macro, use it.
384+ let expanded = ctx. availabilityMacroMap. get (
385+ name: platformName. bridged,
386+ version: version
387+ )
388+ if !expanded. isEmpty {
389+ expanded. withElements ( ofType: UnsafeRawPointer . self) { buffer in
390+ for ptr in buffer {
391+ let spec = BridgedAvailabilitySpec ( raw: UnsafeMutableRawPointer ( mutating: ptr) )
392+ let platform = spec. platform
393+ guard platform != . none else {
394+ continue
395+ }
396+ result. append ( ( platform: platform, version: spec. version) )
397+ }
398+ }
399+ continue
400+ }
401+
402+ // Error.
403+ // TODO: Diagnostics
404+ fatalError ( " invalid platform name " )
405+ }
406+ return result
407+ }
408+
409+ func generate( availabilityCondition node: AvailabilityConditionSyntax ) -> BridgedPoundAvailableInfo {
410+ let specListContext : AvailabilitySpecListContext
411+ switch node. availabilityKeyword. rawText {
412+ case " #available " :
413+ specListContext = . poundAvailable
414+ case " #unavailable " :
415+ specListContext = . poundUnavailable
416+ default :
417+ // TODO: Diagnostics?
418+ fatalError ( " invalid availabilityKeyword " )
419+ }
420+ let specs = self . generateAvailabilitySpecList (
421+ args: node. availabilityArguments,
422+ context: specListContext
423+ )
424+
425+ return . createParsed(
426+ self . ctx,
427+ poundLoc: self . generateSourceLoc ( node. availabilityKeyword) ,
428+ lParenLoc: self . generateSourceLoc ( node. leftParen) ,
429+ specs: specs. lazy. bridgedArray ( in: self ) ,
430+ rParenLoc: self . generateSourceLoc ( node. rightParen) ,
431+ isUnavailable: specListContext == . poundUnavailable
432+ )
433+ }
434+
365435}
366436
367437/// Parse an argument for '-define-availability' compiler option.
0 commit comments