Skip to content

Commit

Permalink
feat(minifier): scaffold peephole replace known methods. (#6245)
Browse files Browse the repository at this point in the history
  • Loading branch information
7086cmd committed Oct 2, 2024
1 parent 2c99d2a commit 2a89dfd
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 4 deletions.
2 changes: 2 additions & 0 deletions crates/oxc_minifier/src/ast_passes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ mod exploit_assigns;
mod peephole_fold_constants;
mod peephole_minimize_conditions;
mod peephole_remove_dead_code;
mod peephole_replace_known_methods;
mod peephole_substitute_alternate_syntax;
mod remove_syntax;
mod statement_fusion;
Expand All @@ -12,6 +13,7 @@ pub use exploit_assigns::ExploitAssigns;
pub use peephole_fold_constants::PeepholeFoldConstants;
pub use peephole_minimize_conditions::PeepholeMinimizeConditions;
pub use peephole_remove_dead_code::PeepholeRemoveDeadCode;
pub use peephole_replace_known_methods::PeepholeReplaceKnownMethods;
pub use peephole_substitute_alternate_syntax::PeepholeSubstituteAlternateSyntax;
pub use remove_syntax::RemoveSyntax;
pub use statement_fusion::StatementFusion;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
use oxc_ast::ast::*;
use oxc_traverse::{Traverse, TraverseCtx};

use crate::CompressorPass;

/// Minimize With Known Methods
/// <https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/PeepholeMinimizeReplacements.java>
pub struct PeepholeReplaceKnownMethods {
changed: bool,
}

impl<'a> CompressorPass<'a> for PeepholeReplaceKnownMethods {
fn changed(&self) -> bool {
self.changed
}

fn build(&mut self, _program: &mut Program<'a>, _ctx: &mut TraverseCtx<'a>) {
self.changed = false;
// oxc_traverse::walk_program(self, program, ctx);
}
}

impl<'a> Traverse<'a> for PeepholeReplaceKnownMethods {}

impl PeepholeReplaceKnownMethods {
pub fn new() -> Self {
Self { changed: false }
}
}

/// <https://github.com/google/closure-compiler/blob/master/test/com/google/javascript/jscomp/PeepholeReplaceKnownMethodsTest.java>
#[cfg(test)]
mod test {
use oxc_allocator::Allocator;

use crate::tester;

fn test(source_text: &str, positive: &str) {
let allocator = Allocator::default();
let mut pass = super::PeepholeReplaceKnownMethods::new();
tester::test(&allocator, source_text, positive, &mut pass);
}

fn test_same(source_text: &str) {
test(source_text, source_text);
}

fn fold_same(js: &str) {
test_same(js);
}

fn fold(js: &str, expected: &str) {
test(js, expected);
}

#[test]
#[ignore]
fn test_string_index_of() {
fold("x = 'abcdef'.indexOf('g')", "x = -1");
fold("x = 'abcdef'.indexOf('b')", "x = 1");
fold("x = 'abcdefbe'.indexOf('b', 2)", "x = 6");
fold("x = 'abcdef'.indexOf('bcd')", "x = 1");
fold("x = 'abcdefsdfasdfbcdassd'.indexOf('bcd', 4)", "x = 13");

fold("x = 'abcdef'.lastIndexOf('b')", "x = 1");
fold("x = 'abcdefbe'.lastIndexOf('b')", "x = 6");
fold("x = 'abcdefbe'.lastIndexOf('b', 5)", "x = 1");

// Both elements must be strings. Don't do anything if either one is not
// string.
fold("x = 'abc1def'.indexOf(1)", "x = 3");
fold("x = 'abcNaNdef'.indexOf(NaN)", "x = 3");
fold("x = 'abcundefineddef'.indexOf(undefined)", "x = 3");
fold("x = 'abcnulldef'.indexOf(null)", "x = 3");
fold("x = 'abctruedef'.indexOf(true)", "x = 3");

// The following test case fails with JSC_PARSE_ERROR. Hence omitted.
// fold_same("x = 1.indexOf('bcd');");
fold_same("x = NaN.indexOf('bcd')");
fold_same("x = undefined.indexOf('bcd')");
fold_same("x = null.indexOf('bcd')");
fold_same("x = true.indexOf('bcd')");
fold_same("x = false.indexOf('bcd')");

// Avoid dealing with regex or other types.
fold_same("x = 'abcdef'.indexOf(/b./)");
fold_same("x = 'abcdef'.indexOf({a:2})");
fold_same("x = 'abcdef'.indexOf([1,2])");

// Template Strings
fold_same("x = `abcdef`.indexOf('b')");
fold_same("x = `Hello ${name}`.indexOf('a')");
fold_same("x = tag `Hello ${name}`.indexOf('a')");
}
}
8 changes: 4 additions & 4 deletions crates/oxc_minifier/src/compressor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use oxc_traverse::TraverseCtx;
use crate::{
ast_passes::{
CollapseVariableDeclarations, ExploitAssigns, PeepholeFoldConstants,
PeepholeMinimizeConditions, PeepholeRemoveDeadCode, PeepholeSubstituteAlternateSyntax,
RemoveSyntax, StatementFusion,
PeepholeMinimizeConditions, PeepholeRemoveDeadCode, PeepholeReplaceKnownMethods,
PeepholeSubstituteAlternateSyntax, RemoveSyntax, StatementFusion,
},
CompressOptions, CompressorPass,
};
Expand Down Expand Up @@ -46,13 +46,13 @@ impl<'a> Compressor<'a> {
CollapseVariableDeclarations::new(self.options).build(program, &mut ctx);

// See `latePeepholeOptimizations`
let mut passes: [&mut dyn CompressorPass; 5] = [
let mut passes: [&mut dyn CompressorPass; 6] = [
&mut StatementFusion::new(),
&mut PeepholeRemoveDeadCode::new(),
// TODO: MinimizeExitPoints
&mut PeepholeMinimizeConditions::new(),
&mut PeepholeSubstituteAlternateSyntax::new(self.options),
// TODO: PeepholeReplaceKnownMethods
&mut PeepholeReplaceKnownMethods::new(),
&mut PeepholeFoldConstants::new(),
];

Expand Down

0 comments on commit 2a89dfd

Please sign in to comment.