feat(es): Add an option to disable builtin transforms (#7873)

This commit is contained in:
Donny/강동윤 2023-08-26 10:12:36 +09:00 committed by GitHub
parent eed290319e
commit 71d01ec127
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 145 additions and 96 deletions

View File

@ -324,7 +324,7 @@ impl Options {
config: Option<Config>,
comments: Option<&'a SingleThreadedComments>,
custom_before_pass: impl FnOnce(&Program) -> P,
) -> Result<BuiltInput<impl 'a + swc_ecma_visit::Fold>, Error>
) -> Result<BuiltInput<Box<dyn 'a + Fold>>, Error>
where
P: 'a + swc_ecma_visit::Fold,
{
@ -759,88 +759,95 @@ impl Options {
noop()
};
let pass = chain!(
lint_to_fold(swc_ecma_lints::rules::all(LintParams {
program: &program,
lint_config: &lints,
top_level_ctxt,
unresolved_ctxt,
es_version,
source_map: cm.clone(),
})),
// Decorators may use type information
Optional::new(
match transform.decorator_version.unwrap_or_default() {
DecoratorVersion::V202112 => {
Either::Left(decorators(decorators::Config {
legacy: transform.legacy_decorator.into_bool(),
emit_metadata: transform.decorator_metadata.into_bool(),
use_define_for_class_fields: !assumptions.set_public_class_fields,
}))
}
DecoratorVersion::V202203 => {
Either::Right(
let pass: Box<dyn Fold> = if experimental
.disable_builtin_transforms_for_internal_testing
.into_bool()
{
Box::new(plugin_transforms)
} else {
Box::new(chain!(
lint_to_fold(swc_ecma_lints::rules::all(LintParams {
program: &program,
lint_config: &lints,
top_level_ctxt,
unresolved_ctxt,
es_version,
source_map: cm.clone(),
})),
// Decorators may use type information
Optional::new(
match transform.decorator_version.unwrap_or_default() {
DecoratorVersion::V202112 => {
Either::Left(decorators(decorators::Config {
legacy: transform.legacy_decorator.into_bool(),
emit_metadata: transform.decorator_metadata.into_bool(),
use_define_for_class_fields: !assumptions.set_public_class_fields,
}))
}
DecoratorVersion::V202203 => {
Either::Right(
swc_ecma_transforms::proposals::decorator_2022_03::decorator_2022_03(),
)
}
},
syntax.decorators()
),
// The transform strips import assertions, so it's only enabled if
// keep_import_assertions is false.
Optional::new(import_assertions(), !keep_import_assertions),
Optional::new(
typescript::strip_with_jsx::<Option<&dyn Comments>>(
cm.clone(),
typescript::Config {
pragma: Some(
transform
.react
.pragma
.clone()
.unwrap_or_else(default_pragma)
),
pragma_frag: Some(
transform
.react
.pragma_frag
.clone()
.unwrap_or_else(default_pragma_frag)
),
ts_enum_config: TsEnumConfig {
treat_const_enum_as_enum: transform
.treat_const_enum_as_enum
.into_bool(),
ts_enum_is_readonly: assumptions.ts_enum_is_readonly,
},
import_export_assign_config,
..Default::default()
}
},
comments.map(|v| v as _),
top_level_mark
syntax.decorators()
),
syntax.typescript()
),
plugin_transforms,
custom_before_pass(&program),
// handle jsx
Optional::new(
react::react::<&dyn Comments>(
cm.clone(),
comments.map(|v| v as _),
transform.react,
top_level_mark,
unresolved_mark
// The transform strips import assertions, so it's only enabled if
// keep_import_assertions is false.
Optional::new(import_assertions(), !keep_import_assertions),
Optional::new(
typescript::strip_with_jsx::<Option<&dyn Comments>>(
cm.clone(),
typescript::Config {
pragma: Some(
transform
.react
.pragma
.clone()
.unwrap_or_else(default_pragma)
),
pragma_frag: Some(
transform
.react
.pragma_frag
.clone()
.unwrap_or_else(default_pragma_frag)
),
ts_enum_config: TsEnumConfig {
treat_const_enum_as_enum: transform
.treat_const_enum_as_enum
.into_bool(),
ts_enum_is_readonly: assumptions.ts_enum_is_readonly,
},
import_export_assign_config,
..Default::default()
},
comments.map(|v| v as _),
top_level_mark
),
syntax.typescript()
),
syntax.jsx()
),
pass,
Optional::new(jest::jest(), transform.hidden.jest.into_bool()),
Optional::new(
dropped_comments_preserver(comments.cloned()),
preserve_all_comments
),
);
plugin_transforms,
custom_before_pass(&program),
// handle jsx
Optional::new(
react::react::<&dyn Comments>(
cm.clone(),
comments.map(|v| v as _),
transform.react,
top_level_mark,
unresolved_mark
),
syntax.jsx()
),
pass,
Optional::new(jest::jest(), transform.hidden.jest.into_bool()),
Optional::new(
dropped_comments_preserver(comments.cloned()),
preserve_all_comments
),
))
};
Ok(BuiltInput {
program,
@ -1454,6 +1461,9 @@ pub struct JscExperimental {
/// and will not be considered as breaking changes.
#[serde(default)]
pub cache_root: Option<String>,
#[serde(default)]
pub disable_builtin_transforms_for_internal_testing: BoolConfig<false>,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]

View File

@ -733,7 +733,7 @@ impl Compiler {
}
}
#[tracing::instrument(level = "info", skip_all)]
#[tracing::instrument(skip_all)]
pub fn read_config(&self, opts: &Options, name: &FileName) -> Result<Option<Config>, Error> {
static CUR_DIR: Lazy<PathBuf> = Lazy::new(|| {
if cfg!(target_arch = "wasm32") {
@ -845,7 +845,7 @@ impl Compiler {
/// This method handles merging of config.
///
/// This method does **not** parse module.
#[tracing::instrument(level = "info", skip_all)]
#[tracing::instrument(skip_all)]
pub fn parse_js_as_input<'a, P>(
&'a self,
fm: Lrc<SourceFile>,
@ -908,7 +908,7 @@ impl Compiler {
})
}
#[tracing::instrument(level = "info", skip_all)]
#[tracing::instrument(skip_all)]
pub fn transform(
&self,
handler: &Handler,
@ -936,7 +936,7 @@ impl Compiler {
///
/// This means, you can use `noop_visit_type`, `noop_fold_type` and
/// `noop_visit_mut_type` in your visitor to reduce the binary size.
#[tracing::instrument(level = "info", skip_all)]
#[tracing::instrument(skip_all)]
pub fn process_js_with_custom_pass<P1, P2>(
&self,
fm: Arc<SourceFile>,
@ -997,11 +997,11 @@ impl Compiler {
None
};
self.process_js_inner(handler, orig.as_ref(), config)
self.apply_transforms(handler, orig.as_ref(), config)
})
}
#[tracing::instrument(level = "info", skip(self, handler, opts))]
#[tracing::instrument(skip(self, handler, opts))]
pub fn process_js_file(
&self,
fm: Arc<SourceFile>,
@ -1019,7 +1019,7 @@ impl Compiler {
)
}
#[tracing::instrument(level = "info", skip_all)]
#[tracing::instrument(skip_all)]
pub fn minify(
&self,
fm: Arc<SourceFile>,
@ -1186,7 +1186,7 @@ impl Compiler {
/// You can use custom pass with this method.
///
/// There exists a [PassBuilder] to help building custom passes.
#[tracing::instrument(level = "info", skip_all)]
#[tracing::instrument(skip_all)]
pub fn process_js(
&self,
handler: &Handler,
@ -1207,8 +1207,8 @@ impl Compiler {
)
}
#[tracing::instrument(level = "info", skip_all)]
fn process_js_inner(
#[tracing::instrument(name = "swc::Compiler::apply_transforms", skip_all)]
fn apply_transforms(
&self,
handler: &Handler,
orig: Option<&sourcemap::SourceMap>,
@ -1281,7 +1281,7 @@ fn find_swcrc(path: &Path, root: &Path, root_mode: RootMode) -> Option<PathBuf>
None
}
#[tracing::instrument(level = "info", skip_all)]
#[tracing::instrument(skip_all)]
fn load_swcrc(path: &Path) -> Result<Rc, Error> {
let content = read_to_string(path).context("failed to read config (.swcrc) file")?;

View File

@ -0,0 +1,31 @@
import swc from "../../..";
describe("when jsc.experimentalDisableBuiltinTransforms is true", () => {
it("should preserve TypeScript", async () => {
const { code } = await swc.transform(
`
const hello: Type = () => {
console.log('hello');
};
`,
{
jsc: {
parser: {
syntax: "typescript",
},
experimental: {
disableBuiltinTransformsForInternalTesting: true,
},
},
minify: false,
}
);
expect(code).toMatchInlineSnapshot(`
"const hello: Type = ()=>{
console.log(\\"hello\\");
};
"
`);
});
});

View File

@ -178,6 +178,6 @@
],
"packageManager": "yarn@3.5.0",
"dependencies": {
"@swc/types": "^0.1.3"
"@swc/types": "^0.1.4"
}
}

View File

@ -591,6 +591,9 @@ export interface JscConfig {
*/
keepClassNames?: boolean;
/**
* This is experimental, and can be removed without a major version bump.
*/
experimental?: {
optimizeHygiene?: boolean;
keepImportAssertions?: boolean;
@ -608,6 +611,11 @@ export interface JscConfig {
* Second parameter of tuple is JSON based configuration for the plugin.
*/
plugins?: Array<[string, Record<string, any>]>;
/**
* Disable builtin transforms. If enabled, only Wasm plugins are used.
*/
disableBuiltinTransformsForInternalTesting?: boolean;
};
baseUrl?: string;

View File

@ -1,6 +1,6 @@
{
"name": "@swc/types",
"version": "0.1.3",
"version": "0.1.4",
"description": "Typings for the swc project.",
"sideEffects": false,
"scripts": {

View File

@ -2564,7 +2564,7 @@ __metadata:
"@swc/core-win32-x64-msvc": 1.2.146
"@swc/helpers": ^0.5.0
"@swc/plugin-jest": latest
"@swc/types": ^0.1.3
"@swc/types": ^0.1.4
"@taplo/cli": ^0.3.2
"@types/jest": ^28.1.4
"@types/node": ^20.5.0
@ -2647,10 +2647,10 @@ __metadata:
languageName: node
linkType: hard
"@swc/types@npm:^0.1.3":
version: 0.1.3
resolution: "@swc/types@npm:0.1.3"
checksum: 89b86ac338076a4c7ad3b8b016bb7d9ea6357517716d46232c372dc21f93166e08ed334da0a157e02cd5a1b1ff651542ddcd6f43988ee74b16f837a840681143
"@swc/types@npm:^0.1.4":
version: 0.1.4
resolution: "@swc/types@npm:0.1.4"
checksum: 9b09de7dca8e4b19bfb43f9e332c771855158cb761d26000807fe858447ecbc5342a6c257b26d9aa5497f7138fc58913693e2bee222e5042e0e8f57c2979ae66
languageName: node
linkType: hard