Skip to content

Commit

Permalink
feat(ts/fast-strip): Distinguish invalid vs unsupported (#9846)
Browse files Browse the repository at this point in the history
**Description:**

I tried adding a property to the error thrown, but `wasm_bindgen` does not support adding a property to an error nor creating different kinds of errors.

So, I throw an object with `code` and `message` instead.
  • Loading branch information
kdy1 authored Jan 10, 2025
1 parent 615ae93 commit 5709bc2
Show file tree
Hide file tree
Showing 23 changed files with 281 additions and 268 deletions.
6 changes: 6 additions & 0 deletions .changeset/metal-penguins-travel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
swc_core: minor
swc_fast_ts_strip: minor
---

feat(ts/fast-strip): Distinguish invalid vs unsupported
6 changes: 5 additions & 1 deletion bindings/binding_minifier_node/src/minify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,11 @@ fn do_work(
.clone()
.into_inner()
.unwrap_or(BoolOr::Data(JsMinifyCommentOption::PreserveSomeComments));
minify_file_comments(&comments, preserve_comments);
minify_file_comments(
&comments,
preserve_comments,
options.format.preserve_annotations,
);

swc_compiler_base::print(
cm.clone(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`transform in strip-only mode should not emit 'Caused by: failed to parse' 1`] = `
" x await isn't allowed in non-async function
{
"code": "InvalidSyntax",
"message": " x await isn't allowed in non-async function
,----
1 | function foo() { await Promise.resolve(1); }
: ^^^^^^^
\`----
"
",
}
`;
exports[`transform in strip-only mode should remove declare enum 1`] = `
Expand Down Expand Up @@ -35,6 +38,32 @@ exports[`transform in strip-only mode should remove declare enum 3`] = `
}
`;
exports[`transform in strip-only mode should report correct error for syntax error 1`] = `
{
"code": "InvalidSyntax",
"message": " x Expected ';', '}' or <eof>
,----
1 | function foo() { invalid syntax }
: ^^^|^^^ ^^^^^^
: \`-- This is the expression part of an expression statement
\`----
",
}
`;
exports[`transform in strip-only mode should report correct error for unsupported syntax 1`] = `
{
"code": "UnsupportedSyntax",
"message": " x TypeScript enum is not supported in strip-only mode
,-[1:1]
1 | ,-> enum Foo {
2 | | a, b
3 | \`-> }
\`----
",
}
`;
exports[`transform in strip-only mode should strip complex expressions 1`] = `
{
"code": "const foo = {
Expand Down Expand Up @@ -89,30 +118,39 @@ exports[`transform in strip-only mode should strip type declarations 1`] = `
`;
exports[`transform in strip-only mode should throw an error when it encounters a module 1`] = `
" x TypeScript namespace declaration is not supported in strip-only mode
{
"code": "UnsupportedSyntax",
"message": " x TypeScript namespace declaration is not supported in strip-only mode
,----
1 | module foo {}
: ^^^^^^^^^^^^^
\`----
"
",
}
`;
exports[`transform in strip-only mode should throw an error when it encounters a namespace 1`] = `
" x TypeScript namespace declaration is not supported in strip-only mode
{
"code": "UnsupportedSyntax",
"message": " x TypeScript namespace declaration is not supported in strip-only mode
,----
1 | namespace Foo {}
: ^^^^^^^^^^^^^^^^
\`----
"
",
}
`;
exports[`transform in strip-only mode should throw an error when it encounters an enum 1`] = `
" x TypeScript enum is not supported in strip-only mode
{
"code": "UnsupportedSyntax",
"message": " x TypeScript enum is not supported in strip-only mode
,----
1 | enum Foo {}
: ^^^^^^^^^^^
\`----
"
",
}
`;
exports[`transform should strip types 1`] = `
Expand Down
19 changes: 19 additions & 0 deletions bindings/binding_typescript_wasm/__tests__/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,5 +138,24 @@ describe("transform", () => {
})
).rejects.toMatchSnapshot();
});


it("should report correct error for syntax error", async () => {
await expect(
swc.transform("function foo() { invalid syntax }", {
mode: "strip-only",
})
).rejects.toMatchSnapshot();
});

it("should report correct error for unsupported syntax", async () => {
await expect(
swc.transform(`enum Foo {
a, b
}`, {
mode: "strip-only",
})
).rejects.toMatchSnapshot();
});
});
});
21 changes: 19 additions & 2 deletions bindings/binding_typescript_wasm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use anyhow::Error;
use serde::Serialize;
use swc_common::{errors::ColorConfig, sync::Lrc, SourceMap, GLOBALS};
use swc_error_reporters::handler::{try_with_handler, HandlerOpts};
use swc_fast_ts_strip::{Options, TransformOutput};
use swc_fast_ts_strip::{ErrorCode, Options, TransformOutput, TsError};
use wasm_bindgen::prelude::*;
use wasm_bindgen_futures::{
future_to_promise,
Expand Down Expand Up @@ -48,10 +49,26 @@ fn operate(input: String, options: Options) -> Result<TransformOutput, Error> {
color: ColorConfig::Never,
skip_filename: true,
},
|handler| swc_fast_ts_strip::operate(&cm, handler, input, options),
|handler| {
swc_fast_ts_strip::operate(&cm, handler, input, options).map_err(anyhow::Error::new)
},
)
}

#[derive(Debug, Serialize)]
struct ErrorObject {
code: ErrorCode,
message: String,
}

pub fn convert_err(err: Error) -> wasm_bindgen::prelude::JsValue {
if let Some(ts_error) = err.downcast_ref::<TsError>() {
return serde_wasm_bindgen::to_value(&ErrorObject {
code: ts_error.code,
message: err.to_string(),
})
.unwrap();
}

format!("{}", err).into()
}
5 changes: 2 additions & 3 deletions crates/swc_fast_ts_strip/benches/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@ fn fast_ts(c: &mut Criterion) {
fn fast_typescript(b: &mut Bencher) {
b.iter(|| {
::testing::run_test(false, |cm, handler| {
black_box(operate(
let _result = black_box(operate(
&cm,
handler,
black_box(SOURCE.to_string()),
Options {
..Default::default()
},
))
.unwrap();
));

Ok(())
})
Expand Down
Loading

0 comments on commit 5709bc2

Please sign in to comment.