]> git.lizzy.rs Git - rust.git/blob - src/tree/mod.rs
aaf048c73415dc5d2e7bb121394bb164aab2fa40
[rust.git] / src / tree / mod.rs
1 use text::{TextRange, TextUnit};
2 use syntax_kinds::syntax_info;
3
4 use std::fmt;
5 use std::cmp;
6
7 mod file_builder;
8 pub use self::file_builder::{FileBuilder, Sink};
9
10 /// The kind of syntax node, e.g. `IDENT`, `USE_KW`, or `STRUCT_DEF`.
11 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
12 pub struct SyntaxKind(pub(crate) u32);
13
14 pub(crate) const EOF: SyntaxKind = SyntaxKind(!0);
15 pub(crate) const EOF_INFO: SyntaxInfo = SyntaxInfo { name: "EOF" };
16
17 pub(crate) const TOMBSTONE: SyntaxKind = SyntaxKind(!0 - 1);
18 pub(crate) const TOMBSTONE_INFO: SyntaxInfo = SyntaxInfo { name: "TOMBSTONE" };
19
20 impl SyntaxKind {
21     fn info(self) -> &'static SyntaxInfo {
22         match self {
23             EOF => &EOF_INFO,
24             TOMBSTONE => &TOMBSTONE_INFO,
25             _ => syntax_info(self),
26         }
27     }
28 }
29
30 impl fmt::Debug for SyntaxKind {
31     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
32         let name = self.info().name;
33         f.write_str(name)
34     }
35 }
36
37 pub(crate) struct SyntaxInfo {
38     pub name: &'static str,
39 }
40
41 /// A token of Rust source.
42 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
43 pub struct Token {
44     /// The kind of token.
45     pub kind: SyntaxKind,
46     /// The length of the token.
47     pub len: TextUnit,
48 }
49
50 /// The contents of a Rust source file.
51 #[derive(Debug)]
52 pub struct File {
53     text: String,
54     nodes: Vec<NodeData>,
55     errors: Vec<SyntaxErrorData>,
56 }
57
58 impl File {
59     /// The root node of this source file.
60     pub fn root<'f>(&'f self) -> Node<'f> {
61         assert!(!self.nodes.is_empty());
62         Node {
63             file: self,
64             idx: NodeIdx(0),
65         }
66     }
67 }
68
69 /// A reference to a token in a Rust source file.
70 #[derive(Clone, Copy)]
71 pub struct Node<'f> {
72     file: &'f File,
73     idx: NodeIdx,
74 }
75
76 impl<'f> Node<'f> {
77     /// The kind of the token at this node.
78     pub fn kind(&self) -> SyntaxKind {
79         self.data().kind
80     }
81
82     /// The text range covered by the token at this node.
83     pub fn range(&self) -> TextRange {
84         self.data().range
85     }
86
87     /// The text at this node.
88     pub fn text(&self) -> &'f str {
89         &self.file.text.as_str()[self.range()]
90     }
91
92     /// The parent node to this node.
93     pub fn parent(&self) -> Option<Node<'f>> {
94         self.as_node(self.data().parent)
95     }
96
97     /// The children nodes of this node.
98     pub fn children(&self) -> Children<'f> {
99         Children {
100             next: self.as_node(self.data().first_child),
101         }
102     }
103
104     /// Any errors contained in this node.
105     pub fn errors(&self) -> SyntaxErrors<'f> {
106         let pos = self.file.errors.iter().position(|e| e.node == self.idx);
107         let next = pos.map(|i| ErrorIdx(i as u32)).map(|idx| SyntaxError {
108             file: self.file,
109             idx,
110         });
111         SyntaxErrors { next }
112     }
113
114     fn data(&self) -> &'f NodeData {
115         &self.file.nodes[self.idx]
116     }
117
118     fn as_node(&self, idx: Option<NodeIdx>) -> Option<Node<'f>> {
119         idx.map(|idx| Node {
120             file: self.file,
121             idx,
122         })
123     }
124 }
125
126 impl<'f> fmt::Debug for Node<'f> {
127     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
128         write!(fmt, "{:?}@{:?}", self.kind(), self.range())
129     }
130 }
131
132 impl<'f> cmp::PartialEq<Node<'f>> for Node<'f> {
133     fn eq(&self, other: &Node<'f>) -> bool {
134         self.idx == other.idx && ::std::ptr::eq(self.file, other.file)
135     }
136 }
137
138 impl<'f> cmp::Eq for Node<'f> {}
139
140 #[derive(Clone, Copy, Debug)]
141 pub struct SyntaxError<'f> {
142     file: &'f File,
143     idx: ErrorIdx,
144 }
145
146 impl<'f> SyntaxError<'f> {
147     pub fn message(&self) -> &'f str {
148         self.data().message.as_str()
149     }
150
151     pub fn after_child(&self) -> Option<Node<'f>> {
152         let idx = self.data().after_child?;
153         Some(Node {
154             file: self.file,
155             idx,
156         })
157     }
158
159     fn data(&self) -> &'f SyntaxErrorData {
160         &self.file.errors[self.idx]
161     }
162
163     fn next(&self) -> Option<SyntaxError<'f>> {
164         let next_idx = self.idx.0 + 1;
165         if !((next_idx as usize) < self.file.errors.len()) {
166             return None;
167         }
168         let result = SyntaxError {
169             file: self.file,
170             idx: ErrorIdx(next_idx),
171         };
172         if result.data().node != self.data().node {
173             return None;
174         }
175         Some(result)
176     }
177 }
178
179 #[derive(Debug)]
180 pub struct Children<'f> {
181     next: Option<Node<'f>>,
182 }
183
184 impl<'f> Iterator for Children<'f> {
185     type Item = Node<'f>;
186
187     fn next(&mut self) -> Option<Node<'f>> {
188         let next = self.next;
189         self.next = next.and_then(|node| node.as_node(node.data().next_sibling));
190         next
191     }
192 }
193
194 #[derive(Debug)]
195 pub struct SyntaxErrors<'f> {
196     next: Option<SyntaxError<'f>>,
197 }
198
199 impl<'f> Iterator for SyntaxErrors<'f> {
200     type Item = SyntaxError<'f>;
201
202     fn next(&mut self) -> Option<SyntaxError<'f>> {
203         let next = self.next;
204         self.next = next.as_ref().and_then(SyntaxError::next);
205         next
206     }
207 }
208
209 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
210 struct NodeIdx(u32);
211
212 #[derive(Debug)]
213 struct NodeData {
214     kind: SyntaxKind,
215     range: TextRange,
216     parent: Option<NodeIdx>,
217     first_child: Option<NodeIdx>,
218     next_sibling: Option<NodeIdx>,
219 }
220
221 impl ::std::ops::Index<NodeIdx> for Vec<NodeData> {
222     type Output = NodeData;
223
224     fn index(&self, NodeIdx(idx): NodeIdx) -> &NodeData {
225         &self[idx as usize]
226     }
227 }
228
229 impl ::std::ops::IndexMut<NodeIdx> for Vec<NodeData> {
230     fn index_mut(&mut self, NodeIdx(idx): NodeIdx) -> &mut NodeData {
231         &mut self[idx as usize]
232     }
233 }
234
235 #[derive(Clone, Copy, Debug)]
236 struct ErrorIdx(u32);
237
238 #[derive(Debug)]
239 struct SyntaxErrorData {
240     node: NodeIdx,
241     message: String,
242     after_child: Option<NodeIdx>,
243 }
244
245 impl ::std::ops::Index<ErrorIdx> for Vec<SyntaxErrorData> {
246     type Output = SyntaxErrorData;
247
248     fn index(&self, ErrorIdx(idx): ErrorIdx) -> &SyntaxErrorData {
249         &self[idx as usize]
250     }
251 }