Skip to content

Commit f8cdefd

Browse files
committed
chore: simplify LiteralValue
1 parent 0fe2d19 commit f8cdefd

File tree

10 files changed

+49
-96
lines changed

10 files changed

+49
-96
lines changed

crates/jsshaker/src/analyzer/factory.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ impl<'a> Factory<'a> {
7070
pub fn new(allocator: &'a Allocator, config: &TreeShakeConfig) -> Factory<'a> {
7171
let r#true = allocator.alloc(LiteralValue::Boolean(true)).into();
7272
let r#false = allocator.alloc(LiteralValue::Boolean(false)).into();
73-
let nan = allocator.alloc(LiteralValue::NaN).into();
73+
let nan = allocator.alloc(LiteralValue::Number(f64::NAN.into())).into();
7474
let null = allocator.alloc(LiteralValue::Null).into();
7575
let undefined = allocator.alloc(LiteralValue::Undefined).into();
7676

@@ -292,8 +292,8 @@ impl<'a> Factory<'a> {
292292
}
293293
}
294294

295-
pub fn number(&self, value: impl Into<F64WithEq>, str_rep: Option<&'a Atom<'a>>) -> Entity<'a> {
296-
self.alloc(LiteralValue::Number(value.into(), str_rep)).into()
295+
pub fn number(&self, value: impl Into<F64WithEq>) -> Entity<'a> {
296+
self.alloc(LiteralValue::Number(value.into())).into()
297297
}
298298
pub fn big_int(&self, value: &'a Atom<'a>) -> Entity<'a> {
299299
self.alloc(LiteralValue::BigInt(value)).into()
@@ -306,10 +306,6 @@ impl<'a> Factory<'a> {
306306
if let Some(value) = value { self.boolean(value) } else { self.unknown_boolean }
307307
}
308308

309-
pub fn infinity(&self, positivie: bool) -> Entity<'a> {
310-
self.alloc(LiteralValue::Infinity(positivie)).into()
311-
}
312-
313309
pub fn symbol(&self, id: SymbolId, str_rep: &'a Atom<'a>) -> Entity<'a> {
314310
self.alloc(LiteralValue::Symbol(id, str_rep)).into()
315311
}

