refactor(wasm): add source_type for parser, replace class options with plain object (#5217)

- Feat: add `source_type` to `ParserOptions`
- Refactor: use plain objects for options instead of `new
OxcRunOptions()` and `new OxcParserOptions()`, allowing easier
serialization.
This commit is contained in:
Kevin Deng 三咲智子 2024-08-26 15:08:35 +08:00 committed by GitHub
parent b4fc521087
commit b39c0d6122
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 112 additions and 329 deletions

View file

@ -149,13 +149,18 @@ impl Oxc {
#[wasm_bindgen]
pub fn run(
&mut self,
run_options: &OxcRunOptions,
parser_options: &OxcParserOptions,
_linter_options: &OxcLinterOptions,
_codegen_options: &OxcCodegenOptions,
minifier_options: &OxcMinifierOptions,
run_options: Option<OxcRunOptions>,
parser_options: Option<OxcParserOptions>,
linter_options: Option<OxcLinterOptions>,
codegen_options: Option<OxcCodegenOptions>,
minifier_options: Option<OxcMinifierOptions>,
) -> Result<(), serde_wasm_bindgen::Error> {
self.diagnostics = RefCell::default();
let run_options = run_options.unwrap_or_default();
let parser_options = parser_options.unwrap_or_default();
let _linter_options = linter_options.unwrap_or_default();
let _codegen_options = codegen_options.unwrap_or_default();
let minifier_options = minifier_options.unwrap_or_default();
let allocator = Allocator::default();
let source_text = &self.source_text;
@ -163,10 +168,17 @@ impl Oxc {
parser_options.source_filename.clone().unwrap_or_else(|| "test.tsx".to_string()),
);
let source_type = SourceType::from_path(&path).unwrap_or_default();
let source_type = match parser_options.source_type.as_deref() {
Some("script") => source_type.with_script(true),
Some("module") => source_type.with_module(true),
_ => source_type,
};
let ret = Parser::new(&allocator, source_text, source_type)
.with_options(ParseOptions {
allow_return_outside_function: parser_options.allow_return_outside_function,
allow_return_outside_function: parser_options
.allow_return_outside_function
.unwrap_or_default(),
..ParseOptions::default()
})
.parse();
@ -185,7 +197,7 @@ impl Oxc {
.with_check_syntax_error(true)
.build(program);
if run_options.syntax() {
if run_options.syntax.unwrap_or_default() {
self.save_diagnostics(
semantic_ret.errors.into_iter().map(Error::from).collect::<Vec<_>>(),
);
@ -193,7 +205,7 @@ impl Oxc {
let semantic = Rc::new(semantic_ret.semantic);
// Only lint if there are not syntax errors
if run_options.lint() && self.diagnostics.borrow().is_empty() {
if run_options.lint.unwrap_or_default() && self.diagnostics.borrow().is_empty() {
let linter_ret = Linter::default().run(&path, Rc::clone(&semantic));
let diagnostics = linter_ret.into_iter().map(|e| Error::from(e.error)).collect();
self.save_diagnostics(diagnostics);
@ -201,10 +213,12 @@ impl Oxc {
self.ast = program.serialize(&self.serializer)?;
if run_options.prettier_format() {
if run_options.prettier_format.unwrap_or_default() {
let ret = Parser::new(&allocator, source_text, source_type)
.with_options(ParseOptions {
allow_return_outside_function: parser_options.allow_return_outside_function,
allow_return_outside_function: parser_options
.allow_return_outside_function
.unwrap_or_default(),
..ParseOptions::default()
})
.parse();
@ -214,10 +228,12 @@ impl Oxc {
self.prettier_formatted_text = printed;
}
if run_options.prettier_ir() {
if run_options.prettier_ir.unwrap_or_default() {
let ret = Parser::new(&allocator, source_text, source_type)
.with_options(ParseOptions {
allow_return_outside_function: parser_options.allow_return_outside_function,
allow_return_outside_function: parser_options
.allow_return_outside_function
.unwrap_or_default(),
..ParseOptions::default()
})
.parse();
@ -236,7 +252,7 @@ impl Oxc {
};
}
if run_options.transform() {
if run_options.transform.unwrap_or_default() {
let (symbols, scopes) = SemanticBuilder::new(source_text, source_type)
.build(program)
.semantic
@ -257,33 +273,35 @@ impl Oxc {
}
}
if run_options.scope() || run_options.symbol() {
if run_options.scope.unwrap_or_default() || run_options.symbol.unwrap_or_default() {
let semantic = SemanticBuilder::new(source_text, source_type)
.build_module_record(PathBuf::new(), program)
.build(program)
.semantic;
if run_options.scope() {
if run_options.scope.unwrap_or_default() {
self.scope_text = Self::get_scope_text(&semantic);
} else if run_options.symbol() {
} else if run_options.symbol.unwrap_or_default() {
self.symbols = semantic.symbols().serialize(&self.serializer)?;
}
}
let program = allocator.alloc(program);
if minifier_options.compress() || minifier_options.mangle() {
let compress_options = minifier_options.compress_options();
if minifier_options.compress.unwrap_or_default()
|| minifier_options.mangle.unwrap_or_default()
{
let compress_options = minifier_options.compress_options.unwrap_or_default();
let options = MinifierOptions {
mangle: minifier_options.mangle(),
compress: if minifier_options.compress() {
mangle: minifier_options.mangle.unwrap_or_default(),
compress: if minifier_options.compress.unwrap_or_default() {
CompressOptions {
booleans: compress_options.booleans(),
drop_console: compress_options.drop_console(),
drop_debugger: compress_options.drop_debugger(),
evaluate: compress_options.evaluate(),
join_vars: compress_options.join_vars(),
loops: compress_options.loops(),
typeofs: compress_options.typeofs(),
booleans: compress_options.booleans,
drop_console: compress_options.drop_console,
drop_debugger: compress_options.drop_debugger,
evaluate: compress_options.evaluate,
join_vars: compress_options.join_vars,
loops: compress_options.loops,
typeofs: compress_options.typeofs,
..CompressOptions::default()
}
} else {
@ -295,7 +313,7 @@ impl Oxc {
self.codegen_text = CodeGenerator::new()
.with_options(CodegenOptions {
minify: minifier_options.whitespace(),
minify: minifier_options.whitespace.unwrap_or_default(),
..CodegenOptions::default()
})
.build(program)

View file

@ -1,233 +1,84 @@
use serde::Deserialize;
use tsify::Tsify;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
#[derive(Default, Clone, Copy, Tsify)]
#[derive(Debug, Default, Clone, Deserialize, Tsify)]
#[tsify(from_wasm_abi)]
#[serde(rename_all = "camelCase")]
pub struct OxcRunOptions {
syntax: bool,
lint: bool,
format: bool,
prettier_format: bool,
prettier_ir: bool,
transform: bool,
type_check: bool,
scope: bool,
symbol: bool,
#[tsify(optional)]
pub syntax: Option<bool>,
#[tsify(optional)]
pub lint: Option<bool>,
#[tsify(optional)]
pub format: Option<bool>,
#[tsify(optional)]
pub prettier_format: Option<bool>,
#[tsify(optional)]
pub prettier_ir: Option<bool>,
#[tsify(optional)]
pub transform: Option<bool>,
#[tsify(optional)]
pub type_check: Option<bool>,
#[tsify(optional)]
pub scope: Option<bool>,
#[tsify(optional)]
pub symbol: Option<bool>,
}
#[wasm_bindgen]
impl OxcRunOptions {
#[wasm_bindgen(constructor)]
pub fn new() -> Self {
Self { syntax: true, lint: true, ..Self::default() }
}
#[wasm_bindgen(getter)]
pub fn syntax(&self) -> bool {
self.syntax
}
#[wasm_bindgen(setter)]
pub fn set_syntax(&mut self, yes: bool) {
self.syntax = yes;
}
#[wasm_bindgen(getter)]
pub fn lint(&self) -> bool {
self.lint
}
#[wasm_bindgen(setter)]
pub fn set_lint(&mut self, yes: bool) {
self.lint = yes;
}
#[wasm_bindgen(getter)]
pub fn format(&self) -> bool {
self.format
}
#[wasm_bindgen(setter)]
pub fn set_format(&mut self, yes: bool) {
self.format = yes;
}
#[wasm_bindgen(getter = "prettierFormat")]
pub fn prettier_format(&self) -> bool {
self.prettier_format
}
#[wasm_bindgen(setter = "prettierFormat")]
pub fn set_prettier_format(&mut self, yes: bool) {
self.prettier_format = yes;
}
#[wasm_bindgen(getter = "prettierIr")]
pub fn prettier_ir(&self) -> bool {
self.prettier_ir
}
#[wasm_bindgen(setter = "prettierIr")]
pub fn set_prettier_ir(&mut self, yes: bool) {
self.prettier_ir = yes;
}
#[wasm_bindgen(getter)]
pub fn transform(&self) -> bool {
self.transform
}
#[wasm_bindgen(setter)]
pub fn set_transform(&mut self, yes: bool) {
self.transform = yes;
}
#[wasm_bindgen(getter = "typeCheck")]
pub fn type_check(&self) -> bool {
self.type_check
}
#[wasm_bindgen(setter = "typeCheck")]
pub fn set_type_check(&mut self, yes: bool) {
self.type_check = yes;
}
#[wasm_bindgen(getter)]
pub fn scope(&self) -> bool {
self.scope
}
#[wasm_bindgen(setter)]
pub fn set_scope(&mut self, yes: bool) {
self.scope = yes;
}
#[wasm_bindgen(getter)]
pub fn symbol(&self) -> bool {
self.symbol
}
#[wasm_bindgen(setter)]
pub fn set_symbol(&mut self, yes: bool) {
self.symbol = yes;
}
}
#[wasm_bindgen(getter_with_clone)]
#[derive(Default, Clone)]
#[derive(Debug, Default, Clone, Deserialize, Tsify)]
#[tsify(from_wasm_abi)]
#[serde(rename_all = "camelCase")]
pub struct OxcParserOptions {
#[wasm_bindgen(js_name = allowReturnOutsideFunction)]
pub allow_return_outside_function: bool,
#[wasm_bindgen(js_name = sourceFilename)]
#[tsify(optional)]
pub allow_return_outside_function: Option<bool>,
#[tsify(optional, type = "\"script\" | \"module\"")]
pub source_type: Option<String>,
#[tsify(optional)]
pub source_filename: Option<String>,
}
#[wasm_bindgen]
impl OxcParserOptions {
#[wasm_bindgen(constructor)]
pub fn new() -> Self {
Self::default()
}
}
#[derive(Debug, Default, Clone, Deserialize, Tsify)]
#[tsify(from_wasm_abi)]
#[serde(rename_all = "camelCase")]
// allow empty object for future compatibility
#[allow(clippy::empty_structs_with_brackets)]
pub struct OxcLinterOptions {}
#[wasm_bindgen]
#[derive(Default, Clone, Copy)]
pub struct OxcLinterOptions;
#[wasm_bindgen]
impl OxcLinterOptions {
#[wasm_bindgen(constructor)]
pub fn new() -> Self {
Self
}
}
#[wasm_bindgen]
#[derive(Default, Clone, Copy)]
#[derive(Debug, Default, Clone, Deserialize, Tsify)]
#[tsify(from_wasm_abi)]
#[serde(rename_all = "camelCase")]
pub struct OxcCodegenOptions {
pub indentation: u8,
#[wasm_bindgen(js_name = enableTypescript)]
pub enable_typescript: bool,
#[tsify(optional)]
pub indentation: Option<u8>,
#[tsify(optional)]
pub enable_typescript: Option<bool>,
}
#[wasm_bindgen]
impl OxcCodegenOptions {
#[wasm_bindgen(constructor)]
pub fn new() -> Self {
Self::default()
}
}
#[wasm_bindgen]
#[derive(Default, Clone, Copy)]
#[derive(Debug, Default, Clone, Deserialize, Tsify)]
#[tsify(from_wasm_abi)]
#[serde(rename_all = "camelCase")]
pub struct OxcMinifierOptions {
whitespace: bool,
mangle: bool,
compress: bool,
compress_options: OxcCompressOptions,
#[tsify(optional)]
pub whitespace: Option<bool>,
#[tsify(optional)]
pub mangle: Option<bool>,
#[tsify(optional)]
pub compress: Option<bool>,
#[tsify(optional)]
pub compress_options: Option<OxcCompressOptions>,
}
#[wasm_bindgen]
#[allow(clippy::trivially_copy_pass_by_ref)]
impl OxcMinifierOptions {
#[wasm_bindgen(constructor)]
pub fn new() -> Self {
Self::default()
}
#[wasm_bindgen(getter)]
pub fn whitespace(&self) -> bool {
self.whitespace
}
#[wasm_bindgen(setter)]
pub fn set_whitespace(&mut self, yes: bool) {
self.whitespace = yes;
}
#[wasm_bindgen(getter)]
pub fn mangle(&self) -> bool {
self.mangle
}
#[wasm_bindgen(setter)]
pub fn set_mangle(&mut self, yes: bool) {
self.mangle = yes;
}
#[wasm_bindgen(getter)]
pub fn compress(&self) -> bool {
self.compress
}
#[wasm_bindgen(setter)]
pub fn set_compress(&mut self, yes: bool) {
self.compress = yes;
}
#[wasm_bindgen(getter = compressOptions)]
pub fn compress_options(&self) -> OxcCompressOptions {
self.compress_options
}
#[wasm_bindgen(setter = compressOptions)]
pub fn set_compress_options(&mut self, options: OxcCompressOptions) {
self.compress_options = options;
}
}
#[wasm_bindgen]
#[derive(Clone, Copy)]
#[derive(Debug, Clone, Deserialize, Tsify)]
#[tsify(from_wasm_abi)]
pub struct OxcCompressOptions {
booleans: bool,
drop_debugger: bool,
drop_console: bool,
evaluate: bool,
join_vars: bool,
loops: bool,
typeofs: bool,
pub booleans: bool,
pub drop_debugger: bool,
pub drop_console: bool,
pub evaluate: bool,
pub join_vars: bool,
pub loops: bool,
pub typeofs: bool,
}
// keep same with `oxc_minifier::options::CompressOptions`
@ -245,92 +96,7 @@ impl Default for OxcCompressOptions {
}
}
#[wasm_bindgen]
impl OxcCompressOptions {
#[wasm_bindgen(constructor)]
pub fn new() -> Self {
Self::default()
}
#[wasm_bindgen(getter)]
pub fn booleans(self) -> bool {
self.booleans
}
#[wasm_bindgen(setter)]
pub fn set_booleans(&mut self, yes: bool) {
self.booleans = yes;
}
#[wasm_bindgen(getter = dropDebugger)]
pub fn drop_debugger(self) -> bool {
self.drop_debugger
}
#[wasm_bindgen(setter = dropDebugger)]
pub fn set_drop_debugger(&mut self, yes: bool) {
self.drop_debugger = yes;
}
#[wasm_bindgen(getter = dropConsole)]
pub fn drop_console(self) -> bool {
self.drop_console
}
#[wasm_bindgen(setter = dropConsole)]
pub fn set_drop_console(&mut self, yes: bool) {
self.drop_console = yes;
}
#[wasm_bindgen(getter)]
pub fn evaluate(self) -> bool {
self.evaluate
}
#[wasm_bindgen(setter)]
pub fn set_evaluate(&mut self, yes: bool) {
self.evaluate = yes;
}
#[wasm_bindgen(getter = joinVars)]
pub fn join_vars(self) -> bool {
self.join_vars
}
#[wasm_bindgen(setter = joinVars)]
pub fn set_join_vars(&mut self, yes: bool) {
self.join_vars = yes;
}
#[wasm_bindgen(getter)]
pub fn loops(self) -> bool {
self.loops
}
#[wasm_bindgen(setter)]
pub fn set_loops(&mut self, yes: bool) {
self.loops = yes;
}
#[wasm_bindgen(getter)]
pub fn typeofs(self) -> bool {
self.typeofs
}
#[wasm_bindgen(setter)]
pub fn set_typeofs(&mut self, yes: bool) {
self.typeofs = yes;
}
}
#[wasm_bindgen]
#[derive(Default, Clone, Copy)]
#[derive(Debug, Default, Clone, Deserialize, Tsify)]
#[tsify(from_wasm_abi)]
#[serde(rename_all = "camelCase")]
pub struct OxcTypeCheckingOptions;
#[wasm_bindgen]
impl OxcTypeCheckingOptions {
#[wasm_bindgen(constructor)]
pub fn new() -> Self {
Self
}
}

View file

@ -9,13 +9,12 @@ use wasm_bindgen::prelude::*;
#[derive(Debug, Default, Clone, Deserialize, Tsify)]
#[tsify(from_wasm_abi)]
#[serde(rename_all = "camelCase")]
pub struct ParserOptions {
#[serde(rename = "sourceType")]
#[tsify(optional, type = "\"script\" | \"module\"")]
pub source_type: Option<String>,
/// "module" and "jsx" will be inferred from `sourceFilename`.
#[serde(rename = "sourceFilename")]
#[tsify(optional)]
pub source_filename: Option<String>,
}