Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bump swc #8881

Merged
merged 9 commits into from
Mar 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 103 additions & 81 deletions Cargo.lock

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import type { Foo } from "./foo";
export { Foo } from "./foo";

export function func(f: Foo) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export enum Foo {
Bar = 123,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { Foo } from "./bar";

export const Bar = Foo.Bar;
27 changes: 24 additions & 3 deletions packages/core/integration-tests/test/typescript.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// @flow
import assert from 'assert';
import path from 'path';
import url from 'url';
import nullthrows from 'nullthrows';
import {
bundle,
run,
Expand All @@ -17,12 +19,12 @@ const tscConfig = path.join(
describe('typescript', function () {
// This tests both the SWC transformer implementation of typescript (which
// powers typescript by default in Parcel) as well as through the Typescript
// tsc transformer. Use a null config to indicate the default config, and the
// tsc transformer. Use a `undefined` config to indicate the default config, and the
// tsc config to use the tsc transformer instead.
//
// If testing details specific to either implementation, create another suite.
for (let config of [
null /* default config -- testing SWC typescript */,
undefined /* default config -- testing SWC typescript */,
tscConfig,
]) {
it('should produce a ts bundle using ES6 imports', async function () {
Expand Down Expand Up @@ -114,7 +116,7 @@ describe('typescript', function () {
assert(/http:\/\/localhost\/test\.[0-9a-f]+\.txt$/.test(output.getRaw()));
assert(
await outputFS.exists(
path.join(distDir, url.parse(output.getRaw()).pathname),
path.join(distDir, nullthrows(url.parse(output.getRaw()).pathname)),
),
);
});
Expand Down Expand Up @@ -234,5 +236,24 @@ describe('typescript', function () {
},
});
});

it('should handle simultaneous import type and reexport correctly', async function () {
if (config != null) {
return;
}
let b = await bundle(
path.join(
__dirname,
'/integration/typescript-import-type-reexport/index.ts',
),
{config},
);

let output = await run(b);

assert.deepEqual(output, {
Bar: 123,
});
});
}
});
6 changes: 3 additions & 3 deletions packages/transformers/js/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ edition = "2021"
crate-type = ["rlib"]

[dependencies]
swc_ecmascript = { version = "0.207.7", features = ["parser", "transforms", "module", "optimization", "react", "typescript", "utils", "visit", "codegen", "utils", "preset_env"] }
swc_common = { version = "0.29.27", features = ["tty-emitter", "sourcemap"] }
swc_atoms = "0.4.33"
swc_ecmascript = { version = "0.225.0", features = ["parser", "transforms", "module", "optimization", "react", "typescript", "utils", "visit", "codegen", "utils", "preset_env"] }
swc_common = { version = "0.30.0", features = ["tty-emitter", "sourcemap"] }
swc_atoms = "0.4.39"
indoc = "1.0.3"
serde = "1.0.123"
serde_bytes = "0.11.5"
Expand Down
4 changes: 2 additions & 2 deletions packages/transformers/js/core/src/dependency_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,7 @@ impl<'a> DependencyCollector<'a> {
}
Arrow(f) => {
let param = f.params.get(0);
let body = match &f.body {
let body = match &*f.body {
ast::BlockStmtOrExpr::Expr(expr) => Some(&**expr),
ast::BlockStmtOrExpr::BlockStmt(block) => self.match_block_stmt_expr(block),
};
Expand Down Expand Up @@ -1106,7 +1106,7 @@ impl Fold for PromiseTransformer {
}

fn fold_arrow_expr(&mut self, node: ast::ArrowExpr) -> ast::ArrowExpr {
if let ast::BlockStmtOrExpr::Expr(expr) = &node.body {
if let ast::BlockStmtOrExpr::Expr(expr) = &*node.body {
if let ast::Expr::Call(call) = &**expr {
if let Some(require_node) = &self.require_node {
if require_node == call {
Expand Down
4 changes: 2 additions & 2 deletions packages/transformers/js/core/src/hoist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ impl<'a> Fold for Hoist<'a> {
return Expr::OptChain(OptChainExpr {
span: opt.span,
question_dot_token: opt.question_dot_token,
base: match opt.base {
base: Box::new(match *opt.base {
OptChainBase::Call(call) => OptChainBase::Call(call.fold_with(self)),
OptChainBase::Member(member) => {
if match_property_name(&member).is_some() {
Expand All @@ -548,7 +548,7 @@ impl<'a> Fold for Hoist<'a> {
OptChainBase::Member(member.fold_children_with(self))
}
}
},
}),
});
}
Expr::Member(member) => {
Expand Down
18 changes: 12 additions & 6 deletions packages/transformers/js/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ use swc_ecmascript::parser::lexer::Lexer;
use swc_ecmascript::parser::{EsConfig, PResult, Parser, StringInput, Syntax, TsConfig};
use swc_ecmascript::preset_env::{preset_env, Mode::Entry, Targets, Version, Versions};
use swc_ecmascript::transforms::fixer::paren_remover;
use swc_ecmascript::transforms::resolver;
use swc_ecmascript::transforms::{
compat::reserved_words::reserved_words, fixer, helpers, hygiene,
optimization::simplify::dead_branch_remover, optimization::simplify::expr_simplifier,
pass::Optional, proposals::decorators, react, typescript,
};
use swc_ecmascript::transforms::{resolver, Assumptions};
use swc_ecmascript::visit::{FoldWith, VisitWith};

use decl_collector::*;
Expand Down Expand Up @@ -188,7 +188,6 @@ pub fn transform(config: Config) -> Result<TransformResult, std::io::Error> {
|| {
let mut react_options = react::Options::default();
if config.is_jsx {
react_options.use_spread = Some(true);
if let Some(jsx_pragma) = &config.jsx_pragma {
react_options.pragma = Some(jsx_pragma.clone());
}
Expand All @@ -215,13 +214,15 @@ pub fn transform(config: Config) -> Result<TransformResult, std::io::Error> {
let global_mark = Mark::fresh(Mark::root());
let unresolved_mark = Mark::fresh(Mark::root());
let module = module.fold_with(&mut chain!(
resolver(unresolved_mark, global_mark, config.is_type_script),
// Decorators can use type information, so must run before the TypeScript pass.
Optional::new(
decorators::decorators(decorators::Config {
legacy: true,
use_define_for_class_fields: config.use_define_for_class_fields,
// Always disabled for now, SWC's implementation doesn't match TSC.
emit_metadata: false,
// use_define_for_class_fields is ignored here, uses preset-env assumptions instead
..Default::default()
}),
config.decorators
),
Expand All @@ -242,7 +243,6 @@ pub fn transform(config: Config) -> Result<TransformResult, std::io::Error> {
typescript::strip(global_mark),
config.is_type_script && !config.is_jsx
),
resolver(unresolved_mark, global_mark, config.is_type_script),
));

// If it's a script, convert into module. This needs to happen after
Expand All @@ -262,6 +262,7 @@ pub fn transform(config: Config) -> Result<TransformResult, std::io::Error> {
Some(&comments),
react_options,
global_mark,
unresolved_mark,
),
config.is_jsx,
));
Expand All @@ -287,6 +288,11 @@ pub fn transform(config: Config) -> Result<TransformResult, std::io::Error> {
}
}

let mut assumptions = Assumptions::default();
if config.is_type_script && !config.use_define_for_class_fields {
assumptions.set_public_class_fields |= true;
}

let mut diagnostics = vec![];
let module = {
let mut passes = chain!(
Expand Down Expand Up @@ -371,13 +377,13 @@ pub fn transform(config: Config) -> Result<TransformResult, std::io::Error> {
global_mark,
Some(&comments),
preset_env_config,
Default::default(),
assumptions,
&mut Default::default(),
),
should_run_preset_env,
),
// Inject SWC helpers if needed.
helpers::inject_helpers(),
helpers::inject_helpers(global_mark),
);

module.fold_with(&mut passes)
Expand Down
2 changes: 1 addition & 1 deletion packages/transformers/js/core/src/modules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ impl ESMFold {
})
} else {
Expr::Arrow(ArrowExpr {
body: BlockStmtOrExpr::Expr(Box::new(local)),
body: Box::new(BlockStmtOrExpr::Expr(Box::new(local))),
is_async: false,
is_generator: false,
params: vec![],
Expand Down
14 changes: 14 additions & 0 deletions packages/transformers/js/src/JSTransformer.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ type TSConfig = {
experimentalDecorators?: boolean,
// https://www.typescriptlang.org/tsconfig#useDefineForClassFields
useDefineForClassFields?: boolean,
// https://www.typescriptlang.org/tsconfig#target
target?: string, // 'es3' | 'es5' | 'es6' | 'es2015' | ... |'es2022' | ... | 'esnext'
...
},
...
Expand Down Expand Up @@ -236,6 +238,18 @@ export default (new Transformer({
isJSX = Boolean(compilerOptions?.jsx || pragma);
decorators = compilerOptions?.experimentalDecorators;
useDefineForClassFields = compilerOptions?.useDefineForClassFields;
if (
useDefineForClassFields === undefined &&
compilerOptions?.target != null
) {
// Default useDefineForClassFields to true if target is ES2022 or higher (including ESNext)
let target = compilerOptions.target.slice(2);
if (target === 'next') {
useDefineForClassFields = true;
} else {
useDefineForClassFields = Number(target) >= 2022;
}
}
}

// Check if we should ignore fs calls
Expand Down