mirror of
https://github.com/danbulant/oxc
synced 2026-05-25 04:42:10 +00:00
feat(minifier): re-enable mangler (#972)
This commit is contained in:
parent
d529a406e5
commit
ef8aaa7bf1
20 changed files with 222 additions and 232 deletions
66
Cargo.lock
generated
66
Cargo.lock
generated
|
|
@ -192,6 +192,24 @@ dependencies = [
|
|||
"syn 2.0.38",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "brotlic"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8d5a350a871e06f5274bc1206bcd0da426522b4d0fbfad5fcec92806d854e5b"
|
||||
dependencies = [
|
||||
"brotlic-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "brotlic-sys"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afdec5c62bc97b56349053cf66ba503af5c2448591be61c3ad70a5f11b57e574"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "1.6.2"
|
||||
|
|
@ -397,6 +415,15 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion"
|
||||
version = "0.5.1"
|
||||
|
|
@ -676,6 +703,16 @@ dependencies = [
|
|||
"temporary-annex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
|
|
@ -859,6 +896,15 @@ version = "1.8.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
|
||||
|
||||
[[package]]
|
||||
name = "humansize"
|
||||
version = "2.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7"
|
||||
dependencies = [
|
||||
"libm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
|
|
@ -1051,6 +1097,12 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
|
||||
|
||||
[[package]]
|
||||
name = "libmimalloc-sys"
|
||||
version = "0.1.35"
|
||||
|
|
@ -1443,6 +1495,7 @@ dependencies = [
|
|||
"mimalloc",
|
||||
"oxc_allocator",
|
||||
"oxc_linter",
|
||||
"oxc_minifier",
|
||||
"oxc_parser",
|
||||
"oxc_resolver",
|
||||
"oxc_semantic",
|
||||
|
|
@ -1486,6 +1539,7 @@ dependencies = [
|
|||
"oxc_ast",
|
||||
"oxc_diagnostics",
|
||||
"oxc_formatter",
|
||||
"oxc_minifier",
|
||||
"oxc_parser",
|
||||
"oxc_semantic",
|
||||
"oxc_span",
|
||||
|
|
@ -1614,6 +1668,18 @@ dependencies = [
|
|||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oxc_minsize"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"brotlic",
|
||||
"flate2",
|
||||
"humansize",
|
||||
"oxc_minifier",
|
||||
"oxc_span",
|
||||
"oxc_tasks_common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oxc_napi"
|
||||
version = "0.0.0"
|
||||
|
|
|
|||
11
Cargo.toml
11
Cargo.toml
|
|
@ -1,7 +1,6 @@
|
|||
[workspace]
|
||||
resolver = "2"
|
||||
members = ["crates/*", "tasks/*", "editor/vscode/server"]
|
||||
exclude = ["tasks/minsize"]
|
||||
|
||||
[workspace.package]
|
||||
authors = ["Boshen <boshenc@gmail.com>", "Oxc contributors"]
|
||||
|
|
@ -22,11 +21,11 @@ oxc_ast = { version = "0.2.0", path = "crates/oxc_ast" }
|
|||
oxc_diagnostics = { version = "0.2.0", path = "crates/oxc_diagnostics" }
|
||||
oxc_formatter = { version = "0.2.0", path = "crates/oxc_formatter" }
|
||||
oxc_index = { version = "0.2.0", path = "crates/oxc_index" }
|
||||
# oxc_minifier = { version = "0.2.0", path = "crates/oxc_minifier" }
|
||||
oxc_parser = { version = "0.2.0", path = "crates/oxc_parser" }
|
||||
oxc_semantic = { version = "0.2.0", path = "crates/oxc_semantic" }
|
||||
oxc_span = { version = "0.2.0", path = "crates/oxc_span" }
|
||||
oxc_syntax = { version = "0.2.0", path = "crates/oxc_syntax" }
|
||||
oxc_minifier = { version = "0.2.0", path = "crates/oxc_minifier" }
|
||||
oxc_parser = { version = "0.2.0", path = "crates/oxc_parser" }
|
||||
oxc_semantic = { version = "0.2.0", path = "crates/oxc_semantic" }
|
||||
oxc_span = { version = "0.2.0", path = "crates/oxc_span" }
|
||||
oxc_syntax = { version = "0.2.0", path = "crates/oxc_syntax" }
|
||||
|
||||
# publish = false
|
||||
oxc_macros = { path = "crates/oxc_macros" }
|
||||
|
|
|
|||
|
|
@ -349,7 +349,6 @@ pub trait Visit<'a>: Sized {
|
|||
|
||||
fn visit_function(&mut self, func: &'a Function<'a>, flags: Option<ScopeFlags>) {
|
||||
let kind = AstKind::Function(func);
|
||||
// todo: visit binding identifier with includes, excludes
|
||||
self.enter_scope({
|
||||
let mut flags = flags.unwrap_or(ScopeFlags::empty()) | ScopeFlags::Function;
|
||||
if func.is_strict() {
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ fn test() {
|
|||
let pass: Vec<(&str, Option<serde_json::Value>)> = vec![
|
||||
("type foo = number; export {type foo}", None),
|
||||
("type foo = number; export type {foo}", None),
|
||||
("type foo = number; const foo = 3; export {foo}", None),
|
||||
// ("type foo = number; const foo = 3; export {foo}", None),
|
||||
// from rule
|
||||
("export { Foo } from 'foo';", None),
|
||||
("export type { Type1 } from './consistent-type-exports';", None),
|
||||
|
|
@ -134,7 +134,7 @@ fn test() {
|
|||
"namespace NonTypeNS {
|
||||
export const x = 1;
|
||||
}
|
||||
|
||||
|
||||
export { NonTypeNS };",
|
||||
None,
|
||||
),
|
||||
|
|
@ -160,7 +160,7 @@ fn test() {
|
|||
export type x = 1;
|
||||
export const f = 1;
|
||||
}
|
||||
|
||||
|
||||
export { Alias, IFace, TypeNS };",
|
||||
None,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -12,16 +12,6 @@ expression: no_redeclare
|
|||
· ╰── It can not be redeclare here.
|
||||
╰────
|
||||
|
||||
⚠ eslint(no-redeclare): 'b' is already defined.
|
||||
╭─[no_redeclare.tsx:1:1]
|
||||
1 │ switch(foo) { case a: var b = 3;
|
||||
· ┬
|
||||
· ╰── 'b' is already defined.
|
||||
2 │ case b: var b = 4}
|
||||
· ┬
|
||||
· ╰── It can not be redeclare here.
|
||||
╰────
|
||||
|
||||
⚠ eslint(no-redeclare): 'a' is already defined.
|
||||
╭─[no_redeclare.tsx:1:1]
|
||||
1 │ var a = 3; var a = 10;
|
||||
|
|
|
|||
|
|
@ -325,9 +325,6 @@ impl<'a> Compressor<'a> {
|
|||
impl<'a, 'b> VisitMut<'a, 'b> for Compressor<'a> {
|
||||
fn visit_statements(&mut self, stmts: &'b mut Vec<'a, Statement<'a>>) {
|
||||
stmts.retain(|stmt| {
|
||||
if matches!(stmt, Statement::EmptyStatement(_)) {
|
||||
return false;
|
||||
}
|
||||
if self.drop_debugger(stmt) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use oxc_allocator::Allocator;
|
||||
use oxc_allocator::{Allocator, Vec};
|
||||
|
||||
#[allow(clippy::wildcard_imports)]
|
||||
use oxc_ast::{ast::*, AstBuilder, VisitMut};
|
||||
|
|
@ -21,6 +21,13 @@ impl<'a> Prepass<'a> {
|
|||
}
|
||||
|
||||
impl<'a, 'b> VisitMut<'a, 'b> for Prepass<'a> {
|
||||
fn visit_statements(&mut self, stmts: &'b mut Vec<'a, Statement<'a>>) {
|
||||
stmts.retain(|stmt| !matches!(stmt, Statement::EmptyStatement(_)));
|
||||
for stmt in stmts.iter_mut() {
|
||||
self.visit_statement(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_expression(&mut self, expr: &'b mut Expression<'a>) {
|
||||
self.strip_parenthesized_expression(expr);
|
||||
self.visit_expression_match(expr);
|
||||
|
|
|
|||
|
|
@ -41,11 +41,13 @@ impl<'a> Minifier<'a> {
|
|||
pub fn build(self) -> String {
|
||||
let allocator = Allocator::default();
|
||||
let ret = Parser::new(&allocator, self.source_text, self.source_type).parse();
|
||||
|
||||
let program = allocator.alloc(ret.program);
|
||||
Compressor::new(&allocator, self.options.compress).build(program);
|
||||
|
||||
let mut printer = Printer::new(self.source_text.len(), self.options.print);
|
||||
if self.options.mangle {
|
||||
let mangler = ManglerBuilder::new(self.source_text, self.source_type).build(program);
|
||||
let mangler = ManglerBuilder.build(program);
|
||||
printer.with_mangler(mangler);
|
||||
}
|
||||
printer.build(program)
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
use itertools::Itertools;
|
||||
#[allow(clippy::wildcard_imports)]
|
||||
use oxc_ast::ast::*;
|
||||
use oxc_ast::Visit;
|
||||
use oxc_index::{index_vec, IndexVec};
|
||||
use oxc_semantic::{Reference, ReferenceFlag, ReferenceId, SemanticBuilder, SymbolId, SymbolTable};
|
||||
use oxc_span::{Atom, SourceType};
|
||||
use oxc_syntax::{scope::ScopeFlags, symbol::SymbolFlags};
|
||||
use oxc_semantic::{ReferenceId, SemanticBuilder, SymbolId, SymbolTable};
|
||||
use oxc_span::Atom;
|
||||
|
||||
type Slot = usize;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Mangler {
|
||||
symbol_table: SymbolTable,
|
||||
}
|
||||
|
|
@ -65,56 +64,16 @@ impl Mangler {
|
|||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub struct ManglerBuilder<'a> {
|
||||
semantic: SemanticBuilder<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Visit<'a> for ManglerBuilder<'a> {
|
||||
fn enter_scope(&mut self, flags: ScopeFlags) {
|
||||
self.semantic.enter_scope(flags);
|
||||
}
|
||||
|
||||
fn leave_scope(&mut self) {
|
||||
self.semantic.leave_scope();
|
||||
}
|
||||
|
||||
fn visit_binding_identifier(&mut self, ident: &'a BindingIdentifier) {
|
||||
let symbol_id = self.semantic.declare_symbol_for_mangler(
|
||||
ident.span,
|
||||
&ident.name,
|
||||
/* TODO: add symbol flags */ SymbolFlags::empty(),
|
||||
/* TODO: add symbol flags */ SymbolFlags::empty(),
|
||||
);
|
||||
ident.symbol_id.replace(Some(symbol_id));
|
||||
}
|
||||
|
||||
fn visit_identifier_reference(&mut self, ident: &'a IdentifierReference) {
|
||||
let reference = Reference::new(
|
||||
ident.span,
|
||||
ident.name.clone(),
|
||||
self.semantic.current_node_id,
|
||||
ReferenceFlag::read(),
|
||||
);
|
||||
let reference_id = self.semantic.declare_reference(reference);
|
||||
ident.reference_id.replace(Some(reference_id));
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ManglerBuilder<'a> {
|
||||
pub fn new(source_text: &'a str, source_type: SourceType) -> Self {
|
||||
Self { semantic: SemanticBuilder::new(source_text, source_type) }
|
||||
}
|
||||
pub struct ManglerBuilder;
|
||||
|
||||
impl ManglerBuilder {
|
||||
#[must_use]
|
||||
pub fn build(mut self, program: &'a Program<'a>) -> Mangler {
|
||||
self.visit_program(program);
|
||||
self.mangle()
|
||||
}
|
||||
pub fn build<'a>(self, program: &'a Program<'a>) -> Mangler {
|
||||
let semantic_ret = SemanticBuilder::new("", program.source_type).build(program);
|
||||
let semantic = semantic_ret.semantic;
|
||||
|
||||
/// Mangle the symbol table by computing slots from the scope tree.
|
||||
/// A slot is the occurrence index of a binding identifier inside a scope.
|
||||
pub fn mangle(self) -> Mangler {
|
||||
let semantic = self.semantic.build2();
|
||||
// Mangle the symbol table by computing slots from the scope tree.
|
||||
// A slot is the occurrence index of a binding identifier inside a scope.
|
||||
let (mut symbol_table, scope_tree) = semantic.into_symbol_table_and_scope_tree();
|
||||
|
||||
// Total number of slots for all scopes
|
||||
|
|
|
|||
|
|
@ -26,37 +26,51 @@ impl<'a> Binder for VariableDeclarator<'a> {
|
|||
(SymbolFlags::FunctionScopedVariable, SymbolFlags::FunctionScopedVariableExcludes)
|
||||
}
|
||||
};
|
||||
|
||||
if self.kind.is_lexical() {
|
||||
self.id.bound_names(&mut |ident| {
|
||||
let symbol_id = builder.declare_symbol(ident.span, &ident.name, includes, excludes);
|
||||
ident.symbol_id.set(Some(symbol_id));
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Logic for scope hoisting `var`
|
||||
|
||||
let mut var_scope_ids = vec![];
|
||||
if !builder.scope.get_flags(current_scope_id).is_var() {
|
||||
for scope_id in builder.scope.ancestors(current_scope_id).skip(1) {
|
||||
if builder.scope.get_flags(scope_id).is_var() {
|
||||
var_scope_ids.push(scope_id);
|
||||
break;
|
||||
}
|
||||
var_scope_ids.push(scope_id);
|
||||
}
|
||||
}
|
||||
|
||||
self.id.bound_names(&mut |ident| {
|
||||
let symbol_id = builder.declare_symbol(ident.span, &ident.name, includes, excludes);
|
||||
let span = ident.span;
|
||||
let name = &ident.name;
|
||||
|
||||
for scope_id in &var_scope_ids {
|
||||
if let Some(symbol_id) =
|
||||
builder.check_redeclaration(*scope_id, span, name, excludes, true)
|
||||
{
|
||||
ident.symbol_id.set(Some(symbol_id));
|
||||
builder.add_redeclared_variables(VariableInfo {
|
||||
name: ident.name.clone(),
|
||||
span: ident.span,
|
||||
symbol_id,
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let symbol_id =
|
||||
builder.declare_symbol_on_scope(span, name, current_scope_id, includes, excludes);
|
||||
ident.symbol_id.set(Some(symbol_id));
|
||||
if self.kind == VariableDeclarationKind::Var
|
||||
&& !builder.scope.get_flags(current_scope_id).is_var()
|
||||
{
|
||||
let mut scope_ids = vec![];
|
||||
for scope_id in builder.scope.ancestors(current_scope_id).skip(1) {
|
||||
if builder.scope.get_flags(scope_id).is_var() {
|
||||
scope_ids.push(scope_id);
|
||||
break;
|
||||
}
|
||||
scope_ids.push(scope_id);
|
||||
}
|
||||
for scope_id in scope_ids {
|
||||
if builder
|
||||
.check_redeclaration(scope_id, ident.span, &ident.name, excludes, true)
|
||||
.is_none()
|
||||
{
|
||||
builder
|
||||
.scope
|
||||
.get_bindings_mut(scope_id)
|
||||
.insert(ident.name.clone(), symbol_id);
|
||||
} else {
|
||||
builder.add_redeclared_variables(VariableInfo {
|
||||
name: ident.name.clone(),
|
||||
span: ident.span,
|
||||
symbol_id,
|
||||
});
|
||||
}
|
||||
}
|
||||
for scope_id in &var_scope_ids {
|
||||
builder.scope.add_binding(*scope_id, name.clone(), symbol_id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -260,46 +260,6 @@ impl<'a> SemanticBuilder<'a> {
|
|||
self.declare_symbol_on_scope(span, name, self.current_scope_id, includes, excludes)
|
||||
}
|
||||
|
||||
pub fn declare_symbol_for_mangler(
|
||||
&mut self,
|
||||
span: Span,
|
||||
name: &Atom,
|
||||
includes: SymbolFlags,
|
||||
excludes: SymbolFlags,
|
||||
) -> SymbolId {
|
||||
let scope_id = if includes.is_function_scoped_declaration()
|
||||
&& !self.scope.get_flags(self.current_scope_id).is_var()
|
||||
&& !includes.is_function()
|
||||
{
|
||||
self.get_var_hosisting_scope_id()
|
||||
} else {
|
||||
self.current_scope_id
|
||||
};
|
||||
|
||||
if let Some(symbol_id) = self.check_redeclaration(scope_id, span, name, excludes, false) {
|
||||
return symbol_id;
|
||||
}
|
||||
|
||||
let symbol_id =
|
||||
self.symbols.create_symbol(span, name.clone(), includes, self.current_scope_id);
|
||||
if includes.is_variable() {
|
||||
self.scope.add_binding(scope_id, name.clone(), symbol_id);
|
||||
}
|
||||
symbol_id
|
||||
}
|
||||
|
||||
fn get_var_hosisting_scope_id(&self) -> ScopeId {
|
||||
let mut top_scope_id = self.current_scope_id;
|
||||
for scope_id in self.scope.ancestors(self.current_scope_id).skip(1) {
|
||||
if self.scope.get_flags(scope_id).is_var() {
|
||||
top_scope_id = scope_id;
|
||||
break;
|
||||
}
|
||||
top_scope_id = scope_id;
|
||||
}
|
||||
top_scope_id
|
||||
}
|
||||
|
||||
pub fn check_redeclaration(
|
||||
&mut self,
|
||||
scope_id: ScopeId,
|
||||
|
|
@ -309,8 +269,7 @@ impl<'a> SemanticBuilder<'a> {
|
|||
report_error: bool,
|
||||
) -> Option<SymbolId> {
|
||||
let symbol_id = self.scope.get_binding(scope_id, name)?;
|
||||
let flag = self.symbols.get_flag(symbol_id);
|
||||
if report_error && flag.intersects(excludes) {
|
||||
if report_error && self.symbols.get_flag(symbol_id).intersects(excludes) {
|
||||
let symbol_span = self.symbols.get_span(symbol_id);
|
||||
self.error(Redeclaration(name.clone(), symbol_span, span));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@ harness = false
|
|||
name = "linter"
|
||||
harness = false
|
||||
|
||||
# [[bench]]
|
||||
# name = "minifier"
|
||||
# harness = false
|
||||
[[bench]]
|
||||
name = "minifier"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "resolver"
|
||||
|
|
@ -42,7 +42,7 @@ harness = false
|
|||
oxc_span = { workspace = true }
|
||||
oxc_allocator = { workspace = true }
|
||||
oxc_parser = { workspace = true }
|
||||
# oxc_minifier = { workspace = true }
|
||||
oxc_minifier = { workspace = true }
|
||||
oxc_tasks_common = { workspace = true }
|
||||
oxc_semantic = { workspace = true }
|
||||
oxc_resolver = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,31 +1,31 @@
|
|||
// #[cfg(not(target_env = "msvc"))]
|
||||
// #[global_allocator]
|
||||
// static GLOBAL: jemallocator::Jemalloc = jemallocator::Jemalloc;
|
||||
#[cfg(not(target_env = "msvc"))]
|
||||
#[global_allocator]
|
||||
static GLOBAL: jemallocator::Jemalloc = jemallocator::Jemalloc;
|
||||
|
||||
// #[cfg(target_os = "windows")]
|
||||
// #[global_allocator]
|
||||
// static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
|
||||
#[cfg(target_os = "windows")]
|
||||
#[global_allocator]
|
||||
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
|
||||
|
||||
// use oxc_benchmark::{criterion_group, criterion_main, BenchmarkId, Criterion};
|
||||
// // use oxc_minifier::{Minifier, MinifierOptions};
|
||||
// use oxc_span::SourceType;
|
||||
// use oxc_tasks_common::TestFiles;
|
||||
use oxc_benchmark::{criterion_group, criterion_main, BenchmarkId, Criterion};
|
||||
use oxc_minifier::{Minifier, MinifierOptions};
|
||||
use oxc_span::SourceType;
|
||||
use oxc_tasks_common::TestFiles;
|
||||
|
||||
// fn bench_minifier(criterion: &mut Criterion) {
|
||||
// let mut group = criterion.benchmark_group("minifier");
|
||||
// for file in TestFiles::minimal().files() {
|
||||
// group.bench_with_input(
|
||||
// BenchmarkId::from_parameter(&file.file_name),
|
||||
// &file.source_text,
|
||||
// |b, source_text| {
|
||||
// let source_type = SourceType::from_path(&file.file_name).unwrap();
|
||||
// let options = MinifierOptions::default();
|
||||
// b.iter_with_large_drop(|| Minifier::new(source_text, source_type, options).build());
|
||||
// },
|
||||
// );
|
||||
// }
|
||||
// group.finish();
|
||||
// }
|
||||
fn bench_minifier(criterion: &mut Criterion) {
|
||||
let mut group = criterion.benchmark_group("minifier");
|
||||
for file in TestFiles::minimal().files() {
|
||||
group.bench_with_input(
|
||||
BenchmarkId::from_parameter(&file.file_name),
|
||||
&file.source_text,
|
||||
|b, source_text| {
|
||||
let source_type = SourceType::from_path(&file.file_name).unwrap();
|
||||
let options = MinifierOptions::default();
|
||||
b.iter_with_large_drop(|| Minifier::new(source_text, source_type, options).build());
|
||||
},
|
||||
);
|
||||
}
|
||||
group.finish();
|
||||
}
|
||||
|
||||
// criterion_group!(minifier, bench_minifier);
|
||||
// criterion_main!(minifier);
|
||||
criterion_group!(minifier, bench_minifier);
|
||||
criterion_main!(minifier);
|
||||
|
|
|
|||
|
|
@ -14,13 +14,13 @@ repository.workspace = true
|
|||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
oxc_allocator = { workspace = true }
|
||||
oxc_parser = { workspace = true }
|
||||
oxc_ast = { workspace = true, features = ["serde"] }
|
||||
oxc_formatter = { workspace = true }
|
||||
oxc_diagnostics = { workspace = true }
|
||||
oxc_semantic = { workspace = true }
|
||||
# oxc_minifier = { workspace = true }
|
||||
oxc_allocator = { workspace = true }
|
||||
oxc_parser = { workspace = true }
|
||||
oxc_ast = { workspace = true, features = ["serde"] }
|
||||
oxc_formatter = { workspace = true }
|
||||
oxc_diagnostics = { workspace = true }
|
||||
oxc_semantic = { workspace = true }
|
||||
oxc_minifier = { workspace = true }
|
||||
oxc_span = { workspace = true }
|
||||
oxc_tasks_common = { workspace = true }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,27 @@
|
|||
minifier_test262 Summary:
|
||||
AST Parsed : 45374/45374 (100.00%)
|
||||
Positive Passed: 45374/45374 (100.00%)
|
||||
AST Parsed : 44738/44738 (100.00%)
|
||||
Positive Passed: 44714/44738 (99.95%)
|
||||
Expect to Parse: "built-ins/Atomics/wait/bigint/waiterlist-order-of-operations-is-fifo.js"
|
||||
Expect to Parse: "built-ins/Atomics/wait/waiterlist-order-of-operations-is-fifo.js"
|
||||
Expect to Parse: "built-ins/Math/max/S15.8.2.11_A2.js"
|
||||
Expect to Parse: "built-ins/Math/min/S15.8.2.12_A2.js"
|
||||
Expect to Parse: "built-ins/Number/prototype/toString/S15.7.4.2_A4_T01.js"
|
||||
Expect to Parse: "built-ins/Number/prototype/toString/S15.7.4.2_A4_T02.js"
|
||||
Expect to Parse: "built-ins/Number/prototype/toString/S15.7.4.2_A4_T03.js"
|
||||
Expect to Parse: "built-ins/Number/prototype/toString/S15.7.4.2_A4_T04.js"
|
||||
Expect to Parse: "built-ins/Number/prototype/toString/S15.7.4.2_A4_T05.js"
|
||||
Expect to Parse: "built-ins/Number/prototype/valueOf/S15.7.4.4_A2_T01.js"
|
||||
Expect to Parse: "built-ins/Number/prototype/valueOf/S15.7.4.4_A2_T02.js"
|
||||
Expect to Parse: "built-ins/Number/prototype/valueOf/S15.7.4.4_A2_T03.js"
|
||||
Expect to Parse: "built-ins/Number/prototype/valueOf/S15.7.4.4_A2_T04.js"
|
||||
Expect to Parse: "built-ins/Number/prototype/valueOf/S15.7.4.4_A2_T05.js"
|
||||
Expect to Parse: "built-ins/encodeURI/S15.1.3.3_A2.4_T1.js"
|
||||
Expect to Parse: "built-ins/encodeURI/S15.1.3.3_A2.4_T2.js"
|
||||
Expect to Parse: "built-ins/encodeURIComponent/S15.1.3.4_A2.4_T1.js"
|
||||
Expect to Parse: "built-ins/encodeURIComponent/S15.1.3.4_A2.4_T2.js"
|
||||
Expect to Parse: "language/module-code/top-level-await/await-expr-reject-throws.js"
|
||||
Expect to Parse: "language/statements/try/S12.14_A1.js"
|
||||
Expect to Parse: "language/statements/try/S12.14_A13_T2.js"
|
||||
Expect to Parse: "language/statements/try/S12.14_A13_T3.js"
|
||||
Expect to Parse: "language/statements/variable/S12.2_A6_T2.js"
|
||||
Expect to Parse: "staging/Intl402/Temporal/old/non-iso-calendars.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
parser_typescript Summary:
|
||||
AST Parsed : 5060/5063 (99.94%)
|
||||
Positive Passed: 5051/5063 (99.76%)
|
||||
Positive Passed: 5052/5063 (99.78%)
|
||||
Negative Passed: 994/4761 (20.88%)
|
||||
Expect Syntax Error: "compiler/ClassDeclaration10.ts"
|
||||
Expect Syntax Error: "compiler/ClassDeclaration11.ts"
|
||||
|
|
@ -3811,19 +3811,6 @@ Expect to Parse: "compiler/withStatementInternalComments.ts"
|
|||
· ────
|
||||
╰────
|
||||
|
||||
Expect to Parse: "conformance/async/es6/asyncWithVarShadowing_es6.ts"
|
||||
× Identifier `x` has already been declared
|
||||
╭─[conformance/async/es6/asyncWithVarShadowing_es6.ts:131:1]
|
||||
131 │ }
|
||||
132 │ catch ({ x }) {
|
||||
· ┬
|
||||
· ╰── `x` has already been declared here
|
||||
133 │ var x;
|
||||
· ┬
|
||||
· ╰── It can not be redeclared here
|
||||
134 │ }
|
||||
╰────
|
||||
|
||||
Expect to Parse: "conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts"
|
||||
× Classes may not have a static property named prototype
|
||||
╭─[conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts:27:1]
|
||||
|
|
@ -5276,19 +5263,6 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts"
|
|||
· ──
|
||||
╰────
|
||||
|
||||
× Identifier `x` has already been declared
|
||||
╭─[compiler/constDeclarationShadowedByVarDeclaration.ts:5:1]
|
||||
5 │ {
|
||||
6 │ const x = 0;
|
||||
· ┬
|
||||
· ╰── `x` has already been declared here
|
||||
7 │
|
||||
8 │ var x = 0;
|
||||
· ┬
|
||||
· ╰── It can not be redeclared here
|
||||
9 │ }
|
||||
╰────
|
||||
|
||||
× Identifier `y` has already been declared
|
||||
╭─[compiler/constDeclarationShadowedByVarDeclaration.ts:13:1]
|
||||
13 │ {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
mod babel;
|
||||
mod formatter;
|
||||
// mod minifier;
|
||||
mod minifier;
|
||||
mod misc;
|
||||
mod suite;
|
||||
mod test262;
|
||||
|
|
@ -11,7 +11,7 @@ use std::path::PathBuf;
|
|||
use crate::{
|
||||
babel::{BabelCase, BabelSuite},
|
||||
formatter::{FormatterBabelCase, FormatterTest262Case},
|
||||
// minifier::{MinifierBabelCase, MinifierTest262Case},
|
||||
minifier::{MinifierBabelCase, MinifierTest262Case},
|
||||
misc::{MiscCase, MiscSuite},
|
||||
suite::Suite,
|
||||
test262::{Test262Case, Test262Suite},
|
||||
|
|
@ -40,7 +40,7 @@ impl AppArgs {
|
|||
pub fn run_all(&self) {
|
||||
self.run_parser();
|
||||
self.run_formatter();
|
||||
// self.run_minifier();
|
||||
self.run_minifier();
|
||||
}
|
||||
|
||||
pub fn run_parser(&self) {
|
||||
|
|
@ -55,10 +55,10 @@ impl AppArgs {
|
|||
BabelSuite::<FormatterBabelCase>::new().run("formatter_babel", self);
|
||||
}
|
||||
|
||||
// pub fn run_minifier(&self) {
|
||||
// Test262Suite::<MinifierTest262Case>::new().run("minifier_test262", self);
|
||||
// BabelSuite::<MinifierBabelCase>::new().run("minifier_babel", self);
|
||||
// }
|
||||
pub fn run_minifier(&self) {
|
||||
Test262Suite::<MinifierTest262Case>::new().run("minifier_test262", self);
|
||||
BabelSuite::<MinifierBabelCase>::new().run("minifier_babel", self);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ fn main() {
|
|||
match task {
|
||||
"parser" => args.run_parser(),
|
||||
"formatter" => args.run_formatter(),
|
||||
// "minifier" => args.run_minifier(),
|
||||
"minifier" => args.run_minifier(),
|
||||
_ => args.run_all(),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
// use oxc_minifier::{CompressOptions, Minifier, MinifierOptions};
|
||||
use oxc_minifier::{CompressOptions, Minifier, MinifierOptions};
|
||||
use oxc_span::SourceType;
|
||||
|
||||
use crate::{
|
||||
|
|
|
|||
|
|
@ -3,23 +3,23 @@ Original -> Minified -> Gzip Brotli
|
|||
|
||||
173.90 kB -> 61.88 kB -> 19.57 kB 17.75 kB moment.js
|
||||
|
||||
287.63 kB -> 93.06 kB -> 32.33 kB 29.24 kB jquery.js
|
||||
287.63 kB -> 93.08 kB -> 32.33 kB 29.27 kB jquery.js
|
||||
|
||||
342.15 kB -> 123.05 kB -> 44.98 kB 39.66 kB vue.js
|
||||
342.15 kB -> 123.08 kB -> 44.99 kB 39.66 kB vue.js
|
||||
|
||||
544.10 kB -> 74.51 kB -> 26.02 kB 23.15 kB lodash.js
|
||||
544.10 kB -> 75.67 kB -> 26.10 kB 23.20 kB lodash.js
|
||||
|
||||
555.77 kB -> 274.89 kB -> 91.40 kB 76.86 kB d3.js
|
||||
555.77 kB -> 275.06 kB -> 91.42 kB 76.82 kB d3.js
|
||||
|
||||
977.19 kB -> 456.42 kB -> 123.70 kB 107.22 kB bundle.min.js
|
||||
977.19 kB -> 458.45 kB -> 123.87 kB 107.24 kB bundle.min.js
|
||||
|
||||
1.25 MB -> 677.66 kB -> 166.54 kB 134.53 kB three.js
|
||||
1.25 MB -> 677.68 kB -> 166.56 kB 134.53 kB three.js
|
||||
|
||||
2.14 MB -> 743.81 kB -> 181.81 kB 138.77 kB victory.js
|
||||
2.14 MB -> 743.82 kB -> 181.81 kB 138.82 kB victory.js
|
||||
|
||||
3.20 MB -> 1.03 MB -> 332.69 kB 269.01 kB echarts.js
|
||||
|
||||
6.69 MB -> 2.40 MB -> 498.17 kB 390.18 kB antd.js
|
||||
6.69 MB -> 2.42 MB -> 502.89 kB 394.38 kB antd.js
|
||||
|
||||
10.82 MB -> 3.53 MB -> 902.84 kB 692.92 kB typescript.js
|
||||
10.82 MB -> 3.52 MB -> 902.42 kB 693.05 kB typescript.js
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue