Skip to content

Commit c939287

Browse files
committed
Propagate inLetOrVar in more cases
Fixes #831 Resolves rdar://100301666
1 parent 1e51b70 commit c939287

File tree

3 files changed

+35
-19
lines changed

3 files changed

+35
-19
lines changed

Sources/SwiftParser/Attributes.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ extension Parser {
117117
leftParen: nil, argumentList: nil, rightParen: nil,
118118
arena: self.arena)
119119
}
120-
let arguments = self.parseArgumentListElements()
120+
let arguments = self.parseArgumentListElements(inLetOrVar: false)
121121
let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
122122
return RawCustomAttributeSyntax(
123123
unexpectedBeforeAtSign,

Sources/SwiftParser/Expressions.swift

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ extension Parser {
4141
/// expression → try-operator? await-operator? prefix-expression infix-expressions?
4242
/// expression-list → expression | expression ',' expression-list
4343
@_spi(RawSyntax)
44-
public mutating func parseExpression(_ flavor: ExprFlavor = .trailingClosure) -> RawExprSyntax {
44+
public mutating func parseExpression(_ flavor: ExprFlavor = .trailingClosure, inLetOrVar: Bool = false) -> RawExprSyntax {
4545
// If we are parsing a refutable pattern, check to see if this is the start
4646
// of a let/var/is pattern. If so, parse it as an UnresolvedPatternExpr and
4747
// let pattern type checking determine its final form.
@@ -52,7 +52,7 @@ extension Parser {
5252
let pattern = self.parseMatchingPattern()
5353
return RawExprSyntax(RawUnresolvedPatternExprSyntax(pattern: pattern, arena: self.arena))
5454
}
55-
return RawExprSyntax(self.parseSequenceExpression(flavor))
55+
return RawExprSyntax(self.parseSequenceExpression(flavor, inVarOrLet: inLetOrVar))
5656
}
5757
}
5858

@@ -441,7 +441,7 @@ extension Parser {
441441
}
442442
return self.parsePostfixExpressionSuffix(
443443
head, flavor, forDirective: forDirective,
444-
periodHasKeyPathBehavior: periodHasKeyPathBehavior)
444+
periodHasKeyPathBehavior: periodHasKeyPathBehavior, inLetOrVar: inVarOrLet)
445445
}
446446

447447
@_spi(RawSyntax)
@@ -502,7 +502,9 @@ extension Parser {
502502
}
503503
let result = parser.parsePostfixExpressionSuffix(
504504
head, flavor, forDirective: forDirective,
505-
periodHasKeyPathBehavior: false)
505+
periodHasKeyPathBehavior: false,
506+
inLetOrVar: false
507+
)
506508

