diff --git a/crates/swc_ecma_ast/src/expr.rs b/crates/swc_ecma_ast/src/expr.rs index 4c06e145c22..0d35fa2d8e8 100644 --- a/crates/swc_ecma_ast/src/expr.rs +++ b/crates/swc_ecma_ast/src/expr.rs @@ -642,6 +642,12 @@ impl Take for TaggedTpl { pub struct TplElement { pub span: Span, pub tail: bool, + + /// This value is never used by `swc_ecma_codegen`, and this fact is + /// considered as a public API. + /// + /// If you are going to use codegen right after creating a [TplElement], you + /// don't have to worry about this value. pub cooked: Option, pub raw: Str, } diff --git a/crates/swc_ecma_ast/src/lit.rs b/crates/swc_ecma_ast/src/lit.rs index 8d8bbe79311..9c0a3593141 100644 --- a/crates/swc_ecma_ast/src/lit.rs +++ b/crates/swc_ecma_ast/src/lit.rs @@ -53,6 +53,16 @@ impl<'a> arbitrary::Arbitrary<'a> for BigInt { } } +/// A string literal. +/// +/// # Note +/// +/// You have to use [StrKind::Synthesized] if you modify the `value` of [Str]. +/// This behavior is for preserving the original source code. +/// +/// In other words, `swc_ecma_codegen` tries to preserve escapes or unicode +/// characters in the original source code and you can opt-out of this by using +/// [StrKind::Synthesized]. #[ast_node("StringLiteral")] #[derive(Eq, Hash, EqIgnoreSpan)] pub struct Str { diff --git a/crates/swc_ecma_transforms_module/src/rewriter.rs b/crates/swc_ecma_transforms_module/src/rewriter.rs index efa19bd38bb..01a1cd70312 100644 --- a/crates/swc_ecma_transforms_module/src/rewriter.rs +++ b/crates/swc_ecma_transforms_module/src/rewriter.rs @@ -47,6 +47,8 @@ where }) .unwrap(); + // This string literal is synthesized + s.kind = Default::default(); s.value = src; } _ => {} diff --git a/crates/swc_ecma_transforms_typescript/examples/ts_to_js.rs b/crates/swc_ecma_transforms_typescript/examples/ts_to_js.rs index 40a9a5f4be1..129f3f3de1f 100644 --- a/crates/swc_ecma_transforms_typescript/examples/ts_to_js.rs +++ b/crates/swc_ecma_transforms_typescript/examples/ts_to_js.rs @@ -8,7 +8,7 @@ use swc_common::{ comments::SingleThreadedComments, errors::{ColorConfig, Handler}, sync::Lrc, - Mark, SourceMap, + Globals, Mark, SourceMap, GLOBALS, }; use swc_ecma_codegen::{text_writer::JsWriter, Emitter}; use swc_ecma_parser::{lexer::Lexer, Parser, StringInput, Syntax, TsConfig}; @@ -56,34 +56,37 @@ fn main() { .map_err(|e| e.into_diagnostic(&handler).emit()) .expect("failed to parse module."); - let top_level_mark = Mark::fresh(Mark::root()); + let globals = Globals::default(); + GLOBALS.set(&globals, || { + let top_level_mark = Mark::fresh(Mark::root()); - // Optionally transforms decorators here before the resolver pass - // as it might produce runtime declarations. + // Optionally transforms decorators here before the resolver pass + // as it might produce runtime declarations. - // Conduct identifier scope analysis - let module = module.fold_with(&mut resolver_with_mark(top_level_mark)); + // Conduct identifier scope analysis + let module = module.fold_with(&mut resolver_with_mark(top_level_mark)); - // Remove typescript types - let module = module.fold_with(&mut strip(top_level_mark)); + // Remove typescript types + let module = module.fold_with(&mut strip(top_level_mark)); - // Fix up any identifiers with the same name, but different contexts - let module = module.fold_with(&mut hygiene()); + // Fix up any identifiers with the same name, but different contexts + let module = module.fold_with(&mut hygiene()); - // Ensure that we have enough parenthesis. - let module = module.fold_with(&mut fixer(Some(&comments))); + // Ensure that we have enough parenthesis. + let module = module.fold_with(&mut fixer(Some(&comments))); - let mut buf = vec![]; - { - let mut emitter = Emitter { - cfg: swc_ecma_codegen::Config { minify: false }, - cm: cm.clone(), - comments: Some(&comments), - wr: JsWriter::new(cm.clone(), "\n", &mut buf, None), - }; + let mut buf = vec![]; + { + let mut emitter = Emitter { + cfg: swc_ecma_codegen::Config { minify: false }, + cm: cm.clone(), + comments: Some(&comments), + wr: JsWriter::new(cm.clone(), "\n", &mut buf, None), + }; - emitter.emit_module(&module).unwrap(); - } + emitter.emit_module(&module).unwrap(); + } - println!("{}", String::from_utf8(buf).expect("non-utf8?")); + println!("{}", String::from_utf8(buf).expect("non-utf8?")); + }) }