From fda8ddc5fe8a764c0dc91fecb92af1bdf3078485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Mon, 5 Nov 2018 18:38:34 +0100 Subject: Introduce Location and make SyntaxError fields private --- crates/ra_syntax/src/lib.rs | 2 +- crates/ra_syntax/src/parser_impl/event.rs | 4 +-- crates/ra_syntax/src/parser_impl/mod.rs | 6 ++-- crates/ra_syntax/src/reparsing.rs | 14 +++----- crates/ra_syntax/src/utils.rs | 8 ++--- crates/ra_syntax/src/validation.rs | 25 +++---------- crates/ra_syntax/src/yellow/builder.rs | 7 ++-- crates/ra_syntax/src/yellow/mod.rs | 2 +- crates/ra_syntax/src/yellow/syntax_error.rs | 54 ++++++++++++++++++++++++++--- 9 files changed, 72 insertions(+), 50 deletions(-) (limited to 'crates/ra_syntax') 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::{ rowan::{SmolStr, TextRange, TextUnit}, syntax_kinds::SyntaxKind, yellow::{ - Direction, OwnedRoot, RefRoot, SyntaxError, SyntaxNode, SyntaxNodeRef, TreeRoot, WalkEvent, + Direction, OwnedRoot, RefRoot, SyntaxError, SyntaxNode, SyntaxNodeRef, TreeRoot, WalkEvent, Location, }, }; 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::{ TextRange, TextUnit, yellow::syntax_error::{ ParseError, + SyntaxError, SyntaxErrorKind, }, }; @@ -162,8 +163,7 @@ impl<'a, S: Sink> EventProcessor<'a, S> { self.leaf(kind, len, n_raw_tokens); } Event::Error { msg } => self.sink.error( - SyntaxErrorKind::ParseError(msg), - TextRange::offset_len(self.text_pos, 1.into()), + SyntaxError::new(SyntaxErrorKind::ParseError(msg), self.text_pos), ), } } 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::{ event::{Event, EventProcessor}, input::{InputPosition, ParserInput}, }, - SmolStr, TextRange, + SmolStr, yellow::syntax_error::{ ParseError, - SyntaxErrorKind, + SyntaxError, }, }; @@ -25,7 +25,7 @@ pub(crate) trait Sink { fn leaf(&mut self, kind: SyntaxKind, text: SmolStr); fn start_internal(&mut self, kind: SyntaxKind); fn finish_internal(&mut self); - fn error(&mut self, kind: SyntaxErrorKind, offset: TextRange); + fn error(&mut self, error: SyntaxError); fn finish(self) -> Self::Tree; } 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( ) -> Vec { let mut res = Vec::new(); for e in old_errors { - if e.range.start() <= old_node.range().start() { + if e.offset() <= old_node.range().start() { res.push(e) - } else if e.range.start() >= old_node.range().end() { - res.push(SyntaxError { - kind: e.kind, - range: e.range + TextUnit::of_str(&edit.insert) - edit.delete.len(), - }) + } else if e.offset() >= old_node.range().end() { + res.push(e.add_offset(TextUnit::of_str(&edit.insert) - edit.delete.len())); } } for e in new_errors { - res.push(SyntaxError { - kind: e.kind, - range: e.range + old_node.range().start(), - }) + res.push(e.add_offset(old_node.range().start())); } res } 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; /// Parse a file and create a string representation of the resulting parse tree. pub fn dump_tree(syntax: SyntaxNodeRef) -> String { let mut errors: Vec<_> = syntax.root_data().to_vec(); - errors.sort_by_key(|e| e.range.start()); + errors.sort_by_key(|e| e.offset()); let mut err_pos = 0; let mut level = 0; let mut buf = String::new(); @@ -23,9 +23,9 @@ pub fn dump_tree(syntax: SyntaxNodeRef) -> String { writeln!(buf, "{:?}", node).unwrap(); if node.first_child().is_none() { let off = node.range().end(); - while err_pos < errors.len() && errors[err_pos].range.start() <= off { + while err_pos < errors.len() && errors[err_pos].offset() <= off { indent!(); - writeln!(buf, "err: `{}`", errors[err_pos].kind).unwrap(); + writeln!(buf, "err: `{}`", errors[err_pos]).unwrap(); err_pos += 1; } } @@ -37,7 +37,7 @@ pub fn dump_tree(syntax: SyntaxNodeRef) -> String { assert_eq!(level, 0); for err in errors[err_pos..].iter() { - writeln!(buf, "err: `{}`", err.kind).unwrap(); + writeln!(buf, "err: `{}`", err).unwrap(); } 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) { AsciiEscape => { if text.len() == 1 { // Escape sequence consists only of leading `\` - errors.push(SyntaxError { - kind: EmptyAsciiEscape, - range: range, - }); + errors.push(SyntaxError::new(EmptyAsciiEscape, range)); } else { let escape_code = text.chars().skip(1).next().unwrap(); if !is_ascii_escape(escape_code) { - errors.push(SyntaxError { - kind: InvalidAsciiEscape, - range: range, - }); + errors.push(SyntaxError::new(InvalidAsciiEscape, range)); } } } @@ -64,24 +58,15 @@ fn validate_char(node: ast::Char, errors: &mut Vec) { } if !components.has_closing_quote { - errors.push(SyntaxError { - kind: UnclosedChar, - range: node.syntax().range(), - }); + errors.push(SyntaxError::new(UnclosedChar, node.syntax().range())); } if len == 0 { - errors.push(SyntaxError { - kind: EmptyChar, - range: node.syntax().range(), - }); + errors.push(SyntaxError::new(EmptyChar, node.syntax().range())); } if len > 1 { - errors.push(SyntaxError { - kind: LongChar, - range: node.syntax().range(), - }); + errors.push(SyntaxError::new(LongChar, node.syntax().range())); } } 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 @@ use crate::{ parser_impl::Sink, - yellow::{GreenNode, RaTypes, SyntaxError, SyntaxErrorKind}, - SmolStr, SyntaxKind, TextRange, + yellow::{GreenNode, RaTypes, SyntaxError}, + SmolStr, SyntaxKind, }; use rowan::GreenNodeBuilder; @@ -34,8 +34,7 @@ impl Sink for GreenBuilder { self.inner.finish_internal(); } - fn error(&mut self, kind: SyntaxErrorKind, range: TextRange) { - let error = SyntaxError { kind, range }; + fn error(&mut self, error: SyntaxError) { self.errors.push(error) } 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::{ }; pub(crate) use self::builder::GreenBuilder; -pub use self::syntax_error::{SyntaxError, SyntaxErrorKind}; +pub use self::syntax_error::{SyntaxError, SyntaxErrorKind, Location}; pub use rowan::{TreeRoot, WalkEvent}; #[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 @@ use std::fmt; -use crate::TextRange; +use crate::{TextRange, TextUnit}; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct SyntaxError { - pub kind: SyntaxErrorKind, - pub range: TextRange, + kind: SyntaxErrorKind, + location: Location, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum Location { + Offset(TextUnit), + Range(TextRange), +} + +impl Into for TextUnit { + fn into(self) -> Location { + Location::Offset(self) + } +} + +impl Into for TextRange { + fn into(self) -> Location { + Location::Range(self) + } } impl SyntaxError { - pub fn new(kind: SyntaxErrorKind, range: TextRange) -> SyntaxError { - SyntaxError { kind, range } + pub fn new>(kind: SyntaxErrorKind, loc: L) -> SyntaxError { + SyntaxError { kind, location: loc.into() } + } + + pub fn location(&self) -> Location { + self.location.clone() + } + + pub fn offset(&self) -> TextUnit { + match self.location { + Location::Offset(offset) => offset, + Location::Range(range) => range.start(), + } + } + + pub fn add_offset(mut self, plus_offset: TextUnit) -> SyntaxError { + self.location = match self.location { + Location::Range(range) => Location::Range(range + plus_offset), + Location::Offset(offset) => Location::Offset(offset + plus_offset) + }; + + self + } +} + +impl fmt::Display for SyntaxError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.kind.fmt(f) } } -- cgit v1.2.3