@@ -56,6 +56,45 @@ fn can_compress_new_regexp(args: Option<&[ExprOrSpread]>) -> bool {
56
56
}
57
57
}
58
58
59
+ fn collect_exprs_from_object ( obj : & mut ObjectLit ) -> Vec < Box < Expr > > {
60
+ let mut exprs = Vec :: new ( ) ;
61
+
62
+ for prop in obj. props . take ( ) {
63
+ if let PropOrSpread :: Prop ( p) = prop {
64
+ match * p {
65
+ Prop :: Shorthand ( p) => {
66
+ exprs. push ( p. into ( ) ) ;
67
+ }
68
+ Prop :: KeyValue ( p) => {
69
+ if let PropName :: Computed ( e) = p. key {
70
+ exprs. push ( e. expr ) ;
71
+ }
72
+
73
+ exprs. push ( p. value ) ;
74
+ }
75
+ Prop :: Getter ( p) => {
76
+ if let PropName :: Computed ( e) = p. key {
77
+ exprs. push ( e. expr ) ;
78
+ }
79
+ }
80
+ Prop :: Setter ( p) => {
81
+ if let PropName :: Computed ( e) = p. key {
82
+ exprs. push ( e. expr ) ;
83
+ }
84
+ }
85
+ Prop :: Method ( p) => {
86
+ if let PropName :: Computed ( e) = p. key {
87
+ exprs. push ( e. expr ) ;
88
+ }
89
+ }
90
+ _ => { }
91
+ }
92
+ }
93
+ }
94
+
95
+ exprs
96
+ }
97
+
59
98
impl Pure < ' _ > {
60
99
/// `foo(...[1, 2])`` => `foo(1, 2)`
61
100
pub ( super ) fn eval_spread_array ( & mut self , args : & mut Vec < ExprOrSpread > ) {
@@ -1417,39 +1456,8 @@ impl Pure<'_> {
1417
1456
}
1418
1457
1419
1458
Expr :: Object ( obj) => {
1420
- if obj. props . iter ( ) . all ( |p| match p {
1421
- PropOrSpread :: Spread ( _) => false ,
1422
- PropOrSpread :: Prop ( p) => matches ! (
1423
- & * * p,
1424
- Prop :: Shorthand ( _) | Prop :: KeyValue ( _) | Prop :: Method ( ..)
1425
- ) ,
1426
- } ) {
1427
- let mut exprs = Vec :: new ( ) ;
1428
-
1429
- for prop in obj. props . take ( ) {
1430
- if let PropOrSpread :: Prop ( p) = prop {
1431
- match * p {
1432
- Prop :: Shorthand ( p) => {
1433
- exprs. push ( p. into ( ) ) ;
1434
- }
1435
- Prop :: KeyValue ( p) => {
1436
- if let PropName :: Computed ( e) = p. key {
1437
- exprs. push ( e. expr ) ;
1438
- }
1439
-
1440
- exprs. push ( p. value ) ;
1441
- }
1442
- Prop :: Method ( p) => {
1443
- if let PropName :: Computed ( e) = p. key {
1444
- exprs. push ( e. expr ) ;
1445
- }
1446
- }
1447
-
1448
- _ => unreachable ! ( ) ,
1449
- }
1450
- }
1451
- }
1452
-
1459
+ if obj. props . iter ( ) . all ( |prop| !prop. is_spread ( ) ) {
1460
+ let exprs = collect_exprs_from_object ( obj) ;
1453
1461
* e = self
1454
1462
. make_ignored_expr ( obj. span , exprs. into_iter ( ) )
1455
1463
. unwrap_or ( Invalid { span : DUMMY_SP } . into ( ) ) ;
@@ -1542,22 +1550,34 @@ impl Pure<'_> {
1542
1550
obj,
1543
1551
prop : MemberProp :: Computed ( prop) ,
1544
1552
..
1545
- } ) => match & * * obj {
1546
- Expr :: Object ( ..) | Expr :: Array ( ..) => {
1553
+ } ) => match obj. as_mut ( ) {
1554
+ Expr :: Object ( object) => {
1555
+ // Accessing getters and setters may cause side effect
1556
+ // More precision is possible if comparing the lit prop names
1557
+ if object. props . iter ( ) . all ( |p| match p {
1558
+ PropOrSpread :: Spread ( ..) => false ,
1559
+ PropOrSpread :: Prop ( p) => match & * * p {
1560
+ Prop :: Getter ( ..) | Prop :: Setter ( ..) => false ,
1561
+ _ => true ,
1562
+ } ,
1563
+ } ) {
1564
+ let mut exprs = collect_exprs_from_object ( object) ;
1565
+ exprs. push ( prop. expr . take ( ) ) ;
1566
+ * e = self
1567
+ . make_ignored_expr ( * span, exprs. into_iter ( ) )
1568
+ . unwrap_or ( Invalid { span : DUMMY_SP } . into ( ) ) ;
1569
+ return ;
1570
+ }
1571
+ }
1572
+ Expr :: Array ( ..) => {
1547
1573
self . ignore_return_value ( obj, opts) ;
1548
-
1549
- match & * * obj {
1550
- Expr :: Object ( ..) => { }
1551
- _ => {
1552
- * e = self
1553
- . make_ignored_expr (
1554
- * span,
1555
- vec ! [ obj. take( ) , prop. expr. take( ) ] . into_iter ( ) ,
1556
- )
1557
- . unwrap_or ( Invalid { span : DUMMY_SP } . into ( ) ) ;
1558
- return ;
1559
- }
1560
- } ;
1574
+ * e = self
1575
+ . make_ignored_expr (
1576
+ * span,
1577
+ vec ! [ obj. take( ) , prop. expr. take( ) ] . into_iter ( ) ,
1578
+ )
1579
+ . unwrap_or ( Invalid { span : DUMMY_SP } . into ( ) ) ;
1580
+ return ;
1561
1581
}
1562
1582
_ => { }
1563
1583
} ,
0 commit comments