Skip to content
Merged
1 change: 1 addition & 0 deletions crates/perry-hir/src/lower/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ impl LoweringContext {
type_param_scopes: Vec::new(),
type_param_constraints: Vec::new(),
native_instances: Vec::new(),
param_native_hints: HashMap::new(),
current_strict: false,
ui_widget_type_aliases: HashMap::new(),
current_class: None,
Expand Down
7 changes: 7 additions & 0 deletions crates/perry-hir/src/lower/lower_module_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,13 @@ pub fn lower_module_full(
// the member instead of silently lowering to 0.
pre_register_module_enums(ast_module, &mut ctx);

// Propagate a native host-handle's class across direct function-call
// boundaries (the `("ws","Client")` upgrade `wsId` handed to a helper) so
// `wsId.send(...)` inside the callee dispatches to the Client runtime
// instead of a silent generic no-op. Must run before any function body is
// lowered so `lower_fn_decl` can tag the receiving parameter.
pre_scan_cross_fn_native_params(ast_module, &mut ctx);

// JSX expressions lower directly to the built-in `jsx`/`jsxs` externs in
// `jsx.rs`. Do not synthesize a `react/jsx-runtime` import here: codegen
// routes those extern names to Perry's runtime adapter, and making the
Expand Down
14 changes: 14 additions & 0 deletions crates/perry-hir/src/lower/lowering_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,20 @@ pub struct LoweringContext {
/// Native class instances: local_name -> (module_name, class_name)
/// Tracks variables that hold instances of native module classes (e.g., EventEmitter)
pub(crate) native_instances: Vec<(String, String, String)>,
/// Cross-function native-instance hints: (fn_ident_span_lo, param_index) ->
/// (module_name, class_name). Populated by `pre_scan_cross_fn_native_params`
/// BEFORE any function body is lowered, so `lower_fn_decl` can tag an
/// otherwise-untyped parameter as a native instance when a known native
/// handle (e.g. the `("ws","Client")` upgrade `wsId`) is passed across the
/// call boundary into it. Without this, `wsId.send(...)` inside a helper
/// reached as `handleConnection(req, wsId)` lowers to a generic (silent
/// no-op) dispatch instead of `js_ws_send_client_i64`.
///
/// Keyed by the function declaration's identifier span (its `lo` byte
/// offset) — a stable AST identity — rather than its name, so a hint seeded
/// for one declaration never leaks onto an unrelated same-named (shadowed or
/// redeclared) function.
pub(crate) param_native_hints: HashMap<(u32, usize), (String, String)>,
/// True while lowering code governed by ECMAScript strict mode.
pub(crate) current_strict: bool,
/// #1483: type-only perry/ui widget import aliases — local_name ->
Expand Down
Loading
Loading