mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 12:33:33 +00:00
Error placement
This commit is contained in:
parent
efcfaae34a
commit
18f9e50b2d
4 changed files with 37 additions and 9 deletions
|
@ -156,7 +156,7 @@ impl<'f> ErrorBuilder<'f> {
|
|||
|
||||
pub fn emit(self) {
|
||||
let message = self.message.expect("Error message not set");
|
||||
let node = self.builder.current_id();
|
||||
self.builder.errors.push(SyntaxErrorData { node, message })
|
||||
let &(node, after_child) = self.builder.in_progress.last().unwrap();
|
||||
self.builder.errors.push(SyntaxErrorData { node, message, after_child })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ use text::{TextUnit, TextRange};
|
|||
use syntax_kinds::syntax_info;
|
||||
|
||||
use std::fmt;
|
||||
use std::cmp;
|
||||
|
||||
mod file_builder;
|
||||
pub use self::file_builder::{FileBuilder, Sink};
|
||||
|
@ -96,6 +97,15 @@ impl<'f> fmt::Debug for Node<'f> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'f> cmp::PartialEq<Node<'f>> for Node<'f> {
|
||||
fn eq(&self, other: &Node<'f>) -> bool {
|
||||
self.idx == other.idx && ::std::ptr::eq(self.file, other.file)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'f> cmp::Eq for Node<'f> {
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct SyntaxError<'f> {
|
||||
file: &'f File,
|
||||
|
@ -107,6 +117,11 @@ impl<'f> SyntaxError<'f> {
|
|||
self.data().message.as_str()
|
||||
}
|
||||
|
||||
pub fn after_child(&self) -> Option<Node<'f>> {
|
||||
let idx = self.data().after_child?;
|
||||
Some(Node { file: self.file, idx })
|
||||
}
|
||||
|
||||
fn data(&self) -> &'f SyntaxErrorData {
|
||||
&self.file.errors[self.idx]
|
||||
}
|
||||
|
@ -187,6 +202,7 @@ struct ErrorIdx(u32);
|
|||
struct SyntaxErrorData {
|
||||
node: NodeIdx,
|
||||
message: String,
|
||||
after_child: Option<NodeIdx>,
|
||||
}
|
||||
|
||||
impl ::std::ops::Index<ErrorIdx> for Vec<SyntaxErrorData> {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
FILE@[0; 34)
|
||||
STRUCT_ITEM@[0; 34) err: `expected COMMA`
|
||||
STRUCT_ITEM@[0; 34)
|
||||
STRUCT_KW@[0; 6)
|
||||
WHITESPACE@[6; 7)
|
||||
IDENT@[7; 8)
|
||||
|
@ -12,9 +12,11 @@ FILE@[0; 34)
|
|||
WHITESPACE@[17; 18)
|
||||
IDENT@[18; 21)
|
||||
WHITESPACE@[21; 26)
|
||||
err: `expected COMMA`
|
||||
STRUCT_FIELD@[26; 33)
|
||||
IDENT@[26; 27)
|
||||
COLON@[27; 28)
|
||||
WHITESPACE@[28; 29)
|
||||
IDENT@[29; 32)
|
||||
WHITESPACE@[32;
|
||||
WHITESPACE@[32; 33)
|
||||
R_CURLY@[33; 34)
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::path::{PathBuf, Path};
|
|||
use std::fs::read_dir;
|
||||
use std::fmt::Write;
|
||||
|
||||
use libsyntax2::{tokenize, parse, Token, Node, File, FileBuilder};
|
||||
use libsyntax2::{tokenize, parse, Node, File};
|
||||
|
||||
#[test]
|
||||
fn parser_tests() {
|
||||
|
@ -70,14 +70,24 @@ fn dump_tree(file: &File) -> String {
|
|||
|
||||
fn go(node: Node, buff: &mut String, level: usize) {
|
||||
buff.push_str(&String::from(" ").repeat(level));
|
||||
write!(buff, "{:?}", node).unwrap();
|
||||
for err in node.errors() {
|
||||
write!(buff, " err: `{}`", err.message()).unwrap();
|
||||
write!(buff, "{:?}\n", node).unwrap();
|
||||
let my_errors = node.errors().filter(|e| e.after_child().is_none());
|
||||
let parent_errors = node.parent().into_iter()
|
||||
.flat_map(|n| n.errors())
|
||||
.filter(|e| e.after_child() == Some(node));
|
||||
|
||||
for err in my_errors {
|
||||
buff.push_str(&String::from(" ").repeat(level));
|
||||
write!(buff, "err: `{}`\n", err.message()).unwrap();
|
||||
}
|
||||
write!(buff, "\n").unwrap();
|
||||
|
||||
for child in node.children() {
|
||||
go(child, buff, level + 1)
|
||||
}
|
||||
|
||||
for err in parent_errors {
|
||||
buff.push_str(&String::from(" ").repeat(level));
|
||||
write!(buff, "err: `{}`\n", err.message()).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue