1use crate::visit_selectors::ClassVisitor;
2
3use swc_core::{
4 common::{sync::Lrc, FileName, SourceMap},
5 ecma::codegen::{text_writer::JsWriter, Emitter},
6 ecma::{
7 parser::{lexer::Lexer, Parser, StringInput},
8 visit::{as_folder, FoldWith, VisitMut},
9 },
10};
11
12pub fn check_js(
13 old_content: &String,
14 class_visitor: &ClassVisitor,
15) -> Option<Vec<u8>> {
16 let map_visitor = MapVisitor::new(class_visitor);
17 let cm: Lrc<SourceMap> = Default::default();
18 let fm = cm.new_source_file(
19 FileName::Custom("test.js".into()),
20 old_content.into(),
21 );
22 let lexer = Lexer::new(
23 swc_core::ecma::parser::Syntax::Es(Default::default()),
24 Default::default(),
25 StringInput::from(&*fm),
26 None,
27 );
28 let mut parser = Parser::new_from(lexer);
29 let s = parser.parse_program();
30 let mut code = vec![];
31 let mut srcmap = vec![];
32
33 match s {
34 Ok(program) => {
35 let program = program.fold_with(&mut as_folder(map_visitor));
36
37 {
38 let mut emitter = Emitter {
39 cfg: Default::default(),
40 cm: cm.clone(),
41 comments: None,
42 wr: JsWriter::new(
43 cm.clone(),
44 "\n",
45 &mut code,
46 Some(&mut srcmap),
47 ),
48 };
49 if let Some(module) = program.as_script() {
50 if emitter.emit_script(module).is_ok() {
51 return Some(code);
52 }
53 }
54 None
55 }
56 }
57 Err(_) => None,
58 }
59}
60
61pub struct MapVisitor<'a> {
62 pub is_set: bool,
63 pub first_string: Option<String>,
64 pub class_visitor: &'a ClassVisitor,
65}
66
67impl<'a> MapVisitor<'a> {
68 fn new(class_visitor: &'a ClassVisitor) -> Self {
69 Self {
70 is_set: false,
71 first_string: None,
72 class_visitor,
73 }
74 }
75}
76
77impl<'a> VisitMut for MapVisitor<'a> {
78 fn visit_mut_ident(&mut self, n: &mut swc_core::ecma::ast::Ident) {
79 let s = n.to_string();
80 if s.starts_with("set") {
81 self.is_set = true;
82 } else {
83 self.is_set = false;
84 self.first_string = None;
85 }
86 }
87
88 fn visit_mut_str(&mut self, n: &mut swc_core::ecma::ast::Str) {
89 if self.is_set {
90 match &self.first_string {
91 Some(s) => {
92 let new_str = &self.class_visitor.get(s);
93 if let Some(new_str) = new_str {
94 let new_str = format!("'{}'", new_str);
95 n.raw = Some(new_str.into());
96 }
97 self.is_set = false;
98 self.first_string = None;
99 }
100 None => {
101 self.is_set = true;
102 self.first_string = Some(n.value.to_string());
103 }
104 }
105 }
106 }
107}