|
10 | 10 | //
|
11 | 11 | //===----------------------------------------------------------------------===//
|
12 | 12 |
|
13 |
| -struct AbsoluteSyntaxPosition { |
14 |
| - /// The UTF-8 offset of the syntax node in the source file |
15 |
| - let offset: UInt32 |
16 |
| - let indexInParent: UInt32 |
17 |
| - |
18 |
| - func advancedBySibling(_ raw: RawSyntax?) -> AbsoluteSyntaxPosition { |
19 |
| - let newOffset = self.offset + UInt32(truncatingIfNeeded: raw?.totalLength.utf8Length ?? 0) |
20 |
| - let newIndexInParent = self.indexInParent + 1 |
21 |
| - return .init(offset: newOffset, indexInParent: newIndexInParent) |
22 |
| - } |
23 |
| - |
24 |
| - func advancedToFirstChild() -> AbsoluteSyntaxPosition { |
25 |
| - return .init(offset: self.offset, indexInParent: 0) |
26 |
| - } |
27 |
| - |
28 |
| - static var forRoot: AbsoluteSyntaxPosition { |
29 |
| - return .init(offset: 0, indexInParent: 0) |
30 |
| - } |
31 |
| -} |
32 |
| - |
33 |
| -/// AbsoluteSyntaxInfo represents the information that relates a RawSyntax to a |
34 |
| -/// source file tree, like its absolute source offset. |
35 |
| -struct AbsoluteSyntaxInfo { |
36 |
| - let position: AbsoluteSyntaxPosition |
37 |
| - let nodeId: SyntaxIdentifier |
38 |
| - |
39 |
| - /// The UTF-8 offset of the syntax node in the source file |
40 |
| - var offset: UInt32 { return position.offset } |
41 |
| - var indexInParent: UInt32 { return position.indexInParent } |
42 |
| - |
43 |
| - func advancedBySibling(_ raw: RawSyntax?) -> AbsoluteSyntaxInfo { |
44 |
| - let newPosition = position.advancedBySibling(raw) |
45 |
| - let newNodeId = nodeId.advancedBySibling(raw) |
46 |
| - return .init(position: newPosition, nodeId: newNodeId) |
47 |
| - } |
48 |
| - |
49 |
| - func advancedToFirstChild() -> AbsoluteSyntaxInfo { |
50 |
| - let newPosition = position.advancedToFirstChild() |
51 |
| - let newNodeId = nodeId.advancedToFirstChild() |
52 |
| - return .init(position: newPosition, nodeId: newNodeId) |
53 |
| - } |
54 |
| - |
55 |
| - static func forRoot(_ raw: RawSyntax) -> AbsoluteSyntaxInfo { |
56 |
| - return .init(position: .forRoot, nodeId: .forRoot(raw)) |
57 |
| - } |
58 |
| -} |
59 |
| - |
60 |
| -/// Represents a unique value for a node within its own tree. |
61 |
| -@_spi(RawSyntax) |
62 |
| -public struct SyntaxIndexInTree: Comparable, Hashable { |
63 |
| - let indexInTree: UInt32 |
64 |
| - |
65 |
| - static var zero: SyntaxIndexInTree = SyntaxIndexInTree(indexInTree: 0) |
66 |
| - |
67 |
| - /// Assuming that this index points to the start of ``Raw``, so that it points |
68 |
| - /// to the next sibling of ``Raw``. |
69 |
| - func advancedBy(_ raw: RawSyntax?) -> SyntaxIndexInTree { |
70 |
| - let newIndexInTree = self.indexInTree + UInt32(truncatingIfNeeded: raw?.totalNodes ?? 0) |
71 |
| - return .init(indexInTree: newIndexInTree) |
72 |
| - } |
73 |
| - |
74 |
| - /// Assuming that this index points to the next sibling of ``Raw``, reverse it |
75 |
| - /// so that it points to the start of ``Raw``. |
76 |
| - func reversedBy(_ raw: RawSyntax?) -> SyntaxIndexInTree { |
77 |
| - let newIndexInTree = self.indexInTree - UInt32(truncatingIfNeeded: raw?.totalNodes ?? 0) |
78 |
| - return .init(indexInTree: newIndexInTree) |
79 |
| - } |
80 |
| - |
81 |
| - func advancedToFirstChild() -> SyntaxIndexInTree { |
82 |
| - let newIndexInTree = self.indexInTree + 1 |
83 |
| - return .init(indexInTree: newIndexInTree) |
84 |
| - } |
85 |
| - |
86 |
| - init(indexInTree: UInt32) { |
87 |
| - self.indexInTree = indexInTree |
88 |
| - } |
89 |
| - |
90 |
| - /// Returns `true` if `lhs` occurs before `rhs` in the tree. |
91 |
| - public static func < (lhs: SyntaxIndexInTree, rhs: SyntaxIndexInTree) -> Bool { |
92 |
| - return lhs.indexInTree < rhs.indexInTree |
93 |
| - } |
94 |
| -} |
95 |
| - |
96 |
| -/// Provides a stable and unique identity for ``Syntax`` nodes. |
97 |
| -/// |
98 |
| -/// Note that two nodes might have the same contents even if their IDs are |
99 |
| -/// different. For example two different ``FunctionDeclSyntax`` nodes in the |
100 |
| -/// might have the exact same contents but if they occur at a different |
101 |
| -/// location in the source file, they have different IDs. |
102 |
| -/// |
103 |
| -/// Also note that the ID of a syntax node changes when it is anchored in a |
104 |
| -/// different syntax tree. Modifying any node in the syntax tree a node is |
105 |
| -/// contained in generates a copy of that tree and thus changes the IDs of all |
106 |
| -/// nodes in the tree, not just the modified node's children. |
107 |
| -public struct SyntaxIdentifier: Hashable { |
108 |
| - /// Unique value for the root node. |
109 |
| - /// |
110 |
| - /// Multiple trees may have the same 'rootId' if their root RawSyntax is the |
111 |
| - /// same instance. This guarantees that the trees with the same 'rootId' have |
112 |
| - /// exact the same structure. But, two trees with exactly the same structure |
113 |
| - /// might still have different 'rootId's. |
114 |
| - let rootId: UInt |
115 |
| - /// Unique value for a node within its own tree. |
116 |
| - @_spi(RawSyntax) |
117 |
| - public let indexInTree: SyntaxIndexInTree |
118 |
| - |
119 |
| - func advancedBySibling(_ raw: RawSyntax?) -> SyntaxIdentifier { |
120 |
| - let newIndexInTree = indexInTree.advancedBy(raw) |
121 |
| - return .init(rootId: self.rootId, indexInTree: newIndexInTree) |
122 |
| - } |
123 |
| - |
124 |
| - func advancedToFirstChild() -> SyntaxIdentifier { |
125 |
| - let newIndexInTree = self.indexInTree.advancedToFirstChild() |
126 |
| - return .init(rootId: self.rootId, indexInTree: newIndexInTree) |
127 |
| - } |
128 |
| - |
129 |
| - static func forRoot(_ raw: RawSyntax) -> SyntaxIdentifier { |
130 |
| - return .init( |
131 |
| - rootId: UInt(bitPattern: raw.pointer), |
132 |
| - indexInTree: .zero |
133 |
| - ) |
134 |
| - } |
135 |
| -} |
136 |
| - |
137 |
| -struct AbsoluteRawSyntax { |
138 |
| - let raw: RawSyntax |
139 |
| - let info: AbsoluteSyntaxInfo |
140 |
| - |
141 |
| - /// Returns first `present` child. |
142 |
| - func firstChild(viewMode: SyntaxTreeViewMode) -> AbsoluteRawSyntax? { |
143 |
| - guard let layoutView = raw.layoutView else { return nil } |
144 |
| - var curInfo = info.advancedToFirstChild() |
145 |
| - for childOpt in layoutView.children { |
146 |
| - if let child = childOpt, viewMode.shouldTraverse(node: child) { |
147 |
| - return AbsoluteRawSyntax(raw: child, info: curInfo) |
148 |
| - } |
149 |
| - curInfo = curInfo.advancedBySibling(childOpt) |
150 |
| - } |
151 |
| - return nil |
152 |
| - } |
153 |
| - |
154 |
| - /// Returns next `present` sibling. |
155 |
| - func nextSibling(parent: AbsoluteRawSyntax, viewMode: SyntaxTreeViewMode) -> AbsoluteRawSyntax? { |
156 |
| - var curInfo = info.advancedBySibling(raw) |
157 |
| - for siblingOpt in parent.raw.layoutView!.children.dropFirst(Int(info.indexInParent + 1)) { |
158 |
| - if let sibling = siblingOpt, viewMode.shouldTraverse(node: sibling) { |
159 |
| - return AbsoluteRawSyntax(raw: sibling, info: curInfo) |
160 |
| - } |
161 |
| - curInfo = curInfo.advancedBySibling(siblingOpt) |
162 |
| - } |
163 |
| - return nil |
164 |
| - } |
165 |
| - |
166 |
| - func replacingSelf(_ newRaw: RawSyntax, newRootId: UInt) -> AbsoluteRawSyntax { |
167 |
| - let nodeId = SyntaxIdentifier(rootId: newRootId, indexInTree: info.nodeId.indexInTree) |
168 |
| - let newInfo = AbsoluteSyntaxInfo(position: info.position, nodeId: nodeId) |
169 |
| - return .init(raw: newRaw, info: newInfo) |
170 |
| - } |
171 |
| -} |
172 |
| - |
173 | 13 | /// SyntaxData is the underlying storage for each Syntax node.
|
174 | 14 | ///
|
175 | 15 | /// SyntaxData is an implementation detail, and should not be exposed to clients
|
|
0 commit comments