17
17
#endif
18
18
19
19
extension Parser {
20
- mutating func parseAttributeList( ) -> RawAttributeListSyntax {
21
- guard self . at ( . atSign, . poundIf) else {
22
- return self . emptyCollection ( RawAttributeListSyntax . self)
20
+ private mutating func parseAttributeListElement( ) -> RawAttributeListSyntax . Element {
21
+ if self . at ( . poundIf) {
22
+ // 'consumeIfConfigOfAttributes()' check in 'parseAttributeList()' already guarantees
23
+ // that this '#if' only contains attribute list elements. We don't check
24
+ // `consumeIfConfigOfAttributes()` here again because it's not only redundant, but it
25
+ // does *not* work for cases like:
26
+ //
27
+ // #if COND1
28
+ // @attr
29
+ // #if COND2
30
+ // #endif
31
+ // #endif
32
+ // func fn() {}
33
+ //
34
+ // In such cases, the second `#if` is not `consumeIfConfigOfAttributes()`.
35
+ return . ifConfigDecl(
36
+ self . parsePoundIfDirective { ( parser, _) -> RawAttributeListSyntax . Element in
37
+ return parser. parseAttributeListElement ( )
38
+ } syntax: { parser, attributes in
39
+ return . attributes( RawAttributeListSyntax ( elements: attributes, arena: parser. arena) )
40
+ }
41
+ )
42
+ } else {
43
+ return . attribute( self . parseAttribute ( ) )
23
44
}
45
+ }
24
46
47
+ mutating func parseAttributeList( ) -> RawAttributeListSyntax {
25
48
var elements = [ RawAttributeListSyntax . Element] ( )
49
+
50
+ func shouldContinue( ) -> Bool {
51
+ if self . at ( . atSign) {
52
+ return true
53
+ }
54
+ if self . at ( . poundIf) && self . withLookahead ( { $0. consumeIfConfigOfAttributes ( ) } ) {
55
+ return true
56
+ }
57
+ return false
58
+ }
59
+
26
60
var loopProgress = LoopProgressCondition ( )
27
- repeat {
28
- let attribute = self . parseAttribute ( )
61
+ while self . hasProgressed ( & loopProgress ) && shouldContinue ( ) {
62
+ let attribute = self . parseAttributeListElement ( )
29
63
elements. append ( attribute)
30
- } while self . at ( . atSign, . poundIf) && self . hasProgressed ( & loopProgress)
31
- return RawAttributeListSyntax ( elements: elements, arena: self . arena)
64
+ }
65
+ if elements. isEmpty {
66
+ return self . emptyCollection ( RawAttributeListSyntax . self)
67
+ } else {
68
+ return RawAttributeListSyntax ( elements: elements, arena: self . arena)
69
+ }
32
70
}
33
71
}
34
72
@@ -148,7 +186,7 @@ extension Parser {
148
186
parseMissingArguments: (
149
187
( inout Parser ) -> ( unexpectedBefore: RawUnexpectedNodesSyntax ? , arguments: RawAttributeSyntax . Arguments )
150
188
) ? = nil
151
- ) -> RawAttributeListSyntax . Element {
189
+ ) -> RawAttributeSyntax {
152
190
var ( unexpectedBeforeAtSign, atSign) = self . expect ( . atSign)
153
191
if atSign. trailingTriviaByteLength > 0 || self . currentToken. leadingTriviaByteLength > 0 {
154
192
let diagnostic = TokenDiagnostic (
@@ -163,9 +201,7 @@ extension Parser {
163
201
case . required:
164
202
shouldParseArgument = true
165
203
case . customAttribute:
166
- shouldParseArgument =
167
- self . withLookahead { $0. atAttributeOrSpecifierArgument ( ) }
168
- && self . at ( TokenSpec ( . leftParen, allowAtStartOfLine: false ) )
204
+ shouldParseArgument = self . withLookahead { $0. atAttributeOrSpecifierArgument ( ) }
169
205
case . optional:
170
206
shouldParseArgument = self . at ( . leftParen)
171
207
case . noArgument:
@@ -190,46 +226,32 @@ extension Parser {
190
226
( unexpectedBeforeArguments, argument) = parseArguments ( & self )
191
227
}
192
228
let ( unexpectedBeforeRightParen, rightParen) = self . expect ( . rightParen)
193
- return . attribute(
194
- RawAttributeSyntax (
195
- unexpectedBeforeAtSign,
196
- atSign: atSign,
197
- attributeName: attributeName,
198
- unexpectedBeforeLeftParen,
199
- leftParen: leftParen,
200
- unexpectedBeforeArguments,
201
- arguments: argument,
202
- unexpectedBeforeRightParen,
203
- rightParen: rightParen,
204
- arena: self . arena
205
- )
229
+ return RawAttributeSyntax (
230
+ unexpectedBeforeAtSign,
231
+ atSign: atSign,
232
+ attributeName: attributeName,
233
+ unexpectedBeforeLeftParen,
234
+ leftParen: leftParen,
235
+ unexpectedBeforeArguments,
236
+ arguments: argument,
237
+ unexpectedBeforeRightParen,
238
+ rightParen: rightParen,
239
+ arena: self . arena
206
240
)
207
241
} else {
208
- return . attribute(
209
- RawAttributeSyntax (
210
- unexpectedBeforeAtSign,
211
- atSign: atSign,
212
- attributeName: attributeName,
213
- leftParen: nil ,
214
- arguments: nil ,
215
- rightParen: nil ,
216
- arena: self . arena
217
- )
242
+ return RawAttributeSyntax (
243
+ unexpectedBeforeAtSign,
244
+ atSign: atSign,
245
+ attributeName: attributeName,
246
+ leftParen: nil ,
247
+ arguments: nil ,
248
+ rightParen: nil ,
249
+ arena: self . arena
218
250
)
219
251
}
220
252
}
221
253
222
- mutating func parseAttribute( ) -> RawAttributeListSyntax . Element {
223
- if self . at ( . poundIf) {
224
- return . ifConfigDecl(
225
- self . parsePoundIfDirective { ( parser, _) -> RawAttributeListSyntax . Element in
226
- return parser. parseAttribute ( )
227
- } syntax: { parser, attributes in
228
- return . attributes( RawAttributeListSyntax ( elements: attributes, arena: parser. arena) )
229
- }
230
- )
231
- }
232
-
254
+ mutating func parseAttribute( ) -> RawAttributeSyntax {
233
255
switch peek ( isAtAnyIn: DeclarationAttributeWithSpecialSyntax . self) {
234
256
case . abi:
235
257
return parseAttribute ( argumentMode: . required) { parser in
@@ -299,17 +321,15 @@ extension Parser {
299
321
case . rethrows:
300
322
let ( unexpectedBeforeAtSign, atSign) = self . expect ( . atSign)
301
323
let ( unexpectedBeforeAttributeName, attributeName) = self . expect ( TokenSpec ( . rethrows, remapping: . identifier) )
302
- return . attribute(
303
- RawAttributeSyntax (
304
- unexpectedBeforeAtSign,
305
- atSign: atSign,
306
- unexpectedBeforeAttributeName,
307
- attributeName: RawIdentifierTypeSyntax ( name: attributeName, genericArgumentClause: nil , arena: self . arena) ,
308
- leftParen: nil ,
309
- arguments: nil ,
310
- rightParen: nil ,
311
- arena: self . arena
312
- )
324
+ return RawAttributeSyntax (
325
+ unexpectedBeforeAtSign,
326
+ atSign: atSign,
327
+ unexpectedBeforeAttributeName,
328
+ attributeName: RawIdentifierTypeSyntax ( name: attributeName, genericArgumentClause: nil , arena: self . arena) ,
329
+ leftParen: nil ,
330
+ arguments: nil ,
331
+ rightParen: nil ,
332
+ arena: self . arena
313
333
)
314
334
case . Sendable:
315
335
return parseAttribute ( argumentMode: . noArgument) { parser in
@@ -1023,6 +1043,10 @@ extension Parser {
1023
1043
1024
1044
extension Parser . Lookahead {
1025
1045
mutating func atAttributeOrSpecifierArgument( ) -> Bool {
1046
+ if !self . at ( TokenSpec ( . leftParen, allowAtStartOfLine: false ) ) {
1047
+ return false
1048
+ }
1049
+
1026
1050
var lookahead = self . lookahead ( )
1027
1051
lookahead. skipSingle ( )
1028
1052
@@ -1055,9 +1079,7 @@ extension Parser.Lookahead {
1055
1079
return false
1056
1080
}
1057
1081
1058
- if self . at ( TokenSpec ( . leftParen, allowAtStartOfLine: false ) )
1059
- && self . withLookahead ( { $0. atAttributeOrSpecifierArgument ( ) } )
1060
- {
1082
+ if self . withLookahead ( { $0. atAttributeOrSpecifierArgument ( ) } ) {
1061
1083
self . skipSingle ( )
1062
1084
}
1063
1085
0 commit comments