From eb573ba5e0a56b2c077507f5dc8f0b4387f6a5d2 Mon Sep 17 00:00:00 2001 From: Alex Hoppen Date: Thu, 13 Jul 2023 12:56:00 +0200 Subject: [PATCH] Support parsing of `borrowing get` rdar://112168704 --- Sources/SwiftParser/Declarations.swift | 4 +-- Sources/SwiftParser/TokenSpecSet.swift | 29 ++++++++++++++++++++ Tests/SwiftParserTest/DeclarationTests.swift | 12 ++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/Sources/SwiftParser/Declarations.swift b/Sources/SwiftParser/Declarations.swift index ec43b0351c8..cece4d921fa 100644 --- a/Sources/SwiftParser/Declarations.swift +++ b/Sources/SwiftParser/Declarations.swift @@ -1421,7 +1421,7 @@ extension Parser { // Check there is an identifier before consuming var look = self.lookahead() let _ = look.consumeAttributeList() - let hasModifier = look.consume(if: .keyword(.mutating), .keyword(.nonmutating), .keyword(.__consuming)) != nil + let hasModifier = look.consume(ifAnyIn: AccessorModifier.self) != nil guard let (kind, _) = look.at(anyIn: AccessorDeclSyntax.AccessorSpecifierOptions.self) ?? forcedKind else { return nil } @@ -1432,7 +1432,7 @@ extension Parser { // get and set. let modifier: RawDeclModifierSyntax? if hasModifier { - let (unexpectedBeforeName, name) = self.expect(.keyword(.mutating), .keyword(.nonmutating), .keyword(.__consuming), default: .keyword(.mutating)) + let (unexpectedBeforeName, name) = self.expect(anyIn: AccessorModifier.self, default: .mutating) modifier = RawDeclModifierSyntax( unexpectedBeforeName, name: name, diff --git a/Sources/SwiftParser/TokenSpecSet.swift b/Sources/SwiftParser/TokenSpecSet.swift index 2578f12aa8b..2a948b80176 100644 --- a/Sources/SwiftParser/TokenSpecSet.swift +++ b/Sources/SwiftParser/TokenSpecSet.swift @@ -23,6 +23,35 @@ protocol TokenSpecSet: CaseIterable { // MARK: - Subsets +enum AccessorModifier: TokenSpecSet { + case __consuming + case consuming + case borrowing + case mutating + case nonmutating + + init?(lexeme: Lexer.Lexeme) { + switch PrepareForKeywordMatch(lexeme) { + case TokenSpec(.__consuming): self = .__consuming + case TokenSpec(.consuming): self = .consuming + case TokenSpec(.borrowing): self = .borrowing + case TokenSpec(.mutating): self = .mutating + case TokenSpec(.nonmutating): self = .nonmutating + default: return nil + } + } + + var spec: TokenSpec { + switch self { + case .__consuming: return .keyword(.__consuming) + case .consuming: return .keyword(.consuming) + case .borrowing: return .keyword(.borrowing) + case .mutating: return .keyword(.mutating) + case .nonmutating: return .keyword(.nonmutating) + } + } +} + enum CanBeStatementStart: TokenSpecSet { case _forget // NOTE: support for deprecated _forget case `break` diff --git a/Tests/SwiftParserTest/DeclarationTests.swift b/Tests/SwiftParserTest/DeclarationTests.swift index a851a0671d1..2fe92f851dc 100644 --- a/Tests/SwiftParserTest/DeclarationTests.swift +++ b/Tests/SwiftParserTest/DeclarationTests.swift @@ -2607,4 +2607,16 @@ final class DeclarationTests: XCTestCase { """ ) } + + func testBorrowingGetAccessor() { + assertParse( + """ + struct Foo { + var x: Int { + borrowing get {} + } + } + """ + ) + } }