Skip to content

Commit 21ba4fb

Browse files
committed
WIP - SyntaxText
1 parent a63ade8 commit 21ba4fb

File tree

2 files changed

+74
-35
lines changed

2 files changed

+74
-35
lines changed

Sources/SwiftSyntax/Identifier.swift

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,45 @@
1212

1313
/// An abstraction for sanitized values on a token.
1414
public struct Identifier: Equatable, Hashable, Sendable {
15-
/// The sanitized `text` of a token.
16-
public let name: String
17-
18-
public init?(_ token: TokenSyntax) {
19-
guard case .identifier(let text) = token.tokenKind else {
20-
return nil
15+
/// The sanitized `text` of a token.
16+
public var name: String {
17+
String(syntaxText: rawIdentifier.name)
18+
}
19+
20+
@_spi(RawSyntax)
21+
public let rawIdentifier: RawIdentifier
22+
23+
let arena: RetainedSyntaxArena
24+
25+
public init?(_ token: TokenSyntax) {
26+
guard case .identifier(let text) = token.tokenKind else {
27+
return nil
28+
}
29+
30+
var rawText = text.contains("`") ? text.trimmingCharacters(in: "`") : Substring(text)
31+
32+
let syntaxArena = SyntaxArena()
33+
34+
let name = rawText.withUTF8 {
35+
syntaxArena.intern(
36+
SyntaxText(buffer: SyntaxArenaAllocatedBufferPointer<UInt8>($0))
37+
)
38+
}
39+
40+
self.rawIdentifier = RawIdentifier(name: name)
41+
self.arena = RetainedSyntaxArena(syntaxArena)
42+
}
43+
44+
public static func == (lhs: Identifier, rhs: Identifier) -> Bool {
45+
lhs.rawIdentifier == rhs.rawIdentifier
2146
}
47+
48+
public func hash(into hasher: inout Hasher) {
49+
hasher.combine(rawIdentifier)
50+
}
51+
}
2252

23-
self.name =
24-
if text.contains("`") {
25-
String(text.trimmingCharacters(in: "`"))
26-
} else {
27-
text
28-
}
29-
}
53+
@_spi(RawSyntax)
54+
public struct RawIdentifier: Equatable, Hashable, Sendable {
55+
public let name: SyntaxText
3056
}

Tests/SwiftSyntaxTest/IdentifierTests.swift

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,42 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import SwiftSyntax
13+
@_spi(RawSyntax) import SwiftSyntax
1414
import XCTest
1515

1616
class IdentifierTests: XCTestCase {
17-
public func testInit() {
18-
let basicToken = TokenSyntax(stringLiteral: "sometoken")
19-
XCTAssertEqual(Identifier(basicToken)?.name, "sometoken")
20-
21-
let backtickedToken = TokenSyntax(stringLiteral: "`backtickedtoken`")
22-
XCTAssertEqual(Identifier(backtickedToken)?.name, "backtickedtoken")
23-
24-
let multiBacktickedToken = TokenSyntax(stringLiteral: "```backtickedtoken```")
25-
XCTAssertEqual(Identifier(multiBacktickedToken)?.name, "backtickedtoken")
26-
27-
let nonIdentifierToken = DeclSyntax("let a = 1").firstToken(viewMode: .all)!
28-
XCTAssertNil(Identifier(nonIdentifierToken))
29-
}
30-
31-
public func testTokenSyntaxIdentifier() {
32-
let tokenSyntax = TokenSyntax(stringLiteral: "sometoken")
33-
XCTAssertEqual(tokenSyntax.identifier, Identifier(tokenSyntax))
34-
35-
let nonIdentifierToken = DeclSyntax("let a = 1").firstToken(viewMode: .all)!
36-
XCTAssertNil(nonIdentifierToken.identifier)
37-
}
17+
public func testIdentifierInit() {
18+
let someToken = TokenSyntax(stringLiteral: "someToken")
19+
XCTAssertNotNil(Identifier(someToken))
20+
21+
let nonIdentifierToken = DeclSyntax("let a = 1").firstToken(viewMode: .all)!
22+
XCTAssertNil(Identifier(nonIdentifierToken))
23+
}
24+
25+
public func testName() {
26+
let basicToken = TokenSyntax(stringLiteral: "basicToken")
27+
XCTAssertEqual(Identifier(basicToken)?.name, "basicToken")
28+
29+
let backtickedToken = TokenSyntax(stringLiteral: "`backtickedToken`")
30+
XCTAssertEqual(Identifier(backtickedToken)?.name, "backtickedToken")
31+
32+
let multiBacktickedToken = TokenSyntax(stringLiteral: "```multiBacktickedToken```")
33+
XCTAssertEqual(Identifier(multiBacktickedToken)?.name, "multiBacktickedToken")
34+
35+
let unicodeNormalizedToken = TokenSyntax(stringLiteral: "\u{e0}") // "a`"
36+
XCTAssertEqual(Identifier(unicodeNormalizedToken)?.name, "\u{61}\u{300}") // "à"
37+
}
38+
39+
public func testRawIdentifier() {
40+
let rawIdentifier = TokenSyntax(stringLiteral: "sometoken").identifier?.rawIdentifier
41+
XCTAssertEqual(rawIdentifier?.name, SyntaxText("sometoken"))
42+
}
43+
44+
public func testTokenSyntaxIdentifier() {
45+
let tokenSyntax = TokenSyntax(stringLiteral: "sometoken")
46+
XCTAssertEqual(tokenSyntax.identifier, Identifier(tokenSyntax))
47+
48+
let nonIdentifierToken = DeclSyntax("let a = 1").firstToken(viewMode: .all)!
49+
XCTAssertNil(nonIdentifierToken.identifier)
50+
}
3851
}

0 commit comments

Comments
 (0)