swc_ecma_minifier/
debug.rs

1use swc_common::{sync::Lrc, SourceMap, SyntaxContext};
2use swc_ecma_ast::*;
3use swc_ecma_codegen::{text_writer::JsWriter, Emitter};
4pub use swc_ecma_transforms_optimization::AssertValid;
5use swc_ecma_utils::{drop_span, DropSpan};
6use swc_ecma_visit::{noop_visit_mut_type, VisitMut, VisitMutWith};
7
8pub(crate) struct Debugger {}
9
10impl VisitMut for Debugger {
11    noop_visit_mut_type!(fail);
12
13    fn visit_mut_ident(&mut self, n: &mut Ident) {
14        if !cfg!(feature = "debug") {
15            return;
16        }
17
18        if n.ctxt == SyntaxContext::empty() {
19            return;
20        }
21
22        n.sym = format!("{}{:?}", n.sym, n.ctxt).into();
23        n.ctxt = SyntaxContext::empty();
24    }
25}
26
27pub(crate) fn dump<N>(node: &N, force: bool) -> String
28where
29    N: swc_ecma_codegen::Node + Clone + VisitMutWith<DropSpan> + VisitMutWith<Debugger>,
30{
31    if !force {
32        #[cfg(not(feature = "debug"))]
33        {
34            return String::new();
35        }
36    }
37
38    let mut node = node.clone();
39    node.visit_mut_with(&mut Debugger {});
40    node = drop_span(node);
41    let mut buf = Vec::new();
42    let cm = Lrc::new(SourceMap::default());
43
44    {
45        let mut emitter = Emitter {
46            cfg: Default::default(),
47            cm: cm.clone(),
48            comments: None,
49            wr: Box::new(JsWriter::new(cm, "\n", &mut buf, None)),
50        };
51
52        node.emit_with(&mut emitter).unwrap();
53    }
54
55    String::from_utf8(buf).unwrap()
56}