Skip to content

Commit dee9356

Browse files
author
Joe Savona
committed
[rust-compiler] Fix remaining snap failures — 1717/1718 passing
FBT loc propagation on identifier/place/declarator/JSXAttribute nodes, component/hook declaration syntax via __componentDeclaration and __hookDeclaration AST fields, 13 missing BuiltInMixedReadonly methods, identifierName in effect-derived-computation diagnostics, and ValidateSourceLocations skip. Only remaining failure is the intentional error.todo-missing-source-locations (pass not ported to Rust).
1 parent ea0c690 commit dee9356

File tree

12 files changed

+537
-42
lines changed

12 files changed

+537
-42
lines changed

compiler/crates/react_compiler/src/entrypoint/gating.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,8 @@ fn insert_additional_function_declaration(
340340
return_type: None,
341341
type_parameters: None,
342342
predicate: None,
343+
component_declaration: false,
344+
hook_declaration: false,
343345
});
344346

345347
// Build: const gating_result = gating();

compiler/crates/react_compiler/src/entrypoint/pipeline.rs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -846,19 +846,9 @@ pub fn compile_fn(
846846
context.add_memo_cache_import();
847847
}
848848

849-
// ValidateSourceLocations: record errors after codegen so pass logs are emitted.
850-
// The Rust port cannot implement this validation (it requires the original Babel AST),
851-
// but we record errors here so the function compilation is suppressed, matching TS behavior
852-
// where validateSourceLocations records errors that cause env.hasErrors() to be true.
853-
if env.config.validate_source_locations {
854-
env.record_error(react_compiler_diagnostics::CompilerErrorDetail {
855-
category: react_compiler_diagnostics::ErrorCategory::Todo,
856-
reason: "ValidateSourceLocations is not yet supported in the Rust compiler".to_string(),
857-
description: Some("Source location validation requires access to the original AST".to_string()),
858-
loc: None,
859-
suggestions: None,
860-
});
861-
}
849+
// ValidateSourceLocations: silently skipped in the Rust compiler.
850+
// This pass requires the original Babel AST (which the Rust compiler doesn't have access to),
851+
// so it cannot be implemented. The pass is simply skipped rather than reporting a Todo error.
862852

863853
// Simulate unexpected exception for testing (matches TS Pipeline.ts)
864854
if env.config.throw_unknown_exception_testonly {
@@ -982,6 +972,8 @@ pub fn compile_outlined_fn(
982972
return_type: None,
983973
type_parameters: None,
984974
predicate: None,
975+
component_declaration: false,
976+
hook_declaration: false,
985977
};
986978

987979
// Build scope info by assigning fake positions to all identifiers

compiler/crates/react_compiler/src/entrypoint/program.rs

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,8 @@ fn get_react_function_type(
811811
is_declaration: bool,
812812
parent_callee_name: Option<&str>,
813813
opts: &PluginOptions,
814+
is_component_declaration: bool,
815+
is_hook_declaration: bool,
814816
) -> Option<ReactFunctionType> {
815817
// Check for opt-in directives in the function body
816818
if let FunctionBody::Block(_) = body {
@@ -825,21 +827,33 @@ fn get_react_function_type(
825827
}
826828

827829
// Component and hook declarations are known components/hooks
828-
// (In the TS version, this uses isComponentDeclaration/isHookDeclaration
829-
// which check for the `component` and `hook` keywords in the syntax.
830-
// Since standard JS doesn't have these, we skip this for now.)
830+
// (Flow `component Foo() { ... }` and `hook useFoo() { ... }` syntax,
831+
// detected via __componentDeclaration / __hookDeclaration from the Hermes parser)
832+
let component_syntax_type = if is_declaration {
833+
if is_component_declaration {
834+
Some(ReactFunctionType::Component)
835+
} else if is_hook_declaration {
836+
Some(ReactFunctionType::Hook)
837+
} else {
838+
None
839+
}
840+
} else {
841+
None
842+
};
831843

832844
match opts.compilation_mode.as_str() {
833845
"annotation" => {
834846
// opt-ins were checked above
835847
None
836848
}
837-
"infer" => get_component_or_hook_like(name, params, body, parent_callee_name),
849+
"infer" => {
850+
// Check if this is a component or hook-like function
851+
component_syntax_type
852+
.or_else(|| get_component_or_hook_like(name, params, body, parent_callee_name))
853+
}
838854
"syntax" => {
839855
// In syntax mode, only compile declared components/hooks
840-
// Since we don't have component/hook syntax support yet, return None
841-
let _ = is_declaration;
842-
None
856+
component_syntax_type
843857
}
844858
"all" => Some(
845859
get_component_or_hook_like(name, params, body, parent_callee_name)
@@ -1357,6 +1371,10 @@ struct FunctionInfo<'a> {
13571371
body_directives: Vec<Directive>,
13581372
base: &'a BaseNode,
13591373
parent_callee_name: Option<String>,
1374+
/// True if the node has `__componentDeclaration` set by the Hermes parser (Flow component syntax)
1375+
is_component_declaration: bool,
1376+
/// True if the node has `__hookDeclaration` set by the Hermes parser (Flow hook syntax)
1377+
is_hook_declaration: bool,
13601378
}
13611379

13621380
/// Extract function info from a FunctionDeclaration
@@ -1369,6 +1387,8 @@ fn fn_info_from_decl(decl: &FunctionDeclaration) -> FunctionInfo<'_> {
13691387
body_directives: decl.body.directives.clone(),
13701388
base: &decl.base,
13711389
parent_callee_name: None,
1390+
is_component_declaration: decl.component_declaration,
1391+
is_hook_declaration: decl.hook_declaration,
13721392
}
13731393
}
13741394

@@ -1386,6 +1406,8 @@ fn fn_info_from_func_expr<'a>(
13861406
body_directives: expr.body.directives.clone(),
13871407
base: &expr.base,
13881408
parent_callee_name,
1409+
is_component_declaration: false,
1410+
is_hook_declaration: false,
13891411
}
13901412
}
13911413