507509
// TODO: diagnose and skip the remaining token in the current clause.
508510
return result
@@ -538,7 +540,8 @@ extension Parser {
538540
_ start: RawExprSyntax,
539541
_ flavor: ExprFlavor,
540542
forDirective: Bool,
541-
periodHasKeyPathBehavior: Bool
543+
periodHasKeyPathBehavior: Bool,
544+
inLetOrVar: Bool
542545
) -> RawExprSyntax {
543546
// Handle suffix expressions.
544547
var leadingExpr = start
@@ -563,7 +566,7 @@ extension Parser {
563566

564567
// If there is an expr-call-suffix, parse it and form a call.
565568
if let lparen = self.consume(if: .leftParen, where: { !$0.isAtStartOfLine }) {
566-
let args = self.parseArgumentListElements()
569+
let args = self.parseArgumentListElements(inLetOrVar: inLetOrVar)
567570
let (unexpectedBeforeRParen, rparen) = self.expect(.rightParen)
568571

569572
// If we can parse trailing closures, do so.
@@ -591,7 +594,7 @@ extension Parser {
591594
// Check for a [expr] suffix.
592595
// Note that this cannot be the start of a new line.
593596
if let lsquare = self.consume(if: .leftSquareBracket, where: { !$0.isAtStartOfLine }) {
594-
let args = self.parseArgumentListElements()
597+
let args = self.parseArgumentListElements(inLetOrVar: inLetOrVar)
595598
let (unexpectedBeforeRSquare, rsquare) = self.expect(.rightSquareBracket)
596599

597600
// If we can parse trailing closures, do so.
@@ -750,14 +753,18 @@ extension Parser {
750753
let base = RawExprSyntax(RawKeyPathBaseExprSyntax(period: dot, arena: self.arena))
751754
expression = self.parsePostfixExpressionSuffix(
752755
base, .basic, forDirective: forDirective,
753-
periodHasKeyPathBehavior: false)
756+
periodHasKeyPathBehavior: false,
757+
inLetOrVar: inVarOrLet
758+
)
754759
} else if self.at(any: [.period, .prefixPeriod]) {
755760
// Inside a keypath's path, the period always behaves normally: the key path
756761
// behavior is only the separation between type and path.
757762
let base = self.parseDottedExpressionSuffix(nil)
758763
expression = self.parsePostfixExpressionSuffix(
759764
base, .basic, forDirective: forDirective,
760-
periodHasKeyPathBehavior: false)
765+
periodHasKeyPathBehavior: false,
766+
inLetOrVar: inVarOrLet
767+
)
761768
} else {
762769
expression = RawExprSyntax(RawMissingExprSyntax(arena: self.arena))
763770
}
@@ -956,7 +963,7 @@ extension Parser {
956963
// only one element without label. However, libSyntax tree doesn't have this
957964
// differentiation. A tuple expression node in libSyntax can have a single
958965
// element without label.
959-
return RawExprSyntax(self.parseTupleExpression())
966+
return RawExprSyntax(self.parseTupleExpression(inLetOrVar: inVarOrLet))
960967

961968
case (.leftSquareBracket, _)?:
962969
return self.parseCollectionLiteral()
@@ -1012,7 +1019,7 @@ extension Parser {
10121019
public mutating func parseObjectLiteralExpression() -> RawObjectLiteralExprSyntax {
10131020
let poundKeyword = self.consumeAnyToken()
10141021
let (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)
1015-
let arguments = self.parseArgumentListElements()
1022+
let arguments = self.parseArgumentListElements(inLetOrVar: false)
10161023
let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
10171024
return RawObjectLiteralExprSyntax(
10181025
identifier: poundKeyword,
@@ -1366,7 +1373,7 @@ extension Parser {
13661373
expressionContent.withBuffer { buf in
13671374
var subparser = Parser(buf, arena: self.arena)
13681375
let (lunexpected, lparen) = subparser.expect(.leftParen)
1369-
let args = subparser.parseArgumentListElements()
1376+
let args = subparser.parseArgumentListElements(inLetOrVar: false)
13701377
// If we stopped parsing the expression before the expression segment is
13711378
// over, eat the remaining tokens into a token list.
13721379
var runexpectedTokens = [RawSyntax]()
@@ -1526,9 +1533,9 @@ extension Parser {
15261533
/// tuple-expression → '(' ')' | '(' tuple-element ',' tuple-element-list ')'
15271534
/// tuple-element-list → tuple-element | tuple-element ',' tuple-element-list
15281535
@_spi(RawSyntax)
1529-
public mutating func parseTupleExpression() -> RawTupleExprSyntax {
1536+
public mutating func parseTupleExpression(inLetOrVar: Bool) -> RawTupleExprSyntax {
15301537
let (unexpectedBeforeLParen, lparen) = self.expect(.leftParen)
1531-
let elements = self.parseArgumentListElements()
1538+
let elements = self.parseArgumentListElements(inLetOrVar: inLetOrVar)
15321539
let (unexpectedBeforeRParen, rparen) = self.expect(.rightParen)
15331540
return RawTupleExprSyntax(
15341541
unexpectedBeforeLParen,
@@ -1995,7 +2002,7 @@ extension Parser {
19952002
///
19962003
/// tuple-element → expression | identifier ':' expression
19972004
@_spi(RawSyntax)
1998-
public mutating func parseArgumentListElements() -> [RawTupleExprElementSyntax] {
2005+
public mutating func parseArgumentListElements(inLetOrVar: Bool) -> [RawTupleExprElementSyntax] {
19992006
guard !self.at(.rightParen) else {
20002007
return []
20012008
}
@@ -2017,7 +2024,7 @@ extension Parser {
20172024
expr = RawExprSyntax(RawIdentifierExprSyntax(
20182025
identifier: ident, declNameArguments: args, arena: self.arena))
20192026
} else {
2020-
expr = self.parseExpression()
2027+
expr = self.parseExpression(inLetOrVar: inLetOrVar)
20212028
}
20222029
keepGoing = self.consume(if: .comma)
20232030
result.append(RawTupleExprElementSyntax(
@@ -2042,9 +2049,9 @@ extension Parser {
20422049
/// tuple-expression → '(' ')' | '(' tuple-element ',' tuple-element-list ')'
20432050
/// tuple-element-list → tuple-element | tuple-element ',' tuple-element-list
20442051
@_spi(RawSyntax)
2045-
public mutating func parseArgumentList(_ flavor: ExprFlavor) -> RawTupleExprSyntax {
2052+
public mutating func parseArgumentList(_ flavor: ExprFlavor, inLetOrVar: Bool) -> RawTupleExprSyntax {
20462053
let (unexpectedBeforeLParen, lparen) = self.expect(.leftParen)
2047-
let args = self.parseArgumentListElements()
2054+
let args = self.parseArgumentListElements(inLetOrVar: inLetOrVar)
20482055
let (unexpectedBeforeRightParen, rparen) = self.expect(.rightParen)
20492056

20502057
// FIXME: Introduce new SyntaxKind for ArgumentList (rdar://81786229)

Tests/SwiftParserTest/Statements.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,4 +265,13 @@ final class StatementTests: XCTestCase {
265265
"""
266266
)
267267
}
268+
269+
func testIdentifierPattern() {
270+
AssertParse(
271+
"switch x { case let .y(z): break }",
272+
substructure: Syntax(IdentifierPatternSyntax(
273+
identifier: .identifier("z")
274+
))
275+
)
276+
}
268277
}

0 commit comments

Comments
 (0)