@@ -33,6 +33,23 @@ extension Parser {
33
33
case trailingClosure
34
34
}
35
35
36
+ public enum PatternContext {
37
+ case none
38
+ case matching
39
+ case `var`
40
+ case `let`
41
+ case implicitlyImmutable
42
+
43
+ var admitsBinding : Bool {
44
+ switch self {
45
+ case . implicitlyImmutable, . var, . let:
46
+ return true
47
+ case . none, . matching:
48
+ return false
49
+ }
50
+ }
51
+ }
52
+
36
53
/// Parse an expression.
37
54
///
38
55
/// Grammar
@@ -41,7 +58,7 @@ extension Parser {
41
58
/// expression → try-operator? await-operator? prefix-expression infix-expressions?
42
59
/// expression-list → expression | expression ',' expression-list
43
60
@_spi ( RawSyntax)
44
- public mutating func parseExpression( _ flavor: ExprFlavor = . trailingClosure, inLetOrVar : Bool = false ) -> RawExprSyntax {
61
+ public mutating func parseExpression( _ flavor: ExprFlavor = . trailingClosure, pattern : PatternContext = . none ) -> RawExprSyntax {
45
62
// If we are parsing a refutable pattern, check to see if this is the start
46
63
// of a let/var/is pattern. If so, parse it as an UnresolvedPatternExpr and
47
64
// let pattern type checking determine its final form.
@@ -52,7 +69,7 @@ extension Parser {
52
69
let pattern = self . parseMatchingPattern ( )
53
70
return RawExprSyntax ( RawUnresolvedPatternExprSyntax ( pattern: pattern, arena: self . arena) )
54
71
}
55
- return RawExprSyntax ( self . parseSequenceExpression ( flavor, inVarOrLet : inLetOrVar ) )
72
+ return RawExprSyntax ( self . parseSequenceExpression ( flavor, pattern : pattern ) )
56
73
}
57
74
}
58
75
@@ -71,7 +88,7 @@ extension Parser {
71
88
public mutating func parseSequenceExpression(
72
89
_ flavor: ExprFlavor ,
73
90
forDirective: Bool = false ,
74
- inVarOrLet : Bool = false
91
+ pattern : PatternContext = . none
75
92
) -> RawExprSyntax {
76
93
if forDirective && self . currentToken. isAtStartOfLine {
77
94
return RawExprSyntax ( RawMissingExprSyntax ( arena: self . arena) )
@@ -87,7 +104,7 @@ extension Parser {
87
104
88
105
lastElement = self . parseSequenceExpressionElement ( flavor,
89
106
forDirective: forDirective,
90
- inVarOrLet : inVarOrLet )
107
+ pattern : pattern )
91
108
92
109
var loopCondition = LoopProgressCondition ( )
93
110
while loopCondition. evaluate ( currentToken) {
@@ -101,7 +118,7 @@ extension Parser {
101
118
// Parse the operator.
102
119
guard
103
120
let ( operatorExpr, rhsExpr) =
104
- self . parseSequenceExpressionOperator ( flavor, inVarOrLet : inVarOrLet )
121
+ self . parseSequenceExpressionOperator ( flavor, pattern : pattern )
105
122
else {
106
123
// Not an operator. We're done.
107
124
break
@@ -120,7 +137,7 @@ extension Parser {
120
137
} else {
121
138
lastElement = self . parseSequenceExpressionElement ( flavor,
122
139
forDirective: forDirective,
123
- inVarOrLet : inVarOrLet )
140
+ pattern : pattern )
124
141
}
125
142
}
126
143
@@ -160,7 +177,7 @@ extension Parser {
160
177
/// arrow-operator -> 'throws' '->'
161
178
/// arrow-operator -> 'async' 'throws' '->'
162
179
mutating func parseSequenceExpressionOperator(
163
- _ flavor: ExprFlavor , inVarOrLet : Bool
180
+ _ flavor: ExprFlavor , pattern : PatternContext
164
181
) -> ( operator: RawExprSyntax , rhs: RawExprSyntax ? ) ? {
165
182
enum ExpectedTokenKind : RawTokenKindSubset {
166
183
case spacedBinaryOperator
@@ -220,7 +237,7 @@ extension Parser {
220
237
case ( . infixQuestionMark, let handle) ? :
221
238
// Save the '?'.
222
239
let question = self . eat ( handle)
223
- let firstChoice = self . parseSequenceExpression ( flavor, inVarOrLet : inVarOrLet )
240
+ let firstChoice = self . parseSequenceExpression ( flavor, pattern : pattern )
224
241
// Make sure there's a matching ':' after the middle expr.
225
242
let ( unexpectedBeforeColon, colon) = self . expect ( . colon)
226
243
@@ -243,16 +260,18 @@ extension Parser {
243
260
return ( RawExprSyntax ( op) , rhs)
244
261
245
262
case ( . equal, let handle) ? :
246
- if inVarOrLet {
263
+ switch pattern {
264
+ case . matching, . let, . var:
247
265
return nil
248
- } else {
266
+ case . none , . implicitlyImmutable :
249
267
let eq = self . eat ( handle)
250
268
let op = RawAssignmentExprSyntax (
251
269
assignToken: eq,
252
270
arena: self . arena
253
271
)
254
272
return ( RawExprSyntax ( op) , nil )
255
273
}
274
+
256
275
257
276
case ( . isKeyword, let handle) ? :
258
277
let isKeyword = self . eat ( handle)
@@ -320,7 +339,7 @@ extension Parser {
320
339
public mutating func parseSequenceExpressionElement(
321
340
_ flavor: ExprFlavor ,
322
341
forDirective: Bool = false ,
323
- inVarOrLet : Bool = false
342
+ pattern : PatternContext = . none
324
343
) -> RawExprSyntax {
325
344
// Try to parse '@' sign or 'inout' as a attributed typerepr.
326
345
if self . at ( any: [ . atSign, . inoutKeyword] ) {
@@ -336,7 +355,7 @@ extension Parser {
336
355
case ( . awaitContextualKeyword, let handle) ? :
337
356
let awaitTok = self . eat ( handle)
338
357
let sub = self . parseSequenceExpressionElement (
339
- flavor, forDirective: forDirective, inVarOrLet : inVarOrLet )
358
+ flavor, forDirective: forDirective, pattern : pattern )
340
359
return RawExprSyntax ( RawAwaitExprSyntax (
341
360
awaitKeyword: awaitTok,
342
361
expression: sub,
@@ -347,7 +366,7 @@ extension Parser {
347
366
let mark = self . consume ( ifAny: [ . exclamationMark, . postfixQuestionMark] )
348
367
349
368
let expression = self . parseSequenceExpressionElement (
350
- flavor, forDirective: forDirective, inVarOrLet : inVarOrLet )
369
+ flavor, forDirective: forDirective, pattern : pattern )
351
370
return RawExprSyntax ( RawTryExprSyntax (
352
371
tryKeyword: tryKeyword,
353
372
questionOrExclamationMark: mark,
@@ -357,13 +376,13 @@ extension Parser {
357
376
case ( . _moveContextualKeyword, let handle) ? :
358
377
let moveTok = self . eat ( handle)
359
378
let sub = self . parseSequenceExpressionElement (
360
- flavor, forDirective: forDirective, inVarOrLet : inVarOrLet )
379
+ flavor, forDirective: forDirective, pattern : pattern )
361
380
return RawExprSyntax ( RawMoveExprSyntax (
362
381
moveKeyword: moveTok,
363
382
expression: sub,
364
383
arena: self . arena) )
365
384
case nil :
366
- return self . parseUnaryExpression ( flavor, forDirective: forDirective, inVarOrLet : inVarOrLet )
385
+ return self . parseUnaryExpression ( flavor, forDirective: forDirective, pattern : pattern )
367
386
}
368
387
}
369
388
@@ -380,26 +399,26 @@ extension Parser {
380
399
public mutating func parseUnaryExpression(
381
400
_ flavor: ExprFlavor ,
382
401
forDirective: Bool = false ,
383
- inVarOrLet : Bool = false
402
+ pattern : PatternContext = . none
384
403
) -> RawExprSyntax {
385
404
// First check to see if we have the start of a regex literal `/.../`.
386
405
// tryLexRegexLiteral(/*forUnappliedOperator*/ false)
387
406
switch self . at ( anyIn: ExpressionPrefixOperator . self) {
388
407
case ( . prefixAmpersand, let handle) ? :
389
408
let amp = self . eat ( handle)
390
- let expr = self . parseUnaryExpression ( flavor, forDirective: forDirective, inVarOrLet : inVarOrLet )
409
+ let expr = self . parseUnaryExpression ( flavor, forDirective: forDirective, pattern : pattern )
391
410
return RawExprSyntax ( RawInOutExprSyntax (
392
411
ampersand: amp,
393
412
expression: RawExprSyntax ( expr) ,
394
413
arena: self . arena
395
414
) )
396
415
397
416
case ( . backslash, _) ? :
398
- return RawExprSyntax ( self . parseKeyPathExpression ( forDirective: forDirective, inVarOrLet : inVarOrLet ) )
417
+ return RawExprSyntax ( self . parseKeyPathExpression ( forDirective: forDirective, pattern : pattern ) )
399
418
400
419
case ( . prefixOperator, let handle) ? :
401
420
let op = self . eat ( handle)
402
- let postfix = self . parseUnaryExpression ( flavor, forDirective: forDirective, inVarOrLet : inVarOrLet )
421
+ let postfix = self . parseUnaryExpression ( flavor, forDirective: forDirective, pattern : pattern )
403
422
return RawExprSyntax ( RawPrefixOperatorExprSyntax (
404
423
operatorToken: op,
405
424
postfixExpression: postfix,
@@ -409,7 +428,7 @@ extension Parser {
409
428
default :
410
429
// If the next token is not an operator, just parse this as expr-postfix.
411
430
return self . parsePostfixExpression (
412
- flavor, forDirective: forDirective, inVarOrLet : inVarOrLet ,
431
+ flavor, forDirective: forDirective, pattern : pattern ,
413
432
periodHasKeyPathBehavior: false )
414
433
}
415
434
}
@@ -432,16 +451,16 @@ extension Parser {
432
451
public mutating func parsePostfixExpression(
433
452
_ flavor: ExprFlavor ,
434
453
forDirective: Bool ,
435
- inVarOrLet : Bool ,
454
+ pattern : PatternContext ,
436
455
periodHasKeyPathBehavior: Bool
437
456
) -> RawExprSyntax {
438
- let head = self . parsePrimaryExpression ( inVarOrLet : inVarOrLet )
457
+ let head = self . parsePrimaryExpression ( pattern : pattern )
439
458
guard !head. is ( RawMissingExprSyntax . self) else {
440
459
return head
441
460
}
442
461
return self . parsePostfixExpressionSuffix (
443
462
head, flavor, forDirective: forDirective,
444
- periodHasKeyPathBehavior: periodHasKeyPathBehavior, inLetOrVar : inVarOrLet )
463
+ periodHasKeyPathBehavior: periodHasKeyPathBehavior, pattern : pattern )
445
464
}
446
465
447
466
@_spi ( RawSyntax)
@@ -503,7 +522,7 @@ extension Parser {
503
522
let result = parser. parsePostfixExpressionSuffix (
504
523
head, flavor, forDirective: forDirective,
505
524
periodHasKeyPathBehavior: false ,
506
- inLetOrVar : false
525
+ pattern : . none
507
526
)
508
527
509
528
// TODO: diagnose and skip the remaining token in the current clause.
@@ -541,7 +560,7 @@ extension Parser {
541
560
_ flavor: ExprFlavor ,
542
561
forDirective: Bool ,
543
562
periodHasKeyPathBehavior: Bool ,
544
- inLetOrVar : Bool
563
+ pattern : PatternContext
545
564
) -> RawExprSyntax {
546
565
// Handle suffix expressions.
547
566
var leadingExpr = start
@@ -568,7 +587,7 @@ extension Parser {
568
587
569
588
// If there is an expr-call-suffix, parse it and form a call.
570
589
if let lparen = self . consume ( if: . leftParen, where: { !$0. isAtStartOfLine } ) {
571
- let args = self . parseArgumentListElements ( inLetOrVar : inLetOrVar )
590
+ let args = self . parseArgumentListElements ( pattern : pattern )
572
591
let ( unexpectedBeforeRParen, rparen) = self . expect ( . rightParen)
573
592
574
593
// If we can parse trailing closures, do so.
@@ -600,7 +619,7 @@ extension Parser {
600
619
if self . at ( . rightSquareBracket) {
601
620
args = [ ]
602
621
} else {
603
- args = self . parseArgumentListElements ( inLetOrVar : inLetOrVar )
622
+ args = self . parseArgumentListElements ( pattern : pattern )
604
623
}
605
624
let ( unexpectedBeforeRSquare, rsquare) = self . expect ( . rightSquareBracket)
606
625
@@ -731,7 +750,7 @@ extension Parser {
731
750
/// key-path-postfixes → key-path-postfix key-path-postfixes?
732
751
/// key-path-postfix → '?' | '!' | 'self' | '[' function-call-argument-list ']'
733
752
@_spi ( RawSyntax)
734
- public mutating func parseKeyPathExpression( forDirective: Bool , inVarOrLet : Bool ) -> RawKeyPathExprSyntax {
753
+ public mutating func parseKeyPathExpression( forDirective: Bool , pattern : PatternContext ) -> RawKeyPathExprSyntax {
735
754
// Consume '\'.
736
755
let ( unexpectedBeforeBackslash, backslash) = self . expect ( . backslash)
737
756
@@ -743,7 +762,7 @@ extension Parser {
743
762
let root : RawExprSyntax ?
744
763
if !self . currentToken. starts ( with: " . " ) {
745
764
root = self . parsePostfixExpression (
746
- . basic, forDirective: forDirective, inVarOrLet : inVarOrLet ,
765
+ . basic, forDirective: forDirective, pattern : pattern ,
747
766
periodHasKeyPathBehavior: true )
748
767
} else {
749
768
root = nil
@@ -761,7 +780,7 @@ extension Parser {
761
780
expression = self . parsePostfixExpressionSuffix (
762
781
base, . basic, forDirective: forDirective,
763
782
periodHasKeyPathBehavior: false ,
764
- inLetOrVar : inVarOrLet
783
+ pattern : pattern
765
784
)
766
785
} else if self . at ( any: [ . period, . prefixPeriod] ) {
767
786
// Inside a keypath's path, the period always behaves normally: the key path
@@ -770,7 +789,7 @@ extension Parser {
770
789
expression = self . parsePostfixExpressionSuffix (
771
790
base, . basic, forDirective: forDirective,
772
791
periodHasKeyPathBehavior: false ,
773
- inLetOrVar : inVarOrLet
792
+ pattern : pattern
774
793
)
775
794
} else {
776
795
expression = RawExprSyntax ( RawMissingExprSyntax ( arena: self . arena) )
@@ -805,7 +824,7 @@ extension Parser {
805
824
/// primary-expression → selector-expression
806
825
/// primary-expression → key-path-string-expression
807
826
@_spi ( RawSyntax)
808
- public mutating func parsePrimaryExpression( inVarOrLet : Bool ) -> RawExprSyntax {
827
+ public mutating func parsePrimaryExpression( pattern : PatternContext ) -> RawExprSyntax {
809
828
switch self . at ( anyIn: PrimaryExpressionStart . self) {
810
829
case ( . integerLiteral, let handle) ? :
811
830
let digits = self . eat ( handle)
@@ -912,7 +931,7 @@ extension Parser {
912
931
// If we have "case let x." or "case let x(", we parse x as a normal
913
932
// name, not a binding, because it is the start of an enum pattern or
914
933
// call pattern.
915
- if inVarOrLet && !self . lookahead ( ) . isNextTokenCallPattern ( ) {
934
+ if pattern . admitsBinding && !self . lookahead ( ) . isNextTokenCallPattern ( ) {
916
935
let identifier = self . eat ( handle)
917
936
let pattern = RawPatternSyntax ( RawIdentifierPatternSyntax (
918
937
identifier: identifier, arena: self . arena) )
@@ -970,7 +989,7 @@ extension Parser {
970
989
// only one element without label. However, libSyntax tree doesn't have this
971
990
// differentiation. A tuple expression node in libSyntax can have a single
972
991
// element without label.
973
- return RawExprSyntax ( self . parseTupleExpression ( inLetOrVar : inVarOrLet ) )
992
+ return RawExprSyntax ( self . parseTupleExpression ( pattern : pattern ) )
974
993
975
994
case ( . leftSquareBracket, _) ? :
976
995
return self . parseCollectionLiteral ( )
@@ -1026,7 +1045,7 @@ extension Parser {
1026
1045
public mutating func parseObjectLiteralExpression( ) -> RawObjectLiteralExprSyntax {
1027
1046
let poundKeyword = self . consumeAnyToken ( )
1028
1047
let ( unexpectedBeforeLeftParen, leftParen) = self . expect ( . leftParen)
1029
- let arguments = self . parseArgumentListElements ( inLetOrVar : false )
1048
+ let arguments = self . parseArgumentListElements ( pattern : . none )
1030
1049
let ( unexpectedBeforeRightParen, rightParen) = self . expect ( . rightParen)
1031
1050
return RawObjectLiteralExprSyntax (
1032
1051
identifier: poundKeyword,
@@ -1380,7 +1399,7 @@ extension Parser {
1380
1399
expressionContent. withBuffer { buf in
1381
1400
var subparser = Parser ( buf, arena: self . arena)
1382
1401
let ( lunexpected, lparen) = subparser. expect ( . leftParen)
1383
- let args = subparser. parseArgumentListElements ( inLetOrVar : false )
1402
+ let args = subparser. parseArgumentListElements ( pattern : . none )
1384
1403
// If we stopped parsing the expression before the expression segment is
1385
1404
// over, eat the remaining tokens into a token list.
1386
1405
var runexpectedTokens = [ RawSyntax] ( )
@@ -1540,9 +1559,9 @@ extension Parser {
1540
1559
/// tuple-expression → '(' ')' | '(' tuple-element ',' tuple-element-list ')'
1541
1560
/// tuple-element-list → tuple-element | tuple-element ',' tuple-element-list
1542
1561
@_spi ( RawSyntax)
1543
- public mutating func parseTupleExpression( inLetOrVar : Bool ) -> RawTupleExprSyntax {
1562
+ public mutating func parseTupleExpression( pattern : PatternContext ) -> RawTupleExprSyntax {
1544
1563
let ( unexpectedBeforeLParen, lparen) = self . expect ( . leftParen)
1545
- let elements = self . parseArgumentListElements ( inLetOrVar : inLetOrVar )
1564
+ let elements = self . parseArgumentListElements ( pattern : pattern )
1546
1565
let ( unexpectedBeforeRParen, rparen) = self . expect ( . rightParen)
1547
1566
return RawTupleExprSyntax (
1548
1567
unexpectedBeforeLParen,
@@ -2009,7 +2028,7 @@ extension Parser {
2009
2028
///
2010
2029
/// tuple-element → expression | identifier ':' expression
2011
2030
@_spi ( RawSyntax)
2012
- public mutating func parseArgumentListElements( inLetOrVar : Bool ) -> [ RawTupleExprElementSyntax ] {
2031
+ public mutating func parseArgumentListElements( pattern : PatternContext ) -> [ RawTupleExprElementSyntax ] {
2013
2032
guard !self . at ( . rightParen) else {
2014
2033
return [ ]
2015
2034
}
@@ -2031,7 +2050,7 @@ extension Parser {
2031
2050
expr = RawExprSyntax ( RawIdentifierExprSyntax (
2032
2051
identifier: ident, declNameArguments: args, arena: self . arena) )
2033
2052
} else {
2034
- expr = self . parseExpression ( inLetOrVar : inLetOrVar )
2053
+ expr = self . parseExpression ( pattern : pattern )
2035
2054
}
2036
2055
keepGoing = self . consume ( if: . comma)
2037
2056
result. append ( RawTupleExprElementSyntax (
@@ -2056,9 +2075,9 @@ extension Parser {
2056
2075
/// tuple-expression → '(' ')' | '(' tuple-element ',' tuple-element-list ')'
2057
2076
/// tuple-element-list → tuple-element | tuple-element ',' tuple-element-list
2058
2077
@_spi ( RawSyntax)
2059
- public mutating func parseArgumentList( _ flavor: ExprFlavor , inLetOrVar : Bool ) -> RawTupleExprSyntax {
2078
+ public mutating func parseArgumentList( _ flavor: ExprFlavor , pattern : PatternContext ) -> RawTupleExprSyntax {
2060
2079
let ( unexpectedBeforeLParen, lparen) = self . expect ( . leftParen)
2061
- let args = self . parseArgumentListElements ( inLetOrVar : inLetOrVar )
2080
+ let args = self . parseArgumentListElements ( pattern : pattern )
2062
2081
let ( unexpectedBeforeRightParen, rparen) = self . expect ( . rightParen)
2063
2082
2064
2083
// FIXME: Introduce new SyntaxKind for ArgumentList (rdar://81786229)
0 commit comments