43
use react_compiler_hir::ReactFunctionType;
44
use react_compiler_hir::environment_config::EnvironmentConfig;
45
use react_compiler_lowering::FunctionNode;
46
-use regex::Regex;
46
47
use super::compile_result::BindingRenameInfo;
48
use super::compile_result::CodegenFunction;
174
None => return Ok(None),
175
};
176
178
- let pattern = Regex::new(r"^use memo if\(([^\)]*)\)$").expect("Invalid dynamic gating regex");
179
-
177
let mut errors: Vec<CompilerErrorDetail> = Vec::new();
178
let mut matches: Vec<(&'a Directive, String)> = Vec::new();
179
180
for directive in directives {
184
- if let Some(caps) = pattern.captures(&directive.value.value) {
185
- if let Some(m) = caps.get(1) {
186
- let ident = m.as_str();
187
- if is_valid_identifier(ident) {
188
- matches.push((directive, ident.to_string()));
189
- } else {
190
- let mut detail = CompilerErrorDetail::new(
191
- ErrorCategory::Gating,
192
- "Dynamic gating directive is not a valid JavaScript identifier",
193
- )
194
- .with_description(format!("Found '{}'", directive.value.value));
195
- detail.loc = directive.base.loc.as_ref().map(convert_loc);
196
- errors.push(detail);
197
- }
181
+ if let Some(ident) = parse_dynamic_gating_directive(&directive.value.value) {
182
+ if is_valid_identifier(ident) {
183
+ matches.push((directive, ident.to_string()));
184
+ } else {
185
+ let mut detail = CompilerErrorDetail::new(
186
+ ErrorCategory::Gating,
187
+ "Dynamic gating directive is not a valid JavaScript identifier",
188
+ )
189
+ .with_description(format!("Found '{}'", directive.value.value));
190
+ detail.loc = directive.base.loc.as_ref().map(convert_loc);
191
+ errors.push(detail);
192
}
193
}
194
}
230
}
231
}
232
233
+/// Parse a `use memo if(<condition>)` directive, returning the condition.
234
+/// Exact equivalent of the TS DYNAMIC_GATING_DIRECTIVE regex
235
+/// `^use memo if\(([^\)]*)\)$`: the condition may not contain `)` and the
236
+/// directive must end at the closing paren.
237
+fn parse_dynamic_gating_directive(value: &str) -> Option<&str> {
238
+ let condition = value
239
+ .strip_prefix("use memo if(")?
240
+ .strip_suffix(')')?;
241
+ if condition.contains(')') {
242
+ return None;
243
+ }
244
+ Some(condition)
245
+}
246
+
247
/// Simple check for valid JavaScript identifier (alphanumeric + underscore + $, starting with letter/$/_ )
248
/// Also rejects reserved words like `true`, `false`, `null`, etc.
249
fn is_valid_identifier(s: &str) -> bool {