mirror of
https://github.com/swc-project/swc.git
synced 2024-11-23 09:38:16 +03:00
feat(es/codegen): Add to_code
(#8968)
**Description:** This is a utility function for printing an AST node as a string
This commit is contained in:
parent
ea14fc8e59
commit
e80fd41ea8
@ -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;
|
||||
@ -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
|
||||
|
@ -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::{
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
@ -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));
|
||||
})
|
||||
}
|
||||
|
@ -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;
|
||||
@ -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()
|
||||
@ -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);
|
||||
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user