mirror of
https://github.com/swc-project/swc.git
synced 2024-11-23 00:32:15 +03:00
fix(es/minifier): Improve output of minifier (#1990)
swc_common: - Add `Span.has_mark`. swc_ecma_codegen: - Emit `1e3` for `1000`. - Optimize output. (#1986) swc_ecma_minifier: - name mangler: Don't use keywords as an id. - `properties`: Optimize member expression with string properties. - `inline`: Inline some function expressions even if it's not fn-local. - `analyzer`: Track reassignment correctly. - `analyzer`: Track fn-local correctly. - `sequences`: Inject `void` if required. - `inline`: Inline function declarations correctly. - `sequences`: Merge expressions into test of if statements. - `sequences`: Reduce calls to an assigned variable. - Use `Marks` instead of `&dyn Comments`. swc_ecma_transforms_optimization: - `expr_simplifier`: Fix infinite loops. node/swc: - Ensure that `.transform` performs minification. (#1989)
This commit is contained in:
parent
e916b35dd2
commit
f44e25c3af
39
Cargo.lock
generated
39
Cargo.lock
generated
@ -1178,6 +1178,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"backtrace",
|
||||
"fxhash",
|
||||
"log",
|
||||
"napi",
|
||||
"napi-build",
|
||||
"napi-derive",
|
||||
@ -2260,7 +2261,7 @@ checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
|
||||
|
||||
[[package]]
|
||||
name = "swc"
|
||||
version = "0.34.0"
|
||||
version = "0.35.0"
|
||||
dependencies = [
|
||||
"ahash 0.7.4",
|
||||
"anyhow",
|
||||
@ -2353,7 +2354,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_bundler"
|
||||
version = "0.48.0"
|
||||
version = "0.49.0"
|
||||
dependencies = [
|
||||
"ahash 0.7.4",
|
||||
"anyhow",
|
||||
@ -2390,7 +2391,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_common"
|
||||
version = "0.11.1"
|
||||
version = "0.11.2"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"ast_node",
|
||||
@ -2432,7 +2433,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_codegen"
|
||||
version = "0.64.3"
|
||||
version = "0.65.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"num-bigint",
|
||||
@ -2502,7 +2503,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_minifier"
|
||||
version = "0.16.1"
|
||||
version = "0.17.0"
|
||||
dependencies = [
|
||||
"ansi_term 0.12.1",
|
||||
"anyhow",
|
||||
@ -2557,7 +2558,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_preset_env"
|
||||
version = "0.31.0"
|
||||
version = "0.32.0"
|
||||
dependencies = [
|
||||
"dashmap",
|
||||
"fxhash",
|
||||
@ -2583,7 +2584,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms"
|
||||
version = "0.61.0"
|
||||
version = "0.62.0"
|
||||
dependencies = [
|
||||
"pretty_assertions 0.6.1",
|
||||
"sourcemap",
|
||||
@ -2610,7 +2611,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_base"
|
||||
version = "0.24.1"
|
||||
version = "0.25.0"
|
||||
dependencies = [
|
||||
"fxhash",
|
||||
"once_cell",
|
||||
@ -2629,7 +2630,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_classes"
|
||||
version = "0.10.0"
|
||||
version = "0.11.0"
|
||||
dependencies = [
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
@ -2641,7 +2642,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_compat"
|
||||
version = "0.27.0"
|
||||
version = "0.28.0"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"fxhash",
|
||||
@ -2677,7 +2678,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_module"
|
||||
version = "0.28.0"
|
||||
version = "0.29.0"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"anyhow",
|
||||
@ -2700,7 +2701,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_optimization"
|
||||
version = "0.31.0"
|
||||
version = "0.32.0"
|
||||
dependencies = [
|
||||
"dashmap",
|
||||
"fxhash",
|
||||
@ -2727,7 +2728,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_proposal"
|
||||
version = "0.28.0"
|
||||
version = "0.29.0"
|
||||
dependencies = [
|
||||
"either",
|
||||
"fxhash",
|
||||
@ -2749,7 +2750,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_react"
|
||||
version = "0.29.0"
|
||||
version = "0.30.0"
|
||||
dependencies = [
|
||||
"base64 0.13.0",
|
||||
"dashmap",
|
||||
@ -2775,7 +2776,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_testing"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
dependencies = [
|
||||
"ansi_term 0.12.1",
|
||||
"serde",
|
||||
@ -2793,7 +2794,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_typescript"
|
||||
version = "0.30.1"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"fxhash",
|
||||
"serde",
|
||||
@ -2829,7 +2830,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_visit"
|
||||
version = "0.35.0"
|
||||
version = "0.35.1"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"swc_atoms",
|
||||
@ -2840,7 +2841,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecmascript"
|
||||
version = "0.50.0"
|
||||
version = "0.51.0"
|
||||
dependencies = [
|
||||
"swc_ecma_ast",
|
||||
"swc_ecma_codegen",
|
||||
@ -2884,7 +2885,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_visit"
|
||||
version = "0.2.4"
|
||||
version = "0.2.5"
|
||||
dependencies = [
|
||||
"either",
|
||||
"swc_visit_macros",
|
||||
|
14
Cargo.toml
14
Cargo.toml
@ -9,7 +9,7 @@ edition = "2018"
|
||||
license = "Apache-2.0/MIT"
|
||||
name = "swc"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
version = "0.34.0"
|
||||
version = "0.35.0"
|
||||
|
||||
[lib]
|
||||
name = "swc"
|
||||
@ -29,16 +29,16 @@ serde = {version = "1", features = ["derive"]}
|
||||
serde_json = "1"
|
||||
sourcemap = "6"
|
||||
swc_atoms = {version = "0.2", path = "./atoms"}
|
||||
swc_bundler = {version = "0.48.0", path = "./bundler"}
|
||||
swc_bundler = {version = "0.49.0", path = "./bundler"}
|
||||
swc_common = {version = "0.11.0", path = "./common", features = ["sourcemap", "concurrent"]}
|
||||
swc_ecma_ast = {version = "0.49.0", path = "./ecmascript/ast"}
|
||||
swc_ecma_codegen = {version = "0.64.0", path = "./ecmascript/codegen"}
|
||||
swc_ecma_codegen = {version = "0.65.0", path = "./ecmascript/codegen"}
|
||||
swc_ecma_ext_transforms = {version = "0.23.0", path = "./ecmascript/ext-transforms"}
|
||||
swc_ecma_loader = {version = "0.12.0", path = "./ecmascript/loader", features = ["lru", "node", "tsc"]}
|
||||
swc_ecma_minifier = {version = "0.16.0", path = "./ecmascript/minifier"}
|
||||
swc_ecma_minifier = {version = "0.17.0", path = "./ecmascript/minifier"}
|
||||
swc_ecma_parser = {version = "0.65.0", path = "./ecmascript/parser"}
|
||||
swc_ecma_preset_env = {version = "0.31.0", path = "./ecmascript/preset-env"}
|
||||
swc_ecma_transforms = {version = "0.61.0", path = "./ecmascript/transforms", features = [
|
||||
swc_ecma_preset_env = {version = "0.32.0", path = "./ecmascript/preset-env"}
|
||||
swc_ecma_transforms = {version = "0.62.0", path = "./ecmascript/transforms", features = [
|
||||
"compat",
|
||||
"module",
|
||||
"optimization",
|
||||
@ -46,7 +46,7 @@ swc_ecma_transforms = {version = "0.61.0", path = "./ecmascript/transforms", fea
|
||||
"react",
|
||||
"typescript",
|
||||
]}
|
||||
swc_ecma_transforms_base = {version = "0.24.1", path = "./ecmascript/transforms/base"}
|
||||
swc_ecma_transforms_base = {version = "0.25.0", path = "./ecmascript/transforms/base"}
|
||||
swc_ecma_utils = {version = "0.41.0", path = "./ecmascript/utils"}
|
||||
swc_ecma_visit = {version = "0.35.0", path = "./ecmascript/visit"}
|
||||
swc_node_base = {version = "0.2.0", path = "./node/base"}
|
||||
|
@ -9,7 +9,7 @@ include = ["Cargo.toml", "build.rs", "src/**/*.rs", "src/**/*.js"]
|
||||
license = "Apache-2.0/MIT"
|
||||
name = "swc_bundler"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
version = "0.48.0"
|
||||
version = "0.49.0"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[features]
|
||||
@ -34,10 +34,10 @@ retain_mut = "0.1.2"
|
||||
swc_atoms = {version = "0.2.4", path = "../atoms"}
|
||||
swc_common = {version = "0.11.0", path = "../common"}
|
||||
swc_ecma_ast = {version = "0.49.0", path = "../ecmascript/ast"}
|
||||
swc_ecma_codegen = {version = "0.64.0", path = "../ecmascript/codegen"}
|
||||
swc_ecma_codegen = {version = "0.65.0", path = "../ecmascript/codegen"}
|
||||
swc_ecma_loader = {version = "0.12.0", path = "../ecmascript/loader"}
|
||||
swc_ecma_parser = {version = "0.65.0", path = "../ecmascript/parser"}
|
||||
swc_ecma_transforms = {version = "0.61.0", path = "../ecmascript/transforms", features = ["optimization"]}
|
||||
swc_ecma_transforms = {version = "0.62.0", path = "../ecmascript/transforms", features = ["optimization"]}
|
||||
swc_ecma_utils = {version = "0.41.0", path = "../ecmascript/utils"}
|
||||
swc_ecma_visit = {version = "0.35.0", path = "../ecmascript/visit"}
|
||||
|
||||
@ -46,7 +46,7 @@ hex = "0.4"
|
||||
ntest = "0.7.2"
|
||||
reqwest = {version = "0.10.8", features = ["blocking"]}
|
||||
sha-1 = "0.9"
|
||||
swc_ecma_transforms = {version = "0.61.0", path = "../ecmascript/transforms", features = ["react", "typescript"]}
|
||||
swc_ecma_transforms = {version = "0.62.0", path = "../ecmascript/transforms", features = ["react", "typescript"]}
|
||||
tempfile = "3.1.0"
|
||||
testing = {version = "0.12.0", path = "../testing"}
|
||||
url = "2.1.1"
|
||||
|
@ -2,7 +2,7 @@ use anyhow::{Context, Error};
|
||||
use crc::{crc64, crc64::Digest, Hasher64};
|
||||
use std::io;
|
||||
use swc_common::{sync::Lrc, SourceMap, Span};
|
||||
use swc_ecma_ast::Module;
|
||||
use swc_ecma_ast::{EsVersion, Module};
|
||||
use swc_ecma_codegen::{text_writer::WriteJs, Emitter};
|
||||
|
||||
pub(crate) fn calc_hash(cm: Lrc<SourceMap>, m: &Module) -> Result<String, Error> {
|
||||
@ -38,6 +38,10 @@ impl Hasher {
|
||||
}
|
||||
|
||||
impl WriteJs for &mut Hasher {
|
||||
fn target(&self) -> EsVersion {
|
||||
EsVersion::latest()
|
||||
}
|
||||
|
||||
fn increase_indent(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ edition = "2018"
|
||||
license = "Apache-2.0/MIT"
|
||||
name = "swc_common"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
version = "0.11.1"
|
||||
version = "0.11.2"
|
||||
|
||||
[features]
|
||||
concurrent = ["parking_lot"]
|
||||
|
@ -361,6 +361,34 @@ impl Span {
|
||||
*self = Span::new(span.lo, span.hi, span.ctxt);
|
||||
mark
|
||||
}
|
||||
|
||||
/// Returns `true` if `self` is marked with `mark`.
|
||||
///
|
||||
/// Panics if `mark` is not a valid mark.
|
||||
#[inline]
|
||||
pub fn has_mark(self, mark: Mark) -> bool {
|
||||
debug_assert_ne!(
|
||||
mark,
|
||||
Mark::root(),
|
||||
"Cannot check if a span contains a `ROOT` mark"
|
||||
);
|
||||
|
||||
let mut ctxt = self.ctxt;
|
||||
|
||||
loop {
|
||||
if ctxt == SyntaxContext::empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let m = ctxt.remove_mark();
|
||||
if m == mark {
|
||||
return true;
|
||||
}
|
||||
if m == Mark::root() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -6,7 +6,7 @@ edition = "2018"
|
||||
license = "Apache-2.0/MIT"
|
||||
name = "swc_ecmascript"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
version = "0.50.0"
|
||||
version = "0.51.0"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
@ -32,11 +32,11 @@ typescript = ["typescript-parser", "swc_ecma_transforms/typescript"]
|
||||
|
||||
[dependencies]
|
||||
swc_ecma_ast = {version = "0.49.0", path = "./ast"}
|
||||
swc_ecma_codegen = {version = "0.64.0", path = "./codegen", optional = true}
|
||||
swc_ecma_codegen = {version = "0.65.0", path = "./codegen", optional = true}
|
||||
swc_ecma_dep_graph = {version = "0.33.0", path = "./dep-graph", optional = true}
|
||||
swc_ecma_minifier = {version = "0.16.0", path = "./minifier", optional = true}
|
||||
swc_ecma_minifier = {version = "0.17.0", path = "./minifier", optional = true}
|
||||
swc_ecma_parser = {version = "0.65.0", path = "./parser", optional = true, default-features = false}
|
||||
swc_ecma_transforms = {version = "0.61.0", path = "./transforms", optional = true}
|
||||
swc_ecma_transforms = {version = "0.62.0", path = "./transforms", optional = true}
|
||||
swc_ecma_utils = {version = "0.41.0", path = "./utils", optional = true}
|
||||
swc_ecma_visit = {version = "0.35.0", path = "./visit", optional = true}
|
||||
|
||||
|
@ -172,3 +172,5 @@ pub trait IdentExt: AsRef<str> {
|
||||
|
||||
impl IdentExt for JsWord {}
|
||||
impl IdentExt for Ident {}
|
||||
impl IdentExt for &'_ str {}
|
||||
impl IdentExt for String {}
|
||||
|
@ -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.64.3"
|
||||
version = "0.65.0"
|
||||
|
||||
[dependencies]
|
||||
bitflags = "1"
|
||||
|
18
ecmascript/codegen/scripts/compare-file.sh
Executable file
18
ecmascript/codegen/scripts/compare-file.sh
Executable file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eu
|
||||
|
||||
echo ''
|
||||
echo ''
|
||||
echo ''
|
||||
echo "Comparing $1"
|
||||
EXPECTED=$(terser "$1" | xargs)
|
||||
ACTUAL=$(cat "$1" | xargs)
|
||||
|
||||
if [[ $EXPECTED == $ACTUAL || $EXPECTED == "$ACTUAL;" ]]; then
|
||||
echo "PASSED";
|
||||
git add "$1"
|
||||
else
|
||||
echo $EXPECTED
|
||||
echo $ACTUAL
|
||||
echo "FAILED"
|
||||
fi
|
7
ecmascript/codegen/scripts/compare.sh
Executable file
7
ecmascript/codegen/scripts/compare.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eu
|
||||
|
||||
git status -u --porcelain \
|
||||
| grep '?? ecmascript/codegen/tests' \
|
||||
| sed -e 's!^?? ecmascript/codegen/!!' \
|
||||
| xargs -L 1 ./scripts/compare-file.sh
|
@ -81,7 +81,19 @@ impl<'a> Emitter<'a> {
|
||||
let span = self.cm.span_until_char(node.span, ' ');
|
||||
keyword!(span, node.kind.as_str());
|
||||
}
|
||||
space!();
|
||||
|
||||
let starts_with_ident = match node.decls.first() {
|
||||
Some(VarDeclarator {
|
||||
name: Pat::Array(..) | Pat::Rest(..) | Pat::Object(..),
|
||||
..
|
||||
}) => false,
|
||||
_ => true,
|
||||
};
|
||||
if starts_with_ident {
|
||||
space!();
|
||||
} else {
|
||||
formatting_space!();
|
||||
}
|
||||
|
||||
self.emit_list(
|
||||
node.span(),
|
||||
|
@ -1,6 +1,8 @@
|
||||
#![recursion_limit = "1024"]
|
||||
#![allow(unused_variables)]
|
||||
|
||||
use crate::util::EndsWithAlphaNum;
|
||||
|
||||
pub use self::config::Config;
|
||||
use self::{
|
||||
list::ListFormat,
|
||||
@ -132,8 +134,15 @@ impl<'a> Emitter<'a> {
|
||||
keyword!("export");
|
||||
space!();
|
||||
keyword!("default");
|
||||
space!();
|
||||
emit!(node.expr);
|
||||
{
|
||||
let starts_with_alpha_num = node.expr.starts_with_alpha_num();
|
||||
if starts_with_alpha_num {
|
||||
space!();
|
||||
} else {
|
||||
formatting_space!();
|
||||
}
|
||||
emit!(node.expr);
|
||||
}
|
||||
formatting_semi!();
|
||||
}
|
||||
|
||||
@ -158,7 +167,16 @@ impl<'a> Emitter<'a> {
|
||||
self.emit_leading_comments_of_span(node.span(), false)?;
|
||||
|
||||
keyword!("import");
|
||||
space!();
|
||||
let starts_with_ident = !node.specifiers.is_empty()
|
||||
&& match &node.specifiers[0] {
|
||||
ImportSpecifier::Default(_) => true,
|
||||
_ => false,
|
||||
};
|
||||
if starts_with_ident {
|
||||
space!();
|
||||
} else {
|
||||
formatting_space!();
|
||||
}
|
||||
|
||||
let mut specifiers = vec![];
|
||||
let mut emitted_default = false;
|
||||
@ -182,7 +200,7 @@ impl<'a> Emitter<'a> {
|
||||
|
||||
assert!(node.specifiers.len() <= 2);
|
||||
punct!("*");
|
||||
space!();
|
||||
formatting_space!();
|
||||
keyword!("as");
|
||||
space!();
|
||||
emit!(ns.local);
|
||||
@ -344,11 +362,11 @@ impl<'a> Emitter<'a> {
|
||||
self.emit_leading_comments_of_span(node.span(), false)?;
|
||||
|
||||
keyword!("export");
|
||||
space!();
|
||||
formatting_space!();
|
||||
punct!("*");
|
||||
formatting_space!();
|
||||
keyword!("from");
|
||||
space!();
|
||||
formatting_space!();
|
||||
emit!(node.src);
|
||||
formatting_semi!();
|
||||
}
|
||||
@ -440,7 +458,18 @@ impl<'a> Emitter<'a> {
|
||||
if num.value.is_sign_negative() && num.value == 0.0 {
|
||||
self.wr.write_str_lit(num.span, "-0")?;
|
||||
} else {
|
||||
self.wr.write_str_lit(num.span, &format!("{}", num.value))?;
|
||||
let mut s = num.value.to_string();
|
||||
if self.cfg.minify {
|
||||
if !s.contains('.') && !s.contains('e') && s.ends_with("000") {
|
||||
let cnt = s.as_bytes().iter().rev().filter(|&&v| v == b'0').count();
|
||||
|
||||
s.truncate(s.len() - cnt);
|
||||
s.push('e');
|
||||
s.push_str(&cnt.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
self.wr.write_str_lit(num.span, &s)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -589,7 +618,14 @@ impl<'a> Emitter<'a> {
|
||||
let span = self.cm.span_until_char(node.span, ' ');
|
||||
keyword!(span, "new");
|
||||
}
|
||||
space!();
|
||||
|
||||
let starts_with_alpha_num = node.callee.starts_with_alpha_num();
|
||||
|
||||
if starts_with_alpha_num {
|
||||
space!();
|
||||
} else {
|
||||
formatting_space!();
|
||||
}
|
||||
emit!(node.callee);
|
||||
|
||||
if let Some(type_args) = &node.type_args {
|
||||
@ -745,16 +781,27 @@ impl<'a> Emitter<'a> {
|
||||
fn emit_bin_expr_trailing(&mut self, node: &BinExpr) -> Result {
|
||||
// let indent_before_op = needs_indention(node, &node.left, node.op);
|
||||
// let indent_after_op = needs_indention(node, node.op, &node.right);
|
||||
let need_space = match node.op {
|
||||
let is_kwd_op = match node.op {
|
||||
op!("in") | op!("instanceof") => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
let need_pre_space = need_space
|
||||
|| match *node.left {
|
||||
Expr::Update(UpdateExpr { prefix: false, .. }) => true,
|
||||
_ => false,
|
||||
};
|
||||
let need_pre_space = if self.cfg.minify {
|
||||
if is_kwd_op {
|
||||
node.left.ends_with_alpha_num()
|
||||
} else {
|
||||
match *node.left {
|
||||
Expr::Update(UpdateExpr { prefix: false, .. }) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
is_kwd_op
|
||||
|| match *node.left {
|
||||
Expr::Update(UpdateExpr { prefix: false, .. }) => true,
|
||||
_ => false,
|
||||
}
|
||||
};
|
||||
if need_pre_space {
|
||||
space!(self);
|
||||
} else {
|
||||
@ -762,11 +809,42 @@ impl<'a> Emitter<'a> {
|
||||
}
|
||||
operator!(self, node.op.as_str());
|
||||
|
||||
let need_post_space = need_space
|
||||
|| match *node.right {
|
||||
Expr::Unary(..) | Expr::Update(UpdateExpr { prefix: true, .. }) => true,
|
||||
_ => false,
|
||||
};
|
||||
let need_post_space = if self.cfg.minify {
|
||||
if is_kwd_op {
|
||||
node.right.starts_with_alpha_num()
|
||||
} else {
|
||||
match (node.op, &*node.right) {
|
||||
(
|
||||
_,
|
||||
Expr::Unary(UnaryExpr {
|
||||
op: op!("typeof") | op!("void") | op!("delete"),
|
||||
..
|
||||
}),
|
||||
) => false,
|
||||
|
||||
(op!("||") | op!("&&"), Expr::Unary(UnaryExpr { op: op!("!"), .. })) => false,
|
||||
|
||||
(op!("*") | op!("/"), Expr::Unary(..)) => false,
|
||||
|
||||
(
|
||||
op!("||") | op!("&&"),
|
||||
Expr::Unary(UnaryExpr {
|
||||
op: op!(unary, "+") | op!(unary, "-") | op!("!"),
|
||||
..
|
||||
}),
|
||||
) => false,
|
||||
|
||||
(_, Expr::Update(UpdateExpr { prefix: true, .. }) | Expr::Unary(..)) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
is_kwd_op
|
||||
|| match *node.right {
|
||||
Expr::Unary(..) | Expr::Update(UpdateExpr { prefix: true, .. }) => true,
|
||||
_ => false,
|
||||
}
|
||||
};
|
||||
if need_post_space {
|
||||
space!(self);
|
||||
} else {
|
||||
@ -844,7 +922,17 @@ impl<'a> Emitter<'a> {
|
||||
if node.super_class.is_some() {
|
||||
space!();
|
||||
keyword!("extends");
|
||||
space!();
|
||||
|
||||
{
|
||||
let starts_with_alpha_num =
|
||||
node.super_class.as_ref().unwrap().starts_with_alpha_num();
|
||||
|
||||
if starts_with_alpha_num {
|
||||
space!();
|
||||
} else {
|
||||
formatting_space!()
|
||||
}
|
||||
}
|
||||
emit!(node.super_class);
|
||||
}
|
||||
|
||||
@ -923,7 +1011,26 @@ impl<'a> Emitter<'a> {
|
||||
|
||||
if n.is_static {
|
||||
keyword!("static");
|
||||
space!();
|
||||
|
||||
let starts_with_alpha_num = match n.kind {
|
||||
MethodKind::Method => {
|
||||
if n.function.is_async {
|
||||
true
|
||||
} else if n.function.is_generator {
|
||||
false
|
||||
} else {
|
||||
n.key.starts_with_alpha_num()
|
||||
}
|
||||
}
|
||||
MethodKind::Getter => true,
|
||||
MethodKind::Setter => true,
|
||||
};
|
||||
|
||||
if starts_with_alpha_num {
|
||||
space!();
|
||||
} else {
|
||||
formatting_space!();
|
||||
}
|
||||
}
|
||||
match n.kind {
|
||||
MethodKind::Method => {
|
||||
@ -939,13 +1046,23 @@ impl<'a> Emitter<'a> {
|
||||
}
|
||||
MethodKind::Getter => {
|
||||
keyword!("get");
|
||||
space!();
|
||||
|
||||
if n.key.starts_with_alpha_num() {
|
||||
space!();
|
||||
} else {
|
||||
formatting_space!()
|
||||
}
|
||||
|
||||
emit!(n.key);
|
||||
}
|
||||
MethodKind::Setter => {
|
||||
keyword!("set");
|
||||
space!();
|
||||
|
||||
if n.key.starts_with_alpha_num() {
|
||||
space!();
|
||||
} else {
|
||||
formatting_space!()
|
||||
}
|
||||
|
||||
emit!(n.key);
|
||||
}
|
||||
@ -1286,7 +1403,7 @@ impl<'a> Emitter<'a> {
|
||||
}
|
||||
|
||||
if let Some(ref arg) = node.arg {
|
||||
if arg.starts_with_alpha_num() {
|
||||
if !node.delegate && arg.starts_with_alpha_num() {
|
||||
space!()
|
||||
} else {
|
||||
formatting_space!()
|
||||
@ -1350,7 +1467,7 @@ impl<'a> Emitter<'a> {
|
||||
self.emit_list(
|
||||
node.span(),
|
||||
Some(&node.props),
|
||||
ListFormat::ObjectLiteralExpressionProperties,
|
||||
ListFormat::ObjectLiteralExpressionProperties | ListFormat::CanSkipTrailingComma,
|
||||
)?;
|
||||
if !self.cfg.minify {
|
||||
self.wr.write_line()?;
|
||||
@ -1394,9 +1511,18 @@ impl<'a> Emitter<'a> {
|
||||
self.emit_leading_comments_of_span(node.span(), false)?;
|
||||
|
||||
keyword!("get");
|
||||
space!();
|
||||
|
||||
let starts_with_alpha_num = match node.key {
|
||||
PropName::Str(_) | PropName::Computed(_) => false,
|
||||
_ => true,
|
||||
};
|
||||
if starts_with_alpha_num {
|
||||
space!();
|
||||
} else {
|
||||
formatting_space!();
|
||||
}
|
||||
emit!(node.key);
|
||||
space!();
|
||||
formatting_space!();
|
||||
punct!("(");
|
||||
punct!(")");
|
||||
formatting_space!();
|
||||
@ -1408,9 +1534,20 @@ impl<'a> Emitter<'a> {
|
||||
self.emit_leading_comments_of_span(node.span(), false)?;
|
||||
|
||||
keyword!("set");
|
||||
space!();
|
||||
|
||||
let starts_with_alpha_num = match node.key {
|
||||
PropName::Str(_) | PropName::Computed(_) => false,
|
||||
_ => true,
|
||||
};
|
||||
|
||||
if starts_with_alpha_num {
|
||||
space!();
|
||||
} else {
|
||||
formatting_space!();
|
||||
}
|
||||
|
||||
emit!(node.key);
|
||||
space!();
|
||||
formatting_space!();
|
||||
|
||||
punct!("(");
|
||||
emit!(node.param);
|
||||
@ -1663,8 +1800,10 @@ impl<'a> Emitter<'a> {
|
||||
};
|
||||
|
||||
if has_trailing_comma && format.contains(ListFormat::CommaDelimited) {
|
||||
punct!(self, ",");
|
||||
formatting_space!(self);
|
||||
if !self.cfg.minify || !format.contains(ListFormat::CanSkipTrailingComma) {
|
||||
punct!(self, ",");
|
||||
formatting_space!(self);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
@ -1843,7 +1982,11 @@ impl<'a> Emitter<'a> {
|
||||
};
|
||||
|
||||
punct!("{");
|
||||
self.emit_list(node.span(), Some(&node.props), format)?;
|
||||
self.emit_list(
|
||||
node.span(),
|
||||
Some(&node.props),
|
||||
format | ListFormat::CanSkipTrailingComma,
|
||||
)?;
|
||||
punct!("}");
|
||||
if node.optional {
|
||||
punct!("?");
|
||||
@ -1873,7 +2016,7 @@ impl<'a> Emitter<'a> {
|
||||
punct!(":");
|
||||
formatting_space!();
|
||||
emit!(node.value);
|
||||
space!();
|
||||
formatting_space!();
|
||||
}
|
||||
|
||||
#[emitter]
|
||||
@ -1885,7 +2028,7 @@ impl<'a> Emitter<'a> {
|
||||
if let Some(ref value) = node.value {
|
||||
punct!("=");
|
||||
emit!(node.value);
|
||||
space!();
|
||||
formatting_space!();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2014,7 +2157,11 @@ impl<'a> Emitter<'a> {
|
||||
if need_paren {
|
||||
punct!("(");
|
||||
} else {
|
||||
space!();
|
||||
if arg.starts_with_alpha_num() {
|
||||
space!();
|
||||
} else {
|
||||
formatting_space!();
|
||||
}
|
||||
}
|
||||
|
||||
emit!(arg);
|
||||
@ -2120,7 +2267,7 @@ impl<'a> Emitter<'a> {
|
||||
punct!(")");
|
||||
}
|
||||
|
||||
space!();
|
||||
formatting_space!();
|
||||
|
||||
emit!(node.body);
|
||||
}
|
||||
@ -2131,7 +2278,15 @@ impl<'a> Emitter<'a> {
|
||||
|
||||
if let Some(ref test) = node.test {
|
||||
keyword!("case");
|
||||
space!();
|
||||
|
||||
let starts_with_alpha_num = test.starts_with_alpha_num();
|
||||
|
||||
if starts_with_alpha_num {
|
||||
space!();
|
||||
} else {
|
||||
formatting_space!();
|
||||
}
|
||||
|
||||
emit!(test);
|
||||
} else {
|
||||
keyword!("default");
|
||||
@ -2164,8 +2319,15 @@ impl<'a> Emitter<'a> {
|
||||
let throw_span = self.cm.span_until_char(node.span, ' ');
|
||||
|
||||
keyword!(throw_span, "throw");
|
||||
space!();
|
||||
emit!(node.arg);
|
||||
|
||||
{
|
||||
if node.arg.starts_with_alpha_num() {
|
||||
space!();
|
||||
} else {
|
||||
formatting_space!();
|
||||
}
|
||||
emit!(node.arg);
|
||||
}
|
||||
formatting_semi!();
|
||||
}
|
||||
|
||||
@ -2247,10 +2409,25 @@ impl<'a> Emitter<'a> {
|
||||
keyword!("for");
|
||||
punct!("(");
|
||||
emit!(node.left);
|
||||
space!();
|
||||
|
||||
if node.left.ends_with_alpha_num() {
|
||||
space!();
|
||||
} else {
|
||||
formatting_space!();
|
||||
}
|
||||
keyword!("in");
|
||||
space!();
|
||||
emit!(node.right);
|
||||
|
||||
{
|
||||
let starts_with_alpha_num = node.right.starts_with_alpha_num();
|
||||
|
||||
if starts_with_alpha_num {
|
||||
space!();
|
||||
} else {
|
||||
formatting_space!()
|
||||
}
|
||||
emit!(node.right);
|
||||
}
|
||||
|
||||
punct!(")");
|
||||
|
||||
emit!(node.body);
|
||||
@ -2268,10 +2445,23 @@ impl<'a> Emitter<'a> {
|
||||
formatting_space!();
|
||||
punct!("(");
|
||||
emit!(node.left);
|
||||
space!();
|
||||
if node.left.ends_with_alpha_num() {
|
||||
space!();
|
||||
} else {
|
||||
formatting_space!();
|
||||
}
|
||||
keyword!("of");
|
||||
space!();
|
||||
emit!(node.right);
|
||||
|
||||
{
|
||||
let starts_with_alpha_num = node.right.starts_with_alpha_num();
|
||||
|
||||
if starts_with_alpha_num {
|
||||
space!();
|
||||
} else {
|
||||
formatting_space!()
|
||||
}
|
||||
emit!(node.right);
|
||||
}
|
||||
punct!(")");
|
||||
emit!(node.body);
|
||||
}
|
||||
|
@ -79,6 +79,10 @@ add_bitflags!(
|
||||
NoSpaceIfEmpty: 1 << 18,
|
||||
SingleElement: 1 << 19,
|
||||
},
|
||||
// Optimization.
|
||||
Values {
|
||||
CanSkipTrailingComma: 1 << 20
|
||||
},
|
||||
/// Precomputed Formats
|
||||
Values {
|
||||
Modifiers: SingleLine | SpaceBetweenSiblings | NoInterveningComments,
|
||||
|
@ -594,7 +594,7 @@ fn issue_1619_1() {
|
||||
assert_min_target(
|
||||
"\"\\x00\" + \"\\x31\"",
|
||||
"\"\\x00\"+\"\\x31\"",
|
||||
EsVersion::Es3,
|
||||
EsVersion::latest(),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -20,9 +20,7 @@ pub trait WriteJs {
|
||||
///
|
||||
/// Implementor **should return same value** regardless how much time it is
|
||||
/// called.
|
||||
fn target(&self) -> JscTarget {
|
||||
JscTarget::Es2020
|
||||
}
|
||||
fn target(&self) -> JscTarget;
|
||||
|
||||
fn increase_indent(&mut self) -> Result;
|
||||
fn decrease_indent(&mut self) -> Result;
|
||||
|
@ -55,9 +55,26 @@ impl<W: WriteJs> WriteJs for OmitTrailingSemi<W> {
|
||||
with_semi!(write_symbol(span: Span, s: &str));
|
||||
|
||||
fn write_punct(&mut self, span: Option<Span>, s: &'static str) -> Result {
|
||||
self.pending_semi = false;
|
||||
match s {
|
||||
"\"" | "'" => {
|
||||
self.commit_pending_semi()?;
|
||||
}
|
||||
|
||||
"{" | "(" => {
|
||||
self.commit_pending_semi()?;
|
||||
}
|
||||
|
||||
_ => {
|
||||
self.pending_semi = false;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(self.inner.write_punct(span, s)?)
|
||||
}
|
||||
|
||||
fn target(&self) -> swc_ecma_ast::EsVersion {
|
||||
self.inner.target()
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: WriteJs> OmitTrailingSemi<W> {
|
||||
|
@ -151,11 +151,70 @@ impl SourceMapperExt for Rc<SourceMap> {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait EndsWithAlphaNum {
|
||||
fn ends_with_alpha_num(&self) -> bool;
|
||||
}
|
||||
|
||||
impl EndsWithAlphaNum for VarDeclOrPat {
|
||||
fn ends_with_alpha_num(&self) -> bool {
|
||||
match self {
|
||||
VarDeclOrPat::VarDecl(n) => n.ends_with_alpha_num(),
|
||||
VarDeclOrPat::Pat(n) => n.ends_with_alpha_num(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EndsWithAlphaNum for Pat {
|
||||
fn ends_with_alpha_num(&self) -> bool {
|
||||
match self {
|
||||
Pat::Object(_) | Pat::Array(_) => false,
|
||||
Pat::Rest(p) => p.arg.ends_with_alpha_num(),
|
||||
Pat::Assign(p) => p.right.ends_with_alpha_num(),
|
||||
Pat::Expr(p) => p.ends_with_alpha_num(),
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EndsWithAlphaNum for VarDecl {
|
||||
fn ends_with_alpha_num(&self) -> bool {
|
||||
match self.decls.last() {
|
||||
None => true,
|
||||
Some(d) => match d.init.as_deref() {
|
||||
Some(e) => e.ends_with_alpha_num(),
|
||||
None => d.name.ends_with_alpha_num(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EndsWithAlphaNum for Expr {
|
||||
fn ends_with_alpha_num(&self) -> bool {
|
||||
match self {
|
||||
Expr::Array(..)
|
||||
| Expr::Object(..)
|
||||
| Expr::Lit(Lit::Str(..))
|
||||
| Expr::Paren(..)
|
||||
| Expr::Member(MemberExpr { computed: true, .. }) => false,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Leftmost recursion
|
||||
pub trait StartsWithAlphaNum {
|
||||
fn starts_with_alpha_num(&self) -> bool;
|
||||
}
|
||||
|
||||
impl StartsWithAlphaNum for PropName {
|
||||
fn starts_with_alpha_num(&self) -> bool {
|
||||
match self {
|
||||
PropName::Str(_) | PropName::Computed(_) => false,
|
||||
PropName::Ident(_) | PropName::Num(_) | PropName::BigInt(_) => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StartsWithAlphaNum for Expr {
|
||||
fn starts_with_alpha_num(&self) -> bool {
|
||||
match *self {
|
||||
|
@ -1,18 +1,26 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use swc_common::input::SourceFileInput;
|
||||
use swc_ecma_ast::EsVersion;
|
||||
use swc_ecma_codegen::{text_writer::JsWriter, Emitter};
|
||||
use swc_ecma_codegen::{
|
||||
text_writer::{JsWriter, WriteJs},
|
||||
Emitter,
|
||||
};
|
||||
use swc_ecma_parser::{lexer::Lexer, Parser, Syntax};
|
||||
use testing::{run_test2, NormalizedOutput};
|
||||
|
||||
#[testing::fixture("tests/fixture/**/input.ts")]
|
||||
fn test_fixture(input: PathBuf) {
|
||||
fn run(input: &Path, minify: bool) {
|
||||
let dir = input.parent().unwrap();
|
||||
let output = dir.join(format!(
|
||||
"output.{}",
|
||||
input.extension().unwrap().to_string_lossy()
|
||||
));
|
||||
let output = if minify {
|
||||
dir.join(format!(
|
||||
"output.min.{}",
|
||||
input.extension().unwrap().to_string_lossy()
|
||||
))
|
||||
} else {
|
||||
dir.join(format!(
|
||||
"output.{}",
|
||||
input.extension().unwrap().to_string_lossy()
|
||||
))
|
||||
};
|
||||
|
||||
run_test2(false, |cm, _| {
|
||||
let fm = cm.load_file(&input).unwrap();
|
||||
@ -31,11 +39,18 @@ fn test_fixture(input: PathBuf) {
|
||||
let mut buf = vec![];
|
||||
|
||||
{
|
||||
let mut wr =
|
||||
Box::new(JsWriter::new(cm.clone(), "\n", &mut buf, None)) as Box<dyn WriteJs>;
|
||||
|
||||
if minify {
|
||||
wr = Box::new(swc_ecma_codegen::text_writer::omit_trailing_semi(wr));
|
||||
}
|
||||
|
||||
let mut emitter = Emitter {
|
||||
cfg: swc_ecma_codegen::Config { minify: false },
|
||||
cfg: swc_ecma_codegen::Config { minify },
|
||||
cm: cm.clone(),
|
||||
comments: None,
|
||||
wr: Box::new(JsWriter::new(cm.clone(), "\n", &mut buf, None)),
|
||||
wr,
|
||||
};
|
||||
|
||||
emitter.emit_module(&m).unwrap();
|
||||
@ -49,3 +64,14 @@ fn test_fixture(input: PathBuf) {
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[testing::fixture("tests/fixture/**/input.ts")]
|
||||
fn ts(input: PathBuf) {
|
||||
run(&input, false);
|
||||
}
|
||||
|
||||
#[testing::fixture("tests/fixture/**/input.js")]
|
||||
fn js(input: PathBuf) {
|
||||
run(&input, false);
|
||||
run(&input, true);
|
||||
}
|
||||
|
@ -0,0 +1,6 @@
|
||||
import other from 'other'
|
||||
const [foo] = other
|
||||
export var __N_SSG = true
|
||||
export default function Home() {
|
||||
return __jsx('div', null)
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
import other from 'other';
|
||||
const [foo] = other;
|
||||
export var __N_SSG = true;
|
||||
export default function Home() {
|
||||
return __jsx('div', null);
|
||||
};
|
@ -0,0 +1 @@
|
||||
import other from'other';const[foo]=other;export var __N_SSG=true;export default function Home(){return __jsx('div',null)}
|
@ -0,0 +1,6 @@
|
||||
import other from 'other'
|
||||
const { a, cat: bar } = other
|
||||
export var __N_SSG = true
|
||||
export default function Home() {
|
||||
return __jsx('div', null)
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
import other from 'other';
|
||||
const { a , cat: bar } = other;
|
||||
export var __N_SSG = true;
|
||||
export default function Home() {
|
||||
return __jsx('div', null);
|
||||
};
|
@ -0,0 +1 @@
|
||||
import other from'other';const{a,cat:bar}=other;export var __N_SSG=true;export default function Home(){return __jsx('div',null)}
|
@ -0,0 +1,5 @@
|
||||
export var __N_SSG = true
|
||||
export class MyClass {}
|
||||
export default function Test() {
|
||||
return __jsx('div', null)
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
export var __N_SSG = true;
|
||||
export class MyClass {
|
||||
}
|
||||
export default function Test() {
|
||||
return __jsx('div', null);
|
||||
};
|
@ -0,0 +1 @@
|
||||
export var __N_SSG=true;export class MyClass{}export default function Test(){return __jsx('div',null)}
|
@ -0,0 +1,11 @@
|
||||
function Function1() {
|
||||
return {
|
||||
a: function bug(a) {
|
||||
return 2
|
||||
},
|
||||
}
|
||||
}
|
||||
function Function2() {
|
||||
var bug = 1
|
||||
return { bug }
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
function Function1() {
|
||||
return {
|
||||
a: function bug(a) {
|
||||
return 2;
|
||||
}
|
||||
};
|
||||
}
|
||||
function Function2() {
|
||||
var bug = 1;
|
||||
return {
|
||||
bug
|
||||
};
|
||||
}
|
@ -0,0 +1 @@
|
||||
function Function1(){return{a:function bug(a){return 2}}}function Function2(){var bug=1;return{bug}}
|
@ -0,0 +1,5 @@
|
||||
export var __N_SSG = true
|
||||
export function Noop() {}
|
||||
export default function Test() {
|
||||
return __jsx('div', null)
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
export var __N_SSG = true;
|
||||
export function Noop() {
|
||||
}
|
||||
export default function Test() {
|
||||
return __jsx('div', null);
|
||||
};
|
@ -0,0 +1 @@
|
||||
export var __N_SSG=true;export function Noop(){}export default function Test(){return __jsx('div',null)}
|
@ -0,0 +1,5 @@
|
||||
export var __N_SSG = true
|
||||
export const foo = 2
|
||||
export default function Test() {
|
||||
return __jsx('div', null)
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
export var __N_SSG = true;
|
||||
export const foo = 2;
|
||||
export default function Test() {
|
||||
return __jsx('div', null);
|
||||
};
|
@ -0,0 +1 @@
|
||||
export var __N_SSG=true;export const foo=2;export default function Test(){return __jsx('div',null)}
|
@ -0,0 +1,4 @@
|
||||
export var __N_SSG = true
|
||||
export default function Test() {
|
||||
return __jsx('div', null)
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
export var __N_SSG = true;
|
||||
export default function Test() {
|
||||
return __jsx('div', null);
|
||||
};
|
@ -0,0 +1 @@
|
||||
export var __N_SSG=true;export default function Test(){return __jsx('div',null)}
|
@ -0,0 +1,5 @@
|
||||
export var __N_SSG = true
|
||||
export { foo, bar as baz } from '.'
|
||||
export default function Test() {
|
||||
return __jsx('div', null)
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
export var __N_SSG = true;
|
||||
export { foo, bar as baz } from '.';
|
||||
export default function Test() {
|
||||
return __jsx('div', null);
|
||||
};
|
@ -0,0 +1 @@
|
||||
export var __N_SSG=true;export{foo,bar as baz}from'.';export default function Test(){return __jsx('div',null)}
|
@ -0,0 +1,4 @@
|
||||
export var __N_SSG = true
|
||||
export default function Test() {
|
||||
return __jsx('div', null)
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
export var __N_SSG = true;
|
||||
export default function Test() {
|
||||
return __jsx('div', null);
|
||||
};
|
@ -0,0 +1 @@
|
||||
export var __N_SSG=true;export default function Test(){return __jsx('div',null)}
|
@ -0,0 +1,4 @@
|
||||
export var __N_SSG = true
|
||||
export default function Test() {
|
||||
return __jsx('div', null)
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
export var __N_SSG = true;
|
||||
export default function Test() {
|
||||
return __jsx('div', null);
|
||||
};
|
@ -0,0 +1 @@
|
||||
export var __N_SSG=true;export default function Test(){return __jsx('div',null)}
|
@ -0,0 +1,4 @@
|
||||
export var __N_SSG = true
|
||||
export default function Test() {
|
||||
return __jsx('div', null)
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
export var __N_SSG = true;
|
||||
export default function Test() {
|
||||
return __jsx('div', null);
|
||||
};
|
@ -0,0 +1 @@
|
||||
export var __N_SSG=true;export default function Test(){return __jsx('div',null)}
|
@ -0,0 +1,4 @@
|
||||
export var __N_SSG = true
|
||||
export default function Test() {
|
||||
return __jsx('div', null)
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
export var __N_SSG = true;
|
||||
export default function Test() {
|
||||
return __jsx('div', null);
|
||||
};
|
@ -0,0 +1 @@
|
||||
export var __N_SSG=true;export default function Test(){return __jsx('div',null)}
|
@ -0,0 +1,10 @@
|
||||
import keep_me from 'hello'
|
||||
import { keep_me2 } from 'hello2'
|
||||
import * as keep_me3 from 'hello3'
|
||||
import { but_not_me } from 'bar'
|
||||
var leave_me_alone = 1
|
||||
function dont_bug_me_either() {}
|
||||
export var __N_SSG = true
|
||||
export default function Test() {
|
||||
return __jsx('div', null)
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
import keep_me from 'hello';
|
||||
import { keep_me2 } from 'hello2';
|
||||
import * as keep_me3 from 'hello3';
|
||||
import { but_not_me } from 'bar';
|
||||
var leave_me_alone = 1;
|
||||
function dont_bug_me_either() {
|
||||
}
|
||||
export var __N_SSG = true;
|
||||
export default function Test() {
|
||||
return __jsx('div', null);
|
||||
};
|
@ -0,0 +1 @@
|
||||
import keep_me from'hello';import{keep_me2}from'hello2';import*as keep_me3 from'hello3';import{but_not_me}from'bar';var leave_me_alone=1;function dont_bug_me_either(){}export var __N_SSG=true;export default function Test(){return __jsx('div',null)}
|
@ -0,0 +1,4 @@
|
||||
export var __N_SSG = true
|
||||
export default function Test() {
|
||||
return __jsx('div', null)
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
export var __N_SSG = true;
|
||||
export default function Test() {
|
||||
return __jsx('div', null);
|
||||
};
|
@ -0,0 +1 @@
|
||||
export var __N_SSG=true;export default function Test(){return __jsx('div',null)}
|
@ -0,0 +1,5 @@
|
||||
const a = 2
|
||||
export var __N_SSG = true
|
||||
export default function Test() {
|
||||
return __jsx('div', null)
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
const a = 2;
|
||||
export var __N_SSG = true;
|
||||
export default function Test() {
|
||||
return __jsx('div', null);
|
||||
};
|
@ -0,0 +1 @@
|
||||
const a=2;export var __N_SSG=true;export default function Test(){return __jsx('div',null)}
|
@ -0,0 +1,4 @@
|
||||
export var __N_SSG = true
|
||||
export default function Test() {
|
||||
return __jsx('div', null)
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
export var __N_SSG = true;
|
||||
export default function Test() {
|
||||
return __jsx('div', null);
|
||||
};
|
@ -0,0 +1 @@
|
||||
export var __N_SSG=true;export default function Test(){return __jsx('div',null)}
|
@ -0,0 +1,4 @@
|
||||
export var __N_SSG = true
|
||||
export default function Test() {
|
||||
return __jsx('div', null)
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
export var __N_SSG = true;
|
||||
export default function Test() {
|
||||
return __jsx('div', null);
|
||||
};
|
@ -0,0 +1 @@
|
||||
export var __N_SSG=true;export default function Test(){return __jsx('div',null)}
|
@ -0,0 +1,4 @@
|
||||
export var __N_SSG = true
|
||||
export default function Home() {
|
||||
return __jsx('div', null)
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
export var __N_SSG = true;
|
||||
export default function Home() {
|
||||
return __jsx('div', null);
|
||||
};
|
@ -0,0 +1 @@
|
||||
export var __N_SSG=true;export default function Home(){return __jsx('div',null)}
|
@ -0,0 +1,7 @@
|
||||
class Test extends React.Component {
|
||||
render() {
|
||||
return __jsx('div', null)
|
||||
}
|
||||
}
|
||||
export var __N_SSG = true
|
||||
export default Test
|
@ -0,0 +1,7 @@
|
||||
class Test extends React.Component {
|
||||
render() {
|
||||
return __jsx('div', null);
|
||||
}
|
||||
}
|
||||
export var __N_SSG = true;
|
||||
export default Test;
|
@ -0,0 +1 @@
|
||||
class Test extends React.Component{render(){return __jsx('div',null)}}export var __N_SSG=true;export default Test
|
@ -0,0 +1,6 @@
|
||||
export var __N_SSG = true
|
||||
export default class Test extends React.Component {
|
||||
render() {
|
||||
return __jsx('div', null)
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
export var __N_SSG = true;
|
||||
export default class Test extends React.Component {
|
||||
render() {
|
||||
return __jsx('div', null);
|
||||
}
|
||||
};
|
@ -0,0 +1 @@
|
||||
export var __N_SSG=true;export default class Test extends React.Component{render(){return __jsx('div',null)}}
|
@ -0,0 +1,8 @@
|
||||
class El extends React.Component {
|
||||
render() {
|
||||
return __jsx('div', null)
|
||||
}
|
||||
}
|
||||
const a = 5
|
||||
export var __N_SSG = true
|
||||
export { El as default, a }
|
@ -0,0 +1,8 @@
|
||||
class El extends React.Component {
|
||||
render() {
|
||||
return __jsx('div', null);
|
||||
}
|
||||
}
|
||||
const a = 5;
|
||||
export var __N_SSG = true;
|
||||
export { El as default, a };
|
@ -0,0 +1 @@
|
||||
class El extends React.Component{render(){return __jsx('div',null)}}const a=5;export var __N_SSG=true;export{El as default,a}
|
@ -0,0 +1,6 @@
|
||||
function El() {
|
||||
return __jsx('div', null)
|
||||
}
|
||||
const a = 5
|
||||
export var __N_SSG = true
|
||||
export { El as default, a }
|
@ -0,0 +1,6 @@
|
||||
function El() {
|
||||
return __jsx('div', null);
|
||||
}
|
||||
const a = 5;
|
||||
export var __N_SSG = true;
|
||||
export { El as default, a };
|
@ -0,0 +1 @@
|
||||
function El(){return __jsx('div',null)}const a=5;export var __N_SSG=true;export{El as default,a}
|
@ -0,0 +1,2 @@
|
||||
export var __N_SSG = true
|
||||
export { default } from 'a'
|
@ -0,0 +1,2 @@
|
||||
export var __N_SSG = true;
|
||||
export { default } from 'a';
|
@ -0,0 +1 @@
|
||||
export var __N_SSG=true;export{default}from'a'
|
@ -0,0 +1,5 @@
|
||||
function El() {
|
||||
return __jsx('div', null)
|
||||
}
|
||||
export var __N_SSG = true
|
||||
export { El as default }
|
@ -0,0 +1,5 @@
|
||||
function El() {
|
||||
return __jsx('div', null);
|
||||
}
|
||||
export var __N_SSG = true;
|
||||
export { El as default };
|
@ -0,0 +1 @@
|
||||
function El(){return __jsx('div',null)}export var __N_SSG=true;export{El as default}
|
@ -0,0 +1,4 @@
|
||||
foo
|
||||
if (foo) {
|
||||
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
foo;
|
||||
if (foo) {
|
||||
}
|
1
ecmascript/codegen/tests/fixture/semi/pending/001/output.min.js
vendored
Normal file
1
ecmascript/codegen/tests/fixture/semi/pending/001/output.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
foo;if(foo){}
|
@ -0,0 +1,2 @@
|
||||
foo
|
||||
"s"
|
@ -0,0 +1,2 @@
|
||||
foo;
|
||||
"s";
|
1
ecmascript/codegen/tests/fixture/semi/pending/002/output.min.js
vendored
Normal file
1
ecmascript/codegen/tests/fixture/semi/pending/002/output.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
foo;"s"
|
@ -0,0 +1,2 @@
|
||||
foo
|
||||
bar
|
@ -0,0 +1,2 @@
|
||||
foo;
|
||||
bar;
|
1
ecmascript/codegen/tests/fixture/semi/pending/003/output.min.js
vendored
Normal file
1
ecmascript/codegen/tests/fixture/semi/pending/003/output.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
foo;bar
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user