main
rs 230 lines 8.52 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 //! Environment configuration, ported from EnvironmentConfigSchema in Environment.ts.
7 //!
8 //! Contains feature flags and custom hook definitions that control compiler behavior.
9
10 use indexmap::IndexMap;
11 use rustc_hash::{FxBuildHasher, FxHashMap};
12
13 use serde::{Deserialize, Serialize};
14
15 use crate::Effect;
16 use crate::type_config::{TypeConfig, ValueKind};
17
18 /// External function reference (source module + import name).
19 /// Corresponds to TS `ExternalFunction`.
20 #[derive(Debug, Clone, Serialize, Deserialize)]
21 #[serde(rename_all = "camelCase")]
22 pub struct ExternalFunctionConfig {
23 pub source: String,
24 pub import_specifier_name: String,
25 }
26
27 /// Instrumentation configuration.
28 /// Corresponds to TS `InstrumentationSchema`.
29 #[derive(Debug, Clone, Serialize, Deserialize)]
30 #[serde(rename_all = "camelCase")]
31 pub struct InstrumentationConfig {
32 #[serde(rename = "fn")]
33 pub fn_: ExternalFunctionConfig,
34 #[serde(default)]
35 pub gating: Option<ExternalFunctionConfig>,
36 #[serde(default)]
37 pub global_gating: Option<String>,
38 }
39
40 /// Custom hook configuration, ported from TS `HookSchema`.
41 #[derive(Debug, Clone, Serialize, Deserialize)]
42 #[serde(rename_all = "camelCase")]
43 pub struct HookConfig {
44 pub effect_kind: Effect,
45 pub value_kind: ValueKind,
46 #[serde(default)]
47 pub no_alias: bool,
48 #[serde(default)]
49 pub transitive_mixed_data: bool,
50 }
51
52 #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
53 pub enum ExhaustiveEffectDepsMode {
54 #[serde(rename = "off")]
55 Off,
56 #[serde(rename = "all")]
57 All,
58 #[serde(rename = "missing-only")]
59 MissingOnly,
60 #[serde(rename = "extra-only")]
61 ExtraOnly,
62 }
63
64 impl Default for ExhaustiveEffectDepsMode {
65 fn default() -> Self {
66 Self::Off
67 }
68 }
69
70 fn default_true() -> bool {
71 true
72 }
73
74 /// Compiler environment configuration. Contains feature flags and settings.
75 ///
76 /// Fields that would require passing JS functions across the JS/Rust boundary
77 /// are omitted with TODO comments. The Rust port uses hardcoded defaults for
78 /// these (e.g., `defaultModuleTypeProvider`).
79 #[derive(Debug, Clone, Serialize, Deserialize)]
80 #[serde(rename_all = "camelCase")]
81 pub struct EnvironmentConfig {
82 /// Custom hook type definitions, keyed by hook name.
83 #[serde(default)]
84 pub custom_hooks: FxHashMap<String, HookConfig>,
85
86 /// Pre-resolved module type provider results.
87 /// Map from module name to TypeConfig, computed by the JS shim.
88 #[serde(default)]
89 pub module_type_provider: Option<IndexMap<String, TypeConfig, FxBuildHasher>>,
90
91 /// Custom macro-like function names that should have their operands
92 /// memoized in the same scope (similar to fbt).
93 #[serde(default)]
94 pub custom_macros: Option<Vec<String>>,
95
96 /// If true, emit code to reset the memo cache on source file changes (HMR/fast refresh).
97 /// If null (None), HMR detection is conditionally enabled based on NODE_ENV/__DEV__.
98 #[serde(default)]
99 pub enable_reset_cache_on_source_file_changes: Option<bool>,
100
101 #[serde(default = "default_true")]
102 pub enable_preserve_existing_memoization_guarantees: bool,
103 #[serde(default = "default_true")]
104 pub validate_preserve_existing_memoization_guarantees: bool,
105 #[serde(default = "default_true")]
106 pub validate_exhaustive_memoization_dependencies: bool,
107 #[serde(default)]
108 pub validate_exhaustive_effect_dependencies: ExhaustiveEffectDepsMode,
109
110 // TODO: flowTypeProvider — requires JS function callback.
111 #[serde(default = "default_true")]
112 pub enable_optional_dependencies: bool,
113 #[serde(default)]
114 pub enable_name_anonymous_functions: bool,
115 #[serde(default = "default_true")]
116 pub validate_hooks_usage: bool,
117 #[serde(default = "default_true")]
118 pub validate_ref_access_during_render: bool,
119 #[serde(default = "default_true")]
120 pub validate_no_set_state_in_render: bool,
121 #[serde(default)]
122 pub enable_use_keyed_state: bool,
123 #[serde(default)]
124 pub validate_no_set_state_in_effects: bool,
125 #[serde(default)]
126 pub validate_no_derived_computations_in_effects: bool,
127 #[serde(default)]
128 #[serde(alias = "validateNoDerivedComputationsInEffects_exp")]
129 pub validate_no_derived_computations_in_effects_exp: bool,
130 #[serde(default)]
131 #[serde(alias = "validateNoJSXInTryStatements")]
132 pub validate_no_jsx_in_try_statements: bool,
133 #[serde(default)]
134 pub validate_static_components: bool,
135 #[serde(default)]
136 pub validate_no_capitalized_calls: Option<Vec<String>>,
137 #[serde(default)]
138 #[serde(alias = "restrictedImports")]
139 pub validate_blocklisted_imports: Option<Vec<String>>,
140 #[serde(default)]
141 pub validate_source_locations: bool,
142 #[serde(default)]
143 pub validate_no_impure_functions_in_render: bool,
144 #[serde(default)]
145 pub validate_no_freezing_known_mutable_functions: bool,
146 #[serde(default = "default_true")]
147 pub enable_assume_hooks_follow_rules_of_react: bool,
148 #[serde(default = "default_true")]
149 pub enable_transitively_freeze_function_expressions: bool,
150
151 /// Hook guard configuration. When set, wraps hook calls with dispatcher guard calls.
152 #[serde(default)]
153 pub enable_emit_hook_guards: Option<ExternalFunctionConfig>,
154
155 /// Instrumentation configuration. When set, emits calls to instrument functions.
156 #[serde(default)]
157 pub enable_emit_instrument_forget: Option<InstrumentationConfig>,
158
159 #[serde(default = "default_true")]
160 pub enable_function_outlining: bool,
161 #[serde(default)]
162 pub enable_jsx_outlining: bool,
163 #[serde(default)]
164 pub assert_valid_mutable_ranges: bool,
165 #[serde(default)]
166 #[serde(alias = "throwUnknownException__testonly")]
167 pub throw_unknown_exception_testonly: bool,
168 #[serde(default)]
169 pub enable_custom_type_definition_for_reanimated: bool,
170 #[serde(default = "default_true")]
171 pub enable_treat_ref_like_identifiers_as_refs: bool,
172 #[serde(default)]
173 pub enable_treat_set_identifiers_as_state_setters: bool,
174 #[serde(default = "default_true")]
175 pub validate_no_void_use_memo: bool,
176 #[serde(default = "default_true")]
177 pub enable_allow_set_state_from_refs_in_effects: bool,
178 #[serde(default)]
179 pub enable_verbose_no_set_state_in_effect: bool,
180
181 // 🌲
182 #[serde(default)]
183 pub enable_forest: bool,
184 }
185
186 impl Default for EnvironmentConfig {
187 fn default() -> Self {
188 Self {
189 custom_hooks: FxHashMap::default(),
190 enable_reset_cache_on_source_file_changes: None,
191 module_type_provider: None,
192 enable_preserve_existing_memoization_guarantees: true,
193 validate_preserve_existing_memoization_guarantees: true,
194 validate_exhaustive_memoization_dependencies: true,
195 validate_exhaustive_effect_dependencies: ExhaustiveEffectDepsMode::Off,
196 enable_optional_dependencies: true,
197 enable_name_anonymous_functions: false,
198 validate_hooks_usage: true,
199 validate_ref_access_during_render: true,
200 validate_no_set_state_in_render: true,
201 enable_use_keyed_state: false,
202 validate_no_set_state_in_effects: false,
203 validate_no_derived_computations_in_effects: false,
204 validate_no_derived_computations_in_effects_exp: false,
205 validate_no_jsx_in_try_statements: false,
206 validate_static_components: false,
207 validate_no_capitalized_calls: None,
208 validate_blocklisted_imports: None,
209 validate_source_locations: false,
210 validate_no_impure_functions_in_render: false,
211 validate_no_freezing_known_mutable_functions: false,
212 enable_assume_hooks_follow_rules_of_react: true,
213 enable_transitively_freeze_function_expressions: true,
214 enable_emit_hook_guards: None,
215 enable_emit_instrument_forget: None,
216 enable_function_outlining: true,
217 enable_jsx_outlining: false,
218 assert_valid_mutable_ranges: false,
219 throw_unknown_exception_testonly: false,
220 enable_custom_type_definition_for_reanimated: false,
221 enable_treat_ref_like_identifiers_as_refs: true,
222 enable_treat_set_identifiers_as_state_setters: false,
223 validate_no_void_use_memo: true,
224 enable_allow_set_state_from_refs_in_effects: true,
225 enable_verbose_no_set_state_in_effect: false,
226 enable_forest: false,
227 custom_macros: None,
228 }
229 }
230 }