-
-
Notifications
You must be signed in to change notification settings - Fork 161
fix(hir): lower classes declared inside TypeScript namespaces completely (#10222) #10231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Fix incomplete lowering of classes declared inside TypeScript namespaces. Exported classes are published as namespace members after evaluating dynamic heritage, computed names, static fields and blocks, and legacy decorators in declaration order. Namespace-local class names are qualified internally so nested namespaces and repeated names remain distinct, while private classes stay available to sibling functions. This fixes missing namespace constructors, uninitialized static fields, and inherited static calls such as Effect's `Context.Service` factory used by OpenCode (#10107). | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -166,6 +166,22 @@ pub(crate) fn lower_ident_expr(ctx: &mut LoweringContext, ident: &ast::Ident) -> | |
| } | ||
| Ok(Expr::LocalGet(id)) | ||
| } else if let Some(id) = ctx.lookup_func(&name) { | ||
| // #10222: inside a namespace body an EXPORTED namespace function is | ||
| // emitted as a static method of the namespace class, not as a module | ||
| // function. Calls are redirected to `StaticMethodCall` (expr_call), but | ||
| // a VALUE reference (`const f = g`, `call(g)`, `Effect.gen(g)`) still | ||
| // lowered to `FuncRef(id)` — a closure over a function that has no | ||
| // module-function body — and calling it returned garbage. Read the | ||
| // published namespace member instead, exactly as `NS.g` resolves from | ||
| // outside the namespace; this also keeps `g === NS.g`. | ||
| if let Some(ref ns_name) = ctx.current_namespace { | ||
| if ctx.has_static_method(ns_name, &name) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Resolve enclosing namespace static methods for nested value references. When Resolve static methods through enclosing namespace scopes, or add a regression for 🤖 Prompt for AI Agents |
||
| return Ok(Expr::IndexGet { | ||
| object: Box::new(Expr::ClassRef(ns_name.clone())), | ||
| index: Box::new(Expr::String(name)), | ||
| }); | ||
| } | ||
| } | ||
| Ok(Expr::FuncRef(id)) | ||
| } else if ctx.lookup_native_module(&name).is_some() { | ||
| Ok(native_module_binding_value(ctx, &name)) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Correct the linked issue number.
The fragment and PR objective identify issue
#10222, but the final parenthetical references#10107. Change it to(#10222).🤖 Prompt for AI Agents