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:
Donny/강동윤 2022-04-26 16:38:50 +09:00 committed by GitHub
parent 1d90d6e726
commit 53610fdafc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1604 changed files with 11663 additions and 11299 deletions

View File

@ -10,7 +10,7 @@ use swc::config::{Config, IsModule, JscConfig, Options, SourceMapsConfig};
use swc_common::{errors::Handler, FileName, FilePathMapping, Mark, SourceFile, SourceMap}; use swc_common::{errors::Handler, FileName, FilePathMapping, Mark, SourceFile, SourceMap};
use swc_ecma_ast::{EsVersion, Program}; use swc_ecma_ast::{EsVersion, Program};
use swc_ecma_parser::{Syntax, TsConfig}; 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; use swc_ecma_visit::FoldWith;
static SOURCE: &str = include_str!("assets/Observable.ts"); 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 { fn as_es(c: &swc::Compiler) -> Program {
let program = parse(c).1; let program = parse(c).1;
let mark = Mark::fresh(Mark::root()); let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();
program program
.fold_with(&mut resolver_with_mark(mark)) .fold_with(&mut resolver(unresolved_mark, top_level_mark, true))
.fold_with(&mut typescript::strip(mark)) .fold_with(&mut typescript::strip(top_level_mark))
} }
fn base_tr_group(c: &mut Criterion) { 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, || { black_box(c.run_transform(&handler, true, || {
module module
.clone() .clone()
.fold_with(&mut resolver()) .fold_with(&mut resolver(Mark::new(), Mark::new(), false))
.fold_with(&mut hygiene()) .fold_with(&mut hygiene())
})) }))
}); });

View File

@ -31,8 +31,12 @@ pub struct PassBuilder<'a, 'b, P: swc_ecma_visit::Fold> {
handler: &'b Handler, handler: &'b Handler,
env: Option<swc_ecma_preset_env::Config>, env: Option<swc_ecma_preset_env::Config>,
pass: P, pass: P,
/// [Mark] for top level bindings and unresolved identifier references. /// [Mark] for top level bindings .
top_level_mark: Mark, top_level_mark: Mark,
/// [Mark] for unresolved refernces.
unresolved_mark: Mark,
target: EsVersion, target: EsVersion,
loose: bool, loose: bool,
assumptions: Assumptions, assumptions: Assumptions,
@ -50,6 +54,7 @@ impl<'a, 'b, P: swc_ecma_visit::Fold> PassBuilder<'a, 'b, P> {
loose: bool, loose: bool,
assumptions: Assumptions, assumptions: Assumptions,
top_level_mark: Mark, top_level_mark: Mark,
unresolved_mark: Mark,
pass: P, pass: P,
) -> Self { ) -> Self {
PassBuilder { PassBuilder {
@ -58,6 +63,7 @@ impl<'a, 'b, P: swc_ecma_visit::Fold> PassBuilder<'a, 'b, P> {
env: None, env: None,
pass, pass,
top_level_mark, top_level_mark,
unresolved_mark,
target: EsVersion::Es5, target: EsVersion::Es5,
loose, loose,
assumptions, assumptions,
@ -80,6 +86,7 @@ impl<'a, 'b, P: swc_ecma_visit::Fold> PassBuilder<'a, 'b, P> {
env: self.env, env: self.env,
pass, pass,
top_level_mark: self.top_level_mark, top_level_mark: self.top_level_mark,
unresolved_mark: self.unresolved_mark,
target: self.target, target: self.target,
loose: self.loose, loose: self.loose,
assumptions: self.assumptions, assumptions: self.assumptions,
@ -318,6 +325,7 @@ impl<'a, 'b, P: swc_ecma_visit::Fold> PassBuilder<'a, 'b, P> {
options: self.minify, options: self.minify,
cm: self.cm.clone(), cm: self.cm.clone(),
comments: comments.cloned(), comments: comments.cloned(),
unresolved_mark: self.unresolved_mark,
top_level_mark: self.top_level_mark, top_level_mark: self.top_level_mark,
}), }),
Optional::new( Optional::new(
@ -333,6 +341,7 @@ struct MinifierPass {
options: Option<JsMinifyOptions>, options: Option<JsMinifyOptions>,
cm: Lrc<SourceMap>, cm: Lrc<SourceMap>,
comments: Option<SingleThreadedComments>, comments: Option<SingleThreadedComments>,
unresolved_mark: Mark,
top_level_mark: Mark, top_level_mark: Mark,
} }
@ -368,6 +377,7 @@ impl VisitMut for MinifierPass {
None, None,
&opts, &opts,
&swc_ecma_minifier::option::ExtraOptions { &swc_ecma_minifier::option::ExtraOptions {
unresolved_mark: self.unresolved_mark,
top_level_mark: self.top_level_mark, top_level_mark: self.top_level_mark,
}, },
) )

View File

@ -53,9 +53,7 @@ use swc_ecma_transforms::{
optimization::{const_modules, json_parse, simplifier}, optimization::{const_modules, json_parse, simplifier},
pass::{noop, Optional}, pass::{noop, Optional},
proposals::{decorators, export_default_from, import_assertions}, proposals::{decorators, export_default_from, import_assertions},
react, react, resolver,
resolver::ts_resolver,
resolver_with_mark,
typescript::{self, TSEnumConfig}, typescript::{self, TSEnumConfig},
Assumptions, Assumptions,
}; };
@ -166,7 +164,7 @@ pub struct Options {
pub disable_fixer: bool, pub disable_fixer: bool,
#[serde(skip_deserializing, default)] #[serde(skip_deserializing, default)]
pub global_mark: Option<Mark>, pub top_level_mark: Option<Mark>,
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
#[serde(default = "default_cwd")] #[serde(default = "default_cwd")]
@ -310,9 +308,8 @@ impl Options {
} }
}); });
let top_level_mark = self let unresolved_mark = Mark::new();
.global_mark let top_level_mark = self.top_level_mark.unwrap_or_else(Mark::new);
.unwrap_or_else(|| Mark::fresh(Mark::root()));
let es_version = target.unwrap_or_default(); let es_version = target.unwrap_or_default();
@ -329,12 +326,14 @@ impl Options {
if syntax.typescript() { if syntax.typescript() {
assumptions.set_class_methods = !transform.use_define_for_class_fields; assumptions.set_class_methods = !transform.use_define_for_class_fields;
assumptions.set_public_class_fields = !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() { if program.is_module() {
js_minify = js_minify.map(|c| { js_minify = js_minify.map(|c| {
let compress = 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 top_level_ctxt = SyntaxContext::empty().apply_mark(top_level_mark);
let pass = chain!( let pass = chain!(
@ -421,26 +421,34 @@ impl Options {
json_parse_pass json_parse_pass
); );
let pass = PassBuilder::new(cm, handler, loose, assumptions, top_level_mark, pass) let pass = PassBuilder::new(
.target(es_version) cm,
.skip_helper_injection(self.skip_helper_injection) handler,
.minify(js_minify) loose,
.hygiene(if self.disable_hygiene { assumptions,
None top_level_mark,
} else { unresolved_mark,
Some(hygiene::Config { keep_class_names }) pass,
}) )
.fixer(!self.disable_fixer) .target(es_version)
.preset_env(config.env) .skip_helper_injection(self.skip_helper_injection)
.regenerator(regenerator) .minify(js_minify)
.finalize( .hygiene(if self.disable_hygiene {
base_url, None
paths.into_iter().collect(), } else {
base, Some(hygiene::Config { keep_class_names })
syntax, })
config.module, .fixer(!self.disable_fixer)
comments, .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; let keep_import_assertions = experimental.keep_import_assertions;
@ -511,6 +519,7 @@ impl Options {
program: &program, program: &program,
lint_config: &lints, lint_config: &lints,
top_level_ctxt, top_level_ctxt,
unresolved_ctxt,
es_version, es_version,
source_map: cm.clone(), source_map: cm.clone(),
})), })),

View File

@ -150,7 +150,7 @@ use swc_ecma_transforms::{
hygiene, hygiene,
modules::path::NodeImportResolver, modules::path::NodeImportResolver,
pass::noop, pass::noop,
resolver_with_mark, resolver,
}; };
use swc_ecma_visit::{noop_visit_type, FoldWith, Visit, VisitMutWith, VisitWith}; use swc_ecma_visit::{noop_visit_type, FoldWith, Visit, VisitMutWith, VisitWith};
pub use swc_error_reporters::handler::{try_with_handler, HandlerOpts}; pub use swc_error_reporters::handler::{try_with_handler, HandlerOpts};
@ -1037,12 +1037,14 @@ impl Compiler {
Default::default() 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 is_mangler_enabled = min_opts.mangle.is_some();
let module = self.run_transform(handler, false, || { 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( let mut module = swc_ecma_minifier::optimize(
module, module,
@ -1050,7 +1052,10 @@ impl Compiler {
Some(&comments), Some(&comments),
None, None,
&min_opts, &min_opts,
&swc_ecma_minifier::option::ExtraOptions { top_level_mark }, &swc_ecma_minifier::option::ExtraOptions {
unresolved_mark,
top_level_mark,
},
); );
if !is_mangler_enabled { if !is_mangler_enabled {

View File

@ -161,7 +161,7 @@ fn shopify_2_same_opt() {
skip_helper_injection: false, skip_helper_injection: false,
disable_hygiene: false, disable_hygiene: false,
disable_fixer: false, disable_fixer: false,
global_mark: None, top_level_mark: None,
cwd: "/Users/kdy1/projects/example-swcify".into(), cwd: "/Users/kdy1/projects/example-swcify".into(),
filename: "/Users/kdy1/projects/example-swcify/src/App/App.tsx".into(), filename: "/Users/kdy1/projects/example-swcify/src/App/App.tsx".into(),
env_name: "development".into(), env_name: "development".into(),

View File

@ -1 +1 @@
x, x.y, new (x()); x.y, new (x());

View File

@ -1 +1 @@
x, x.y, new (x()); x.y, new (x());

View File

@ -7,13 +7,13 @@ var B;
} }
B1.D = D; B1.D = D;
})(B || (B = {})); })(B || (B = {}));
var A; var A1;
(function(A1) { (function(A) {
class C { class C {
} }
A1.C = C; A.C = C;
var b = B; var b = B;
A1.b = b; A.b = b;
})(A || (A = {})); })(A1 || (A1 = {}));
var c; var c;
var c = new B.a.C(); var c = new B.a.C();

View File

@ -1,13 +1,13 @@
var B, A; var B, A1;
!function(B1) { !function(B1) {
var a = A; var a = A;
B1.a = a; B1.a = a;
class D extends a.C { class D extends a.C {
} }
B1.D = D; B1.D = D;
}(B || (B = {})), function(A1) { }(B || (B = {})), function(A) {
A1.C = class { A.C = class {
}; };
var b = B; var b = B;
A1.b = b; A.b = b;
}(A || (A = {})), new B.a.C(); }(A1 || (A1 = {})), new B.a.C();

View File

@ -16,15 +16,15 @@ var B;
}(a.C); }(a.C);
B1.D = D; B1.D = D;
})(B || (B = {})); })(B || (B = {}));
var A; var A1;
(function(A1) { (function(A) {
var C = function C() { var C = function C() {
"use strict"; "use strict";
swcHelpers.classCallCheck(this, C); swcHelpers.classCallCheck(this, C);
}; };
A1.C = C; A.C = C;
var b = B; var b = B;
A1.b = b; A.b = b;
})(A || (A = {})); })(A1 || (A1 = {}));
var c; var c;
var c = new B.a.C(); var c = new B.a.C();

