Skip to content

Commit 8a4c3a9

Browse files
committed
[Experiment] Add Hashable conformance to concrete types
1 parent 2165d02 commit 8a4c3a9

File tree

5 files changed

+54
-27
lines changed

5 files changed

+54
-27
lines changed

test/SwiftSyntax/LazyCaching.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ LazyCaching.test("Pathological") {
1515
let tuple = SyntaxFactory.makeVoidTupleType()
1616

1717
DispatchQueue.concurrentPerform(iterations: 100) { _ in
18-
expectEqual(tuple.leftParen.uniqueIdentifier,
19-
tuple.leftParen.uniqueIdentifier)
18+
expectEqual(tuple.leftParen, tuple.leftParen)
2019
}
2120
}
2221

@@ -42,9 +41,9 @@ LazyCaching.test("TwoAccesses") {
4241

4342
expectNotNil(node1)
4443
expectNotNil(node2)
45-
expectEqual(node1?.uniqueIdentifier, node2?.uniqueIdentifier)
46-
expectEqual(node1?.uniqueIdentifier, final.uniqueIdentifier)
47-
expectEqual(node2?.uniqueIdentifier, final.uniqueIdentifier)
44+
expectEqual(node1, node2)
45+
expectEqual(node1, final)
46+
expectEqual(node2, final)
4847
}
4948

5049
runAllTests()

test/SwiftSyntax/SyntaxFactory.swift

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ SyntaxFactoryAPI.test("Generated") {
3434
}
3535
""")
3636

37-
let forType = SyntaxFactory.makeIdentifier("for",
37+
let forType = SyntaxFactory.makeIdentifier("for",
3838
leadingTrivia: .backticks(1),
3939
trailingTrivia: [
4040
.backticks(1), .spaces(1)
@@ -52,19 +52,17 @@ SyntaxFactoryAPI.test("Generated") {
5252
}
5353
""")
5454

55-
expectNotEqual(structDecl.members.uniqueIdentifier,
56-
renamed.members.uniqueIdentifier)
57-
expectEqual(structDecl.uniqueIdentifier, structDecl.root.uniqueIdentifier)
55+
expectNotEqual(structDecl.members, renamed.members)
56+
expectEqual(structDecl, structDecl.root as? StructDeclSyntax)
5857
expectNil(structDecl.parent)
5958
expectNotNil(structDecl.members.parent)
60-
expectEqual(structDecl.members.parent?.uniqueIdentifier,
61-
structDecl.uniqueIdentifier)
59+
expectEqual(structDecl.members.parent as? StructDeclSyntax, structDecl)
6260

6361
// Ensure that accessing children via named identifiers is exactly the
6462
// same as accessing them as their underlying data.
65-
expectEqual(structDecl.members.uniqueIdentifier,
66-
structDecl.child(at: 7)?.uniqueIdentifier)
67-
63+
expectEqual(structDecl.members,
64+
structDecl.child(at: 7) as? MemberDeclBlockSyntax)
65+
6866
expectEqual("\(structDecl.members.rightBrace)",
6967
"""
7068

test/SwiftSyntax/VisitorTest.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ VisitorTests.test("Basic") {
3131
expectDoesNotThrow({
3232
let parsed = try Syntax.parse(getInput("visitor.swift"))
3333
let counter = FuncCounter()
34-
let idBefore = parsed.uniqueIdentifier
34+
let hashBefore = parsed.hashValue
3535
counter.visit(parsed)
3636
expectEqual(counter.funcCount, 3)
37-
expectEqual(idBefore, parsed.uniqueIdentifier)
37+
expectEqual(hashBefore, parsed.hashValue)
3838
})
3939
}
4040

41-
runAllTests()
41+
runAllTests()

tools/SwiftSyntax/Syntax.swift

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,6 @@ extension Syntax {
6363
return data.raw
6464
}
6565

66-
public var uniqueIdentifier: Int {
67-
return ObjectIdentifier(data).hashValue
68-
}
69-
7066
/// An iterator over children of this node.
7167
public var children: SyntaxChildren {
7268
return SyntaxChildren(node: self)
@@ -158,13 +154,13 @@ extension Syntax {
158154

159155
/// Determines if two nodes are equal to each other.
160156
public func ==(lhs: Syntax, rhs: Syntax) -> Bool {
161-
return lhs.uniqueIdentifier == rhs.uniqueIdentifier
157+
return lhs.data === rhs.data
162158
}
163159

164160
/// MARK: - Nodes
165161

166162
/// A Syntax node representing a single token.
167-
public struct TokenSyntax: _SyntaxBase {
163+
public struct TokenSyntax: _SyntaxBase, Hashable {
168164
var _root: SyntaxData
169165
unowned var _data: SyntaxData
170166

@@ -251,4 +247,12 @@ public struct TokenSyntax: _SyntaxBase {
251247
}
252248
return kind
253249
}
250+
251+
public static func ==(lhs: TokenSyntax, rhs: TokenSyntax) -> Bool {
252+
return lhs._data === rhs._data
253+
}
254+
255+
public var hashValue: Int {
256+
return ObjectIdentifier(_data).hashValue
257+
}
254258
}

tools/SwiftSyntax/SyntaxNodes.swift.gyb

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Each node will have:
3838
"""
3939
}%
4040

