diff options
Diffstat (limited to 'src/tree')
-rw-r--r-- | src/tree/file_builder.rs | 32 | ||||
-rw-r--r-- | src/tree/mod.rs | 44 |
2 files changed, 44 insertions, 32 deletions
diff --git a/src/tree/file_builder.rs b/src/tree/file_builder.rs index 35702ddd7..939922cb2 100644 --- a/src/tree/file_builder.rs +++ b/src/tree/file_builder.rs | |||
@@ -1,5 +1,5 @@ | |||
1 | use {SyntaxKind, TextUnit, TextRange}; | 1 | use {SyntaxKind, TextRange, TextUnit}; |
2 | use super::{NodeData, SyntaxErrorData, NodeIdx, File}; | 2 | use super::{File, NodeData, NodeIdx, SyntaxErrorData}; |
3 | 3 | ||
4 | pub trait Sink { | 4 | pub trait Sink { |
5 | fn leaf(&mut self, kind: SyntaxKind, len: TextUnit); | 5 | fn leaf(&mut self, kind: SyntaxKind, len: TextUnit); |
@@ -8,7 +8,6 @@ pub trait Sink { | |||
8 | fn error(&mut self) -> ErrorBuilder; | 8 | fn error(&mut self) -> ErrorBuilder; |
9 | } | 9 | } |
10 | 10 | ||
11 | |||
12 | pub struct FileBuilder { | 11 | pub struct FileBuilder { |
13 | text: String, | 12 | text: String, |
14 | nodes: Vec<NodeData>, | 13 | nodes: Vec<NodeData>, |
@@ -48,9 +47,9 @@ impl Sink for FileBuilder { | |||
48 | } | 47 | } |
49 | 48 | ||
50 | fn finish_internal(&mut self) { | 49 | fn finish_internal(&mut self) { |
51 | let (id, _) = self.in_progress.pop().expect( | 50 | let (id, _) = self.in_progress |
52 | "trying to complete a node, but there are no in-progress nodes" | 51 | .pop() |
53 | ); | 52 | .expect("trying to complete a node, but there are no in-progress nodes"); |
54 | if !self.in_progress.is_empty() { | 53 | if !self.in_progress.is_empty() { |
55 | self.add_len(id); | 54 | self.add_len(id); |
56 | } | 55 | } |
@@ -76,11 +75,14 @@ impl FileBuilder { | |||
76 | assert!( | 75 | assert!( |
77 | self.in_progress.is_empty(), | 76 | self.in_progress.is_empty(), |
78 | "some nodes in FileBuilder are unfinished: {:?}", | 77 | "some nodes in FileBuilder are unfinished: {:?}", |
79 | self.in_progress.iter().map(|&(idx, _)| self.nodes[idx].kind) | 78 | self.in_progress |
79 | .iter() | ||
80 | .map(|&(idx, _)| self.nodes[idx].kind) | ||
80 | .collect::<Vec<_>>() | 81 | .collect::<Vec<_>>() |
81 | ); | 82 | ); |
82 | assert_eq!( | 83 | assert_eq!( |
83 | self.pos, (self.text.len() as u32).into(), | 84 | self.pos, |
85 | (self.text.len() as u32).into(), | ||
84 | "nodes in FileBuilder do not cover the whole file" | 86 | "nodes in FileBuilder do not cover the whole file" |
85 | ); | 87 | ); |
86 | File { | 88 | File { |
@@ -100,7 +102,6 @@ impl FileBuilder { | |||
100 | child.parent = Some(self.current_id()); | 102 | child.parent = Some(self.current_id()); |
101 | let id = self.new_node(child); | 103 | let id = self.new_node(child); |
102 | { | 104 | { |
103 | |||
104 | let (parent, sibling) = *self.in_progress.last().unwrap(); | 105 | let (parent, sibling) = *self.in_progress.last().unwrap(); |
105 | let slot = if let Some(idx) = sibling { | 106 | let slot = if let Some(idx) = sibling { |
106 | &mut self.nodes[idx].next_sibling | 107 | &mut self.nodes[idx].next_sibling |
@@ -140,12 +141,15 @@ fn grow(left: &mut TextRange, right: TextRange) { | |||
140 | 141 | ||
141 | pub struct ErrorBuilder<'f> { | 142 | pub struct ErrorBuilder<'f> { |
142 | message: Option<String>, | 143 | message: Option<String>, |
143 | builder: &'f mut FileBuilder | 144 | builder: &'f mut FileBuilder, |
144 | } | 145 | } |
145 | 146 | ||
146 | impl<'f> ErrorBuilder<'f> { | 147 | impl<'f> ErrorBuilder<'f> { |
147 | fn new(builder: &'f mut FileBuilder) -> Self { | 148 | fn new(builder: &'f mut FileBuilder) -> Self { |
148 | ErrorBuilder { message: None, builder } | 149 | ErrorBuilder { |
150 | message: None, | ||
151 | builder, | ||
152 | } | ||
149 | } | 153 | } |
150 | 154 | ||
151 | pub fn message<M: Into<String>>(mut self, m: M) -> Self { | 155 | pub fn message<M: Into<String>>(mut self, m: M) -> Self { |
@@ -156,6 +160,10 @@ impl<'f> ErrorBuilder<'f> { | |||
156 | pub fn emit(self) { | 160 | pub fn emit(self) { |
157 | let message = self.message.expect("Error message not set"); | 161 | let message = self.message.expect("Error message not set"); |
158 | let &(node, after_child) = self.builder.in_progress.last().unwrap(); | 162 | let &(node, after_child) = self.builder.in_progress.last().unwrap(); |
159 | self.builder.errors.push(SyntaxErrorData { node, message, after_child }) | 163 | self.builder.errors.push(SyntaxErrorData { |
164 | node, | ||
165 | message, | ||
166 | after_child, | ||
167 | }) | ||
160 | } | 168 | } |
161 | } | 169 | } |
diff --git a/src/tree/mod.rs b/src/tree/mod.rs index 3315b926e..a330caf54 100644 --- a/src/tree/mod.rs +++ b/src/tree/mod.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use text::{TextUnit, TextRange}; | 1 | use text::{TextRange, TextUnit}; |
2 | use syntax_kinds::syntax_info; | 2 | use syntax_kinds::syntax_info; |
3 | 3 | ||
4 | use std::fmt; | 4 | use std::fmt; |
@@ -11,15 +11,10 @@ pub use self::file_builder::{FileBuilder, Sink}; | |||
11 | pub struct SyntaxKind(pub(crate) u32); | 11 | pub struct SyntaxKind(pub(crate) u32); |
12 | 12 | ||
13 | pub(crate) const EOF: SyntaxKind = SyntaxKind(!0); | 13 | pub(crate) const EOF: SyntaxKind = SyntaxKind(!0); |
14 | pub(crate) const EOF_INFO: SyntaxInfo = SyntaxInfo { | 14 | pub(crate) const EOF_INFO: SyntaxInfo = SyntaxInfo { name: "EOF" }; |
15 | name: "EOF" | ||
16 | }; | ||
17 | 15 | ||
18 | pub(crate) const TOMBSTONE: SyntaxKind = SyntaxKind(!0 - 1); | 16 | pub(crate) const TOMBSTONE: SyntaxKind = SyntaxKind(!0 - 1); |
19 | pub(crate) const TOMBSTONE_INFO: SyntaxInfo = SyntaxInfo { | 17 | pub(crate) const TOMBSTONE_INFO: SyntaxInfo = SyntaxInfo { name: "TOMBSTONE" }; |
20 | name: "TOMBSTONE" | ||
21 | }; | ||
22 | |||
23 | 18 | ||
24 | impl SyntaxKind { | 19 | impl SyntaxKind { |
25 | fn info(self) -> &'static SyntaxInfo { | 20 | fn info(self) -> &'static SyntaxInfo { |
@@ -38,7 +33,6 @@ impl fmt::Debug for SyntaxKind { | |||
38 | } | 33 | } |
39 | } | 34 | } |
40 | 35 | ||
41 | |||
42 | pub(crate) struct SyntaxInfo { | 36 | pub(crate) struct SyntaxInfo { |
43 | pub name: &'static str, | 37 | pub name: &'static str, |
44 | } | 38 | } |
@@ -58,7 +52,10 @@ pub struct File { | |||
58 | impl File { | 52 | impl File { |
59 | pub fn root<'f>(&'f self) -> Node<'f> { | 53 | pub fn root<'f>(&'f self) -> Node<'f> { |
60 | assert!(!self.nodes.is_empty()); | 54 | assert!(!self.nodes.is_empty()); |
61 | Node { file: self, idx: NodeIdx(0) } | 55 | Node { |
56 | file: self, | ||
57 | idx: NodeIdx(0), | ||
58 | } | ||
62 | } | 59 | } |
63 | } | 60 | } |
64 | 61 | ||
@@ -86,14 +83,17 @@ impl<'f> Node<'f> { | |||
86 | } | 83 | } |
87 | 84 | ||
88 | pub fn children(&self) -> Children<'f> { | 85 | pub fn children(&self) -> Children<'f> { |
89 | Children { next: self.as_node(self.data().first_child) } | 86 | Children { |
87 | next: self.as_node(self.data().first_child), | ||
88 | } | ||
90 | } | 89 | } |
91 | 90 | ||
92 | pub fn errors(&self) -> SyntaxErrors<'f> { | 91 | pub fn errors(&self) -> SyntaxErrors<'f> { |
93 | let pos = self.file.errors.iter().position(|e| e.node == self.idx); | 92 | let pos = self.file.errors.iter().position(|e| e.node == self.idx); |
94 | let next = pos | 93 | let next = pos.map(|i| ErrorIdx(i as u32)).map(|idx| SyntaxError { |
95 | .map(|i| ErrorIdx(i as u32)) | 94 | file: self.file, |
96 | .map(|idx| SyntaxError { file: self.file, idx }); | 95 | idx, |
96 | }); | ||
97 | SyntaxErrors { next } | 97 | SyntaxErrors { next } |
98 | } | 98 | } |
99 | 99 | ||
@@ -102,7 +102,10 @@ impl<'f> Node<'f> { | |||
102 | } | 102 | } |
103 | 103 | ||
104 | fn as_node(&self, idx: Option<NodeIdx>) -> Option<Node<'f>> { | 104 | fn as_node(&self, idx: Option<NodeIdx>) -> Option<Node<'f>> { |
105 | idx.map(|idx| Node { file: self.file, idx }) | 105 | idx.map(|idx| Node { |
106 | file: self.file, | ||
107 | idx, | ||
108 | }) | ||
106 | } | 109 | } |
107 | } | 110 | } |
108 | 111 | ||
@@ -118,8 +121,7 @@ impl<'f> cmp::PartialEq<Node<'f>> for Node<'f> { | |||
118 | } | 121 | } |
119 | } | 122 | } |
120 | 123 | ||
121 | impl<'f> cmp::Eq for Node<'f> { | 124 | impl<'f> cmp::Eq for Node<'f> {} |
122 | } | ||
123 | 125 | ||
124 | #[derive(Clone, Copy)] | 126 | #[derive(Clone, Copy)] |
125 | pub struct SyntaxError<'f> { | 127 | pub struct SyntaxError<'f> { |
@@ -134,7 +136,10 @@ impl<'f> SyntaxError<'f> { | |||
134 | 136 | ||
135 | pub fn after_child(&self) -> Option<Node<'f>> { | 137 | pub fn after_child(&self) -> Option<Node<'f>> { |
136 | let idx = self.data().after_child?; | 138 | let idx = self.data().after_child?; |
137 | Some(Node { file: self.file, idx }) | 139 | Some(Node { |
140 | file: self.file, | ||
141 | idx, | ||
142 | }) | ||
138 | } | 143 | } |
139 | 144 | ||
140 | fn data(&self) -> &'f SyntaxErrorData { | 145 | fn data(&self) -> &'f SyntaxErrorData { |
@@ -148,7 +153,7 @@ impl<'f> SyntaxError<'f> { | |||
148 | } | 153 | } |
149 | let result = SyntaxError { | 154 | let result = SyntaxError { |
150 | file: self.file, | 155 | file: self.file, |
151 | idx: ErrorIdx(next_idx) | 156 | idx: ErrorIdx(next_idx), |
152 | }; | 157 | }; |
153 | if result.data().node != self.data().node { | 158 | if result.data().node != self.data().node { |
154 | return None; | 159 | return None; |
@@ -185,7 +190,6 @@ impl<'f> Iterator for SyntaxErrors<'f> { | |||
185 | } | 190 | } |
186 | } | 191 | } |
187 | 192 | ||
188 | |||
189 | #[derive(Clone, Copy, PartialEq, Eq)] | 193 | #[derive(Clone, Copy, PartialEq, Eq)] |
190 | struct NodeIdx(u32); | 194 | struct NodeIdx(u32); |
191 | 195 | ||