aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib.rs2
-rw-r--r--src/parser/event.rs6
-rw-r--r--src/parser/grammar/attributes.rs8
-rw-r--r--src/parser/grammar/expressions.rs2
-rw-r--r--src/parser/grammar/items/mod.rs8
-rw-r--r--src/parser/grammar/items/structs.rs4
-rw-r--r--src/parser/grammar/items/use_item.rs2
-rw-r--r--src/parser/grammar/mod.rs6
-rw-r--r--src/parser/grammar/paths.rs4
-rw-r--r--src/parser/parser.rs28
-rw-r--r--src/tree/file_builder.rs45
-rw-r--r--src/tree/mod.rs2
12 files changed, 48 insertions, 69 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 0ea8f6a63..153458644 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -25,7 +25,7 @@ mod parser;
25pub mod syntax_kinds; 25pub mod syntax_kinds;
26pub use text::{TextRange, TextUnit}; 26pub use text::{TextRange, TextUnit};
27pub use tree::{File, Node, SyntaxKind, Token}; 27pub use tree::{File, Node, SyntaxKind, Token};
28pub(crate) use tree::{FileBuilder, Sink}; 28pub(crate) use tree::{ErrorMsg, FileBuilder, Sink};
29pub use lexer::{next_token, tokenize}; 29pub use lexer::{next_token, tokenize};
30pub use parser::parse; 30pub use parser::parse;
31 31
diff --git a/src/parser/event.rs b/src/parser/event.rs
index e97350c89..90348398e 100644
--- a/src/parser/event.rs
+++ b/src/parser/event.rs
@@ -1,4 +1,4 @@
1use {File, FileBuilder, Sink, SyntaxKind, TextUnit, Token}; 1use {ErrorMsg, File, FileBuilder, Sink, SyntaxKind, TextUnit, Token};
2use syntax_kinds::TOMBSTONE; 2use syntax_kinds::TOMBSTONE;
3use super::is_insignificant; 3use super::is_insignificant;
4 4
@@ -140,7 +140,9 @@ pub(super) fn to_file(text: String, tokens: &[Token], events: Vec<Event>) -> Fil
140 } 140 }
141 builder.leaf(kind, len); 141 builder.leaf(kind, len);
142 } 142 }
143 &Event::Error { ref message } => builder.error().message(message.clone()).emit(), 143 &Event::Error { ref message } => builder.error(ErrorMsg {
144 message: message.clone(),
145 }),
144 } 146 }
145 } 147 }
146 builder.finish() 148 builder.finish()
diff --git a/src/parser/grammar/attributes.rs b/src/parser/grammar/attributes.rs
index 8bf04afce..92dfb99ef 100644
--- a/src/parser/grammar/attributes.rs
+++ b/src/parser/grammar/attributes.rs
@@ -37,7 +37,7 @@ fn meta_item(p: &mut Parser) {
37 EQ => { 37 EQ => {
38 p.bump(); 38 p.bump();
39 if !expressions::literal(p) { 39 if !expressions::literal(p) {
40 p.error().message("expected literal").emit(); 40 p.error("expected literal");
41 } 41 }
42 } 42 }
43 L_PAREN => meta_item_arg_list(p), 43 L_PAREN => meta_item_arg_list(p),
@@ -45,7 +45,7 @@ fn meta_item(p: &mut Parser) {
45 } 45 }
46 meta_item.complete(p, META_ITEM); 46 meta_item.complete(p, META_ITEM);
47 } else { 47 } else {
48 p.error().message("expected attribute value").emit() 48 p.error("expected attribute value");
49 } 49 }
50} 50}
51 51
@@ -60,12 +60,12 @@ fn meta_item_arg_list(p: &mut Parser) {
60 let message = "expected attribute"; 60 let message = "expected attribute";
61 61
62 if items::ITEM_FIRST.contains(c) { 62 if items::ITEM_FIRST.contains(c) {
63 p.error().message(message).emit(); 63 p.error(message);
64 return; 64 return;
65 } 65 }
66 66
67 let err = p.start(); 67 let err = p.start();
68 p.error().message(message).emit(); 68 p.error(message);
69 p.bump(); 69 p.bump();
70 err.complete(p, ERROR); 70 err.complete(p, ERROR);
71 continue; 71 continue;
diff --git a/src/parser/grammar/expressions.rs b/src/parser/grammar/expressions.rs
index 8caaf3553..3704cb16f 100644
--- a/src/parser/grammar/expressions.rs
+++ b/src/parser/grammar/expressions.rs
@@ -15,6 +15,6 @@ pub(super) fn literal(p: &mut Parser) -> bool {
15 15
16pub(super) fn expr(p: &mut Parser) { 16pub(super) fn expr(p: &mut Parser) {
17 if !literal(p) { 17 if !literal(p) {
18 p.error().message("expected expression").emit(); 18 p.error("expected expression");
19 } 19 }
20} 20}
diff --git a/src/parser/grammar/items/mod.rs b/src/parser/grammar/items/mod.rs
index 37f2ab132..b73628ec0 100644
--- a/src/parser/grammar/items/mod.rs
+++ b/src/parser/grammar/items/mod.rs
@@ -51,7 +51,7 @@ fn item(p: &mut Parser) {
51 // extern struct Foo; 51 // extern struct Foo;
52 _ => { 52 _ => {
53 item.abandon(p); 53 item.abandon(p);
54 p.error().message("expected `fn` or `{`").emit(); 54 p.error("expected `fn` or `{`");
55 return; 55 return;
56 } 56 }
57 } 57 }
@@ -121,7 +121,7 @@ fn item(p: &mut Parser) {
121 abi(p); 121 abi(p);
122 if !p.at(FN_KW) { 122 if !p.at(FN_KW) {
123 item.abandon(p); 123 item.abandon(p);
124 p.error().message("expected function").emit(); 124 p.error("expected function");
125 return; 125 return;
126 } 126 }
127 fn_item(p); 127 fn_item(p);
@@ -144,7 +144,7 @@ fn item(p: &mut Parser) {
144 if t == L_CURLY { 144 if t == L_CURLY {
145 error_block(p, message); 145 error_block(p, message);
146 } else { 146 } else {
147 p.error().message(message).emit(); 147 p.error(message);
148 } 148 }
149 return; 149 return;
150 } 150 }
@@ -234,7 +234,7 @@ fn fn_item(p: &mut Parser) {
234 if p.at(L_PAREN) { 234 if p.at(L_PAREN) {
235 fn_value_parameters(p); 235 fn_value_parameters(p);
236 } else { 236 } else {
237 p.error().message("expected function arguments").emit(); 237 p.error("expected function arguments");
238 } 238 }
239 239
240 if p.at(L_CURLY) { 240 if p.at(L_CURLY) {
diff --git a/src/parser/grammar/items/structs.rs b/src/parser/grammar/items/structs.rs
index 69d95c698..640b940e4 100644
--- a/src/parser/grammar/items/structs.rs
+++ b/src/parser/grammar/items/structs.rs
@@ -19,7 +19,7 @@ pub(super) fn struct_item(p: &mut Parser) {
19 L_CURLY => named_fields(p), 19 L_CURLY => named_fields(p),
20 _ => { 20 _ => {
21 //TODO: special case `(` error message 21 //TODO: special case `(` error message
22 p.error().message("expected `;` or `{`").emit(); 22 p.error("expected `;` or `{`");
23 return; 23 return;
24 } 24 }
25 } 25 }
@@ -34,7 +34,7 @@ pub(super) fn struct_item(p: &mut Parser) {
34 p.expect(SEMI); 34 p.expect(SEMI);
35 } 35 }
36 _ => { 36 _ => {
37 p.error().message("expected `;`, `{`, or `(`").emit(); 37 p.error("expected `;`, `{`, or `(`");
38 return; 38 return;
39 } 39 }
40 } 40 }
diff --git a/src/parser/grammar/items/use_item.rs b/src/parser/grammar/items/use_item.rs
index 38e7b3f8a..a3f7f0da8 100644
--- a/src/parser/grammar/items/use_item.rs
+++ b/src/parser/grammar/items/use_item.rs
@@ -37,7 +37,7 @@ fn use_tree(p: &mut Parser) {
37 L_CURLY => nested_trees(p), 37 L_CURLY => nested_trees(p),
38 _ => { 38 _ => {
39 // is this unreachable? 39 // is this unreachable?
40 p.error().message("expected `{` or `*`").emit(); 40 p.error("expected `{` or `*`");
41 } 41 }
42 } 42 }
43 } 43 }
diff --git a/src/parser/grammar/mod.rs b/src/parser/grammar/mod.rs
index afce308d0..b949583ff 100644
--- a/src/parser/grammar/mod.rs
+++ b/src/parser/grammar/mod.rs
@@ -53,7 +53,7 @@ fn alias(p: &mut Parser) -> bool {
53fn error_block(p: &mut Parser, message: &str) { 53fn error_block(p: &mut Parser, message: &str) {
54 assert!(p.at(L_CURLY)); 54 assert!(p.at(L_CURLY));
55 let err = p.start(); 55 let err = p.start();
56 p.error().message(message).emit(); 56 p.error(message);
57 p.bump(); 57 p.bump();
58 let mut level: u32 = 1; 58 let mut level: u32 = 1;
59 while level > 0 && !p.at(EOF) { 59 while level > 0 && !p.at(EOF) {
@@ -74,7 +74,7 @@ impl<'p> Parser<'p> {
74 74
75 fn err_and_bump(&mut self, message: &str) { 75 fn err_and_bump(&mut self, message: &str) {
76 let err = self.start(); 76 let err = self.start();
77 self.error().message(message).emit(); 77 self.error(message);
78 self.bump(); 78 self.bump();
79 err.complete(self, ERROR); 79 err.complete(self, ERROR);
80 } 80 }
@@ -84,7 +84,7 @@ impl<'p> Parser<'p> {
84 self.bump(); 84 self.bump();
85 true 85 true
86 } else { 86 } else {
87 self.error().message(format!("expected {:?}", kind)).emit(); 87 self.error(format!("expected {:?}", kind));
88 false 88 false
89 } 89 }
90 } 90 }
diff --git a/src/parser/grammar/paths.rs b/src/parser/grammar/paths.rs
index 6efac2610..a7fc90774 100644
--- a/src/parser/grammar/paths.rs
+++ b/src/parser/grammar/paths.rs
@@ -43,7 +43,9 @@ fn path_segment(p: &mut Parser, first: bool) {
43 } 43 }
44 match p.current() { 44 match p.current() {
45 IDENT | SELF_KW | SUPER_KW => p.bump(), 45 IDENT | SELF_KW | SUPER_KW => p.bump(),
46 _ => p.error().message("expected identifier").emit(), 46 _ => {
47 p.error("expected identifier");
48 }
47 }; 49 };
48 segment.complete(p, PATH_SEGMENT); 50 segment.complete(p, PATH_SEGMENT);
49} 51}
diff --git a/src/parser/parser.rs b/src/parser/parser.rs
index 752d532d0..7c8e47cb6 100644
--- a/src/parser/parser.rs
+++ b/src/parser/parser.rs
@@ -129,8 +129,8 @@ impl<'t> Parser<'t> {
129 m 129 m
130 } 130 }
131 131
132 pub(crate) fn error<'p>(&'p mut self) -> ErrorBuilder<'p, 't> { 132 pub(crate) fn error<'p, T: Into<String>>(&'p mut self, msg: T) -> ErrorBuilder<'p, 't> {
133 ErrorBuilder::new(self) 133 ErrorBuilder::new(self, msg.into())
134 } 134 }
135 135
136 pub(crate) fn bump(&mut self) { 136 pub(crate) fn bump(&mut self) {
@@ -175,25 +175,19 @@ impl<'t> Parser<'t> {
175} 175}
176 176
177pub(crate) struct ErrorBuilder<'p, 't: 'p> { 177pub(crate) struct ErrorBuilder<'p, 't: 'p> {
178 message: Option<String>, 178 message: String,
179 parser: &'p mut Parser<'t>, 179 parser: &'p mut Parser<'t>,
180} 180}
181 181
182impl<'t, 'p> ErrorBuilder<'p, 't> { 182impl<'p, 't: 'p> Drop for ErrorBuilder<'p, 't> {
183 fn new(parser: &'p mut Parser<'t>) -> Self { 183 fn drop(&mut self) {
184 ErrorBuilder { 184 let message = ::std::mem::replace(&mut self.message, String::new());
185 message: None, 185 self.parser.event(Event::Error { message });
186 parser,
187 }
188 }
189
190 pub fn message<M: Into<String>>(mut self, m: M) -> Self {
191 self.message = Some(m.into());
192 self
193 } 186 }
187}
194 188
195 pub fn emit(self) { 189impl<'t, 'p> ErrorBuilder<'p, 't> {
196 let message = self.message.expect("Error message not set"); 190 fn new(parser: &'p mut Parser<'t>, message: String) -> Self {
197 self.parser.event(Event::Error { message }); 191 ErrorBuilder { message, parser }
198 } 192 }
199} 193}
diff --git a/src/tree/file_builder.rs b/src/tree/file_builder.rs
index 47038496d..3c7e2d7cf 100644
--- a/src/tree/file_builder.rs
+++ b/src/tree/file_builder.rs
@@ -14,7 +14,7 @@ pub(crate) trait Sink {
14 fn leaf(&mut self, kind: SyntaxKind, len: TextUnit); 14 fn leaf(&mut self, kind: SyntaxKind, len: TextUnit);
15 fn start_internal(&mut self, kind: SyntaxKind); 15 fn start_internal(&mut self, kind: SyntaxKind);
16 fn finish_internal(&mut self); 16 fn finish_internal(&mut self);
17 fn error(&mut self) -> ErrorBuilder; 17 fn error(&mut self, err: ErrorMsg);
18} 18}
19 19
20#[derive(Debug)] 20#[derive(Debug)]
@@ -22,7 +22,8 @@ pub(crate) struct FileBuilder {
22 text: String, 22 text: String,
23 nodes: Vec<NodeData>, 23 nodes: Vec<NodeData>,
24 errors: Vec<SyntaxErrorData>, 24 errors: Vec<SyntaxErrorData>,
25 in_progress: Vec<(NodeIdx, Option<NodeIdx>)>, // (parent, last_child) 25 in_progress: Vec<(NodeIdx, Option<NodeIdx>)>,
26 // (parent, last_child)
26 pos: TextUnit, 27 pos: TextUnit,
27} 28}
28 29
@@ -65,8 +66,13 @@ impl Sink for FileBuilder {
65 } 66 }
66 } 67 }
67 68
68 fn error(&mut self) -> ErrorBuilder { 69 fn error(&mut self, err: ErrorMsg) {
69 ErrorBuilder::new(self) 70 let &(node, after_child) = self.in_progress.last().unwrap();
71 self.errors.push(SyntaxErrorData {
72 node,
73 message: err.message,
74 after_child,
75 })
70 } 76 }
71} 77}
72 78
@@ -149,32 +155,7 @@ fn grow(left: &mut TextRange, right: TextRange) {
149 *left = TextRange::from_to(left.start(), right.end()) 155 *left = TextRange::from_to(left.start(), right.end())
150} 156}
151 157
152#[derive(Debug)] 158#[derive(Default)]
153pub struct ErrorBuilder<'f> { 159pub(crate) struct ErrorMsg {
154 message: Option<String>, 160 pub(crate) message: String,
155 builder: &'f mut FileBuilder,
156}
157
158impl<'f> ErrorBuilder<'f> {
159 fn new(builder: &'f mut FileBuilder) -> Self {
160 ErrorBuilder {
161 message: None,
162 builder,
163 }
164 }
165
166 pub fn message<M: Into<String>>(mut self, m: M) -> Self {
167 self.message = Some(m.into());
168 self
169 }
170
171 pub fn emit(self) {
172 let message = self.message.expect("Error message not set");
173 let &(node, after_child) = self.builder.in_progress.last().unwrap();
174 self.builder.errors.push(SyntaxErrorData {
175 node,
176 message,
177 after_child,
178 })
179 }
180} 161}
diff --git a/src/tree/mod.rs b/src/tree/mod.rs
index 9ed0504c7..ebf26777b 100644
--- a/src/tree/mod.rs
+++ b/src/tree/mod.rs
@@ -4,7 +4,7 @@ use std::fmt;
4use std::cmp; 4use std::cmp;
5 5
6mod file_builder; 6mod file_builder;
7pub(crate) use self::file_builder::{FileBuilder, Sink}; 7pub(crate) use self::file_builder::{ErrorMsg, FileBuilder, Sink};
8 8
9pub use syntax_kinds::SyntaxKind; 9pub use syntax_kinds::SyntaxKind;
10 10