refactor(parser)!: remove builder pattern from Parser struct (#5000)

part of #4455

use `with_options(ParseOptions { ..ParseOptions::default() })` API instead.
This commit is contained in:
Boshen 2024-08-20 07:40:25 +00:00
parent 081e2a37d9
commit b2ff2df5af
9 changed files with 51 additions and 45 deletions

View file

@ -15,7 +15,7 @@ use oxc_linter::{
}, },
FixKind, Linter, FixKind, Linter,
}; };
use oxc_parser::Parser; use oxc_parser::{ParseOptions, Parser};
use oxc_semantic::SemanticBuilder; use oxc_semantic::SemanticBuilder;
use oxc_span::{SourceType, VALID_EXTENSIONS}; use oxc_span::{SourceType, VALID_EXTENSIONS};
use ropey::Rope; use ropey::Rope;
@ -270,7 +270,10 @@ impl IsolatedLintHandler {
source; source;
let allocator = Allocator::default(); let allocator = Allocator::default();
let ret = Parser::new(&allocator, javascript_source_text, source_type) let ret = Parser::new(&allocator, javascript_source_text, source_type)
.allow_return_outside_function(true) .with_options(ParseOptions {
allow_return_outside_function: true,
..ParseOptions::default()
})
.parse(); .parse();
if !ret.errors.is_empty() { if !ret.errors.is_empty() {

View file

@ -10,7 +10,7 @@ use std::{
use dashmap::DashMap; use dashmap::DashMap;
use oxc_allocator::Allocator; use oxc_allocator::Allocator;
use oxc_diagnostics::{DiagnosticSender, DiagnosticService, Error, OxcDiagnostic}; use oxc_diagnostics::{DiagnosticSender, DiagnosticService, Error, OxcDiagnostic};
use oxc_parser::Parser; use oxc_parser::{ParseOptions, Parser};
use oxc_resolver::Resolver; use oxc_resolver::Resolver;
use oxc_semantic::{ModuleRecord, SemanticBuilder}; use oxc_semantic::{ModuleRecord, SemanticBuilder};
use oxc_span::{SourceType, VALID_EXTENSIONS}; use oxc_span::{SourceType, VALID_EXTENSIONS};
@ -254,7 +254,10 @@ impl Runtime {
tx_error: &DiagnosticSender, tx_error: &DiagnosticSender,
) -> Vec<Message<'a>> { ) -> Vec<Message<'a>> {
let ret = Parser::new(allocator, source_text, source_type) let ret = Parser::new(allocator, source_text, source_type)
.allow_return_outside_function(true) .with_options(ParseOptions {
allow_return_outside_function: true,
..ParseOptions::default()
})
.parse(); .parse();
if !ret.errors.is_empty() { if !ret.errors.is_empty() {

View file

@ -226,7 +226,7 @@ impl<'a> ParserImpl<'a> {
) )
}; };
Ok(if self.preserve_parens { Ok(if self.options.preserve_parens {
self.ast.expression_parenthesized(paren_span, expression) self.ast.expression_parenthesized(paren_span, expression)
} else { } else {
expression expression

View file

@ -103,10 +103,15 @@ pub struct ParserReturn<'a> {
pub panicked: bool, pub panicked: bool,
} }
/// Parser options /// Parse options
#[derive(Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct ParseOptions { pub struct ParseOptions {
/// Allow return outside of function
///
/// By default, a return statement at the top level raises an error.
/// Set this to true to accept such code.
pub allow_return_outside_function: bool, pub allow_return_outside_function: bool,
/// Emit `ParenthesizedExpression` in AST. /// Emit `ParenthesizedExpression` in AST.
/// ///
/// If this option is true, parenthesized expressions are represented by /// If this option is true, parenthesized expressions are represented by
@ -145,26 +150,6 @@ impl<'a> Parser<'a> {
self.options = options; self.options = options;
self self
} }
/// Allow return outside of function
///
/// By default, a return statement at the top level raises an error.
/// Set this to true to accept such code.
#[must_use]
pub fn allow_return_outside_function(mut self, allow: bool) -> Self {
self.options.allow_return_outside_function = allow;
self
}
/// Emit `ParenthesizedExpression` in AST.
///
/// If this option is true, parenthesized expressions are represented by (non-standard)
/// `ParenthesizedExpression` nodes that have a single expression property containing the expression inside parentheses.
#[must_use]
pub fn preserve_parens(mut self, allow: bool) -> Self {
self.options.preserve_parens = allow;
self
}
} }
mod parser_parse { mod parser_parse {
@ -243,6 +228,8 @@ use parser_parse::UniquePromise;
/// Implementation of parser. /// Implementation of parser.
/// `Parser` is just a public wrapper, the guts of the implementation is in this type. /// `Parser` is just a public wrapper, the guts of the implementation is in this type.
struct ParserImpl<'a> { struct ParserImpl<'a> {
options: ParseOptions,
lexer: Lexer<'a>, lexer: Lexer<'a>,
/// SourceType: JavaScript or TypeScript, Script or Module, jsx support? /// SourceType: JavaScript or TypeScript, Script or Module, jsx support?
@ -269,10 +256,6 @@ struct ParserImpl<'a> {
/// Ast builder for creating AST spans /// Ast builder for creating AST spans
ast: AstBuilder<'a>, ast: AstBuilder<'a>,
/// Emit `ParenthesizedExpression` in AST.
/// Default: `true`
preserve_parens: bool,
} }
impl<'a> ParserImpl<'a> { impl<'a> ParserImpl<'a> {
@ -289,6 +272,7 @@ impl<'a> ParserImpl<'a> {
unique: UniquePromise, unique: UniquePromise,
) -> Self { ) -> Self {
Self { Self {
options,
lexer: Lexer::new(allocator, source_text, source_type, unique), lexer: Lexer::new(allocator, source_text, source_type, unique),
source_type, source_type,
source_text, source_text,
@ -298,7 +282,6 @@ impl<'a> ParserImpl<'a> {
state: ParserState::default(), state: ParserState::default(),
ctx: Self::default_context(source_type, options), ctx: Self::default_context(source_type, options),
ast: AstBuilder::new(allocator), ast: AstBuilder::new(allocator),
preserve_parens: options.preserve_parens,
} }
} }

View file

@ -2,7 +2,7 @@
use std::path::Path; use std::path::Path;
use oxc_allocator::Allocator; use oxc_allocator::Allocator;
use oxc_parser::Parser; use oxc_parser::{ParseOptions, Parser};
use oxc_prettier::{Prettier, PrettierOptions, TrailingComma}; use oxc_prettier::{Prettier, PrettierOptions, TrailingComma};
use oxc_span::SourceType; use oxc_span::SourceType;
use pico_args::Arguments; use pico_args::Arguments;
@ -22,7 +22,9 @@ fn main() -> std::io::Result<()> {
let source_text = std::fs::read_to_string(path)?; let source_text = std::fs::read_to_string(path)?;
let allocator = Allocator::default(); let allocator = Allocator::default();
let source_type = SourceType::from_path(path).unwrap(); let source_type = SourceType::from_path(path).unwrap();
let ret = Parser::new(&allocator, &source_text, source_type).preserve_parens(false).parse(); let ret = Parser::new(&allocator, &source_text, source_type)
.with_options(ParseOptions { preserve_parens: false, ..ParseOptions::default() })
.parse();
let output = Prettier::new( let output = Prettier::new(
&allocator, &allocator,
&source_text, &source_text,

View file

@ -11,7 +11,7 @@ use oxc::{
codegen::{CodeGenerator, WhitespaceRemover}, codegen::{CodeGenerator, WhitespaceRemover},
diagnostics::Error, diagnostics::Error,
minifier::{CompressOptions, Minifier, MinifierOptions}, minifier::{CompressOptions, Minifier, MinifierOptions},
parser::Parser, parser::{ParseOptions, Parser},
semantic::{ScopeId, Semantic, SemanticBuilder}, semantic::{ScopeId, Semantic, SemanticBuilder},
span::SourceType, span::SourceType,
transformer::{TransformOptions, Transformer}, transformer::{TransformOptions, Transformer},
@ -169,7 +169,10 @@ impl Oxc {
let source_type = SourceType::from_path(&path).unwrap_or_default(); let source_type = SourceType::from_path(&path).unwrap_or_default();
let ret = Parser::new(&allocator, source_text, source_type) let ret = Parser::new(&allocator, source_text, source_type)
.allow_return_outside_function(parser_options.allow_return_outside_function) .with_options(ParseOptions {
allow_return_outside_function: parser_options.allow_return_outside_function,
..ParseOptions::default()
})
.parse(); .parse();
self.comments = self.map_comments(&ret.trivias); self.comments = self.map_comments(&ret.trivias);
@ -204,7 +207,10 @@ impl Oxc {
if run_options.prettier_format() { if run_options.prettier_format() {
let ret = Parser::new(&allocator, source_text, source_type) let ret = Parser::new(&allocator, source_text, source_type)
.allow_return_outside_function(parser_options.allow_return_outside_function) .with_options(ParseOptions {
allow_return_outside_function: parser_options.allow_return_outside_function,
..ParseOptions::default()
})
.parse(); .parse();
let printed = let printed =
Prettier::new(&allocator, source_text, ret.trivias, PrettierOptions::default()) Prettier::new(&allocator, source_text, ret.trivias, PrettierOptions::default())
@ -214,7 +220,10 @@ impl Oxc {
if run_options.prettier_ir() { if run_options.prettier_ir() {
let ret = Parser::new(&allocator, source_text, source_type) let ret = Parser::new(&allocator, source_text, source_type)
.allow_return_outside_function(parser_options.allow_return_outside_function) .with_options(ParseOptions {
allow_return_outside_function: parser_options.allow_return_outside_function,
..ParseOptions::default()
})
.parse(); .parse();
let prettier_doc = Prettier::new( let prettier_doc = Prettier::new(
&allocator, &allocator,

View file

@ -8,7 +8,7 @@ use oxc_allocator::Allocator;
pub use oxc_ast::ast::Program; pub use oxc_ast::ast::Program;
use oxc_ast::CommentKind; use oxc_ast::CommentKind;
use oxc_diagnostics::{Error, NamedSource}; use oxc_diagnostics::{Error, NamedSource};
use oxc_parser::{Parser, ParserReturn}; use oxc_parser::{ParseOptions, Parser, ParserReturn};
use oxc_span::SourceType; use oxc_span::SourceType;
pub use crate::module_lexer::*; pub use crate::module_lexer::*;
@ -64,7 +64,10 @@ fn parse<'a>(
_ => source_type, _ => source_type,
}; };
Parser::new(allocator, source_text, source_type) Parser::new(allocator, source_text, source_type)
.preserve_parens(options.preserve_parens.unwrap_or(true)) .with_options(ParseOptions {
preserve_parens: options.preserve_parens.unwrap_or(true),
..ParseOptions::default()
})
.parse() .parse()
} }

View file

@ -1,7 +1,7 @@
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use oxc::allocator::Allocator; use oxc::allocator::Allocator;
use oxc::parser::{Parser, ParserReturn}; use oxc::parser::{ParseOptions, Parser, ParserReturn};
use oxc::span::SourceType; use oxc::span::SourceType;
use oxc_prettier::{Prettier, PrettierOptions}; use oxc_prettier::{Prettier, PrettierOptions};
@ -18,13 +18,14 @@ fn get_result(source_text: &str, source_type: SourceType) -> TestResult {
let options = PrettierOptions::default(); let options = PrettierOptions::default();
let allocator = Allocator::default(); let allocator = Allocator::default();
let parse_options = ParseOptions { preserve_parens: false, ..ParseOptions::default() };
let ParserReturn { program, trivias, .. } = let ParserReturn { program, trivias, .. } =
Parser::new(&allocator, source_text, source_type).preserve_parens(false).parse(); Parser::new(&allocator, source_text, source_type).with_options(parse_options).parse();
let source_text1 = Prettier::new(&allocator, source_text, trivias, options).build(&program); let source_text1 = Prettier::new(&allocator, source_text, trivias, options).build(&program);
let allocator = Allocator::default(); let allocator = Allocator::default();
let ParserReturn { program, trivias, .. } = let ParserReturn { program, trivias, .. } =
Parser::new(&allocator, &source_text1, source_type).preserve_parens(false).parse(); Parser::new(&allocator, &source_text1, source_type).with_options(parse_options).parse();
let source_text2 = Prettier::new(&allocator, &source_text1, trivias, options).build(&program); let source_text2 = Prettier::new(&allocator, &source_text1, trivias, options).build(&program);
if source_text1 == source_text2 { if source_text1 == source_text2 {

View file

@ -9,7 +9,7 @@ use std::{
}; };
use oxc_allocator::Allocator; use oxc_allocator::Allocator;
use oxc_parser::Parser; use oxc_parser::{ParseOptions, Parser};
use oxc_prettier::{Prettier, PrettierOptions}; use oxc_prettier::{Prettier, PrettierOptions};
use oxc_span::SourceType; use oxc_span::SourceType;
use oxc_tasks_common::project_root; use oxc_tasks_common::project_root;
@ -382,7 +382,9 @@ impl TestRunner {
fn prettier(path: &Path, source_text: &str, prettier_options: PrettierOptions) -> String { fn prettier(path: &Path, source_text: &str, prettier_options: PrettierOptions) -> String {
let allocator = Allocator::default(); let allocator = Allocator::default();
let source_type = SourceType::from_path(path).unwrap(); let source_type = SourceType::from_path(path).unwrap();
let ret = Parser::new(&allocator, source_text, source_type).preserve_parens(false).parse(); let ret = Parser::new(&allocator, source_text, source_type)
.with_options(ParseOptions { preserve_parens: false, ..ParseOptions::default() })
.parse();
Prettier::new(&allocator, source_text, ret.trivias, prettier_options).build(&ret.program) Prettier::new(&allocator, source_text, ret.trivias, prettier_options).build(&ret.program)
} }
} }