mirror of
https://github.com/danbulant/oxc
synced 2026-05-25 12:51:57 +00:00
perf(parser): lazily build trivia map instead of build in-place (#903)
closes #898
This commit is contained in:
parent
95cae98e2b
commit
babbc47d61
7 changed files with 35 additions and 24 deletions
|
|
@ -22,7 +22,11 @@ mod visit_mut;
|
||||||
pub use num_bigint::BigUint;
|
pub use num_bigint::BigUint;
|
||||||
|
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
ast_builder::AstBuilder, ast_kind::AstKind, trivia::Trivias, visit::Visit, visit_mut::VisitMut,
|
ast_builder::AstBuilder,
|
||||||
|
ast_kind::AstKind,
|
||||||
|
trivia::{Comment, CommentKind, Trivias, TriviasMap},
|
||||||
|
visit::Visit,
|
||||||
|
visit_mut::VisitMut,
|
||||||
};
|
};
|
||||||
|
|
||||||
// After experimenting with two types of boxed enum variants:
|
// After experimenting with two types of boxed enum variants:
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,25 @@ use std::collections::BTreeMap;
|
||||||
|
|
||||||
use oxc_span::Span;
|
use oxc_span::Span;
|
||||||
|
|
||||||
|
/// A vec of trivias from the lexer, tupled by (span.start, span.end).
|
||||||
|
pub type Trivias = Vec<(u32, u32, CommentKind)>;
|
||||||
|
|
||||||
/// Trivias such as comments
|
/// Trivias such as comments
|
||||||
///
|
///
|
||||||
/// Trivia (called that because it's trivial) represent the parts of the source text that are largely insignificant for normal understanding of the code.
|
/// Trivia (called that because it's trivial) represent the parts of the source text that are largely insignificant for normal understanding of the code.
|
||||||
/// For example: whitespace, comments, and even conflict markers.
|
/// For example: whitespace, comments, and even conflict markers.
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Trivias {
|
pub struct TriviasMap {
|
||||||
/// Keyed by span.start
|
/// Keyed by span.start
|
||||||
comments: BTreeMap<u32, Comment>,
|
comments: BTreeMap<u32, Comment>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Trivias> for TriviasMap {
|
||||||
|
fn from(trivias: Trivias) -> Self {
|
||||||
|
Self { comments: trivias.iter().map(|t| (t.0, Comment::new(t.1, t.2))).collect() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Single or multiline comment
|
/// Single or multiline comment
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
|
@ -46,7 +55,7 @@ impl Comment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Trivias {
|
impl TriviasMap {
|
||||||
pub fn comments(&self) -> &BTreeMap<u32, Comment> {
|
pub fn comments(&self) -> &BTreeMap<u32, Comment> {
|
||||||
&self.comments
|
&self.comments
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use oxc_ast::Trivias;
|
use oxc_ast::TriviasMap;
|
||||||
use oxc_span::Span;
|
use oxc_span::Span;
|
||||||
use rust_lapper::{Interval, Lapper};
|
use rust_lapper::{Interval, Lapper};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
@ -28,7 +28,7 @@ impl<'a> DisableDirectives<'a> {
|
||||||
|
|
||||||
pub struct DisableDirectivesBuilder<'a, 'b> {
|
pub struct DisableDirectivesBuilder<'a, 'b> {
|
||||||
source_text: &'a str,
|
source_text: &'a str,
|
||||||
trivias: &'b Trivias,
|
trivias: &'b TriviasMap,
|
||||||
/// All the disabled rules with their corresponding covering spans
|
/// All the disabled rules with their corresponding covering spans
|
||||||
intervals: Lapper<u32, DisabledRule<'a>>,
|
intervals: Lapper<u32, DisabledRule<'a>>,
|
||||||
/// Start of `eslint-disable`
|
/// Start of `eslint-disable`
|
||||||
|
|
@ -38,7 +38,7 @@ pub struct DisableDirectivesBuilder<'a, 'b> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b> DisableDirectivesBuilder<'a, 'b> {
|
impl<'a, 'b> DisableDirectivesBuilder<'a, 'b> {
|
||||||
pub fn new(source_text: &'a str, trivias: &'b Trivias) -> Self {
|
pub fn new(source_text: &'a str, trivias: &'b TriviasMap) -> Self {
|
||||||
Self {
|
Self {
|
||||||
source_text,
|
source_text,
|
||||||
trivias,
|
trivias,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
use oxc_ast::Trivias;
|
use oxc_ast::{CommentKind, Trivias};
|
||||||
use oxc_span::Span;
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct TriviaBuilder {
|
pub struct TriviaBuilder {
|
||||||
|
|
@ -11,13 +10,13 @@ impl TriviaBuilder {
|
||||||
self.trivias
|
self.trivias
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// skip leading `//`
|
||||||
pub fn add_single_line_comment(&mut self, start: u32, end: u32) {
|
pub fn add_single_line_comment(&mut self, start: u32, end: u32) {
|
||||||
// skip leading `//`
|
self.trivias.push((start + 2, end, CommentKind::SingleLine));
|
||||||
self.trivias.add_single_line_comment(Span::new(start + 2, end));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// skip leading `/*` and trailing `*/`
|
||||||
pub fn add_multi_line_comment(&mut self, start: u32, end: u32) {
|
pub fn add_multi_line_comment(&mut self, start: u32, end: u32) {
|
||||||
// skip leading `/*` and trailing `*/`
|
self.trivias.push((start + 2, end - 2, CommentKind::MultiLine));
|
||||||
self.trivias.add_multi_line_comment(Span::new(start + 2, end - 2));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use std::{cell::RefCell, path::PathBuf, rc::Rc, sync::Arc};
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
#[allow(clippy::wildcard_imports)]
|
#[allow(clippy::wildcard_imports)]
|
||||||
use oxc_ast::{ast::*, AstKind, Trivias, Visit};
|
use oxc_ast::{ast::*, AstKind, Trivias, TriviasMap, Visit};
|
||||||
use oxc_diagnostics::Error;
|
use oxc_diagnostics::Error;
|
||||||
use oxc_span::{Atom, SourceType, Span};
|
use oxc_span::{Atom, SourceType, Span};
|
||||||
use oxc_syntax::{module_record::ModuleRecord, operator::AssignmentOperator};
|
use oxc_syntax::{module_record::ModuleRecord, operator::AssignmentOperator};
|
||||||
|
|
@ -40,7 +40,7 @@ pub struct SemanticBuilder<'a> {
|
||||||
|
|
||||||
pub source_type: SourceType,
|
pub source_type: SourceType,
|
||||||
|
|
||||||
trivias: Rc<Trivias>,
|
trivias: Rc<TriviasMap>,
|
||||||
|
|
||||||
/// Semantic early errors such as redeclaration errors.
|
/// Semantic early errors such as redeclaration errors.
|
||||||
errors: RefCell<Vec<Error>>,
|
errors: RefCell<Vec<Error>>,
|
||||||
|
|
@ -82,7 +82,7 @@ impl<'a> SemanticBuilder<'a> {
|
||||||
let scope = ScopeTree::new(source_type);
|
let scope = ScopeTree::new(source_type);
|
||||||
let current_scope_id = scope.root_scope_id();
|
let current_scope_id = scope.root_scope_id();
|
||||||
|
|
||||||
let trivias = Rc::new(Trivias::default());
|
let trivias = Rc::new(TriviasMap::default());
|
||||||
Self {
|
Self {
|
||||||
source_text,
|
source_text,
|
||||||
source_type,
|
source_type,
|
||||||
|
|
@ -106,9 +106,8 @@ impl<'a> SemanticBuilder<'a> {
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn with_trivias(mut self, trivias: Trivias) -> Self {
|
pub fn with_trivias(mut self, trivias: Trivias) -> Self {
|
||||||
let trivias = Rc::new(trivias);
|
self.trivias = Rc::new(TriviasMap::from(trivias));
|
||||||
self.trivias = Rc::clone(&trivias);
|
self.jsdoc = JSDocBuilder::new(self.source_text, &self.trivias);
|
||||||
self.jsdoc = JSDocBuilder::new(self.source_text, &trivias);
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{collections::BTreeMap, rc::Rc};
|
use std::{collections::BTreeMap, rc::Rc};
|
||||||
|
|
||||||
use oxc_ast::{AstKind, Trivias};
|
use oxc_ast::{AstKind, TriviasMap};
|
||||||
use oxc_span::{GetSpan, Span};
|
use oxc_span::{GetSpan, Span};
|
||||||
|
|
||||||
use super::{JSDoc, JSDocComment};
|
use super::{JSDoc, JSDocComment};
|
||||||
|
|
@ -8,13 +8,13 @@ use super::{JSDoc, JSDocComment};
|
||||||
pub struct JSDocBuilder<'a> {
|
pub struct JSDocBuilder<'a> {
|
||||||
source_text: &'a str,
|
source_text: &'a str,
|
||||||
|
|
||||||
trivias: Rc<Trivias>,
|
trivias: Rc<TriviasMap>,
|
||||||
|
|
||||||
docs: BTreeMap<Span, JSDocComment<'a>>,
|
docs: BTreeMap<Span, JSDocComment<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> JSDocBuilder<'a> {
|
impl<'a> JSDocBuilder<'a> {
|
||||||
pub fn new(source_text: &'a str, trivias: &Rc<Trivias>) -> Self {
|
pub fn new(source_text: &'a str, trivias: &Rc<TriviasMap>) -> Self {
|
||||||
Self { source_text, trivias: Rc::clone(trivias), docs: BTreeMap::default() }
|
Self { source_text, trivias: Rc::clone(trivias), docs: BTreeMap::default() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use std::{rc::Rc, sync::Arc};
|
||||||
|
|
||||||
pub use builder::{SemanticBuilder, SemanticBuilderReturn};
|
pub use builder::{SemanticBuilder, SemanticBuilderReturn};
|
||||||
pub use jsdoc::{JSDoc, JSDocComment, JSDocTag};
|
pub use jsdoc::{JSDoc, JSDocComment, JSDocTag};
|
||||||
use oxc_ast::{ast::IdentifierReference, AstKind, Trivias};
|
use oxc_ast::{ast::IdentifierReference, AstKind, TriviasMap};
|
||||||
use oxc_span::SourceType;
|
use oxc_span::SourceType;
|
||||||
pub use oxc_syntax::{
|
pub use oxc_syntax::{
|
||||||
module_record::ModuleRecord,
|
module_record::ModuleRecord,
|
||||||
|
|
@ -39,7 +39,7 @@ pub struct Semantic<'a> {
|
||||||
|
|
||||||
symbols: SymbolTable,
|
symbols: SymbolTable,
|
||||||
|
|
||||||
trivias: Rc<Trivias>,
|
trivias: Rc<TriviasMap>,
|
||||||
|
|
||||||
module_record: Arc<ModuleRecord>,
|
module_record: Arc<ModuleRecord>,
|
||||||
|
|
||||||
|
|
@ -69,7 +69,7 @@ impl<'a> Semantic<'a> {
|
||||||
&self.scopes
|
&self.scopes
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trivias(&self) -> &Trivias {
|
pub fn trivias(&self) -> &TriviasMap {
|
||||||
&self.trivias
|
&self.trivias
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue