diff options
-rw-r--r-- | crates/ra_editor/src/lib.rs | 12 | ||||
-rw-r--r-- | crates/ra_syntax/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_syntax/src/parser_impl/event.rs | 4 | ||||
-rw-r--r-- | crates/ra_syntax/src/parser_impl/mod.rs | 6 | ||||
-rw-r--r-- | crates/ra_syntax/src/reparsing.rs | 14 | ||||
-rw-r--r-- | crates/ra_syntax/src/utils.rs | 8 | ||||
-rw-r--r-- | crates/ra_syntax/src/validation.rs | 25 | ||||
-rw-r--r-- | crates/ra_syntax/src/yellow/builder.rs | 7 | ||||
-rw-r--r-- | crates/ra_syntax/src/yellow/mod.rs | 2 | ||||
-rw-r--r-- | crates/ra_syntax/src/yellow/syntax_error.rs | 54 |
10 files changed, 82 insertions, 52 deletions
diff --git a/crates/ra_editor/src/lib.rs b/crates/ra_editor/src/lib.rs index 25124dbe3..f92181b86 100644 --- a/crates/ra_editor/src/lib.rs +++ b/crates/ra_editor/src/lib.rs | |||
@@ -31,6 +31,7 @@ use ra_syntax::{ | |||
31 | algo::find_leaf_at_offset, | 31 | algo::find_leaf_at_offset, |
32 | ast::{self, AstNode, NameOwner}, | 32 | ast::{self, AstNode, NameOwner}, |
33 | File, | 33 | File, |
34 | Location, | ||
34 | SyntaxKind::{self, *}, | 35 | SyntaxKind::{self, *}, |
35 | SyntaxNodeRef, TextRange, TextUnit, | 36 | SyntaxNodeRef, TextRange, TextUnit, |
36 | }; | 37 | }; |
@@ -100,11 +101,18 @@ pub fn highlight(file: &File) -> Vec<HighlightedRange> { | |||
100 | } | 101 | } |
101 | 102 | ||
102 | pub fn diagnostics(file: &File) -> Vec<Diagnostic> { | 103 | pub fn diagnostics(file: &File) -> Vec<Diagnostic> { |
104 | fn location_to_range(location: Location) -> TextRange { | ||
105 | match location { | ||
106 | Location::Offset(offset) => TextRange::offset_len(offset, 1.into()), | ||
107 | Location::Range(range) => range, | ||
108 | } | ||
109 | } | ||
110 | |||
103 | file.errors() | 111 | file.errors() |
104 | .into_iter() | 112 | .into_iter() |
105 | .map(|err| Diagnostic { | 113 | .map(|err| Diagnostic { |
106 | range: err.range, | 114 | range: location_to_range(err.location()), |
107 | msg: format!("Syntax Error: {}", err.kind), | 115 | msg: format!("Syntax Error: {}", err), |
108 | }) | 116 | }) |
109 | .collect() | 117 | .collect() |
110 | } | 118 | } |
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index 8996eb921..69a679d04 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs | |||
@@ -54,7 +54,7 @@ pub use crate::{ | |||
54 | rowan::{SmolStr, TextRange, TextUnit}, | 54 | rowan::{SmolStr, TextRange, TextUnit}, |
55 | syntax_kinds::SyntaxKind, | 55 | syntax_kinds::SyntaxKind, |
56 | yellow::{ | 56 | yellow::{ |
57 | Direction, OwnedRoot, RefRoot, SyntaxError, SyntaxNode, SyntaxNodeRef, TreeRoot, WalkEvent, | 57 | Direction, OwnedRoot, RefRoot, SyntaxError, SyntaxNode, SyntaxNodeRef, TreeRoot, WalkEvent, Location, |
58 | }, | 58 | }, |
59 | }; | 59 | }; |
60 | 60 | ||
diff --git a/crates/ra_syntax/src/parser_impl/event.rs b/crates/ra_syntax/src/parser_impl/event.rs index ced09bcff..1445401bc 100644 --- a/crates/ra_syntax/src/parser_impl/event.rs +++ b/crates/ra_syntax/src/parser_impl/event.rs | |||
@@ -15,6 +15,7 @@ use crate::{ | |||
15 | TextRange, TextUnit, | 15 | TextRange, TextUnit, |
16 | yellow::syntax_error::{ | 16 | yellow::syntax_error::{ |
17 | ParseError, | 17 | ParseError, |
18 | SyntaxError, | ||
18 | SyntaxErrorKind, | 19 | SyntaxErrorKind, |
19 | }, | 20 | }, |
20 | }; | 21 | }; |
@@ -162,8 +163,7 @@ impl<'a, S: Sink> EventProcessor<'a, S> { | |||
162 | self.leaf(kind, len, n_raw_tokens); | 163 | self.leaf(kind, len, n_raw_tokens); |
163 | } | 164 | } |
164 | Event::Error { msg } => self.sink.error( | 165 | Event::Error { msg } => self.sink.error( |
165 | SyntaxErrorKind::ParseError(msg), | 166 | SyntaxError::new(SyntaxErrorKind::ParseError(msg), self.text_pos), |
166 | TextRange::offset_len(self.text_pos, 1.into()), | ||
167 | ), | 167 | ), |
168 | } | 168 | } |
169 | } | 169 | } |
diff --git a/crates/ra_syntax/src/parser_impl/mod.rs b/crates/ra_syntax/src/parser_impl/mod.rs index ade25770b..cb6e370ac 100644 --- a/crates/ra_syntax/src/parser_impl/mod.rs +++ b/crates/ra_syntax/src/parser_impl/mod.rs | |||
@@ -10,10 +10,10 @@ use crate::{ | |||
10 | event::{Event, EventProcessor}, | 10 | event::{Event, EventProcessor}, |
11 | input::{InputPosition, ParserInput}, | 11 | input::{InputPosition, ParserInput}, |
12 | }, | 12 | }, |
13 | SmolStr, TextRange, | 13 | SmolStr, |
14 | yellow::syntax_error::{ | 14 | yellow::syntax_error::{ |
15 | ParseError, | 15 | ParseError, |
16 | SyntaxErrorKind, | 16 | SyntaxError, |
17 | }, | 17 | }, |
18 | }; | 18 | }; |
19 | 19 | ||
@@ -25,7 +25,7 @@ pub(crate) trait Sink { | |||
25 | fn leaf(&mut self, kind: SyntaxKind, text: SmolStr); | 25 | fn leaf(&mut self, kind: SyntaxKind, text: SmolStr); |
26 | fn start_internal(&mut self, kind: SyntaxKind); | 26 | fn start_internal(&mut self, kind: SyntaxKind); |
27 | fn finish_internal(&mut self); | 27 | fn finish_internal(&mut self); |
28 | fn error(&mut self, kind: SyntaxErrorKind, offset: TextRange); | 28 | fn error(&mut self, error: SyntaxError); |
29 | fn finish(self) -> Self::Tree; | 29 | fn finish(self) -> Self::Tree; |
30 | } | 30 | } |
31 | 31 | ||
diff --git a/crates/ra_syntax/src/reparsing.rs b/crates/ra_syntax/src/reparsing.rs index 9f5baf1ef..3c4ea5c22 100644 --- a/crates/ra_syntax/src/reparsing.rs +++ b/crates/ra_syntax/src/reparsing.rs | |||
@@ -165,20 +165,14 @@ fn merge_errors( | |||
165 | ) -> Vec<SyntaxError> { | 165 | ) -> Vec<SyntaxError> { |
166 | let mut res = Vec::new(); | 166 | let mut res = Vec::new(); |
167 | for e in old_errors { | 167 | for e in old_errors { |
168 | if e.range.start() <= old_node.range().start() { | 168 | if e.offset() <= old_node.range().start() { |
169 | res.push(e) | 169 | res.push(e) |
170 | } else if e.range.start() >= old_node.range().end() { | 170 | } else if e.offset() >= old_node.range().end() { |
171 | res.push(SyntaxError { | 171 | res.push(e.add_offset(TextUnit::of_str(&edit.insert) - edit.delete.len())); |
172 | kind: e.kind, | ||
173 | range: e.range + TextUnit::of_str(&edit.insert) - edit.delete.len(), | ||
174 | }) | ||
175 | } | 172 | } |
176 | } | 173 | } |
177 | for e in new_errors { | 174 | for e in new_errors { |
178 | res.push(SyntaxError { | 175 | res.push(e.add_offset(old_node.range().start())); |
179 | kind: e.kind, | ||
180 | range: e.range + old_node.range().start(), | ||
181 | }) | ||
182 | } | 176 | } |
183 | res | 177 | res |
184 | } | 178 | } |
diff --git a/crates/ra_syntax/src/utils.rs b/crates/ra_syntax/src/utils.rs index f55568d94..288d7edd4 100644 --- a/crates/ra_syntax/src/utils.rs +++ b/crates/ra_syntax/src/utils.rs | |||
@@ -4,7 +4,7 @@ use std::fmt::Write; | |||
4 | /// Parse a file and create a string representation of the resulting parse tree. | 4 | /// Parse a file and create a string representation of the resulting parse tree. |
5 | pub fn dump_tree(syntax: SyntaxNodeRef) -> String { | 5 | pub fn dump_tree(syntax: SyntaxNodeRef) -> String { |
6 | let mut errors: Vec<_> = syntax.root_data().to_vec(); | 6 | let mut errors: Vec<_> = syntax.root_data().to_vec(); |
7 | errors.sort_by_key(|e| e.range.start()); | 7 | errors.sort_by_key(|e| e.offset()); |
8 | let mut err_pos = 0; | 8 | let mut err_pos = 0; |
9 | let mut level = 0; | 9 | let mut level = 0; |
10 | let mut buf = String::new(); | 10 | let mut buf = String::new(); |
@@ -23,9 +23,9 @@ pub fn dump_tree(syntax: SyntaxNodeRef) -> String { | |||
23 | writeln!(buf, "{:?}", node).unwrap(); | 23 | writeln!(buf, "{:?}", node).unwrap(); |
24 | if node.first_child().is_none() { | 24 | if node.first_child().is_none() { |
25 | let off = node.range().end(); | 25 | let off = node.range().end(); |
26 | while err_pos < errors.len() && errors[err_pos].range.start() <= off { | 26 | while err_pos < errors.len() && errors[err_pos].offset() <= off { |
27 | indent!(); | 27 | indent!(); |
28 | writeln!(buf, "err: `{}`", errors[err_pos].kind).unwrap(); | 28 | writeln!(buf, "err: `{}`", errors[err_pos]).unwrap(); |
29 | err_pos += 1; | 29 | err_pos += 1; |
30 | } | 30 | } |
31 | } | 31 | } |
@@ -37,7 +37,7 @@ pub fn dump_tree(syntax: SyntaxNodeRef) -> String { | |||
37 | 37 | ||
38 | assert_eq!(level, 0); | 38 | assert_eq!(level, 0); |
39 | for err in errors[err_pos..].iter() { | 39 | for err in errors[err_pos..].iter() { |
40 | writeln!(buf, "err: `{}`", err.kind).unwrap(); | 40 | writeln!(buf, "err: `{}`", err).unwrap(); |
41 | } | 41 | } |
42 | 42 | ||
43 | buf | 43 | buf |
diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs index 06e6e7505..009f5052f 100644 --- a/crates/ra_syntax/src/validation.rs +++ b/crates/ra_syntax/src/validation.rs | |||
@@ -33,17 +33,11 @@ fn validate_char(node: ast::Char, errors: &mut Vec<SyntaxError>) { | |||
33 | AsciiEscape => { | 33 | AsciiEscape => { |
34 | if text.len() == 1 { | 34 | if text.len() == 1 { |
35 | // Escape sequence consists only of leading `\` | 35 | // Escape sequence consists only of leading `\` |
36 | errors.push(SyntaxError { | 36 | errors.push(SyntaxError::new(EmptyAsciiEscape, range)); |
37 | kind: EmptyAsciiEscape, | ||
38 | range: range, | ||
39 | }); | ||
40 | } else { | 37 | } else { |
41 | let escape_code = text.chars().skip(1).next().unwrap(); | 38 | let escape_code = text.chars().skip(1).next().unwrap(); |
42 | if !is_ascii_escape(escape_code) { | 39 | if !is_ascii_escape(escape_code) { |
43 | errors.push(SyntaxError { | 40 | errors.push(SyntaxError::new(InvalidAsciiEscape, range)); |
44 | kind: InvalidAsciiEscape, | ||
45 | range: range, | ||
46 | }); | ||
47 | } | 41 | } |
48 | } | 42 | } |
49 | } | 43 | } |
@@ -64,24 +58,15 @@ fn validate_char(node: ast::Char, errors: &mut Vec<SyntaxError>) { | |||
64 | } | 58 | } |
65 | 59 | ||
66 | if !components.has_closing_quote { | 60 | if !components.has_closing_quote { |
67 | errors.push(SyntaxError { | 61 | errors.push(SyntaxError::new(UnclosedChar, node.syntax().range())); |
68 | kind: UnclosedChar, | ||
69 | range: node.syntax().range(), | ||
70 | }); | ||
71 | } | 62 | } |
72 | 63 | ||
73 | if len == 0 { | 64 | if len == 0 { |
74 | errors.push(SyntaxError { | 65 | errors.push(SyntaxError::new(EmptyChar, node.syntax().range())); |
75 | kind: EmptyChar, | ||
76 | range: node.syntax().range(), | ||
77 | }); | ||
78 | } | 66 | } |
79 | 67 | ||
80 | if len > 1 { | 68 | if len > 1 { |
81 | errors.push(SyntaxError { | 69 | errors.push(SyntaxError::new(LongChar, node.syntax().range())); |
82 | kind: LongChar, | ||
83 | range: node.syntax().range(), | ||
84 | }); | ||
85 | } | 70 | } |
86 | } | 71 | } |
87 | 72 | ||
diff --git a/crates/ra_syntax/src/yellow/builder.rs b/crates/ra_syntax/src/yellow/builder.rs index dbe2df125..9fcebfb93 100644 --- a/crates/ra_syntax/src/yellow/builder.rs +++ b/crates/ra_syntax/src/yellow/builder.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use crate::{ | 1 | use crate::{ |
2 | parser_impl::Sink, | 2 | parser_impl::Sink, |
3 | yellow::{GreenNode, RaTypes, SyntaxError, SyntaxErrorKind}, | 3 | yellow::{GreenNode, RaTypes, SyntaxError}, |
4 | SmolStr, SyntaxKind, TextRange, | 4 | SmolStr, SyntaxKind, |
5 | }; | 5 | }; |
6 | use rowan::GreenNodeBuilder; | 6 | use rowan::GreenNodeBuilder; |
7 | 7 | ||
@@ -34,8 +34,7 @@ impl Sink for GreenBuilder { | |||
34 | self.inner.finish_internal(); | 34 | self.inner.finish_internal(); |
35 | } | 35 | } |
36 | 36 | ||
37 | fn error(&mut self, kind: SyntaxErrorKind, range: TextRange) { | 37 | fn error(&mut self, error: SyntaxError) { |
38 | let error = SyntaxError { kind, range }; | ||
39 | self.errors.push(error) | 38 | self.errors.push(error) |
40 | } | 39 | } |
41 | 40 | ||
diff --git a/crates/ra_syntax/src/yellow/mod.rs b/crates/ra_syntax/src/yellow/mod.rs index fd2b5bd33..6da948648 100644 --- a/crates/ra_syntax/src/yellow/mod.rs +++ b/crates/ra_syntax/src/yellow/mod.rs | |||
@@ -11,7 +11,7 @@ use std::{ | |||
11 | }; | 11 | }; |
12 | 12 | ||
13 | pub(crate) use self::builder::GreenBuilder; | 13 | pub(crate) use self::builder::GreenBuilder; |
14 | pub use self::syntax_error::{SyntaxError, SyntaxErrorKind}; | 14 | pub use self::syntax_error::{SyntaxError, SyntaxErrorKind, Location}; |
15 | pub use rowan::{TreeRoot, WalkEvent}; | 15 | pub use rowan::{TreeRoot, WalkEvent}; |
16 | 16 | ||
17 | #[derive(Debug, Clone, Copy)] | 17 | #[derive(Debug, Clone, Copy)] |
diff --git a/crates/ra_syntax/src/yellow/syntax_error.rs b/crates/ra_syntax/src/yellow/syntax_error.rs index e8c818dc6..098366f85 100644 --- a/crates/ra_syntax/src/yellow/syntax_error.rs +++ b/crates/ra_syntax/src/yellow/syntax_error.rs | |||
@@ -1,16 +1,60 @@ | |||
1 | use std::fmt; | 1 | use std::fmt; |
2 | 2 | ||
3 | use crate::TextRange; | 3 | use crate::{TextRange, TextUnit}; |
4 | 4 | ||
5 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 5 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
6 | pub struct SyntaxError { | 6 | pub struct SyntaxError { |
7 | pub kind: SyntaxErrorKind, | 7 | kind: SyntaxErrorKind, |
8 | pub range: TextRange, | 8 | location: Location, |
9 | } | ||
10 | |||
11 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
12 | pub enum Location { | ||
13 | Offset(TextUnit), | ||
14 | Range(TextRange), | ||
15 | } | ||
16 | |||
17 | impl Into<Location> for TextUnit { | ||
18 | fn into(self) -> Location { | ||
19 | Location::Offset(self) | ||
20 | } | ||
21 | } | ||
22 | |||
23 | impl Into<Location> for TextRange { | ||
24 | fn into(self) -> Location { | ||
25 | Location::Range(self) | ||
26 | } | ||
9 | } | 27 | } |
10 | 28 | ||
11 | impl SyntaxError { | 29 | impl SyntaxError { |
12 | pub fn new(kind: SyntaxErrorKind, range: TextRange) -> SyntaxError { | 30 | pub fn new<L: Into<Location>>(kind: SyntaxErrorKind, loc: L) -> SyntaxError { |
13 | SyntaxError { kind, range } | 31 | SyntaxError { kind, location: loc.into() } |
32 | } | ||
33 | |||
34 | pub fn location(&self) -> Location { | ||
35 | self.location.clone() | ||
36 | } | ||
37 | |||
38 | pub fn offset(&self) -> TextUnit { | ||
39 | match self.location { | ||
40 | Location::Offset(offset) => offset, | ||
41 | Location::Range(range) => range.start(), | ||
42 | } | ||
43 | } | ||
44 | |||
45 | pub fn add_offset(mut self, plus_offset: TextUnit) -> SyntaxError { | ||
46 | self.location = match self.location { | ||
47 | Location::Range(range) => Location::Range(range + plus_offset), | ||
48 | Location::Offset(offset) => Location::Offset(offset + plus_offset) | ||
49 | }; | ||
50 | |||
51 | self | ||
52 | } | ||
53 | } | ||
54 | |||
55 | impl fmt::Display for SyntaxError { | ||
56 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
57 | self.kind.fmt(f) | ||
14 | } | 58 | } |
15 | } | 59 | } |
16 | 60 | ||