@@ -53,15 +53,9 @@ extension TokenConsumer {
53
53
}
54
54
55
55
mutating func atStartOfDeclaration(
56
- isAtTopLevel: Bool = false ,
57
56
allowInitDecl: Bool = true ,
58
- allowRecovery: Bool = false ,
59
- requiresDecl: Bool = false ,
57
+ requiresDecl: Bool = false
60
58
) -> Bool {
61
- if self . at ( . poundIf) {
62
- return true
63
- }
64
-
65
59
var subparser = self . lookahead ( )
66
60
67
61
var hasAttribute = false
@@ -71,7 +65,6 @@ extension TokenConsumer {
71
65
_ = subparser. consumeAttributeList ( )
72
66
hasAttribute = true
73
67
} else if subparser. at ( . poundIf) && subparser. consumeIfConfigOfAttributes ( ) {
74
- subparser. skipSingle ( )
75
68
hasAttribute = true
76
69
} else {
77
70
break
@@ -106,17 +99,7 @@ extension TokenConsumer {
106
99
}
107
100
}
108
101
109
- let declStartKeyword : DeclarationKeyword ?
110
- if allowRecovery {
111
- declStartKeyword =
112
- subparser. canRecoverTo (
113
- anyIn: DeclarationKeyword . self,
114
- overrideRecoveryPrecedence: isAtTopLevel ? nil : . closingBrace
115
- ) ? . 0
116
- } else {
117
- declStartKeyword = subparser. at ( anyIn: DeclarationKeyword . self) ? . 0
118
- }
119
- switch declStartKeyword {
102
+ switch subparser. at ( anyIn: DeclarationKeyword . self) ? . 0 {
120
103
case . lhs( . actor ) :
121
104
// actor Foo {}
122
105
if subparser. peek ( ) . rawTokenKind == . identifier {
@@ -128,7 +111,7 @@ extension TokenConsumer {
128
111
var lookahead = subparser. lookahead ( )
129
112
repeat {
130
113
lookahead. consumeAnyToken ( )
131
- } while lookahead. atStartOfDeclaration ( isAtTopLevel : isAtTopLevel , allowInitDecl: allowInitDecl)
114
+ } while lookahead. atStartOfDeclaration ( allowInitDecl: allowInitDecl)
132
115
return lookahead. at ( . identifier)
133
116
case . lhs( . case) :
134
117
// When 'case' appears inside a function, it's probably a switch
@@ -177,9 +160,8 @@ extension TokenConsumer {
177
160
if subparser. at ( anyIn: ContextualDeclKeyword . self) ? . 0 != nil {
178
161
subparser. consumeAnyToken ( )
179
162
return subparser. atStartOfDeclaration (
180
- isAtTopLevel: isAtTopLevel,
181
163
allowInitDecl: allowInitDecl,
182
- allowRecovery : allowRecovery
164
+ requiresDecl : requiresDecl
183
165
)
184
166
}
185
167
if requiresDecl {
@@ -278,50 +260,6 @@ extension Parser {
278
260
/// - Parameter context: Describes the code around the declaration being parsed. This affects how the parser tries
279
261
/// to recover from malformed syntax in the declaration.
280
262
mutating func parseDeclaration( in context: DeclarationParseContext = . topLevelOrCodeBlock) -> RawDeclSyntax {
281
- // If we are at a `#if` of attributes, the `#if` directive should be
282
- // parsed when we're parsing the attributes.
283
- if self . at ( . poundIf) && !self . withLookahead ( { $0. consumeIfConfigOfAttributes ( ) } ) {
284
- let directive = self . parsePoundIfDirective { ( parser, _) in
285
- let parsedDecl = parser. parseDeclaration ( )
286
- let semicolon = parser. consume ( if: . semicolon)
287
- return RawMemberBlockItemSyntax (
288
- decl: parsedDecl,
289
- semicolon: semicolon,
290
- arena: parser. arena
291
- )
292
- } addSemicolonIfNeeded: { lastElement, newItemAtStartOfLine, newItem, parser in
293
- if lastElement. semicolon == nil && !newItemAtStartOfLine && !newItem. decl. is ( RawUnexpectedCodeDeclSyntax . self) {
294
- return RawMemberBlockItemSyntax (
295
- lastElement. unexpectedBeforeDecl,
296
- decl: lastElement. decl,
297
- lastElement. unexpectedBetweenDeclAndSemicolon,
298
- semicolon: parser. missingToken ( . semicolon) ,
299
- lastElement. unexpectedAfterSemicolon,
300
- arena: parser. arena
301
- )
302
- } else {
303
- return nil
304
- }
305
- } syntax: { parser, elements in
306
- return . decls( RawMemberBlockItemListSyntax ( elements: elements, arena: parser. arena) )
307
- }
308
- if !context. allowsIfConfigDecl {
309
- // Convert the IfConfig to unexpected syntax around the first decl inside it, if any.
310
- return directive. makeUnexpectedKeepingFirstNode ( of: RawDeclSyntax . self, arena: self . arena) { node in
311
- return !node. is ( RawIfConfigDeclSyntax . self)
312
- } makeMissing: {
313
- return RawDeclSyntax (
314
- RawMissingDeclSyntax (
315
- attributes: self . emptyCollection ( RawAttributeListSyntax . self) ,
316
- modifiers: self . emptyCollection ( RawDeclModifierListSyntax . self) ,
317
- arena: self . arena
318
- )
319
- )
320
- }
321
- }
322
- return RawDeclSyntax ( directive)
323
- }
324
-
325
263
let attrs = DeclAttributes (
326
264
attributes: self . parseAttributeList ( ) ,
327
265
modifiers: self . parseDeclModifierList ( )
@@ -992,7 +930,7 @@ extension Parser {
992
930
}
993
931
994
932
extension Parser {
995
- mutating func parseMemberBlockItem( ) -> RawMemberBlockItemSyntax ? {
933
+ mutating func parseMemberBlockItem( until stopCondition : ( inout Parser ) -> Bool ) -> RawMemberBlockItemSyntax ? {
996
934
let startToken = self . currentToken
997
935
if let syntax = self . loadCurrentSyntaxNodeFromCache ( for: . memberBlockItem) {
998
936
self . registerNodeForIncrementalParse ( node: syntax. raw, startToken: startToken)
@@ -1013,35 +951,47 @@ extension Parser {
1013
951
}
1014
952
1015
953
let decl : RawDeclSyntax
954
+ let attachSemi : Bool
1016
955
if self . at ( . poundSourceLocation) {
1017
956
decl = RawDeclSyntax ( self . parsePoundSourceLocationDirective ( ) )
1018
- } else if self . atStartOfDeclaration ( isAtTopLevel: false , allowInitDecl: true , requiresDecl: true ) {
957
+ attachSemi = false
958
+ } else if self . at ( . poundIf) && !self . withLookahead ( { $0. consumeIfConfigOfAttributes ( ) } ) {
959
+ decl = RawDeclSyntax ( self . parsePoundIfDirective { parser in
960
+ return . decls( parser. parseMemberDeclList ( until: { $0. atEndOfIfConfigClauseBody ( ) } ) )
961
+ } )
962
+ attachSemi = false
963
+ } else if self . atStartOfDeclaration ( allowInitDecl: true , requiresDecl: true ) {
1019
964
decl = self . parseDeclaration ( in: . memberDeclList)
965
+ attachSemi = true
1020
966
} else {
1021
967
decl = RawDeclSyntax (
1022
968
self . parseUnexpectedCodeDeclaration (
1023
- isAtTopLevel: false ,
1024
969
allowInitDecl: true ,
1025
970
requiresDecl: true ,
1026
- skipToDeclOnly: true
971
+ skipToDeclOnly: true ,
972
+ until: stopCondition
1027
973
)
1028
974
)
1029
- }
1030
-
1031
- if decl. isEmpty && !self . at ( . semicolon) {
1032
- return nil
975
+ attachSemi = true
1033
976
}
1034
977
1035
978
let semi : RawTokenSyntax ?
1036
- if !decl. isEmpty {
1037
- semi = self . consume ( if: . semicolon)
979
+ var trailingSemis : [ RawTokenSyntax ] = [ ]
980
+ if attachSemi {
981
+ if !decl. isEmpty {
982
+ semi = self . consume ( if: . semicolon)
983
+ } else {
984
+ semi = nil
985
+ }
986
+ while let trailingSemi = self . consume ( if: . semicolon) {
987
+ trailingSemis. append ( trailingSemi)
988
+ }
1038
989
} else {
1039
- // orphan ';' case. Put it to "unexpected" nodes.
1040
990
semi = nil
1041
991
}
1042
- var trailingSemis : [ RawTokenSyntax ] = [ ]
1043
- while let trailingSemi = self . consume ( if : . semicolon ) {
1044
- trailingSemis . append ( trailingSemi )
992
+
993
+ if decl . isEmpty && semi == nil && trailingSemis . isEmpty {
994
+ return nil
1045
995
}
1046
996
1047
997
let result = RawMemberBlockItemSyntax (
@@ -1056,13 +1006,13 @@ extension Parser {
1056
1006
return result
1057
1007
}
1058
1008
1059
- mutating func parseMemberDeclList( ) -> RawMemberBlockItemListSyntax {
1009
+ mutating func parseMemberDeclList( until stopCondition : ( inout Parser ) -> Bool = { $0 . at ( . rightBrace ) } ) -> RawMemberBlockItemListSyntax {
1060
1010
var elements = [ RawMemberBlockItemSyntax] ( )
1061
1011
do {
1062
1012
var loopProgress = LoopProgressCondition ( )
1063
- while !self . at ( . endOfFile, . rightBrace , . poundEndif ) && self . hasProgressed ( & loopProgress) {
1013
+ while !self . at ( . endOfFile) && !stopCondition ( & self ) && self . hasProgressed ( & loopProgress) {
1064
1014
let newItemAtStartOfLine = self . atStartOfLine
1065
- guard let newElement = self . parseMemberBlockItem ( ) else {
1015
+ guard let newElement = self . parseMemberBlockItem ( until : stopCondition ) else {
1066
1016
break
1067
1017
}
1068
1018
if let lastItem = elements. last,
@@ -2380,52 +2330,42 @@ extension Parser {
2380
2330
)
2381
2331
}
2382
2332
2333
+ /// Eat tokens until a start of decl, or if `skipToDeclOnly` is not set until
2334
+ /// a start of statement or expression.
2335
+ /// Returns consumed tokens as a `RawUnexpectedCodeDeclSyntax` declaration.
2383
2336
mutating func parseUnexpectedCodeDeclaration(
2384
- isAtTopLevel: Bool ,
2385
2337
allowInitDecl: Bool ,
2386
2338
requiresDecl: Bool ,
2387
2339
skipToDeclOnly: Bool ,
2340
+ until stopCondition: ( inout Parser ) -> Bool
2388
2341
) -> RawUnexpectedCodeDeclSyntax {
2389
- let numTokensToSkip = withLookahead { ( lookahead) -> Int in
2390
- while !lookahead. at ( . endOfFile, . semicolon) {
2391
- if lookahead. at ( . poundElse, . poundElseif, . poundEndif) {
2392
- break ;
2393
- }
2394
- if !isAtTopLevel && lookahead. at ( . rightBrace) {
2395
- break ;
2396
- }
2397
- lookahead. skipSingle ( )
2342
+ var unexpectedTokens = [ RawSyntax] ( )
2343
+ while !self . at ( . endOfFile, . semicolon) && !stopCondition( & self ) {
2344
+ let numTokensToSkip = self . withLookahead ( { $0. skipSingle ( ) ; return $0. tokensConsumed } )
2345
+ for _ in 0 ..< numTokensToSkip {
2346
+ unexpectedTokens. append ( RawSyntax ( self . consumeAnyTokenWithoutAdjustingNestingLevel ( ) ) )
2347
+ }
2398
2348
2399
- if lookahead. at ( . poundIf) {
2400
- break
2401
- }
2402
- if lookahead. at ( . poundSourceLocation) {
2403
- break
2404
- }
2405
- if lookahead. atStartOfDeclaration (
2406
- isAtTopLevel: isAtTopLevel,
2407
- allowInitDecl: allowInitDecl,
2408
- requiresDecl: requiresDecl
2409
- ) {
2410
- break
2411
- }
2349
+ if self . at ( . poundIf) {
2350
+ break
2351
+ }
2352
+ if self . at ( . poundSourceLocation) {
2353
+ break
2354
+ }
2355
+ if self . atStartOfDeclaration ( allowInitDecl: allowInitDecl, requiresDecl: requiresDecl) {
2356
+ break
2357
+ }
2412
2358
2413
- if skipToDeclOnly {
2414
- continue
2415
- }
2416
- if lookahead. atStartOfStatement ( preferExpr: false ) {
2417
- break
2418
- }
2419
- // Recover to an expression only if it's on the next line.
2420
- if lookahead. currentToken. isAtStartOfLine && lookahead. atStartOfExpression ( ) {
2421
- break
2422
- }
2359
+ if skipToDeclOnly {
2360
+ continue
2361
+ }
2362
+ if self . atStartOfStatement ( preferExpr: false ) {
2363
+ break
2364
+ }
2365
+ // Recover to an expression only if it's on the next line.
2366
+ if self . currentToken. isAtStartOfLine && self . atStartOfExpression ( ) {
2367
+ break
2423
2368
}
2424
- return lookahead. tokensConsumed
2425
- }
2426
- var unexpectedTokens = [ RawSyntax] ( )
2427
- for _ in 0 ..< numTokensToSkip {
2428
- unexpectedTokens. append ( RawSyntax ( self . consumeAnyTokenWithoutAdjustingNestingLevel ( ) ) )
2429
2369
}
2430
2370
return RawUnexpectedCodeDeclSyntax (
2431
2371
unexpectedCode: RawUnexpectedNodesSyntax ( elements: unexpectedTokens, arena: self . arena) ,
0 commit comments