mirror of
https://github.com/swc-project/swc.git
synced 2024-11-24 02:06:08 +03:00
fix(ecmascript/transforms): Fix dce (#1301)
swc_bunder: - Fix `keywords` pass. swc_ecma_codegen: - Ensure that the code generator handles unicode characters properly. (denoland/deno#8925) swc_ecma_parser: - Ensure that the parser handles unicode characters properly. (denoland/deno#8925) swc_ecma_transforms: - Fix dce.
This commit is contained in:
parent
5d88e8ba54
commit
842b6f953c
@ -8,7 +8,7 @@ edition = "2018"
|
||||
license = "Apache-2.0/MIT"
|
||||
name = "swc_bundler"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
version = "0.19.0"
|
||||
version = "0.19.1"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[features]
|
||||
@ -42,7 +42,7 @@ hex = "0.4"
|
||||
ntest = "0.7.2"
|
||||
reqwest = {version = "0.10.8", features = ["blocking"]}
|
||||
sha-1 = "0.9"
|
||||
swc_ecma_transforms = {version = "0.32.0", path = "../ecmascript/transforms", features = ["react"]}
|
||||
swc_ecma_transforms = {version = "0.32.0", path = "../ecmascript/transforms", features = ["react", "typescript"]}
|
||||
tempfile = "3.1.0"
|
||||
testing = {version = "0.10.0", path = "../testing"}
|
||||
url = "2.1.1"
|
||||
|
@ -1,4 +1,5 @@
|
||||
use super::plan::{DepType, Plan};
|
||||
use super::plan::DepType;
|
||||
use super::plan::Plan;
|
||||
use crate::bundler::chunk::export::inject_export;
|
||||
use crate::bundler::keywords::KeywordRenamer;
|
||||
use crate::{
|
||||
@ -1061,7 +1062,7 @@ where
|
||||
ModuleDecl::ExportDefaultExpr(mut export) => {
|
||||
vars.push(
|
||||
VarDeclarator {
|
||||
span: DUMMY_SP.with_ctxt(injected_ctxt),
|
||||
span: DUMMY_SP,
|
||||
name: Pat::Ident(Ident::new(
|
||||
js_word!("default"),
|
||||
DUMMY_SP.with_ctxt(info.export_ctxt()),
|
||||
|
@ -76,4 +76,22 @@ impl VisitMut for KeywordRenamer {
|
||||
n.orig = renamed;
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_class_prop(&mut self, n: &mut ClassProp) {
|
||||
if n.computed {
|
||||
n.key.visit_mut_with(self);
|
||||
}
|
||||
|
||||
n.decorators.visit_mut_with(self);
|
||||
n.value.visit_mut_with(self);
|
||||
}
|
||||
|
||||
fn visit_mut_private_prop(&mut self, n: &mut PrivateProp) {
|
||||
if n.computed {
|
||||
n.key.visit_mut_with(self);
|
||||
}
|
||||
|
||||
n.decorators.visit_mut_with(self);
|
||||
n.value.visit_mut_with(self);
|
||||
}
|
||||
}
|
||||
|
6
bundler/tests/deno-exec/.deno-8970/case1/entry.ts
Normal file
6
bundler/tests/deno-exec/.deno-8970/case1/entry.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import * as React from "https://esm.sh/react@17.0.1"
|
||||
|
||||
console.log(React)
|
||||
if (!React) {
|
||||
throw new Error()
|
||||
}
|
6
bundler/tests/deno-exec/.deno-8970/case2/entry.ts
Normal file
6
bundler/tests/deno-exec/.deno-8970/case2/entry.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import React from "https://esm.sh/react@17.0.1"
|
||||
|
||||
console.log(React)
|
||||
if (!React) {
|
||||
throw new Error()
|
||||
}
|
1
bundler/tests/deno-exec/deno-8943/deps.ts
Normal file
1
bundler/tests/deno-exec/deno-8943/deps.ts
Normal file
@ -0,0 +1 @@
|
||||
export * as flags from 'https://deno.land/std@0.83.0/flags/mod.ts';
|
3
bundler/tests/deno-exec/deno-8943/entry.ts
Normal file
3
bundler/tests/deno-exec/deno-8943/entry.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { flags } from './deps.ts';
|
||||
|
||||
console.log(flags.parse(Deno.args));
|
1
bundler/tests/deno-exec/deno-8952/entry.ts
Normal file
1
bundler/tests/deno-exec/deno-8952/entry.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from 'https://deno.land/std@0.82.0/flags/mod.ts';
|
1
bundler/tests/deno-exec/deno-8985/entry.ts
Normal file
1
bundler/tests/deno-exec/deno-8985/entry.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from 'https://deno.land/std@0.83.0/log/mod.ts';
|
8
bundler/tests/deno-exec/deno-8988/entry.ts
Normal file
8
bundler/tests/deno-exec/deno-8988/entry.ts
Normal file
@ -0,0 +1,8 @@
|
||||
class T {
|
||||
private throws: number[] = [];
|
||||
m(): void {
|
||||
console.log(this.throws.length);
|
||||
}
|
||||
}
|
||||
|
||||
new T().m();
|
@ -1,19 +1,15 @@
|
||||
const m = "test";
|
||||
if (!m) {
|
||||
throw new Error('b');
|
||||
}
|
||||
export class Comparator {
|
||||
constructor(comp1, optionsOrLoose = {
|
||||
}){
|
||||
}
|
||||
parse(comp) {
|
||||
const m1 = "another";
|
||||
if (!m1) {
|
||||
const m = "another";
|
||||
if (!m) {
|
||||
throw new TypeError("Invalid comparator: " + comp);
|
||||
}
|
||||
const m11 = m1[1];
|
||||
console.log(m11);
|
||||
if (!m1[2]) {
|
||||
const m1 = m[1];
|
||||
console.log(m1);
|
||||
if (!m[2]) {
|
||||
console.log('other');
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ const [a, b, c] = [
|
||||
3
|
||||
];
|
||||
const b1 = b;
|
||||
const b2 = b1;
|
||||
const mod = function() {
|
||||
return {
|
||||
b: b1
|
||||
|
@ -498,11 +498,8 @@ fn dneo_8541_1() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn denoo_8541_2() {
|
||||
test_from_to(
|
||||
"React.createElement('span', null, '\\u00b7');",
|
||||
"React.createElement('span', null, '\\u00b7');",
|
||||
);
|
||||
fn deno_8925() {
|
||||
assert_pretty("const 𝒫 = 2;", "const 𝒫 = 2;");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -533,6 +530,14 @@ fn test_escape_without_source() {
|
||||
es2020("\u{10ffff}", "\\u{10ffff}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deno_8541_2() {
|
||||
test_from_to(
|
||||
"React.createElement('span', null, '\\u00b7');",
|
||||
"React.createElement('span', null, '\\u00b7');",
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Buf(Arc<RwLock<Vec<u8>>>);
|
||||
impl Write for Buf {
|
||||
|
@ -0,0 +1,2 @@
|
||||
const 𝒫 = 2;
|
||||
console.log(𝒫)
|
116
ecmascript/parser/tests/typescript/deno-8925/case1/input.ts.json
Normal file
116
ecmascript/parser/tests/typescript/deno-8925/case1/input.ts.json
Normal file
@ -0,0 +1,116 @@
|
||||
{
|
||||
"type": "Script",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 33,
|
||||
"ctxt": 0
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
"type": "VariableDeclaration",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 15,
|
||||
"ctxt": 0
|
||||
},
|
||||
"kind": "const",
|
||||
"declare": false,
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"span": {
|
||||
"start": 6,
|
||||
"end": 14,
|
||||
"ctxt": 0
|
||||
},
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 6,
|
||||
"end": 10,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "𝒫",
|
||||
"typeAnnotation": null,
|
||||
"optional": false
|
||||
},
|
||||
"init": {
|
||||
"type": "NumericLiteral",
|
||||
"span": {
|
||||
"start": 13,
|
||||
"end": 14,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": 2.0
|
||||
},
|
||||
"definite": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "ExpressionStatement",
|
||||
"span": {
|
||||
"start": 16,
|
||||
"end": 33,
|
||||
"ctxt": 0
|
||||
},
|
||||
"expression": {
|
||||
"type": "CallExpression",
|
||||
"span": {
|
||||
"start": 16,
|
||||
"end": 33,
|
||||
"ctxt": 0
|
||||
},
|
||||
"callee": {
|
||||
"type": "MemberExpression",
|
||||
"span": {
|
||||
"start": 16,
|
||||
"end": 27,
|
||||
"ctxt": 0
|
||||
},
|
||||
"object": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 16,
|
||||
"end": 23,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "console",
|
||||
"typeAnnotation": null,
|
||||
"optional": false
|
||||
},
|
||||
"property": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 24,
|
||||
"end": 27,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "log",
|
||||
"typeAnnotation": null,
|
||||
"optional": false
|
||||
},
|
||||
"computed": false
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"spread": null,
|
||||
"expression": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 28,
|
||||
"end": 32,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "𝒫",
|
||||
"typeAnnotation": null,
|
||||
"optional": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"typeArguments": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"interpreter": null
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
export const 𝒫 = 2;
|
||||
console.log(𝒫)
|
124
ecmascript/parser/tests/typescript/deno-8925/case2/input.ts.json
Normal file
124
ecmascript/parser/tests/typescript/deno-8925/case2/input.ts.json
Normal file
@ -0,0 +1,124 @@
|
||||
{
|
||||
"type": "Module",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 40,
|
||||
"ctxt": 0
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
"type": "ExportDeclaration",
|
||||
"span": {
|
||||
"start": 0,
|
||||
"end": 22,
|
||||
"ctxt": 0
|
||||
},
|
||||
"declaration": {
|
||||
"type": "VariableDeclaration",
|
||||
"span": {
|
||||
"start": 7,
|
||||
"end": 22,
|
||||
"ctxt": 0
|
||||
},
|
||||
"kind": "const",
|
||||
"declare": false,
|
||||
"declarations": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"span": {
|
||||
"start": 13,
|
||||
"end": 21,
|
||||
"ctxt": 0
|
||||
},
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 13,
|
||||
"end": 17,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "𝒫",
|
||||
"typeAnnotation": null,
|
||||
"optional": false
|
||||
},
|
||||
"init": {
|
||||
"type": "NumericLiteral",
|
||||
"span": {
|
||||
"start": 20,
|
||||
"end": 21,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": 2.0
|
||||
},
|
||||
"definite": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ExpressionStatement",
|
||||
"span": {
|
||||
"start": 23,
|
||||
"end": 40,
|
||||
"ctxt": 0
|
||||
},
|
||||
"expression": {
|
||||
"type": "CallExpression",
|
||||
"span": {
|
||||
"start": 23,
|
||||
"end": 40,
|
||||
"ctxt": 0
|
||||
},
|
||||
"callee": {
|
||||
"type": "MemberExpression",
|
||||
"span": {
|
||||
"start": 23,
|
||||
"end": 34,
|
||||
"ctxt": 0
|
||||
},
|
||||
"object": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 23,
|
||||
"end": 30,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "console",
|
||||
"typeAnnotation": null,
|
||||
"optional": false
|
||||
},
|
||||
"property": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 31,
|
||||
"end": 34,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "log",
|
||||
"typeAnnotation": null,
|
||||
"optional": false
|
||||
},
|
||||
"computed": false
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"spread": null,
|
||||
"expression": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 35,
|
||||
"end": 39,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "𝒫",
|
||||
"typeAnnotation": null,
|
||||
"optional": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"typeArguments": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"interpreter": null
|
||||
}
|
@ -6,7 +6,7 @@ edition = "2018"
|
||||
license = "Apache-2.0/MIT"
|
||||
name = "swc_ecma_transforms_optimization"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
|
@ -139,6 +139,57 @@ impl Repeated for Dce<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
/// This is currently overly conservative.
|
||||
///
|
||||
/// TODO: Skip visiting key if the key of class member or property is not
|
||||
/// computed.
|
||||
macro_rules! normal {
|
||||
(
|
||||
$name:ident,
|
||||
$T:ty,
|
||||
$($singluar_props:ident),*
|
||||
) => {
|
||||
normal!($name, $T, [$($singluar_props),*], []);
|
||||
};
|
||||
|
||||
(
|
||||
$name:ident,
|
||||
$T:ty,
|
||||
[$($singluar_props:ident),*],
|
||||
[$($array_like_props:ident),*]
|
||||
) => {
|
||||
fn $name(&mut self, node: &mut $T) {
|
||||
log::trace!("Visit<{}>: marking = {}; {:?}", stringify!($T), self.marking_phase, node);
|
||||
if self.is_marked(node.span()) {
|
||||
log::trace!("Visit<{}>: Already marked", stringify!($T));
|
||||
return;
|
||||
}
|
||||
|
||||
node.visit_mut_children_with(self);
|
||||
|
||||
if self.marking_phase
|
||||
$(
|
||||
|| self.is_marked(node.$singluar_props.span())
|
||||
)*
|
||||
$(
|
||||
|| self.has_marked_elem(&node.$array_like_props)
|
||||
)*
|
||||
{
|
||||
log::trace!("Visit<{}>: Marking", stringify!($T));
|
||||
node.span = node.span.apply_mark(self.config.used_mark);
|
||||
|
||||
$(
|
||||
self.mark(&mut node.$singluar_props);
|
||||
)*
|
||||
|
||||
$(
|
||||
self.mark(&mut node.$array_like_props);
|
||||
)*
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl VisitMut for Dce<'_> {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
@ -159,19 +210,6 @@ impl VisitMut for Dce<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_class_decl(&mut self, node: &mut ClassDecl) {
|
||||
if self.is_marked(node.span()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if self.marking_phase || self.included.contains(&node.ident.to_id()) {
|
||||
node.class.span = node.class.span.apply_mark(self.config.used_mark);
|
||||
self.mark(&mut node.class);
|
||||
}
|
||||
|
||||
node.visit_mut_children_with(self)
|
||||
}
|
||||
|
||||
fn visit_mut_do_while_stmt(&mut self, node: &mut DoWhileStmt) {
|
||||
if self.is_marked(node.span) {
|
||||
return;
|
||||
@ -521,33 +559,8 @@ impl VisitMut for Dce<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_throw_stmt(&mut self, node: &mut ThrowStmt) {
|
||||
if self.is_marked(node.span) {
|
||||
return;
|
||||
}
|
||||
node.span = node.span.apply_mark(self.config.used_mark);
|
||||
|
||||
self.mark(&mut node.arg)
|
||||
}
|
||||
|
||||
fn visit_mut_try_stmt(&mut self, node: &mut TryStmt) {
|
||||
if self.is_marked(node.span) {
|
||||
return;
|
||||
}
|
||||
|
||||
node.visit_mut_children_with(self);
|
||||
|
||||
if self.is_marked(node.block.span())
|
||||
|| self.is_marked(node.handler.span())
|
||||
|| self.is_marked(node.finalizer.span())
|
||||
{
|
||||
node.span = node.span.apply_mark(self.config.used_mark);
|
||||
|
||||
self.mark(&mut node.block);
|
||||
self.mark(&mut node.handler);
|
||||
self.mark(&mut node.finalizer);
|
||||
}
|
||||
}
|
||||
normal!(visit_mut_throw_stmt, ThrowStmt, arg);
|
||||
normal!(visit_mut_try_stmt, TryStmt, block, handler, finalizer);
|
||||
|
||||
fn visit_mut_update_expr(&mut self, node: &mut UpdateExpr) {
|
||||
if self.is_marked(node.span) {
|
||||
@ -627,6 +640,24 @@ impl VisitMut for Dce<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_bin_expr(&mut self, node: &mut BinExpr) {
|
||||
if self.is_marked(node.span) {
|
||||
return;
|
||||
}
|
||||
|
||||
node.visit_mut_children_with(self);
|
||||
|
||||
if self.marking_phase
|
||||
|| self.is_marked(node.left.span())
|
||||
|| self.is_marked(node.right.span())
|
||||
{
|
||||
node.span = node.span.apply_mark(self.config.used_mark);
|
||||
|
||||
self.mark(&mut node.left);
|
||||
self.mark(&mut node.right);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_new_expr(&mut self, node: &mut NewExpr) {
|
||||
if self.is_marked(node.span) {
|
||||
return;
|
||||
@ -678,6 +709,112 @@ impl VisitMut for Dce<'_> {
|
||||
}
|
||||
self.visit_mut_stmt_like(n)
|
||||
}
|
||||
|
||||
fn visit_mut_private_name(&mut self, _: &mut PrivateName) {}
|
||||
|
||||
fn visit_mut_prop_name(&mut self, n: &mut PropName) {
|
||||
match n {
|
||||
PropName::Computed(_) => n.visit_mut_children_with(self),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_class_decl(&mut self, node: &mut ClassDecl) {
|
||||
if self.is_marked(node.span()) {
|
||||
return;
|
||||
}
|
||||
node.visit_mut_children_with(self);
|
||||
|
||||
if self.marking_phase
|
||||
|| self.included.contains(&node.ident.to_id())
|
||||
|| self.is_marked(node.ident.span())
|
||||
|| self.is_marked(node.class.span())
|
||||
{
|
||||
self.mark(&mut node.ident);
|
||||
self.mark(&mut node.class);
|
||||
}
|
||||
}
|
||||
|
||||
// ---- ---- ----- ---- -----
|
||||
// If Spanned::span is synthesized, we should some work
|
||||
|
||||
// normal!(visit_mut_assign_prop, AssignProp, key, value);
|
||||
// normal!(visit_mut_key_value_pat_prop, KeyValuePatProp, key, value);
|
||||
// normal!(visit_mut_key_value_prop, KeyValueProp, key, value);
|
||||
// fn visit_mut_spread_element(&mut self, n: &mut SpreadElement) {}
|
||||
|
||||
// ---- ---- ----- ---- -----
|
||||
// If an ast node delagates Spanned::span to a field, we don't need to handle it
|
||||
// because of the way Spanned::span works.
|
||||
|
||||
// normal!(visit_mut_class_expr, ClassExpr, ident, class);
|
||||
// normal!(visit_mut_method_prop, MethodProp, key, value);
|
||||
// normal!(
|
||||
// visit_mut_export_default_specifier,
|
||||
// ExportDefaultSpecifier,
|
||||
// exported
|
||||
// );
|
||||
// normal!(visit_mut_fn_expr, FnExpr, ident, function);
|
||||
|
||||
// ---- ---- ----- ---- -----
|
||||
// If an ast node has a span and not a declarations, use general logic.
|
||||
|
||||
normal!(visit_mut_array_lit, ArrayLit, [], [elems]);
|
||||
normal!(visit_mut_array_pat, ArrayPat, [], [elems]);
|
||||
normal!(visit_mut_arrow_expr, ArrowExpr, [body], [params]);
|
||||
normal!(visit_mut_assign_expr, AssignExpr, left, right);
|
||||
normal!(visit_mut_assign_pat, AssignPat, left, right);
|
||||
normal!(visit_mut_assign_pat_prop, AssignPatProp, key, value);
|
||||
normal!(visit_mut_await_expr, AwaitExpr, arg);
|
||||
normal!(visit_mut_catch_clause, CatchClause, param, body);
|
||||
normal!(visit_mut_class, Class, [super_class], [decorators, body]);
|
||||
normal!(visit_mut_class_method, ClassMethod, key, function);
|
||||
normal!(visit_mut_class_prop, ClassProp, [key, value], [decorators]);
|
||||
normal!(visit_mut_computed_prop_name, ComputedPropName, expr);
|
||||
normal!(visit_mut_cond_expr, CondExpr, test, cons, alt);
|
||||
normal!(visit_mut_constructor, Constructor, [key, body], [params]);
|
||||
normal!(visit_mut_decorator, Decorator, expr);
|
||||
normal!(visit_mut_export_named_specifier, ExportNamedSpecifier, orig);
|
||||
normal!(
|
||||
visit_mut_export_namespace_specifier,
|
||||
ExportNamespaceSpecifier,
|
||||
name
|
||||
);
|
||||
// normal!(visit_mut_function,Function, [body], [params, decorators]);
|
||||
normal!(visit_mut_getter_prop, GetterProp, key, body);
|
||||
normal!(
|
||||
visit_mut_import_default_specifier,
|
||||
ImportDefaultSpecifier,
|
||||
local
|
||||
);
|
||||
normal!(
|
||||
visit_mut_import_named_specifier,
|
||||
ImportNamedSpecifier,
|
||||
local
|
||||
);
|
||||
normal!(
|
||||
visit_mut_import_star_as_specifier,
|
||||
ImportStarAsSpecifier,
|
||||
local
|
||||
);
|
||||
normal!(visit_mut_object_lit, ObjectLit, [], [props]);
|
||||
normal!(visit_mut_object_pat, ObjectPat, [], [props]);
|
||||
normal!(visit_mut_opt_chain_expr, OptChainExpr, expr);
|
||||
normal!(visit_mut_param, Param, [pat], [decorators]);
|
||||
normal!(visit_mut_paren_expr, ParenExpr, expr);
|
||||
normal!(visit_mut_private_method, PrivateMethod, key, function);
|
||||
normal!(
|
||||
visit_mut_private_prop,
|
||||
PrivateProp,
|
||||
[key, value],
|
||||
[decorators]
|
||||
);
|
||||
normal!(visit_mut_rest_pat, RestPat, arg);
|
||||
normal!(visit_mut_seq_expr, SeqExpr, [], [exprs]);
|
||||
normal!(visit_mut_setter_prop, SetterProp, key, param, body);
|
||||
normal!(visit_mut_tagged_tpl, TaggedTpl, [tag], [exprs]);
|
||||
normal!(visit_mut_tpl, Tpl, [], [exprs]);
|
||||
normal!(visit_mut_yield_expr, YieldExpr, arg);
|
||||
}
|
||||
|
||||
impl Dce<'_> {
|
||||
@ -779,6 +916,13 @@ impl Dce<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_marked_elem<T>(&self, n: &[T]) -> bool
|
||||
where
|
||||
T: Spanned,
|
||||
{
|
||||
n.iter().any(|n| self.is_marked(n.span()))
|
||||
}
|
||||
|
||||
pub fn should_preserve_export(&self, i: &JsWord) -> bool {
|
||||
self.config.used.is_none()
|
||||
|| self
|
||||
@ -790,9 +934,9 @@ impl Dce<'_> {
|
||||
.any(|exported| exported.0 == *i)
|
||||
}
|
||||
|
||||
// pub fn with_child<T, F>(&mut self, op: F) -> T
|
||||
// pub fn with_child<T, F>(&mut self, op: F) -> T
|
||||
// where
|
||||
// F: for<'any> FnOnce(&mut Dce<'any>) -> T,
|
||||
// F: for<'any> FnOnce(&mut Dce<'any>) -> T,
|
||||
// {
|
||||
// let mut child = Dce {
|
||||
// changed: false,
|
||||
|
Loading…
Reference in New Issue
Block a user