aboutsummaryrefslogtreecommitdiff
path: root/src/tree/mod.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2017-12-31 15:58:03 +0000
committerAleksey Kladov <[email protected]>2017-12-31 15:58:03 +0000
commit9c804accf19d1a93739a7cbfdd1da5528833d6c3 (patch)
treed199c5634a12011a162e4a9d324b89891d369ba6 /src/tree/mod.rs
parent9ce4db545efba697f20ab5cecbefc0589c7146ca (diff)
Move tree to a separate module
Diffstat (limited to 'src/tree/mod.rs')
-rw-r--r--src/tree/mod.rs101
1 files changed, 101 insertions, 0 deletions
diff --git a/src/tree/mod.rs b/src/tree/mod.rs
new file mode 100644
index 000000000..2ac25e795
--- /dev/null
+++ b/src/tree/mod.rs
@@ -0,0 +1,101 @@
1use text::{TextUnit, TextRange};
2use syntax_kinds::syntax_info;
3
4use std::fmt;
5
6#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
7pub struct SyntaxKind(pub(crate) u32);
8
9impl SyntaxKind {
10 fn info(self) -> &'static SyntaxInfo {
11 syntax_info(self)
12 }
13}
14
15impl fmt::Debug for SyntaxKind {
16 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
17 let name = self.info().name;
18 f.write_str(name)
19 }
20}
21
22
23pub(crate) struct SyntaxInfo {
24 pub name: &'static str,
25}
26
27#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
28pub struct Token {
29 pub kind: SyntaxKind,
30 pub len: TextUnit,
31}
32
33pub struct File {
34 text: String,
35 nodes: Vec<NodeData>,
36}
37
38impl File {
39 pub fn root<'f>(&'f self) -> Node<'f> {
40 assert!(!self.nodes.is_empty());
41 Node { file: self, idx: NodeIdx(0) }
42 }
43}
44
45#[derive(Clone, Copy)]
46pub struct Node<'f> {
47 file: &'f File,
48 idx: NodeIdx,
49}
50
51impl<'f> Node<'f> {
52 pub fn kind(&self) -> SyntaxKind {
53 self.data().kind
54 }
55
56 pub fn text(&self) -> &'f str {
57 let range = self.data().range;
58 &self.file.text.as_str()[range]
59 }
60
61 pub fn parent(&self) -> Option<Node<'f>> {
62 self.as_node(self.data().parent)
63 }
64
65 pub fn children(&self) -> Children<'f> {
66 Children { next: self.as_node(self.data().first_child) }
67 }
68
69 fn data(&self) -> &'f NodeData {
70 &self.file.nodes[self.idx.0 as usize]
71 }
72
73 fn as_node(&self, idx: Option<NodeIdx>) -> Option<Node<'f>> {
74 idx.map(|idx| Node { file: self.file, idx })
75 }
76}
77
78pub struct Children<'f> {
79 next: Option<Node<'f>>,
80}
81
82impl<'f> Iterator for Children<'f> {
83 type Item = Node<'f>;
84
85 fn next(&mut self) -> Option<Node<'f>> {
86 let next = self.next;
87 self.next = next.and_then(|node| node.as_node(node.data().next_sibling));
88 next
89 }
90}
91
92#[derive(Clone, Copy)]
93struct NodeIdx(u32);
94
95struct NodeData {
96 kind: SyntaxKind,
97 range: TextRange,
98 parent: Option<NodeIdx>,
99 first_child: Option<NodeIdx>,
100 next_sibling: Option<NodeIdx>,
101}