Skip to content

Commit

Permalink
feat(es/codegen): Add to_code (#8968)
Browse files Browse the repository at this point in the history
**Description:**

This is a utility function for printing an AST node as a string
  • Loading branch information
kdy1 committed May 23, 2024
1 parent ea14fc8 commit e80fd41
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 73 deletions.
32 changes: 31 additions & 1 deletion crates/swc_ecma_codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use swc_atoms::Atom;
use swc_common::{
comments::{CommentKind, Comments},
sync::Lrc,
BytePos, SourceMapper, Span, Spanned, DUMMY_SP,
BytePos, SourceMap, SourceMapper, Span, Spanned, DUMMY_SP,
};
use swc_ecma_ast::*;
use swc_ecma_codegen_macros::emitter;
Expand All @@ -38,6 +38,36 @@ pub mod util;

pub type Result = io::Result<()>;

/// Generate a code from a syntax node using default options.
pub fn to_code_default(
cm: Lrc<SourceMap>,
comments: Option<&dyn Comments>,
node: impl Node,
) -> String {
let mut buf = vec![];
{
let mut emitter = Emitter {
cfg: Default::default(),
cm: cm.clone(),
comments,
wr: text_writer::JsWriter::new(cm, "\n", &mut buf, None),
};
node.emit_with(&mut emitter).unwrap();
}

String::from_utf8(buf).expect("codegen generated non-utf8 output")
}

/// Generate a code from a syntax node using default options.
pub fn to_code_with_comments(comments: Option<&dyn Comments>, node: impl Node) -> String {
to_code_default(Default::default(), comments, node)
}

/// Generate a code from a syntax node using default options.
pub fn to_code(node: impl Node) -> String {
to_code_with_comments(None, node)
}

pub trait Node: Spanned {
fn emit_with<W, S>(&self, e: &mut Emitter<'_, W, S>) -> Result
where
Expand Down
23 changes: 2 additions & 21 deletions crates/swc_ecma_transforms_testing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use swc_common::{
FileName, Mark, SourceMap, DUMMY_SP,
};
use swc_ecma_ast::*;
use swc_ecma_codegen::Emitter;
use swc_ecma_codegen::{to_code_default, Emitter};
use swc_ecma_parser::{lexer::Lexer, Parser, StringInput, Syntax};
use swc_ecma_testing::{exec_node_js, JsExecOptions};
use swc_ecma_transforms_base::{
Expand Down Expand Up @@ -188,26 +188,7 @@ impl<'a> Tester<'a> {
}

pub fn print(&mut self, module: &Module, comments: &Rc<SingleThreadedComments>) -> String {
let mut buf = vec![];
{
let mut emitter = Emitter {
cfg: Default::default(),
cm: self.cm.clone(),
wr: Box::new(swc_ecma_codegen::text_writer::JsWriter::new(
self.cm.clone(),
"\n",
&mut buf,
None,
)),
comments: Some(comments),
};

// println!("Emitting: {:?}", module);
emitter.emit_module(module).unwrap();
}

let s = String::from_utf8_lossy(&buf);
s.to_string()
to_code_default(self.cm.clone(), Some(comments), module)
}
}

Expand Down
16 changes: 2 additions & 14 deletions crates/swc_ecma_transforms_typescript/examples/ts_to_js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use swc_common::{
sync::Lrc,
Globals, Mark, SourceMap, GLOBALS,
};
use swc_ecma_codegen::{text_writer::JsWriter, Emitter};
use swc_ecma_codegen::to_code_default;
use swc_ecma_parser::{lexer::Lexer, Parser, StringInput, Syntax, TsConfig};
use swc_ecma_transforms_base::{fixer::fixer, hygiene::hygiene, resolver};
use swc_ecma_transforms_typescript::strip;
Expand Down Expand Up @@ -76,18 +76,6 @@ fn main() {
// Ensure that we have enough parenthesis.
let program = module.fold_with(&mut fixer(Some(&comments)));

let mut buf = vec![];
{
let mut emitter = Emitter {
cfg: swc_ecma_codegen::Config::default(),
cm: cm.clone(),
comments: Some(&comments),
wr: JsWriter::new(cm.clone(), "\n", &mut buf, None),
};

emitter.emit_program(&program).unwrap();
}

println!("{}", String::from_utf8(buf).expect("non-utf8?"));
println!("{}", to_code_default(cm, Some(&comments), program));
})
}
42 changes: 5 additions & 37 deletions crates/swc_ecma_transforms_typescript/tests/strip_correctness.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
use std::{
io::{self, Write},
path::PathBuf,
sync::{Arc, RwLock},
};
use std::path::PathBuf;

use swc_common::{FileName, Mark};
use swc_ecma_ast::*;
use swc_ecma_codegen::Emitter;
use swc_ecma_codegen::to_code_default;
use swc_ecma_parser::{lexer::Lexer, EsConfig, Parser, Syntax, TsConfig};
use swc_ecma_transforms_base::{fixer::fixer, hygiene::hygiene, resolver};
use swc_ecma_transforms_typescript::typescript;
Expand Down Expand Up @@ -98,21 +94,7 @@ fn identity(entry: PathBuf) {
None,
);

let mut wr = Buf(Arc::new(RwLock::new(vec![])));

{
let mut emitter = Emitter {
cfg: swc_ecma_codegen::Config::default(),
cm: cm.clone(),
wr: Box::new(swc_ecma_codegen::text_writer::JsWriter::new(
cm.clone(),
"\n",
&mut wr,
None,
)),
comments: None,
};

let js_content = {
// Parse source
let program = parser
.parse_typescript_module()
Expand Down Expand Up @@ -142,10 +124,8 @@ fn identity(entry: PathBuf) {
Err(_) => return Ok(()),
};

emitter.emit_program(&program).unwrap();
}

let js_content = String::from_utf8_lossy(&wr.0.read().unwrap()).to_string();
to_code_default(cm.clone(), None, program)
};

println!("---------------- JS ----------------\n\n{}", js_content);

Expand Down Expand Up @@ -182,15 +162,3 @@ fn identity(entry: PathBuf) {
})
.expect("failed to run test");
}

#[derive(Debug, Clone)]
struct Buf(Arc<RwLock<Vec<u8>>>);
impl Write for Buf {
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
self.0.write().unwrap().write(data)
}

fn flush(&mut self) -> io::Result<()> {
self.0.write().unwrap().flush()
}
}

0 comments on commit e80fd41

Please sign in to comment.