refactor(oxc_parser): parser and lexer does not need to share the errors vec

This commit is contained in:
Boshen 2023-04-01 13:53:29 +08:00
parent adef772d6c
commit d4ff0bb40e
3 changed files with 19 additions and 26 deletions

View file

@ -261,7 +261,7 @@ impl<'a> Parser<'a> {
lexer: self.lexer.checkpoint(),
cur_token: self.token.clone(),
prev_span_end: self.prev_token_end,
errors_pos: self.errors.borrow().len(),
errors_pos: self.errors.len(),
}
}
@ -272,7 +272,7 @@ impl<'a> Parser<'a> {
self.lexer.rewind(lexer);
self.token = cur_token;
self.prev_token_end = prev_span_end;
self.errors.borrow_mut().truncate(errors_lens);
self.errors.truncate(errors_lens);
}
/// # Errors

View file

@ -17,7 +17,7 @@ use std::{collections::VecDeque, str::Chars};
use oxc_allocator::{Allocator, String};
use oxc_ast::{ast::RegExpFlags, SourceType, Span};
use oxc_diagnostics::{Diagnostics, Error};
use oxc_diagnostics::Error;
use simd::{SkipMultilineComment, SkipWhitespace};
pub use token::{RegExp, Token, TokenValue};
@ -60,7 +60,7 @@ pub struct Lexer<'a> {
current: LexerCheckpoint<'a>,
errors: Diagnostics,
pub(crate) errors: Vec<Error>,
lookahead: VecDeque<LexerCheckpoint<'a>>,
@ -72,25 +72,19 @@ pub struct Lexer<'a> {
#[allow(clippy::unused_self)]
impl<'a> Lexer<'a> {
#[must_use]
pub fn new(
allocator: &'a Allocator,
source: &'a str,
errors: Diagnostics,
source_type: SourceType,
) -> Self {
pub fn new(allocator: &'a Allocator, source: &'a str, source_type: SourceType) -> Self {
let token = Token {
// the first token is at the start of file, so is allows on a new line
is_on_new_line: true,
..Token::default()
};
let current =
LexerCheckpoint { chars: source.chars(), token, errors_pos: errors.borrow().len() };
let current = LexerCheckpoint { chars: source.chars(), token, errors_pos: 0 };
Self {
allocator,
source,
source_type,
current,
errors,
errors: vec![],
lookahead: VecDeque::with_capacity(4),
context: LexerContext::Regular,
trivia_builder: TriviaBuilder::default(),
@ -110,13 +104,13 @@ impl<'a> Lexer<'a> {
LexerCheckpoint {
chars: self.current.chars.clone(),
token: self.current.token.clone(),
errors_pos: self.errors.borrow().len(),
errors_pos: self.errors.len(),
}
}
/// Rewinds the lexer to the same state as when the passed in `checkpoint` was created.
pub fn rewind(&mut self, checkpoint: LexerCheckpoint<'a>) {
self.errors.borrow_mut().truncate(checkpoint.errors_pos);
self.errors.truncate(checkpoint.errors_pos);
self.current = checkpoint;
self.lookahead.clear();
}
@ -147,7 +141,7 @@ impl<'a> Lexer<'a> {
self.lookahead.push_back(LexerCheckpoint {
chars: self.current.chars.clone(),
token: peeked,
errors_pos: self.errors.borrow().len(),
errors_pos: self.errors.len(),
});
}
@ -255,7 +249,7 @@ impl<'a> Lexer<'a> {
// ---------- Private Methods ---------- //
fn error<T: Into<Error>>(&mut self, error: T) {
self.errors.borrow_mut().push(error.into());
self.errors.push(error.into());
}
/// Get the length offset from the source, in UTF-8 bytes

View file

@ -19,7 +19,7 @@ use std::rc::Rc;
use oxc_allocator::Allocator;
use oxc_ast::{ast::Program, context::Context, AstBuilder, SourceType, Span, Trivias};
use oxc_diagnostics::{Diagnostics, Error, Result};
use oxc_diagnostics::{Error, Result};
use crate::{
lexer::{Kind, Lexer, Token},
@ -48,7 +48,7 @@ pub struct Parser<'a> {
/// All syntax errors from parser and lexer
/// Note: favor adding to `Diagnostics` instead of raising Err
errors: Diagnostics,
errors: Vec<Error>,
/// The current parsing token
token: Token<'a>,
@ -69,12 +69,11 @@ pub struct Parser<'a> {
impl<'a> Parser<'a> {
#[must_use]
pub fn new(allocator: &'a Allocator, source: &'a str, source_type: SourceType) -> Self {
let errors = Diagnostics::default();
Self {
lexer: Lexer::new(allocator, source, errors.clone(), source_type),
lexer: Lexer::new(allocator, source, source_type),
source_type,
source,
errors,
errors: vec![],
token: Token::default(),
prev_token_end: 0,
state: ParserState::new(allocator),
@ -107,7 +106,7 @@ impl<'a> Parser<'a> {
(program, true)
}
};
let errors = self.errors.borrow_mut().drain(..).collect();
let errors = self.lexer.errors.into_iter().chain(self.errors).collect();
let trivias = self.lexer.trivia_builder.build();
ParserReturn { program, errors, trivias, panicked }
}
@ -138,18 +137,18 @@ impl<'a> Parser<'a> {
/// Return error info at current token
/// # Panics
/// * The lexer did not push a diagnostic when `Kind::Undetermined` is returned
fn unexpected<T>(&self) -> Result<T> {
fn unexpected<T>(&mut self) -> Result<T> {
// The lexer should have reported a more meaningful diagnostic
// when it is a undetermined kind.
if self.cur_kind() == Kind::Undetermined {
return Err(self.errors.borrow_mut().pop().unwrap());
return Err(self.lexer.errors.pop().unwrap());
}
Err(diagnostics::UnexpectedToken(self.cur_token().span()).into())
}
/// Push a Syntax Error
fn error<T: Into<Error>>(&mut self, error: T) {
self.errors.borrow_mut().push(error.into());
self.errors.push(error.into());
}
#[must_use]