main
rs 56 lines 2.28 KB
Raw
1 // Copyright (c) Meta Platforms, Inc. and affiliates.
2 //
3 // This source code is licensed under the MIT license found in the
4 // LICENSE file in the root directory of this source tree.
5
6 //! Converts `MethodCall` instructions on props objects into `CallExpression`
7 //! instructions.
8 //!
9 //! When the receiver of a method call is typed as the component's props object,
10 //! we can safely convert the method call `props.foo(args)` into a direct call
11 //! `foo(args)` using the property as the callee. This simplifies downstream
12 //! analysis by removing the receiver dependency.
13 //!
14 //! Analogous to TS `Optimization/OptimizePropsMethodCalls.ts`.
15
16 use react_compiler_hir::environment::Environment;
17 use react_compiler_hir::{HirFunction, InstructionValue, is_props_type};
18
19 pub fn optimize_props_method_calls(func: &mut HirFunction, env: &Environment) {
20 for (_block_id, block) in &func.body.blocks {
21 let instruction_ids: Vec<_> = block.instructions.clone();
22 for instr_id in instruction_ids {
23 let instr = &mut func.instructions[instr_id.0 as usize];
24 let should_replace = matches!(
25 &instr.value,
26 InstructionValue::MethodCall { receiver, .. }
27 if {
28 let identifier = &env.identifiers[receiver.identifier.0 as usize];
29 let ty = &env.types[identifier.type_.0 as usize];
30 is_props_type(ty)
31 }
32 );
33 if should_replace {
34 // Take the old value out, replacing with a temporary.
35 // The if-let is guaranteed to match since we checked above.
36 let old =
37 std::mem::replace(&mut instr.value, InstructionValue::Debugger { loc: None });
38 match old {
39 InstructionValue::MethodCall {
40 property,
41 args,
42 loc,
43 ..
44 } => {
45 instr.value = InstructionValue::CallExpression {
46 callee: property,
47 args,
48 loc,
49 };
50 }
51 _ => unreachable!(),
52 }
53 }
54 }
55 }
56 }