View File

@ -1,4 +1,4 @@
var B, A; var B, A1;
import * as swcHelpers from "@swc/helpers"; import * as swcHelpers from "@swc/helpers";
!function(B1) { !function(B1) {
var a = A; var a = A;
@ -13,12 +13,12 @@ import * as swcHelpers from "@swc/helpers";
return D; return D;
}(a.C); }(a.C);
B1.D = D; B1.D = D;
}(B || (B = {})), function(A1) { }(B || (B = {})), function(A) {
var C = function() { var C = function() {
"use strict"; "use strict";
swcHelpers.classCallCheck(this, C); swcHelpers.classCallCheck(this, C);
}; };
A1.C = C; A.C = C;
var b = B; var b = B;
A1.b = b; A.b = b;
}(A || (A = {})), new B.a.C(); }(A1 || (A1 = {})), new B.a.C();

View File

@ -6,12 +6,12 @@ var M;
} }
M1.D = D; M1.D = D;
})(M || (M = {})); })(M || (M = {}));
var N; var N1;
(function(N1) { (function(N) {
class E extends M.D { class E extends M.D {
} }
N1.E = E; N.E = E;
})(N || (N = {})); })(N1 || (N1 = {}));
var O; var O;
(function(O) { (function(O) {
class C2 extends Q.E2 { class C2 extends Q.E2 {

View File

@ -1,12 +1,12 @@
var M, N, O; var M, N1, O;
class C extends N.E { class C extends N.E {
} }
(M || (M = {})).D = class extends C { (M || (M = {})).D = class extends C {
}, function(N1) { }, function(N) {
class E extends M.D { class E extends M.D {
} }
N1.E = E; N.E = E;
}(N || (N = {})), function(O) { }(N1 || (N1 = {})), function(O) {
class C2 extends Q.E2 { class C2 extends Q.E2 {
} }
let P; let P;

View File

@ -24,8 +24,8 @@ var M;
}(C); }(C);
M1.D = D; M1.D = D;
})(M || (M = {})); })(M || (M = {}));
var N; var _$N;
(function(N1) { (function(N) {
var E = /*#__PURE__*/ function(_D) { var E = /*#__PURE__*/ function(_D) {
"use strict"; "use strict";
swcHelpers.inherits(E, _D); swcHelpers.inherits(E, _D);
@ -36,8 +36,8 @@ var N;
} }
return E; return E;
}(M.D); }(M.D);
N1.E = E; N.E = E;
})(N || (N = {})); })(_$N || (_$N = {}));
var O; var O;
(function(O) { (function(O) {
var C2 = /*#__PURE__*/ function(_E2) { var C2 = /*#__PURE__*/ function(_E2) {

View File

@ -1,5 +1,5 @@
import * as swcHelpers from "@swc/helpers"; import * as swcHelpers from "@swc/helpers";
var M, N, O, C = function(_E) { var M, _$N, O, C = function(_E) {
"use strict"; "use strict";
swcHelpers.inherits(C, _E); swcHelpers.inherits(C, _E);
var _super = swcHelpers.createSuper(C); var _super = swcHelpers.createSuper(C);
@ -19,7 +19,7 @@ var M, N, O, C = function(_E) {
return D; return D;
}(C); }(C);
M1.D = D; M1.D = D;
}(M || (M = {})), function(N1) { }(M || (M = {})), function(N) {
var E = function(_D) { var E = function(_D) {
"use strict"; "use strict";
swcHelpers.inherits(E, _D); swcHelpers.inherits(E, _D);
@ -29,8 +29,8 @@ var M, N, O, C = function(_E) {
} }
return E; return E;
}(M.D); }(M.D);
N1.E = E; N.E = E;
}(N || (N = {})), function(O) { }(_$N || (_$N = {})), function(O) {
var P, _$Q, P1, D2, Q1, E2, C2 = function(_E2) { var P, _$Q, P1, D2, Q1, E2, C2 = function(_E2) {
"use strict"; "use strict";
swcHelpers.inherits(C2, _E2); swcHelpers.inherits(C2, _E2);

View File

@ -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;

View File

@ -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;

View File

@ -1,2 +1,2 @@
var a; var a;
null != o || (a = 1), a.toString(), null == o || o; null != o || (a = 1), a.toString();

View File

@ -6,7 +6,7 @@ null == o || o.x[b = 1], b.toString();
let c; let c;
null == o || o(c = 1), c.toString(); null == o || o(c = 1), c.toString();
let d; 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; let lastSomeProperty;
function someFunction(someOptionalObject) { 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 == someOptionalObject ? void 0 : someOptionalObject.someProperty) !== lastSomeProperty && (console.log(someOptionalObject), console.log(someOptionalObject.someProperty), lastSomeProperty = null == someOptionalObject ? void 0 : someOptionalObject.someProperty);

View File

@ -2,7 +2,7 @@ import * as swcHelpers from "@swc/helpers";
function someFunction(someOptionalObject) { 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 == 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 someProperty: 42
}), someFunction(void 0); }), 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"); 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");

View File

@ -1,4 +1,4 @@
list, wrap(list), wrap((x)=>[ wrap(list), wrap((x)=>[
x x
] ]
), compose((a)=>list(a) ), compose((a)=>list(a)

View File

@ -1,4 +1,4 @@
list, wrap(list), wrap(function(x) { wrap(list), wrap(function(x) {
return [ return [
x x
]; ];

View File

@ -1,4 +1,4 @@
ab.kind, x; ab.kind;
const x1 = { const x1 = {
a: 'foo', a: 'foo',
b: 42 b: 42

View File

@ -1,4 +1,4 @@
ab.kind, x; ab.kind;
var x2 = { var x2 = {
a: "foo", a: "foo",
b: !0 b: !0

View File

@ -1,4 +1,4 @@
ab.kind, x, f10(a1), f10(a2); ab.kind, f10(a1), f10(a2);
const x1 = { const x1 = {
a: 'foo', a: 'foo',
b: 42 b: 42
@ -6,4 +6,4 @@ const x1 = {
a: 'foo', a: 'foo',
b: !0 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;

View File

@ -1,4 +1,4 @@
ab.kind, x, f10(a1), f10(a2); ab.kind, f10(a1), f10(a2);
var x2 = { var x2 = {
a: "foo", a: "foo",
b: !0 b: !0
@ -6,4 +6,4 @@ var x2 = {
({ ({
a: "foo", a: "foo",
b: 42 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;

View File

@ -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;

View File

@ -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;

View File

@ -1,3 +1,2 @@
import * as React from "react"; import * as React from "react";
import * as React from "react"; import * as React from "react";
MyComp;

View File

@ -1,3 +1,2 @@
import * as React from "react"; import * as React from "react";
import * as React from "react"; import * as React from "react";
MyComp;

View File

@ -1,27 +1,27 @@
import * as swcHelpers from "@swc/helpers"; import * as swcHelpers from "@swc/helpers";
this.props.children, Composite, this.props.children; this.props.children, this.props.children;
var x = React.createElement("div", { var x = React.createElement("div", {
attr1: "foobar", attr1: "foobar",
attr2: "foobarbazbug", attr2: "foobarbazbug",
attr3: "foobarbazbug", attr3: "foobarbazbug",
attr4: "baz" attr4: "baz"
}); });
Component, Namespace.Component, Namespace.DeepNamespace.Component, Component, swcHelpers.extends({}, x, { Namespace.Component, Namespace.DeepNamespace.Component, swcHelpers.extends({}, x, {
y: 2, y: 2,
z: !0 z: !0
}), Component, swcHelpers.extends({}, this.props, { }), swcHelpers.extends({}, this.props, {
sound: "moo" sound: "moo"
}), Component, Component, swcHelpers.extends({}, x), Component, swcHelpers.extends({}, x, { }), swcHelpers.extends({}, x), swcHelpers.extends({}, x, {
y: 2 y: 2
}), Component, swcHelpers.extends({}, x, { }), swcHelpers.extends({}, x, {
y: 2, y: 2,
z: !0 z: !0
}), Component, swcHelpers.extends({ }), swcHelpers.extends({
x: 1 x: 1
}, y), Component, swcHelpers.extends({ }, y), swcHelpers.extends({
x: 1, x: 1,
y: "2" y: "2"
}, z, z), Child, Component, swcHelpers.extends({ }, z, z), swcHelpers.extends({
x: "1" x: "1"
}, z = { }, z = {
y: 2 y: 2

View File

@ -1,27 +1,27 @@
import * as swcHelpers from "@swc/helpers"; import * as swcHelpers from "@swc/helpers";
this.props.children, Composite, this.props.children; this.props.children, this.props.children;
var x = React.createElement("div", { var x = React.createElement("div", {
attr1: "foobar", attr1: "foobar",
attr2: "foobarbazbug", attr2: "foobarbazbug",
attr3: "foobarbazbug", attr3: "foobarbazbug",
attr4: "baz" attr4: "baz"
}); });
Component, Namespace.Component, Namespace.DeepNamespace.Component, Component, swcHelpers.extends({}, x, { Namespace.Component, Namespace.DeepNamespace.Component, swcHelpers.extends({}, x, {
y: 2, y: 2,
z: !0 z: !0
}), Component, swcHelpers.extends({}, this.props, { }), swcHelpers.extends({}, this.props, {
sound: "moo" sound: "moo"
}), Component, Component, swcHelpers.extends({}, x), Component, swcHelpers.extends({}, x, { }), swcHelpers.extends({}, x), swcHelpers.extends({}, x, {
y: 2 y: 2
}), Component, swcHelpers.extends({}, x, { }), swcHelpers.extends({}, x, {
y: 2, y: 2,
z: !0 z: !0
}), Component, swcHelpers.extends({ }), swcHelpers.extends({
x: 1 x: 1
}, y), Component, swcHelpers.extends({ }, y), swcHelpers.extends({
x: 1, x: 1,
y: "2" y: "2"
}, z, z), Child, Component, swcHelpers.extends({ }, z, z), swcHelpers.extends({
x: "1" x: "1"
}, z = { }, z = {
y: 2 y: 2

View File

@ -1,2 +1,2 @@
var a; 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();

View File

@ -1,2 +1,2 @@
var a; 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();

View File

@ -1,2 +1,2 @@
var ref, ref1, ref2, ref3; 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);

View File

@ -1,2 +1,2 @@
var ref, ref1, ref2, ref3; 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);

View File

@ -30,7 +30,7 @@ a2.a, a2.b, a2 = {
let b2 = swcHelpers.objectSpread({}, b1, { let b2 = swcHelpers.objectSpread({}, b1, {
z: 55 z: 55
}); });
swcHelpers.objectSpread({}, b2), opts; swcHelpers.objectSpread({}, b2);
let d1 = { let d1 = {
kind: 'a', kind: 'a',
pos: { pos: {

View File

@ -30,7 +30,7 @@ a2.a, a2.b, a2 = {
var b2 = swcHelpers.objectSpread({}, b1, { var b2 = swcHelpers.objectSpread({}, b1, {
z: 55 z: 55
}); });
swcHelpers.objectSpread({}, b2), opts; swcHelpers.objectSpread({}, b2);
var d1 = { var d1 = {
kind: "a", kind: "a",
pos: { pos: {

View File

@ -1 +1 @@
stringDictionary = optionalProperties, stringDictionary = undefinedProperties, probablyArray = numberLiteralKeys, optionalUndefined; stringDictionary = optionalProperties, stringDictionary = undefinedProperties, probablyArray = numberLiteralKeys;

View File

@ -1 +1 @@
stringDictionary = optionalProperties, stringDictionary = undefinedProperties, probablyArray = numberLiteralKeys, optionalUndefined; stringDictionary = optionalProperties, stringDictionary = undefinedProperties, probablyArray = numberLiteralKeys;

View File

@ -1,2 +1 @@
import * as swcHelpers from "@swc/helpers"; import * as swcHelpers from "@swc/helpers";
a;

View File

@ -9,4 +9,3 @@ var A1 = function() {
value: void 0 value: void 0
}); });
}; };
a;

View File

@ -1,3 +1,3 @@
import * as swcHelpers from "@swc/helpers"; import * as swcHelpers from "@swc/helpers";
import Main from 'mod'; import Main from 'mod';
Foo, Foo, swcHelpers.extends({}, Main); swcHelpers.extends({}, Main);

View File

@ -1,3 +1,3 @@
import * as swcHelpers from "@swc/helpers"; import * as swcHelpers from "@swc/helpers";
import Main from "mod"; import Main from "mod";
Foo, Foo, swcHelpers.extends({}, Main); swcHelpers.extends({}, Main);

View File

@ -1,2 +1,2 @@
require('react'), MyComp; require('react');
export { }; export { };

View File

@ -6,18 +6,18 @@ let obj = {
}, obj1 = { }, obj1 = {
yy: !0 yy: !0
}, defaultObj; }, 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 yy: 42
}, { }, {
yy1: "hi" yy1: "hi"
}), OneThing, swcHelpers.extends({}, obj1, { }), swcHelpers.extends({}, obj1, {
yy: 10000, yy: 10000,
yy1: "true" yy1: "true"
}), OneThing, swcHelpers.extends({}, defaultObj, { }), swcHelpers.extends({}, defaultObj, {
yy: !0 yy: !0
}, obj), OneThing, OneThing, swcHelpers.extends({}, { }, obj), swcHelpers.extends({}, {
"ignore-prop": 200 "ignore-prop": 200
}), OneThing, swcHelpers.extends({}, { }), swcHelpers.extends({}, {
yy: 500, yy: 500,
"ignore-prop": "hello" "ignore-prop": "hello"
}, { }, {

View File

@ -6,18 +6,18 @@ var defaultObj, obj = {
}, obj1 = { }, obj1 = {
yy: !0 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 yy: 42
}, { }, {
yy1: "hi" yy1: "hi"
}), OneThing, swcHelpers.extends({}, obj1, { }), swcHelpers.extends({}, obj1, {
yy: 10000, yy: 10000,
yy1: "true" yy1: "true"
}), OneThing, swcHelpers.extends({}, defaultObj, { }), swcHelpers.extends({}, defaultObj, {
yy: !0 yy: !0
}, obj), OneThing, OneThing, swcHelpers.extends({}, { }, obj), swcHelpers.extends({}, {
"ignore-prop": 200 "ignore-prop": 200
}), OneThing, swcHelpers.extends({}, { }), swcHelpers.extends({}, {
yy: 500, yy: 500,
"ignore-prop": "hello" "ignore-prop": "hello"
}, { }, {

View File

@ -1,9 +1,9 @@
import * as swcHelpers from "@swc/helpers"; import * as swcHelpers from "@swc/helpers";
let obj2; let obj2;
ZeroThingOrTwoThing, ZeroThingOrTwoThing, ZeroThingOrTwoThing, swcHelpers.extends({}, obj2), ZeroThingOrTwoThing, swcHelpers.extends({ swcHelpers.extends({}, obj2), swcHelpers.extends({
yy: 1000 yy: 1000
}, obj2), ZeroThingOrTwoThing, swcHelpers.extends({}, obj2, { }, obj2), swcHelpers.extends({}, obj2, {
yy: 1000 yy: 1000
}), ThreeThing, ThreeThing, ThreeThing, swcHelpers.extends({}, obj2, { }), swcHelpers.extends({}, obj2, {
y2: 10 y2: 10
}); });

View File

@ -1,9 +1,9 @@
var obj2; var obj2;
import * as swcHelpers from "@swc/helpers"; import * as swcHelpers from "@swc/helpers";
ZeroThingOrTwoThing, ZeroThingOrTwoThing, ZeroThingOrTwoThing, swcHelpers.extends({}, obj2), ZeroThingOrTwoThing, swcHelpers.extends({ swcHelpers.extends({}, obj2), swcHelpers.extends({
yy: 1000 yy: 1000
}, obj2), ZeroThingOrTwoThing, swcHelpers.extends({}, obj2, { }, obj2), swcHelpers.extends({}, obj2, {
yy: 1000 yy: 1000
}), ThreeThing, ThreeThing, ThreeThing, swcHelpers.extends({}, obj2, { }), swcHelpers.extends({}, obj2, {
y2: 10 y2: 10
}); });

View File

@ -4,16 +4,16 @@ let obj = {
yy: 10, yy: 10,
yy1: "hello" yy1: "hello"
}, obj2; }, obj2;
OneThing, OneThing, OneThing, swcHelpers.extends({}, obj, { swcHelpers.extends({}, obj, {
yy1: !0 yy1: !0
}), OneThing, swcHelpers.extends({}, obj, { }), swcHelpers.extends({}, obj, {
extra: "extra attr" extra: "extra attr"
}), OneThing, swcHelpers.extends({}, obj, { }), swcHelpers.extends({}, obj, {
y1: 10000 y1: 10000
}), OneThing, swcHelpers.extends({}, obj, { }), swcHelpers.extends({}, obj, {
yy: !0 yy: !0
}), OneThing, swcHelpers.extends({}, obj2, { }), swcHelpers.extends({}, obj2, {
extra: "extra attr" extra: "extra attr"
}), OneThing, swcHelpers.extends({}, obj2, { }), swcHelpers.extends({}, obj2, {
yy: !0 yy: !0
}), TestingOneThing, TestingOneThing, TestingOptional, TestingOptional, TestingOptional, TestingOptional; });

View File

@ -4,16 +4,16 @@ var obj2, obj = {
yy: 10, yy: 10,
yy1: "hello" yy1: "hello"
}; };
OneThing, OneThing, OneThing, swcHelpers.extends({}, obj, { swcHelpers.extends({}, obj, {
yy1: !0 yy1: !0
}), OneThing, swcHelpers.extends({}, obj, { }), swcHelpers.extends({}, obj, {
extra: "extra attr" extra: "extra attr"
}), OneThing, swcHelpers.extends({}, obj, { }), swcHelpers.extends({}, obj, {
y1: 10000 y1: 10000
}), OneThing, swcHelpers.extends({}, obj, { }), swcHelpers.extends({}, obj, {
yy: !0 yy: !0
}), OneThing, swcHelpers.extends({}, obj2, { }), swcHelpers.extends({}, obj2, {
extra: "extra attr" extra: "extra attr"
}), OneThing, swcHelpers.extends({}, obj2, { }), swcHelpers.extends({}, obj2, {
yy: !0 yy: !0
}), TestingOneThing, TestingOneThing, TestingOptional, TestingOptional, TestingOptional, TestingOptional; });

View File

@ -1,2 +1,2 @@
import * as swcHelpers from "@swc/helpers"; import * as swcHelpers from "@swc/helpers";
require('react'), InferParamComponent; require('react');

View File

@ -1,2 +1,2 @@
import * as swcHelpers from "@swc/helpers"; import * as swcHelpers from "@swc/helpers";
require("react"), InferParamComponent; require("react");

View File

@ -1,2 +1,2 @@
import * as swcHelpers from "@swc/helpers"; import * as swcHelpers from "@swc/helpers";
require('react'), InferParamComponent; require('react');

View File

@ -1,2 +1,2 @@
import * as swcHelpers from "@swc/helpers"; import * as swcHelpers from "@swc/helpers";
require("react"), InferParamComponent; require("react");

View File

@ -1,12 +1,12 @@
import * as swcHelpers from "@swc/helpers"; import * as swcHelpers from "@swc/helpers";
let constCall = Symbol(); let constCall = Symbol();
Symbol(), Symbol(), Symbol(), constType, constType, constType, constType; Symbol(), Symbol(), Symbol();
class C { class C {
constructor(){ constructor(){
this.readonlyCall = Symbol(), this.readwriteCall = Symbol(); 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 { class C0 {
method1() { 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; 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;

View File

@ -41,12 +41,12 @@ var _obj, _marked = regeneratorRuntime.mark(function() {
} }
}, _marked3); }, _marked3);
}), constCall = Symbol(), letCall = Symbol(), varCall = Symbol(); }), constCall = Symbol(), letCall = Symbol(), varCall = Symbol();
Symbol(), constType, constType, constType, constType; Symbol();
var C = function() { var C = function() {
"use strict"; "use strict";
swcHelpers.classCallCheck(this, C), this.readonlyCall = Symbol(), this.readwriteCall = Symbol(); 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) { return regeneratorRuntime.wrap(function(_ctx) {
for(;;)switch(_ctx.prev = _ctx.next){ for(;;)switch(_ctx.prev = _ctx.next){
case 0: case 0:
@ -104,7 +104,7 @@ var C0 = function() {
return p; return p;
}, C0; }, 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() { var C1 = function() {
"use strict"; "use strict";
swcHelpers.classCallCheck(this, C1); swcHelpers.classCallCheck(this, C1);

View File

@ -1,12 +1,12 @@
import * as swcHelpers from "@swc/helpers"; import * as swcHelpers from "@swc/helpers";
let constCall = Symbol(); let constCall = Symbol();
Symbol(), Symbol(), Symbol(), constType, constType, constType, constType; Symbol(), Symbol(), Symbol();
class C { class C {
constructor(){ constructor(){
this.readonlyCall = Symbol(), this.readwriteCall = Symbol(); 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 { class C0 {
method1() { 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; 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;

View File

@ -41,12 +41,12 @@ var _obj, _marked = regeneratorRuntime.mark(function() {
} }
}, _marked3); }, _marked3);
}), constCall = Symbol(), letCall = Symbol(), varCall = Symbol(); }), constCall = Symbol(), letCall = Symbol(), varCall = Symbol();
Symbol(), constType, constType, constType, constType; Symbol();
var C = function() { var C = function() {
"use strict"; "use strict";
swcHelpers.classCallCheck(this, C), this.readonlyCall = Symbol(), this.readwriteCall = Symbol(); 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) { return regeneratorRuntime.wrap(function(_ctx) {
for(;;)switch(_ctx.prev = _ctx.next){ for(;;)switch(_ctx.prev = _ctx.next){
case 0: case 0:
@ -104,7 +104,7 @@ var C0 = function() {
return p; return p;
}, C0; }, 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() { var C1 = function() {
"use strict"; "use strict";
swcHelpers.classCallCheck(this, C1); swcHelpers.classCallCheck(this, C1);

View File

@ -134,7 +134,8 @@ fn do_test(_entry: &Path, entries: HashMap<String, FileName>, inline: bool, mini
..Default::default() ..Default::default()
}, },
&ExtraOptions { &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)); b.module.visit_mut_with(&mut fixer(None));

View File

@ -10,7 +10,7 @@ use swc_ecma_ast::{
CallExpr, Callee, Expr, Ident, ImportDecl, ImportSpecifier, MemberExpr, MemberProp, Module, CallExpr, Callee, Expr, Ident, ImportDecl, ImportSpecifier, MemberExpr, MemberProp, Module,
ModuleDecl, ModuleExportName, Str, SuperProp, SuperPropExpr, ModuleDecl, ModuleExportName, Str, SuperProp, SuperPropExpr,
}; };
use swc_ecma_transforms_base::resolver::resolver_with_mark; use swc_ecma_transforms_base::resolver;
use swc_ecma_visit::{ use swc_ecma_visit::{
noop_visit_mut_type, noop_visit_type, FoldWith, Visit, VisitMut, VisitMutWith, VisitWith, noop_visit_mut_type, noop_visit_type, FoldWith, Visit, VisitMut, VisitMutWith, VisitWith,
}; };
@ -137,7 +137,9 @@ where
data.module.visit_mut_with(&mut ClearMark); 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 // let code = self

View File

@ -20,7 +20,7 @@ use swc_ecma_ast::EsVersion;
use swc_ecma_parser::{parse_file_as_module, Syntax, TsConfig}; use swc_ecma_parser::{parse_file_as_module, Syntax, TsConfig};
use swc_ecma_transforms_base::{ use swc_ecma_transforms_base::{
helpers::{inject_helpers, Helpers, HELPERS}, helpers::{inject_helpers, Helpers, HELPERS},
resolver::resolver_with_mark, resolver,
}; };
use swc_ecma_transforms_proposal::decorators; use swc_ecma_transforms_proposal::decorators;
use swc_ecma_transforms_react::react; use swc_ecma_transforms_react::react;
@ -90,7 +90,8 @@ impl Load for Loader {
fn load(&self, f: &FileName) -> Result<ModuleData, Error> { fn load(&self, f: &FileName) -> Result<ModuleData, Error> {
eprintln!("load: {}", f); 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 tsx;
let fm = match f { let fm = match f {
@ -131,15 +132,14 @@ impl Load for Loader {
panic!("failed to parse") panic!("failed to parse")
}); });
let mark = Mark::fresh(Mark::root());
let module = HELPERS.set(&Helpers::new(false), || { let module = HELPERS.set(&Helpers::new(false), || {
module module
.fold_with(&mut resolver_with_mark(mark)) .fold_with(&mut resolver(unresolved_mark, top_level_mark, false))
.fold_with(&mut decorators(decorators::Config { .fold_with(&mut decorators(decorators::Config {
legacy: true, legacy: true,
emit_metadata: Default::default(), emit_metadata: Default::default(),
})) }))
.fold_with(&mut strip(mark)) .fold_with(&mut strip(top_level_mark))
.fold_with(&mut react::<SingleThreadedComments>( .fold_with(&mut react::<SingleThreadedComments>(
self.cm.clone(), self.cm.clone(),
None, None,

View File

@ -16,7 +16,7 @@ use swc_ecma_codegen::{
Emitter, Emitter,
}; };
use swc_ecma_minifier::option::MangleOptions; 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_utils::{find_ids, Id};
use swc_ecma_visit::{Visit, VisitMutWith, VisitWith}; use swc_ecma_visit::{Visit, VisitMutWith, VisitWith};
use testing::assert_eq; use testing::assert_eq;
@ -1047,9 +1047,10 @@ fn bundle(url: &str, minify: bool) -> String {
let mut module = output.into_iter().next().unwrap().module; let mut module = output.into_iter().next().unwrap().module;
if minify { 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 = swc_ecma_minifier::optimize(
module, module,
@ -1064,7 +1065,10 @@ fn bundle(url: &str, minify: bool) -> String {
}), }),
..Default::default() ..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)); module.visit_mut_with(&mut fixer(None));
} }

View File

@ -94,6 +94,12 @@ extern "C" {
} }
impl Mark { 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 { pub fn fresh(parent: Mark) -> Self {
// Note: msvc tries to link against proxied fn for normal build, // Note: msvc tries to link against proxied fn for normal build,
// have to limit build target to wasm only to avoid it. // have to limit build target to wasm only to avoid it.

View File

@ -2,7 +2,7 @@ use swc_common::{errors::HANDLER, Mark, SyntaxContext};
use swc_ecma_ast::*; use swc_ecma_ast::*;
use swc_ecma_lints::{rule::Rule, rules::LintParams}; use swc_ecma_lints::{rule::Rule, rules::LintParams};
use swc_ecma_parser::Syntax; 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; use swc_ecma_visit::VisitMutWith;
fn main() { 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); 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 { let mut rules = swc_ecma_lints::rules::all(LintParams {
program: &program, program: &program,
lint_config: &Default::default(), lint_config: &Default::default(),
unresolved_ctxt,
top_level_ctxt, top_level_ctxt,
es_version: EsVersion::latest(), es_version: EsVersion::latest(),
source_map: cm.clone(), source_map: cm.clone(),

View File

@ -46,6 +46,7 @@ use non_critical_lints::*;
pub struct LintParams<'a> { pub struct LintParams<'a> {
pub program: &'a Program, pub program: &'a Program,
pub lint_config: &'a LintConfig, pub lint_config: &'a LintConfig,
pub unresolved_ctxt: SyntaxContext,
pub top_level_ctxt: SyntaxContext, pub top_level_ctxt: SyntaxContext,
pub es_version: EsVersion, pub es_version: EsVersion,
pub source_map: Arc<SourceMap>, pub source_map: Arc<SourceMap>,
@ -64,7 +65,8 @@ pub fn all(lint_params: LintParams) -> Vec<Box<dyn Rule>> {
let LintParams { let LintParams {
program, program,
lint_config, lint_config,
top_level_ctxt, unresolved_ctxt,
top_level_ctxt: _,
es_version, es_version,
source_map, source_map,
} = lint_params; } = lint_params;
@ -75,13 +77,12 @@ pub fn all(lint_params: LintParams) -> Vec<Box<dyn Rule>> {
rules.extend(no_console::no_console( rules.extend(no_console::no_console(
&lint_config.no_console, &lint_config.no_console,
top_level_ctxt, unresolved_ctxt,
)); ));
rules.extend(no_alert::no_alert( rules.extend(no_alert::no_alert(
program,
&lint_config.no_alert, &lint_config.no_alert,
top_level_ctxt, unresolved_ctxt,
es_version, 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(quotes::quotes(&lint_config.quotes));
rules.extend(prefer_regex_literals::prefer_regex_literals( rules.extend(prefer_regex_literals::prefer_regex_literals(
program,
&lint_config.prefer_regex_literals, &lint_config.prefer_regex_literals,
top_level_ctxt, unresolved_ctxt,
es_version, es_version,
)); ));
@ -120,7 +120,7 @@ pub fn all(lint_params: LintParams) -> Vec<Box<dyn Rule>> {
&lint_config.no_restricted_syntax, &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)); 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(yoda::yoda(&lint_config.yoda));
rules.extend(no_new_symbol::no_new_symbol( rules.extend(no_new_symbol::no_new_symbol(
program, unresolved_ctxt,
top_level_ctxt,
&lint_config.no_new_symbol, &lint_config.no_new_symbol,
)); ));
rules.extend(use_is_nan::use_is_nan( rules.extend(use_is_nan::use_is_nan(
program, unresolved_ctxt,
top_level_ctxt,
&lint_config.use_isnan, &lint_config.use_isnan,
)); ));
@ -149,14 +147,12 @@ pub fn all(lint_params: LintParams) -> Vec<Box<dyn Rule>> {
)); ));
rules.extend(symbol_description::symbol_description( rules.extend(symbol_description::symbol_description(
program, unresolved_ctxt,
top_level_ctxt,
&lint_config.symbol_description, &lint_config.symbol_description,
)); ));
rules.extend(no_obj_calls::no_obj_calls( rules.extend(no_obj_calls::no_obj_calls(
program, unresolved_ctxt,
top_level_ctxt,
&lint_config.no_obj_calls, &lint_config.no_obj_calls,
)); ));
} }

View File

@ -1,7 +1,6 @@
use swc_atoms::JsWord; 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_ast::*;
use swc_ecma_utils::{collect_decls_with_ctxt, ident::IdentLike};
use swc_ecma_visit::{noop_visit_type, Visit, VisitWith}; use swc_ecma_visit::{noop_visit_type, Visit, VisitWith};
use crate::{ use crate::{
@ -14,9 +13,8 @@ const GLOBAL_THIS_PROP: &str = "globalThis";
const OBJ_NAMES: &[&str] = &["window", GLOBAL_THIS_PROP]; const OBJ_NAMES: &[&str] = &["window", GLOBAL_THIS_PROP];
pub fn no_alert( pub fn no_alert(
program: &Program,
config: &RuleConfig<()>, config: &RuleConfig<()>,
top_level_ctxt: SyntaxContext, unresolved_ctxt: SyntaxContext,
es_version: EsVersion, es_version: EsVersion,
) -> Option<Box<dyn Rule>> { ) -> Option<Box<dyn Rule>> {
let rule_reaction = config.get_rule_reaction(); let rule_reaction = config.get_rule_reaction();
@ -25,8 +23,7 @@ pub fn no_alert(
LintRuleReaction::Off => None, LintRuleReaction::Off => None,
_ => Some(visitor_rule(NoAlert::new( _ => Some(visitor_rule(NoAlert::new(
rule_reaction, rule_reaction,
collect_decls_with_ctxt(program, top_level_ctxt), unresolved_ctxt,
top_level_ctxt,
es_version, es_version,
))), ))),
} }
@ -35,8 +32,7 @@ pub fn no_alert(
#[derive(Debug, Default)] #[derive(Debug, Default)]
struct NoAlert { struct NoAlert {
expected_reaction: LintRuleReaction, expected_reaction: LintRuleReaction,
top_level_ctxt: SyntaxContext, unresolved_ctxt: SyntaxContext,
top_level_declared_vars: AHashSet<Id>,
pass_call_on_global_this: bool, pass_call_on_global_this: bool,
inside_callee: bool, inside_callee: bool,
classes_depth: usize, classes_depth: usize,
@ -49,14 +45,12 @@ struct NoAlert {
impl NoAlert { impl NoAlert {
fn new( fn new(
expected_reaction: LintRuleReaction, expected_reaction: LintRuleReaction,
top_level_declared_vars: AHashSet<Id>, unresolved_ctxt: SyntaxContext,
top_level_ctxt: SyntaxContext,
es_version: EsVersion, es_version: EsVersion,
) -> Self { ) -> Self {
Self { Self {
expected_reaction, expected_reaction,
top_level_ctxt, unresolved_ctxt,
top_level_declared_vars,
pass_call_on_global_this: es_version < EsVersion::Es2020, pass_call_on_global_this: es_version < EsVersion::Es2020,
inside_callee: false, inside_callee: false,
classes_depth: 0, classes_depth: 0,
@ -114,11 +108,7 @@ impl NoAlert {
} }
fn is_satisfying_indent(&self, ident: &Ident) -> bool { fn is_satisfying_indent(&self, ident: &Ident) -> bool {
if ident.span.ctxt != self.top_level_ctxt { if ident.span.ctxt != self.unresolved_ctxt {
return false;
}
if self.top_level_declared_vars.contains(&ident.to_id()) {
return false; return false;
} }

View File

@ -18,23 +18,23 @@ pub struct NoConsoleConfig {
pub fn no_console( pub fn no_console(
config: &RuleConfig<NoConsoleConfig>, config: &RuleConfig<NoConsoleConfig>,
top_level_ctxt: SyntaxContext, unresolved_ctxt: SyntaxContext,
) -> Option<Box<dyn Rule>> { ) -> Option<Box<dyn Rule>> {
match config.get_rule_reaction() { match config.get_rule_reaction() {
LintRuleReaction::Off => None, LintRuleReaction::Off => None,
_ => Some(visitor_rule(NoConsole::new(config, top_level_ctxt))), _ => Some(visitor_rule(NoConsole::new(config, unresolved_ctxt))),
} }
} }
#[derive(Debug, Default)] #[derive(Debug, Default)]
struct NoConsole { struct NoConsole {
expected_reaction: LintRuleReaction, expected_reaction: LintRuleReaction,
top_level_ctxt: SyntaxContext, unresolved_ctxt: SyntaxContext,
allow: Option<AHashSet<JsWord>>, allow: Option<AHashSet<JsWord>>,
} }
impl NoConsole { impl NoConsole {
fn new(config: &RuleConfig<NoConsoleConfig>, top_level_ctxt: SyntaxContext) -> Self { fn new(config: &RuleConfig<NoConsoleConfig>, unresolved_ctxt: SyntaxContext) -> Self {
Self { Self {
expected_reaction: config.get_rule_reaction(), expected_reaction: config.get_rule_reaction(),
allow: config.get_rule_config().allow.as_ref().map(|method_names| { 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())) .map(|method_name| JsWord::from(method_name.as_str()))
.collect() .collect()
}), }),
top_level_ctxt, unresolved_ctxt,
} }
} }
fn check(&self, span: Span, ident: &Ident, method: &JsWord) { 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 let Some(allow) = &self.allow {
if allow.contains(method) { if allow.contains(method) {
return; return;

View File

@ -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_ast::*;
use swc_ecma_utils::{collect_decls_with_ctxt, ident::IdentLike};
use swc_ecma_visit::{noop_visit_type, Visit, VisitWith}; use swc_ecma_visit::{noop_visit_type, Visit, VisitWith};
use crate::{ use crate::{
@ -11,8 +10,7 @@ use crate::{
const MESSAGE: &str = "`Symbol` cannot be called as a constructor"; const MESSAGE: &str = "`Symbol` cannot be called as a constructor";
pub fn no_new_symbol( pub fn no_new_symbol(
program: &Program, unresolved_ctxt: SyntaxContext,
top_level_ctxt: SyntaxContext,
config: &RuleConfig<()>, config: &RuleConfig<()>,
) -> Option<Box<dyn Rule>> { ) -> Option<Box<dyn Rule>> {
let expected_reaction = config.get_rule_reaction(); let expected_reaction = config.get_rule_reaction();
@ -20,8 +18,7 @@ pub fn no_new_symbol(
match expected_reaction { match expected_reaction {
LintRuleReaction::Off => None, LintRuleReaction::Off => None,
_ => Some(visitor_rule(NoNewSymbol::new( _ => Some(visitor_rule(NoNewSymbol::new(
collect_decls_with_ctxt(program, top_level_ctxt), unresolved_ctxt,
top_level_ctxt,
expected_reaction, expected_reaction,
))), ))),
} }
@ -30,29 +27,19 @@ pub fn no_new_symbol(
#[derive(Debug, Default)] #[derive(Debug, Default)]
struct NoNewSymbol { struct NoNewSymbol {
expected_reaction: LintRuleReaction, expected_reaction: LintRuleReaction,
top_level_ctxt: SyntaxContext, unresolved_ctxt: SyntaxContext,
top_level_declared_vars: AHashSet<Id>,
} }
impl NoNewSymbol { impl NoNewSymbol {
fn new( fn new(unresolved_ctxt: SyntaxContext, expected_reaction: LintRuleReaction) -> Self {
top_level_declared_vars: AHashSet<Id>,
top_level_ctxt: SyntaxContext,
expected_reaction: LintRuleReaction,
) -> Self {
Self { Self {
expected_reaction, expected_reaction,
top_level_ctxt, unresolved_ctxt,
top_level_declared_vars,
} }
} }
fn check(&self, span: Span, ident: &Ident) { fn check(&self, span: Span, ident: &Ident) {
if self.top_level_declared_vars.contains(&ident.to_id()) { if ident.span.ctxt != self.unresolved_ctxt {
return;
}
if ident.span.ctxt != self.top_level_ctxt {
return; return;
} }

View File

@ -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_ast::*;
use swc_ecma_utils::{collect_decls_with_ctxt, ident::IdentLike};
use swc_ecma_visit::{Visit, VisitWith}; use swc_ecma_visit::{Visit, VisitWith};
use crate::{ use crate::{
@ -11,8 +10,7 @@ use crate::{
const OBJECTS_NAMES: &[&str] = &["Math", "JSON", "Reflect", "Atomics"]; const OBJECTS_NAMES: &[&str] = &["Math", "JSON", "Reflect", "Atomics"];
pub fn no_obj_calls( pub fn no_obj_calls(
program: &Program, unresolved_ctxt: SyntaxContext,
top_level_ctxt: SyntaxContext,
config: &RuleConfig<()>, config: &RuleConfig<()>,
) -> Option<Box<dyn Rule>> { ) -> Option<Box<dyn Rule>> {
let expected_reaction = config.get_rule_reaction(); let expected_reaction = config.get_rule_reaction();
@ -20,8 +18,7 @@ pub fn no_obj_calls(
match expected_reaction { match expected_reaction {
LintRuleReaction::Off => None, LintRuleReaction::Off => None,
_ => Some(visitor_rule(NoObjCalls::new( _ => Some(visitor_rule(NoObjCalls::new(
collect_decls_with_ctxt(program, top_level_ctxt), unresolved_ctxt,
top_level_ctxt,
expected_reaction, expected_reaction,
))), ))),
} }
@ -30,20 +27,14 @@ pub fn no_obj_calls(
#[derive(Debug, Default)] #[derive(Debug, Default)]
struct NoObjCalls { struct NoObjCalls {
expected_reaction: LintRuleReaction, expected_reaction: LintRuleReaction,
top_level_ctxt: SyntaxContext, unresolved_ctxt: SyntaxContext,
top_level_declared_vars: AHashSet<Id>,
} }
impl NoObjCalls { impl NoObjCalls {
fn new( fn new(unresolved_ctxt: SyntaxContext, expected_reaction: LintRuleReaction) -> Self {
top_level_declared_vars: AHashSet<Id>,
top_level_ctxt: SyntaxContext,
expected_reaction: LintRuleReaction,
) -> Self {
Self { Self {
expected_reaction, expected_reaction,
top_level_ctxt, unresolved_ctxt,
top_level_declared_vars,
} }
} }
@ -62,11 +53,7 @@ impl NoObjCalls {
} }
fn check(&self, span: Span, ident: &Ident) { fn check(&self, span: Span, ident: &Ident) {
if self.top_level_declared_vars.contains(&ident.to_id()) { if ident.span.ctxt != self.unresolved_ctxt {
return;
}
if ident.span.ctxt != self.top_level_ctxt {
return; return;
} }

View File

@ -1,7 +1,6 @@
use serde::{Deserialize, Serialize}; 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_ast::*;
use swc_ecma_utils::{collect_decls_with_ctxt, ident::IdentLike};
use swc_ecma_visit::{noop_visit_type, Visit, VisitWith}; use swc_ecma_visit::{noop_visit_type, Visit, VisitWith};
use crate::{ use crate::{
@ -28,9 +27,8 @@ pub struct PreferRegexLiteralsConfig {
} }
pub fn prefer_regex_literals( pub fn prefer_regex_literals(
program: &Program,
config: &RuleConfig<PreferRegexLiteralsConfig>, config: &RuleConfig<PreferRegexLiteralsConfig>,
top_level_ctxt: SyntaxContext, unresolved_ctxt: SyntaxContext,
es_version: EsVersion, es_version: EsVersion,
) -> Option<Box<dyn Rule>> { ) -> Option<Box<dyn Rule>> {
let rule_reaction = config.get_rule_reaction(); let rule_reaction = config.get_rule_reaction();
@ -45,8 +43,7 @@ pub fn prefer_regex_literals(
_ => Some(visitor_rule(PreferRegexLiterals::new( _ => Some(visitor_rule(PreferRegexLiterals::new(
rule_reaction, rule_reaction,
disallow_redundant_wrapping, disallow_redundant_wrapping,
collect_decls_with_ctxt(program, top_level_ctxt), unresolved_ctxt,
top_level_ctxt,
es_version, es_version,
))), ))),
} }
@ -56,8 +53,7 @@ pub fn prefer_regex_literals(
struct PreferRegexLiterals { struct PreferRegexLiterals {
expected_reaction: LintRuleReaction, expected_reaction: LintRuleReaction,
disallow_redundant_wrapping: bool, disallow_redundant_wrapping: bool,
top_level_ctxt: SyntaxContext, unresolved_ctxt: SyntaxContext,
top_level_declared_vars: AHashSet<Id>,
allow_global_this: bool, allow_global_this: bool,
call_span: Option<Span>, call_span: Option<Span>,
first_arg: Option<ArgValue>, first_arg: Option<ArgValue>,
@ -68,15 +64,13 @@ impl PreferRegexLiterals {
fn new( fn new(
expected_reaction: LintRuleReaction, expected_reaction: LintRuleReaction,
disallow_redundant_wrapping: bool, disallow_redundant_wrapping: bool,
top_level_declared_vars: AHashSet<Id>, unresolved_ctxt: SyntaxContext,
top_level_ctxt: SyntaxContext,
es_version: EsVersion, es_version: EsVersion,
) -> Self { ) -> Self {
Self { Self {
expected_reaction, expected_reaction,
disallow_redundant_wrapping, disallow_redundant_wrapping,
top_level_ctxt, unresolved_ctxt,
top_level_declared_vars,
allow_global_this: es_version < EsVersion::Es2020, allow_global_this: es_version < EsVersion::Es2020,
call_span: None, call_span: None,
first_arg: None, first_arg: None,
@ -95,16 +89,14 @@ impl PreferRegexLiterals {
if let Some(ExprOrSpread { expr, .. }) = args.get(0) { if let Some(ExprOrSpread { expr, .. }) = args.get(0) {
self.first_arg = Some(extract_arg_val( self.first_arg = Some(extract_arg_val(
&self.top_level_ctxt, self.unresolved_ctxt,
&self.top_level_declared_vars,
unwrap_seqs_and_parens(expr.as_ref()), unwrap_seqs_and_parens(expr.as_ref()),
)); ));
} }
if let Some(ExprOrSpread { expr, .. }) = args.get(1) { if let Some(ExprOrSpread { expr, .. }) = args.get(1) {
self.second_arg = Some(extract_arg_val( self.second_arg = Some(extract_arg_val(
&self.top_level_ctxt, self.unresolved_ctxt,
&self.top_level_declared_vars,
unwrap_seqs_and_parens(expr.as_ref()), unwrap_seqs_and_parens(expr.as_ref()),
)); ));
} }
@ -183,11 +175,7 @@ impl Visit for PreferRegexLiterals {
} }
fn visit_ident(&mut self, ident: &Ident) { fn visit_ident(&mut self, ident: &Ident) {
if ident.span.ctxt != self.top_level_ctxt { if ident.span.ctxt != self.unresolved_ctxt {
return;
}
if self.top_level_declared_vars.contains(&ident.to_id()) {
return; return;
} }
@ -208,11 +196,7 @@ impl Visit for PreferRegexLiterals {
} }
if let Some(ident) = member_expr.obj.as_ident() { if let Some(ident) = member_expr.obj.as_ident() {
if ident.span.ctxt != self.top_level_ctxt { if ident.span.ctxt != self.unresolved_ctxt {
return;
}
if self.top_level_declared_vars.contains(&ident.to_id()) {
return; return;
} }

View File

@ -1,12 +1,10 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use swc_atoms::JsWord; use swc_atoms::JsWord;
use swc_common::{ use swc_common::{
collections::AHashSet,
errors::{DiagnosticBuilder, HANDLER}, errors::{DiagnosticBuilder, HANDLER},
Span, SyntaxContext, Span, SyntaxContext,
}; };
use swc_ecma_ast::*; use swc_ecma_ast::*;
use swc_ecma_utils::{collect_decls_with_ctxt, ident::IdentLike};
use swc_ecma_visit::{noop_visit_type, Visit, VisitWith}; use swc_ecma_visit::{noop_visit_type, Visit, VisitWith};
use crate::{ use crate::{
@ -45,25 +43,19 @@ pub struct RadixConfig {
} }
pub fn radix( pub fn radix(
program: &Program, unresolved_ctxt: SyntaxContext,
top_level_ctxt: SyntaxContext,
config: &RuleConfig<RadixConfig>, config: &RuleConfig<RadixConfig>,
) -> Option<Box<dyn Rule>> { ) -> Option<Box<dyn Rule>> {
match config.get_rule_reaction() { match config.get_rule_reaction() {
LintRuleReaction::Off => None, LintRuleReaction::Off => None,
_ => Some(visitor_rule(Radix::new( _ => Some(visitor_rule(Radix::new(unresolved_ctxt, config))),
collect_decls_with_ctxt(program, top_level_ctxt),
top_level_ctxt,
config,
))),
} }
} }
#[derive(Default, Debug)] #[derive(Default, Debug)]
struct Radix { struct Radix {
expected_reaction: LintRuleReaction, expected_reaction: LintRuleReaction,
top_level_ctxt: SyntaxContext, unresolved_ctxt: SyntaxContext,
top_level_declared_vars: AHashSet<Id>,
radix_mode: RadixMode, radix_mode: RadixMode,
unwrap_parens_and_seqs: bool, unwrap_parens_and_seqs: bool,
@ -74,17 +66,12 @@ struct Radix {
} }
impl Radix { impl Radix {
fn new( fn new(unresolved_ctxt: SyntaxContext, config: &RuleConfig<RadixConfig>) -> Self {
top_level_declared_vars: AHashSet<Id>,
top_level_ctxt: SyntaxContext,
config: &RuleConfig<RadixConfig>,
) -> Self {
let rule_config = config.get_rule_config(); let rule_config = config.get_rule_config();
Self { Self {
expected_reaction: config.get_rule_reaction(), expected_reaction: config.get_rule_reaction(),
top_level_ctxt, unresolved_ctxt,
top_level_declared_vars,
radix_mode: rule_config.mode.unwrap_or_default(), radix_mode: rule_config.mode.unwrap_or_default(),
unwrap_parens_and_seqs: rule_config.unwrap_parens_and_seqs.unwrap_or(true), unwrap_parens_and_seqs: rule_config.unwrap_parens_and_seqs.unwrap_or(true),
@ -158,7 +145,7 @@ impl Radix {
expr.as_ref() 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::Ident => {}
ArgValue::Number(radix) => { ArgValue::Number(radix) => {
if radix.fract() != 0.0 || !(2f64..=36f64).contains(radix) { if radix.fract() != 0.0 || !(2f64..=36f64).contains(radix) {
@ -191,11 +178,7 @@ impl Radix {
} }
fn is_satisfying_indent(&self, ident: &Ident) -> bool { fn is_satisfying_indent(&self, ident: &Ident) -> bool {
if ident.span.ctxt != self.top_level_ctxt { if ident.span.ctxt != self.unresolved_ctxt {
return false;
}
if self.top_level_declared_vars.contains(&ident.to_id()) {
return false; return false;
} }

View File

@ -1,7 +1,6 @@
use serde::{Deserialize, Serialize}; 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_ast::*;
use swc_ecma_utils::{collect_decls_with_ctxt, ident::IdentLike};
use swc_ecma_visit::{Visit, VisitWith}; use swc_ecma_visit::{Visit, VisitWith};
use crate::{ use crate::{
@ -20,15 +19,13 @@ pub struct SymbolDescriptionConfig {
} }
pub fn symbol_description( pub fn symbol_description(
program: &Program, unresolved_ctxt: SyntaxContext,
top_level_ctxt: SyntaxContext,
config: &RuleConfig<SymbolDescriptionConfig>, config: &RuleConfig<SymbolDescriptionConfig>,
) -> Option<Box<dyn Rule>> { ) -> Option<Box<dyn Rule>> {
match config.get_rule_reaction() { match config.get_rule_reaction() {
LintRuleReaction::Off => None, LintRuleReaction::Off => None,
_ => Some(visitor_rule(SymbolDescription::new( _ => Some(visitor_rule(SymbolDescription::new(
collect_decls_with_ctxt(program, top_level_ctxt), unresolved_ctxt,
top_level_ctxt,
config, config,
))), ))),
} }
@ -37,33 +34,25 @@ pub fn symbol_description(
#[derive(Debug, Default)] #[derive(Debug, Default)]
struct SymbolDescription { struct SymbolDescription {
expected_reaction: LintRuleReaction, expected_reaction: LintRuleReaction,
top_level_ctxt: SyntaxContext, unresolved_ctxt: SyntaxContext,
top_level_declared_vars: AHashSet<Id>,
enforce_string_description: bool, enforce_string_description: bool,
} }
impl SymbolDescription { impl SymbolDescription {
fn new( fn new(unresolved_ctxt: SyntaxContext, config: &RuleConfig<SymbolDescriptionConfig>) -> Self {
top_level_declared_vars: AHashSet<Id>,
top_level_ctxt: SyntaxContext,
config: &RuleConfig<SymbolDescriptionConfig>,
) -> Self {
let rule_config = config.get_rule_config(); let rule_config = config.get_rule_config();
Self { Self {
expected_reaction: config.get_rule_reaction(), expected_reaction: config.get_rule_reaction(),
top_level_ctxt, unresolved_ctxt,
top_level_declared_vars,
enforce_string_description: rule_config.enforce_string_description.unwrap_or(true), enforce_string_description: rule_config.enforce_string_description.unwrap_or(true),
} }
} }
fn is_symbol_call(&self, ident: &Ident) -> bool { fn is_symbol_call(&self, ident: &Ident) -> bool {
if self.top_level_declared_vars.contains(&ident.to_id()) { if ident.span.ctxt != self.unresolved_ctxt {
return false;
}
if ident.span.ctxt != self.top_level_ctxt {
return false; return false;
} }
@ -73,11 +62,7 @@ impl SymbolDescription {
fn check(&self, span: Span, first_arg: Option<&ExprOrSpread>) { fn check(&self, span: Span, first_arg: Option<&ExprOrSpread>) {
if let Some(ExprOrSpread { expr, .. }) = first_arg { if let Some(ExprOrSpread { expr, .. }) = first_arg {
if self.enforce_string_description { if self.enforce_string_description {
match extract_arg_val( match extract_arg_val(self.unresolved_ctxt, unwrap_seqs_and_parens(expr)) {
&self.top_level_ctxt,
&self.top_level_declared_vars,
unwrap_seqs_and_parens(expr),
) {
ArgValue::Str(_) => {} ArgValue::Str(_) => {}
_ => { _ => {
self.emit_report(span, SYMBOL_STRING_DESCRIPTION_EXPECTED_MESSAGE); self.emit_report(span, SYMBOL_STRING_DESCRIPTION_EXPECTED_MESSAGE);

View File

@ -1,7 +1,6 @@
use serde::{Deserialize, Serialize}; 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_ast::*;
use swc_ecma_utils::{collect_decls_with_ctxt, ident::IdentLike};
use swc_ecma_visit::{Visit, VisitWith}; use swc_ecma_visit::{Visit, VisitWith};
use crate::{ use crate::{
@ -20,42 +19,32 @@ pub struct UseIsNanConfig {
} }
pub fn use_is_nan( pub fn use_is_nan(
program: &Program, unresolved_ctxt: SyntaxContext,
top_level_ctxt: SyntaxContext,
config: &RuleConfig<UseIsNanConfig>, config: &RuleConfig<UseIsNanConfig>,
) -> Option<Box<dyn Rule>> { ) -> Option<Box<dyn Rule>> {
match config.get_rule_reaction() { match config.get_rule_reaction() {
LintRuleReaction::Off => None, LintRuleReaction::Off => None,
_ => Some(visitor_rule(UseIsNan::new( _ => Some(visitor_rule(UseIsNan::new(unresolved_ctxt, config))),
collect_decls_with_ctxt(program, top_level_ctxt),
top_level_ctxt,
config,
))),
} }
} }
#[derive(Debug, Default)] #[derive(Debug, Default)]
struct UseIsNan { struct UseIsNan {
expected_reaction: LintRuleReaction, expected_reaction: LintRuleReaction,
top_level_ctxt: SyntaxContext, unresolved_ctxt: SyntaxContext,
top_level_declared_vars: AHashSet<Id>,
enforce_for_switch_case: bool, enforce_for_switch_case: bool,
enforce_for_index_of: bool, enforce_for_index_of: bool,
check_any_cast: bool, check_any_cast: bool,
} }
impl UseIsNan { impl UseIsNan {
fn new( fn new(unresolved_ctxt: SyntaxContext, config: &RuleConfig<UseIsNanConfig>) -> Self {
top_level_declared_vars: AHashSet<Id>,
top_level_ctxt: SyntaxContext,
config: &RuleConfig<UseIsNanConfig>,
) -> Self {
let rule_config = config.get_rule_config(); let rule_config = config.get_rule_config();
Self { Self {
expected_reaction: config.get_rule_reaction(), expected_reaction: config.get_rule_reaction(),
top_level_declared_vars, unresolved_ctxt,
top_level_ctxt,
enforce_for_switch_case: rule_config.enforce_for_switch_case.unwrap_or(true), 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), enforce_for_index_of: rule_config.enforce_for_index_of.unwrap_or(true),
check_any_cast: rule_config.check_any_cast.unwrap_or(true), check_any_cast: rule_config.check_any_cast.unwrap_or(true),
@ -104,11 +93,7 @@ impl UseIsNan {
obj, prop, span, .. obj, prop, span, ..
}) => { }) => {
if let Expr::Ident(obj) = obj.as_ref() { if let Expr::Ident(obj) = obj.as_ref() {
if obj.span.ctxt != self.top_level_ctxt { if obj.span.ctxt != self.unresolved_ctxt {
return;
}
if self.top_level_declared_vars.contains(&obj.to_id()) {
return; return;
} }

View File

@ -1,10 +1,9 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use swc_atoms::JsWord; use swc_atoms::JsWord;
use swc_common::{collections::AHashSet, SyntaxContext}; use swc_common::SyntaxContext;
use swc_ecma_ast::{ 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)] #[derive(Debug, Clone, Copy, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")] #[serde(rename_all = "lowercase")]
@ -52,11 +51,7 @@ pub enum ArgValue {
Other, Other,
} }
pub fn extract_arg_val( pub fn extract_arg_val(unresolved_ctxt: SyntaxContext, expr: &Expr) -> ArgValue {
top_level_ctxt: &SyntaxContext,
top_level_declared_vars: &AHashSet<Id>,
expr: &Expr,
) -> ArgValue {
match expr { match expr {
Expr::Ident(_) => ArgValue::Ident, Expr::Ident(_) => ArgValue::Ident,
Expr::Lit(Lit::Str(Str { value, .. })) => ArgValue::Str(value.clone()), Expr::Lit(Lit::Str(Str { value, .. })) => ArgValue::Str(value.clone()),
@ -84,11 +79,7 @@ pub fn extract_arg_val(
return ArgValue::Other; return ArgValue::Other;
} }
if obj.span.ctxt != *top_level_ctxt { if obj.span.ctxt != unresolved_ctxt {
return ArgValue::Other;
}
if top_level_declared_vars.contains(&obj.to_id()) {
return ArgValue::Other; return ArgValue::Other;
} }

View File

@ -8,7 +8,7 @@ use swc_ecma_lints::{
rules::{all, LintParams}, rules::{all, LintParams},
}; };
use swc_ecma_parser::{lexer::Lexer, Parser, Syntax}; 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_utils::HANDLER;
use swc_ecma_visit::VisitMutWith; use swc_ecma_visit::VisitMutWith;
@ -42,14 +42,14 @@ fn pass(input: PathBuf) {
let mut parser = Parser::new_from(lexer); let mut parser = Parser::new_from(lexer);
let mut program = parser.parse_program().unwrap(); 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" { let need_ts = 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));
}
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 top_level_ctxt = SyntaxContext::empty().apply_mark(top_level_mark);
let config = LintConfig::default(); let config = LintConfig::default();
@ -57,6 +57,7 @@ fn pass(input: PathBuf) {
let mut rules = all(LintParams { let mut rules = all(LintParams {
program: &program, program: &program,
lint_config: &config, lint_config: &config,
unresolved_ctxt,
top_level_ctxt, top_level_ctxt,
es_version, es_version,
source_map: cm, source_map: cm,

View File

@ -12,7 +12,7 @@ use swc_ecma_minifier::{
option::{CompressOptions, ExtraOptions, MangleOptions, MinifyOptions}, option::{CompressOptions, ExtraOptions, MangleOptions, MinifyOptions},
}; };
use swc_ecma_parser::parse_file_as_module; 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 swc_ecma_visit::FoldWith;
pub fn bench_files(c: &mut Criterion) { pub fn bench_files(c: &mut Criterion) {
@ -51,7 +51,8 @@ fn run(src: &str) {
testing::run_test2(false, |cm, handler| { testing::run_test2(false, |cm, handler| {
let fm = cm.new_source_file(FileName::Anon, src.into()); 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( let program = parse_file_as_module(
&fm, &fm,
@ -63,7 +64,7 @@ fn run(src: &str) {
.map_err(|err| { .map_err(|err| {
err.into_diagnostic(&handler).emit(); 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(); .unwrap();
let output = optimize( let output = optimize(
@ -89,7 +90,10 @@ fn run(src: &str) {
wrap: false, wrap: false,
enclose: false, enclose: false,
}, },
&ExtraOptions { top_level_mark }, &ExtraOptions {
unresolved_mark,
top_level_mark,
},
); );
let output = output.fold_with(&mut fixer(None)); let output = output.fold_with(&mut fixer(None));

View File

@ -15,7 +15,7 @@ use swc_ecma_minifier::{
option::{ExtraOptions, MinifyOptions}, option::{ExtraOptions, MinifyOptions},
}; };
use swc_ecma_parser::parse_file_as_module; 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 swc_ecma_visit::FoldWith;
fn main() { fn main() {
@ -26,7 +26,8 @@ fn main() {
testing::run_test2(false, |cm, handler| { testing::run_test2(false, |cm, handler| {
let fm = cm.load_file(Path::new(&file)).expect("failed to load file"); 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( let program = parse_file_as_module(
&fm, &fm,
@ -38,7 +39,7 @@ fn main() {
.map_err(|err| { .map_err(|err| {
err.into_diagnostic(&handler).emit(); 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(); .unwrap();
let output = optimize( let output = optimize(
@ -51,7 +52,10 @@ fn main() {
mangle: None, mangle: None,
..Default::default() ..Default::default()
}, },
&ExtraOptions { top_level_mark }, &ExtraOptions {
unresolved_mark,
top_level_mark,
},
); );
let output = output.fold_with(&mut fixer(None)); let output = output.fold_with(&mut fixer(None));

View File

@ -11,7 +11,7 @@ use swc_ecma_minifier::{
option::{ExtraOptions, MangleOptions, MinifyOptions}, option::{ExtraOptions, MangleOptions, MinifyOptions},
}; };
use swc_ecma_parser::parse_file_as_module; 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 swc_ecma_visit::FoldWith;
fn main() { fn main() {
@ -22,7 +22,8 @@ fn main() {
testing::run_test2(false, |cm, handler| { testing::run_test2(false, |cm, handler| {
let fm = cm.load_file(Path::new(&file)).expect("failed to load file"); 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( let program = parse_file_as_module(
&fm, &fm,
@ -34,7 +35,7 @@ fn main() {
.map_err(|err| { .map_err(|err| {
err.into_diagnostic(&handler).emit(); 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(); .unwrap();
let output = optimize( let output = optimize(
@ -50,7 +51,10 @@ fn main() {
}), }),
..Default::default() ..Default::default()
}, },
&ExtraOptions { top_level_mark }, &ExtraOptions {
unresolved_mark,
top_level_mark,
},
); );
let output = output.fold_with(&mut fixer(None)); let output = output.fold_with(&mut fixer(None));

View File

@ -13,7 +13,7 @@ use swc_ecma_minifier::{
option::{ExtraOptions, MangleOptions, MinifyOptions}, option::{ExtraOptions, MangleOptions, MinifyOptions},
}; };
use swc_ecma_parser::parse_file_as_module; 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 swc_ecma_visit::FoldWith;
use walkdir::WalkDir; use walkdir::WalkDir;
@ -29,7 +29,8 @@ fn main() {
GLOBALS.set(globals, || { GLOBALS.set(globals, || {
let fm = cm.load_file(&path).expect("failed to load file"); 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( let program = parse_file_as_module(
&fm, &fm,
@ -41,7 +42,9 @@ fn main() {
.map_err(|err| { .map_err(|err| {
err.into_diagnostic(&handler).emit(); 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(); .unwrap();
let output = optimize( let output = optimize(
@ -57,7 +60,10 @@ fn main() {
}), }),
..Default::default() ..Default::default()
}, },
&ExtraOptions { top_level_mark }, &ExtraOptions {
unresolved_mark,
top_level_mark,
},
); );
let output = output.fold_with(&mut fixer(None)); let output = output.fold_with(&mut fixer(None));

View File

@ -3,7 +3,7 @@ use std::path::PathBuf;
use swc_common::{comments::SingleThreadedComments, Mark}; use swc_common::{comments::SingleThreadedComments, Mark};
use swc_ecma_ast::Id; use swc_ecma_ast::Id;
use swc_ecma_parser::{parse_file_as_module, EsConfig, Syntax}; 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 swc_ecma_visit::FoldWith;
use testing::NormalizedOutput; use testing::NormalizedOutput;
@ -20,7 +20,8 @@ fn snapshot(input: PathBuf) {
let fm = cm.load_file(&input).expect("failed to load input.js"); let fm = cm.load_file(&input).expect("failed to load input.js");
let comments = SingleThreadedComments::default(); 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(); let marks = Marks::new();
@ -37,7 +38,7 @@ fn snapshot(input: PathBuf) {
.map_err(|err| { .map_err(|err| {
err.into_diagnostic(&handler).emit(); 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 { let program = match program {
Ok(program) => program, Ok(program) => program,

View File

@ -66,7 +66,7 @@ where
as_folder(compressor), as_folder(compressor),
Optional { Optional {
enabled: options.evaluate || options.side_effects, 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 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); n.apply(&mut visitor);
self.changed |= visitor.changed(); self.changed |= visitor.changed();
@ -370,7 +370,7 @@ where
let start_time = now(); 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); n.apply(&mut v);
if let Some(start_time) = start_time { if let Some(start_time) = start_time {

View File

@ -411,7 +411,7 @@ where
*e = Expr::Ident(Ident::new( *e = Expr::Ident(Ident::new(
js_word!("NaN"), js_word!("NaN"),
bin.span.with_ctxt( bin.span.with_ctxt(
SyntaxContext::empty().apply_mark(self.marks.top_level_mark), SyntaxContext::empty().apply_mark(self.marks.unresolved_mark),
), ),
)); ));
} }

View File

@ -972,7 +972,7 @@ where
if ids if ids
.iter() .iter()
.all(|id| id.1.outer() == self.marks.top_level_mark) .all(|id| id.1.outer() == self.marks.unresolved_mark)
{ {
return true; return true;
} }

View File

@ -165,7 +165,7 @@ where
*n = Expr::Ident(Ident::new( *n = Expr::Ident(Ident::new(
js_word!("NaN"), js_word!("NaN"),
span.with_ctxt( span.with_ctxt(
SyntaxContext::empty().apply_mark(self.marks.top_level_mark), SyntaxContext::empty().apply_mark(self.marks.unresolved_mark),
), ),
)); ));
self.changed = true; self.changed = true;

View File

@ -270,7 +270,7 @@ where
match e { match e {
Expr::Ident(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) { if is_global_var(&e.sym) {
return false; return false;
} }

View File

@ -489,7 +489,7 @@ impl Pure<'_> {
if let Expr::Ident(i) = e { if let Expr::Ident(i) = e {
// If it's not a top level, it's a reference to a declared variable. // 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 if self.options.side_effects
|| (self.options.unused && opts.drop_global_refs_if_unused) || (self.options.unused && opts.drop_global_refs_if_unused)
{ {
@ -580,14 +580,12 @@ impl Pure<'_> {
} }
Expr::Ident(i) => { Expr::Ident(i) => {
if let Some(bindings) = self.bindings.as_deref() { if i.span.ctxt.outer() != self.marks.unresolved_mark {
if bindings.contains(&i.to_id()) { report_change!("Dropping an identifier as it's declared");
report_change!("Dropping an identifier as it's declared");
self.changed = true; self.changed = true;
*e = Expr::Invalid(Invalid { span: DUMMY_SP }); *e = Expr::Invalid(Invalid { span: DUMMY_SP });
return; return;
}
} }
} }
@ -736,14 +734,11 @@ impl Pure<'_> {
// Remove pure member expressions. // Remove pure member expressions.
if let Expr::Member(MemberExpr { obj, prop, .. }) = e { if let Expr::Member(MemberExpr { obj, prop, .. }) = e {
if let Expr::Ident(obj) = &**obj { if let Expr::Ident(obj) = &**obj {
if obj.span.ctxt.outer() == self.marks.top_level_mark { if obj.span.ctxt.outer() == self.marks.unresolved_mark {
if let Some(bindings) = self.bindings.as_deref() { if is_pure_member_access(obj, prop) {
if !bindings.contains(&obj.to_id()) { self.changed = true;
if is_pure_member_access(obj, prop) { report_change!("Remving pure member access to global var");
self.changed = true; *e = Expr::Invalid(Invalid { span: DUMMY_SP });
*e = Expr::Invalid(Invalid { span: DUMMY_SP });
}
}
} }
} }
} }

View File

@ -1,11 +1,9 @@
#![allow(clippy::needless_update)] #![allow(clippy::needless_update)]
use std::sync::Arc;
use rayon::prelude::*; 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_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 swc_ecma_visit::{noop_visit_mut_type, VisitMut, VisitMutWith, VisitWith};
use tracing::{debug, span, Level}; use tracing::{debug, span, Level};
@ -57,7 +55,6 @@ pub(crate) fn pure_optimizer<'a>(
changed: Default::default(), changed: Default::default(),
enable_everything, enable_everything,
debug_infinite_loop, debug_infinite_loop,
bindings: Default::default(),
} }
} }
@ -71,8 +68,6 @@ struct Pure<'a> {
enable_everything: bool, enable_everything: bool,
debug_infinite_loop: bool, debug_infinite_loop: bool,
bindings: Option<Arc<AHashSet<Id>>>,
} }
impl Repeated for Pure<'_> { impl Repeated for Pure<'_> {
@ -81,7 +76,6 @@ impl Repeated for Pure<'_> {
} }
fn reset(&mut self) { fn reset(&mut self) {
self.bindings = None;
self.ctx = Default::default(); self.ctx = Default::default();
self.changed = false; self.changed = false;
} }
@ -163,7 +157,6 @@ impl Pure<'_> {
for node in nodes { for node in nodes {
let mut v = Pure { let mut v = Pure {
changed: false, changed: false,
bindings: self.bindings.clone(),
..*self ..*self
}; };
node.visit_mut_with(&mut v); node.visit_mut_with(&mut v);
@ -182,7 +175,6 @@ impl Pure<'_> {
..self.ctx ..self.ctx
}, },
changed: false, changed: false,
bindings: self.bindings.clone(),
..*self ..*self
}; };
node.visit_mut_with(&mut v); 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>) { fn visit_mut_module_items(&mut self, items: &mut Vec<ModuleItem>) {
self.bindings = Some(Arc::new(collect_decls(items)));
let ctx = Ctx { let ctx = Ctx {
top_level: true, top_level: true,
..self.ctx ..self.ctx

View File

@ -192,7 +192,7 @@ impl Evaluator {
}); });
e.visit_mut_with(&mut expr_simplifier( e.visit_mut_with(&mut expr_simplifier(
self.marks.top_level_mark, self.marks.unresolved_mark,
ExprSimplifierConfig {}, ExprSimplifierConfig {},
)); ));
return Some(Box::new(e)); return Some(Box::new(e));

View File

@ -28,7 +28,7 @@
use compress::pure_optimizer; use compress::pure_optimizer;
use mode::Mode; 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_ast::Module;
use swc_ecma_visit::{FoldWith, VisitMutWith}; use swc_ecma_visit::{FoldWith, VisitMutWith};
use swc_timer::timer; use swc_timer::timer;
@ -76,10 +76,8 @@ pub fn optimize(
) -> Module { ) -> Module {
let _timer = timer!("minify"); let _timer = timer!("minify");
let top_level_ctxt = SyntaxContext::empty().apply_mark(extra.top_level_mark);
let mut marks = Marks::new(); 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) { if let Some(defs) = options.compress.as_ref().map(|c| &c.global_defs) {
let _timer = timer!("inline global defs"); let _timer = timer!("inline global defs");
@ -91,7 +89,11 @@ pub fn optimize(
if !defs.is_empty() { if !defs.is_empty() {
let defs = defs.iter().map(|(k, v)| (k.clone(), v.clone())).collect(); 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() { 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()); m.visit_mut_with(&mut unique_scope());
@ -172,7 +174,7 @@ pub fn optimize(
let _timer = timer!("mangle names"); let _timer = timer!("mangle names");
// TODO: base54.reset(); // 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()) { if let Some(property_mangle_options) = options.mangle.as_ref().and_then(|o| o.props.as_ref()) {

View File

@ -47,14 +47,14 @@ pub struct Marks {
/// preserve the side effects. /// preserve the side effects.
pub(crate) fake_block: Mark, pub(crate) fake_block: Mark,
pub(crate) top_level_mark: Mark, pub(crate) unresolved_mark: Mark,
} }
impl Marks { impl Marks {
#[allow(clippy::new_without_default)] #[allow(clippy::new_without_default)]
pub fn new() -> Self { pub fn new() -> Self {
fn m() -> Mark { fn m() -> Mark {
Mark::fresh(Mark::root()) Mark::new()
} }
Marks { Marks {
@ -66,7 +66,7 @@ impl Marks {
noinline: m(), noinline: m(),
pure: m(), pure: m(),
fake_block: m(), fake_block: m(),
top_level_mark: m(), unresolved_mark: m(),
} }
} }
} }

View File

@ -17,14 +17,13 @@ mod tests;
pub(crate) fn info_marker( pub(crate) fn info_marker(
comments: Option<&dyn Comments>, comments: Option<&dyn Comments>,
marks: Marks, marks: Marks,
top_level_mark: Mark, unresolved_mark: Mark,
) -> impl '_ + VisitMut { ) -> impl '_ + VisitMut {
InfoMarker { InfoMarker {
comments, comments,
marks, marks,
top_level_mark, unresolved_mark,
state: Default::default(), state: Default::default(),
top_level_bindings: Default::default(),
} }
} }
@ -37,9 +36,8 @@ struct State {
struct InfoMarker<'a> { struct InfoMarker<'a> {
comments: Option<&'a dyn Comments>, comments: Option<&'a dyn Comments>,
marks: Marks, marks: Marks,
top_level_mark: Mark, unresolved_mark: Mark,
state: State, state: State,
top_level_bindings: Vec<Id>,
} }
impl InfoMarker<'_> { impl InfoMarker<'_> {
@ -164,11 +162,7 @@ impl VisitMut for InfoMarker<'_> {
) )
}) })
{ {
if is_standalone( if is_standalone(&mut n.function, self.unresolved_mark) {
&mut n.function,
self.top_level_mark,
&self.top_level_bindings,
) {
// self.state.is_bundle = true; // self.state.is_bundle = true;
// n.function.span = // n.function.span =
@ -182,15 +176,6 @@ impl VisitMut for InfoMarker<'_> {
fn visit_mut_lit(&mut self, _: &mut Lit) {} fn visit_mut_lit(&mut self, _: &mut Lit) {}
fn visit_mut_module(&mut self, m: &mut Module) { 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); m.visit_mut_children_with(self);
if self.state.is_bundle { 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 where
N: VisitMutWith<IdentCollector>, 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 bindings = {
let mut v = IdentCollector { let mut v = IdentCollector {
@ -291,17 +276,7 @@ where
_ => {} _ => {}
} }
if external_bindings.contains(used_id) { if used_id.1 == unresolved_ctxt {
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 cfg!(feature = "debug") { // if cfg!(feature = "debug") {
// debug!("bundle: Ignoring {}{:?} (top level)", used_id.0, // debug!("bundle: Ignoring {}{:?} (top level)", used_id.0,
// used_id.1); } // used_id.1); }

View File

@ -9,7 +9,10 @@ pub mod terser;
/// This is not serializable. /// This is not serializable.
#[derive(Debug)] #[derive(Debug)]
pub struct ExtraOptions { 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, pub top_level_mark: Mark,
} }

View File

@ -1,13 +1,17 @@
use std::borrow::Cow; 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_ast::*;
use swc_ecma_utils::{ident::IdentLike, Id};
use swc_ecma_visit::{noop_visit_mut_type, noop_visit_type, Visit, VisitMut, VisitMutWith}; 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 { GlobalDefs {
defs, defs,
unresolved_ctxt: SyntaxContext::empty().apply_mark(unresolved_mark),
top_level_ctxt: SyntaxContext::empty().apply_mark(top_level_mark), top_level_ctxt: SyntaxContext::empty().apply_mark(top_level_mark),
..Default::default() ..Default::default()
} }
@ -16,14 +20,10 @@ pub fn globals_defs(defs: Vec<(Box<Expr>, Box<Expr>)>, top_level_mark: Mark) ->
#[derive(Default)] #[derive(Default)]
struct GlobalDefs { struct GlobalDefs {
defs: Vec<(Box<Expr>, Box<Expr>)>, 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, 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, in_lhs_of_assign: bool,
} }
@ -58,17 +58,13 @@ impl VisitMut for GlobalDefs {
match n { match n {
Expr::Ident(i) => { Expr::Ident(i) => {
if i.span.ctxt != self.top_level_ctxt if i.span.ctxt != self.unresolved_ctxt && i.span.ctxt != self.top_level_ctxt {
|| self.top_level_bindings.contains(&i.to_id())
{
return; return;
} }
} }
Expr::Member(MemberExpr { obj, .. }) => { Expr::Member(MemberExpr { obj, .. }) => {
if let Expr::Ident(i) = &**obj { if let Expr::Ident(i) = &**obj {
if i.span.ctxt != self.top_level_ctxt if i.span.ctxt != self.unresolved_ctxt && i.span.ctxt != self.top_level_ctxt {
|| self.top_level_bindings.contains(&i.to_id())
{
return; return;
} }
} }

View File

@ -1,4 +1,4 @@
use swc_common::{chain, SyntaxContext}; use swc_common::chain;
use swc_ecma_visit::VisitMut; use swc_ecma_visit::VisitMut;
use crate::{marks::Marks, option::MangleOptions}; use crate::{marks::Marks, option::MangleOptions};
@ -8,13 +8,9 @@ mod preserver;
mod private_name; mod private_name;
mod real_impl; mod real_impl;
pub(crate) fn name_mangler( pub(crate) fn name_mangler(options: MangleOptions, marks: Marks) -> impl VisitMut {
options: MangleOptions,
marks: Marks,
top_level_ctxt: SyntaxContext,
) -> impl VisitMut {
chain!( chain!(
self::private_name::private_name_mangler(options.keep_private_props), 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