mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 04:53:34 +00:00
commit
419b9b7e5e
12 changed files with 49 additions and 70 deletions
|
@ -25,7 +25,7 @@ mod parser;
|
|||
pub mod syntax_kinds;
|
||||
pub use text::{TextRange, TextUnit};
|
||||
pub use tree::{File, Node, SyntaxKind, Token};
|
||||
pub(crate) use tree::{FileBuilder, Sink};
|
||||
pub(crate) use tree::{ErrorMsg, FileBuilder, Sink};
|
||||
pub use lexer::{next_token, tokenize};
|
||||
pub use parser::parse;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use {File, FileBuilder, Sink, SyntaxKind, TextUnit, Token};
|
||||
use {ErrorMsg, File, FileBuilder, Sink, SyntaxKind, TextUnit, Token};
|
||||
use syntax_kinds::TOMBSTONE;
|
||||
use super::is_insignificant;
|
||||
|
||||
|
@ -140,7 +140,9 @@ pub(super) fn to_file(text: String, tokens: &[Token], events: Vec<Event>) -> Fil
|
|||
}
|
||||
builder.leaf(kind, len);
|
||||
}
|
||||
&Event::Error { ref message } => builder.error().message(message.clone()).emit(),
|
||||
&Event::Error { ref message } => builder.error(ErrorMsg {
|
||||
message: message.clone(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
builder.finish()
|
||||
|
|
|
@ -37,7 +37,7 @@ fn meta_item(p: &mut Parser) {
|
|||
EQ => {
|
||||
p.bump();
|
||||
if !expressions::literal(p) {
|
||||
p.error().message("expected literal").emit();
|
||||
p.error("expected literal");
|
||||
}
|
||||
}
|
||||
L_PAREN => meta_item_arg_list(p),
|
||||
|
@ -45,7 +45,7 @@ fn meta_item(p: &mut Parser) {
|
|||
}
|
||||
meta_item.complete(p, META_ITEM);
|
||||
} else {
|
||||
p.error().message("expected attribute value").emit()
|
||||
p.error("expected attribute value");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,12 +60,12 @@ fn meta_item_arg_list(p: &mut Parser) {
|
|||
let message = "expected attribute";
|
||||
|
||||
if items::ITEM_FIRST.contains(c) {
|
||||
p.error().message(message).emit();
|
||||
p.error(message);
|
||||
return;
|
||||
}
|
||||
|
||||
let err = p.start();
|
||||
p.error().message(message).emit();
|
||||
p.error(message);
|
||||
p.bump();
|
||||
err.complete(p, ERROR);
|
||||
continue;
|
||||
|
|
|
@ -15,6 +15,6 @@ pub(super) fn literal(p: &mut Parser) -> bool {
|
|||
|
||||
pub(super) fn expr(p: &mut Parser) {
|
||||
if !literal(p) {
|
||||
p.error().message("expected expression").emit();
|
||||
p.error("expected expression");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ fn item(p: &mut Parser) {
|
|||
// extern struct Foo;
|
||||
_ => {
|
||||
item.abandon(p);
|
||||
p.error().message("expected `fn` or `{`").emit();
|
||||
p.error("expected `fn` or `{`");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ fn item(p: &mut Parser) {
|
|||
abi(p);
|
||||
if !p.at(FN_KW) {
|
||||
item.abandon(p);
|
||||
p.error().message("expected function").emit();
|
||||
p.error("expected function");
|
||||
return;
|
||||
}
|
||||
fn_item(p);
|
||||
|
@ -144,7 +144,7 @@ fn item(p: &mut Parser) {
|
|||
if t == L_CURLY {
|
||||
error_block(p, message);
|
||||
} else {
|
||||
p.error().message(message).emit();
|
||||
p.error(message);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ fn fn_item(p: &mut Parser) {
|
|||
if p.at(L_PAREN) {
|
||||
fn_value_parameters(p);
|
||||
} else {
|
||||
p.error().message("expected function arguments").emit();
|
||||
p.error("expected function arguments");
|
||||
}
|
||||
|
||||
if p.at(L_CURLY) {
|
||||
|
|
|
@ -19,7 +19,7 @@ pub(super) fn struct_item(p: &mut Parser) {
|
|||
L_CURLY => named_fields(p),
|
||||
_ => {
|
||||
//TODO: special case `(` error message
|
||||
p.error().message("expected `;` or `{`").emit();
|
||||
p.error("expected `;` or `{`");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ pub(super) fn struct_item(p: &mut Parser) {
|
|||
p.expect(SEMI);
|
||||
}
|
||||
_ => {
|
||||
p.error().message("expected `;`, `{`, or `(`").emit();
|
||||
p.error("expected `;`, `{`, or `(`");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ fn use_tree(p: &mut Parser) {
|
|||
L_CURLY => nested_trees(p),
|
||||
_ => {
|
||||
// is this unreachable?
|
||||
p.error().message("expected `{` or `*`").emit();
|
||||
p.error("expected `{` or `*`");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ fn alias(p: &mut Parser) -> bool {
|
|||
fn error_block(p: &mut Parser, message: &str) {
|
||||
assert!(p.at(L_CURLY));
|
||||
let err = p.start();
|
||||
p.error().message(message).emit();
|
||||
p.error(message);
|
||||
p.bump();
|
||||
let mut level: u32 = 1;
|
||||
while level > 0 && !p.at(EOF) {
|
||||
|
@ -74,7 +74,7 @@ impl<'p> Parser<'p> {
|
|||
|
||||
fn err_and_bump(&mut self, message: &str) {
|
||||
let err = self.start();
|
||||
self.error().message(message).emit();
|
||||
self.error(message);
|
||||
self.bump();
|
||||
err.complete(self, ERROR);
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ impl<'p> Parser<'p> {
|
|||
self.bump();
|
||||
true
|
||||
} else {
|
||||
self.error().message(format!("expected {:?}", kind)).emit();
|
||||
self.error(format!("expected {:?}", kind));
|
||||
false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,9 @@ fn path_segment(p: &mut Parser, first: bool) {
|
|||
}
|
||||
match p.current() {
|
||||
IDENT | SELF_KW | SUPER_KW => p.bump(),
|
||||
_ => p.error().message("expected identifier").emit(),
|
||||
_ => {
|
||||
p.error("expected identifier");
|
||||
}
|
||||
};
|
||||
segment.complete(p, PATH_SEGMENT);
|
||||
}
|
||||
|
|
|
@ -129,8 +129,8 @@ impl<'t> Parser<'t> {
|
|||
m
|
||||
}
|
||||
|
||||
pub(crate) fn error<'p>(&'p mut self) -> ErrorBuilder<'p, 't> {
|
||||
ErrorBuilder::new(self)
|
||||
pub(crate) fn error<'p, T: Into<String>>(&'p mut self, msg: T) -> ErrorBuilder<'p, 't> {
|
||||
ErrorBuilder::new(self, msg.into())
|
||||
}
|
||||
|
||||
pub(crate) fn bump(&mut self) {
|
||||
|
@ -175,25 +175,19 @@ impl<'t> Parser<'t> {
|
|||
}
|
||||
|
||||
pub(crate) struct ErrorBuilder<'p, 't: 'p> {
|
||||
message: Option<String>,
|
||||
message: String,
|
||||
parser: &'p mut Parser<'t>,
|
||||
}
|
||||
|
||||
impl<'t, 'p> ErrorBuilder<'p, 't> {
|
||||
fn new(parser: &'p mut Parser<'t>) -> Self {
|
||||
ErrorBuilder {
|
||||
message: None,
|
||||
parser,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn message<M: Into<String>>(mut self, m: M) -> Self {
|
||||
self.message = Some(m.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn emit(self) {
|
||||
let message = self.message.expect("Error message not set");
|
||||
impl<'p, 't: 'p> Drop for ErrorBuilder<'p, 't> {
|
||||
fn drop(&mut self) {
|
||||
let message = ::std::mem::replace(&mut self.message, String::new());
|
||||
self.parser.event(Event::Error { message });
|
||||
}
|
||||
}
|
||||
|
||||
impl<'t, 'p> ErrorBuilder<'p, 't> {
|
||||
fn new(parser: &'p mut Parser<'t>, message: String) -> Self {
|
||||
ErrorBuilder { message, parser }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ pub(crate) trait Sink {
|
|||
fn leaf(&mut self, kind: SyntaxKind, len: TextUnit);
|
||||
fn start_internal(&mut self, kind: SyntaxKind);
|
||||
fn finish_internal(&mut self);
|
||||
fn error(&mut self) -> ErrorBuilder;
|
||||
fn error(&mut self, err: ErrorMsg);
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -22,7 +22,8 @@ pub(crate) struct FileBuilder {
|
|||
text: String,
|
||||
nodes: Vec<NodeData>,
|
||||
errors: Vec<SyntaxErrorData>,
|
||||
in_progress: Vec<(NodeIdx, Option<NodeIdx>)>, // (parent, last_child)
|
||||
in_progress: Vec<(NodeIdx, Option<NodeIdx>)>,
|
||||
// (parent, last_child)
|
||||
pos: TextUnit,
|
||||
}
|
||||
|
||||
|
@ -65,8 +66,13 @@ impl Sink for FileBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
fn error(&mut self) -> ErrorBuilder {
|
||||
ErrorBuilder::new(self)
|
||||
fn error(&mut self, err: ErrorMsg) {
|
||||
let &(node, after_child) = self.in_progress.last().unwrap();
|
||||
self.errors.push(SyntaxErrorData {
|
||||
node,
|
||||
message: err.message,
|
||||
after_child,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,32 +155,7 @@ fn grow(left: &mut TextRange, right: TextRange) {
|
|||
*left = TextRange::from_to(left.start(), right.end())
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ErrorBuilder<'f> {
|
||||
message: Option<String>,
|
||||
builder: &'f mut FileBuilder,
|
||||
}
|
||||
|
||||
impl<'f> ErrorBuilder<'f> {
|
||||
fn new(builder: &'f mut FileBuilder) -> Self {
|
||||
ErrorBuilder {
|
||||
message: None,
|
||||
builder,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn message<M: Into<String>>(mut self, m: M) -> Self {
|
||||
self.message = Some(m.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn emit(self) {
|
||||
let message = self.message.expect("Error message not set");
|
||||
let &(node, after_child) = self.builder.in_progress.last().unwrap();
|
||||
self.builder.errors.push(SyntaxErrorData {
|
||||
node,
|
||||
message,
|
||||
after_child,
|
||||
})
|
||||
}
|
||||
#[derive(Default)]
|
||||
pub(crate) struct ErrorMsg {
|
||||
pub(crate) message: String,
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::fmt;
|
|||
use std::cmp;
|
||||
|
||||
mod file_builder;
|
||||
pub(crate) use self::file_builder::{FileBuilder, Sink};
|
||||
pub(crate) use self::file_builder::{ErrorMsg, FileBuilder, Sink};
|
||||
|
||||
pub use syntax_kinds::SyntaxKind;
|
||||
|
||||
|
|
Loading…
Reference in a new issue