diff --git a/compiler/crates/react_compiler/src/entrypoint/program.rs b/compiler/crates/react_compiler/src/entrypoint/program.rs index 66fe552dca7a..a0471b8ca265 100644 --- a/compiler/crates/react_compiler/src/entrypoint/program.rs +++ b/compiler/crates/react_compiler/src/entrypoint/program.rs @@ -904,7 +904,8 @@ fn calls_hooks_or_creates_jsx_in_pattern(pattern: &PatternLike) -> bool { | PatternLike::TSAsExpression(_) | PatternLike::TSSatisfiesExpression(_) | PatternLike::TSNonNullExpression(_) - | PatternLike::TSTypeAssertion(_) => false, + | PatternLike::TSTypeAssertion(_) + | PatternLike::TypeCastExpression(_) => false, } } @@ -923,7 +924,8 @@ fn is_valid_props_annotation(param: &PatternLike) -> bool { | PatternLike::TSAsExpression(_) | PatternLike::TSSatisfiesExpression(_) | PatternLike::TSNonNullExpression(_) - | PatternLike::TSTypeAssertion(_) => None, + | PatternLike::TSTypeAssertion(_) + | PatternLike::TypeCastExpression(_) => None, }; let annot = match type_annotation { Some(val) => val, diff --git a/compiler/crates/react_compiler/src/entrypoint/validate_source_locations.rs b/compiler/crates/react_compiler/src/entrypoint/validate_source_locations.rs index c785d7137457..a63d556ac97c 100644 --- a/compiler/crates/react_compiler/src/entrypoint/validate_source_locations.rs +++ b/compiler/crates/react_compiler/src/entrypoint/validate_source_locations.rs @@ -749,7 +749,8 @@ fn collect_original_pattern( PatternLike::TSAsExpression(_) | PatternLike::TSSatisfiesExpression(_) | PatternLike::TSNonNullExpression(_) - | PatternLike::TSTypeAssertion(_) => {} + | PatternLike::TSTypeAssertion(_) + | PatternLike::TypeCastExpression(_) => {} } } @@ -1243,7 +1244,8 @@ fn collect_generated_pattern( PatternLike::TSAsExpression(_) | PatternLike::TSSatisfiesExpression(_) | PatternLike::TSNonNullExpression(_) - | PatternLike::TSTypeAssertion(_) => {} + | PatternLike::TSTypeAssertion(_) + | PatternLike::TypeCastExpression(_) => {} } } diff --git a/compiler/crates/react_compiler_ast/src/patterns.rs b/compiler/crates/react_compiler_ast/src/patterns.rs index 48e199fd4473..1064ea7e6378 100644 --- a/compiler/crates/react_compiler_ast/src/patterns.rs +++ b/compiler/crates/react_compiler_ast/src/patterns.rs @@ -20,6 +20,8 @@ pub enum PatternLike { TSSatisfiesExpression(crate::expressions::TSSatisfiesExpression), TSNonNullExpression(crate::expressions::TSNonNullExpression), TSTypeAssertion(crate::expressions::TSTypeAssertion), + // Flow's analogue of the TS cast wrappers: `(expr: SomeType)`. + TypeCastExpression(crate::expressions::TypeCastExpression), } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/compiler/crates/react_compiler_ast/src/visitor.rs b/compiler/crates/react_compiler_ast/src/visitor.rs index 21dafa6dbfe4..496d93f49623 100644 --- a/compiler/crates/react_compiler_ast/src/visitor.rs +++ b/compiler/crates/react_compiler_ast/src/visitor.rs @@ -597,6 +597,9 @@ impl<'a> AstWalker<'a> { self.walk_expression(v, &node.expression) } PatternLike::TSTypeAssertion(node) => self.walk_expression(v, &node.expression), + PatternLike::TypeCastExpression(node) => { + self.walk_expression(v, &node.expression) + } } } diff --git a/compiler/crates/react_compiler_ast/tests/scope_resolution.rs b/compiler/crates/react_compiler_ast/tests/scope_resolution.rs index 6c5adbaaf1b3..0fcef0d35145 100644 --- a/compiler/crates/react_compiler_ast/tests/scope_resolution.rs +++ b/compiler/crates/react_compiler_ast/tests/scope_resolution.rs @@ -761,6 +761,10 @@ fn visit_pat(pat: &mut PatternLike, si: &ScopeInfo) { visit_expr(&mut e.expression, si); visit_json(&mut e.type_annotation, si); } + PatternLike::TypeCastExpression(e) => { + visit_expr(&mut e.expression, si); + visit_json(&mut e.type_annotation, si); + } } } diff --git a/compiler/crates/react_compiler_lowering/src/build_hir.rs b/compiler/crates/react_compiler_lowering/src/build_hir.rs index ac045b8c31c2..b7e5bcf85911 100644 --- a/compiler/crates/react_compiler_lowering/src/build_hir.rs +++ b/compiler/crates/react_compiler_lowering/src/build_hir.rs @@ -65,6 +65,7 @@ fn pattern_like_loc( PatternLike::TSSatisfiesExpression(p) => p.base.loc.clone(), PatternLike::TSNonNullExpression(p) => p.base.loc.clone(), PatternLike::TSTypeAssertion(p) => p.base.loc.clone(), + PatternLike::TypeCastExpression(p) => p.base.loc.clone(), } } @@ -2327,7 +2328,8 @@ fn pattern_declares_name(pattern: &react_compiler_ast::patterns::PatternLike, na PatternLike::TSAsExpression(_) | PatternLike::TSSatisfiesExpression(_) | PatternLike::TSNonNullExpression(_) - | PatternLike::TSTypeAssertion(_) => false, + | PatternLike::TSTypeAssertion(_) + | PatternLike::TypeCastExpression(_) => false, } } @@ -2533,7 +2535,8 @@ fn collect_binding_names_from_pattern( PatternLike::TSAsExpression(_) | PatternLike::TSSatisfiesExpression(_) | PatternLike::TSNonNullExpression(_) - | PatternLike::TSTypeAssertion(_) => {} + | PatternLike::TSTypeAssertion(_) + | PatternLike::TypeCastExpression(_) => {} } } @@ -5091,13 +5094,15 @@ fn lower_assignment( )?) } - // TS assignment-target wrappers (e.g. `(x as T) = ...`). The TS-faithful - // Todo is recorded once in `find_context_identifiers`; lowering itself - // never reaches a successful path for these, so do not record again. + // TS assignment-target wrappers (e.g. `(x as T) = ...`) and the Flow + // analogue `TypeCastExpression`. The TS-faithful Todo is recorded once + // in `find_context_identifiers`; lowering itself never reaches a + // successful path for these, so do not record again. PatternLike::TSAsExpression(_) | PatternLike::TSSatisfiesExpression(_) | PatternLike::TSNonNullExpression(_) - | PatternLike::TSTypeAssertion(_) => Ok(None), + | PatternLike::TSTypeAssertion(_) + | PatternLike::TypeCastExpression(_) => Ok(None), } } @@ -6037,7 +6042,8 @@ fn lower_inner( react_compiler_ast::patterns::PatternLike::TSAsExpression(_) | react_compiler_ast::patterns::PatternLike::TSSatisfiesExpression(_) | react_compiler_ast::patterns::PatternLike::TSNonNullExpression(_) - | react_compiler_ast::patterns::PatternLike::TSTypeAssertion(_) => {} + | react_compiler_ast::patterns::PatternLike::TSTypeAssertion(_) + | react_compiler_ast::patterns::PatternLike::TypeCastExpression(_) => {} } } diff --git a/compiler/crates/react_compiler_lowering/src/find_context_identifiers.rs b/compiler/crates/react_compiler_lowering/src/find_context_identifiers.rs index 9d7e34e24d79..fb54d7de4101 100644 --- a/compiler/crates/react_compiler_lowering/src/find_context_identifiers.rs +++ b/compiler/crates/react_compiler_lowering/src/find_context_identifiers.rs @@ -234,6 +234,13 @@ fn walk_lval_for_reassignment( convert_opt_loc(&node.base.loc), )?; } + PatternLike::TypeCastExpression(node) => { + record_unsupported_lval( + visitor.env, + "TypeCastExpression", + convert_opt_loc(&node.base.loc), + )?; + } } Ok(()) } diff --git a/compiler/crates/react_compiler_oxc/src/convert_ast.rs b/compiler/crates/react_compiler_oxc/src/convert_ast.rs index 37d56fec6b91..4b1b8a3e9f9c 100644 --- a/compiler/crates/react_compiler_oxc/src/convert_ast.rs +++ b/compiler/crates/react_compiler_oxc/src/convert_ast.rs @@ -2637,7 +2637,8 @@ impl<'a> ConvertCtx<'a> { PatternLike::TSAsExpression(_) | PatternLike::TSSatisfiesExpression(_) | PatternLike::TSNonNullExpression(_) - | PatternLike::TSTypeAssertion(_) => {} + | PatternLike::TSTypeAssertion(_) + | PatternLike::TypeCastExpression(_) => {} } } diff --git a/compiler/crates/react_compiler_oxc/src/convert_ast_reverse.rs b/compiler/crates/react_compiler_oxc/src/convert_ast_reverse.rs index 1a5de6bdb950..9f6ee0fd5da2 100644 --- a/compiler/crates/react_compiler_oxc/src/convert_ast_reverse.rs +++ b/compiler/crates/react_compiler_oxc/src/convert_ast_reverse.rs @@ -1156,7 +1156,8 @@ impl<'a> ReverseCtx<'a> { | PatternLike::TSAsExpression(_) | PatternLike::TSSatisfiesExpression(_) | PatternLike::TSNonNullExpression(_) - | PatternLike::TSTypeAssertion(_) => self + | PatternLike::TSTypeAssertion(_) + | PatternLike::TypeCastExpression(_) => self .builder .binding_pattern_binding_identifier(SPAN, self.atom("__member_pattern__")), } @@ -1285,7 +1286,8 @@ impl<'a> ReverseCtx<'a> { PatternLike::TSAsExpression(_) | PatternLike::TSSatisfiesExpression(_) | PatternLike::TSNonNullExpression(_) - | PatternLike::TSTypeAssertion(_) => self + | PatternLike::TSTypeAssertion(_) + | PatternLike::TypeCastExpression(_) => self .builder .simple_assignment_target_assignment_target_identifier( SPAN, diff --git a/compiler/crates/react_compiler_swc/src/convert_ast_reverse.rs b/compiler/crates/react_compiler_swc/src/convert_ast_reverse.rs index 56529a231df5..843e653b95a5 100644 --- a/compiler/crates/react_compiler_swc/src/convert_ast_reverse.rs +++ b/compiler/crates/react_compiler_swc/src/convert_ast_reverse.rs @@ -1577,6 +1577,9 @@ impl ReverseCtx { PatternLike::TSTypeAssertion(e) => { Pat::Expr(Box::new(self.convert_expression(&e.expression))) } + PatternLike::TypeCastExpression(e) => { + Pat::Expr(Box::new(self.convert_expression(&e.expression))) + } } } @@ -1624,9 +1627,10 @@ impl ReverseCtx { PatternLike::TSAsExpression(_) | PatternLike::TSSatisfiesExpression(_) | PatternLike::TSNonNullExpression(_) - | PatternLike::TSTypeAssertion(_) => AssignTarget::Simple(SimpleAssignTarget::Ident( - self.binding_ident("__unknown__", DUMMY_SP), - )), + | PatternLike::TSTypeAssertion(_) + | PatternLike::TypeCastExpression(_) => AssignTarget::Simple( + SimpleAssignTarget::Ident(self.binding_ident("__unknown__", DUMMY_SP)), + ), } }