diff --git a/atoms/Cargo.toml b/atoms/Cargo.toml index b0f72bdca06..3732fd3fe0a 100644 --- a/atoms/Cargo.toml +++ b/atoms/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_atoms" repository = "https://github.com/swc-project/swc.git" -version = "0.2.2" +version = "0.2.3" [dependencies] string_cache = "0.8" diff --git a/atoms/words.txt b/atoms/words.txt index 32dc006c50a..33964242bce 100644 --- a/atoms/words.txt +++ b/atoms/words.txt @@ -577,6 +577,7 @@ any apply arguments as +assert asserts async await diff --git a/bundler/Cargo.toml b/bundler/Cargo.toml index 80b21334c05..ea010f8b21b 100644 --- a/bundler/Cargo.toml +++ b/bundler/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_bundler" repository = "https://github.com/swc-project/swc.git" -version = "0.7.4" +version = "0.8.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] @@ -27,12 +27,12 @@ relative-path = "1.2" retain_mut = "=0.1.1" swc_atoms = {version = "0.2", path = "../atoms"} swc_common = {version = "0.10.0", path = "../common"} -swc_ecma_ast = {version = "0.31.0", path = "../ecmascript/ast"} -swc_ecma_codegen = {version = "0.35.0", path = "../ecmascript/codegen"} -swc_ecma_parser = {version = "0.37.0", path = "../ecmascript/parser"} -swc_ecma_transforms = {version = "0.23.1", path = "../ecmascript/transforms"} -swc_ecma_utils = {version = "0.21.0", path = "../ecmascript/utils"} -swc_ecma_visit = {version = "0.17.0", path = "../ecmascript/visit"} +swc_ecma_ast = {version = "0.32.0", path = "../ecmascript/ast"} +swc_ecma_codegen = {version = "0.36.0", path = "../ecmascript/codegen"} +swc_ecma_parser = {version = "0.38.0", path = "../ecmascript/parser"} +swc_ecma_transforms = {version = "0.24.0", path = "../ecmascript/transforms"} +swc_ecma_utils = {version = "0.22.0", path = "../ecmascript/utils"} +swc_ecma_visit = {version = "0.18.0", path = "../ecmascript/visit"} [dev-dependencies] testing = {version = "0.10.0", path = "../testing"} diff --git a/bundler/src/bundler/import/mod.rs b/bundler/src/bundler/import/mod.rs index 1c6c5287929..d3d43c60d18 100644 --- a/bundler/src/bundler/import/mod.rs +++ b/bundler/src/bundler/import/mod.rs @@ -455,6 +455,7 @@ where specifiers: vec![], src: src.clone(), type_only: false, + asserts: None, }; if self.top_level { @@ -553,6 +554,7 @@ where .collect(), src, type_only: false, + asserts: None, }; // if self.top_level { diff --git a/bundler/src/bundler/load.rs b/bundler/src/bundler/load.rs index 2fcaff38567..845eac34afd 100644 --- a/bundler/src/bundler/load.rs +++ b/bundler/src/bundler/load.rs @@ -277,6 +277,7 @@ where specifiers: vec![], src, type_only: false, + asserts: None, }, true, false, diff --git a/ecmascript/Cargo.toml b/ecmascript/Cargo.toml index 913b30afa46..1b3431c181e 100644 --- a/ecmascript/Cargo.toml +++ b/ecmascript/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecmascript" repository = "https://github.com/swc-project/swc.git" -version = "0.7.11" +version = "0.8.0" [features] codegen = ["swc_ecma_codegen"] @@ -20,12 +20,12 @@ const-modules = ["swc_ecma_transforms", "swc_ecma_transforms/const-modules"] react = ["swc_ecma_transforms", "swc_ecma_transforms/react"] [dependencies] -swc_ecma_ast = {version = "0.31.0", path = "./ast"} -swc_ecma_codegen = {version = "0.35.2", path = "./codegen", optional = true} -swc_ecma_dep_graph = {version = "0.3.0", path = "./dep-graph", optional = true} -swc_ecma_parser = {version = "0.37.2", path = "./parser", optional = true} -swc_ecma_transforms = {version = "0.23.15", path = "./transforms", optional = true} -swc_ecma_utils = {version = "0.21.0", path = "./utils", optional = true} -swc_ecma_visit = {version = "0.17.2", path = "./visit", optional = true} +swc_ecma_ast = {version = "0.32.0", path = "./ast"} +swc_ecma_codegen = {version = "0.36.0", path = "./codegen", optional = true} +swc_ecma_dep_graph = {version = "0.4.0", path = "./dep-graph", optional = true} +swc_ecma_parser = {version = "0.38.0", path = "./parser", optional = true} +swc_ecma_transforms = {version = "0.24.0", path = "./transforms", optional = true} +swc_ecma_utils = {version = "0.22.0", path = "./utils", optional = true} +swc_ecma_visit = {version = "0.18.0", path = "./visit", optional = true} [dev-dependencies] diff --git a/ecmascript/ast/Cargo.toml b/ecmascript/ast/Cargo.toml index c2650e60185..5a466f17ee8 100644 --- a/ecmascript/ast/Cargo.toml +++ b/ecmascript/ast/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecma_ast" repository = "https://github.com/swc-project/swc.git" -version = "0.31.0" +version = "0.32.0" [dependencies] enum_kind = {version = "0.2", path = "../../macros/enum_kind"} diff --git a/ecmascript/ast/src/module_decl.rs b/ecmascript/ast/src/module_decl.rs index 4d59d9f655f..558f604d6ce 100644 --- a/ecmascript/ast/src/module_decl.rs +++ b/ecmascript/ast/src/module_decl.rs @@ -4,6 +4,7 @@ use crate::{ ident::Ident, lit::Str, typescript::{TsExportAssignment, TsImportEqualsDecl, TsInterfaceDecl, TsNamespaceExportDecl}, + ObjectLit, }; use is_macro::Is; use swc_common::{ast_node, Span}; @@ -70,6 +71,9 @@ pub struct ImportDecl { #[serde(rename = "typeOnly")] pub type_only: bool, + + #[serde(default)] + pub asserts: Option, } /// `export * from 'mod'` diff --git a/ecmascript/codegen/Cargo.toml b/ecmascript/codegen/Cargo.toml index 67292d9299d..345fa52b698 100644 --- a/ecmascript/codegen/Cargo.toml +++ b/ecmascript/codegen/Cargo.toml @@ -7,7 +7,7 @@ include = ["Cargo.toml", "src/**/*.rs"] license = "Apache-2.0/MIT" name = "swc_ecma_codegen" repository = "https://github.com/swc-project/swc.git" -version = "0.35.3" +version = "0.36.0" [dependencies] bitflags = "1" @@ -15,10 +15,10 @@ num-bigint = {version = "0.2", features = ["serde"]} sourcemap = "6" swc_atoms = {version = "0.2", path = "../../atoms"} swc_common = {version = "0.10.0", path = "../../common"} -swc_ecma_ast = {version = "0.31.0", path = "../ast"} +swc_ecma_ast = {version = "0.32.0", path = "../ast"} swc_ecma_codegen_macros = {version = "0.5", path = "./macros"} [dev-dependencies] swc_common = {version = "0.10.0", path = "../../common", features = ["sourcemap"]} -swc_ecma_parser = {version = "0.37.0", path = "../parser"} +swc_ecma_parser = {version = "0.38.0", path = "../parser"} testing = {version = "0.10.0", path = "../../testing"} diff --git a/ecmascript/dep-graph/Cargo.toml b/ecmascript/dep-graph/Cargo.toml index b279ff2ac49..654d4836b8a 100644 --- a/ecmascript/dep-graph/Cargo.toml +++ b/ecmascript/dep-graph/Cargo.toml @@ -6,14 +6,14 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecma_dep_graph" repository = "https://github.com/swc-project/swc.git" -version = "0.3.0" +version = "0.4.0" [dependencies] swc_atoms = {version = "0.2", path = "../../atoms"} swc_common = {version = "0.10.1", path = "../../common"} -swc_ecma_ast = {version = "0.31.0", path = "../ast"} -swc_ecma_visit = {version = "0.17.0", path = "../visit"} +swc_ecma_ast = {version = "0.32.0", path = "../ast"} +swc_ecma_visit = {version = "0.18.0", path = "../visit"} [dev-dependencies] -swc_ecma_parser = {version = "0.37.0", path = "../parser"} +swc_ecma_parser = {version = "0.38.0", path = "../parser"} testing = {version = "0.10.0", path = "../../testing"} diff --git a/ecmascript/jsdoc/Cargo.toml b/ecmascript/jsdoc/Cargo.toml index cfabea938d6..a508bdc45e4 100644 --- a/ecmascript/jsdoc/Cargo.toml +++ b/ecmascript/jsdoc/Cargo.toml @@ -5,7 +5,7 @@ documentation = "https://swc.rs/rustdoc/jsdoc/" edition = "2018" license = "Apache-2.0/MIT" name = "jsdoc" -version = "0.5.1" +version = "0.6.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -18,7 +18,7 @@ swc_common = {version = "0.10.0", path = "../../common"} [dev-dependencies] anyhow = "1" dashmap = "3" -swc_ecma_ast = {version = "0.31.0", path = "../ast"} -swc_ecma_parser = {version = "0.37.0", path = "../parser"} +swc_ecma_ast = {version = "0.32.0", path = "../ast"} +swc_ecma_parser = {version = "0.38.0", path = "../parser"} testing = {version = "0.10.0", path = "../../testing"} walkdir = "2" diff --git a/ecmascript/parser/Cargo.toml b/ecmascript/parser/Cargo.toml index 7d73981d901..2359d01466c 100644 --- a/ecmascript/parser/Cargo.toml +++ b/ecmascript/parser/Cargo.toml @@ -7,7 +7,7 @@ include = ["Cargo.toml", "src/**/*.rs", "examples/**/*.rs"] license = "Apache-2.0/MIT" name = "swc_ecma_parser" repository = "https://github.com/swc-project/swc.git" -version = "0.37.2" +version = "0.38.0" [features] default = [] @@ -20,11 +20,11 @@ log = "0.4" num-bigint = "0.2" serde = {version = "1", features = ["derive"]} smallvec = "1" -swc_atoms = {version = "0.2", path = "../../atoms"} +swc_atoms = {version = "0.2.3", path = "../../atoms"} swc_common = {version = "0.10.0", path = "../../common"} -swc_ecma_ast = {version = "0.31.0", path = "../ast"} +swc_ecma_ast = {version = "0.32.0", path = "../ast"} swc_ecma_parser_macros = {version = "0.4.1", path = "./macros"} -swc_ecma_visit = {version = "0.17.0", path = "../visit"} +swc_ecma_visit = {version = "0.18.0", path = "../visit"} unicode-xid = "0.2" [dev-dependencies] diff --git a/ecmascript/parser/src/lib.rs b/ecmascript/parser/src/lib.rs index 1c62ec0eba2..4752d5eba4b 100644 --- a/ecmascript/parser/src/lib.rs +++ b/ecmascript/parser/src/lib.rs @@ -123,6 +123,17 @@ impl Default for Syntax { } impl Syntax { + pub fn import_assertions(self) -> bool { + match self { + Syntax::Es(EsConfig { + import_assertions, .. + }) + | Syntax::Typescript(TsConfig { + import_assertions, .. + }) => import_assertions, + } + } + /// Should we parse jsx? pub fn jsx(self) -> bool { match self { @@ -292,6 +303,10 @@ pub struct TsConfig { #[serde(skip, default)] pub no_early_errors: bool, + + /// Stage 3. + #[serde(default)] + pub import_assertions: bool, } #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialOrd, Ord, PartialEq, Eq)] @@ -382,6 +397,10 @@ pub struct EsConfig { /// Stage 3. #[serde(default)] pub top_level_await: bool, + + /// Stage 3. + #[serde(default)] + pub import_assertions: bool, } /// Syntactic context. diff --git a/ecmascript/parser/src/macros.rs b/ecmascript/parser/src/macros.rs index d77928773a3..6388855e0da 100644 --- a/ecmascript/parser/src/macros.rs +++ b/ecmascript/parser/src/macros.rs @@ -356,6 +356,9 @@ macro_rules! tok { ("type") => { crate::token::Token::Word(crate::token::Word::Ident(swc_atoms::js_word!("type"))) }; + ("assert") => { + crate::token::Token::Word(crate::token::Word::Ident(swc_atoms::js_word!("assert"))) + }; } macro_rules! token_including_semi { diff --git a/ecmascript/parser/src/parser/stmt/module_item.rs b/ecmascript/parser/src/parser/stmt/module_item.rs index bd6a3c0c866..b9cbe39125b 100644 --- a/ecmascript/parser/src/parser/stmt/module_item.rs +++ b/ecmascript/parser/src/parser/stmt/module_item.rs @@ -56,6 +56,7 @@ impl<'a, I: Tokens> Parser { src, specifiers: vec![], type_only: false, + asserts: None, })) .map(ModuleItem::from); } @@ -106,13 +107,40 @@ impl<'a, I: Tokens> Parser { } } - let src = self.parse_from_clause_and_semi()?; + let src = { + expect!("from"); + let str_start = cur_pos!(); + let src = match *cur!(true)? { + Token::Str { .. } => match bump!() { + Token::Str { value, has_escape } => Str { + value, + has_escape, + span: span!(str_start), + }, + _ => unreachable!(), + }, + _ => unexpected!("a string literal"), + }; + src + }; + + let asserts = if self.input.syntax().import_assertions() && eat!("assert") { + match *self.parse_object::>()? { + Expr::Object(v) => Some(v), + _ => unreachable!(), + } + } else { + None + }; + + expect!(';'); Ok(ModuleDecl::Import(ImportDecl { span: span!(start), specifiers, src, type_only, + asserts, })) .map(ModuleItem::from) } diff --git a/ecmascript/parser/tests/jsx/basic/custom/unary-paren/input.js.json b/ecmascript/parser/tests/jsx/basic/custom/unary-paren/input.js.json index b01091531ee..8f8005701e5 100644 --- a/ecmascript/parser/tests/jsx/basic/custom/unary-paren/input.js.json +++ b/ecmascript/parser/tests/jsx/basic/custom/unary-paren/input.js.json @@ -44,7 +44,8 @@ "value": "react", "hasEscape": false }, - "typeOnly": false + "typeOnly": false, + "asserts": null }, { "type": "FunctionDeclaration", diff --git a/ecmascript/parser/tests/jsx/basic/custom/unary/input.js.json b/ecmascript/parser/tests/jsx/basic/custom/unary/input.js.json index 5ebc6c94992..8ba561d7b2f 100644 --- a/ecmascript/parser/tests/jsx/basic/custom/unary/input.js.json +++ b/ecmascript/parser/tests/jsx/basic/custom/unary/input.js.json @@ -44,7 +44,8 @@ "value": "react", "hasEscape": false }, - "typeOnly": false + "typeOnly": false, + "asserts": null }, { "type": "FunctionDeclaration", diff --git a/ecmascript/parser/tests/span.rs b/ecmascript/parser/tests/span.rs index a67f1eaad5e..62991317973 100644 --- a/ecmascript/parser/tests/span.rs +++ b/ecmascript/parser/tests/span.rs @@ -77,9 +77,8 @@ fn load_tests(tests: &mut Vec) -> Result<(), io::Error> { Syntax::Typescript(TsConfig { tsx: true, decorators: true, - dynamic_import: false, - dts: false, no_early_errors: true, + ..Default::default() }), Default::default(), (&*src).into(), diff --git a/ecmascript/parser/tests/typescript.rs b/ecmascript/parser/tests/typescript.rs index 95095fdc0d7..2ec5c227267 100644 --- a/ecmascript/parser/tests/typescript.rs +++ b/ecmascript/parser/tests/typescript.rs @@ -229,6 +229,7 @@ where tsx: fname.contains("tsx"), dynamic_import: true, decorators: true, + import_assertions: true, no_early_errors, ..Default::default() }), diff --git a/ecmascript/parser/tests/typescript/custom/issue-535/input.ts.json b/ecmascript/parser/tests/typescript/custom/issue-535/input.ts.json index 5ef41fc9945..b27765d294c 100644 --- a/ecmascript/parser/tests/typescript/custom/issue-535/input.ts.json +++ b/ecmascript/parser/tests/typescript/custom/issue-535/input.ts.json @@ -42,7 +42,8 @@ "value": "test", "hasEscape": false }, - "typeOnly": false + "typeOnly": false, + "asserts": null }, { "type": "ImportDeclaration", @@ -82,7 +83,8 @@ "value": "test", "hasEscape": false }, - "typeOnly": false + "typeOnly": false, + "asserts": null } ], "interpreter": null diff --git a/ecmascript/parser/tests/typescript/custom/tsx-unary/input.tsx.json b/ecmascript/parser/tests/typescript/custom/tsx-unary/input.tsx.json index 5ebc6c94992..8ba561d7b2f 100644 --- a/ecmascript/parser/tests/typescript/custom/tsx-unary/input.tsx.json +++ b/ecmascript/parser/tests/typescript/custom/tsx-unary/input.tsx.json @@ -44,7 +44,8 @@ "value": "react", "hasEscape": false }, - "typeOnly": false + "typeOnly": false, + "asserts": null }, { "type": "FunctionDeclaration", diff --git a/ecmascript/parser/tests/typescript/custom/type-only/import/aliased/input.ts.json b/ecmascript/parser/tests/typescript/custom/type-only/import/aliased/input.ts.json index fb73b271471..5e2c1cd1d1b 100644 --- a/ecmascript/parser/tests/typescript/custom/type-only/import/aliased/input.ts.json +++ b/ecmascript/parser/tests/typescript/custom/type-only/import/aliased/input.ts.json @@ -55,7 +55,8 @@ "value": "foo", "hasEscape": false }, - "typeOnly": true + "typeOnly": true, + "asserts": null } ], "interpreter": null diff --git a/ecmascript/parser/tests/typescript/custom/type-only/import/default/input.ts.json b/ecmascript/parser/tests/typescript/custom/type-only/import/default/input.ts.json index 62720ceda0e..ecf15096e9e 100644 --- a/ecmascript/parser/tests/typescript/custom/type-only/import/default/input.ts.json +++ b/ecmascript/parser/tests/typescript/custom/type-only/import/default/input.ts.json @@ -44,7 +44,8 @@ "value": "foo", "hasEscape": false }, - "typeOnly": true + "typeOnly": true, + "asserts": null }, { "type": "ImportDeclaration", @@ -84,7 +85,8 @@ "value": "./a", "hasEscape": false }, - "typeOnly": false + "typeOnly": false, + "asserts": null } ], "interpreter": null diff --git a/ecmascript/parser/tests/typescript/custom/type-only/import/specific/input.ts.json b/ecmascript/parser/tests/typescript/custom/type-only/import/specific/input.ts.json index 0dd6fb11c09..4d0a48a2983 100644 --- a/ecmascript/parser/tests/typescript/custom/type-only/import/specific/input.ts.json +++ b/ecmascript/parser/tests/typescript/custom/type-only/import/specific/input.ts.json @@ -45,7 +45,8 @@ "value": "foo", "hasEscape": false }, - "typeOnly": true + "typeOnly": true, + "asserts": null }, { "type": "ImportDeclaration", @@ -65,7 +66,8 @@ "value": "foo", "hasEscape": false }, - "typeOnly": true + "typeOnly": true, + "asserts": null } ], "interpreter": null diff --git a/ecmascript/parser/tests/typescript/import-assertions/dynamic-import/expr/input.ts b/ecmascript/parser/tests/typescript/import-assertions/dynamic-import/expr/input.ts new file mode 100644 index 00000000000..27b97761342 --- /dev/null +++ b/ecmascript/parser/tests/typescript/import-assertions/dynamic-import/expr/input.ts @@ -0,0 +1 @@ +foo(import('./lazy', { assert: { type: "json" } })) \ No newline at end of file diff --git a/ecmascript/parser/tests/typescript/import-assertions/dynamic-import/expr/input.ts.json b/ecmascript/parser/tests/typescript/import-assertions/dynamic-import/expr/input.ts.json new file mode 100644 index 00000000000..c773e391cb9 --- /dev/null +++ b/ecmascript/parser/tests/typescript/import-assertions/dynamic-import/expr/input.ts.json @@ -0,0 +1,140 @@ +{ + "type": "Module", + "span": { + "start": 0, + "end": 51, + "ctxt": 0 + }, + "body": [ + { + "type": "ExpressionStatement", + "span": { + "start": 0, + "end": 51, + "ctxt": 0 + }, + "expression": { + "type": "CallExpression", + "span": { + "start": 0, + "end": 51, + "ctxt": 0 + }, + "callee": { + "type": "Identifier", + "span": { + "start": 0, + "end": 3, + "ctxt": 0 + }, + "value": "foo", + "typeAnnotation": null, + "optional": false + }, + "arguments": [ + { + "spread": null, + "expression": { + "type": "CallExpression", + "span": { + "start": 4, + "end": 50, + "ctxt": 0 + }, + "callee": { + "type": "Identifier", + "span": { + "start": 4, + "end": 10, + "ctxt": 0 + }, + "value": "import", + "typeAnnotation": null, + "optional": false + }, + "arguments": [ + { + "spread": null, + "expression": { + "type": "StringLiteral", + "span": { + "start": 11, + "end": 19, + "ctxt": 0 + }, + "value": "./lazy", + "hasEscape": false + } + }, + { + "spread": null, + "expression": { + "type": "ObjectExpression", + "span": { + "start": 21, + "end": 49, + "ctxt": 0 + }, + "properties": [ + { + "type": "KeyValueProperty", + "key": { + "type": "Identifier", + "span": { + "start": 23, + "end": 29, + "ctxt": 0 + }, + "value": "assert", + "typeAnnotation": null, + "optional": false + }, + "value": { + "type": "ObjectExpression", + "span": { + "start": 31, + "end": 47, + "ctxt": 0 + }, + "properties": [ + { + "type": "KeyValueProperty", + "key": { + "type": "Identifier", + "span": { + "start": 33, + "end": 37, + "ctxt": 0 + }, + "value": "type", + "typeAnnotation": null, + "optional": false + }, + "value": { + "type": "StringLiteral", + "span": { + "start": 39, + "end": 45, + "ctxt": 0 + }, + "value": "json", + "hasEscape": false + } + } + ] + } + } + ] + } + } + ], + "typeArguments": null + } + } + ], + "typeArguments": null + } + } + ], + "interpreter": null +} diff --git a/ecmascript/parser/tests/typescript/import-assertions/dynamic-import/top/input.ts b/ecmascript/parser/tests/typescript/import-assertions/dynamic-import/top/input.ts new file mode 100644 index 00000000000..18505c2e29e --- /dev/null +++ b/ecmascript/parser/tests/typescript/import-assertions/dynamic-import/top/input.ts @@ -0,0 +1,2 @@ +import('./lazy', { assert: { type: "json" } }) + .then((lazy) => console.log(lazy)) \ No newline at end of file diff --git a/ecmascript/parser/tests/typescript/import-assertions/dynamic-import/top/input.ts.json b/ecmascript/parser/tests/typescript/import-assertions/dynamic-import/top/input.ts.json new file mode 100644 index 00000000000..a964264f360 --- /dev/null +++ b/ecmascript/parser/tests/typescript/import-assertions/dynamic-import/top/input.ts.json @@ -0,0 +1,230 @@ +{ + "type": "Module", + "span": { + "start": 0, + "end": 85, + "ctxt": 0 + }, + "body": [ + { + "type": "ExpressionStatement", + "span": { + "start": 0, + "end": 85, + "ctxt": 0 + }, + "expression": { + "type": "CallExpression", + "span": { + "start": 0, + "end": 85, + "ctxt": 0 + }, + "callee": { + "type": "MemberExpression", + "span": { + "start": 0, + "end": 56, + "ctxt": 0 + }, + "object": { + "type": "CallExpression", + "span": { + "start": 0, + "end": 46, + "ctxt": 0 + }, + "callee": { + "type": "Identifier", + "span": { + "start": 0, + "end": 6, + "ctxt": 0 + }, + "value": "import", + "typeAnnotation": null, + "optional": false + }, + "arguments": [ + { + "spread": null, + "expression": { + "type": "StringLiteral", + "span": { + "start": 7, + "end": 15, + "ctxt": 0 + }, + "value": "./lazy", + "hasEscape": false + } + }, + { + "spread": null, + "expression": { + "type": "ObjectExpression", + "span": { + "start": 17, + "end": 45, + "ctxt": 0 + }, + "properties": [ + { + "type": "KeyValueProperty", + "key": { + "type": "Identifier", + "span": { + "start": 19, + "end": 25, + "ctxt": 0 + }, + "value": "assert", + "typeAnnotation": null, + "optional": false + }, + "value": { + "type": "ObjectExpression", + "span": { + "start": 27, + "end": 43, + "ctxt": 0 + }, + "properties": [ + { + "type": "KeyValueProperty", + "key": { + "type": "Identifier", + "span": { + "start": 29, + "end": 33, + "ctxt": 0 + }, + "value": "type", + "typeAnnotation": null, + "optional": false + }, + "value": { + "type": "StringLiteral", + "span": { + "start": 35, + "end": 41, + "ctxt": 0 + }, + "value": "json", + "hasEscape": false + } + } + ] + } + } + ] + } + } + ], + "typeArguments": null + }, + "property": { + "type": "Identifier", + "span": { + "start": 52, + "end": 56, + "ctxt": 0 + }, + "value": "then", + "typeAnnotation": null, + "optional": false + }, + "computed": false + }, + "arguments": [ + { + "spread": null, + "expression": { + "type": "ArrowFunctionExpression", + "span": { + "start": 57, + "end": 84, + "ctxt": 0 + }, + "params": [ + { + "type": "Identifier", + "span": { + "start": 58, + "end": 62, + "ctxt": 0 + }, + "value": "lazy", + "typeAnnotation": null, + "optional": false + } + ], + "body": { + "type": "CallExpression", + "span": { + "start": 67, + "end": 84, + "ctxt": 0 + }, + "callee": { + "type": "MemberExpression", + "span": { + "start": 67, + "end": 78, + "ctxt": 0 + }, + "object": { + "type": "Identifier", + "span": { + "start": 67, + "end": 74, + "ctxt": 0 + }, + "value": "console", + "typeAnnotation": null, + "optional": false + }, + "property": { + "type": "Identifier", + "span": { + "start": 75, + "end": 78, + "ctxt": 0 + }, + "value": "log", + "typeAnnotation": null, + "optional": false + }, + "computed": false + }, + "arguments": [ + { + "spread": null, + "expression": { + "type": "Identifier", + "span": { + "start": 79, + "end": 83, + "ctxt": 0 + }, + "value": "lazy", + "typeAnnotation": null, + "optional": false + } + } + ], + "typeArguments": null + }, + "async": false, + "generator": false, + "typeParameters": null, + "returnType": null + } + } + ], + "typeArguments": null + } + } + ], + "interpreter": null +} diff --git a/ecmascript/parser/tests/typescript/import-assertions/stmt/test1/input.ts b/ecmascript/parser/tests/typescript/import-assertions/stmt/test1/input.ts new file mode 100644 index 00000000000..890e4290079 --- /dev/null +++ b/ecmascript/parser/tests/typescript/import-assertions/stmt/test1/input.ts @@ -0,0 +1 @@ +import json from "./foo.json" assert { type: "json" }; diff --git a/ecmascript/parser/tests/typescript/import-assertions/stmt/test1/input.ts.json b/ecmascript/parser/tests/typescript/import-assertions/stmt/test1/input.ts.json new file mode 100644 index 00000000000..3d6c36f5d4f --- /dev/null +++ b/ecmascript/parser/tests/typescript/import-assertions/stmt/test1/input.ts.json @@ -0,0 +1,85 @@ +{ + "type": "Module", + "span": { + "start": 0, + "end": 54, + "ctxt": 0 + }, + "body": [ + { + "type": "ImportDeclaration", + "span": { + "start": 0, + "end": 54, + "ctxt": 0 + }, + "specifiers": [ + { + "type": "ImportDefaultSpecifier", + "span": { + "start": 7, + "end": 11, + "ctxt": 0 + }, + "local": { + "type": "Identifier", + "span": { + "start": 7, + "end": 11, + "ctxt": 0 + }, + "value": "json", + "typeAnnotation": null, + "optional": false + } + } + ], + "source": { + "type": "StringLiteral", + "span": { + "start": 17, + "end": 29, + "ctxt": 0 + }, + "value": "./foo.json", + "hasEscape": false + }, + "typeOnly": false, + "asserts": { + "type": "ObjectExpression", + "span": { + "start": 37, + "end": 53, + "ctxt": 0 + }, + "properties": [ + { + "type": "KeyValueProperty", + "key": { + "type": "Identifier", + "span": { + "start": 39, + "end": 43, + "ctxt": 0 + }, + "value": "type", + "typeAnnotation": null, + "optional": false + }, + "value": { + "type": "StringLiteral", + "span": { + "start": 45, + "end": 51, + "ctxt": 0 + }, + "value": "json", + "hasEscape": false + } + } + ] + } + } + ], + "interpreter": null +} diff --git a/ecmascript/parser/tests/typescript/import/not-top-level/input.ts.json b/ecmascript/parser/tests/typescript/import/not-top-level/input.ts.json index 2268ce07fa1..4d08dd7b1c3 100644 --- a/ecmascript/parser/tests/typescript/import/not-top-level/input.ts.json +++ b/ecmascript/parser/tests/typescript/import/not-top-level/input.ts.json @@ -71,7 +71,8 @@ "value": "a", "hasEscape": false }, - "typeOnly": false + "typeOnly": false, + "asserts": null } ] } diff --git a/ecmascript/parser/tests/typescript/issue-913/input.ts.json b/ecmascript/parser/tests/typescript/issue-913/input.ts.json index 66693a2b97a..6c3cb52d90a 100644 --- a/ecmascript/parser/tests/typescript/issue-913/input.ts.json +++ b/ecmascript/parser/tests/typescript/issue-913/input.ts.json @@ -45,7 +45,8 @@ "value": "../../deps.ts", "hasEscape": false }, - "typeOnly": false + "typeOnly": false, + "asserts": null }, { "type": "ImportDeclaration", @@ -85,7 +86,8 @@ "value": "../../members.ts", "hasEscape": false }, - "typeOnly": false + "typeOnly": false, + "asserts": null }, { "type": "ImportDeclaration", @@ -126,7 +128,8 @@ "value": "../../../mod.ts", "hasEscape": false }, - "typeOnly": false + "typeOnly": false, + "asserts": null }, { "type": "ExpressionStatement", diff --git a/ecmascript/preset_env/src/lib.rs b/ecmascript/preset_env/src/lib.rs index 57d1a55924e..c31c89ca190 100644 --- a/ecmascript/preset_env/src/lib.rs +++ b/ecmascript/preset_env/src/lib.rs @@ -286,6 +286,7 @@ impl Fold for Polyfills { has_escape: false, }, type_only: false, + asserts: None, })) }), ); @@ -302,6 +303,7 @@ impl Fold for Polyfills { has_escape: false, }, type_only: false, + asserts: None, })) }), ); diff --git a/ecmascript/transforms/Cargo.toml b/ecmascript/transforms/Cargo.toml index 47f3286e5d4..8ad8d08c77b 100644 --- a/ecmascript/transforms/Cargo.toml +++ b/ecmascript/transforms/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecma_transforms" repository = "https://github.com/swc-project/swc.git" -version = "0.23.16" +version = "0.24.0" [features] const-modules = ["dashmap"] @@ -21,7 +21,7 @@ either = "1.5" fxhash = "0.2" indexmap = "1" is-macro = "0.1" -jsdoc = {version = "0.5.0", path = "../jsdoc"} +jsdoc = {version = "0.6.0", path = "../jsdoc"} log = "0.4.8" once_cell = "1" ordered-float = "1.0.1" @@ -34,17 +34,17 @@ serde_json = "1" smallvec = "1" swc_atoms = {version = "0.2.0", path = "../../atoms"} swc_common = {version = "0.10.0", path = "../../common"} -swc_ecma_ast = {version = "0.31.0", path = "../ast"} -swc_ecma_parser = {version = "0.37.0", path = "../parser"} +swc_ecma_ast = {version = "0.32.0", path = "../ast"} +swc_ecma_parser = {version = "0.38.0", path = "../parser"} swc_ecma_transforms_macros = {version = "0.1.1", path = "./macros"} -swc_ecma_utils = {version = "0.21.0", path = "../utils"} -swc_ecma_visit = {version = "0.17.0", path = "../visit"} +swc_ecma_utils = {version = "0.22.0", path = "../utils"} +swc_ecma_visit = {version = "0.18.0", path = "../visit"} unicode-xid = "0.2" [dev-dependencies] pretty_assertions = "0.6" sourcemap = "6" -swc_ecma_codegen = {version = "0.35.0", path = "../codegen"} +swc_ecma_codegen = {version = "0.36.0", path = "../codegen"} tempfile = "3" testing = {version = "0.10.0", path = "../../testing"} walkdir = "2" diff --git a/ecmascript/transforms/src/helpers.rs b/ecmascript/transforms/src/helpers.rs index cb05a0aad66..501016e2286 100644 --- a/ecmascript/transforms/src/helpers.rs +++ b/ecmascript/transforms/src/helpers.rs @@ -246,6 +246,7 @@ impl InjectHelpers { })], src: quote_str!("@swc/helpers"), type_only: false, + asserts: None, }))] } else { vec![] diff --git a/ecmascript/transforms/src/proposals.rs b/ecmascript/transforms/src/proposals.rs index c6123418f8c..10c79c54f78 100644 --- a/ecmascript/transforms/src/proposals.rs +++ b/ecmascript/transforms/src/proposals.rs @@ -1,4 +1,5 @@ -pub use self::{decorators::decorators, export::export}; +pub use self::{decorators::decorators, export::export, import_assertions::import_assertions}; pub mod decorators; mod export; +mod import_assertions; diff --git a/ecmascript/transforms/src/proposals/export.rs b/ecmascript/transforms/src/proposals/export.rs index b47655a3091..c8f1e9065ac 100644 --- a/ecmascript/transforms/src/proposals/export.rs +++ b/ecmascript/transforms/src/proposals/export.rs @@ -50,6 +50,7 @@ impl Fold for ExportDefaultFrom { .clone() .expect("`export default from` requires source"), type_only: false, + asserts: None, }))); extra_stmts.push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed( NamedExport { @@ -82,6 +83,7 @@ impl Fold for ExportDefaultFrom { .clone() .expect("`export default from` requires source"), type_only: false, + asserts: None, }))); extra_stmts.push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed( NamedExport { diff --git a/ecmascript/transforms/src/proposals/import_assertions.rs b/ecmascript/transforms/src/proposals/import_assertions.rs new file mode 100644 index 00000000000..febf4a21927 --- /dev/null +++ b/ecmascript/transforms/src/proposals/import_assertions.rs @@ -0,0 +1,15 @@ +use swc_ecma_ast::ImportDecl; +use swc_ecma_visit::{as_folder, noop_visit_mut_type, Fold, VisitMut}; + +pub fn import_assertions() -> impl Fold { + as_folder(ImportAssertions) +} +struct ImportAssertions; + +impl VisitMut for ImportAssertions { + noop_visit_mut_type!(); + + fn visit_mut_import_decl(&mut self, n: &mut ImportDecl) { + n.asserts = None; + } +} diff --git a/ecmascript/transforms/tests/typescript_strip_correctness.rs b/ecmascript/transforms/tests/typescript_strip_correctness.rs index 4b15654f6fb..04f07d853ee 100644 --- a/ecmascript/transforms/tests/typescript_strip_correctness.rs +++ b/ecmascript/transforms/tests/typescript_strip_correctness.rs @@ -150,6 +150,7 @@ fn correctness_tests(tests: &mut Vec) -> Result<(), io::Error> { dynamic_import: true, dts: false, no_early_errors: false, + import_assertions: true, }), (&*src).into(), None, diff --git a/ecmascript/utils/Cargo.toml b/ecmascript/utils/Cargo.toml index be6a615d0d8..eeba37f4c56 100644 --- a/ecmascript/utils/Cargo.toml +++ b/ecmascript/utils/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecma_utils" repository = "https://github.com/swc-project/swc.git" -version = "0.21.0" +version = "0.22.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -15,8 +15,8 @@ once_cell = "1" scoped-tls = "1" swc_atoms = {version = "0.2.0", path = "../../atoms"} swc_common = {version = "0.10.0", path = "../../common"} -swc_ecma_ast = {version = "0.31.0", path = "../ast"} -swc_ecma_visit = {version = "0.17.0", path = "../visit"} +swc_ecma_ast = {version = "0.32.0", path = "../ast"} +swc_ecma_visit = {version = "0.18.0", path = "../visit"} unicode-xid = "0.2" [dev-dependencies] diff --git a/ecmascript/visit/Cargo.toml b/ecmascript/visit/Cargo.toml index 08e6adfc90b..3e9c84d361d 100644 --- a/ecmascript/visit/Cargo.toml +++ b/ecmascript/visit/Cargo.toml @@ -6,11 +6,11 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecma_visit" repository = "https://github.com/swc-project/swc.git" -version = "0.17.2" +version = "0.18.0" [dependencies] num-bigint = {version = "0.2", features = ["serde"]} swc_atoms = {version = "0.2", path = "../../atoms"} swc_common = {version = "0.10.0", path = "../../common"} -swc_ecma_ast = {version = "0.31.0", path = "../ast"} +swc_ecma_ast = {version = "0.32.0", path = "../ast"} swc_visit = {version = "0.2.0", path = "../../visit"} diff --git a/ecmascript/visit/src/lib.rs b/ecmascript/visit/src/lib.rs index bc686794e8c..e23ef4dc30e 100644 --- a/ecmascript/visit/src/lib.rs +++ b/ecmascript/visit/src/lib.rs @@ -926,6 +926,7 @@ define!({ pub specifiers: Vec, pub src: Str, pub type_only: bool, + pub asserts: Option, } pub struct ExportAll { pub span: Span, diff --git a/src/builder.rs b/src/builder.rs index 280ce2f49bf..5e59f54ef41 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -5,7 +5,8 @@ use swc_atoms::JsWord; use swc_common::{chain, comments::Comments, errors::Handler, Mark, SourceMap}; use swc_ecma_parser::Syntax; use swc_ecma_transforms::{ - compat, const_modules, fixer, helpers, hygiene, modules, pass::Optional, typescript, + compat, const_modules, fixer, helpers, hygiene, modules, pass::Optional, + proposals::import_assertions, typescript, }; /// Builder is used to create a high performance `Compiler`. @@ -129,11 +130,13 @@ impl<'a, 'b, P: swc_ecma_visit::Fold> PassBuilder<'a, 'b, P> { // compat let compat_pass = if let Some(env) = self.env { Either::Left(chain!( + import_assertions(), Optional::new(typescript::strip(), syntax.typescript()), swc_ecma_preset_env::preset_env(self.global_mark, env) )) } else { Either::Right(chain!( + import_assertions(), Optional::new( compat::es2020::nullish_coalescing(), self.target < JscTarget::Es2020