@@ -48,28 +48,6 @@ extension Parser {
48
48
arena: self . arena
49
49
)
50
50
)
51
-
52
- // Before continuing to parse the next specification, we check that it's
53
- // also in the shorthand syntax and recover from it.
54
- if keepGoing != nil ,
55
- let ( _, handle) = self . at ( anyIn: AvailabilityArgumentKind . self)
56
- {
57
- var tokens = [ RawTokenSyntax] ( )
58
- tokens. append ( self . eat ( handle) )
59
- var recoveryProgress = LoopProgressCondition ( )
60
- while !self . at ( any: [ . eof, . comma, . rightParen] ) && recoveryProgress. evaluate ( currentToken) {
61
- tokens. append ( self . consumeAnyToken ( ) )
62
- }
63
- let syntax = RawTokenListSyntax ( elements: tokens, arena: self . arena)
64
- keepGoing = self . consume ( if: . comma)
65
- elements. append (
66
- RawAvailabilityArgumentSyntax (
67
- entry: . tokenList( syntax) ,
68
- trailingComma: keepGoing,
69
- arena: self . arena
70
- )
71
- )
72
- }
73
51
} while keepGoing != nil && availablityArgumentProgress. evaluate ( currentToken)
74
52
}
75
53
@@ -84,6 +62,8 @@ extension Parser {
84
62
case obsoleted
85
63
case unavailable
86
64
case noasync
65
+ case star
66
+ case identifier
87
67
88
68
init ? ( lexeme: Lexer . Lexeme ) {
89
69
switch lexeme {
@@ -94,6 +74,8 @@ extension Parser {
94
74
case RawTokenKindMatch ( . obsoleted) : self = . obsoleted
95
75
case RawTokenKindMatch ( . unavailable) : self = . unavailable
96
76
case RawTokenKindMatch ( . noasync) : self = . noasync
77
+ case RawTokenKindMatch ( . binaryOperator) where lexeme. tokenText == " * " : self = . star
78
+ case RawTokenKindMatch ( . identifier) : self = . identifier
97
79
default : return nil
98
80
}
99
81
}
@@ -107,100 +89,94 @@ extension Parser {
107
89
case . obsoleted: return . keyword( . obsoleted)
108
90
case . unavailable: return . keyword( . unavailable)
109
91
case . noasync: return . keyword( . noasync)
92
+ case . star: return . binaryOperator
93
+ case . identifier: return . identifier
110
94
}
111
95
}
112
96
}
113
97
114
- mutating func parseExtendedAvailabilitySpecList ( ) -> RawAvailabilitySpecListSyntax {
98
+ mutating func parseAvailabilityArgumentSpecList ( ) -> RawAvailabilitySpecListSyntax {
115
99
var elements = [ RawAvailabilityArgumentSyntax] ( )
100
+ var keepGoing : RawTokenSyntax ? = nil
116
101
117
- // Parse the platform from the first element.
118
- let platform = self . consumeAnyToken ( )
119
- var keepGoing : RawTokenSyntax ? = self . consume ( if : . comma )
120
- elements . append (
121
- RawAvailabilityArgumentSyntax (
122
- entry : . token ( platform ) ,
123
- trailingComma : keepGoing ,
124
- arena : self . arena
125
- )
126
- )
102
+ var loopProgressCondition = LoopProgressCondition ( )
103
+ LOOP: repeat {
104
+ let entry : RawAvailabilityArgumentSyntax . Entry
105
+ switch self . at ( anyIn : AvailabilityArgumentKind . self ) {
106
+ case ( . message , let handle ) ? ,
107
+ ( . renamed , let handle ) ? :
108
+ let argumentLabel = self . eat ( handle )
109
+ let ( unexpectedBeforeColon , colon ) = self . expect ( . colon )
110
+ // FIXME: Make sure this is a string literal with no interpolation.
111
+ let stringValue = self . consumeAnyToken ( )
127
112
128
- do {
129
- var loopProgressCondition = LoopProgressCondition ( )
130
- while keepGoing != nil && loopProgressCondition. evaluate ( currentToken) {
131
- let entry : RawAvailabilityArgumentSyntax . Entry
132
- switch self . at ( anyIn: AvailabilityArgumentKind . self) {
133
- case ( . message, let handle) ? ,
134
- ( . renamed, let handle) ? :
135
- let argumentLabel = self . eat ( handle)
136
- let ( unexpectedBeforeColon, colon) = self . expect ( . colon)
137
- // FIXME: Make sure this is a string literal with no interpolation.
138
- let stringValue = self . consumeAnyToken ( )
139
-
140
- entry = . availabilityLabeledArgument(
141
- RawAvailabilityLabeledArgumentSyntax (
142
- label: argumentLabel,
143
- unexpectedBeforeColon,
144
- colon: colon,
145
- value: . string( stringValue) ,
146
- arena: self . arena
147
- )
113
+ entry = . availabilityLabeledArgument(
114
+ RawAvailabilityLabeledArgumentSyntax (
115
+ label: argumentLabel,
116
+ unexpectedBeforeColon,
117
+ colon: colon,
118
+ value: . string( stringValue) ,
119
+ arena: self . arena
120
+ )
121
+ )
122
+ case ( . introduced, let handle) ? ,
123
+ ( . obsoleted, let handle) ? :
124
+ let argumentLabel = self . eat ( handle)
125
+ let ( unexpectedBeforeColon, colon) = self . expect ( . colon)
126
+ let version = self . parseVersionTuple ( )
127
+ entry = . availabilityLabeledArgument(
128
+ RawAvailabilityLabeledArgumentSyntax (
129
+ label: argumentLabel,
130
+ unexpectedBeforeColon,
131
+ colon: colon,
132
+ value: . version( version) ,
133
+ arena: self . arena
148
134
)
149
- case ( . introduced , let handle ) ? ,
150
- ( . obsoleted , let handle) ? :
151
- let argumentLabel = self . eat ( handle)
152
- let ( unexpectedBeforeColon , colon) = self . expect ( . colon)
135
+ )
136
+ case ( . deprecated , let handle) ? :
137
+ let argumentLabel = self . eat ( handle)
138
+ if let colon = self . consume ( if : . colon) {
153
139
let version = self . parseVersionTuple ( )
154
140
entry = . availabilityLabeledArgument(
155
141
RawAvailabilityLabeledArgumentSyntax (
156
142
label: argumentLabel,
157
- unexpectedBeforeColon,
158
143
colon: colon,
159
144
value: . version( version) ,
160
145
arena: self . arena
161
146
)
162
147
)
163
- case ( . deprecated, let handle) ? :
164
- let argumentLabel = self . eat ( handle)
165
- if let colon = self . consume ( if: . colon) {
166
- let version = self . parseVersionTuple ( )
167
- entry = . availabilityLabeledArgument(
168
- RawAvailabilityLabeledArgumentSyntax (
169
- label: argumentLabel,
170
- colon: colon,
171
- value: . version( version) ,
172
- arena: self . arena
173
- )
174
- )
175
- } else {
176
- entry = . token( argumentLabel)
177
- }
178
- case ( . unavailable, let handle) ? ,
179
- ( . noasync, let handle) ? :
180
- let argument = self . eat ( handle)
181
- // FIXME: Can we model this in SwiftSyntax by making the
182
- // 'labeled' argument part optional?
183
- entry = . token( argument)
184
- case nil :
185
- // Not sure what this label is but, let's just eat it and
186
- // keep going.
187
- var tokens = [ RawTokenSyntax] ( )
188
- while !self . at ( any: [ . eof, . comma, . rightParen] ) {
189
- tokens. append ( self . consumeAnyToken ( ) )
190
- }
191
- entry = . tokenList( RawTokenListSyntax ( elements: tokens, arena: self . arena) )
148
+ } else {
149
+ entry = . token( argumentLabel)
192
150
}
151
+ case ( . unavailable, let handle) ? ,
152
+ ( . noasync, let handle) ? :
153
+ let argument = self . eat ( handle)
154
+ // FIXME: Can we model this in SwiftSyntax by making the
155
+ // 'labeled' argument part optional?
156
+ entry = . token( argument)
157
+ case ( . star, _) ? :
158
+ entry = self . parseAvailabilitySpec ( )
159
+ case ( . identifier, let handle) ? :
160
+ if self . peek ( ) . rawTokenKind == . comma {
161
+ // An argument like `_iOS13Aligned` that isn't followed by a version.
162
+ let version = self . eat ( handle)
163
+ entry = . token( version)
164
+ } else {
165
+ entry = self . parseAvailabilitySpec ( )
166
+ }
167
+ case nil :
168
+ break LOOP
169
+ }
193
170
194
- keepGoing = self . consume ( if: . comma)
195
- elements. append (
196
- RawAvailabilityArgumentSyntax (
197
- entry: entry,
198
- trailingComma: keepGoing,
199
- arena: self . arena
200
- )
171
+ keepGoing = self . consume ( if: . comma)
172
+ elements. append (
173
+ RawAvailabilityArgumentSyntax (
174
+ entry: entry,
175
+ trailingComma: keepGoing,
176
+ arena: self . arena
201
177
)
202
- }
203
- }
178
+ )
179
+ } while keepGoing != nil && loopProgressCondition . evaluate ( currentToken )
204
180
return RawAvailabilitySpecListSyntax ( elements: elements, arena: self . arena)
205
181
}
206
182
0 commit comments