Skip to content

Commit e1fb17f

Browse files
authored
Merge pull request #1379 from jckarter/se-0366-consume-final-spelling
Implement `consume x` operator with the accepted SE-0366 syntax.
2 parents 5594b98 + f4de999 commit e1fb17f

File tree

8 files changed

+48
-4
lines changed

8 files changed

+48
-4
lines changed

CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ public let KEYWORDS: [KeywordSpec] = [
105105
KeywordSpec("case", isLexerClassified: true, requiresTrailingSpace: true),
106106
KeywordSpec("catch", isLexerClassified: true, requiresLeadingSpace: true),
107107
KeywordSpec("class", isLexerClassified: true, requiresTrailingSpace: true),
108+
KeywordSpec("consume"),
108109
KeywordSpec("consuming"),
109110
KeywordSpec("continue", isLexerClassified: true, requiresTrailingSpace: true),
110111
KeywordSpec("convenience"),

CodeGeneration/Sources/SyntaxSupport/gyb_generated/ExprNodes.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ public let EXPR_NODES: [Node] = [
637637
kind: "Expr",
638638
children: [
639639
Child(name: "MoveKeyword",
640-
kind: .token(choices: [.keyword(text: "_move")])),
640+
kind: .token(choices: [.keyword(text: "_move"), .keyword(text: "consume")])),
641641
Child(name: "Expression",
642642
kind: .node(kind: "Expr"))
643643
]),

Sources/SwiftParser/Expressions.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,34 @@ extension Parser {
471471
arena: self.arena
472472
)
473473
)
474+
475+
case (.consumeKeyword, let handle)?:
476+
// `consume` is only contextually a keyword, if it's followed by an
477+
// identifier or keyword on the same line.
478+
let next = peek()
479+
if next.isAtStartOfLine {
480+
fallthrough
481+
}
482+
if next.rawTokenKind != .identifier,
483+
next.rawTokenKind != .dollarIdentifier,
484+
next.rawTokenKind != .keyword
485+
{
486+
fallthrough
487+
}
488+
489+
let consumeTok = self.eat(handle)
490+
let sub = self.parseSequenceExpressionElement(
491+
flavor,
492+
forDirective: forDirective,
493+
pattern: pattern
494+
)
495+
return RawExprSyntax(
496+
RawMoveExprSyntax(
497+
moveKeyword: consumeTok,
498+
expression: sub,
499+
arena: self.arena
500+
)
501+
)
474502
case nil:
475503
return self.parseUnaryExpression(flavor, forDirective: forDirective, pattern: pattern)
476504
}

Sources/SwiftParser/Statements.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -972,7 +972,12 @@ extension Parser.Lookahead {
972972
return !self.peek().isAtStartOfLine
973973
}
974974
case .forgetKeyword?:
975-
switch peek().rawTokenKind {
975+
let next = peek()
976+
// The thing to be forgotten must be on the same line as `forget`.
977+
if next.isAtStartOfLine {
978+
return false
979+
}
980+
switch next.rawTokenKind {
976981
case .identifier, .keyword:
977982
// Since some identifiers like "self" are classified as keywords,
978983
// we want to recognize those too, to handle "forget self". We also

Sources/SwiftParser/TokenSpecSet.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,13 +513,15 @@ enum AwaitTryMove: TokenSpecSet {
513513
case _moveKeyword
514514
case _borrowKeyword
515515
case tryKeyword
516+
case consumeKeyword
516517

517518
init?(lexeme: Lexer.Lexeme) {
518519
switch PrepareForKeywordMatch(lexeme) {
519520
case TokenSpec(.await): self = .awaitKeyword
520521
case TokenSpec(._move): self = ._moveKeyword
521522
case TokenSpec(._borrow): self = ._borrowKeyword
522523
case TokenSpec(.try): self = .tryKeyword
524+
case TokenSpec(.consume): self = .consumeKeyword
523525
default: return nil
524526
}
525527
}
@@ -529,6 +531,7 @@ enum AwaitTryMove: TokenSpecSet {
529531
case .awaitKeyword: return .keyword(.await)
530532
case ._moveKeyword: return .keyword(._move)
531533
case ._borrowKeyword: return .keyword(._borrow)
534+
case .consumeKeyword: return .keyword(.consume)
532535
case .tryKeyword: return .keyword(.try)
533536
}
534537
}

Sources/SwiftSyntax/generated/Keyword.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ public enum Keyword: UInt8, Hashable {
8989
case `case`
9090
case `catch`
9191
case `class`
92+
case consume
9293
case consuming
9394
case `continue`
9495
case convenience
@@ -425,6 +426,8 @@ public enum Keyword: UInt8, Hashable {
425426
self = ._linear
426427
case "_modify":
427428
self = ._modify
429+
case "consume":
430+
self = .consume
428431
case "default":
429432
self = .`default`
430433
case "dynamic":
@@ -921,6 +924,7 @@ public enum Keyword: UInt8, Hashable {
921924
"case",
922925
"catch",
923926
"class",
927+
"consume",
924928
"consuming",
925929
"continue",
926930
"convenience",

Sources/SwiftSyntax/generated/syntaxNodes/SyntaxExprNodes.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4328,7 +4328,7 @@ public struct MoveExprSyntax: ExprSyntaxProtocol, SyntaxHashable {
43284328
public init<E: ExprSyntaxProtocol>(
43294329
leadingTrivia: Trivia? = nil,
43304330
_ unexpectedBeforeMoveKeyword: UnexpectedNodesSyntax? = nil,
4331-
moveKeyword: TokenSyntax = .keyword(._move),
4331+
moveKeyword: TokenSyntax,
43324332
_ unexpectedBetweenMoveKeywordAndExpression: UnexpectedNodesSyntax? = nil,
43334333
expression: E,
43344334
_ unexpectedAfterExpression: UnexpectedNodesSyntax? = nil,

gyb_syntax_support/ExprNodes.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@
5353
Node('MoveExpr', name_for_diagnostics="'_move' expression", kind='Expr',
5454
children=[
5555
Child('MoveKeyword', kind='KeywordToken',
56-
token_choices=['KeywordToken|_move']),
56+
token_choices=[
57+
'KeywordToken|_move',
58+
'KeywordToken|consume',
59+
]),
5760
Child('Expression', kind='Expr'),
5861
]),
5962

0 commit comments

Comments
 (0)