fix(es/typescript): Preserve type assertions (#9328)

**Related issue:**

 - Closes https://github.com/swc-project/swc/issues/9295
This commit is contained in:
Donny/강동윤 2024-07-24 13:07:39 +09:00 committed by GitHub
parent 1a9bf88f2c
commit 4d60f528d1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 81 additions and 44 deletions

View File

@ -0,0 +1,5 @@
---
swc_fast_ts_strip: patch
---
fix(es/typescript): Preserve type assertions

View File

@ -440,15 +440,6 @@ impl Visit for TsStrip {
}
}
fn visit_class_decl(&mut self, n: &ClassDecl) {
if n.declare {
self.add_replacement(n.span());
return;
}
n.visit_children_with(self);
}
fn visit_class(&mut self, n: &Class) {
if n.is_abstract {
let r#abstract = self.get_next_token(n.span_lo());
@ -475,6 +466,15 @@ impl Visit for TsStrip {
n.visit_children_with(self);
}
fn visit_class_decl(&mut self, n: &ClassDecl) {
if n.declare {
self.add_replacement(n.span());
return;
}
n.visit_children_with(self);
}
fn visit_class_method(&mut self, n: &ClassMethod) {
if n.function.body.is_none() || n.is_abstract {
self.add_replacement(n.span);
@ -552,10 +552,6 @@ impl Visit for TsStrip {
n.visit_children_with(self);
}
fn visit_ts_index_signature(&mut self, n: &TsIndexSignature) {
self.add_replacement(n.span);
}
fn visit_export_all(&mut self, n: &ExportAll) {
if n.type_only {
self.add_replacement(n.span);
@ -636,29 +632,6 @@ impl Visit for TsStrip {
}
}
fn visit_ts_import_equals_decl(&mut self, n: &TsImportEqualsDecl) {
if n.is_type_only {
self.add_replacement(n.span);
return;
}
HANDLER.with(|handler| {
handler.span_err(
n.span,
"TypeScript import equals declaration is not supported in strip-only mode",
);
});
}
fn visit_ts_export_assignment(&mut self, n: &TsExportAssignment) {
HANDLER.with(|handler| {
handler.span_err(
n.span,
"TypeScript export assignment is not supported in strip-only mode",
);
});
}
fn visit_params(&mut self, n: &[Param]) {
if let Some(p) = n.first().filter(|param| {
matches!(
@ -710,6 +683,33 @@ impl Visit for TsStrip {
});
}
fn visit_ts_export_assignment(&mut self, n: &TsExportAssignment) {
HANDLER.with(|handler| {
handler.span_err(
n.span,
"TypeScript export assignment is not supported in strip-only mode",
);
});
}
fn visit_ts_import_equals_decl(&mut self, n: &TsImportEqualsDecl) {
if n.is_type_only {
self.add_replacement(n.span);
return;
}
HANDLER.with(|handler| {
handler.span_err(
n.span,
"TypeScript import equals declaration is not supported in strip-only mode",
);
});
}
fn visit_ts_index_signature(&mut self, n: &TsIndexSignature) {
self.add_replacement(n.span);
}
fn visit_ts_instantiation(&mut self, n: &TsInstantiation) {
self.add_replacement(span(n.expr.span().hi, n.span.hi));
@ -777,8 +777,17 @@ impl Visit for TsStrip {
self.add_replacement(n.span);
}
/// We do not strip type assertion because it's not safe.
///
/// See https://github.com/swc-project/swc/issues/9295
fn visit_ts_type_assertion(&mut self, n: &TsTypeAssertion) {
self.add_replacement(span(n.span.lo, n.expr.span().lo));
HANDLER.with(|handler| {
handler.span_err(
n.span,
"The angle-bracket syntax for type assertions, `<T>expr`, is not supported in \
type strip mode. Instead, use the 'as' syntax: `expr as T`.",
);
});
n.expr.visit_children_with(self);
}

View File

@ -7,10 +7,11 @@ use testing::NormalizedOutput;
#[testing::fixture("tests/fixture/**/*.ts")]
fn test(input: PathBuf) {
let input_code = std::fs::read_to_string(&input).unwrap();
let output_stderr = input.with_extension("swc-stderr");
let output_file = input.with_extension("js");
let transform_output_file = input.with_extension("transform.js");
testing::run_test(false, |cm, handler| {
let err = testing::run_test(false, |cm, handler| {
let code = operate(&cm, handler, input_code.clone(), opts(Mode::StripOnly))
.expect("should not return Err()")
.code;
@ -19,9 +20,14 @@ fn test(input: PathBuf) {
.compare_to_file(output_file)
.unwrap();
if handler.has_errors() {
return Err(());
}
Ok(())
})
.expect("should not fail");
});
if let Err(err) = err {
err.compare_to_file(output_stderr).unwrap();
}
testing::run_test(false, |cm, handler| {
let code = operate(&cm, handler, input_code, opts(Mode::Transform))

View File

@ -4,7 +4,7 @@ let x /**/ /**/ = 1 ;
[] ;
// ^^^^^^^^^^^^^^^^^^
( "test");
(<string>"test");
//^^^^^^^^
class C /**/ /**/ extends Array/**/ /**/ /**/ {

View File

@ -0,0 +1,7 @@
x The angle-bracket syntax for type assertions, `<T>expr`, is not supported in type strip mode. Instead, use the 'as' syntax: `expr as T`.
,-[7:1]
6 |
7 | (<string>"test");
: ^^^^^^^^^^^^^^
8 | //^^^^^^^^
`----

View File

@ -1,7 +1,7 @@
function foo() {
(void 1); throw new Error('foo');
<任意>(void 1); throw new Error('foo');
}
foo();

View File

@ -0,0 +1,7 @@
x The angle-bracket syntax for type assertions, `<T>expr`, is not supported in type strip mode. Instead, use the 'as' syntax: `expr as T`.
,-[4:1]
3 | function foo() {
4 | <任意>(void 1); throw new Error('foo');
: ^^^^^^^^^^^^^^
5 | }
`----

View File

@ -14,7 +14,7 @@ use swc_common::{
sync::{Lazy, OnceCell},
};
#[cfg(not(target_arch = "wasm32"))]
use wasmer::{BaseTunables, CpuFeature, Engine, Target, Triple};
use wasmer::{sys::BaseTunables, CpuFeature, Engine, Target, Triple};
use wasmer::{Module, Store};
#[cfg(all(not(target_arch = "wasm32"), feature = "filesystem_cache"))]
use wasmer_cache::{Cache as WasmerCache, FileSystemCache, Hash};

View File

@ -12,7 +12,10 @@ use wasmer_wasix::Runtime;
static ENGINE: Lazy<Mutex<wasmer::Engine>> = Lazy::new(|| {
// Use empty enumset to disable simd.
use enumset::EnumSet;
use wasmer::{BaseTunables, CompilerConfig, EngineBuilder, Target, Triple};
use wasmer::{
sys::{BaseTunables, EngineBuilder},
CompilerConfig, Target, Triple,
};
let mut set = EnumSet::new();
// [TODO]: Should we use is_x86_feature_detected! macro instead?