Skip to content

Commit 3a32d1b

Browse files
committed
Implement recovery in eat
At the moment this doesn’t change anything because all places that call `eat` have previous checks that make sure the parser is currently positioned at the expected token. In the future, this will allow us to start parsing functions that `eat` a token at a different token and this function is responsible for eating all intermediate tokens until the expected one.
1 parent f905feb commit 3a32d1b

15 files changed

+656
-275
lines changed

Sources/SwiftParser/Attributes.swift

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -182,30 +182,34 @@ extension Parser {
182182
}
183183

184184

185-
let atSign = self.eat(.atSign)
185+
let (unexpectedBeforeAtSign, atSign) = self.eat(.atSign)
186186
let ident = self.consumeIdentifier()
187+
let unexpectedBeforeLeftParen: RawUnexpectedNodesSyntax?
187188
let leftParen: RawTokenSyntax?
188189
let arg: RawSyntax?
189190
let unexpectedBeforeRightParen: RawUnexpectedNodesSyntax?
190191
let rightParen: RawTokenSyntax?
191192
if self.at(.leftParen) {
192193
var args = [RawTokenSyntax]()
193-
leftParen = self.eat(.leftParen)
194+
(unexpectedBeforeLeftParen, leftParen) = self.eat(.leftParen)
194195
var loopProgress = LoopProgressCondition()
195196
while !self.at(.eof) && !self.at(.rightParen) && loopProgress.evaluate(currentToken) {
196197
args.append(self.consumeAnyToken())
197198
}
198199
arg = RawSyntax(RawTokenListSyntax(elements: args, arena: self.arena))
199200
(unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
200201
} else {
202+
unexpectedBeforeLeftParen = nil
201203
leftParen = nil
202204
arg = nil
203205
unexpectedBeforeRightParen = nil
204206
rightParen = nil
205207
}
206208
return RawSyntax(RawAttributeSyntax(
209+
unexpectedBeforeAtSign,
207210
atSignToken: atSign,
208211
attributeName: ident,
212+
unexpectedBeforeLeftParen,
209213
leftParen: leftParen,
210214
argument: arg,
211215
unexpectedBeforeRightParen,
@@ -215,7 +219,7 @@ extension Parser {
215219
}
216220

217221
mutating func parseCustomAttribute() -> RawCustomAttributeSyntax {
218-
let atSign = self.eat(.atSign)
222+
let (unexpectedBeforeAtSign, atSign) = self.eat(.atSign)
219223
let attrName = self.parseType()
220224

221225
// Custom attributes are stricter than normal attributes about their
@@ -226,11 +230,14 @@ extension Parser {
226230
leftParen: nil, argumentList: nil, rightParen: nil,
227231
arena: self.arena)
228232
}
229-
let leftParen = self.eat(.leftParen)
233+
let (unexpectedBeforeLeftParen, leftParen) = self.eat(.leftParen)
230234
let arguments = self.parseArgumentListElements()
231235
let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
232236
return RawCustomAttributeSyntax(
233-
atSignToken: atSign, attributeName: attrName,
237+
unexpectedBeforeAtSign,
238+
atSignToken: atSign,
239+
attributeName: attrName,
240+
unexpectedBeforeLeftParen,
234241
leftParen: leftParen,
235242
argumentList: RawTupleExprElementListSyntax(elements: arguments, arena: self.arena),
236243
unexpectedBeforeRightParen,
@@ -241,7 +248,7 @@ extension Parser {
241248

242249
extension Parser {
243250
mutating func parseAvailabilityAttribute() -> RawAttributeSyntax {
244-
let atSign = self.eat(.atSign)
251+
let (unexpectedBeforeAtSign, atSign) = self.eat(.atSign)
245252
assert(self.currentToken.tokenText == "available")
246253
let available = self.consumeAnyToken()
247254
let (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)
@@ -259,6 +266,7 @@ extension Parser {
259266
let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
260267

261268
return RawAttributeSyntax(
269+
unexpectedBeforeAtSign,
262270
atSignToken: atSign,
263271
attributeName: available,
264272
unexpectedBeforeLeftParen,
@@ -273,7 +281,7 @@ extension Parser {
273281

274282
extension Parser {
275283
mutating func parseDifferentiableAttribute() -> RawAttributeSyntax {
276-
let atSign = self.eat(.atSign)
284+
let (unexpectedBeforeAtSign, atSign) = self.eat(.atSign)
277285
assert(self.currentToken.tokenText == "differentiable")
278286
let differentiable = self.consumeAnyToken()
279287
let (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)
@@ -282,6 +290,7 @@ extension Parser {
282290
let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
283291

284292
return RawAttributeSyntax(
293+
unexpectedBeforeAtSign,
285294
atSignToken: atSign,
286295
attributeName: differentiable,
287296
unexpectedBeforeLeftParen,
@@ -355,7 +364,7 @@ extension Parser {
355364
)
356365
}
357366

358-
let leftParen = self.eat(.leftParen)
367+
let (unexpectedBeforeLeftParen, leftParen) = self.eat(.leftParen)
359368
var elements = [RawDifferentiabilityParamSyntax]()
360369
var loopProgress = LoopProgressCondition()
361370
while !self.at(.eof) && !self.at(.rightParen) && loopProgress.evaluate(currentToken) {
@@ -368,6 +377,7 @@ extension Parser {
368377

369378
let parameters = RawDifferentiabilityParamListSyntax(elements: elements, arena: self.arena)
370379
let list = RawDifferentiabilityParamsSyntax(
380+
unexpectedBeforeLeftParen,
371381
leftParen: leftParen,
372382
diffParams: parameters,
373383
unexpectedBeforeRightParen,
@@ -396,10 +406,14 @@ extension Parser {
396406
return RawDifferentiabilityParamSyntax(
397407
parameter: RawSyntax(token), trailingComma: comma, arena: self.arena)
398408
case .selfKeyword:
399-
let token = self.eat(.selfKeyword)
409+
let (unexpectedBeforeToken, token) = self.eat(.selfKeyword)
400410
let comma = self.consume(if: .comma)
401411
return RawDifferentiabilityParamSyntax(
402-
parameter: RawSyntax(token), trailingComma: comma, arena: self.arena)
412+
unexpectedBeforeToken,
413+
parameter: RawSyntax(token),
414+
trailingComma: comma,
415+
arena: self.arena
416+
)
403417
default:
404418
return nil
405419
}
@@ -408,27 +422,32 @@ extension Parser {
408422

409423
extension Parser {
410424
mutating func parseObjectiveCAttribute() -> RawAttributeSyntax {
411-
let atSign = self.eat(.atSign)
425+
let (unexpectedBeforeAtSign, atSign) = self.eat(.atSign)
412426
assert(self.currentToken.tokenText == "objc")
413427
let objc = self.consumeAnyToken()
414428

429+
let unexpectedBeforeLeftParen: RawUnexpectedNodesSyntax?
415430
let leftParen: RawTokenSyntax?
416431
let argument: RawObjCSelectorSyntax?
417432
let unexpectedBeforeRightParen: RawUnexpectedNodesSyntax?
418433
let rightParen: RawTokenSyntax?
419434
if self.at(.leftParen) {
420-
leftParen = self.eat(.leftParen)
435+
(unexpectedBeforeLeftParen, leftParen) = self.eat(.leftParen)
421436
argument = self.parseObjectiveCSelector()
422437
(unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
423438
} else {
439+
unexpectedBeforeLeftParen = nil
424440
leftParen = nil
425441
argument = nil
426442
unexpectedBeforeRightParen = nil
427443
rightParen = nil
428444
}
429445

430446
return RawAttributeSyntax(
431-
atSignToken: atSign, attributeName: objc,
447+
unexpectedBeforeAtSign,
448+
atSignToken: atSign,
449+
attributeName: objc,
450+
unexpectedBeforeLeftParen,
432451
leftParen: leftParen,
433452
argument: argument.map(RawSyntax.init),
434453
unexpectedBeforeRightParen,
@@ -443,9 +462,13 @@ extension Parser {
443462
while !self.at(.eof) && !self.at(.rightParen) && loopProgress.evaluate(currentToken) {
444463
// Empty selector piece.
445464
if self.at(.colon) {
446-
let colon = self.eat(.colon)
465+
let (unexpectedBeforeColon, colon) = self.eat(.colon)
447466
elements.append(RawObjCSelectorPieceSyntax(
448-
name: nil, colon: colon, arena: self.arena))
467+
name: nil,
468+
unexpectedBeforeColon,
469+
colon: colon,
470+
arena: self.arena
471+
))
449472
continue
450473
}
451474

@@ -465,13 +488,14 @@ extension Parser {
465488

466489
extension Parser {
467490
mutating func parseSpecializeAttribute() -> RawAttributeSyntax {
468-
let atSign = self.eat(.atSign)
491+
let (unexpectedBeforeAtSign, atSign) = self.eat(.atSign)
469492
assert(self.currentToken.tokenText == "_specialize")
470493
let specializeToken = self.consumeAnyToken()
471494
let (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)
472495
let argument = self.parseSpecializeAttributeSpecList()
473496
let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
474497
return RawAttributeSyntax(
498+
unexpectedBeforeAtSign,
475499
atSignToken: atSign,
476500
attributeName: specializeToken,
477501
unexpectedBeforeLeftParen,
@@ -649,7 +673,7 @@ extension Parser {
649673

650674
extension Parser {
651675
mutating func parsePrivateImportAttribute() -> RawAttributeSyntax {
652-
let atSign = self.eat(.atSign)
676+
let (unexpectedBeforeAtSign, atSign) = self.eat(.atSign)
653677
assert(self.currentToken.tokenText == "_private")
654678
let privateToken = self.consumeAnyToken()
655679
let (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)
@@ -658,6 +682,7 @@ extension Parser {
658682
let filename = self.consumeAnyToken()
659683
let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
660684
return RawAttributeSyntax(
685+
unexpectedBeforeAtSign,
661686
atSignToken: atSign,
662687
attributeName: privateToken,
663688
unexpectedBeforeLeftParen,
@@ -678,7 +703,7 @@ extension Parser {
678703

679704
extension Parser {
680705
mutating func parseDynamicReplacementAttribute() -> RawAttributeSyntax {
681-
let atSign = self.eat(.atSign)
706+
let (unexpectedBeforeAtSign, atSign) = self.eat(.atSign)
682707
assert(self.currentToken.tokenText == "_dynamicReplacement")
683708
let dynamicReplacementToken = self.consumeAnyToken()
684709
let (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)
@@ -695,6 +720,7 @@ extension Parser {
695720
let method = RawDeclNameSyntax(declBaseName: RawSyntax(base), declNameArguments: args, arena: self.arena)
696721
let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
697722
return RawAttributeSyntax(
723+
unexpectedBeforeAtSign,
698724
atSignToken: atSign,
699725
attributeName: dynamicReplacementToken,
700726
unexpectedBeforeLeftParen,
@@ -715,13 +741,14 @@ extension Parser {
715741

716742
extension Parser {
717743
mutating func parseSPIAttribute() -> RawAttributeSyntax {
718-
let atSign = self.eat(.atSign)
744+
let (unexpectedBeforeAtSign, atSign) = self.eat(.atSign)
719745
assert(self.currentToken.tokenText == "_spi")
720746
let spiToken = self.consumeAnyToken()
721747
let (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)
722748
let label = self.consumeAnyToken()
723749
let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
724750
return RawAttributeSyntax(
751+
unexpectedBeforeAtSign,
725752
atSignToken: atSign,
726753
attributeName: spiToken,
727754
unexpectedBeforeLeftParen,

Sources/SwiftParser/Availability.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,15 @@ extension Parser {
132132
case .deprecated:
133133
let argumentLabel = self.consumeAnyToken()
134134
if self.at(.colon) {
135-
let colon = self.eat(.colon)
135+
let (unexpectedBeforeColon, colon) = self.eat(.colon)
136136
let version = self.parseVersionTuple()
137137
entry = RawSyntax(RawAvailabilityLabeledArgumentSyntax(
138-
label: argumentLabel, colon: colon, value: RawSyntax(version), arena: self.arena))
138+
label: argumentLabel,
139+
unexpectedBeforeColon,
140+
colon: colon,
141+
value: RawSyntax(version),
142+
arena: self.arena
143+
))
139144
} else {
140145
entry = RawSyntax(argumentLabel)
141146
}

0 commit comments

Comments
 (0)