Skip to content

Commit f23ec9e

Browse files
committed
Split transformer implementation
1 parent 0b9e315 commit f23ec9e

File tree

5 files changed

+104
-91
lines changed

5 files changed

+104
-91
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
use super::parse_js_code_to_statements::parse_js_code_to_statements;
2+
use oxc_allocator::{Allocator, Box};
3+
use oxc_ast::ast::FunctionBody;
4+
use oxc_span::SourceType;
5+
6+
pub fn insert_single_statement_into_func<'a>(
7+
allocator: &'a Allocator,
8+
body: &mut Box<'a, FunctionBody<'a>>,
9+
pos: usize,
10+
source_text: &'a str,
11+
) {
12+
body.statements.insert(
13+
pos,
14+
parse_js_code_to_statements(&allocator, &source_text, SourceType::mjs())
15+
.into_iter()
16+
.next()
17+
.unwrap(),
18+
);
19+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pub mod get_import_code_str;
22
pub mod get_method_arg_names;
3+
pub mod insert_single_statement_into_func;
34
pub mod parse_js_code_to_statements;
45
pub mod select_sourcetype_based_on_enum;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
pub mod helpers;
22
pub mod instructions;
33
pub mod transformer;
4+
mod transformer_impl;
Lines changed: 4 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
use oxc_allocator::{Allocator, Box};
2-
use oxc_ast::ast::{FunctionBody, MethodDefinition};
1+
use oxc_allocator::Allocator;
32
use oxc_codegen::{Codegen, CodegenOptions};
43
use oxc_parser::{ParseOptions, Parser};
54
use oxc_semantic::SemanticBuilder;
65
use oxc_span::SourceType;
7-
use oxc_traverse::{traverse_mut, Traverse, TraverseCtx};
6+
use oxc_traverse::traverse_mut;
87

98
use super::{
109
helpers::{
11-
get_import_code_str::get_import_code_str, get_method_arg_names::get_method_arg_names,
10+
get_import_code_str::get_import_code_str,
1211
parse_js_code_to_statements::parse_js_code_to_statements,
1312
select_sourcetype_based_on_enum::select_sourcetype_based_on_enum,
1413
},
1514
instructions::FileInstructions,
15+
transformer_impl::Transformer,
1616
};
1717

1818
pub fn transform_code_str(
@@ -84,90 +84,3 @@ pub fn transform_code_str(
8484

8585
js.code
8686
}
87-
88-
struct Transformer<'a> {
89-
allocator: &'a Allocator,
90-
file_instructions: &'a FileInstructions,
91-
pkg_name: &'a str,
92-
pkg_version: &'a str,
93-
}
94-
95-
impl<'a> Traverse<'a> for Transformer<'a> {
96-
fn enter_method_definition(
97-
&mut self,
98-
node: &mut MethodDefinition<'a>,
99-
_ctx: &mut TraverseCtx<'a>,
100-
) {
101-
if !node.key.is_identifier() || !node.value.body.is_some() || !node.key.name().is_some() {
102-
return;
103-
}
104-
105-
if !node.kind.is_method() {
106-
// Ignore constructor, getters and setters for now
107-
return;
108-
}
109-
110-
let method_name = node.key.name().unwrap().to_string();
111-
112-
let found_instruction = self
113-
.file_instructions
114-
.functions
115-
.iter()
116-
.find(|f| f.node_type == "MethodDefinition" && f.name == method_name);
117-
118-
if found_instruction.is_none() {
119-
return;
120-
}
121-
122-
let instruction = found_instruction.unwrap();
123-
124-
// We need to collect the arg names before we make the body mutable
125-
let arg_names = if instruction.modify_args {
126-
get_method_arg_names(node)
127-
} else {
128-
Vec::new()
129-
};
130-
131-
let body = node.value.body.as_mut().unwrap();
132-
133-
if instruction.modify_args && !arg_names.is_empty() {
134-
// Modify the arguments by adding a statement to the beginning of the function
135-
// [arg1, arg2, ...] = __instrumentModifyArgs('function_identifier', [arg1, arg2, ...]);
136-
137-
let arg_names_str = arg_names.join(", ");
138-
let source_text: &'a str = self.allocator.alloc_str(&format!(
139-
"[{}] = __instrumentModifyArgs('{}', [{}]);",
140-
arg_names_str, instruction.identifier, arg_names_str
141-
));
142-
143-
insert_single_statement_into_func(self.allocator, body, 0, &source_text);
144-
}
145-
146-
if instruction.inspect_args {
147-
// Add a statement to the beginning of the function: __instrumentInspectArgs('function_identifier', arguments);
148-
let source_text: &'a str = self.allocator.alloc_str(&format!(
149-
"__instrumentInspectArgs('{}', arguments, '{}', '{}', '{}', this);",
150-
instruction.identifier, self.pkg_name, self.pkg_version, instruction.name
151-
));
152-
153-
insert_single_statement_into_func(self.allocator, body, 0, source_text);
154-
}
155-
156-
// Todo support return value modification
157-
}
158-
}
159-
160-
fn insert_single_statement_into_func<'a>(
161-
allocator: &'a Allocator,
162-
body: &mut Box<'a, FunctionBody<'a>>,
163-
pos: usize,
164-
source_text: &'a str,
165-
) {
166-
body.statements.insert(
167-
pos,
168-
parse_js_code_to_statements(&allocator, &source_text, SourceType::mjs())
169-
.into_iter()
170-
.next()
171-
.unwrap(),
172-
);
173-
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
use super::helpers::get_method_arg_names;
2+
use super::instructions::FileInstructions;
3+
use oxc_allocator::Allocator;
4+
use oxc_ast::ast::MethodDefinition;
5+
use oxc_traverse::{Traverse, TraverseCtx};
6+
7+
use super::helpers::insert_single_statement_into_func::insert_single_statement_into_func;
8+
9+
pub struct Transformer<'a> {
10+
pub allocator: &'a Allocator,
11+
pub file_instructions: &'a FileInstructions,
12+
pub pkg_name: &'a str,
13+
pub pkg_version: &'a str,
14+
}
15+
16+
impl<'a> Traverse<'a> for Transformer<'a> {
17+
fn enter_method_definition(
18+
&mut self,
19+
node: &mut MethodDefinition<'a>,
20+
_ctx: &mut TraverseCtx<'a>,
21+
) {
22+
if !node.key.is_identifier() || !node.value.body.is_some() || !node.key.name().is_some() {
23+
return;
24+
}
25+
26+
if !node.kind.is_method() {
27+
// Ignore constructor, getters and setters for now
28+
return;
29+
}
30+
31+
let method_name = node.key.name().unwrap().to_string();
32+
33+
let found_instruction = self
34+
.file_instructions
35+
.functions
36+
.iter()
37+
.find(|f| f.node_type == "MethodDefinition" && f.name == method_name);
38+
39+
if found_instruction.is_none() {
40+
return;
41+
}
42+
43+
let instruction = found_instruction.unwrap();
44+
45+
// We need to collect the arg names before we make the body mutable
46+
let arg_names = if instruction.modify_args {
47+
get_method_arg_names::get_method_arg_names(node)
48+
} else {
49+
Vec::new()
50+
};
51+
52+
let body = node.value.body.as_mut().unwrap();
53+
54+
if instruction.modify_args && !arg_names.is_empty() {
55+
// Modify the arguments by adding a statement to the beginning of the function
56+
// [arg1, arg2, ...] = __instrumentModifyArgs('function_identifier', [arg1, arg2, ...]);
57+
58+
let arg_names_str = arg_names.join(", ");
59+
let source_text: &'a str = self.allocator.alloc_str(&format!(
60+
"[{}] = __instrumentModifyArgs('{}', [{}]);",
61+
arg_names_str, instruction.identifier, arg_names_str
62+
));
63+
64+
insert_single_statement_into_func(self.allocator, body, 0, &source_text);
65+
}
66+
67+
if instruction.inspect_args {
68+
// Add a statement to the beginning of the function: __instrumentInspectArgs('function_identifier', arguments);
69+
let source_text: &'a str = self.allocator.alloc_str(&format!(
70+
"__instrumentInspectArgs('{}', arguments, '{}', '{}', '{}', this);",
71+
instruction.identifier, self.pkg_name, self.pkg_version, instruction.name
72+
));
73+
74+
insert_single_statement_into_func(self.allocator, body, 0, source_text);
75+
}
76+
77+
// Todo support return value modification
78+
}
79+
}

0 commit comments

Comments
 (0)