mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
feat(minifier): scaffold peephole replace known methods. (#6245)
This commit is contained in:
parent
c32af57e13
commit
ee6c85003d
3 changed files with 101 additions and 4 deletions
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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')");
|
||||
}
|
||||
}
|
||||
|
|
@ -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,
|
||||
};
|
||||
|
|
@ -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(),
|
||||
];
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue