feat(es/transforms): Add Assumptions (#3215)

swc_ecma_transforms_base:
 - Add `Assumptions`. (Closes #2057)

swc_ecma_transforms:
 - Reexport `Assumptions`.

swc:
 - Add `jsc.assumptions`.
This commit is contained in:
Donny/강동윤 2022-01-08 23:26:09 +09:00 committed by GitHub
parent 70c2f3b3a5
commit 42f726873e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 127 additions and 4 deletions

1
Cargo.lock generated
View File

@ -3031,6 +3031,7 @@ dependencies = [
"phf",
"rayon",
"scoped-tls",
"serde",
"smallvec",
"swc_atoms",
"swc_common",

View File

@ -16,7 +16,7 @@ use swc_ecma_parser::Syntax;
use swc_ecma_transforms::{
compat, compat::es2022::private_in_object, fixer, helpers, hygiene,
hygiene::hygiene_with_config, modules, modules::util::Scope, optimization::const_modules,
pass::Optional,
pass::Optional, Assumptions,
};
use swc_ecma_visit::{as_folder, noop_visit_mut_type, VisitMut};
@ -30,6 +30,7 @@ pub struct PassBuilder<'a, 'b, P: swc_ecma_visit::Fold> {
top_level_mark: Mark,
target: EsVersion,
loose: bool,
assumptions: Assumptions,
hygiene: Option<hygiene::Config>,
fixer: bool,
inject_helpers: bool,
@ -42,6 +43,7 @@ impl<'a, 'b, P: swc_ecma_visit::Fold> PassBuilder<'a, 'b, P> {
cm: &'a Arc<SourceMap>,
handler: &'b Handler,
loose: bool,
assumptions: Assumptions,
top_level_mark: Mark,
pass: P,
) -> Self {
@ -53,6 +55,7 @@ impl<'a, 'b, P: swc_ecma_visit::Fold> PassBuilder<'a, 'b, P> {
top_level_mark,
target: EsVersion::Es5,
loose,
assumptions,
hygiene: Some(Default::default()),
fixer: true,
inject_helpers: true,
@ -74,6 +77,7 @@ impl<'a, 'b, P: swc_ecma_visit::Fold> PassBuilder<'a, 'b, P> {
top_level_mark: self.top_level_mark,
target: self.target,
loose: self.loose,
assumptions: self.assumptions,
hygiene: self.hygiene,
fixer: self.fixer,
inject_helpers: self.inject_helpers,

View File

@ -48,7 +48,7 @@ use swc_ecma_transforms::{
optimization::{const_modules, json_parse, simplifier},
pass::{noop, Optional},
proposals::{decorators, export_default_from, import_assertions},
react, resolver_with_mark, typescript,
react, resolver_with_mark, typescript, Assumptions,
};
use swc_ecma_transforms_compat::es2015::regenerator;
use swc_ecma_transforms_optimization::{inline_globals2, GlobalExprMap};
@ -266,6 +266,7 @@ impl Options {
source_maps.merge(&config.source_maps);
let JscConfig {
assumptions,
transform,
syntax,
external_helpers,
@ -279,6 +280,14 @@ impl Options {
..
} = config.jsc;
let assumptions = assumptions.unwrap_or_else(|| {
if loose {
Assumptions::all()
} else {
Assumptions::default()
}
});
let target = target.unwrap_or_default();
let syntax = syntax.unwrap_or_default();
@ -369,7 +378,7 @@ impl Options {
json_parse_pass
);
let pass = PassBuilder::new(&cm, &handler, loose, top_level_mark, pass)
let pass = PassBuilder::new(&cm, &handler, loose, assumptions, top_level_mark, pass)
.target(target)
.skip_helper_injection(self.skip_helper_injection)
.minify(js_minify)
@ -930,6 +939,9 @@ pub struct BuiltInput<P: swc_ecma_visit::Fold> {
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub struct JscConfig {
#[serde(default)]
pub assumptions: Option<Assumptions>,
#[serde(rename = "parser", default)]
pub syntax: Option<Syntax>,

View File

@ -144,6 +144,7 @@ fn shopify_2_same_opt() {
paths: Default::default(),
minify: None,
experimental: Default::default(),
assumptions: Default::default(),
},
module: None,
minify: false,

View File

@ -6,7 +6,9 @@ pub use self::{
hygiene::hygiene,
resolver::{resolver, resolver_with_mark},
};
pub use swc_ecma_transforms_base::{fixer, helpers, hygiene, pass, perf, resolver};
pub use swc_ecma_transforms_base::{
assumptions::Assumptions, fixer, helpers, hygiene, pass, perf, resolver,
};
#[cfg(feature = "swc_ecma_transforms_compat")]
#[cfg_attr(docsrs, doc(cfg(feature = "compat")))]
pub use swc_ecma_transforms_compat as compat;

View File

@ -19,6 +19,7 @@ once_cell = "1.5.2"
phf = {version = "0.8.0", features = ["macros"]}
rayon = {version = "1", optional = true}
scoped-tls = "1.0.0"
serde = {version = "1", features = ["derive"]}
smallvec = "1.6.0"
swc_atoms = {version = "0.2", path = "../swc_atoms"}
swc_common = {version = "0.16.0", path = "../swc_common"}

View File

@ -0,0 +1,101 @@
use serde::{Deserialize, Serialize};
/// Alternative for https://babeljs.io/docs/en/assumptions
///
/// All fields default to `false`.
#[derive(
Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct Assumptions {
/// https://babeljs.io/docs/en/assumptions#arraylikeisiterable
pub array_like_is_iterable: bool,
/// https://babeljs.io/docs/en/assumptions#constantreexports
pub constant_reexports: bool,
/// https://babeljs.io/docs/en/assumptions#constantsuper
pub constant_super: bool,
/// https://babeljs.io/docs/en/assumptions#enumerablemodulemeta
pub enumerable_module_meta: bool,
/// https://babeljs.io/docs/en/assumptions#ignorefunctionlength
pub ignore_function_length: bool,
/// https://babeljs.io/docs/en/assumptions#ignoretoprimitivehint
pub ignore_to_primitive_hint: bool,
/// https://babeljs.io/docs/en/assumptions#iterableisarray
pub iterable_is_array: bool,
/// https://babeljs.io/docs/en/assumptions#mutabletemplateobject
pub mutable_template_object: bool,
/// https://babeljs.io/docs/en/assumptions#noclasscalls
pub no_class_calls: bool,
/// https://babeljs.io/docs/en/assumptions#nodocumentall
pub no_document_all: bool,
/// https://babeljs.io/docs/en/assumptions#noincompletensimportdetection
pub no_incomplete_ns_import_detection: bool,
/// https://babeljs.io/docs/en/assumptions#nonewarrows
pub no_new_arrows: bool,
/// https://babeljs.io/docs/en/assumptions#objectrestnosymbols
pub object_rest_no_symbols: bool,
/// https://babeljs.io/docs/en/assumptions#privatefieldsasproperties
pub private_fields_as_properties: bool,
/// https://babeljs.io/docs/en/assumptions#puregetters
pub pure_getters: bool,
/// https://babeljs.io/docs/en/assumptions#setclassmethods
pub set_class_methods: bool,
/// https://babeljs.io/docs/en/assumptions#setcomputedproperties
pub set_computed_properties: bool,
/// https://babeljs.io/docs/en/assumptions#setpublicclassfields
pub set_public_class_fields: bool,
/// https://babeljs.io/docs/en/assumptions#setspreadproperties
pub set_spread_properties: bool,
/// https://babeljs.io/docs/en/assumptions#skipforofiteratorclosing
pub skip_for_of_iterator_closing: bool,
/// https://babeljs.io/docs/en/assumptions#superiscallableconstructor
pub super_is_callable_constructor: bool,
}
impl Assumptions {
pub fn all() -> Self {
Self {
array_like_is_iterable: true,
constant_reexports: true,
constant_super: true,
enumerable_module_meta: true,
ignore_function_length: true,
ignore_to_primitive_hint: true,
iterable_is_array: true,
mutable_template_object: true,
no_class_calls: true,
no_document_all: true,
no_incomplete_ns_import_detection: true,
no_new_arrows: true,
object_rest_no_symbols: true,
private_fields_as_properties: true,
pure_getters: true,
set_class_methods: true,
set_computed_properties: true,
set_public_class_fields: true,
set_spread_properties: true,
skip_for_of_iterator_closing: true,
super_is_callable_constructor: true,
}
}
}

View File

@ -3,6 +3,7 @@ pub mod ext;
pub mod fixer;
#[macro_use]
pub mod hygiene;
pub mod assumptions;
pub mod helpers;
#[doc(hidden)]
pub mod native;