aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_editor/src/lib.rs12
-rw-r--r--crates/ra_syntax/src/lib.rs2
-rw-r--r--crates/ra_syntax/src/parser_impl/event.rs4
-rw-r--r--crates/ra_syntax/src/parser_impl/mod.rs6
-rw-r--r--crates/ra_syntax/src/reparsing.rs14
-rw-r--r--crates/ra_syntax/src/utils.rs8
-rw-r--r--crates/ra_syntax/src/validation.rs25
-rw-r--r--crates/ra_syntax/src/yellow/builder.rs7
-rw-r--r--crates/ra_syntax/src/yellow/mod.rs2
-rw-r--r--crates/ra_syntax/src/yellow/syntax_error.rs54
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
102pub fn diagnostics(file: &File) -> Vec<Diagnostic> { 103pub 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.
5pub fn dump_tree(syntax: SyntaxNodeRef) -> String { 5pub 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 @@
1use crate::{ 1use 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};
6use rowan::GreenNodeBuilder; 6use 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
13pub(crate) use self::builder::GreenBuilder; 13pub(crate) use self::builder::GreenBuilder;
14pub use self::syntax_error::{SyntaxError, SyntaxErrorKind}; 14pub use self::syntax_error::{SyntaxError, SyntaxErrorKind, Location};
15pub use rowan::{TreeRoot, WalkEvent}; 15pub 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 @@
1use std::fmt; 1use std::fmt;
2 2
3use crate::TextRange; 3use crate::{TextRange, TextUnit};
4 4
5#[derive(Debug, Clone, PartialEq, Eq, Hash)] 5#[derive(Debug, Clone, PartialEq, Eq, Hash)]
6pub struct SyntaxError { 6pub 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)]
12pub enum Location {
13 Offset(TextUnit),
14 Range(TextRange),
15}
16
17impl Into<Location> for TextUnit {
18 fn into(self) -> Location {
19 Location::Offset(self)
20 }
21}
22
23impl Into<Location> for TextRange {
24 fn into(self) -> Location {
25 Location::Range(self)
26 }
9} 27}
10 28
11impl SyntaxError { 29impl 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
55impl 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