Skip to content

Commit 5881e56

Browse files
committed
refactor: FnCallInfo
1 parent 7b1e157 commit 5881e56

8 files changed

Lines changed: 205 additions & 256 deletions

File tree

crates/jsshaker/src/nodes/expr/arrow_function_expression.rs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,10 @@ use oxc::ast::{
66
use crate::{
77
analyzer::Analyzer,
88
ast::{AstKind2, DeclarationKind},
9-
dep::Dep,
109
entity::Entity,
11-
scope::VariableScopeId,
1210
transformer::Transformer,
13-
utils::{CalleeInfo, CalleeNode},
14-
value::{ArgumentsValue, cache::FnCacheTrackingData},
11+
utils::CalleeNode,
12+
value::{cache::FnCacheTrackingData, call::FnCallInfo},
1513
};
1614

1715
impl<'a> Analyzer<'a> {
@@ -24,31 +22,31 @@ impl<'a> Analyzer<'a> {
2422

2523
pub fn call_arrow_function_expression(
2624
&mut self,
27-
callee: CalleeInfo<'a>,
28-
call_dep: Dep<'a>,
2925
node: &'a ArrowFunctionExpression<'a>,
30-
lexical_scope: Option<VariableScopeId>,
31-
args: ArgumentsValue<'a>,
32-
consume: bool,
26+
info: FnCallInfo<'a>,
3327
) -> (Entity<'a>, FnCacheTrackingData<'a>) {
3428
let runner = move |analyzer: &mut Analyzer<'a>| {
35-
analyzer.push_call_scope(callee, call_dep, lexical_scope, node.r#async, false, consume);
29+
analyzer.push_call_scope(info, node.r#async, false);
3630

37-
analyzer.exec_formal_parameters(&node.params, args, DeclarationKind::ArrowFunctionParameter);
31+
analyzer.exec_formal_parameters(
32+
&node.params,
33+
info.args,
34+
DeclarationKind::ArrowFunctionParameter,
35+
);
3836
if node.expression {
3937
analyzer.exec_function_expression_body(&node.body);
4038
} else {
4139
analyzer.exec_function_body(&node.body);
4240
}
4341

44-
if consume {
42+
if info.consume {
4543
analyzer.consume_return_values();
4644
}
4745

4846
analyzer.pop_call_scope()
4947
};
5048

51-
if !consume && node.r#async {
49+
if !info.consume && node.r#async {
5250
// Too complex to analyze the control flow, thus run exhaustively
5351
self.exec_async_or_generator_fn(move |analyzer| {
5452
runner(analyzer).0.consume(analyzer);

crates/jsshaker/src/nodes/misc/class.rs

Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,10 @@ use oxc::{
1313
use crate::{
1414
analyzer::Analyzer,
1515
ast::{AstKind2, DeclarationKind},
16-
dep::Dep,
1716
entity::Entity,
18-
scope::VariableScopeId,
1917
transformer::Transformer,
20-
utils::{CalleeInfo, CalleeNode},
21-
value::{ArgumentsValue, ObjectPrototype, ValueTrait, cache::FnCacheTrackingData},
18+
utils::CalleeNode,
19+
value::{ObjectPrototype, ValueTrait, cache::FnCacheTrackingData, call::FnCallInfo},
2220
};
2321

2422
#[derive(Default)]
@@ -54,15 +52,6 @@ impl<'a> Analyzer<'a> {
5452
};
5553

5654
// Enter class statics scope
57-
let variable_scope = self.scoping.variable.top();
58-
self.push_call_scope(
59-
self.new_callee_info(CalleeNode::ClassStatics(node)),
60-
self.factory.no_dep,
61-
variable_scope,
62-
false,
63-
false,
64-
false,
65-
);
6655
self.variable_scope_mut().super_class =
6756
Some(data.super_class.unwrap_or(self.factory.undefined));
6857

@@ -118,8 +107,6 @@ impl<'a> Analyzer<'a> {
118107
}
119108
}
120109

121-
self.pop_call_scope();
122-
123110
let class = class.into();
124111
data.value = Some(class);
125112
class
@@ -139,23 +126,19 @@ impl<'a> Analyzer<'a> {
139126

140127
pub fn call_class_constructor(
141128
&mut self,
142-
callee: CalleeInfo<'a>,
143-
call_dep: Dep<'a>,
144129
node: &'a Class<'a>,
145-
lexical_scope: Option<VariableScopeId>,
146-
this: Entity<'a>,
147-
args: ArgumentsValue<'a>,
148-
consume: bool,
130+
info: FnCallInfo<'a>,
149131
) -> (Entity<'a>, FnCacheTrackingData<'a>) {
150132
let factory = self.factory;
151133
let data = self.load_data::<Data>(AstKind2::Class(node));
152134

153-
self.push_call_scope(callee, call_dep, lexical_scope, false, false, consume);
135+
self.push_call_scope(info, false, false);
154136
let super_class = data.super_class.unwrap_or(self.factory.undefined);
155-
let body_scope = self.variable_scope_mut();
156-
body_scope.this = Some(this);
157-
body_scope.arguments = Some((args, factory.vec(/* later filled by formal parameters */)));
158-
body_scope.super_class = Some(super_class);
137+
let variable_scope = self.variable_scope_mut();
138+
variable_scope.this = Some(info.this);
139+
variable_scope.arguments =
140+
Some((info.args, factory.vec(/* later filled by formal parameters */)));
141+
variable_scope.super_class = Some(super_class);
159142

160143
if let Some(id) = &node.id {
161144
self.declare_binding_identifier(id, false, DeclarationKind::NamedFunctionInBody);
@@ -168,7 +151,7 @@ impl<'a> Analyzer<'a> {
168151
&& !node.r#static
169152
{
170153
let value = self.exec_property_definition(node);
171-
this.set_property(self, self.factory.no_dep, key.unwrap(), value);
154+
info.this.set_property(self, self.factory.no_dep, key.unwrap(), value);
172155
}
173156
}
174157

@@ -177,15 +160,15 @@ impl<'a> Analyzer<'a> {
177160
let function = constructor.value.as_ref();
178161
let dep = self.factory.dep(AstKind2::Function(function));
179162
self.cf_scope_mut().push_dep(dep);
180-
self.exec_formal_parameters(&function.params, args, DeclarationKind::FunctionParameter);
163+
self.exec_formal_parameters(&function.params, info.args, DeclarationKind::FunctionParameter);
181164
self.exec_function_body(function.body.as_ref().unwrap());
182-
if consume {
165+
if info.consume {
183166
self.consume_return_values();
184167
}
185168
self.pop_call_scope()
186169
} else if let Some(super_class) = &data.super_class {
187170
self.pop_call_scope();
188-
let ret_val = super_class.call(self, self.factory.no_dep, this, args);
171+
let ret_val = super_class.call(self, self.factory.no_dep, info.this, info.args);
189172
(ret_val, FnCacheTrackingData::worst_case())
190173
} else {
191174
let (_, cache_tracking) = self.pop_call_scope();

crates/jsshaker/src/nodes/misc/function.rs

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,10 @@ use oxc::{
99
use crate::{
1010
analyzer::Analyzer,
1111
ast::{AstKind2, DeclarationKind},
12-
dep::Dep,
1312
entity::Entity,
14-
scope::VariableScopeId,
1513
transformer::Transformer,
16-
utils::{CalleeInfo, CalleeNode},
17-
value::{ArgumentsValue, cache::FnCacheTrackingData},
14+
utils::CalleeNode,
15+
value::{cache::FnCacheTrackingData, call::FnCallInfo},
1816
};
1917

2018
impl<'a> Analyzer<'a> {
@@ -40,29 +38,17 @@ impl<'a> Analyzer<'a> {
4038

4139
pub fn call_function(
4240
&mut self,
43-
fn_entity: Entity<'a>,
44-
callee: CalleeInfo<'a>,
45-
call_dep: Dep<'a>,
4641
node: &'a Function<'a>,
47-
lexical_scope: Option<VariableScopeId>,
48-
this: Entity<'a>,
49-
args: ArgumentsValue<'a>,
50-
consume: bool,
42+
info: FnCallInfo<'a>,
5143
) -> (Entity<'a>, FnCacheTrackingData<'a>) {
5244
let runner = move |analyzer: &mut Analyzer<'a>| {
53-
analyzer.push_call_scope(
54-
callee,
55-
call_dep,
56-
lexical_scope,
57-
node.r#async,
58-
node.generator,
59-
consume,
60-
);
45+
analyzer.push_call_scope(info, node.r#async, node.generator);
6146

6247
let factory = analyzer.factory;
63-
let body_scope = analyzer.variable_scope_mut();
64-
body_scope.this = Some(this);
65-
body_scope.arguments = Some((args, factory.vec(/* later filled by formal parameters */)));
48+
let variable_scope = analyzer.variable_scope_mut();
49+
variable_scope.this = Some(info.this);
50+
variable_scope.arguments =
51+
Some((info.args, factory.vec(/* later filled by formal parameters */)));
6652

6753
let declare_in_body = node.r#type == FunctionType::FunctionExpression && node.id.is_some();
6854
if declare_in_body {
@@ -72,21 +58,21 @@ impl<'a> Analyzer<'a> {
7258
AstKind2::BindingIdentifier(id),
7359
false,
7460
DeclarationKind::NamedFunctionInBody,
75-
Some(analyzer.factory.computed(fn_entity, AstKind2::BindingIdentifier(id))),
61+
Some(analyzer.factory.computed(info.func.into(), AstKind2::BindingIdentifier(id))),
7662
);
7763
}
7864

79-
analyzer.exec_formal_parameters(&node.params, args, DeclarationKind::FunctionParameter);
65+
analyzer.exec_formal_parameters(&node.params, info.args, DeclarationKind::FunctionParameter);
8066
analyzer.exec_function_body(node.body.as_ref().unwrap());
8167

82-
if consume {
68+
if info.consume {
8369
analyzer.consume_return_values();
8470
}
8571

8672
analyzer.pop_call_scope()
8773
};
8874

89-
if !consume && (node.r#async || node.generator) {
75+
if !info.consume && (node.r#async || node.generator) {
9076
// Too complex to analyze the control flow, thus run exhaustively
9177
self.exec_async_or_generator_fn(move |analyzer| {
9278
runner(analyzer).0.consume(analyzer);

crates/jsshaker/src/scope/mod.rs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::{
2222
module::ModuleId,
2323
scope::linked_tree::LinkedTree,
2424
utils::{CalleeInfo, CalleeNode},
25-
value::{ObjectId, cache::FnCacheTrackingData},
25+
value::{ObjectId, cache::FnCacheTrackingData, call::FnCallInfo},
2626
};
2727

2828
pub struct Scoping<'a> {
@@ -106,33 +106,27 @@ impl<'a> Analyzer<'a> {
106106
self.scoping.variable.replace_top(new_top)
107107
}
108108

109-
pub fn push_call_scope(
110-
&mut self,
111-
callee: CalleeInfo<'a>,
112-
call_dep: Dep<'a>,
113-
lexical_scope: Option<VariableScopeId>,
114-
is_async: bool,
115-
is_generator: bool,
116-
consume: bool,
117-
) {
109+
pub fn push_call_scope(&mut self, info: FnCallInfo<'a>, is_async: bool, is_generator: bool) {
118110
let dep_id = DepAtom::from_counter();
119-
if consume {
111+
if info.consume {
120112
self.refer_dep(dep_id);
121113
}
122114

123-
self.module_stack.push(callee.module_id);
124-
let old_variable_scope = self.replace_variable_scope(lexical_scope);
115+
self.module_stack.push(info.func.callee.module_id);
116+
let old_variable_scope_stack = self.replace_variable_scope(info.func.lexical_scope);
125117
let body_variable_scope = self.push_variable_scope();
126118
let cf_scope_depth = self.push_cf_scope_with_deps(
127-
CfScopeKind::Function(self.allocator.alloc(FnCacheTrackingData::new_in(self.allocator))),
128-
self.factory.vec1(self.dep((call_dep, dep_id))),
119+
CfScopeKind::Function(
120+
self.allocator.alloc(FnCacheTrackingData::new_in(self.allocator, info)),
121+
),
122+
self.factory.vec1(self.dep((info.call_dep, dep_id))),
129123
false,
130124
);
131125

132126
self.scoping.call.push(CallScope::new_in(
133127
dep_id,
134-
callee,
135-
old_variable_scope,
128+
info.func.callee,
129+
old_variable_scope_stack,
136130
cf_scope_depth,
137131
body_variable_scope,
138132
is_async,

crates/jsshaker/src/value/function/bound.rs

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,8 @@ use oxc::span::Span;
22

33
use crate::{
44
Analyzer,
5-
dep::Dep,
65
entity::Entity,
7-
scope::VariableScopeId,
8-
utils::CalleeInfo,
9-
value::{ArgumentsValue, cache::FnCacheTrackingData},
6+
value::{ArgumentsValue, cache::FnCacheTrackingData, call::FnCallInfo},
107
};
118

129
#[derive(Debug)]
@@ -18,30 +15,23 @@ pub struct BoundFunction<'a> {
1815
}
1916

2017
impl<'a> Analyzer<'a> {
21-
pub fn call_bound_function(
18+
pub fn call_bound_function<const IS_CTOR: bool>(
2219
&mut self,
23-
callee: CalleeInfo<'a>,
24-
call_dep: Dep<'a>,
2520
bound_fn: &'a BoundFunction<'a>,
26-
lexical_scope: Option<VariableScopeId>,
27-
ctor_this: Option<Entity<'a>>,
28-
args: ArgumentsValue<'a>,
29-
consume: bool,
21+
info: FnCallInfo<'a>,
3022
) -> (Entity<'a>, FnCacheTrackingData<'a>) {
31-
self.push_call_scope(callee, call_dep, lexical_scope, false, false, consume);
23+
self.push_call_scope(info, false, false);
3224

33-
// self.exec_formal_parameters(&node.params, args, DeclarationKind::ArrowFunctionParameter);
34-
// if node.expression {
35-
// self.exec_function_expression_body(&node.body);
36-
// } else {
37-
// self.exec_function_body(&node.body);
38-
// }
39-
40-
let args = ArgumentsValue::from_concatenate(self, bound_fn.bound_args, args);
41-
let ret = bound_fn.target.call(self, call_dep, ctor_this.unwrap_or(bound_fn.bound_this), args);
25+
let args = ArgumentsValue::from_concatenate(self, bound_fn.bound_args, info.args);
26+
let ret = bound_fn.target.call(
27+
self,
28+
info.call_dep,
29+
if IS_CTOR { info.this } else { bound_fn.bound_this },
30+
args,
31+
);
4232
self.return_value(ret, self.factory.no_dep);
4333

44-
if consume {
34+
if info.consume {
4535
self.consume_return_values();
4636
}
4737

0 commit comments

Comments
 (0)