crates/jsshaker/src/analyzer/operations.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ impl<'a> Analyzer<'a> {
111111
pub fn op_lt(&self, lhs: Entity<'a>, rhs: Entity<'a>, eq: bool) -> Option<bool> {
112112
fn literal_lt(lhs: LiteralValue, rhs: LiteralValue, eq: bool) -> Option<bool> {
113113
match (lhs, rhs) {
114-
(LiteralValue::Number(l, _), LiteralValue::Number(r, _)) => {
114+
(LiteralValue::Number(l), LiteralValue::Number(r)) => {
115115
Some(if eq { l.0 <= r.0 } else { l.0 < r.0 })
116116
}
117117
(LiteralValue::String(l, _), LiteralValue::String(r, _)) => {
@@ -215,7 +215,7 @@ impl<'a> Analyzer<'a> {
215215
(Some(l), Some(r)) => match (l, r) {
216216
(Some(l), Some(r)) => {
217217
let val = l.0 + r.0;
218-
values.push(self.factory.number(val, None));
218+
values.push(self.factory.number(val));
219219
}
220220
_ => {
221221
values.push(self.factory.nan);
@@ -265,8 +265,7 @@ impl<'a> Analyzer<'a> {
265265
self.factory.computed(
266266
if let (Some(l), Some(r)) = (lhs.get_literal(self), rhs.get_literal(self)) {
267267
match (l, r) {
268-
(LiteralValue::Number(l, _), LiteralValue::Number(r, _)) => calc(l.0, r.0),
269-
(LiteralValue::NaN, _) | (_, LiteralValue::NaN) => self.factory.nan,
268+
(LiteralValue::Number(l), LiteralValue::Number(r)) => calc(l.0, r.0),
270269
_ => self.factory.unknown_primitive,
271270
}
272271
} else {
@@ -278,11 +277,10 @@ impl<'a> Analyzer<'a> {
278277

279278
pub fn op_update(&self, input: Entity<'a>, operator: UpdateOperator) -> Entity<'a> {
280279
let apply_update = |v: f64| {
281-
let val = match operator {
280+
self.factory.number(match operator {
282281
UpdateOperator::Increment => v + 1.0,
283282
UpdateOperator::Decrement => v - 1.0,
284-
};
285-
self.factory.number(val, None)
283+
})
286284
};
287285

288286
if let Some(num) = input.get_literal(self).and_then(|lit| lit.to_number()) {
@@ -362,7 +360,7 @@ impl<'a> Analyzer<'a> {
362360
BinaryOperator::Exponential => l.powf(r),
363361
_ => unreachable!(),
364362
};
365-
if value.is_nan() { factory.nan } else { factory.number(value, None) }
363+
if value.is_nan() { factory.nan } else { factory.number(value) }
366364
}),
367365

368366
BinaryOperator::ShiftLeft
@@ -387,7 +385,7 @@ impl<'a> Analyzer<'a> {
387385
}
388386
_ => unreachable!(),
389387
};
390-
factory.number(value, None)
388+
factory.number(value)
391389
})
392390
}
393391

@@ -401,7 +399,7 @@ impl<'a> Analyzer<'a> {
401399
BinaryOperator::BitwiseAnd => l & r,
402400
_ => unreachable!(),
403401
};
404-
factory.number(f64::from(value), None)
402+
factory.number(f64::from(value))
405403
}),
406404

407405
BinaryOperator::In => factory.computed_unknown_boolean((lhs, rhs)),

crates/jsshaker/src/builtins/globals/array_constructor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ impl<'a> Builtins<'a> {
4444

4545
for (i, element) in elements.into_iter().enumerate() {
4646
let element = if no_map_fn != Some(true) {
47-
let index = analyzer.factory.number(i as f64, None);
47+
let index = analyzer.factory.number(i as f64);
4848
let args = analyzer.factory.arguments(analyzer.allocator.alloc([element, index]), None);
4949
let mapped = map_fn.call(analyzer, dep, this_arg, args);
5050
if no_map_fn == Some(false) { mapped } else { analyzer.factory.union((element, mapped)) }

crates/jsshaker/src/builtins/globals/constants.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ impl Builtins<'_> {
77
init_map!(self.globals, {
88
// Value properties
99
"undefined" => factory.undefined,
10-
"Infinity" => factory.infinity(true),
10+
"Infinity" => factory.number(f64::INFINITY),
1111
"NaN" => factory.nan,
1212
"globalThis" => factory.unknown,
1313

crates/jsshaker/src/nodes/expr/literals.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ impl<'a> Analyzer<'a> {
1414
if node.base == NumberBase::Float {
1515
self.factory.unknown_number
1616
} else {
17-
self.factory.number(node.value, None)
17+
self.factory.number(node.value)
1818
}
1919
}
2020

crates/jsshaker/src/nodes/expr/unary_expression.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ impl<'a> Analyzer<'a> {
5151
if let Some(num) = argument.get_literal(self).and_then(|lit| lit.to_number()) {
5252
if let Some(num) = num {
5353
let num = -num.0;
54-
self.factory.number(num, None)
54+
self.factory.number(num)
5555
} else {
5656
self.factory.nan
5757
}
@@ -74,11 +74,10 @@ impl<'a> Analyzer<'a> {
7474
if let Some(literals) = argument.get_to_numeric(self).get_to_literals(self) {
7575
self.factory.union(allocator::Vec::from_iter_in(
7676
literals.into_iter().map(|lit| match lit {
77-
LiteralValue::Number(num, _) => {
77+
LiteralValue::Number(num) => {
7878
let num = !num.0.to_int_32();
79-
self.factory.number(num as f64, None)
79+
self.factory.number(num as f64)
8080
}
81-
LiteralValue::NaN => self.factory.number(-1f64, None),
8281
_ => self.factory.unknown_primitive,
8382
}),
8483
self.allocator,

crates/jsshaker/src/value/array.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ impl<'a> ValueTrait<'a> for ArrayValue<'a> {
9292
} else if key == "length" {
9393
result.push(self.get_length().map_or_else(
9494
|| analyzer.factory.computed_unknown_number(&self.rest),
95-
|length| analyzer.factory.number(length as f64, None),
95+
|length| analyzer.factory.number(length as f64),
9696
));
9797
} else if let Some(property) = analyzer.builtins.prototypes.array.get_keyed(
9898
analyzer,

crates/jsshaker/src/value/literal/mod.rs

Lines changed: 28 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,10 @@ use crate::{
3030
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
3131
pub enum LiteralValue<'a> {
3232
String(&'a Atom<'a>, Option<MangleAtom>),
33-
Number(F64WithEq, Option<&'a Atom<'a>>),
33+
Number(F64WithEq),
3434
BigInt(&'a Atom<'a>),
3535
Boolean(bool),
3636
Symbol(SymbolId, &'a Atom<'a>),
37-
Infinity(bool),
38-
NaN,
3937
Null,
4038
Undefined,
4139
}
@@ -191,21 +189,18 @@ impl<'a> ValueTrait<'a> for LiteralValue<'a> {
191189

192190
fn get_to_numeric(&'a self, analyzer: &Analyzer<'a>) -> Entity<'a> {
193191
match self {
194-
LiteralValue::Number(_, _)
195-
| LiteralValue::BigInt(_)
196-
| LiteralValue::NaN
197-
| LiteralValue::Infinity(_) => self.into(),
192+
LiteralValue::Number(_) | LiteralValue::BigInt(_) => self.into(),
198193
LiteralValue::Boolean(value) => {
199194
if *value {
200-
analyzer.factory.number(1.0, Some(builtin_atom!("1")))
195+
analyzer.factory.number(1.0)
201196
} else {
202-
analyzer.factory.number(0.0, Some(builtin_atom!("0")))
197+
analyzer.factory.number(0.0)
203198
}
204199
}
205200
LiteralValue::String(str, atom) => {
206201
analyzer.factory.computed(str.get_to_numeric(analyzer), *atom)
207202
}
208-
LiteralValue::Null => analyzer.factory.number(0.0, Some(builtin_atom!("0"))),
203+
LiteralValue::Null => analyzer.factory.number(0.0),
209204
LiteralValue::Symbol(_, _) => {
210205
// TODO: warn: TypeError: Cannot convert a Symbol value to a number
211206
analyzer.factory.unknown
@@ -254,12 +249,10 @@ impl<'a> ValueTrait<'a> for LiteralValue<'a> {
254249
fn test_typeof(&self) -> TypeofResult {
255250
match self {
256251
LiteralValue::String(_, _) => TypeofResult::String,
257-
LiteralValue::Number(_, _) => TypeofResult::Number,
252+
LiteralValue::Number(_) => TypeofResult::Number,
258253
LiteralValue::BigInt(_) => TypeofResult::BigInt,
259254
LiteralValue::Boolean(_) => TypeofResult::Boolean,
260255
LiteralValue::Symbol(_, _) => TypeofResult::Symbol,
261-
LiteralValue::Infinity(_) => TypeofResult::Number,
262-
LiteralValue::NaN => TypeofResult::Number,
263256
LiteralValue::Null => TypeofResult::Object,
264257
LiteralValue::Undefined => TypeofResult::Undefined,
265258
}
@@ -268,12 +261,11 @@ impl<'a> ValueTrait<'a> for LiteralValue<'a> {
268261
fn test_truthy(&self) -> Option<bool> {
269262
Some(match self {
270263
LiteralValue::String(value, _) => !value.is_empty(),
271-
LiteralValue::Number(value, _) => *value != 0.0.into() && *value != (-0.0).into(),
264+
LiteralValue::Number(value) => *value != 0.0.into() && *value != (-0.0).into(),
272265
LiteralValue::BigInt(value) => !value.chars().all(|c| c == '0'),
273266
LiteralValue::Boolean(value) => *value,
274267
LiteralValue::Symbol(_, _) => true,
275-
LiteralValue::Infinity(_) => true,
276-
LiteralValue::NaN | LiteralValue::Null | LiteralValue::Undefined => false,
268+
LiteralValue::Null | LiteralValue::Undefined => false,
277269
})
278270
}
279271

@@ -304,10 +296,15 @@ impl<'a> LiteralValue<'a> {
304296
let mangled = atom.and_then(|a| mangler.resolve(a)).unwrap_or(value);
305297
ast.expression_string_literal(span, mangled, None)
306298
}
307-
LiteralValue::Number(value, raw) => {
299+
LiteralValue::Number(value) => {
308300
let negated = value.0.is_sign_negative();
309-
let absolute =
310-
ast.expression_numeric_literal(span, value.0.abs(), raw.copied(), NumberBase::Decimal);
301+
let absolute = if value.0.is_infinite() {
302+
ast.expression_identifier(span, "Infinity")
303+
} else if value.0.is_nan() {
304+
ast.expression_identifier(span, "NaN")
305+
} else {
306+
ast.expression_numeric_literal(span, value.0.abs(), None, NumberBase::Decimal)
307+
};
311308
if negated {
312309
ast.expression_unary(span, UnaryOperator::UnaryNegation, absolute)
313310
} else {
@@ -319,18 +316,6 @@ impl<'a> LiteralValue<'a> {
319316
}
320317
LiteralValue::Boolean(value) => ast.expression_boolean_literal(span, *value),
321318
LiteralValue::Symbol(_, _) => unreachable!("Cannot build expression for Symbol"),
322-
LiteralValue::Infinity(positive) => {
323-
if *positive {
324-
ast.expression_identifier(span, "Infinity")
325-
} else {
326-
ast.expression_unary(
327-
span,
328-
UnaryOperator::UnaryNegation,
329-
ast.expression_identifier(span, "Infinity"),
330-
)
331-
}
332-
}
333-
LiteralValue::NaN => ast.expression_identifier(span, "NaN"),
334319
LiteralValue::Null => ast.expression_null_literal(span),
335320
LiteralValue::Undefined => ast.expression_unary(
336321
span,
@@ -344,16 +329,15 @@ impl<'a> LiteralValue<'a> {
344329
let config = &analyzer.config;
345330
match self {
346331
LiteralValue::String(value, _) => value.len() <= config.max_simple_string_length,
347-
LiteralValue::Number(value, _) => {
348-
value.0.fract() == 0.0
349-
&& config.min_simple_number_value <= (value.0 as i64)
350-
&& (value.0 as i64) <= config.max_simple_number_value
332+
LiteralValue::Number(value) => {
333+
!value.0.is_finite()
334+
|| (value.0.fract() == 0.0
335+
&& config.min_simple_number_value <= (value.0 as i64)
336+
&& (value.0 as i64) <= config.max_simple_number_value)
351337
}
352338
LiteralValue::BigInt(_) => false,
353339
LiteralValue::Boolean(_) => true,
354340
LiteralValue::Symbol(_, _) => false,
355-
LiteralValue::Infinity(_) => true,
356-
LiteralValue::NaN => true,
357341
LiteralValue::Null => true,
358342
LiteralValue::Undefined => true,
359343
}
@@ -362,9 +346,7 @@ impl<'a> LiteralValue<'a> {
362346
pub fn to_string(self, allocator: &'a Allocator) -> &'a Atom<'a> {
363347
match self {
364348
LiteralValue::String(value, _) => value,
365-
LiteralValue::Number(value, str_rep) => {
366-
str_rep.unwrap_or_else(|| value.0.to_js_string().to_atom_ref(allocator))
367-
}
349+
LiteralValue::Number(value) => value.0.to_js_string().to_atom_ref(allocator),
368350
LiteralValue::BigInt(value) => value,
369351
LiteralValue::Boolean(value) => {
370352
if value {
@@ -374,14 +356,6 @@ impl<'a> LiteralValue<'a> {
374356
}
375357
}
376358
LiteralValue::Symbol(_, str_rep) => str_rep,
377-
LiteralValue::Infinity(positive) => {
378-
if positive {
379-
builtin_atom!("Infinity")
380-
} else {
381-
builtin_atom!("-Infinity")
382-
}
383-
}
384-
LiteralValue::NaN => builtin_atom!("NaN"),
385359
LiteralValue::Null => builtin_atom!("null"),
386360
LiteralValue::Undefined => builtin_atom!("undefined"),
387361
}
@@ -390,7 +364,7 @@ impl<'a> LiteralValue<'a> {
390364
// `None` for unresolvable, `Some(None)` for NaN, `Some(Some(value))` for number
391365
pub fn to_number(self) -> Option<Option<F64WithEq>> {
392366
match self {
393-
LiteralValue::Number(value, _) => Some(Some(value)),
367+
LiteralValue::Number(value) => Some(Some(value)),
394368
LiteralValue::BigInt(_value) => {
395369
// TODO: warn: TypeError: Cannot convert a BigInt value to a number
396370
None
@@ -405,34 +379,27 @@ impl<'a> LiteralValue<'a> {
405379
// TODO: warn: TypeError: Cannot convert a Symbol value to a number
406380
None
407381
}
408-
LiteralValue::NaN | LiteralValue::Undefined => Some(None),
409-
LiteralValue::Infinity(_) => None,
382+
LiteralValue::Undefined => Some(None),
410383
}
411384
}
412385

413386
fn get_prototype(&self, analyzer: &mut Analyzer<'a>) -> &'a BuiltinPrototype<'a> {
414387
match self {
415388
LiteralValue::String(_, _) => &analyzer.builtins.prototypes.string,
416-
LiteralValue::Number(_, _) => &analyzer.builtins.prototypes.number,
389+
LiteralValue::Number(_) => &analyzer.builtins.prototypes.number,
417390
LiteralValue::BigInt(_) => &analyzer.builtins.prototypes.bigint,
418391
LiteralValue::Boolean(_) => &analyzer.builtins.prototypes.boolean,
419392
LiteralValue::Symbol(_, _) => &analyzer.builtins.prototypes.symbol,
420-
LiteralValue::Infinity(_) => &analyzer.builtins.prototypes.number,
421-
LiteralValue::NaN => &analyzer.builtins.prototypes.number,
422393
LiteralValue::Null | LiteralValue::Undefined => {
423394
unreachable!("Cannot get prototype of null or undefined")
424395
}
425396
}
426397
}
427398

428399
pub fn strict_eq(self, other: LiteralValue, object_is: bool) -> (bool, Option<MangleConstraint>) {
429-
// 0.0 === -0.0
430-
if !object_is && let (LiteralValue::Number(l, _), LiteralValue::Number(r, _)) = (self, other) {
431-
let eq = if l == 0.0.into() || l == (-0.0).into() {
432-
r == 0.0.into() || r == (-0.0).into()
433-
} else {
434-
l == r
435-
};
400+
if let (LiteralValue::Number(l), LiteralValue::Number(r)) = (self, other) {
401+
// 0.0 === -0.0
402+
let eq = if object_is { l == r } else { l.0 == r.0 };
436403
return (eq, None);
437404
}
438405

@@ -445,10 +412,6 @@ impl<'a> LiteralValue<'a> {
445412
return (false, None);
446413
}
447414

448-
if !object_is && self == LiteralValue::NaN {
449-
return (false, None);
450-
}
451-
452415
(true, None)
453416
}
454417
}

crates/jsshaker/src/value/literal/string.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ impl<'a> ValueTrait<'a> for Atom<'a> {
159159
fn get_to_numeric(&'a self, analyzer: &Analyzer<'a>) -> Entity<'a> {
160160
let value = self.as_str();
161161
let val = value.trim().string_to_number();
162-
if val.is_nan() { analyzer.factory.nan } else { analyzer.factory.number(val, None) }
162+
if val.is_nan() { analyzer.factory.nan } else { analyzer.factory.number(val) }
163163
}
164164

165165
fn get_to_boolean(&'a self, analyzer: &Analyzer<'a>) -> Entity<'a> {
@@ -210,7 +210,7 @@ fn get_known_instance_property<'a>(
210210
) -> Option<Entity<'a>> {
211211
let LiteralValue::String(key, _) = key else { return None };
212212
if key == "length" {
213-
Some(analyzer.factory.number(value.len() as f64, None))
213+
Some(analyzer.factory.number(value.len() as f64))
214214
} else {
215215
let index = key.as_str().string_to_number();
216216
if index.is_finite() {

0 commit comments

Comments
 (0)