From 754eb03300031b52672bacc3fd9abf6541bfb4c4 Mon Sep 17 00:00:00 2001 From: Alex Hoppen Date: Thu, 6 Jul 2023 13:43:58 +0200 Subject: [PATCH] Detect `attached` attributes using a contextual keyword instead of string matching MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don’t want to do any string-matching based on token texts in SwiftParser. The correct design here is to add `attached` as a contextual keyword. --- .../Sources/SyntaxSupport/KeywordSpec.swift | 1 + Sources/SwiftParser/Attributes.swift | 17 +++++++++-------- Sources/SwiftParser/Types.swift | 4 ---- Sources/SwiftSyntax/generated/Keyword.swift | 4 ++++ 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift b/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift index 728cdd38124..cfe38ee1964 100644 --- a/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift +++ b/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift @@ -95,6 +95,7 @@ public let KEYWORDS: [KeywordSpec] = [ KeywordSpec("associatedtype", isLexerClassified: true, requiresTrailingSpace: true), KeywordSpec("associativity"), KeywordSpec("async", requiresTrailingSpace: true), + KeywordSpec("attached"), KeywordSpec("autoclosure"), KeywordSpec("availability"), KeywordSpec("available"), diff --git a/Sources/SwiftParser/Attributes.swift b/Sources/SwiftParser/Attributes.swift index 252ed9ed4d4..eb16ee9f82f 100644 --- a/Sources/SwiftParser/Attributes.swift +++ b/Sources/SwiftParser/Attributes.swift @@ -54,6 +54,7 @@ extension Parser { case _typeEraser case _unavailableFromAsync case `rethrows` + case attached case available case backDeployed case derivative @@ -88,6 +89,7 @@ extension Parser { case TokenSpec(._typeEraser): self = ._typeEraser case TokenSpec(._unavailableFromAsync): self = ._unavailableFromAsync case TokenSpec(.`rethrows`): self = .rethrows + case TokenSpec(.attached): self = .attached case TokenSpec(.available): self = .available case TokenSpec(.backDeployed): self = .backDeployed case TokenSpec(.derivative): self = .derivative @@ -126,6 +128,7 @@ extension Parser { case ._typeEraser: return .keyword(._typeEraser) case ._unavailableFromAsync: return .keyword(._unavailableFromAsync) case .`rethrows`: return .keyword(.rethrows) + case .attached: return .keyword(.attached) case .available: return .keyword(.available) case .backDeployed: return .keyword(.backDeployed) case .derivative: return .keyword(.derivative) @@ -313,6 +316,11 @@ extension Parser { return parseAttribute(argumentMode: .optional) { parser in return .unavailableFromAsyncArguments(parser.parseUnavailableFromAsyncArguments()) } + case .attached: + return parseAttribute(argumentMode: .customAttribute) { parser in + let arguments = parser.parseAttachedArguments() + return .argumentList(RawTupleExprElementListSyntax(elements: arguments, arena: parser.arena)) + } case .rethrows: let (unexpectedBeforeAtSign, atSign) = self.expect(.atSign) let (unexpectedBeforeAttributeName, attributeName) = self.expect(TokenSpec(.rethrows, remapping: .identifier)) @@ -329,15 +337,8 @@ extension Parser { ) ) case nil: - let isAttached = self.peek().isAttachedKeyword return parseAttribute(argumentMode: .customAttribute) { parser in - let arguments: [RawTupleExprElementSyntax] - if isAttached { - arguments = parser.parseAttachedArguments() - } else { - arguments = parser.parseArgumentListElements(pattern: .none) - } - + let arguments = parser.parseArgumentListElements(pattern: .none) return .argumentList(RawTupleExprElementListSyntax(elements: arguments, arena: parser.arena)) } } diff --git a/Sources/SwiftParser/Types.swift b/Sources/SwiftParser/Types.swift index 346f1fa2723..e3453b61f22 100644 --- a/Sources/SwiftParser/Types.swift +++ b/Sources/SwiftParser/Types.swift @@ -1076,10 +1076,6 @@ extension Lexer.Lexeme { || self.rawTokenKind == .prefixOperator } - var isAttachedKeyword: Bool { - return self.rawTokenKind == .identifier && self.tokenText == "attached" - } - var isEllipsis: Bool { return self.isAnyOperator && self.tokenText == "..." } diff --git a/Sources/SwiftSyntax/generated/Keyword.swift b/Sources/SwiftSyntax/generated/Keyword.swift index c3da1f5a39b..23726fcba6a 100644 --- a/Sources/SwiftSyntax/generated/Keyword.swift +++ b/Sources/SwiftSyntax/generated/Keyword.swift @@ -71,6 +71,7 @@ public enum Keyword: UInt8, Hashable { case `associatedtype` case associativity case async + case attached case autoclosure case availability case available @@ -478,6 +479,8 @@ public enum Keyword: UInt8, Hashable { self = ._version case "accesses": self = .accesses + case "attached": + self = .attached case "compiler": self = .compiler case "continue": @@ -817,6 +820,7 @@ public enum Keyword: UInt8, Hashable { "associatedtype", "associativity", "async", + "attached", "autoclosure", "availability", "available",