diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 2 | ||||
-rw-r--r-- | src/parser/event.rs | 6 | ||||
-rw-r--r-- | src/parser/grammar/attributes.rs | 8 | ||||
-rw-r--r-- | src/parser/grammar/expressions.rs | 2 | ||||
-rw-r--r-- | src/parser/grammar/items/mod.rs | 8 | ||||
-rw-r--r-- | src/parser/grammar/items/structs.rs | 4 | ||||
-rw-r--r-- | src/parser/grammar/items/use_item.rs | 2 | ||||
-rw-r--r-- | src/parser/grammar/mod.rs | 6 | ||||
-rw-r--r-- | src/parser/grammar/paths.rs | 4 | ||||
-rw-r--r-- | src/parser/parser.rs | 28 | ||||
-rw-r--r-- | src/tree/file_builder.rs | 45 | ||||
-rw-r--r-- | src/tree/mod.rs | 2 |
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; | |||
25 | pub mod syntax_kinds; | 25 | pub mod syntax_kinds; |
26 | pub use text::{TextRange, TextUnit}; | 26 | pub use text::{TextRange, TextUnit}; |
27 | pub use tree::{File, Node, SyntaxKind, Token}; | 27 | pub use tree::{File, Node, SyntaxKind, Token}; |
28 | pub(crate) use tree::{FileBuilder, Sink}; | 28 | pub(crate) use tree::{ErrorMsg, FileBuilder, Sink}; |
29 | pub use lexer::{next_token, tokenize}; | 29 | pub use lexer::{next_token, tokenize}; |
30 | pub use parser::parse; | 30 | pub 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 @@ | |||
1 | use {File, FileBuilder, Sink, SyntaxKind, TextUnit, Token}; | 1 | use {ErrorMsg, File, FileBuilder, Sink, SyntaxKind, TextUnit, Token}; |
2 | use syntax_kinds::TOMBSTONE; | 2 | use syntax_kinds::TOMBSTONE; |
3 | use super::is_insignificant; | 3 | use 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 | ||
16 | pub(super) fn expr(p: &mut Parser) { | 16 | pub(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 { | |||
53 | fn error_block(p: &mut Parser, message: &str) { | 53 | fn 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 | ||
177 | pub(crate) struct ErrorBuilder<'p, 't: 'p> { | 177 | pub(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 | ||
182 | impl<'t, 'p> ErrorBuilder<'p, 't> { | 182 | impl<'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) { | 189 | impl<'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)] |
153 | pub struct ErrorBuilder<'f> { | 159 | pub(crate) struct ErrorMsg { |
154 | message: Option<String>, | 160 | pub(crate) message: String, |
155 | builder: &'f mut FileBuilder, | ||
156 | } | ||
157 | |||
158 | impl<'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; | |||
4 | use std::cmp; | 4 | use std::cmp; |
5 | 5 | ||
6 | mod file_builder; | 6 | mod file_builder; |
7 | pub(crate) use self::file_builder::{FileBuilder, Sink}; | 7 | pub(crate) use self::file_builder::{ErrorMsg, FileBuilder, Sink}; |
8 | 8 | ||
9 | pub use syntax_kinds::SyntaxKind; | 9 | pub use syntax_kinds::SyntaxKind; |
10 | 10 | ||