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_ecma_ast::{EsVersion, Program};
use swc_ecma_parser::{Syntax, TsConfig};
use swc_ecma_transforms::{fixer, hygiene, resolver, resolver_with_mark, typescript};
use swc_ecma_transforms::{fixer, hygiene, resolver, typescript};
use swc_ecma_visit::FoldWith;
static SOURCE: &str = include_str!("assets/Observable.ts");
@ -45,10 +45,12 @@ fn parse(c: &swc::Compiler) -> (Arc<SourceFile>, Program) {
fn as_es(c: &swc::Compiler) -> Program {
let program = parse(c).1;
let mark = Mark::fresh(Mark::root());
let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();
program
.fold_with(&mut resolver_with_mark(mark))
.fold_with(&mut typescript::strip(mark))
.fold_with(&mut resolver(unresolved_mark, top_level_mark, true))
.fold_with(&mut typescript::strip(top_level_mark))
}
fn base_tr_group(c: &mut Criterion) {
@ -83,7 +85,7 @@ fn base_tr_resolver_and_hygiene(b: &mut Bencher) {
black_box(c.run_transform(&handler, true, || {
module
.clone()
.fold_with(&mut resolver())
.fold_with(&mut resolver(Mark::new(), Mark::new(), false))
.fold_with(&mut hygiene())
}))
});

View File

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

View File

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

View File

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

View File

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

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;
})(B || (B = {}));
var A;
(function(A1) {
var A1;
(function(A) {
class C {
}
A1.C = C;
A.C = C;
var b = B;
A1.b = b;
})(A || (A = {}));
A.b = b;
})(A1 || (A1 = {}));
var c;
var c = new B.a.C();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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;
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;
null == o || o(c = 1), c.toString();
let d;
null == o || o.x(d = 1), d.toString(), null == f || f(x), x, f, f(x), x, f, f(x), (null == o2 ? void 0 : o2.f(x)) ? (x, o2.f, null == o2 || o2.f, null == o2 || o2.f(x)) : (x, o2, null == o2 || o2.f, o2.f), x, o2, null == o2 || o2.f, o2.f, (null == o3 ? void 0 : o3.x) === 1 ? (o3, o3.x, null == o3 || o3.x) : (o3, null == o3 || o3.x, o3.x), o3, null == o3 || o3.x, o3.x, (null === (ref = o4.x) || void 0 === ref ? void 0 : ref.y) ? (o4.x, o4.x.y, null === (ref9 = o4.x) || void 0 === ref9 || ref9.y) : (o4.x, null === (ref10 = o4.x) || void 0 === ref10 || ref10.y, o4.x.y), o4.x, null === (ref1 = o4.x) || void 0 === ref1 || ref1.y, o4.x.y, (null === (ref3 = null === (ref2 = o5.x) || void 0 === ref2 ? void 0 : ref2.y.z) || void 0 === ref3 ? void 0 : ref3.w) ? (o5.x, o5.x.y, o5.x.y.z, o5.x.y.z.w, null === (ref11 = o5.x.y.z) || void 0 === ref11 || ref11.w, null === (ref12 = o5.x) || void 0 === ref12 || ref12.y.z.w, null === (ref14 = null === (ref13 = o5.x) || void 0 === ref13 ? void 0 : ref13.y.z) || void 0 === ref14 || ref14.w) : (o5.x, null === (ref15 = o5.x) || void 0 === ref15 || ref15.y, null === (ref16 = o5.x) || void 0 === ref16 || ref16.y.z, null === (ref18 = null === (ref17 = o5.x) || void 0 === ref17 ? void 0 : ref17.y.z) || void 0 === ref18 || ref18.w, o5.x.y, o5.x.y.z.w), o5.x, null === (ref4 = o5.x) || void 0 === ref4 || ref4.y, null === (ref5 = o5.x) || void 0 === ref5 || ref5.y.z, null === (ref7 = null === (ref6 = o5.x) || void 0 === ref6 ? void 0 : ref6.y.z) || void 0 === ref7 || ref7.w, o5.x.y, o5.x.y.z.w, (null == o6 ? void 0 : o6.f()) ? (o6, o6.f) : (o6, null == o6 || o6.f, o6.f), o6, null == o6 || o6.f, o6.f;
null == o || o.x(d = 1), d.toString(), null == f || f(x), f(x), f(x), (null == o2 ? void 0 : o2.f(x)) ? (o2.f, null == o2 || o2.f, null == o2 || o2.f(x)) : (null == o2 || o2.f, o2.f), null == o2 || o2.f, o2.f, (null == o3 ? void 0 : o3.x) === 1 ? (o3.x, null == o3 || o3.x) : (null == o3 || o3.x, o3.x), null == o3 || o3.x, o3.x, (null === (ref = o4.x) || void 0 === ref ? void 0 : ref.y) ? (o4.x, o4.x.y, null === (ref9 = o4.x) || void 0 === ref9 || ref9.y) : (o4.x, null === (ref10 = o4.x) || void 0 === ref10 || ref10.y, o4.x.y), o4.x, null === (ref1 = o4.x) || void 0 === ref1 || ref1.y, o4.x.y, (null === (ref3 = null === (ref2 = o5.x) || void 0 === ref2 ? void 0 : ref2.y.z) || void 0 === ref3 ? void 0 : ref3.w) ? (o5.x, o5.x.y, o5.x.y.z, o5.x.y.z.w, null === (ref11 = o5.x.y.z) || void 0 === ref11 || ref11.w, null === (ref12 = o5.x) || void 0 === ref12 || ref12.y.z.w, null === (ref14 = null === (ref13 = o5.x) || void 0 === ref13 ? void 0 : ref13.y.z) || void 0 === ref14 || ref14.w) : (o5.x, null === (ref15 = o5.x) || void 0 === ref15 || ref15.y, null === (ref16 = o5.x) || void 0 === ref16 || ref16.y.z, null === (ref18 = null === (ref17 = o5.x) || void 0 === ref17 ? void 0 : ref17.y.z) || void 0 === ref18 || ref18.w, o5.x.y, o5.x.y.z.w), o5.x, null === (ref4 = o5.x) || void 0 === ref4 || ref4.y, null === (ref5 = o5.x) || void 0 === ref5 || ref5.y.z, null === (ref7 = null === (ref6 = o5.x) || void 0 === ref6 ? void 0 : ref6.y.z) || void 0 === ref7 || ref7.w, o5.x.y, o5.x.y.z.w, (null == o6 ? void 0 : o6.f()) || null == o6 || o6.f, o6.f, null == o6 || o6.f, o6.f;
let lastSomeProperty;
function someFunction(someOptionalObject) {
(null == someOptionalObject ? void 0 : someOptionalObject.someProperty) !== lastSomeProperty && (console.log(someOptionalObject), console.log(someOptionalObject.someProperty), lastSomeProperty = null == someOptionalObject ? void 0 : someOptionalObject.someProperty);

View File

@ -2,7 +2,7 @@ import * as swcHelpers from "@swc/helpers";
function someFunction(someOptionalObject) {
(null == someOptionalObject ? void 0 : someOptionalObject.someProperty) !== lastSomeProperty && (console.log(someOptionalObject), console.log(someOptionalObject.someProperty), lastSomeProperty = null == someOptionalObject ? void 0 : someOptionalObject.someProperty);
}
null == o || o[a = 1], a.toString(), null == o || o.x[b = 1], b.toString(), null == o || o(c = 1), c.toString(), null == o || o.x(d = 1), d.toString(), null == f || f(x), x, f, f(x), x, f, f(x), (null == o2 ? void 0 : o2.f(x)) ? (x, o2.f, null == o2 || o2.f, null == o2 || o2.f(x)) : (x, o2, null == o2 || o2.f, o2.f), x, o2, null == o2 || o2.f, o2.f, (null == o3 ? void 0 : o3.x) === 1 ? (o3, o3.x, null == o3 || o3.x) : (o3, null == o3 || o3.x, o3.x), o3, null == o3 || o3.x, o3.x, (null === (ref = o4.x) || void 0 === ref ? void 0 : ref.y) ? (o4.x, o4.x.y, null === (ref9 = o4.x) || void 0 === ref9 || ref9.y) : (o4.x, null === (ref10 = o4.x) || void 0 === ref10 || ref10.y, o4.x.y), o4.x, null === (ref1 = o4.x) || void 0 === ref1 || ref1.y, o4.x.y, (null === (ref3 = null === (ref2 = o5.x) || void 0 === ref2 ? void 0 : ref2.y.z) || void 0 === ref3 ? void 0 : ref3.w) ? (o5.x, o5.x.y, o5.x.y.z, o5.x.y.z.w, null === (ref11 = o5.x.y.z) || void 0 === ref11 || ref11.w, null === (ref12 = o5.x) || void 0 === ref12 || ref12.y.z.w, null === (ref14 = null === (ref13 = o5.x) || void 0 === ref13 ? void 0 : ref13.y.z) || void 0 === ref14 || ref14.w) : (o5.x, null === (ref15 = o5.x) || void 0 === ref15 || ref15.y, null === (ref16 = o5.x) || void 0 === ref16 || ref16.y.z, null === (ref18 = null === (ref17 = o5.x) || void 0 === ref17 ? void 0 : ref17.y.z) || void 0 === ref18 || ref18.w, o5.x.y, o5.x.y.z.w), o5.x, null === (ref4 = o5.x) || void 0 === ref4 || ref4.y, null === (ref5 = o5.x) || void 0 === ref5 || ref5.y.z, null === (ref7 = null === (ref6 = o5.x) || void 0 === ref6 ? void 0 : ref6.y.z) || void 0 === ref7 || ref7.w, o5.x.y, o5.x.y.z.w, (null == o6 ? void 0 : o6.f()) ? (o6, o6.f) : (o6, null == o6 || o6.f, o6.f), o6, null == o6 || o6.f, o6.f, someFunction({
null == o || o[a = 1], a.toString(), null == o || o.x[b = 1], b.toString(), null == o || o(c = 1), c.toString(), null == o || o.x(d = 1), d.toString(), null == f || f(x), f(x), f(x), (null == o2 ? void 0 : o2.f(x)) ? (o2.f, null == o2 || o2.f, null == o2 || o2.f(x)) : (null == o2 || o2.f, o2.f), null == o2 || o2.f, o2.f, (null == o3 ? void 0 : o3.x) === 1 ? (o3.x, null == o3 || o3.x) : (null == o3 || o3.x, o3.x), null == o3 || o3.x, o3.x, (null === (ref = o4.x) || void 0 === ref ? void 0 : ref.y) ? (o4.x, o4.x.y, null === (ref9 = o4.x) || void 0 === ref9 || ref9.y) : (o4.x, null === (ref10 = o4.x) || void 0 === ref10 || ref10.y, o4.x.y), o4.x, null === (ref1 = o4.x) || void 0 === ref1 || ref1.y, o4.x.y, (null === (ref3 = null === (ref2 = o5.x) || void 0 === ref2 ? void 0 : ref2.y.z) || void 0 === ref3 ? void 0 : ref3.w) ? (o5.x, o5.x.y, o5.x.y.z, o5.x.y.z.w, null === (ref11 = o5.x.y.z) || void 0 === ref11 || ref11.w, null === (ref12 = o5.x) || void 0 === ref12 || ref12.y.z.w, null === (ref14 = null === (ref13 = o5.x) || void 0 === ref13 ? void 0 : ref13.y.z) || void 0 === ref14 || ref14.w) : (o5.x, null === (ref15 = o5.x) || void 0 === ref15 || ref15.y, null === (ref16 = o5.x) || void 0 === ref16 || ref16.y.z, null === (ref18 = null === (ref17 = o5.x) || void 0 === ref17 ? void 0 : ref17.y.z) || void 0 === ref18 || ref18.w, o5.x.y, o5.x.y.z.w), o5.x, null === (ref4 = o5.x) || void 0 === ref4 || ref4.y, null === (ref5 = o5.x) || void 0 === ref5 || ref5.y.z, null === (ref7 = null === (ref6 = o5.x) || void 0 === ref6 ? void 0 : ref6.y.z) || void 0 === ref7 || ref7.w, o5.x.y, o5.x.y.z.w, (null == o6 ? void 0 : o6.f()) || null == o6 || o6.f, o6.f, null == o6 || o6.f, o6.f, someFunction({
someProperty: 42
}), someFunction(void 0);
for(var ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, ref8, a, b, c, d, ref9, ref10, ref11, ref12, ref13, ref14, ref15, ref16, ref17, ref18, lastSomeProperty, ref19, i = 0; (null === (ref8 = arr[i]) || void 0 === ref8 ? void 0 : ref8.tag) === "left";)i += 1, (null === (ref19 = arr[i]) || void 0 === ref19 ? void 0 : ref19.tag) === "right" && console.log("I should ALSO be reachable");

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
ab.kind, x, f10(a1), f10(a2);
ab.kind, f10(a1), f10(a2);
const x1 = {
a: 'foo',
b: 42
@ -6,4 +6,4 @@ const x1 = {
a: 'foo',
b: !0
};
x1[k] = 'bar', x2[k] = 'bar', s2 = s1 = s2, t2 = t1 = t2, shouldBeB;
x1[k] = 'bar', x2[k] = 'bar', s2 = s1 = s2, t2 = t1 = t2;

View File

@ -1,4 +1,4 @@
ab.kind, x, f10(a1), f10(a2);
ab.kind, f10(a1), f10(a2);
var x2 = {
a: "foo",
b: !0
@ -6,4 +6,4 @@ var x2 = {
({
a: "foo",
b: 42
})[k] = "bar", x2[k] = "bar", s2 = s1 = s2, t2 = t1 = t2, shouldBeB;
})[k] = "bar", x2[k] = "bar", s2 = s1 = s2, t2 = t1 = t2;

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";
MyComp;

View File

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

View File

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

View File

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

View File

@ -1,2 +1,2 @@
var a;
a.toString, a = void 0, a = null, a = b, a = c, a = a = d, 'object' != typeof b && b.toString(), 'object' == typeof b && (a = b), 'object' == typeof d && (b = d), d.toString(), d, d.toString(), d, d.toString(), d.toString();
a.toString, a = void 0, a = null, a = b, a = c, a = a = d, 'object' != typeof b && b.toString(), 'object' == typeof b && (a = b), 'object' == typeof d && (b = d), d.toString(), d.toString(), d.toString(), d.toString();

View File

@ -1,2 +1,2 @@
var a;
a.toString, a = void 0, a = null, a = b, a = c, a = a = d, "object" != typeof b && b.toString(), "object" == typeof b && (a = b), "object" == typeof d && (b = d), d.toString(), d, d.toString(), d, d.toString(), d.toString();
a.toString, a = void 0, a = null, a = b, a = c, a = a = d, "object" != typeof b && b.toString(), "object" == typeof b && (a = b), "object" == typeof d && (b = d), d.toString(), d.toString(), d.toString(), d.toString();

View File

@ -1,2 +1,2 @@
var ref, ref1, ref2, ref3;
null !== (ref3 = null !== (ref2 = null !== (ref1 = null !== (ref = null != a1 ? a1 : a2) && void 0 !== ref ? ref : a3) && void 0 !== ref1 ? ref1 : a4) && void 0 !== ref2 ? ref2 : a5) && void 0 !== ref3 || a6;
null !== (ref3 = null !== (ref2 = null !== (ref1 = null !== (ref = null != a1 ? a1 : a2) && void 0 !== ref ? ref : a3) && void 0 !== ref1 ? ref1 : a4) && void 0 !== ref2 ? ref2 : a5);

View File

@ -1,2 +1,2 @@
var ref, ref1, ref2, ref3;
null !== (ref3 = null !== (ref2 = null !== (ref1 = null !== (ref = null != a1 ? a1 : a2) && void 0 !== ref ? ref : a3) && void 0 !== ref1 ? ref1 : a4) && void 0 !== ref2 ? ref2 : a5) && void 0 !== ref3 || a6;
null !== (ref3 = null !== (ref2 = null !== (ref1 = null !== (ref = null != a1 ? a1 : a2) && void 0 !== ref ? ref : a3) && void 0 !== ref1 ? ref1 : a4) && void 0 !== ref2 ? ref2 : a5);

View File

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

View File

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

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";
a;

View File

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

View File

@ -1,3 +1,3 @@
import * as swcHelpers from "@swc/helpers";
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 Main from "mod";
Foo, Foo, swcHelpers.extends({}, Main);
swcHelpers.extends({}, Main);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,12 +1,12 @@
import * as swcHelpers from "@swc/helpers";
let constCall = Symbol();
Symbol(), Symbol(), Symbol(), constType, constType, constType, constType;
Symbol(), Symbol(), Symbol();
class C {
constructor(){
this.readonlyCall = Symbol(), this.readwriteCall = Symbol();
}
}
C.readonlyStaticCall = Symbol(), C.readonlyStaticTypeAndCall = Symbol(), C.readwriteStaticCall = Symbol(), C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, i.readonlyType, i.readonlyType, i.readonlyType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, Promise.resolve(constCall), f(s), f(N.s), f(N.s), N.s, N.s, s, N.s, N.s, (p = s)=>p
C.readonlyStaticCall = Symbol(), C.readonlyStaticTypeAndCall = Symbol(), C.readwriteStaticCall = Symbol(), C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, i.readonlyType, i.readonlyType, i.readonlyType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, Promise.resolve(constCall), f(s), f(N.s), f(N.s), N.s, N.s, N.s, N.s, (p = s)=>p
;
class C0 {
method1() {
@ -32,4 +32,4 @@ class C0 {
this.a = s, this.b = N.s, this.c = N.s, this.d = s, this.e = N.s, this.f = N.s;
}
}
C0.a = s, C0.b = N.s, C0.c = N.s, C0.d = s, C0.e = N.s, C0.f = N.s, o[s], o[N.s], o[N.s], f(s), f(N.s), f(N.s), g(s), g(N.s), g(N.s), s, N.s, N.s, 2 * Math.random() && N.s, 2 * Math.random() && N.s, s, N.s;
C0.a = s, C0.b = N.s, C0.c = N.s, C0.d = s, C0.e = N.s, C0.f = N.s, o[s], o[N.s], o[N.s], f(s), f(N.s), f(N.s), g(s), g(N.s), g(N.s), N.s, N.s, 2 * Math.random() && N.s, 2 * Math.random() && N.s, N.s;

View File

@ -41,12 +41,12 @@ var _obj, _marked = regeneratorRuntime.mark(function() {
}
}, _marked3);
}), constCall = Symbol(), letCall = Symbol(), varCall = Symbol();
Symbol(), constType, constType, constType, constType;
Symbol();
var C = function() {
"use strict";
swcHelpers.classCallCheck(this, C), this.readonlyCall = Symbol(), this.readwriteCall = Symbol();
};
C.readonlyStaticCall = Symbol(), C.readonlyStaticTypeAndCall = Symbol(), C.readwriteStaticCall = Symbol(), C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, i.readonlyType, i.readonlyType, i.readonlyType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, Promise.resolve(constCall), f(s), f(N.s), f(N.s), N.s, N.s, s, N.s, N.s, regeneratorRuntime.mark(function method4() {
C.readonlyStaticCall = Symbol(), C.readonlyStaticTypeAndCall = Symbol(), C.readwriteStaticCall = Symbol(), C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, i.readonlyType, i.readonlyType, i.readonlyType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, Promise.resolve(constCall), f(s), f(N.s), f(N.s), N.s, N.s, N.s, N.s, regeneratorRuntime.mark(function method4() {
return regeneratorRuntime.wrap(function(_ctx) {
for(;;)switch(_ctx.prev = _ctx.next){
case 0:
@ -104,7 +104,7 @@ var C0 = function() {
return p;
}, C0;
}();
C0.a = s, C0.b = N.s, C0.c = N.s, C0.d = s, C0.e = N.s, C0.f = N.s, o[s], o[N.s], o[N.s], f(s), f(N.s), f(N.s), g(s), g(N.s), g(N.s), s, N.s, N.s, 2 * Math.random() && N.s, 2 * Math.random() && N.s, _obj = {}, swcHelpers.defineProperty(_obj, s, "a"), swcHelpers.defineProperty(_obj, N.s, "b");
C0.a = s, C0.b = N.s, C0.c = N.s, C0.d = s, C0.e = N.s, C0.f = N.s, o[s], o[N.s], o[N.s], f(s), f(N.s), f(N.s), g(s), g(N.s), g(N.s), N.s, N.s, 2 * Math.random() && N.s, 2 * Math.random() && N.s, _obj = {}, swcHelpers.defineProperty(_obj, s, "a"), swcHelpers.defineProperty(_obj, N.s, "b");
var C1 = function() {
"use strict";
swcHelpers.classCallCheck(this, C1);

View File

@ -1,12 +1,12 @@
import * as swcHelpers from "@swc/helpers";
let constCall = Symbol();
Symbol(), Symbol(), Symbol(), constType, constType, constType, constType;
Symbol(), Symbol(), Symbol();
class C {
constructor(){
this.readonlyCall = Symbol(), this.readwriteCall = Symbol();
}
}
C.readonlyStaticCall = Symbol(), C.readonlyStaticTypeAndCall = Symbol(), C.readwriteStaticCall = Symbol(), C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, i.readonlyType, i.readonlyType, i.readonlyType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, Promise.resolve(constCall), f(s), f(N.s), f(N.s), N.s, N.s, s, N.s, N.s, (p = s)=>p
C.readonlyStaticCall = Symbol(), C.readonlyStaticTypeAndCall = Symbol(), C.readwriteStaticCall = Symbol(), C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, i.readonlyType, i.readonlyType, i.readonlyType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, Promise.resolve(constCall), f(s), f(N.s), f(N.s), N.s, N.s, N.s, N.s, (p = s)=>p
;
class C0 {
method1() {
@ -32,4 +32,4 @@ class C0 {
this.a = s, this.b = N.s, this.c = N.s, this.d = s, this.e = N.s, this.f = N.s;
}
}
C0.a = s, C0.b = N.s, C0.c = N.s, C0.d = s, C0.e = N.s, C0.f = N.s, o[s], o[N.s], o[N.s], f(s), f(N.s), f(N.s), g(s), g(N.s), g(N.s), s, N.s, N.s, 2 * Math.random() && N.s, 2 * Math.random() && N.s, s, N.s;
C0.a = s, C0.b = N.s, C0.c = N.s, C0.d = s, C0.e = N.s, C0.f = N.s, o[s], o[N.s], o[N.s], f(s), f(N.s), f(N.s), g(s), g(N.s), g(N.s), N.s, N.s, 2 * Math.random() && N.s, 2 * Math.random() && N.s, N.s;

View File

@ -41,12 +41,12 @@ var _obj, _marked = regeneratorRuntime.mark(function() {
}
}, _marked3);
}), constCall = Symbol(), letCall = Symbol(), varCall = Symbol();
Symbol(), constType, constType, constType, constType;
Symbol();
var C = function() {
"use strict";
swcHelpers.classCallCheck(this, C), this.readonlyCall = Symbol(), this.readwriteCall = Symbol();
};
C.readonlyStaticCall = Symbol(), C.readonlyStaticTypeAndCall = Symbol(), C.readwriteStaticCall = Symbol(), C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, i.readonlyType, i.readonlyType, i.readonlyType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, Promise.resolve(constCall), f(s), f(N.s), f(N.s), N.s, N.s, s, N.s, N.s, regeneratorRuntime.mark(function method4() {
C.readonlyStaticCall = Symbol(), C.readonlyStaticTypeAndCall = Symbol(), C.readwriteStaticCall = Symbol(), C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, C.readonlyStaticCall, C.readonlyStaticType, C.readonlyStaticTypeAndCall, C.readwriteStaticCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, c.readonlyCall, c.readwriteCall, i.readonlyType, i.readonlyType, i.readonlyType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, l.readonlyType, l.nested.readonlyNestedType, Promise.resolve(constCall), f(s), f(N.s), f(N.s), N.s, N.s, N.s, N.s, regeneratorRuntime.mark(function method4() {
return regeneratorRuntime.wrap(function(_ctx) {
for(;;)switch(_ctx.prev = _ctx.next){
case 0:
@ -104,7 +104,7 @@ var C0 = function() {
return p;
}, C0;
}();
C0.a = s, C0.b = N.s, C0.c = N.s, C0.d = s, C0.e = N.s, C0.f = N.s, o[s], o[N.s], o[N.s], f(s), f(N.s), f(N.s), g(s), g(N.s), g(N.s), s, N.s, N.s, 2 * Math.random() && N.s, 2 * Math.random() && N.s, _obj = {}, swcHelpers.defineProperty(_obj, s, "a"), swcHelpers.defineProperty(_obj, N.s, "b");
C0.a = s, C0.b = N.s, C0.c = N.s, C0.d = s, C0.e = N.s, C0.f = N.s, o[s], o[N.s], o[N.s], f(s), f(N.s), f(N.s), g(s), g(N.s), g(N.s), N.s, N.s, 2 * Math.random() && N.s, 2 * Math.random() && N.s, _obj = {}, swcHelpers.defineProperty(_obj, s, "a"), swcHelpers.defineProperty(_obj, N.s, "b");
var C1 = function() {
"use strict";
swcHelpers.classCallCheck(this, C1);

View File

@ -134,7 +134,8 @@ fn do_test(_entry: &Path, entries: HashMap<String, FileName>, inline: bool, mini
..Default::default()
},
&ExtraOptions {
top_level_mark: Mark::fresh(Mark::root()),
unresolved_mark: Mark::new(),
top_level_mark: Mark::new(),
},
);
b.module.visit_mut_with(&mut fixer(None));

View File

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

View File

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

View File

@ -16,7 +16,7 @@ use swc_ecma_codegen::{
Emitter,
};
use swc_ecma_minifier::option::MangleOptions;
use swc_ecma_transforms_base::{fixer::fixer, resolver::resolver_with_mark};
use swc_ecma_transforms_base::{fixer::fixer, resolver};
use swc_ecma_utils::{find_ids, Id};
use swc_ecma_visit::{Visit, VisitMutWith, VisitWith};
use testing::assert_eq;
@ -1047,9 +1047,10 @@ fn bundle(url: &str, minify: bool) -> String {
let mut module = output.into_iter().next().unwrap().module;
if minify {
let top_level_mark = Mark::fresh(Mark::root());
let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();
module.visit_mut_with(&mut resolver_with_mark(top_level_mark));
module.visit_mut_with(&mut resolver(unresolved_mark, top_level_mark, false));
module = swc_ecma_minifier::optimize(
module,
@ -1064,7 +1065,10 @@ fn bundle(url: &str, minify: bool) -> String {
}),
..Default::default()
},
&swc_ecma_minifier::option::ExtraOptions { top_level_mark },
&swc_ecma_minifier::option::ExtraOptions {
unresolved_mark,
top_level_mark,
},
);
module.visit_mut_with(&mut fixer(None));
}

View File

@ -94,6 +94,12 @@ extern "C" {
}
impl Mark {
/// Shortcut for `Mark::fresh(Mark::root())`
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
Mark::fresh(Mark::root())
}
pub fn fresh(parent: Mark) -> Self {
// Note: msvc tries to link against proxied fn for normal build,
// have to limit build target to wasm only to avoid it.

View File

@ -2,7 +2,7 @@ use swc_common::{errors::HANDLER, Mark, SyntaxContext};
use swc_ecma_ast::*;
use swc_ecma_lints::{rule::Rule, rules::LintParams};
use swc_ecma_parser::Syntax;
use swc_ecma_transforms_base::resolver::resolver_with_mark;
use swc_ecma_transforms_base::resolver;
use swc_ecma_visit::VisitMutWith;
fn main() {
@ -28,14 +28,17 @@ fn main() {
}
};
let top_level_mark = Mark::fresh(Mark::root());
let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();
let unresolved_ctxt = SyntaxContext::empty().apply_mark(unresolved_mark);
let top_level_ctxt = SyntaxContext::empty().apply_mark(top_level_mark);
program.visit_mut_with(&mut resolver_with_mark(top_level_mark));
program.visit_mut_with(&mut resolver(unresolved_mark, top_level_mark, false));
let mut rules = swc_ecma_lints::rules::all(LintParams {
program: &program,
lint_config: &Default::default(),
unresolved_ctxt,
top_level_ctxt,
es_version: EsVersion::latest(),
source_map: cm.clone(),

View File

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

View File

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

View File

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -8,7 +8,7 @@ use swc_ecma_lints::{
rules::{all, LintParams},
};
use swc_ecma_parser::{lexer::Lexer, Parser, Syntax};
use swc_ecma_transforms_base::resolver::{resolver_with_mark, ts_resolver};
use swc_ecma_transforms_base::resolver;
use swc_ecma_utils::HANDLER;
use swc_ecma_visit::VisitMutWith;
@ -42,14 +42,14 @@ fn pass(input: PathBuf) {
let mut parser = Parser::new_from(lexer);
let mut program = parser.parse_program().unwrap();
let top_level_mark = Mark::fresh(Mark::root());
let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();
if input.extension().unwrap() == "ts" || input.extension().unwrap() == "tsx" {
program.visit_mut_with(&mut ts_resolver(top_level_mark));
} else {
program.visit_mut_with(&mut resolver_with_mark(top_level_mark));
}
let need_ts = input.extension().unwrap() == "ts" || input.extension().unwrap() == "tsx";
program.visit_mut_with(&mut resolver(unresolved_mark, top_level_mark, need_ts));
let unresolved_ctxt = SyntaxContext::empty().apply_mark(unresolved_mark);
let top_level_ctxt = SyntaxContext::empty().apply_mark(top_level_mark);
let config = LintConfig::default();
@ -57,6 +57,7 @@ fn pass(input: PathBuf) {
let mut rules = all(LintParams {
program: &program,
lint_config: &config,
unresolved_ctxt,
top_level_ctxt,
es_version,
source_map: cm,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -66,7 +66,7 @@ where
as_folder(compressor),
Optional {
enabled: options.evaluate || options.side_effects,
visitor: expr_simplifier(marks.top_level_mark, ExprSimplifierConfig {})
visitor: expr_simplifier(marks.unresolved_mark, ExprSimplifierConfig {})
}
)
}
@ -278,7 +278,7 @@ where
let start_time = now();
let mut visitor = expr_simplifier(self.marks.top_level_mark, ExprSimplifierConfig {});
let mut visitor = expr_simplifier(self.marks.unresolved_mark, ExprSimplifierConfig {});
n.apply(&mut visitor);
self.changed |= visitor.changed();
@ -370,7 +370,7 @@ where
let start_time = now();
let mut v = dead_branch_remover(self.marks.top_level_mark);
let mut v = dead_branch_remover(self.marks.unresolved_mark);
n.apply(&mut v);
if let Some(start_time) = start_time {

View File

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

View File

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

View File

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

View File

@ -270,7 +270,7 @@ where
match e {
Expr::Ident(e) => {
if e.span.ctxt.outer() == self.marks.top_level_mark {
if e.span.ctxt.outer() == self.marks.unresolved_mark {
if is_global_var(&e.sym) {
return false;
}

View File

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

View File

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

View File

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

View File

@ -28,7 +28,7 @@
use compress::pure_optimizer;
use mode::Mode;
use swc_common::{comments::Comments, pass::Repeat, sync::Lrc, SourceMap, SyntaxContext, GLOBALS};
use swc_common::{comments::Comments, pass::Repeat, sync::Lrc, SourceMap, GLOBALS};
use swc_ecma_ast::Module;
use swc_ecma_visit::{FoldWith, VisitMutWith};
use swc_timer::timer;
@ -76,10 +76,8 @@ pub fn optimize(
) -> Module {
let _timer = timer!("minify");
let top_level_ctxt = SyntaxContext::empty().apply_mark(extra.top_level_mark);
let mut marks = Marks::new();
marks.top_level_mark = extra.top_level_mark;
marks.unresolved_mark = extra.unresolved_mark;
if let Some(defs) = options.compress.as_ref().map(|c| &c.global_defs) {
let _timer = timer!("inline global defs");
@ -91,7 +89,11 @@ pub fn optimize(
if !defs.is_empty() {
let defs = defs.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
m.visit_mut_with(&mut global_defs::globals_defs(defs, extra.top_level_mark));
m.visit_mut_with(&mut global_defs::globals_defs(
defs,
extra.unresolved_mark,
extra.top_level_mark,
));
}
}
@ -102,7 +104,7 @@ pub fn optimize(
}
if options.compress.is_some() {
m.visit_mut_with(&mut info_marker(comments, marks, extra.top_level_mark));
m.visit_mut_with(&mut info_marker(comments, marks, extra.unresolved_mark));
}
m.visit_mut_with(&mut unique_scope());
@ -172,7 +174,7 @@ pub fn optimize(
let _timer = timer!("mangle names");
// TODO: base54.reset();
m.visit_mut_with(&mut name_mangler(mangle.clone(), marks, top_level_ctxt));
m.visit_mut_with(&mut name_mangler(mangle.clone(), marks));
}
if let Some(property_mangle_options) = options.mangle.as_ref().and_then(|o| o.props.as_ref()) {

View File

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

View File

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

View File

@ -9,7 +9,10 @@ pub mod terser;
/// This is not serializable.
#[derive(Debug)]
pub struct ExtraOptions {
/// The [Mark] used for `resolver_with_mark`.
/// It should be the [Mark] used for `resolver`.
pub unresolved_mark: Mark,
/// It should be the [Mark] used for `resolver`.
pub top_level_mark: Mark,
}

View File

@ -1,13 +1,17 @@
use std::borrow::Cow;
use swc_common::{collections::AHashSet, pass::CompilerPass, EqIgnoreSpan, Mark, SyntaxContext};
use swc_common::{pass::CompilerPass, EqIgnoreSpan, Mark, SyntaxContext};
use swc_ecma_ast::*;
use swc_ecma_utils::{ident::IdentLike, Id};
use swc_ecma_visit::{noop_visit_mut_type, noop_visit_type, Visit, VisitMut, VisitMutWith};
pub fn globals_defs(defs: Vec<(Box<Expr>, Box<Expr>)>, top_level_mark: Mark) -> impl VisitMut {
pub fn globals_defs(
defs: Vec<(Box<Expr>, Box<Expr>)>,
unresolved_mark: Mark,
top_level_mark: Mark,
) -> impl VisitMut {
GlobalDefs {
defs,
unresolved_ctxt: SyntaxContext::empty().apply_mark(unresolved_mark),
top_level_ctxt: SyntaxContext::empty().apply_mark(top_level_mark),
..Default::default()
}
@ -16,14 +20,10 @@ pub fn globals_defs(defs: Vec<(Box<Expr>, Box<Expr>)>, top_level_mark: Mark) ->
#[derive(Default)]
struct GlobalDefs {
defs: Vec<(Box<Expr>, Box<Expr>)>,
/// If syntax context of a identifier reference is not top-level, it means
/// the reference points a binding (var / fn / class or whatever).
unresolved_ctxt: SyntaxContext,
top_level_ctxt: SyntaxContext,
/// If a varaible is registered in this variable, it's not a global
/// constant.
///
/// Non-top level bindings are filtered using `top_level_mark`.
top_level_bindings: AHashSet<Id>,
in_lhs_of_assign: bool,
}
@ -58,17 +58,13 @@ impl VisitMut for GlobalDefs {
match n {
Expr::Ident(i) => {
if i.span.ctxt != self.top_level_ctxt
|| self.top_level_bindings.contains(&i.to_id())
{
if i.span.ctxt != self.unresolved_ctxt && i.span.ctxt != self.top_level_ctxt {
return;
}
}
Expr::Member(MemberExpr { obj, .. }) => {
if let Expr::Ident(i) = &**obj {
if i.span.ctxt != self.top_level_ctxt
|| self.top_level_bindings.contains(&i.to_id())
{
if i.span.ctxt != self.unresolved_ctxt && i.span.ctxt != self.top_level_ctxt {
return;
}
}

View File

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

Some files were not shown because too many files have changed in this diff Show More