Skip to content

Commit

Permalink
feat(minifier): constant fold 'x'.toString() and true.toString() (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Boshen authored Jan 4, 2025
1 parent fd5af73 commit f73dc9e
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
4 changes: 4 additions & 0 deletions crates/oxc_ecmascript/src/constant_evaluation/value_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ impl ValueType {
pub fn is_object(self) -> bool {
self == Self::Object
}

pub fn is_undetermined(self) -> bool {
self == Self::Undetermined
}
}

/// `get_known_value_type`
Expand Down
32 changes: 31 additions & 1 deletion crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use oxc_ast::ast::*;
use oxc_ecmascript::{
constant_evaluation::{ConstantEvaluation, ConstantValue, ValueType},
side_effects::MayHaveSideEffects,
ToJsString,
};
use oxc_span::{GetSpan, SPAN};
use oxc_syntax::{
Expand Down Expand Up @@ -35,7 +36,8 @@ impl<'a> Traverse<'a> for PeepholeFoldConstants {
Expression::StaticMemberExpression(e) => Self::try_fold_static_member_expr(e, ctx),
Expression::LogicalExpression(e) => Self::try_fold_logical_expr(e, ctx),
Expression::ChainExpression(e) => Self::try_fold_optional_chain(e, ctx),
Expression::CallExpression(e) => Self::try_fold_number_constructor(e, ctx),
Expression::CallExpression(e) => Self::try_fold_number_constructor(e, ctx)
.or_else(|| Self::try_fold_to_string(e, ctx)),
_ => None,
} {
*expr = folded_expr;
Expand Down Expand Up @@ -601,6 +603,26 @@ impl<'a, 'b> PeepholeFoldConstants {
}),
))
}

fn try_fold_to_string(e: &CallExpression<'a>, ctx: Ctx<'a, 'b>) -> Option<Expression<'a>> {
let Expression::StaticMemberExpression(member_expr) = &e.callee else { return None };
if member_expr.property.name != "toString" {
return None;
}
if !e.arguments.is_empty() {
return None;
}
let object = &member_expr.object;
if !matches!(
ValueType::from(object),
ValueType::String | ValueType::Boolean | ValueType::Number
) {
return None;
}
object
.to_js_string()
.map(|value| ctx.ast.expression_string_literal(object.span(), value, None))
}
}

/// <https://github.com/google/closure-compiler/blob/v20240609/test/com/google/javascript/jscomp/PeepholeFoldConstantsTest.java>
Expand Down Expand Up @@ -1733,4 +1755,12 @@ mod test {
test("Number('1')", "1");
test_same("var Number; Number(1)");
}

#[test]
fn test_fold_to_string() {
test("'x'.toString()", "'x'");
test("1 .toString()", "'1'");
test("true.toString()", "'true'");
test("false.toString()", "'false'");
}
}

0 comments on commit f73dc9e

Please sign in to comment.