aboutsummaryrefslogtreecommitdiff
path: root/src/tree
diff options
context:
space:
mode:
Diffstat (limited to 'src/tree')
-rw-r--r--src/tree/file_builder.rs32
-rw-r--r--src/tree/mod.rs44
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 @@
1use {SyntaxKind, TextUnit, TextRange}; 1use {SyntaxKind, TextRange, TextUnit};
2use super::{NodeData, SyntaxErrorData, NodeIdx, File}; 2use super::{File, NodeData, NodeIdx, SyntaxErrorData};
3 3
4pub trait Sink { 4pub 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
12pub struct FileBuilder { 11pub 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
141pub struct ErrorBuilder<'f> { 142pub 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
146impl<'f> ErrorBuilder<'f> { 147impl<'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 @@
1use text::{TextUnit, TextRange}; 1use text::{TextRange, TextUnit};
2use syntax_kinds::syntax_info; 2use syntax_kinds::syntax_info;
3 3
4use std::fmt; 4use std::fmt;
@@ -11,15 +11,10 @@ pub use self::file_builder::{FileBuilder, Sink};
11pub struct SyntaxKind(pub(crate) u32); 11pub struct SyntaxKind(pub(crate) u32);
12 12
13pub(crate) const EOF: SyntaxKind = SyntaxKind(!0); 13pub(crate) const EOF: SyntaxKind = SyntaxKind(!0);
14pub(crate) const EOF_INFO: SyntaxInfo = SyntaxInfo { 14pub(crate) const EOF_INFO: SyntaxInfo = SyntaxInfo { name: "EOF" };
15 name: "EOF"
16};
17 15
18pub(crate) const TOMBSTONE: SyntaxKind = SyntaxKind(!0 - 1); 16pub(crate) const TOMBSTONE: SyntaxKind = SyntaxKind(!0 - 1);
19pub(crate) const TOMBSTONE_INFO: SyntaxInfo = SyntaxInfo { 17pub(crate) const TOMBSTONE_INFO: SyntaxInfo = SyntaxInfo { name: "TOMBSTONE" };
20 name: "TOMBSTONE"
21};
22
23 18
24impl SyntaxKind { 19impl 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
42pub(crate) struct SyntaxInfo { 36pub(crate) struct SyntaxInfo {
43 pub name: &'static str, 37 pub name: &'static str,
44} 38}
@@ -58,7 +52,10 @@ pub struct File {
58impl File { 52impl 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
121impl<'f> cmp::Eq for Node<'f> { 124impl<'f> cmp::Eq for Node<'f> {}
122}
123 125
124#[derive(Clone, Copy)] 126#[derive(Clone, Copy)]
125pub struct SyntaxError<'f> { 127pub 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)]
190struct NodeIdx(u32); 194struct NodeIdx(u32);
191 195