mirror of
https://github.com/swc-project/swc.git
synced 2024-12-26 23:27:56 +03:00
feat(es/resolver): Use different syntax context for unresolved refs (#4436)
- We don't need a list of bindings to check if an identifier is unresolved. - Checking if an identifier is unresolved is now one CPU instruction. - Previously it was one hashmap operation. - This PR also improves performance, by removing the hashmaps mentioned above.
This commit is contained in:
parent
1d90d6e726
commit
53610fdafc
@ -10,7 +10,7 @@ use swc::config::{Config, IsModule, JscConfig, Options, SourceMapsConfig};
|
||||
use swc_common::{errors::Handler, FileName, FilePathMapping, Mark, SourceFile, SourceMap};
|
||||
use swc_ecma_ast::{EsVersion, Program};
|
||||
use swc_ecma_parser::{Syntax, TsConfig};
|
||||
use swc_ecma_transforms::{fixer, hygiene, resolver, resolver_with_mark, typescript};
|
||||
use swc_ecma_transforms::{fixer, hygiene, resolver, typescript};
|
||||
use swc_ecma_visit::FoldWith;
|
||||
|
||||
static SOURCE: &str = include_str!("assets/Observable.ts");
|
||||
@ -45,10 +45,12 @@ fn parse(c: &swc::Compiler) -> (Arc<SourceFile>, Program) {
|
||||
|
||||
fn as_es(c: &swc::Compiler) -> Program {
|
||||
let program = parse(c).1;
|
||||
let mark = Mark::fresh(Mark::root());
|
||||
let unresolved_mark = Mark::new();
|
||||
let top_level_mark = Mark::new();
|
||||
|
||||
program
|
||||
.fold_with(&mut resolver_with_mark(mark))
|
||||
.fold_with(&mut typescript::strip(mark))
|
||||
.fold_with(&mut resolver(unresolved_mark, top_level_mark, true))
|
||||
.fold_with(&mut typescript::strip(top_level_mark))
|
||||
}
|
||||
|
||||
fn base_tr_group(c: &mut Criterion) {
|
||||
@ -83,7 +85,7 @@ fn base_tr_resolver_and_hygiene(b: &mut Bencher) {
|
||||
black_box(c.run_transform(&handler, true, || {
|
||||
module
|
||||
.clone()
|
||||
.fold_with(&mut resolver())
|
||||
.fold_with(&mut resolver(Mark::new(), Mark::new(), false))
|
||||
.fold_with(&mut hygiene())
|
||||
}))
|
||||
});
|
||||
|
@ -31,8 +31,12 @@ pub struct PassBuilder<'a, 'b, P: swc_ecma_visit::Fold> {
|
||||
handler: &'b Handler,
|
||||
env: Option<swc_ecma_preset_env::Config>,
|
||||
pass: P,
|
||||
/// [Mark] for top level bindings and unresolved identifier references.
|
||||
/// [Mark] for top level bindings .
|
||||
top_level_mark: Mark,
|
||||
|
||||
/// [Mark] for unresolved refernces.
|
||||
unresolved_mark: Mark,
|
||||
|
||||
target: EsVersion,
|
||||
loose: bool,
|
||||
assumptions: Assumptions,
|
||||
@ -50,6 +54,7 @@ impl<'a, 'b, P: swc_ecma_visit::Fold> PassBuilder<'a, 'b, P> {
|
||||
loose: bool,
|
||||
assumptions: Assumptions,
|
||||
top_level_mark: Mark,
|
||||
unresolved_mark: Mark,
|
||||
pass: P,
|
||||
) -> Self {
|
||||
PassBuilder {
|
||||
@ -58,6 +63,7 @@ impl<'a, 'b, P: swc_ecma_visit::Fold> PassBuilder<'a, 'b, P> {
|
||||
env: None,
|
||||
pass,
|
||||
top_level_mark,
|
||||
unresolved_mark,
|
||||
target: EsVersion::Es5,
|
||||
loose,
|
||||
assumptions,
|
||||
@ -80,6 +86,7 @@ impl<'a, 'b, P: swc_ecma_visit::Fold> PassBuilder<'a, 'b, P> {
|
||||
env: self.env,
|
||||
pass,
|
||||
top_level_mark: self.top_level_mark,
|
||||
unresolved_mark: self.unresolved_mark,
|
||||
target: self.target,
|
||||
loose: self.loose,
|
||||
assumptions: self.assumptions,
|
||||
@ -318,6 +325,7 @@ impl<'a, 'b, P: swc_ecma_visit::Fold> PassBuilder<'a, 'b, P> {
|
||||
options: self.minify,
|
||||
cm: self.cm.clone(),
|
||||
comments: comments.cloned(),
|
||||
unresolved_mark: self.unresolved_mark,
|
||||
top_level_mark: self.top_level_mark,
|
||||
}),
|
||||
Optional::new(
|
||||
@ -333,6 +341,7 @@ struct MinifierPass {
|
||||
options: Option<JsMinifyOptions>,
|
||||
cm: Lrc<SourceMap>,
|
||||
comments: Option<SingleThreadedComments>,
|
||||
unresolved_mark: Mark,
|
||||
top_level_mark: Mark,
|
||||
}
|
||||
|
||||
@ -368,6 +377,7 @@ impl VisitMut for MinifierPass {
|
||||
None,
|
||||
&opts,
|
||||
&swc_ecma_minifier::option::ExtraOptions {
|
||||
unresolved_mark: self.unresolved_mark,
|
||||
top_level_mark: self.top_level_mark,
|
||||
},
|
||||
)
|
||||
|
@ -53,9 +53,7 @@ use swc_ecma_transforms::{
|
||||
optimization::{const_modules, json_parse, simplifier},
|
||||
pass::{noop, Optional},
|
||||
proposals::{decorators, export_default_from, import_assertions},
|
||||
react,
|
||||
resolver::ts_resolver,
|
||||
resolver_with_mark,
|
||||
react, resolver,
|
||||
typescript::{self, TSEnumConfig},
|
||||
Assumptions,
|
||||
};
|
||||
@ -166,7 +164,7 @@ pub struct Options {
|
||||
pub disable_fixer: bool,
|
||||
|
||||
#[serde(skip_deserializing, default)]
|
||||
pub global_mark: Option<Mark>,
|
||||
pub top_level_mark: Option<Mark>,
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[serde(default = "default_cwd")]
|
||||
@ -310,9 +308,8 @@ impl Options {
|
||||
}
|
||||
});
|
||||
|
||||
let top_level_mark = self
|
||||
.global_mark
|
||||
.unwrap_or_else(|| Mark::fresh(Mark::root()));
|
||||
let unresolved_mark = Mark::new();
|
||||
let top_level_mark = self.top_level_mark.unwrap_or_else(Mark::new);
|
||||
|
||||
let es_version = target.unwrap_or_default();
|
||||
|
||||
@ -329,12 +326,14 @@ impl Options {
|
||||
if syntax.typescript() {
|
||||
assumptions.set_class_methods = !transform.use_define_for_class_fields;
|
||||
assumptions.set_public_class_fields = !transform.use_define_for_class_fields;
|
||||
|
||||
program.visit_mut_with(&mut ts_resolver(top_level_mark));
|
||||
} else {
|
||||
program.visit_mut_with(&mut resolver_with_mark(top_level_mark));
|
||||
}
|
||||
|
||||
program.visit_mut_with(&mut resolver(
|
||||
unresolved_mark,
|
||||
top_level_mark,
|
||||
syntax.typescript(),
|
||||
));
|
||||
|
||||
if program.is_module() {
|
||||
js_minify = js_minify.map(|c| {
|
||||
let compress = c
|
||||
@ -408,6 +407,7 @@ impl Options {
|
||||
}
|
||||
};
|
||||
|
||||
let unresolved_ctxt = SyntaxContext::empty().apply_mark(unresolved_mark);
|
||||
let top_level_ctxt = SyntaxContext::empty().apply_mark(top_level_mark);
|
||||
|
||||
let pass = chain!(
|
||||
@ -421,26 +421,34 @@ impl Options {
|
||||
json_parse_pass
|
||||
);
|
||||
|
||||
let pass = PassBuilder::new(cm, handler, loose, assumptions, top_level_mark, pass)
|
||||
.target(es_version)
|
||||
.skip_helper_injection(self.skip_helper_injection)
|
||||
.minify(js_minify)
|
||||
.hygiene(if self.disable_hygiene {
|
||||
None
|
||||
} else {
|
||||
Some(hygiene::Config { keep_class_names })
|
||||
})
|
||||
.fixer(!self.disable_fixer)
|
||||
.preset_env(config.env)
|
||||
.regenerator(regenerator)
|
||||
.finalize(
|
||||
base_url,
|
||||
paths.into_iter().collect(),
|
||||
base,
|
||||
syntax,
|
||||
config.module,
|
||||
comments,
|
||||
);
|
||||
let pass = PassBuilder::new(
|
||||
cm,
|
||||
handler,
|
||||
loose,
|
||||
assumptions,
|
||||
top_level_mark,
|
||||
unresolved_mark,
|
||||
pass,
|
||||
)
|
||||
.target(es_version)
|
||||
.skip_helper_injection(self.skip_helper_injection)
|
||||
.minify(js_minify)
|
||||
.hygiene(if self.disable_hygiene {
|
||||
None
|
||||
} else {
|
||||
Some(hygiene::Config { keep_class_names })
|
||||
})
|
||||
.fixer(!self.disable_fixer)
|
||||
.preset_env(config.env)
|
||||
.regenerator(regenerator)
|
||||
.finalize(
|
||||
base_url,
|
||||
paths.into_iter().collect(),
|
||||
base,
|
||||
syntax,
|
||||
config.module,
|
||||
comments,
|
||||
);
|
||||
|
||||
let keep_import_assertions = experimental.keep_import_assertions;
|
||||
|
||||
@ -511,6 +519,7 @@ impl Options {
|
||||
program: &program,
|
||||
lint_config: &lints,
|
||||
top_level_ctxt,
|
||||
unresolved_ctxt,
|
||||
es_version,
|
||||
source_map: cm.clone(),
|
||||
})),
|
||||
|
@ -150,7 +150,7 @@ use swc_ecma_transforms::{
|
||||
hygiene,
|
||||
modules::path::NodeImportResolver,
|
||||
pass::noop,
|
||||
resolver_with_mark,
|
||||
resolver,
|
||||
};
|
||||
use swc_ecma_visit::{noop_visit_type, FoldWith, Visit, VisitMutWith, VisitWith};
|
||||
pub use swc_error_reporters::handler::{try_with_handler, HandlerOpts};
|
||||
@ -1037,12 +1037,14 @@ impl Compiler {
|
||||
Default::default()
|
||||
};
|
||||
|
||||
let top_level_mark = Mark::fresh(Mark::root());
|
||||
let unresolved_mark = Mark::new();
|
||||
let top_level_mark = Mark::new();
|
||||
|
||||
let is_mangler_enabled = min_opts.mangle.is_some();
|
||||
|
||||
let module = self.run_transform(handler, false, || {
|
||||
let module = module.fold_with(&mut resolver_with_mark(top_level_mark));
|
||||
let module =
|
||||
module.fold_with(&mut resolver(unresolved_mark, top_level_mark, false));
|
||||
|
||||
let mut module = swc_ecma_minifier::optimize(
|
||||
module,
|
||||
@ -1050,7 +1052,10 @@ impl Compiler {
|
||||
Some(&comments),
|
||||
None,
|
||||
&min_opts,
|
||||
&swc_ecma_minifier::option::ExtraOptions { top_level_mark },
|
||||
&swc_ecma_minifier::option::ExtraOptions {
|
||||
unresolved_mark,
|
||||
top_level_mark,
|
||||
},
|
||||
);
|
||||
|
||||
if !is_mangler_enabled {
|
||||
|
@ -161,7 +161,7 @@ fn shopify_2_same_opt() {
|
||||
skip_helper_injection: false,
|
||||
disable_hygiene: false,
|
||||
disable_fixer: false,
|
||||
global_mark: None,
|
||||
top_level_mark: None,
|
||||
cwd: "/Users/kdy1/projects/example-swcify".into(),
|
||||
filename: "/Users/kdy1/projects/example-swcify/src/App/App.tsx".into(),
|
||||
env_name: "development".into(),
|
||||
|
@ -1 +0,0 @@
|
||||
M;
|
@ -1 +0,0 @@
|
||||
M;
|
@ -1 +1 @@
|
||||
x, x.y, new (x());
|
||||
x.y, new (x());
|
||||
|
@ -1 +1 @@
|
||||
x, x.y, new (x());
|
||||
x.y, new (x());
|
||||
|
@ -7,13 +7,13 @@ var B;
|
||||
}
|
||||
B1.D = D;
|
||||
})(B || (B = {}));
|
||||
var A;
|
||||
(function(A1) {
|
||||
var A1;
|
||||
(function(A) {
|
||||
class C {
|
||||
}
|
||||
A1.C = C;
|
||||
A.C = C;
|
||||
var b = B;
|
||||
A1.b = b;
|
||||
})(A || (A = {}));
|
||||
A.b = b;
|
||||
})(A1 || (A1 = {}));
|
||||
var c;
|
||||
var c = new B.a.C();
|
||||
|
@ -1,13 +1,13 @@
|
||||
var B, A;
|
||||
var B, A1;
|
||||
!function(B1) {
|
||||
var a = A;
|
||||
B1.a = a;
|
||||
class D extends a.C {
|
||||
}
|
||||
B1.D = D;
|
||||
}(B || (B = {})), function(A1) {
|
||||
A1.C = class {
|
||||
}(B || (B = {})), function(A) {
|
||||
A.C = class {
|
||||
};
|
||||
var b = B;
|
||||
A1.b = b;
|
||||
}(A || (A = {})), new B.a.C();
|
||||
A.b = b;
|
||||
}(A1 || (A1 = {})), new B.a.C();
|
||||
|
@ -16,15 +16,15 @@ var B;
|
||||
}(a.C);
|
||||
B1.D = D;
|
||||
})(B || (B = {}));
|
||||
var A;
|
||||
(function(A1) {
|
||||
var A1;
|
||||
(function(A) {
|
||||
var C = function C() {
|
||||
"use strict";
|
||||
swcHelpers.classCallCheck(this, C);
|
||||
};
|
||||
A1.C = C;
|
||||
A.C = C;
|
||||
var b = B;
|
||||
A1.b = b;
|
||||
})(A || (A = {}));
|
||||
A.b = b;
|
||||
})(A1 || (A1 = {}));
|
||||
var c;
|
||||
var c = new B.a.C();
|
||||
|
@ -1,4 +1,4 @@
|
||||
var B, A;
|
||||
var B, A1;
|
||||
import * as swcHelpers from "@swc/helpers";
|
||||
!function(B1) {
|
||||
var a = A;
|
||||
@ -13,12 +13,12 @@ import * as swcHelpers from "@swc/helpers";
|
||||
return D;
|
||||
}(a.C);
|
||||
B1.D = D;
|
||||
}(B || (B = {})), function(A1) {
|
||||
}(B || (B = {})), function(A) {
|
||||
var C = function() {
|
||||
"use strict";
|
||||
swcHelpers.classCallCheck(this, C);
|
||||
};
|
||||
A1.C = C;
|
||||
A.C = C;
|
||||
var b = B;
|
||||
A1.b = b;
|
||||
}(A || (A = {})), new B.a.C();
|
||||
A.b = b;
|
||||
}(A1 || (A1 = {})), new B.a.C();
|
||||
|
@ -6,12 +6,12 @@ var M;
|
||||
}
|
||||
M1.D = D;
|
||||
})(M || (M = {}));
|
||||
var N;
|
||||
(function(N1) {
|
||||
var N1;
|
||||
(function(N) {
|
||||
class E extends M.D {
|
||||
}
|
||||
N1.E = E;
|
||||
})(N || (N = {}));
|
||||
N.E = E;
|
||||
})(N1 || (N1 = {}));
|
||||
var O;
|
||||
(function(O) {
|
||||
class C2 extends Q.E2 {
|
||||
|
@ -1,12 +1,12 @@
|
||||
var M, N, O;
|
||||
var M, N1, O;
|
||||
class C extends N.E {
|
||||
}
|
||||
(M || (M = {})).D = class extends C {
|
||||
}, function(N1) {
|
||||
}, function(N) {
|
||||
class E extends M.D {
|
||||
}
|
||||
N1.E = E;
|
||||
}(N || (N = {})), function(O) {
|
||||
N.E = E;
|
||||
}(N1 || (N1 = {})), function(O) {
|
||||
class C2 extends Q.E2 {
|
||||
}
|
||||
let P;
|
||||
|
@ -24,8 +24,8 @@ var M;
|
||||
}(C);
|
||||
M1.D = D;
|
||||
})(M || (M = {}));
|
||||
var N;
|
||||
(function(N1) {
|
||||
var _$N;
|
||||
(function(N) {
|
||||
var E = /*#__PURE__*/ function(_D) {
|
||||
"use strict";
|
||||
swcHelpers.inherits(E, _D);
|
||||
@ -36,8 +36,8 @@ var N;
|
||||
}
|
||||
return E;
|
||||
}(M.D);
|
||||
N1.E = E;
|
||||
})(N || (N = {}));
|
||||
N.E = E;
|
||||
})(_$N || (_$N = {}));
|
||||
var O;
|
||||
(function(O) {
|
||||
var C2 = /*#__PURE__*/ function(_E2) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as swcHelpers from "@swc/helpers";
|
||||
var M, N, O, C = function(_E) {
|
||||
var M, _$N, O, C = function(_E) {
|
||||
"use strict";
|
||||
swcHelpers.inherits(C, _E);
|
||||
var _super = swcHelpers.createSuper(C);
|
||||
@ -19,7 +19,7 @@ var M, N, O, C = function(_E) {
|
||||
return D;
|
||||
}(C);
|
||||
M1.D = D;
|
||||
}(M || (M = {})), function(N1) {
|
||||
}(M || (M = {})), function(N) {
|
||||
var E = function(_D) {
|
||||
"use strict";
|
||||
swcHelpers.inherits(E, _D);
|
||||
@ -29,8 +29,8 @@ var M, N, O, C = function(_E) {
|
||||
}
|
||||
return E;
|
||||
}(M.D);
|
||||
N1.E = E;
|
||||
}(N || (N = {})), function(O) {
|
||||
N.E = E;
|
||||
}(_$N || (_$N = {})), function(O) {
|
||||
var P, _$Q, P1, D2, Q1, E2, C2 = function(_E2) {
|
||||
"use strict";
|
||||
swcHelpers.inherits(C2, _E2);
|
||||
|
@ -1 +1 @@
|
||||
'a' in c && (c, c.a), 'd' in c && c, 'a' in c && (c, c.a), 'd' in c && c;
|
||||
'a' in c && c.a, 'a' in c && c.a;
|
||||
|
@ -1 +1 @@
|
||||
"a" in c && (c, c.a), "d" in c && c, "a" in c && (c, c.a), "d" in c && c;
|
||||
"a" in c && c.a, "a" in c && c.a;
|
||||
|
@ -1,2 +1,2 @@
|
||||
var a;
|
||||
null != o || (a = 1), a.toString(), null == o || o;
|
||||
null != o || (a = 1), a.toString();
|
||||
|
@ -6,7 +6,7 @@ null == o || o.x[b = 1], b.toString();
|
||||
let c;
|
||||
null == o || o(c = 1), c.toString();
|
||||
let d;
|
||||
null == o || o.x(d = 1), d.toString(), null == f || f(x), x, f, f(x), x, f, f(x), (null == o2 ? void 0 : o2.f(x)) ? (x, o2.f, null == o2 || o2.f, null == o2 || o2.f(x)) : (x, o2, null == o2 || o2.f, o2.f), x, o2, null == o2 || o2.f, o2.f, (null == o3 ? void 0 : o3.x) === 1 ? (o3, o3.x, null == o3 || o3.x) : (o3, null == o3 || o3.x, o3.x), o3, null == o3 || o3.x, o3.x, (null === (ref = o4.x) || void 0 === ref ? void 0 : ref.y) ? (o4.x, o4.x.y, null === (ref9 = o4.x) || void 0 === ref9 || ref9.y) : (o4.x, null === (ref10 = o4.x) || void 0 === ref10 || ref10.y, o4.x.y), o4.x, null === (ref1 = o4.x) || void 0 === ref1 || ref1.y, o4.x.y, (null === (ref3 = null === (ref2 = o5.x) || void 0 === ref2 ? void 0 : ref2.y.z) || void 0 === ref3 ? void 0 : ref3.w) ? (o5.x, o5.x.y, o5.x.y.z, o5.x.y.z.w, null === (ref11 = o5.x.y.z) || void 0 === ref11 || ref11.w, null === (ref12 = o5.x) || void 0 === ref12 || ref12.y.z.w, null === (ref14 = null === (ref13 = o5.x) || void 0 === ref13 ? void 0 : ref13.y.z) || void 0 === ref14 || ref14.w) : (o5.x, null === (ref15 = o5.x) || void 0 === ref15 || ref15.y, null === (ref16 = o5.x) || void 0 === ref16 || ref16.y.z, null === (ref18 = null === (ref17 = o5.x) || void 0 === ref17 ? void 0 : ref17.y.z) || void 0 === ref18 || ref18.w, o5.x.y, o5.x.y.z.w), o5.x, null === (ref4 = o5.x) || void 0 === ref4 || ref4.y, null === (ref5 = o5.x) || void 0 === ref5 || ref5.y.z, null === (ref7 = null === (ref6 = o5.x) || void 0 === ref6 ? void 0 : ref6.y.z) || void 0 === ref7 || ref7.w, o5.x.y, o5.x.y.z.w, (null == o6 ? void 0 : o6.f()) ? (o6, o6.f) : (o6, null == o6 || o6.f, o6.f), o6, null == o6 || o6.f, o6.f;
|
||||
null == o || o.x(d = 1), d.toString(), null == f || f(x), f(x), f(x), (null == o2 ? void 0 : o2.f(x)) ? (o2.f, null == o2 || o2.f, null == o2 || o2.f(x)) : (null == o2 || o2.f, o2.f), null == o2 || o2.f, o2.f, (null == o3 ? void 0 : o3.x) === 1 ? (o3.x, null == o3 || o3.x) : (null == o3 || o3.x, o3.x), null == o3 || o3.x, o3.x, (null === (ref = o4.x) || void 0 === ref ? void 0 : ref.y) ? (o4.x, o4.x.y, null === (ref9 = o4.x) || void 0 === ref9 || ref9.y) : (o4.x, null === (ref10 = o4.x) || void 0 === ref10 || ref10.y, o4.x.y), o4.x, null === (ref1 = o4.x) || void 0 === ref1 || ref1.y, o4.x.y, (null === (ref3 = null === (ref2 = o5.x) || void 0 === ref2 ? void 0 : ref2.y.z) || void 0 === ref3 ? void 0 : ref3.w) ? (o5.x, o5.x.y, o5.x.y.z, o5.x.y.z.w, null === (ref11 = o5.x.y.z) || void 0 === ref11 || ref11.w, null === (ref12 = o5.x) || void 0 === ref12 || ref12.y.z.w, null === (ref14 = null === (ref13 = o5.x) || void 0 === ref13 ? void 0 : ref13.y.z) || void 0 === ref14 || ref14.w) : (o5.x, null === (ref15 = o5.x) || void 0 === ref15 || ref15.y, null === (ref16 = o5.x) || void 0 === ref16 || ref16.y.z, null === (ref18 = null === (ref17 = o5.x) || void 0 === ref17 ? void 0 : ref17.y.z) || void 0 === ref18 || ref18.w, o5.x.y, o5.x.y.z.w), o5.x, null === (ref4 = o5.x) || void 0 === ref4 || ref4.y, null === (ref5 = o5.x) || void 0 === ref5 || ref5.y.z, null === (ref7 = null === (ref6 = o5.x) || void 0 === ref6 ? void 0 : ref6.y.z) || void 0 === ref7 || ref7.w, o5.x.y, o5.x.y.z.w, (null == o6 ? void 0 : o6.f()) || null == o6 || o6.f, o6.f, null == o6 || o6.f, o6.f;
|
||||
let lastSomeProperty;
|
||||
function someFunction(someOptionalObject) {
|
||||
(null == someOptionalObject ? void 0 : someOptionalObject.someProperty) !== lastSomeProperty && (console.log(someOptionalObject), console.log(someOptionalObject.someProperty), lastSomeProperty = null == someOptionalObject ? void 0 : someOptionalObject.someProperty);
|
||||
|
@ -2,7 +2,7 @@ import * as swcHelpers from "@swc/helpers";
|
||||
function someFunction(someOptionalObject) {
|
||||
(null == someOptionalObject ? void 0 : someOptionalObject.someProperty) !== lastSomeProperty && (console.log(someOptionalObject), console.log(someOptionalObject.someProperty), lastSomeProperty = null == someOptionalObject ? void 0 : someOptionalObject.someProperty);
|
||||
}
|
||||
null == o || o[a = 1], a.toString(), null == o || o.x[b = 1], b.toString(), null == o || o(c = 1), c.toString(), null == o || o.x(d = 1), d.toString(), null == f || f(x), x, f, f(x), x, f, f(x), (null == o2 ? void 0 : o2.f(x)) ? (x, o2.f, null == o2 || o2.f, null == o2 || o2.f(x)) : (x, o2, null == o2 || o2.f, o2.f), x, o2, null == o2 || o2.f, o2.f, (null == o3 ? void 0 : o3.x) === 1 ? (o3, o3.x, null == o3 || o3.x) : (o3, null == o3 || o3.x, o3.x), o3, null == o3 || o3.x, o3.x, (null === (ref = o4.x) || void 0 === ref ? void 0 : ref.y) ? (o4.x, o4.x.y, null === (ref9 = o4.x) || void 0 === ref9 || ref9.y) : (o4.x, null === (ref10 = o4.x) || void 0 === ref10 || ref10.y, o4.x.y), o4.x, null === (ref1 = o4.x) || void 0 === ref1 || ref1.y, o4.x.y, (null === (ref3 = null === (ref2 = o5.x) || void 0 === ref2 ? void 0 : ref2.y.z) || void 0 === ref3 ? void 0 : ref3.w) ? (o5.x, o5.x.y, o5.x.y.z, o5.x.y.z.w, null === (ref11 = o5.x.y.z) || void 0 === ref11 || ref11.w, null === (ref12 = o5.x) || void 0 === ref12 || ref12.y.z.w, null === (ref14 = null === (ref13 = o5.x) || void 0 === ref13 ? void 0 : ref13.y.z) || void 0 === ref14 || ref14.w) : (o5.x, null === (ref15 = o5.x) || void 0 === ref15 || ref15.y, null === (ref16 = o5.x) || void 0 === ref16 || ref16.y.z, null === (ref18 = null === (ref17 = o5.x) || void 0 === ref17 ? void 0 : ref17.y.z) || void 0 === ref18 || ref18.w, o5.x.y, o5.x.y.z.w), o5.x, null === (ref4 = o5.x) || void 0 === ref4 || ref4.y, null === (ref5 = o5.x) || void 0 === ref5 || ref5.y.z, null === (ref7 = null === (ref6 = o5.x) || void 0 === ref6 ? void 0 : ref6.y.z) || void 0 === ref7 || ref7.w, o5.x.y, o5.x.y.z.w, (null == o6 ? void 0 : o6.f()) ? (o6, o6.f) : (o6, null == o6 || o6.f, o6.f), o6, null == o6 || o6.f, o6.f, someFunction({
|
||||
null == o || o[a = 1], a.toString(), null == o || o.x[b = 1], b.toString(), null == o || o(c = 1), c.toString(), null == o || o.x(d = 1), d.toString(), null == f || f(x), f(x), f(x), (null == o2 ? void 0 : o2.f(x)) ? (o2.f, null == o2 || o2.f, null == o2 || o2.f(x)) : (null == o2 || o2.f, o2.f), null == o2 || o2.f, o2.f, (null == o3 ? void 0 : o3.x) === 1 ? (o3.x, null == o3 || o3.x) : (null == o3 || o3.x, o3.x), null == o3 || o3.x, o3.x, (null === (ref = o4.x) || void 0 === ref ? void 0 : ref.y) ? (o4.x, o4.x.y, null === (ref9 = o4.x) || void 0 === ref9 || ref9.y) : (o4.x, null === (ref10 = o4.x) || void 0 === ref10 || ref10.y, o4.x.y), o4.x, null === (ref1 = o4.x) || void 0 === ref1 || ref1.y, o4.x.y, (null === (ref3 = null === (ref2 = o5.x) || void 0 === ref2 ? void 0 : ref2.y.z) || void 0 === ref3 ? void 0 : ref3.w) ? (o5.x, o5.x.y, o5.x.y.z, o5.x.y.z.w, null === (ref11 = o5.x.y.z) || void 0 === ref11 || ref11.w, null === (ref12 = o5.x) || void 0 === ref12 || ref12.y.z.w, null === (ref14 = null === (ref13 = o5.x) || void 0 === ref13 ? void 0 : ref13.y.z) || void 0 === ref14 || ref14.w) : (o5.x, null === (ref15 = o5.x) || void 0 === ref15 || ref15.y, null === (ref16 = o5.x) || void 0 === ref16 || ref16.y.z, null === (ref18 = null === (ref17 = o5.x) || void 0 === ref17 ? void 0 : ref17.y.z) || void 0 === ref18 || ref18.w, o5.x.y, o5.x.y.z.w), o5.x, null === (ref4 = o5.x) || void 0 === ref4 || ref4.y, null === (ref5 = o5.x) || void 0 === ref5 || ref5.y.z, null === (ref7 = null === (ref6 = o5.x) || void 0 === ref6 ? void 0 : ref6.y.z) || void 0 === ref7 || ref7.w, o5.x.y, o5.x.y.z.w, (null == o6 ? void 0 : o6.f()) || null == o6 || o6.f, o6.f, null == o6 || o6.f, o6.f, someFunction({
|
||||
someProperty: 42
|
||||
}), someFunction(void 0);
|
||||
for(var ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, ref8, a, b, c, d, ref9, ref10, ref11, ref12, ref13, ref14, ref15, ref16, ref17, ref18, lastSomeProperty, ref19, i = 0; (null === (ref8 = arr[i]) || void 0 === ref8 ? void 0 : ref8.tag) === "left";)i += 1, (null === (ref19 = arr[i]) || void 0 === ref19 ? void 0 : ref19.tag) === "right" && console.log("I should ALSO be reachable");
|
||||
|
@ -1,4 +1,4 @@
|
||||
list, wrap(list), wrap((x)=>[
|
||||
wrap(list), wrap((x)=>[
|
||||
x
|
||||
]
|
||||
), compose((a)=>list(a)
|
||||
|
@ -1,4 +1,4 @@
|
||||
list, wrap(list), wrap(function(x) {
|
||||
wrap(list), wrap(function(x) {
|
||||
return [
|
||||
x
|
||||
];
|
||||
|
@ -1,4 +1,4 @@
|
||||
ab.kind, x;
|
||||
ab.kind;
|
||||
const x1 = {
|
||||
a: 'foo',
|
||||
b: 42
|
||||
|
@ -1,4 +1,4 @@
|
||||
ab.kind, x;
|
||||
ab.kind;
|
||||
var x2 = {
|
||||
a: "foo",
|
||||
b: !0
|
||||
|
@ -1,4 +1,4 @@
|
||||
ab.kind, x, f10(a1), f10(a2);
|
||||
ab.kind, f10(a1), f10(a2);
|
||||
const x1 = {
|
||||
a: 'foo',
|
||||
b: 42
|
||||
@ -6,4 +6,4 @@ const x1 = {
|
||||
a: 'foo',
|
||||
b: !0
|
||||
};
|
||||
x1[k] = 'bar', x2[k] = 'bar', s2 = s1 = s2, t2 = t1 = t2, shouldBeB;
|
||||
x1[k] = 'bar', x2[k] = 'bar', s2 = s1 = s2, t2 = t1 = t2;
|
||||
|
@ -1,4 +1,4 @@
|
||||
ab.kind, x, f10(a1), f10(a2);
|
||||
ab.kind, f10(a1), f10(a2);
|
||||
var x2 = {
|
||||
a: "foo",
|
||||
b: !0
|
||||
@ -6,4 +6,4 @@ var x2 = {
|
||||
({
|
||||
a: "foo",
|
||||
b: 42
|
||||
})[k] = "bar", x2[k] = "bar", s2 = s1 = s2, t2 = t1 = t2, shouldBeB;
|
||||
})[k] = "bar", x2[k] = "bar", s2 = s1 = s2, t2 = t1 = t2;
|
||||
|
@ -1 +1 @@
|
||||
ta1 = sa1, ta1 = sa2, ta2 = sa1, ta2 = sa2, tb1 = sb1, q.asd.a.substr(1), q.asd.b, q, tt = ss;
|
||||
ta1 = sa1, ta1 = sa2, ta2 = sa1, ta2 = sa2, tb1 = sb1, q.asd.a.substr(1), q.asd.b, tt = ss;
|
||||
|
@ -1 +1 @@
|
||||
ta1 = sa1, ta1 = sa2, ta2 = sa1, ta2 = sa2, tb1 = sb1, q.asd.a.substr(1), q.asd.b, q, tt = ss;
|
||||
ta1 = sa1, ta1 = sa2, ta2 = sa1, ta2 = sa2, tb1 = sb1, q.asd.a.substr(1), q.asd.b, tt = ss;
|
||||
|
@ -1,3 +1,2 @@
|
||||
import * as React from "react";
|
||||
import * as React from "react";
|
||||
MyComp;
|
||||
|
@ -1,3 +1,2 @@
|
||||
import * as React from "react";
|
||||
import * as React from "react";
|
||||
MyComp;
|
||||
|
@ -1,27 +1,27 @@
|
||||
import * as swcHelpers from "@swc/helpers";
|
||||
this.props.children, Composite, this.props.children;
|
||||
this.props.children, this.props.children;
|
||||
var x = React.createElement("div", {
|
||||
attr1: "foobar",
|
||||
attr2: "foobarbazbug",
|
||||
attr3: "foobarbazbug",
|
||||
attr4: "baz"
|
||||
});
|
||||
Component, Namespace.Component, Namespace.DeepNamespace.Component, Component, swcHelpers.extends({}, x, {
|
||||
Namespace.Component, Namespace.DeepNamespace.Component, swcHelpers.extends({}, x, {
|
||||
y: 2,
|
||||
z: !0
|
||||
}), Component, swcHelpers.extends({}, this.props, {
|
||||
}), swcHelpers.extends({}, this.props, {
|
||||
sound: "moo"
|
||||
}), Component, Component, swcHelpers.extends({}, x), Component, swcHelpers.extends({}, x, {
|
||||
}), swcHelpers.extends({}, x), swcHelpers.extends({}, x, {
|
||||
y: 2
|
||||
}), Component, swcHelpers.extends({}, x, {
|
||||
}), swcHelpers.extends({}, x, {
|
||||
y: 2,
|
||||
z: !0
|
||||
}), Component, swcHelpers.extends({
|
||||
}), swcHelpers.extends({
|
||||
x: 1
|
||||
}, y), Component, swcHelpers.extends({
|
||||
}, y), swcHelpers.extends({
|
||||
x: 1,
|
||||
y: "2"
|
||||
}, z, z), Child, Component, swcHelpers.extends({
|
||||
}, z, z), swcHelpers.extends({
|
||||
x: "1"
|
||||
}, z = {
|
||||
y: 2
|
||||
|
@ -1,27 +1,27 @@
|
||||
import * as swcHelpers from "@swc/helpers";
|
||||
this.props.children, Composite, this.props.children;
|
||||
this.props.children, this.props.children;
|
||||
var x = React.createElement("div", {
|
||||
attr1: "foobar",
|
||||
attr2: "foobarbazbug",
|
||||
attr3: "foobarbazbug",
|
||||
attr4: "baz"
|
||||
});
|
||||
Component, Namespace.Component, Namespace.DeepNamespace.Component, Component, swcHelpers.extends({}, x, {
|
||||
Namespace.Component, Namespace.DeepNamespace.Component, swcHelpers.extends({}, x, {
|
||||
y: 2,
|
||||
z: !0
|
||||
}), Component, swcHelpers.extends({}, this.props, {
|
||||
}), swcHelpers.extends({}, this.props, {
|
||||
sound: "moo"
|
||||
}), Component, Component, swcHelpers.extends({}, x), Component, swcHelpers.extends({}, x, {
|
||||
}), swcHelpers.extends({}, x), swcHelpers.extends({}, x, {
|
||||
y: 2
|
||||
}), Component, swcHelpers.extends({}, x, {
|
||||
}), swcHelpers.extends({}, x, {
|
||||
y: 2,
|
||||
z: !0
|
||||
}), Component, swcHelpers.extends({
|
||||
}), swcHelpers.extends({
|
||||
x: 1
|
||||
}, y), Component, swcHelpers.extends({
|
||||
}, y), swcHelpers.extends({
|
||||
x: 1,
|
||||
y: "2"
|
||||
}, z, z), Child, Component, swcHelpers.extends({
|
||||
}, z, z), swcHelpers.extends({
|
||||
x: "1"
|
||||
}, z = {
|
||||
y: 2
|
||||
|
@ -1,2 +1,2 @@
|
||||
var a;
|
||||
a.toString, a = void 0, a = null, a = b, a = c, a = a = d, 'object' != typeof b && b.toString(), 'object' == typeof b && (a = b), 'object' == typeof d && (b = d), d.toString(), d, d.toString(), d, d.toString(), d.toString();
|
||||
a.toString, a = void 0, a = null, a = b, a = c, a = a = d, 'object' != typeof b && b.toString(), 'object' == typeof b && (a = b), 'object' == typeof d && (b = d), d.toString(), d.toString(), d.toString(), d.toString();
|
||||
|
@ -1,2 +1,2 @@
|
||||
var a;
|
||||
a.toString, a = void 0, a = null, a = b, a = c, a = a = d, "object" != typeof b && b.toString(), "object" == typeof b && (a = b), "object" == typeof d && (b = d), d.toString(), d, d.toString(), d, d.toString(), d.toString();
|
||||
a.toString, a = void 0, a = null, a = b, a = c, a = a = d, "object" != typeof b && b.toString(), "object" == typeof b && (a = b), "object" == typeof d && (b = d), d.toString(), d.toString(), d.toString(), d.toString();
|
||||
|
@ -1,2 +1,2 @@
|
||||
var ref, ref1, ref2, ref3;
|
||||
null !== (ref3 = null !== (ref2 = null !== (ref1 = null !== (ref = null != a1 ? a1 : a2) && void 0 !== ref ? ref : a3) && void 0 !== ref1 ? ref1 : a4) && void 0 !== ref2 ? ref2 : a5) && void 0 !== ref3 || a6;
|
||||
null !== (ref3 = null !== (ref2 = null !== (ref1 = null !== (ref = null != a1 ? a1 : a2) && void 0 !== ref ? ref : a3) && void 0 !== ref1 ? ref1 : a4) && void 0 !== ref2 ? ref2 : a5);
|
||||
|
@ -1,2 +1,2 @@
|
||||
var ref, ref1, ref2, ref3;
|
||||
null !== (ref3 = null !== (ref2 = null !== (ref1 = null !== (ref = null != a1 ? a1 : a2) && void 0 !== ref ? ref : a3) && void 0 !== ref1 ? ref1 : a4) && void 0 !== ref2 ? ref2 : a5) && void 0 !== ref3 || a6;
|
||||
null !== (ref3 = null !== (ref2 = null !== (ref1 = null !== (ref = null != a1 ? a1 : a2) && void 0 !== ref ? ref : a3) && void 0 !== ref1 ? ref1 : a4) && void 0 !== ref2 ? ref2 : a5);
|
||||
|
@ -30,7 +30,7 @@ a2.a, a2.b, a2 = {
|
||||
let b2 = swcHelpers.objectSpread({}, b1, {
|
||||
z: 55
|
||||
});
|
||||
swcHelpers.objectSpread({}, b2), opts;
|
||||
swcHelpers.objectSpread({}, b2);
|
||||
let d1 = {
|
||||
kind: 'a',
|
||||
pos: {
|
||||
|
@ -30,7 +30,7 @@ a2.a, a2.b, a2 = {
|
||||
var b2 = swcHelpers.objectSpread({}, b1, {
|
||||
z: 55
|
||||
});
|
||||
swcHelpers.objectSpread({}, b2), opts;
|
||||
swcHelpers.objectSpread({}, b2);
|
||||
var d1 = {
|
||||
kind: "a",
|
||||
pos: {
|
||||
|
@ -1 +1 @@
|
||||
stringDictionary = optionalProperties, stringDictionary = undefinedProperties, probablyArray = numberLiteralKeys, optionalUndefined;
|
||||
stringDictionary = optionalProperties, stringDictionary = undefinedProperties, probablyArray = numberLiteralKeys;
|
||||
|
@ -1 +1 @@
|
||||
stringDictionary = optionalProperties, stringDictionary = undefinedProperties, probablyArray = numberLiteralKeys, optionalUndefined;
|
||||
stringDictionary = optionalProperties, stringDictionary = undefinedProperties, probablyArray = numberLiteralKeys;
|
||||
|
@ -1,2 +1 @@
|
||||
import * as swcHelpers from "@swc/helpers";
|
||||
a;
|
||||
|
@ -9,4 +9,3 @@ var A1 = function() {
|
||||
value: void 0
|
||||
});
|
||||
};
|
||||
a;
|
||||
|
@ -1,3 +1,3 @@
|
||||
import * as swcHelpers from "@swc/helpers";
|
||||
import Main from 'mod';
|
||||
Foo, Foo, swcHelpers.extends({}, Main);
|
||||
swcHelpers.extends({}, Main);
|
||||
|
@ -1,3 +1,3 @@
|
||||
import * as swcHelpers from "@swc/helpers";
|
||||
import Main from "mod";
|
||||
Foo, Foo, swcHelpers.extends({}, Main);
|
||||
swcHelpers.extends({}, Main);
|
||||
|
@ -1,2 +1,2 @@
|
||||
require('react'), MyComp;
|
||||
require('react');
|
||||
export { };
|
||||
|
@ -1,2 +1 @@
|
||||
MyComp;
|
||||
export { };
|
||||
|
@ -6,18 +6,18 @@ let obj = {
|
||||
}, obj1 = {
|
||||
yy: !0
|
||||
}, defaultObj;
|
||||
OneThing, OneThing, swcHelpers.extends({}, obj), OneThing, swcHelpers.extends({}, {}), OneThing, swcHelpers.extends({}, obj1, obj), OneThing, swcHelpers.extends({}, obj1, {
|
||||
swcHelpers.extends({}, obj), swcHelpers.extends({}, {}), swcHelpers.extends({}, obj1, obj), swcHelpers.extends({}, obj1, {
|
||||
yy: 42
|
||||
}, {
|
||||
yy1: "hi"
|
||||
}), OneThing, swcHelpers.extends({}, obj1, {
|
||||
}), swcHelpers.extends({}, obj1, {
|
||||
yy: 10000,
|
||||
yy1: "true"
|
||||
}), OneThing, swcHelpers.extends({}, defaultObj, {
|
||||
}), swcHelpers.extends({}, defaultObj, {
|
||||
yy: !0
|
||||
}, obj), OneThing, OneThing, swcHelpers.extends({}, {
|
||||
}, obj), swcHelpers.extends({}, {
|
||||
"ignore-prop": 200
|
||||
}), OneThing, swcHelpers.extends({}, {
|
||||
}), swcHelpers.extends({}, {
|
||||
yy: 500,
|
||||
"ignore-prop": "hello"
|
||||
}, {
|
||||
|
@ -6,18 +6,18 @@ var defaultObj, obj = {
|
||||
}, obj1 = {
|
||||
yy: !0
|
||||
};
|
||||
OneThing, OneThing, swcHelpers.extends({}, obj), OneThing, swcHelpers.extends({}, {}), OneThing, swcHelpers.extends({}, obj1, obj), OneThing, swcHelpers.extends({}, obj1, {
|
||||
swcHelpers.extends({}, obj), swcHelpers.extends({}, {}), swcHelpers.extends({}, obj1, obj), swcHelpers.extends({}, obj1, {
|
||||
yy: 42
|
||||
}, {
|
||||
yy1: "hi"
|
||||
}), OneThing, swcHelpers.extends({}, obj1, {
|
||||
}), swcHelpers.extends({}, obj1, {
|
||||
yy: 10000,
|
||||
yy1: "true"
|
||||
}), OneThing, swcHelpers.extends({}, defaultObj, {
|
||||
}), swcHelpers.extends({}, defaultObj, {
|
||||
yy: !0
|
||||
}, obj), OneThing, OneThing, swcHelpers.extends({}, {
|
||||
}, obj), swcHelpers.extends({}, {
|
||||
"ignore-prop": 200
|
||||
}), OneThing, swcHelpers.extends({}, {
|
||||
}), swcHelpers.extends({}, {
|
||||
yy: 500,
|
||||
"ignore-prop": "hello"
|
||||
}, {
|
||||
|
@ -1,9 +1,9 @@
|
||||
import * as swcHelpers from "@swc/helpers";
|
||||
let obj2;
|
||||
ZeroThingOrTwoThing, ZeroThingOrTwoThing, ZeroThingOrTwoThing, swcHelpers.extends({}, obj2), ZeroThingOrTwoThing, swcHelpers.extends({
|
||||
swcHelpers.extends({}, obj2), swcHelpers.extends({
|
||||
yy: 1000
|
||||
}, obj2), ZeroThingOrTwoThing, swcHelpers.extends({}, obj2, {
|
||||
}, obj2), swcHelpers.extends({}, obj2, {
|
||||
yy: 1000
|
||||
}), ThreeThing, ThreeThing, ThreeThing, swcHelpers.extends({}, obj2, {
|
||||
}), swcHelpers.extends({}, obj2, {
|
||||
y2: 10
|
||||
});
|
||||
|
@ -1,9 +1,9 @@
|
||||
var obj2;
|
||||
import * as swcHelpers from "@swc/helpers";
|
||||
ZeroThingOrTwoThing, ZeroThingOrTwoThing, ZeroThingOrTwoThing, swcHelpers.extends({}, obj2), ZeroThingOrTwoThing, swcHelpers.extends({
|
||||
swcHelpers.extends({}, obj2), swcHelpers.extends({
|
||||
yy: 1000
|
||||
}, obj2), ZeroThingOrTwoThing, swcHelpers.extends({}, obj2, {
|
||||
}, obj2), swcHelpers.extends({}, obj2, {
|
||||
yy: 1000
|
||||
}), ThreeThing, ThreeThing, ThreeThing, swcHelpers.extends({}, obj2, {
|
||||
}), swcHelpers.extends({}, obj2, {
|
||||
y2: 10
|
||||
});
|
||||
|
@ -4,16 +4,16 @@ let obj = {
|
||||
yy: 10,
|
||||
yy1: "hello"
|
||||
}, obj2;
|
||||
OneThing, OneThing, OneThing, swcHelpers.extends({}, obj, {
|
||||
swcHelpers.extends({}, obj, {
|
||||
yy1: !0
|
||||
}), OneThing, swcHelpers.extends({}, obj, {
|
||||
}), swcHelpers.extends({}, obj, {
|
||||
extra: "extra attr"
|
||||
}), OneThing, swcHelpers.extends({}, obj, {
|
||||
}), swcHelpers.extends({}, obj, {
|
||||
y1: 10000
|
||||
}), OneThing, swcHelpers.extends({}, obj, {
|
||||
}), swcHelpers.extends({}, obj, {
|
||||
yy: !0
|
||||
}), OneThing, swcHelpers.extends({}, obj2, {
|
||||
}), swcHelpers.extends({}, obj2, {
|
||||
extra: "extra attr"
|
||||
}), OneThing, swcHelpers.extends({}, obj2, {
|
||||
}), swcHelpers.extends({}, obj2, {
|
||||
yy: !0
|
||||
}), TestingOneThing, TestingOneThing, TestingOptional, TestingOptional, TestingOptional, TestingOptional;
|
||||
});
|
||||
|
@ -4,16 +4,16 @@ var obj2, obj = {
|
||||
yy: 10,
|
||||
yy1: "hello"
|
||||
};
|
||||
OneThing, OneThing, OneThing, swcHelpers.extends({}, obj, {
|
||||
swcHelpers.extends({}, obj, {
|
||||
yy1: !0
|
||||
}), OneThing, swcHelpers.extends({}, obj, {
|
||||
}), swcHelpers.extends({}, obj, {
|
||||
extra: "extra attr"
|
||||
}), OneThing, swcHelpers.extends({}, obj, {
|
||||
}), swcHelpers.extends({}, obj, {
|
||||
y1: 10000
|
||||
}), OneThing, swcHelpers.extends({}, obj, {
|
||||
}), swcHelpers.extends({}, obj, {
|
||||
yy: !0
|
||||
}), OneThing, swcHelpers.extends({}, obj2, {
|
||||
}), swcHelpers.extends({}, obj2, {
|
||||
extra: "extra attr"
|
||||
}), OneThing, swcHelpers.extends({}, obj2, {
|
||||
}), swcHelpers.extends({}, obj2, {
|
||||
yy: !0
|
||||
}), TestingOneThing, TestingOneThing, TestingOptional, TestingOptional, TestingOptional, TestingOptional;
|
||||
});
|
||||
|
@ -1,2 +1,2 @@
|
||||
import * as swcHelpers from "@swc/helpers";
|
||||
require('react'), InferParamComponent;
|
||||
require('react');
|
||||
|
@ -1,2 +1,2 @@
|
||||
import * as swcHelpers from "@swc/helpers";
|
||||
require("react"), InferParamComponent;
|
||||
require("react");
|
||||
|
@ -1,2 +1,2 @@
|
||||
import * as swcHelpers from "@swc/helpers";
|
||||
require('react'), InferParamComponent;
|
||||
require('react');
|
||||
|
@ -1,2 +1,2 @@
|
||||
import * as swcHelpers from "@swc/helpers";
|
||||
require("react"), InferParamComponent;
|
||||
require("react");
|
||||
|
@ -1,12 +1,12 @@
|
||||
import * as swcHelpers from "@swc/helpers";
|
||||
let constCall = Symbol();
|
||||
Symbol(), Symbol(), Symbol(), constType, constType, constType, constType;
|
||||
Symbol(), Symbol(), Symbol();
|
||||
class C {
|
||||
constructor(){
|
||||
this.readonlyCall = Symbol(), this.readwriteCall = Symbol();
|
||||
}
|
||||
}
|
||||
C.readonlyStaticCall = Symbol(), C.readonlyStaticTypeAndCall = Symbol(), C.readwriteStaticCall = Symbol(), C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, i.readonlyType, i.readonlyType, i.readonlyType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, Promise.resolve(constCall), f(s), f(N.s), f(N.s), N.s, N.s, s, N.s, N.s, (p = s)=>p
|
||||
C.readonlyStaticCall = Symbol(), C.readonlyStaticTypeAndCall = Symbol(), C.readwriteStaticCall = Symbol(), C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, i.readonlyType, i.readonlyType, i.readonlyType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, Promise.resolve(constCall), f(s), f(N.s), f(N.s), N.s, N.s, N.s, N.s, (p = s)=>p
|
||||
;
|
||||
class C0 {
|
||||
method1() {
|
||||
@ -32,4 +32,4 @@ class C0 {
|
||||
this.a = s, this.b = N.s, this.c = N.s, this.d = s, this.e = N.s, this.f = N.s;
|
||||
}
|
||||
}
|
||||
C0.a = s, C0.b = N.s, C0.c = N.s, C0.d = s, C0.e = N.s, C0.f = N.s, o[s], o[N.s], o[N.s], f(s), f(N.s), f(N.s), g(s), g(N.s), g(N.s), s, N.s, N.s, 2 * Math.random() && N.s, 2 * Math.random() && N.s, s, N.s;
|
||||
C0.a = s, C0.b = N.s, C0.c = N.s, C0.d = s, C0.e = N.s, C0.f = N.s, o[s], o[N.s], o[N.s], f(s), f(N.s), f(N.s), g(s), g(N.s), g(N.s), N.s, N.s, 2 * Math.random() && N.s, 2 * Math.random() && N.s, N.s;
|
||||
|
@ -41,12 +41,12 @@ var _obj, _marked = regeneratorRuntime.mark(function() {
|
||||
}
|
||||
}, _marked3);
|
||||
}), constCall = Symbol(), letCall = Symbol(), varCall = Symbol();
|
||||
Symbol(), constType, constType, constType, constType;
|
||||
Symbol();
|
||||
var C = function() {
|
||||
"use strict";
|
||||
swcHelpers.classCallCheck(this, C), this.readonlyCall = Symbol(), this.readwriteCall = Symbol();
|
||||
};
|
||||
C.readonlyStaticCall = Symbol(), C.readonlyStaticTypeAndCall = Symbol(), C.readwriteStaticCall = Symbol(), C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, i.readonlyType, i.readonlyType, i.readonlyType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, Promise.resolve(constCall), f(s), f(N.s), f(N.s), N.s, N.s, s, N.s, N.s, regeneratorRuntime.mark(function method4() {
|
||||
C.readonlyStaticCall = Symbol(), C.readonlyStaticTypeAndCall = Symbol(), C.readwriteStaticCall = Symbol(), C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, i.readonlyType, i.readonlyType, i.readonlyType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, Promise.resolve(constCall), f(s), f(N.s), f(N.s), N.s, N.s, N.s, N.s, regeneratorRuntime.mark(function method4() {
|
||||
return regeneratorRuntime.wrap(function(_ctx) {
|
||||
for(;;)switch(_ctx.prev = _ctx.next){
|
||||
case 0:
|
||||
@ -104,7 +104,7 @@ var C0 = function() {
|
||||
return p;
|
||||
}, C0;
|
||||
}();
|
||||
C0.a = s, C0.b = N.s, C0.c = N.s, C0.d = s, C0.e = N.s, C0.f = N.s, o[s], o[N.s], o[N.s], f(s), f(N.s), f(N.s), g(s), g(N.s), g(N.s), s, N.s, N.s, 2 * Math.random() && N.s, 2 * Math.random() && N.s, _obj = {}, swcHelpers.defineProperty(_obj, s, "a"), swcHelpers.defineProperty(_obj, N.s, "b");
|
||||
C0.a = s, C0.b = N.s, C0.c = N.s, C0.d = s, C0.e = N.s, C0.f = N.s, o[s], o[N.s], o[N.s], f(s), f(N.s), f(N.s), g(s), g(N.s), g(N.s), N.s, N.s, 2 * Math.random() && N.s, 2 * Math.random() && N.s, _obj = {}, swcHelpers.defineProperty(_obj, s, "a"), swcHelpers.defineProperty(_obj, N.s, "b");
|
||||
var C1 = function() {
|
||||
"use strict";
|
||||
swcHelpers.classCallCheck(this, C1);
|
||||
|
@ -1,12 +1,12 @@
|
||||
import * as swcHelpers from "@swc/helpers";
|
||||
let constCall = Symbol();
|
||||
Symbol(), Symbol(), Symbol(), constType, constType, constType, constType;
|
||||
Symbol(), Symbol(), Symbol();
|
||||
class C {
|
||||
constructor(){
|
||||
this.readonlyCall = Symbol(), this.readwriteCall = Symbol();
|
||||
}
|
||||
}
|
||||
C.readonlyStaticCall = Symbol(), C.readonlyStaticTypeAndCall = Symbol(), C.readwriteStaticCall = Symbol(), C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, i.readonlyType, i.readonlyType, i.readonlyType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, Promise.resolve(constCall), f(s), f(N.s), f(N.s), N.s, N.s, s, N.s, N.s, (p = s)=>p
|
||||
C.readonlyStaticCall = Symbol(), C.readonlyStaticTypeAndCall = Symbol(), C.readwriteStaticCall = Symbol(), C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, i.readonlyType, i.readonlyType, i.readonlyType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, Promise.resolve(constCall), f(s), f(N.s), f(N.s), N.s, N.s, N.s, N.s, (p = s)=>p
|
||||
;
|
||||
class C0 {
|
||||
method1() {
|
||||
@ -32,4 +32,4 @@ class C0 {
|
||||
this.a = s, this.b = N.s, this.c = N.s, this.d = s, this.e = N.s, this.f = N.s;
|
||||
}
|
||||
}
|
||||
C0.a = s, C0.b = N.s, C0.c = N.s, C0.d = s, C0.e = N.s, C0.f = N.s, o[s], o[N.s], o[N.s], f(s), f(N.s), f(N.s), g(s), g(N.s), g(N.s), s, N.s, N.s, 2 * Math.random() && N.s, 2 * Math.random() && N.s, s, N.s;
|
||||
C0.a = s, C0.b = N.s, C0.c = N.s, C0.d = s, C0.e = N.s, C0.f = N.s, o[s], o[N.s], o[N.s], f(s), f(N.s), f(N.s), g(s), g(N.s), g(N.s), N.s, N.s, 2 * Math.random() && N.s, 2 * Math.random() && N.s, N.s;
|
||||
|
@ -41,12 +41,12 @@ var _obj, _marked = regeneratorRuntime.mark(function() {
|
||||
}
|
||||
}, _marked3);
|
||||
}), constCall = Symbol(), letCall = Symbol(), varCall = Symbol();
|
||||
Symbol(), constType, constType, constType, constType;
|
||||
Symbol();
|
||||
var C = function() {
|
||||
"use strict";
|
||||
swcHelpers.classCallCheck(this, C), this.readonlyCall = Symbol(), this.readwriteCall = Symbol();
|
||||
};
|
||||
C.readonlyStaticCall = Symbol(), C.readonlyStaticTypeAndCall = Symbol(), C.readwriteStaticCall = Symbol(), C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, i.readonlyType, i.readonlyType, i.readonlyType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, Promise.resolve(constCall), f(s), f(N.s), f(N.s), N.s, N.s, s, N.s, N.s, regeneratorRuntime.mark(function method4() {
|
||||
C.readonlyStaticCall = Symbol(), C.readonlyStaticTypeAndCall = Symbol(), C.readwriteStaticCall = Symbol(), C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, i.readonlyType, i.readonlyType, i.readonlyType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, Promise.resolve(constCall), f(s), f(N.s), f(N.s), N.s, N.s, N.s, N.s, regeneratorRuntime.mark(function method4() {
|
||||
return regeneratorRuntime.wrap(function(_ctx) {
|
||||
for(;;)switch(_ctx.prev = _ctx.next){
|
||||
case 0:
|
||||
@ -104,7 +104,7 @@ var C0 = function() {
|
||||
return p;
|
||||
}, C0;
|
||||
}();
|
||||
C0.a = s, C0.b = N.s, C0.c = N.s, C0.d = s, C0.e = N.s, C0.f = N.s, o[s], o[N.s], o[N.s], f(s), f(N.s), f(N.s), g(s), g(N.s), g(N.s), s, N.s, N.s, 2 * Math.random() && N.s, 2 * Math.random() && N.s, _obj = {}, swcHelpers.defineProperty(_obj, s, "a"), swcHelpers.defineProperty(_obj, N.s, "b");
|
||||
C0.a = s, C0.b = N.s, C0.c = N.s, C0.d = s, C0.e = N.s, C0.f = N.s, o[s], o[N.s], o[N.s], f(s), f(N.s), f(N.s), g(s), g(N.s), g(N.s), N.s, N.s, 2 * Math.random() && N.s, 2 * Math.random() && N.s, _obj = {}, swcHelpers.defineProperty(_obj, s, "a"), swcHelpers.defineProperty(_obj, N.s, "b");
|
||||
var C1 = function() {
|
||||
"use strict";
|
||||
swcHelpers.classCallCheck(this, C1);
|
||||
|
@ -1 +1 @@
|
||||
g, o.method;
|
||||
o.method;
|
||||
|
@ -1 +1 @@
|
||||
g, o.method;
|
||||
o.method;
|
||||
|
@ -134,7 +134,8 @@ fn do_test(_entry: &Path, entries: HashMap<String, FileName>, inline: bool, mini
|
||||
..Default::default()
|
||||
},
|
||||
&ExtraOptions {
|
||||
top_level_mark: Mark::fresh(Mark::root()),
|
||||
unresolved_mark: Mark::new(),
|
||||
top_level_mark: Mark::new(),
|
||||
},
|
||||
);
|
||||
b.module.visit_mut_with(&mut fixer(None));
|
||||
|
@ -10,7 +10,7 @@ use swc_ecma_ast::{
|
||||
CallExpr, Callee, Expr, Ident, ImportDecl, ImportSpecifier, MemberExpr, MemberProp, Module,
|
||||
ModuleDecl, ModuleExportName, Str, SuperProp, SuperPropExpr,
|
||||
};
|
||||
use swc_ecma_transforms_base::resolver::resolver_with_mark;
|
||||
use swc_ecma_transforms_base::resolver;
|
||||
use swc_ecma_visit::{
|
||||
noop_visit_mut_type, noop_visit_type, FoldWith, Visit, VisitMut, VisitMutWith, VisitWith,
|
||||
};
|
||||
@ -137,7 +137,9 @@ where
|
||||
|
||||
data.module.visit_mut_with(&mut ClearMark);
|
||||
|
||||
let mut module = data.module.fold_with(&mut resolver_with_mark(local_mark));
|
||||
let mut module = data
|
||||
.module
|
||||
.fold_with(&mut resolver(local_mark, local_mark, false));
|
||||
|
||||
// {
|
||||
// let code = self
|
||||
|
@ -20,7 +20,7 @@ use swc_ecma_ast::EsVersion;
|
||||
use swc_ecma_parser::{parse_file_as_module, Syntax, TsConfig};
|
||||
use swc_ecma_transforms_base::{
|
||||
helpers::{inject_helpers, Helpers, HELPERS},
|
||||
resolver::resolver_with_mark,
|
||||
resolver,
|
||||
};
|
||||
use swc_ecma_transforms_proposal::decorators;
|
||||
use swc_ecma_transforms_react::react;
|
||||
@ -90,7 +90,8 @@ impl Load for Loader {
|
||||
fn load(&self, f: &FileName) -> Result<ModuleData, Error> {
|
||||
eprintln!("load: {}", f);
|
||||
|
||||
let top_level_mark = Mark::fresh(Mark::root());
|
||||
let unresolved_mark = Mark::new();
|
||||
let top_level_mark = Mark::new();
|
||||
|
||||
let tsx;
|
||||
let fm = match f {
|
||||
@ -131,15 +132,14 @@ impl Load for Loader {
|
||||
panic!("failed to parse")
|
||||
});
|
||||
|
||||
let mark = Mark::fresh(Mark::root());
|
||||
let module = HELPERS.set(&Helpers::new(false), || {
|
||||
module
|
||||
.fold_with(&mut resolver_with_mark(mark))
|
||||
.fold_with(&mut resolver(unresolved_mark, top_level_mark, false))
|
||||
.fold_with(&mut decorators(decorators::Config {
|
||||
legacy: true,
|
||||
emit_metadata: Default::default(),
|
||||
}))
|
||||
.fold_with(&mut strip(mark))
|
||||
.fold_with(&mut strip(top_level_mark))
|
||||
.fold_with(&mut react::<SingleThreadedComments>(
|
||||
self.cm.clone(),
|
||||
None,
|
||||
|
@ -16,7 +16,7 @@ use swc_ecma_codegen::{
|
||||
Emitter,
|
||||
};
|
||||
use swc_ecma_minifier::option::MangleOptions;
|
||||
use swc_ecma_transforms_base::{fixer::fixer, resolver::resolver_with_mark};
|
||||
use swc_ecma_transforms_base::{fixer::fixer, resolver};
|
||||
use swc_ecma_utils::{find_ids, Id};
|
||||
use swc_ecma_visit::{Visit, VisitMutWith, VisitWith};
|
||||
use testing::assert_eq;
|
||||
@ -1047,9 +1047,10 @@ fn bundle(url: &str, minify: bool) -> String {
|
||||
let mut module = output.into_iter().next().unwrap().module;
|
||||
|
||||
if minify {
|
||||
let top_level_mark = Mark::fresh(Mark::root());
|
||||
let unresolved_mark = Mark::new();
|
||||
let top_level_mark = Mark::new();
|
||||
|
||||
module.visit_mut_with(&mut resolver_with_mark(top_level_mark));
|
||||
module.visit_mut_with(&mut resolver(unresolved_mark, top_level_mark, false));
|
||||
|
||||
module = swc_ecma_minifier::optimize(
|
||||
module,
|
||||
@ -1064,7 +1065,10 @@ fn bundle(url: &str, minify: bool) -> String {
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
&swc_ecma_minifier::option::ExtraOptions { top_level_mark },
|
||||
&swc_ecma_minifier::option::ExtraOptions {
|
||||
unresolved_mark,
|
||||
top_level_mark,
|
||||
},
|
||||
);
|
||||
module.visit_mut_with(&mut fixer(None));
|
||||
}
|
||||
|
@ -94,6 +94,12 @@ extern "C" {
|
||||
}
|
||||
|
||||
impl Mark {
|
||||
/// Shortcut for `Mark::fresh(Mark::root())`
|
||||
#[allow(clippy::new_without_default)]
|
||||
pub fn new() -> Self {
|
||||
Mark::fresh(Mark::root())
|
||||
}
|
||||
|
||||
pub fn fresh(parent: Mark) -> Self {
|
||||
// Note: msvc tries to link against proxied fn for normal build,
|
||||
// have to limit build target to wasm only to avoid it.
|
||||
|
@ -2,7 +2,7 @@ use swc_common::{errors::HANDLER, Mark, SyntaxContext};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_lints::{rule::Rule, rules::LintParams};
|
||||
use swc_ecma_parser::Syntax;
|
||||
use swc_ecma_transforms_base::resolver::resolver_with_mark;
|
||||
use swc_ecma_transforms_base::resolver;
|
||||
use swc_ecma_visit::VisitMutWith;
|
||||
|
||||
fn main() {
|
||||
@ -28,14 +28,17 @@ fn main() {
|
||||
}
|
||||
};
|
||||
|
||||
let top_level_mark = Mark::fresh(Mark::root());
|
||||
let unresolved_mark = Mark::new();
|
||||
let top_level_mark = Mark::new();
|
||||
let unresolved_ctxt = SyntaxContext::empty().apply_mark(unresolved_mark);
|
||||
let top_level_ctxt = SyntaxContext::empty().apply_mark(top_level_mark);
|
||||
|
||||
program.visit_mut_with(&mut resolver_with_mark(top_level_mark));
|
||||
program.visit_mut_with(&mut resolver(unresolved_mark, top_level_mark, false));
|
||||
|
||||
let mut rules = swc_ecma_lints::rules::all(LintParams {
|
||||
program: &program,
|
||||
lint_config: &Default::default(),
|
||||
unresolved_ctxt,
|
||||
top_level_ctxt,
|
||||
es_version: EsVersion::latest(),
|
||||
source_map: cm.clone(),
|
||||
|
@ -46,6 +46,7 @@ use non_critical_lints::*;
|
||||
pub struct LintParams<'a> {
|
||||
pub program: &'a Program,
|
||||
pub lint_config: &'a LintConfig,
|
||||
pub unresolved_ctxt: SyntaxContext,
|
||||
pub top_level_ctxt: SyntaxContext,
|
||||
pub es_version: EsVersion,
|
||||
pub source_map: Arc<SourceMap>,
|
||||
@ -64,7 +65,8 @@ pub fn all(lint_params: LintParams) -> Vec<Box<dyn Rule>> {
|
||||
let LintParams {
|
||||
program,
|
||||
lint_config,
|
||||
top_level_ctxt,
|
||||
unresolved_ctxt,
|
||||
top_level_ctxt: _,
|
||||
es_version,
|
||||
source_map,
|
||||
} = lint_params;
|
||||
@ -75,13 +77,12 @@ pub fn all(lint_params: LintParams) -> Vec<Box<dyn Rule>> {
|
||||
|
||||
rules.extend(no_console::no_console(
|
||||
&lint_config.no_console,
|
||||
top_level_ctxt,
|
||||
unresolved_ctxt,
|
||||
));
|
||||
|
||||
rules.extend(no_alert::no_alert(
|
||||
program,
|
||||
&lint_config.no_alert,
|
||||
top_level_ctxt,
|
||||
unresolved_ctxt,
|
||||
es_version,
|
||||
));
|
||||
|
||||
@ -90,9 +91,8 @@ pub fn all(lint_params: LintParams) -> Vec<Box<dyn Rule>> {
|
||||
rules.extend(quotes::quotes(&lint_config.quotes));
|
||||
|
||||
rules.extend(prefer_regex_literals::prefer_regex_literals(
|
||||
program,
|
||||
&lint_config.prefer_regex_literals,
|
||||
top_level_ctxt,
|
||||
unresolved_ctxt,
|
||||
es_version,
|
||||
));
|
||||
|
||||
@ -120,7 +120,7 @@ pub fn all(lint_params: LintParams) -> Vec<Box<dyn Rule>> {
|
||||
&lint_config.no_restricted_syntax,
|
||||
));
|
||||
|
||||
rules.extend(radix::radix(program, top_level_ctxt, &lint_config.radix));
|
||||
rules.extend(radix::radix(unresolved_ctxt, &lint_config.radix));
|
||||
|
||||
rules.extend(no_bitwise::no_bitwise(&lint_config.no_bitwise));
|
||||
|
||||
@ -131,14 +131,12 @@ pub fn all(lint_params: LintParams) -> Vec<Box<dyn Rule>> {
|
||||
rules.extend(yoda::yoda(&lint_config.yoda));
|
||||
|
||||
rules.extend(no_new_symbol::no_new_symbol(
|
||||
program,
|
||||
top_level_ctxt,
|
||||
unresolved_ctxt,
|
||||
&lint_config.no_new_symbol,
|
||||
));
|
||||
|
||||
rules.extend(use_is_nan::use_is_nan(
|
||||
program,
|
||||
top_level_ctxt,
|
||||
unresolved_ctxt,
|
||||
&lint_config.use_isnan,
|
||||
));
|
||||
|
||||
@ -149,14 +147,12 @@ pub fn all(lint_params: LintParams) -> Vec<Box<dyn Rule>> {
|
||||
));
|
||||
|
||||
rules.extend(symbol_description::symbol_description(
|
||||
program,
|
||||
top_level_ctxt,
|
||||
unresolved_ctxt,
|
||||
&lint_config.symbol_description,
|
||||
));
|
||||
|
||||
rules.extend(no_obj_calls::no_obj_calls(
|
||||
program,
|
||||
top_level_ctxt,
|
||||
unresolved_ctxt,
|
||||
&lint_config.no_obj_calls,
|
||||
));
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::{collections::AHashSet, errors::HANDLER, Span, SyntaxContext};
|
||||
use swc_common::{errors::HANDLER, Span, SyntaxContext};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::{collect_decls_with_ctxt, ident::IdentLike};
|
||||
use swc_ecma_visit::{noop_visit_type, Visit, VisitWith};
|
||||
|
||||
use crate::{
|
||||
@ -14,9 +13,8 @@ const GLOBAL_THIS_PROP: &str = "globalThis";
|
||||
const OBJ_NAMES: &[&str] = &["window", GLOBAL_THIS_PROP];
|
||||
|
||||
pub fn no_alert(
|
||||
program: &Program,
|
||||
config: &RuleConfig<()>,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
unresolved_ctxt: SyntaxContext,
|
||||
es_version: EsVersion,
|
||||
) -> Option<Box<dyn Rule>> {
|
||||
let rule_reaction = config.get_rule_reaction();
|
||||
@ -25,8 +23,7 @@ pub fn no_alert(
|
||||
LintRuleReaction::Off => None,
|
||||
_ => Some(visitor_rule(NoAlert::new(
|
||||
rule_reaction,
|
||||
collect_decls_with_ctxt(program, top_level_ctxt),
|
||||
top_level_ctxt,
|
||||
unresolved_ctxt,
|
||||
es_version,
|
||||
))),
|
||||
}
|
||||
@ -35,8 +32,7 @@ pub fn no_alert(
|
||||
#[derive(Debug, Default)]
|
||||
struct NoAlert {
|
||||
expected_reaction: LintRuleReaction,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
top_level_declared_vars: AHashSet<Id>,
|
||||
unresolved_ctxt: SyntaxContext,
|
||||
pass_call_on_global_this: bool,
|
||||
inside_callee: bool,
|
||||
classes_depth: usize,
|
||||
@ -49,14 +45,12 @@ struct NoAlert {
|
||||
impl NoAlert {
|
||||
fn new(
|
||||
expected_reaction: LintRuleReaction,
|
||||
top_level_declared_vars: AHashSet<Id>,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
unresolved_ctxt: SyntaxContext,
|
||||
es_version: EsVersion,
|
||||
) -> Self {
|
||||
Self {
|
||||
expected_reaction,
|
||||
top_level_ctxt,
|
||||
top_level_declared_vars,
|
||||
unresolved_ctxt,
|
||||
pass_call_on_global_this: es_version < EsVersion::Es2020,
|
||||
inside_callee: false,
|
||||
classes_depth: 0,
|
||||
@ -114,11 +108,7 @@ impl NoAlert {
|
||||
}
|
||||
|
||||
fn is_satisfying_indent(&self, ident: &Ident) -> bool {
|
||||
if ident.span.ctxt != self.top_level_ctxt {
|
||||
return false;
|
||||
}
|
||||
|
||||
if self.top_level_declared_vars.contains(&ident.to_id()) {
|
||||
if ident.span.ctxt != self.unresolved_ctxt {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -18,23 +18,23 @@ pub struct NoConsoleConfig {
|
||||
|
||||
pub fn no_console(
|
||||
config: &RuleConfig<NoConsoleConfig>,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
unresolved_ctxt: SyntaxContext,
|
||||
) -> Option<Box<dyn Rule>> {
|
||||
match config.get_rule_reaction() {
|
||||
LintRuleReaction::Off => None,
|
||||
_ => Some(visitor_rule(NoConsole::new(config, top_level_ctxt))),
|
||||
_ => Some(visitor_rule(NoConsole::new(config, unresolved_ctxt))),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct NoConsole {
|
||||
expected_reaction: LintRuleReaction,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
unresolved_ctxt: SyntaxContext,
|
||||
allow: Option<AHashSet<JsWord>>,
|
||||
}
|
||||
|
||||
impl NoConsole {
|
||||
fn new(config: &RuleConfig<NoConsoleConfig>, top_level_ctxt: SyntaxContext) -> Self {
|
||||
fn new(config: &RuleConfig<NoConsoleConfig>, unresolved_ctxt: SyntaxContext) -> Self {
|
||||
Self {
|
||||
expected_reaction: config.get_rule_reaction(),
|
||||
allow: config.get_rule_config().allow.as_ref().map(|method_names| {
|
||||
@ -43,12 +43,12 @@ impl NoConsole {
|
||||
.map(|method_name| JsWord::from(method_name.as_str()))
|
||||
.collect()
|
||||
}),
|
||||
top_level_ctxt,
|
||||
unresolved_ctxt,
|
||||
}
|
||||
}
|
||||
|
||||
fn check(&self, span: Span, ident: &Ident, method: &JsWord) {
|
||||
if &*ident.sym == "console" && ident.span.ctxt == self.top_level_ctxt {
|
||||
if &*ident.sym == "console" && ident.span.ctxt == self.unresolved_ctxt {
|
||||
if let Some(allow) = &self.allow {
|
||||
if allow.contains(method) {
|
||||
return;
|
||||
|
@ -1,6 +1,5 @@
|
||||
use swc_common::{collections::AHashSet, errors::HANDLER, Span, SyntaxContext};
|
||||
use swc_common::{errors::HANDLER, Span, SyntaxContext};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::{collect_decls_with_ctxt, ident::IdentLike};
|
||||
use swc_ecma_visit::{noop_visit_type, Visit, VisitWith};
|
||||
|
||||
use crate::{
|
||||
@ -11,8 +10,7 @@ use crate::{
|
||||
const MESSAGE: &str = "`Symbol` cannot be called as a constructor";
|
||||
|
||||
pub fn no_new_symbol(
|
||||
program: &Program,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
unresolved_ctxt: SyntaxContext,
|
||||
config: &RuleConfig<()>,
|
||||
) -> Option<Box<dyn Rule>> {
|
||||
let expected_reaction = config.get_rule_reaction();
|
||||
@ -20,8 +18,7 @@ pub fn no_new_symbol(
|
||||
match expected_reaction {
|
||||
LintRuleReaction::Off => None,
|
||||
_ => Some(visitor_rule(NoNewSymbol::new(
|
||||
collect_decls_with_ctxt(program, top_level_ctxt),
|
||||
top_level_ctxt,
|
||||
unresolved_ctxt,
|
||||
expected_reaction,
|
||||
))),
|
||||
}
|
||||
@ -30,29 +27,19 @@ pub fn no_new_symbol(
|
||||
#[derive(Debug, Default)]
|
||||
struct NoNewSymbol {
|
||||
expected_reaction: LintRuleReaction,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
top_level_declared_vars: AHashSet<Id>,
|
||||
unresolved_ctxt: SyntaxContext,
|
||||
}
|
||||
|
||||
impl NoNewSymbol {
|
||||
fn new(
|
||||
top_level_declared_vars: AHashSet<Id>,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
expected_reaction: LintRuleReaction,
|
||||
) -> Self {
|
||||
fn new(unresolved_ctxt: SyntaxContext, expected_reaction: LintRuleReaction) -> Self {
|
||||
Self {
|
||||
expected_reaction,
|
||||
top_level_ctxt,
|
||||
top_level_declared_vars,
|
||||
unresolved_ctxt,
|
||||
}
|
||||
}
|
||||
|
||||
fn check(&self, span: Span, ident: &Ident) {
|
||||
if self.top_level_declared_vars.contains(&ident.to_id()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ident.span.ctxt != self.top_level_ctxt {
|
||||
if ident.span.ctxt != self.unresolved_ctxt {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
use swc_common::{collections::AHashSet, errors::HANDLER, Span, SyntaxContext};
|
||||
use swc_common::{errors::HANDLER, Span, SyntaxContext};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::{collect_decls_with_ctxt, ident::IdentLike};
|
||||
use swc_ecma_visit::{Visit, VisitWith};
|
||||
|
||||
use crate::{
|
||||
@ -11,8 +10,7 @@ use crate::{
|
||||
const OBJECTS_NAMES: &[&str] = &["Math", "JSON", "Reflect", "Atomics"];
|
||||
|
||||
pub fn no_obj_calls(
|
||||
program: &Program,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
unresolved_ctxt: SyntaxContext,
|
||||
config: &RuleConfig<()>,
|
||||
) -> Option<Box<dyn Rule>> {
|
||||
let expected_reaction = config.get_rule_reaction();
|
||||
@ -20,8 +18,7 @@ pub fn no_obj_calls(
|
||||
match expected_reaction {
|
||||
LintRuleReaction::Off => None,
|
||||
_ => Some(visitor_rule(NoObjCalls::new(
|
||||
collect_decls_with_ctxt(program, top_level_ctxt),
|
||||
top_level_ctxt,
|
||||
unresolved_ctxt,
|
||||
expected_reaction,
|
||||
))),
|
||||
}
|
||||
@ -30,20 +27,14 @@ pub fn no_obj_calls(
|
||||
#[derive(Debug, Default)]
|
||||
struct NoObjCalls {
|
||||
expected_reaction: LintRuleReaction,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
top_level_declared_vars: AHashSet<Id>,
|
||||
unresolved_ctxt: SyntaxContext,
|
||||
}
|
||||
|
||||
impl NoObjCalls {
|
||||
fn new(
|
||||
top_level_declared_vars: AHashSet<Id>,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
expected_reaction: LintRuleReaction,
|
||||
) -> Self {
|
||||
fn new(unresolved_ctxt: SyntaxContext, expected_reaction: LintRuleReaction) -> Self {
|
||||
Self {
|
||||
expected_reaction,
|
||||
top_level_ctxt,
|
||||
top_level_declared_vars,
|
||||
unresolved_ctxt,
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,11 +53,7 @@ impl NoObjCalls {
|
||||
}
|
||||
|
||||
fn check(&self, span: Span, ident: &Ident) {
|
||||
if self.top_level_declared_vars.contains(&ident.to_id()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ident.span.ctxt != self.top_level_ctxt {
|
||||
if ident.span.ctxt != self.unresolved_ctxt {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use swc_common::{collections::AHashSet, errors::HANDLER, Span, SyntaxContext};
|
||||
use swc_common::{errors::HANDLER, Span, SyntaxContext};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::{collect_decls_with_ctxt, ident::IdentLike};
|
||||
use swc_ecma_visit::{noop_visit_type, Visit, VisitWith};
|
||||
|
||||
use crate::{
|
||||
@ -28,9 +27,8 @@ pub struct PreferRegexLiteralsConfig {
|
||||
}
|
||||
|
||||
pub fn prefer_regex_literals(
|
||||
program: &Program,
|
||||
config: &RuleConfig<PreferRegexLiteralsConfig>,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
unresolved_ctxt: SyntaxContext,
|
||||
es_version: EsVersion,
|
||||
) -> Option<Box<dyn Rule>> {
|
||||
let rule_reaction = config.get_rule_reaction();
|
||||
@ -45,8 +43,7 @@ pub fn prefer_regex_literals(
|
||||
_ => Some(visitor_rule(PreferRegexLiterals::new(
|
||||
rule_reaction,
|
||||
disallow_redundant_wrapping,
|
||||
collect_decls_with_ctxt(program, top_level_ctxt),
|
||||
top_level_ctxt,
|
||||
unresolved_ctxt,
|
||||
es_version,
|
||||
))),
|
||||
}
|
||||
@ -56,8 +53,7 @@ pub fn prefer_regex_literals(
|
||||
struct PreferRegexLiterals {
|
||||
expected_reaction: LintRuleReaction,
|
||||
disallow_redundant_wrapping: bool,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
top_level_declared_vars: AHashSet<Id>,
|
||||
unresolved_ctxt: SyntaxContext,
|
||||
allow_global_this: bool,
|
||||
call_span: Option<Span>,
|
||||
first_arg: Option<ArgValue>,
|
||||
@ -68,15 +64,13 @@ impl PreferRegexLiterals {
|
||||
fn new(
|
||||
expected_reaction: LintRuleReaction,
|
||||
disallow_redundant_wrapping: bool,
|
||||
top_level_declared_vars: AHashSet<Id>,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
unresolved_ctxt: SyntaxContext,
|
||||
es_version: EsVersion,
|
||||
) -> Self {
|
||||
Self {
|
||||
expected_reaction,
|
||||
disallow_redundant_wrapping,
|
||||
top_level_ctxt,
|
||||
top_level_declared_vars,
|
||||
unresolved_ctxt,
|
||||
allow_global_this: es_version < EsVersion::Es2020,
|
||||
call_span: None,
|
||||
first_arg: None,
|
||||
@ -95,16 +89,14 @@ impl PreferRegexLiterals {
|
||||
|
||||
if let Some(ExprOrSpread { expr, .. }) = args.get(0) {
|
||||
self.first_arg = Some(extract_arg_val(
|
||||
&self.top_level_ctxt,
|
||||
&self.top_level_declared_vars,
|
||||
self.unresolved_ctxt,
|
||||
unwrap_seqs_and_parens(expr.as_ref()),
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(ExprOrSpread { expr, .. }) = args.get(1) {
|
||||
self.second_arg = Some(extract_arg_val(
|
||||
&self.top_level_ctxt,
|
||||
&self.top_level_declared_vars,
|
||||
self.unresolved_ctxt,
|
||||
unwrap_seqs_and_parens(expr.as_ref()),
|
||||
));
|
||||
}
|
||||
@ -183,11 +175,7 @@ impl Visit for PreferRegexLiterals {
|
||||
}
|
||||
|
||||
fn visit_ident(&mut self, ident: &Ident) {
|
||||
if ident.span.ctxt != self.top_level_ctxt {
|
||||
return;
|
||||
}
|
||||
|
||||
if self.top_level_declared_vars.contains(&ident.to_id()) {
|
||||
if ident.span.ctxt != self.unresolved_ctxt {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -208,11 +196,7 @@ impl Visit for PreferRegexLiterals {
|
||||
}
|
||||
|
||||
if let Some(ident) = member_expr.obj.as_ident() {
|
||||
if ident.span.ctxt != self.top_level_ctxt {
|
||||
return;
|
||||
}
|
||||
|
||||
if self.top_level_declared_vars.contains(&ident.to_id()) {
|
||||
if ident.span.ctxt != self.unresolved_ctxt {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,10 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::{
|
||||
collections::AHashSet,
|
||||
errors::{DiagnosticBuilder, HANDLER},
|
||||
Span, SyntaxContext,
|
||||
};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::{collect_decls_with_ctxt, ident::IdentLike};
|
||||
use swc_ecma_visit::{noop_visit_type, Visit, VisitWith};
|
||||
|
||||
use crate::{
|
||||
@ -45,25 +43,19 @@ pub struct RadixConfig {
|
||||
}
|
||||
|
||||
pub fn radix(
|
||||
program: &Program,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
unresolved_ctxt: SyntaxContext,
|
||||
config: &RuleConfig<RadixConfig>,
|
||||
) -> Option<Box<dyn Rule>> {
|
||||
match config.get_rule_reaction() {
|
||||
LintRuleReaction::Off => None,
|
||||
_ => Some(visitor_rule(Radix::new(
|
||||
collect_decls_with_ctxt(program, top_level_ctxt),
|
||||
top_level_ctxt,
|
||||
config,
|
||||
))),
|
||||
_ => Some(visitor_rule(Radix::new(unresolved_ctxt, config))),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
struct Radix {
|
||||
expected_reaction: LintRuleReaction,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
top_level_declared_vars: AHashSet<Id>,
|
||||
unresolved_ctxt: SyntaxContext,
|
||||
|
||||
radix_mode: RadixMode,
|
||||
unwrap_parens_and_seqs: bool,
|
||||
@ -74,17 +66,12 @@ struct Radix {
|
||||
}
|
||||
|
||||
impl Radix {
|
||||
fn new(
|
||||
top_level_declared_vars: AHashSet<Id>,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
config: &RuleConfig<RadixConfig>,
|
||||
) -> Self {
|
||||
fn new(unresolved_ctxt: SyntaxContext, config: &RuleConfig<RadixConfig>) -> Self {
|
||||
let rule_config = config.get_rule_config();
|
||||
|
||||
Self {
|
||||
expected_reaction: config.get_rule_reaction(),
|
||||
top_level_ctxt,
|
||||
top_level_declared_vars,
|
||||
unresolved_ctxt,
|
||||
|
||||
radix_mode: rule_config.mode.unwrap_or_default(),
|
||||
unwrap_parens_and_seqs: rule_config.unwrap_parens_and_seqs.unwrap_or(true),
|
||||
@ -158,7 +145,7 @@ impl Radix {
|
||||
expr.as_ref()
|
||||
};
|
||||
|
||||
match &extract_arg_val(&self.top_level_ctxt, &self.top_level_declared_vars, expr) {
|
||||
match &extract_arg_val(self.unresolved_ctxt, expr) {
|
||||
ArgValue::Ident => {}
|
||||
ArgValue::Number(radix) => {
|
||||
if radix.fract() != 0.0 || !(2f64..=36f64).contains(radix) {
|
||||
@ -191,11 +178,7 @@ impl Radix {
|
||||
}
|
||||
|
||||
fn is_satisfying_indent(&self, ident: &Ident) -> bool {
|
||||
if ident.span.ctxt != self.top_level_ctxt {
|
||||
return false;
|
||||
}
|
||||
|
||||
if self.top_level_declared_vars.contains(&ident.to_id()) {
|
||||
if ident.span.ctxt != self.unresolved_ctxt {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use swc_common::{collections::AHashSet, errors::HANDLER, Span, SyntaxContext};
|
||||
use swc_common::{errors::HANDLER, Span, SyntaxContext};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::{collect_decls_with_ctxt, ident::IdentLike};
|
||||
use swc_ecma_visit::{Visit, VisitWith};
|
||||
|
||||
use crate::{
|
||||
@ -20,15 +19,13 @@ pub struct SymbolDescriptionConfig {
|
||||
}
|
||||
|
||||
pub fn symbol_description(
|
||||
program: &Program,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
unresolved_ctxt: SyntaxContext,
|
||||
config: &RuleConfig<SymbolDescriptionConfig>,
|
||||
) -> Option<Box<dyn Rule>> {
|
||||
match config.get_rule_reaction() {
|
||||
LintRuleReaction::Off => None,
|
||||
_ => Some(visitor_rule(SymbolDescription::new(
|
||||
collect_decls_with_ctxt(program, top_level_ctxt),
|
||||
top_level_ctxt,
|
||||
unresolved_ctxt,
|
||||
config,
|
||||
))),
|
||||
}
|
||||
@ -37,33 +34,25 @@ pub fn symbol_description(
|
||||
#[derive(Debug, Default)]
|
||||
struct SymbolDescription {
|
||||
expected_reaction: LintRuleReaction,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
top_level_declared_vars: AHashSet<Id>,
|
||||
unresolved_ctxt: SyntaxContext,
|
||||
|
||||
enforce_string_description: bool,
|
||||
}
|
||||
|
||||
impl SymbolDescription {
|
||||
fn new(
|
||||
top_level_declared_vars: AHashSet<Id>,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
config: &RuleConfig<SymbolDescriptionConfig>,
|
||||
) -> Self {
|
||||
fn new(unresolved_ctxt: SyntaxContext, config: &RuleConfig<SymbolDescriptionConfig>) -> Self {
|
||||
let rule_config = config.get_rule_config();
|
||||
|
||||
Self {
|
||||
expected_reaction: config.get_rule_reaction(),
|
||||
top_level_ctxt,
|
||||
top_level_declared_vars,
|
||||
unresolved_ctxt,
|
||||
|
||||
enforce_string_description: rule_config.enforce_string_description.unwrap_or(true),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_symbol_call(&self, ident: &Ident) -> bool {
|
||||
if self.top_level_declared_vars.contains(&ident.to_id()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ident.span.ctxt != self.top_level_ctxt {
|
||||
if ident.span.ctxt != self.unresolved_ctxt {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -73,11 +62,7 @@ impl SymbolDescription {
|
||||
fn check(&self, span: Span, first_arg: Option<&ExprOrSpread>) {
|
||||
if let Some(ExprOrSpread { expr, .. }) = first_arg {
|
||||
if self.enforce_string_description {
|
||||
match extract_arg_val(
|
||||
&self.top_level_ctxt,
|
||||
&self.top_level_declared_vars,
|
||||
unwrap_seqs_and_parens(expr),
|
||||
) {
|
||||
match extract_arg_val(self.unresolved_ctxt, unwrap_seqs_and_parens(expr)) {
|
||||
ArgValue::Str(_) => {}
|
||||
_ => {
|
||||
self.emit_report(span, SYMBOL_STRING_DESCRIPTION_EXPECTED_MESSAGE);
|
||||
|
@ -1,7 +1,6 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use swc_common::{collections::AHashSet, errors::HANDLER, Span, SyntaxContext};
|
||||
use swc_common::{errors::HANDLER, Span, SyntaxContext};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::{collect_decls_with_ctxt, ident::IdentLike};
|
||||
use swc_ecma_visit::{Visit, VisitWith};
|
||||
|
||||
use crate::{
|
||||
@ -20,42 +19,32 @@ pub struct UseIsNanConfig {
|
||||
}
|
||||
|
||||
pub fn use_is_nan(
|
||||
program: &Program,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
unresolved_ctxt: SyntaxContext,
|
||||
config: &RuleConfig<UseIsNanConfig>,
|
||||
) -> Option<Box<dyn Rule>> {
|
||||
match config.get_rule_reaction() {
|
||||
LintRuleReaction::Off => None,
|
||||
_ => Some(visitor_rule(UseIsNan::new(
|
||||
collect_decls_with_ctxt(program, top_level_ctxt),
|
||||
top_level_ctxt,
|
||||
config,
|
||||
))),
|
||||
_ => Some(visitor_rule(UseIsNan::new(unresolved_ctxt, config))),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct UseIsNan {
|
||||
expected_reaction: LintRuleReaction,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
top_level_declared_vars: AHashSet<Id>,
|
||||
unresolved_ctxt: SyntaxContext,
|
||||
|
||||
enforce_for_switch_case: bool,
|
||||
enforce_for_index_of: bool,
|
||||
check_any_cast: bool,
|
||||
}
|
||||
|
||||
impl UseIsNan {
|
||||
fn new(
|
||||
top_level_declared_vars: AHashSet<Id>,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
config: &RuleConfig<UseIsNanConfig>,
|
||||
) -> Self {
|
||||
fn new(unresolved_ctxt: SyntaxContext, config: &RuleConfig<UseIsNanConfig>) -> Self {
|
||||
let rule_config = config.get_rule_config();
|
||||
|
||||
Self {
|
||||
expected_reaction: config.get_rule_reaction(),
|
||||
top_level_declared_vars,
|
||||
top_level_ctxt,
|
||||
unresolved_ctxt,
|
||||
enforce_for_switch_case: rule_config.enforce_for_switch_case.unwrap_or(true),
|
||||
enforce_for_index_of: rule_config.enforce_for_index_of.unwrap_or(true),
|
||||
check_any_cast: rule_config.check_any_cast.unwrap_or(true),
|
||||
@ -104,11 +93,7 @@ impl UseIsNan {
|
||||
obj, prop, span, ..
|
||||
}) => {
|
||||
if let Expr::Ident(obj) = obj.as_ref() {
|
||||
if obj.span.ctxt != self.top_level_ctxt {
|
||||
return;
|
||||
}
|
||||
|
||||
if self.top_level_declared_vars.contains(&obj.to_id()) {
|
||||
if obj.span.ctxt != self.unresolved_ctxt {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,9 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::{collections::AHashSet, SyntaxContext};
|
||||
use swc_common::SyntaxContext;
|
||||
use swc_ecma_ast::{
|
||||
Expr, Id, Lit, MemberExpr, MemberProp, Number, ParenExpr, Regex, SeqExpr, Str, TaggedTpl, Tpl,
|
||||
Expr, Lit, MemberExpr, MemberProp, Number, ParenExpr, Regex, SeqExpr, Str, TaggedTpl, Tpl,
|
||||
};
|
||||
use swc_ecma_utils::ident::IdentLike;
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
@ -52,11 +51,7 @@ pub enum ArgValue {
|
||||
Other,
|
||||
}
|
||||
|
||||
pub fn extract_arg_val(
|
||||
top_level_ctxt: &SyntaxContext,
|
||||
top_level_declared_vars: &AHashSet<Id>,
|
||||
expr: &Expr,
|
||||
) -> ArgValue {
|
||||
pub fn extract_arg_val(unresolved_ctxt: SyntaxContext, expr: &Expr) -> ArgValue {
|
||||
match expr {
|
||||
Expr::Ident(_) => ArgValue::Ident,
|
||||
Expr::Lit(Lit::Str(Str { value, .. })) => ArgValue::Str(value.clone()),
|
||||
@ -84,11 +79,7 @@ pub fn extract_arg_val(
|
||||
return ArgValue::Other;
|
||||
}
|
||||
|
||||
if obj.span.ctxt != *top_level_ctxt {
|
||||
return ArgValue::Other;
|
||||
}
|
||||
|
||||
if top_level_declared_vars.contains(&obj.to_id()) {
|
||||
if obj.span.ctxt != unresolved_ctxt {
|
||||
return ArgValue::Other;
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ use swc_ecma_lints::{
|
||||
rules::{all, LintParams},
|
||||
};
|
||||
use swc_ecma_parser::{lexer::Lexer, Parser, Syntax};
|
||||
use swc_ecma_transforms_base::resolver::{resolver_with_mark, ts_resolver};
|
||||
use swc_ecma_transforms_base::resolver;
|
||||
use swc_ecma_utils::HANDLER;
|
||||
use swc_ecma_visit::VisitMutWith;
|
||||
|
||||
@ -42,14 +42,14 @@ fn pass(input: PathBuf) {
|
||||
let mut parser = Parser::new_from(lexer);
|
||||
|
||||
let mut program = parser.parse_program().unwrap();
|
||||
let top_level_mark = Mark::fresh(Mark::root());
|
||||
let unresolved_mark = Mark::new();
|
||||
let top_level_mark = Mark::new();
|
||||
|
||||
if input.extension().unwrap() == "ts" || input.extension().unwrap() == "tsx" {
|
||||
program.visit_mut_with(&mut ts_resolver(top_level_mark));
|
||||
} else {
|
||||
program.visit_mut_with(&mut resolver_with_mark(top_level_mark));
|
||||
}
|
||||
let need_ts = input.extension().unwrap() == "ts" || input.extension().unwrap() == "tsx";
|
||||
|
||||
program.visit_mut_with(&mut resolver(unresolved_mark, top_level_mark, need_ts));
|
||||
|
||||
let unresolved_ctxt = SyntaxContext::empty().apply_mark(unresolved_mark);
|
||||
let top_level_ctxt = SyntaxContext::empty().apply_mark(top_level_mark);
|
||||
|
||||
let config = LintConfig::default();
|
||||
@ -57,6 +57,7 @@ fn pass(input: PathBuf) {
|
||||
let mut rules = all(LintParams {
|
||||
program: &program,
|
||||
lint_config: &config,
|
||||
unresolved_ctxt,
|
||||
top_level_ctxt,
|
||||
es_version,
|
||||
source_map: cm,
|
||||
|
@ -12,7 +12,7 @@ use swc_ecma_minifier::{
|
||||
option::{CompressOptions, ExtraOptions, MangleOptions, MinifyOptions},
|
||||
};
|
||||
use swc_ecma_parser::parse_file_as_module;
|
||||
use swc_ecma_transforms_base::{fixer::fixer, resolver::resolver_with_mark};
|
||||
use swc_ecma_transforms_base::{fixer::fixer, resolver};
|
||||
use swc_ecma_visit::FoldWith;
|
||||
|
||||
pub fn bench_files(c: &mut Criterion) {
|
||||
@ -51,7 +51,8 @@ fn run(src: &str) {
|
||||
testing::run_test2(false, |cm, handler| {
|
||||
let fm = cm.new_source_file(FileName::Anon, src.into());
|
||||
|
||||
let top_level_mark = Mark::fresh(Mark::root());
|
||||
let unresolved_mark = Mark::new();
|
||||
let top_level_mark = Mark::new();
|
||||
|
||||
let program = parse_file_as_module(
|
||||
&fm,
|
||||
@ -63,7 +64,7 @@ fn run(src: &str) {
|
||||
.map_err(|err| {
|
||||
err.into_diagnostic(&handler).emit();
|
||||
})
|
||||
.map(|module| module.fold_with(&mut resolver_with_mark(top_level_mark)))
|
||||
.map(|module| module.fold_with(&mut resolver(unresolved_mark, top_level_mark, false)))
|
||||
.unwrap();
|
||||
|
||||
let output = optimize(
|
||||
@ -89,7 +90,10 @@ fn run(src: &str) {
|
||||
wrap: false,
|
||||
enclose: false,
|
||||
},
|
||||
&ExtraOptions { top_level_mark },
|
||||
&ExtraOptions {
|
||||
unresolved_mark,
|
||||
top_level_mark,
|
||||
},
|
||||
);
|
||||
|
||||
let output = output.fold_with(&mut fixer(None));
|
||||
|
@ -15,7 +15,7 @@ use swc_ecma_minifier::{
|
||||
option::{ExtraOptions, MinifyOptions},
|
||||
};
|
||||
use swc_ecma_parser::parse_file_as_module;
|
||||
use swc_ecma_transforms_base::{fixer::fixer, resolver::resolver_with_mark};
|
||||
use swc_ecma_transforms_base::{fixer::fixer, resolver};
|
||||
use swc_ecma_visit::FoldWith;
|
||||
|
||||
fn main() {
|
||||
@ -26,7 +26,8 @@ fn main() {
|
||||
testing::run_test2(false, |cm, handler| {
|
||||
let fm = cm.load_file(Path::new(&file)).expect("failed to load file");
|
||||
|
||||
let top_level_mark = Mark::fresh(Mark::root());
|
||||
let unresolved_mark = Mark::new();
|
||||
let top_level_mark = Mark::new();
|
||||
|
||||
let program = parse_file_as_module(
|
||||
&fm,
|
||||
@ -38,7 +39,7 @@ fn main() {
|
||||
.map_err(|err| {
|
||||
err.into_diagnostic(&handler).emit();
|
||||
})
|
||||
.map(|module| module.fold_with(&mut resolver_with_mark(top_level_mark)))
|
||||
.map(|module| module.fold_with(&mut resolver(unresolved_mark, top_level_mark, false)))
|
||||
.unwrap();
|
||||
|
||||
let output = optimize(
|
||||
@ -51,7 +52,10 @@ fn main() {
|
||||
mangle: None,
|
||||
..Default::default()
|
||||
},
|
||||
&ExtraOptions { top_level_mark },
|
||||
&ExtraOptions {
|
||||
unresolved_mark,
|
||||
top_level_mark,
|
||||
},
|
||||
);
|
||||
|
||||
let output = output.fold_with(&mut fixer(None));
|
||||
|
@ -11,7 +11,7 @@ use swc_ecma_minifier::{
|
||||
option::{ExtraOptions, MangleOptions, MinifyOptions},
|
||||
};
|
||||
use swc_ecma_parser::parse_file_as_module;
|
||||
use swc_ecma_transforms_base::{fixer::fixer, resolver::resolver_with_mark};
|
||||
use swc_ecma_transforms_base::{fixer::fixer, resolver};
|
||||
use swc_ecma_visit::FoldWith;
|
||||
|
||||
fn main() {
|
||||
@ -22,7 +22,8 @@ fn main() {
|
||||
testing::run_test2(false, |cm, handler| {
|
||||
let fm = cm.load_file(Path::new(&file)).expect("failed to load file");
|
||||
|
||||
let top_level_mark = Mark::fresh(Mark::root());
|
||||
let unresolved_mark = Mark::new();
|
||||
let top_level_mark = Mark::new();
|
||||
|
||||
let program = parse_file_as_module(
|
||||
&fm,
|
||||
@ -34,7 +35,7 @@ fn main() {
|
||||
.map_err(|err| {
|
||||
err.into_diagnostic(&handler).emit();
|
||||
})
|
||||
.map(|module| module.fold_with(&mut resolver_with_mark(top_level_mark)))
|
||||
.map(|module| module.fold_with(&mut resolver(unresolved_mark, top_level_mark, false)))
|
||||
.unwrap();
|
||||
|
||||
let output = optimize(
|
||||
@ -50,7 +51,10 @@ fn main() {
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
&ExtraOptions { top_level_mark },
|
||||
&ExtraOptions {
|
||||
unresolved_mark,
|
||||
top_level_mark,
|
||||
},
|
||||
);
|
||||
|
||||
let output = output.fold_with(&mut fixer(None));
|
||||
|
@ -13,7 +13,7 @@ use swc_ecma_minifier::{
|
||||
option::{ExtraOptions, MangleOptions, MinifyOptions},
|
||||
};
|
||||
use swc_ecma_parser::parse_file_as_module;
|
||||
use swc_ecma_transforms_base::{fixer::fixer, resolver::resolver_with_mark};
|
||||
use swc_ecma_transforms_base::{fixer::fixer, resolver};
|
||||
use swc_ecma_visit::FoldWith;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
@ -29,7 +29,8 @@ fn main() {
|
||||
GLOBALS.set(globals, || {
|
||||
let fm = cm.load_file(&path).expect("failed to load file");
|
||||
|
||||
let top_level_mark = Mark::fresh(Mark::root());
|
||||
let unresolved_mark = Mark::new();
|
||||
let top_level_mark = Mark::new();
|
||||
|
||||
let program = parse_file_as_module(
|
||||
&fm,
|
||||
@ -41,7 +42,9 @@ fn main() {
|
||||
.map_err(|err| {
|
||||
err.into_diagnostic(&handler).emit();
|
||||
})
|
||||
.map(|module| module.fold_with(&mut resolver_with_mark(top_level_mark)))
|
||||
.map(|module| {
|
||||
module.fold_with(&mut resolver(unresolved_mark, top_level_mark, false))
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let output = optimize(
|
||||
@ -57,7 +60,10 @@ fn main() {
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
&ExtraOptions { top_level_mark },
|
||||
&ExtraOptions {
|
||||
unresolved_mark,
|
||||
top_level_mark,
|
||||
},
|
||||
);
|
||||
|
||||
let output = output.fold_with(&mut fixer(None));
|
||||
|
@ -3,7 +3,7 @@ use std::path::PathBuf;
|
||||
use swc_common::{comments::SingleThreadedComments, Mark};
|
||||
use swc_ecma_ast::Id;
|
||||
use swc_ecma_parser::{parse_file_as_module, EsConfig, Syntax};
|
||||
use swc_ecma_transforms_base::resolver::resolver_with_mark;
|
||||
use swc_ecma_transforms_base::resolver;
|
||||
use swc_ecma_visit::FoldWith;
|
||||
use testing::NormalizedOutput;
|
||||
|
||||
@ -20,7 +20,8 @@ fn snapshot(input: PathBuf) {
|
||||
let fm = cm.load_file(&input).expect("failed to load input.js");
|
||||
let comments = SingleThreadedComments::default();
|
||||
|
||||
let top_level_mark = Mark::fresh(Mark::root());
|
||||
let unresolved_mark = Mark::new();
|
||||
let top_level_mark = Mark::new();
|
||||
|
||||
let marks = Marks::new();
|
||||
|
||||
@ -37,7 +38,7 @@ fn snapshot(input: PathBuf) {
|
||||
.map_err(|err| {
|
||||
err.into_diagnostic(&handler).emit();
|
||||
})
|
||||
.map(|module| module.fold_with(&mut resolver_with_mark(top_level_mark)));
|
||||
.map(|module| module.fold_with(&mut resolver(unresolved_mark, top_level_mark, false)));
|
||||
|
||||
let program = match program {
|
||||
Ok(program) => program,
|
||||
|
@ -66,7 +66,7 @@ where
|
||||
as_folder(compressor),
|
||||
Optional {
|
||||
enabled: options.evaluate || options.side_effects,
|
||||
visitor: expr_simplifier(marks.top_level_mark, ExprSimplifierConfig {})
|
||||
visitor: expr_simplifier(marks.unresolved_mark, ExprSimplifierConfig {})
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -278,7 +278,7 @@ where
|
||||
|
||||
let start_time = now();
|
||||
|
||||
let mut visitor = expr_simplifier(self.marks.top_level_mark, ExprSimplifierConfig {});
|
||||
let mut visitor = expr_simplifier(self.marks.unresolved_mark, ExprSimplifierConfig {});
|
||||
n.apply(&mut visitor);
|
||||
|
||||
self.changed |= visitor.changed();
|
||||
@ -370,7 +370,7 @@ where
|
||||
|
||||
let start_time = now();
|
||||
|
||||
let mut v = dead_branch_remover(self.marks.top_level_mark);
|
||||
let mut v = dead_branch_remover(self.marks.unresolved_mark);
|
||||
n.apply(&mut v);
|
||||
|
||||
if let Some(start_time) = start_time {
|
||||
|
@ -411,7 +411,7 @@ where
|
||||
*e = Expr::Ident(Ident::new(
|
||||
js_word!("NaN"),
|
||||
bin.span.with_ctxt(
|
||||
SyntaxContext::empty().apply_mark(self.marks.top_level_mark),
|
||||
SyntaxContext::empty().apply_mark(self.marks.unresolved_mark),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
@ -972,7 +972,7 @@ where
|
||||
|
||||
if ids
|
||||
.iter()
|
||||
.all(|id| id.1.outer() == self.marks.top_level_mark)
|
||||
.all(|id| id.1.outer() == self.marks.unresolved_mark)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ where
|
||||
*n = Expr::Ident(Ident::new(
|
||||
js_word!("NaN"),
|
||||
span.with_ctxt(
|
||||
SyntaxContext::empty().apply_mark(self.marks.top_level_mark),
|
||||
SyntaxContext::empty().apply_mark(self.marks.unresolved_mark),
|
||||
),
|
||||
));
|
||||
self.changed = true;
|
||||
|
@ -270,7 +270,7 @@ where
|
||||
|
||||
match e {
|
||||
Expr::Ident(e) => {
|
||||
if e.span.ctxt.outer() == self.marks.top_level_mark {
|
||||
if e.span.ctxt.outer() == self.marks.unresolved_mark {
|
||||
if is_global_var(&e.sym) {
|
||||
return false;
|
||||
}
|
||||
|
@ -489,7 +489,7 @@ impl Pure<'_> {
|
||||
|
||||
if let Expr::Ident(i) = e {
|
||||
// If it's not a top level, it's a reference to a declared variable.
|
||||
if i.span.ctxt.outer() == self.marks.top_level_mark {
|
||||
if i.span.ctxt.outer() == self.marks.unresolved_mark {
|
||||
if self.options.side_effects
|
||||
|| (self.options.unused && opts.drop_global_refs_if_unused)
|
||||
{
|
||||
@ -580,14 +580,12 @@ impl Pure<'_> {
|
||||
}
|
||||
|
||||
Expr::Ident(i) => {
|
||||
if let Some(bindings) = self.bindings.as_deref() {
|
||||
if bindings.contains(&i.to_id()) {
|
||||
report_change!("Dropping an identifier as it's declared");
|
||||
if i.span.ctxt.outer() != self.marks.unresolved_mark {
|
||||
report_change!("Dropping an identifier as it's declared");
|
||||
|
||||
self.changed = true;
|
||||
*e = Expr::Invalid(Invalid { span: DUMMY_SP });
|
||||
return;
|
||||
}
|
||||
self.changed = true;
|
||||
*e = Expr::Invalid(Invalid { span: DUMMY_SP });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -736,14 +734,11 @@ impl Pure<'_> {
|
||||
// Remove pure member expressions.
|
||||
if let Expr::Member(MemberExpr { obj, prop, .. }) = e {
|
||||
if let Expr::Ident(obj) = &**obj {
|
||||
if obj.span.ctxt.outer() == self.marks.top_level_mark {
|
||||
if let Some(bindings) = self.bindings.as_deref() {
|
||||
if !bindings.contains(&obj.to_id()) {
|
||||
if is_pure_member_access(obj, prop) {
|
||||
self.changed = true;
|
||||
*e = Expr::Invalid(Invalid { span: DUMMY_SP });
|
||||
}
|
||||
}
|
||||
if obj.span.ctxt.outer() == self.marks.unresolved_mark {
|
||||
if is_pure_member_access(obj, prop) {
|
||||
self.changed = true;
|
||||
report_change!("Remving pure member access to global var");
|
||||
*e = Expr::Invalid(Invalid { span: DUMMY_SP });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,9 @@
|
||||
#![allow(clippy::needless_update)]
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use rayon::prelude::*;
|
||||
use swc_common::{collections::AHashSet, pass::Repeated, util::take::Take, DUMMY_SP, GLOBALS};
|
||||
use swc_common::{pass::Repeated, util::take::Take, DUMMY_SP, GLOBALS};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::{collect_decls, undefined};
|
||||
use swc_ecma_utils::undefined;
|
||||
use swc_ecma_visit::{noop_visit_mut_type, VisitMut, VisitMutWith, VisitWith};
|
||||
use tracing::{debug, span, Level};
|
||||
|
||||
@ -57,7 +55,6 @@ pub(crate) fn pure_optimizer<'a>(
|
||||
changed: Default::default(),
|
||||
enable_everything,
|
||||
debug_infinite_loop,
|
||||
bindings: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,8 +68,6 @@ struct Pure<'a> {
|
||||
enable_everything: bool,
|
||||
|
||||
debug_infinite_loop: bool,
|
||||
|
||||
bindings: Option<Arc<AHashSet<Id>>>,
|
||||
}
|
||||
|
||||
impl Repeated for Pure<'_> {
|
||||
@ -81,7 +76,6 @@ impl Repeated for Pure<'_> {
|
||||
}
|
||||
|
||||
fn reset(&mut self) {
|
||||
self.bindings = None;
|
||||
self.ctx = Default::default();
|
||||
self.changed = false;
|
||||
}
|
||||
@ -163,7 +157,6 @@ impl Pure<'_> {
|
||||
for node in nodes {
|
||||
let mut v = Pure {
|
||||
changed: false,
|
||||
bindings: self.bindings.clone(),
|
||||
..*self
|
||||
};
|
||||
node.visit_mut_with(&mut v);
|
||||
@ -182,7 +175,6 @@ impl Pure<'_> {
|
||||
..self.ctx
|
||||
},
|
||||
changed: false,
|
||||
bindings: self.bindings.clone(),
|
||||
..*self
|
||||
};
|
||||
node.visit_mut_with(&mut v);
|
||||
@ -460,8 +452,6 @@ impl VisitMut for Pure<'_> {
|
||||
}
|
||||
|
||||
fn visit_mut_module_items(&mut self, items: &mut Vec<ModuleItem>) {
|
||||
self.bindings = Some(Arc::new(collect_decls(items)));
|
||||
|
||||
let ctx = Ctx {
|
||||
top_level: true,
|
||||
..self.ctx
|
||||
|
@ -192,7 +192,7 @@ impl Evaluator {
|
||||
});
|
||||
|
||||
e.visit_mut_with(&mut expr_simplifier(
|
||||
self.marks.top_level_mark,
|
||||
self.marks.unresolved_mark,
|
||||
ExprSimplifierConfig {},
|
||||
));
|
||||
return Some(Box::new(e));
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
use compress::pure_optimizer;
|
||||
use mode::Mode;
|
||||
use swc_common::{comments::Comments, pass::Repeat, sync::Lrc, SourceMap, SyntaxContext, GLOBALS};
|
||||
use swc_common::{comments::Comments, pass::Repeat, sync::Lrc, SourceMap, GLOBALS};
|
||||
use swc_ecma_ast::Module;
|
||||
use swc_ecma_visit::{FoldWith, VisitMutWith};
|
||||
use swc_timer::timer;
|
||||
@ -76,10 +76,8 @@ pub fn optimize(
|
||||
) -> Module {
|
||||
let _timer = timer!("minify");
|
||||
|
||||
let top_level_ctxt = SyntaxContext::empty().apply_mark(extra.top_level_mark);
|
||||
|
||||
let mut marks = Marks::new();
|
||||
marks.top_level_mark = extra.top_level_mark;
|
||||
marks.unresolved_mark = extra.unresolved_mark;
|
||||
|
||||
if let Some(defs) = options.compress.as_ref().map(|c| &c.global_defs) {
|
||||
let _timer = timer!("inline global defs");
|
||||
@ -91,7 +89,11 @@ pub fn optimize(
|
||||
|
||||
if !defs.is_empty() {
|
||||
let defs = defs.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
|
||||
m.visit_mut_with(&mut global_defs::globals_defs(defs, extra.top_level_mark));
|
||||
m.visit_mut_with(&mut global_defs::globals_defs(
|
||||
defs,
|
||||
extra.unresolved_mark,
|
||||
extra.top_level_mark,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,7 +104,7 @@ pub fn optimize(
|
||||
}
|
||||
|
||||
if options.compress.is_some() {
|
||||
m.visit_mut_with(&mut info_marker(comments, marks, extra.top_level_mark));
|
||||
m.visit_mut_with(&mut info_marker(comments, marks, extra.unresolved_mark));
|
||||
}
|
||||
m.visit_mut_with(&mut unique_scope());
|
||||
|
||||
@ -172,7 +174,7 @@ pub fn optimize(
|
||||
let _timer = timer!("mangle names");
|
||||
// TODO: base54.reset();
|
||||
|
||||
m.visit_mut_with(&mut name_mangler(mangle.clone(), marks, top_level_ctxt));
|
||||
m.visit_mut_with(&mut name_mangler(mangle.clone(), marks));
|
||||
}
|
||||
|
||||
if let Some(property_mangle_options) = options.mangle.as_ref().and_then(|o| o.props.as_ref()) {
|
||||
|
@ -47,14 +47,14 @@ pub struct Marks {
|
||||
/// preserve the side effects.
|
||||
pub(crate) fake_block: Mark,
|
||||
|
||||
pub(crate) top_level_mark: Mark,
|
||||
pub(crate) unresolved_mark: Mark,
|
||||
}
|
||||
|
||||
impl Marks {
|
||||
#[allow(clippy::new_without_default)]
|
||||
pub fn new() -> Self {
|
||||
fn m() -> Mark {
|
||||
Mark::fresh(Mark::root())
|
||||
Mark::new()
|
||||
}
|
||||
|
||||
Marks {
|
||||
@ -66,7 +66,7 @@ impl Marks {
|
||||
noinline: m(),
|
||||
pure: m(),
|
||||
fake_block: m(),
|
||||
top_level_mark: m(),
|
||||
unresolved_mark: m(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,14 +17,13 @@ mod tests;
|
||||
pub(crate) fn info_marker(
|
||||
comments: Option<&dyn Comments>,
|
||||
marks: Marks,
|
||||
top_level_mark: Mark,
|
||||
unresolved_mark: Mark,
|
||||
) -> impl '_ + VisitMut {
|
||||
InfoMarker {
|
||||
comments,
|
||||
marks,
|
||||
top_level_mark,
|
||||
unresolved_mark,
|
||||
state: Default::default(),
|
||||
top_level_bindings: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,9 +36,8 @@ struct State {
|
||||
struct InfoMarker<'a> {
|
||||
comments: Option<&'a dyn Comments>,
|
||||
marks: Marks,
|
||||
top_level_mark: Mark,
|
||||
unresolved_mark: Mark,
|
||||
state: State,
|
||||
top_level_bindings: Vec<Id>,
|
||||
}
|
||||
|
||||
impl InfoMarker<'_> {
|
||||
@ -164,11 +162,7 @@ impl VisitMut for InfoMarker<'_> {
|
||||
)
|
||||
})
|
||||
{
|
||||
if is_standalone(
|
||||
&mut n.function,
|
||||
self.top_level_mark,
|
||||
&self.top_level_bindings,
|
||||
) {
|
||||
if is_standalone(&mut n.function, self.unresolved_mark) {
|
||||
// self.state.is_bundle = true;
|
||||
|
||||
// n.function.span =
|
||||
@ -182,15 +176,6 @@ impl VisitMut for InfoMarker<'_> {
|
||||
fn visit_mut_lit(&mut self, _: &mut Lit) {}
|
||||
|
||||
fn visit_mut_module(&mut self, m: &mut Module) {
|
||||
self.top_level_bindings = {
|
||||
let mut v = TopLevelBindingCollector {
|
||||
top_level_ctxt: SyntaxContext::empty().apply_mark(self.top_level_mark),
|
||||
bindings: Default::default(),
|
||||
};
|
||||
m.visit_with(&mut v);
|
||||
v.bindings
|
||||
};
|
||||
|
||||
m.visit_mut_children_with(self);
|
||||
|
||||
if self.state.is_bundle {
|
||||
@ -255,11 +240,11 @@ impl Visit for TopLevelBindingCollector {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_standalone<N>(n: &mut N, top_level_mark: Mark, external_bindings: &[Id]) -> bool
|
||||
fn is_standalone<N>(n: &mut N, unresolved_mark: Mark) -> bool
|
||||
where
|
||||
N: VisitMutWith<IdentCollector>,
|
||||
{
|
||||
let top_level_ctxt = SyntaxContext::empty().apply_mark(top_level_mark);
|
||||
let unresolved_ctxt = SyntaxContext::empty().apply_mark(unresolved_mark);
|
||||
|
||||
let bindings = {
|
||||
let mut v = IdentCollector {
|
||||
@ -291,17 +276,7 @@ where
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if external_bindings.contains(used_id) {
|
||||
trace_op!(
|
||||
"bundle: Due to {}{:?} (top-level), it's not a bundle",
|
||||
used_id.0,
|
||||
used_id.1
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if used_id.1 == top_level_ctxt {
|
||||
if used_id.1 == unresolved_ctxt {
|
||||
// if cfg!(feature = "debug") {
|
||||
// debug!("bundle: Ignoring {}{:?} (top level)", used_id.0,
|
||||
// used_id.1); }
|
||||
|
@ -9,7 +9,10 @@ pub mod terser;
|
||||
/// This is not serializable.
|
||||
#[derive(Debug)]
|
||||
pub struct ExtraOptions {
|
||||
/// The [Mark] used for `resolver_with_mark`.
|
||||
/// It should be the [Mark] used for `resolver`.
|
||||
pub unresolved_mark: Mark,
|
||||
|
||||
/// It should be the [Mark] used for `resolver`.
|
||||
pub top_level_mark: Mark,
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,17 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use swc_common::{collections::AHashSet, pass::CompilerPass, EqIgnoreSpan, Mark, SyntaxContext};
|
||||
use swc_common::{pass::CompilerPass, EqIgnoreSpan, Mark, SyntaxContext};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::{ident::IdentLike, Id};
|
||||
use swc_ecma_visit::{noop_visit_mut_type, noop_visit_type, Visit, VisitMut, VisitMutWith};
|
||||
|
||||
pub fn globals_defs(defs: Vec<(Box<Expr>, Box<Expr>)>, top_level_mark: Mark) -> impl VisitMut {
|
||||
pub fn globals_defs(
|
||||
defs: Vec<(Box<Expr>, Box<Expr>)>,
|
||||
unresolved_mark: Mark,
|
||||
top_level_mark: Mark,
|
||||
) -> impl VisitMut {
|
||||
GlobalDefs {
|
||||
defs,
|
||||
unresolved_ctxt: SyntaxContext::empty().apply_mark(unresolved_mark),
|
||||
top_level_ctxt: SyntaxContext::empty().apply_mark(top_level_mark),
|
||||
..Default::default()
|
||||
}
|
||||
@ -16,14 +20,10 @@ pub fn globals_defs(defs: Vec<(Box<Expr>, Box<Expr>)>, top_level_mark: Mark) ->
|
||||
#[derive(Default)]
|
||||
struct GlobalDefs {
|
||||
defs: Vec<(Box<Expr>, Box<Expr>)>,
|
||||
/// If syntax context of a identifier reference is not top-level, it means
|
||||
/// the reference points a binding (var / fn / class or whatever).
|
||||
|
||||
unresolved_ctxt: SyntaxContext,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
/// If a varaible is registered in this variable, it's not a global
|
||||
/// constant.
|
||||
///
|
||||
/// Non-top level bindings are filtered using `top_level_mark`.
|
||||
top_level_bindings: AHashSet<Id>,
|
||||
|
||||
in_lhs_of_assign: bool,
|
||||
}
|
||||
|
||||
@ -58,17 +58,13 @@ impl VisitMut for GlobalDefs {
|
||||
|
||||
match n {
|
||||
Expr::Ident(i) => {
|
||||
if i.span.ctxt != self.top_level_ctxt
|
||||
|| self.top_level_bindings.contains(&i.to_id())
|
||||
{
|
||||
if i.span.ctxt != self.unresolved_ctxt && i.span.ctxt != self.top_level_ctxt {
|
||||
return;
|
||||
}
|
||||
}
|
||||
Expr::Member(MemberExpr { obj, .. }) => {
|
||||
if let Expr::Ident(i) = &**obj {
|
||||
if i.span.ctxt != self.top_level_ctxt
|
||||
|| self.top_level_bindings.contains(&i.to_id())
|
||||
{
|
||||
if i.span.ctxt != self.unresolved_ctxt && i.span.ctxt != self.top_level_ctxt {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use swc_common::{chain, SyntaxContext};
|
||||
use swc_common::chain;
|
||||
use swc_ecma_visit::VisitMut;
|
||||
|
||||
use crate::{marks::Marks, option::MangleOptions};
|
||||
@ -8,13 +8,9 @@ mod preserver;
|
||||
mod private_name;
|
||||
mod real_impl;
|
||||
|
||||
pub(crate) fn name_mangler(
|
||||
options: MangleOptions,
|
||||
marks: Marks,
|
||||
top_level_ctxt: SyntaxContext,
|
||||
) -> impl VisitMut {
|
||||
pub(crate) fn name_mangler(options: MangleOptions, marks: Marks) -> impl VisitMut {
|
||||
chain!(
|
||||
self::private_name::private_name_mangler(options.keep_private_props),
|
||||
self::real_impl::name_mangler(options, marks, top_level_ctxt)
|
||||
self::real_impl::name_mangler(options, marks,)
|
||||
)
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user