From 53952a4248cfc494a856f098bff17569e2a7b1bf Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Mon, 3 Jun 2024 08:42:41 -0400 Subject: [PATCH] Add Identifier wrapper that strips backticks from token text rdar://112672035 --- Release Notes/600.md | 4 ++ Sources/SwiftSyntax/CMakeLists.txt | 1 + Sources/SwiftSyntax/Identifier.swift | 50 +++++++++++++++++++ Sources/SwiftSyntax/TokenSyntax.swift | 10 ++++ Tests/SwiftSyntaxTest/IdentifierTests.swift | 53 +++++++++++++++++++++ 5 files changed, 118 insertions(+) create mode 100644 Sources/SwiftSyntax/Identifier.swift create mode 100644 Tests/SwiftSyntaxTest/IdentifierTests.swift diff --git a/Release Notes/600.md b/Release Notes/600.md index 6b6bd2b7665..1160bfcbd7f 100644 --- a/Release Notes/600.md +++ b/Release Notes/600.md @@ -95,6 +95,10 @@ - Description: A version of the `SwiftSyntaxMacrosTestSupport` module that doesn't depend on `Foundation` or `XCTest` and can thus be used to write macro tests using `swift-testing`. Since swift-syntax can't depend on swift-testing (which would incur a circular dependency since swift-testing depends on swift-syntax), users need to manually specify a failure handler like the following, that fails the swift-testing test: `Issue.record("\($0.message)", fileID: $0.location.fileID, filePath: $0.location.filePath, line: $0.location.line, column: $0.location.column)` - Pull request: https://github.com/apple/swift-syntax/pull/2647 +- `TokenSyntax.identifier` + - Description: Adds an `identifier` property to `TokenSyntax` which returns a canonicalized representation of an identifier that strips away backticks. + - Pull request: https://github.com/apple/swift-syntax/pull/2576 + ## API Behavior Changes ## Deprecations diff --git a/Sources/SwiftSyntax/CMakeLists.txt b/Sources/SwiftSyntax/CMakeLists.txt index 23cdd2fbb59..0f72aed545b 100644 --- a/Sources/SwiftSyntax/CMakeLists.txt +++ b/Sources/SwiftSyntax/CMakeLists.txt @@ -15,6 +15,7 @@ add_swift_syntax_library(SwiftSyntax CommonAncestor.swift Convenience.swift CustomTraits.swift + Identifier.swift MemoryLayout.swift MissingNodeInitializers.swift SourceEdit.swift diff --git a/Sources/SwiftSyntax/Identifier.swift b/Sources/SwiftSyntax/Identifier.swift new file mode 100644 index 00000000000..0864e754744 --- /dev/null +++ b/Sources/SwiftSyntax/Identifier.swift @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +/// A canonicalized representation of an identifier that strips away backticks. +public struct Identifier: Equatable, Hashable, Sendable { + /// The sanitized `text` of a token. + public var name: String { + String(syntaxText: raw.name) + } + + @_spi(RawSyntax) + public let raw: RawIdentifier + + private let arena: SyntaxArenaRef + + public init?(_ token: TokenSyntax) { + guard case .identifier = token.tokenKind else { + return nil + } + + self.raw = RawIdentifier(token.tokenView) + self.arena = token.tokenView.raw.arenaReference + } +} + +@_spi(RawSyntax) +public struct RawIdentifier: Equatable, Hashable, Sendable { + public let name: SyntaxText + + @_spi(RawSyntax) + fileprivate init(_ raw: RawSyntaxTokenView) { + let backtick = SyntaxText("`") + if raw.rawText.count > 2 && raw.rawText.hasPrefix(backtick) && raw.rawText.hasSuffix(backtick) { + let startIndex = raw.rawText.index(after: raw.rawText.startIndex) + let endIndex = raw.rawText.index(before: raw.rawText.endIndex) + self.name = SyntaxText(rebasing: raw.rawText[startIndex..