@@ -1409,6 +1431,8 @@ fn fn_info_from_arrow<'a>(
14091431
body_directives: directives,
14101432
base: &expr.base,
14111433
parent_callee_name,
1434+
is_component_declaration: false,
1435+
is_hook_declaration: false,
14121436
}
14131437
}
14141438

@@ -1430,9 +1454,11 @@ fn try_make_compile_source<'a>(
14301454
info.params,
14311455
&info.body,
14321456
&info.body_directives,
1433-
false,
1457+
info.is_component_declaration || info.is_hook_declaration,
14341458
info.parent_callee_name.as_deref(),
14351459
opts,
1460+
info.is_component_declaration,
1461+
info.is_hook_declaration,
14361462
)?;
14371463

14381464
// Mark as compiled
@@ -2229,6 +2255,8 @@ fn apply_compiled_functions(
22292255
return_type: None,
22302256
type_parameters: None,
22312257
predicate: None,
2258+
component_declaration: false,
2259+
hook_declaration: false,
22322260
};
22332261
outlined_decls.push((compiled.fn_start, compiled.original_kind, outlined_decl));
22342262
}
@@ -2740,6 +2768,8 @@ fn apply_gated_function_hoisted(
27402768
return_type: None,
27412769
type_parameters: None,
27422770
predicate: None,
2771+
component_declaration: false,
2772+
hook_declaration: false,
27432773
};
27442774

27452775
// Build the gating result variable: `const gating_result = gating();`
@@ -2913,6 +2943,8 @@ fn apply_gated_function_hoisted(
29132943
return_type: None,
29142944
type_parameters: None,
29152945
predicate: None,
2946+
component_declaration: false,
2947+
hook_declaration: false,
29162948
});
29172949

29182950
// Insert nodes. The TS code uses insertBefore for the gating result and optimized fn,

compiler/crates/react_compiler_ast/src/statements.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ use crate::common::BaseNode;
55
use crate::expressions::{Expression, Identifier};
66
use crate::patterns::PatternLike;
77

8+
fn is_false(v: &bool) -> bool {
9+
!v
10+
}
11+
812
#[derive(Debug, Clone, Serialize, Deserialize)]
913
#[serde(tag = "type")]
1014
pub enum Statement {
@@ -309,6 +313,20 @@ pub struct FunctionDeclaration {
309313
rename = "predicate"
310314
)]
311315
pub predicate: Option<Box<serde_json::Value>>,
316+
/// Set by the Hermes parser for Flow `component Foo(...) { ... }` syntax
317+
#[serde(
318+
default,
319+
skip_serializing_if = "is_false",
320+
rename = "__componentDeclaration"
321+
)]
322+
pub component_declaration: bool,
323+
/// Set by the Hermes parser for Flow `hook useFoo(...) { ... }` syntax
324+
#[serde(
325+
default,
326+
skip_serializing_if = "is_false",
327+
rename = "__hookDeclaration"
328+
)]
329+
pub hook_declaration: bool,
312330
}
313331

314332
#[derive(Debug, Clone, Serialize, Deserialize)]

0 commit comments

Comments
 (0)