41-
public struct AnySyntax: _SyntaxBase {
41+
public struct AnySyntax: _SyntaxBase, Hashable {
4242
var _root: SyntaxData
4343
unowned var _data: SyntaxData
4444

@@ -47,27 +47,44 @@ public struct AnySyntax: _SyntaxBase {
4747
self._root = root
4848
self._data = data
4949
}
50+
51+
public static func ==(lhs: AnySyntax, rhs: AnySyntax) -> Bool {
52+
return lhs._data === rhs._data
53+
}
54+
55+
public var hashValue: Int {
56+
return ObjectIdentifier(_data).hashValue
57+
}
5058
}
5159

5260
% for node in SYNTAX_NODES:
5361
% base_type = node.base_type
5462
% if node.is_base():
5563
public protocol ${node.name}: Syntax {}
56-
public struct Any${node.name}: ${node.name}, _SyntaxBase {
64+
public struct ${node.swift_type_name}: ${node.name}, _SyntaxBase, Hashable {
5765
var _root: SyntaxData
5866
unowned var _data: SyntaxData
5967

60-
/// Creates an `Any${node.name}`` node from the provided root and data.
68+
/// Creates an `${node.swift_type_name}` node from the provided root and data.
6169
internal init(root: SyntaxData, data: SyntaxData) {
6270
self._root = root
6371
self._data = data
6472
}
73+
74+
public static func ==(lhs: ${node.swift_type_name},
75+
rhs: ${node.swift_type_name}) -> Bool {
76+
return lhs._data === rhs._data
77+
}
78+
79+
public var hashValue: Int {
80+
return ObjectIdentifier(_data).hashValue
81+
}
6582
}
6683

6784
% elif node.collection_element:
6885
public typealias ${node.name} = SyntaxCollection<${node.swift_collection_element_type}>
6986
% else:
70-
public struct ${node.name}: ${base_type}, _SyntaxBase {
87+
public struct ${node.name}: ${base_type}, _SyntaxBase, Hashable {
7188
% if node.children:
7289
enum Cursor: Int {
7390
% for child in node.children:
@@ -157,6 +174,15 @@ public struct ${node.name}: ${base_type}, _SyntaxBase {
157174
return ${node.name}(root: root, data: newData)
158175
}
159176
% end
177+
178+
public static func ==(lhs: ${node.swift_type_name},
179+
rhs: ${node.swift_type_name}) -> Bool {
180+
return lhs._data === rhs._data
181+
}
182+
183+
public var hashValue: Int {
184+
return ObjectIdentifier(_data).hashValue
185+
}
160186
}
161187

162188
% end

0 commit comments

Comments
 (0)