@@ -163,18 +163,11 @@ fn emit_js_setter(
163163}
164164
165165///|
166- /// Emit JS method - generates appropriate argument list and call.
167- /// `import_name` is the wasm import key (disambiguated, e.g. "fill_2"),
168- /// `original_name` is the actual JS method name (e.g. "fill").
169- fn emit_js_method (
170- import_name : String ,
171- original_name : String ,
166+ /// Build JS argument name and call-expression lists from WebIDL arguments.
167+ /// Returns (param_names, call_parts) where call_parts include spread for variadic args.
168+ fn build_js_args (
172169 args : Array [@parser .Argument ],
173- is_static : Bool ,
174- is_bigint ? : Bool = false ,
175- interface_name ? : String = "" ,
176- ) -> String {
177- // Build argument names list (params without spread, call_args with spread for variadic)
170+ ) -> (Array [String ], Array [String ]) {
178171 let arg_names : Array [String ] = []
179172 let call_parts : Array [String ] = []
180173 for arg in args {
@@ -186,16 +179,31 @@ fn emit_js_method(
186179 call_parts .push (name )
187180 }
188181 }
182+ (arg_names , call_parts )
183+ }
184+
185+ ///|
186+ /// Emit JS method - generates appropriate argument list and call.
187+ /// `import_name` is the wasm import key (disambiguated, e.g. "fill_2"),
188+ /// `original_name` is the actual JS method name (e.g. "fill").
189+ /// Also used for namespace methods (via is_static=true, interface_name=namespace).
190+ fn emit_js_method (
191+ import_name : String ,
192+ original_name : String ,
193+ args : Array [@parser .Argument ],
194+ is_static : Bool ,
195+ is_bigint ? : Bool = false ,
196+ interface_name ? : String = "" ,
197+ ) -> String {
198+ let (arg_names , call_parts ) = build_js_args (args )
189199 let comma_sep = ", "
190200 if is_static {
191- // Static method: no obj parameter, call on the class directly
192201 let params = arg_names .join (comma_sep )
193202 let call_args = call_parts .join (comma_sep )
194203 let expr = "\{ interface_name } .\{ original_name } (\{ call_args } )"
195204 let expr = if is_bigint { "BigInt(\{ expr } )" } else { expr }
196205 " \{ import_name } : (\{ params } ) => \{ expr } "
197206 } else {
198- // Instance method: obj is first parameter
199207 let args_str = arg_names .join (comma_sep )
200208 let params = if arg_names .length () > 0 { "obj, \{ args_str } " } else { "obj" }
201209 let call_args = call_parts .join (comma_sep )
@@ -213,17 +221,7 @@ fn emit_js_constructor(
213221 interface_name : String ,
214222 args : Array [@parser .Argument ],
215223) -> String {
216- let arg_names : Array [String ] = []
217- let call_parts : Array [String ] = []
218- for arg in args {
219- let name = js_safe (@type_mapping .safe_identifier (arg .name))
220- arg_names .push (name )
221- if arg .variadic {
222- call_parts .push ("...\{ name } " )
223- } else {
224- call_parts .push (name )
225- }
226- }
224+ let (arg_names , call_parts ) = build_js_args (args )
227225 let comma_sep = ", "
228226 let params = arg_names .join (comma_sep )
229227 let call_args = call_parts .join (comma_sep )
@@ -448,47 +446,9 @@ fn emit_js_callback_module(cb : @parser.CallbackFunctionDefinition) -> String {
448446}
449447
450448///|
451- /// Emit JS method for a namespace (static call with namespace prefix).
452- fn emit_js_namespace_method (
453- import_name : String ,
454- namespace_name : String ,
455- method_name : String ,
456- args : Array [@parser .Argument ],
457- is_bigint ? : Bool = false ,
458- ) -> String {
459- let arg_names : Array [String ] = []
460- let call_parts : Array [String ] = []
461- for arg in args {
462- let name = js_safe (@type_mapping .safe_identifier (arg .name))
463- arg_names .push (name )
464- if arg .variadic {
465- call_parts .push ("...\{ name } " )
466- } else {
467- call_parts .push (name )
468- }
469- }
470- let comma_sep = ", "
471- let params = arg_names .join (comma_sep )
472- let call_args = call_parts .join (comma_sep )
473- let expr = "\{ namespace_name } .\{ method_name } (\{ call_args } )"
474- let expr = if is_bigint { "BigInt(\{ expr } )" } else { expr }
475- " \{ import_name } : (\{ params } ) => \{ expr } "
476- }
477-
478- ///|
479- /// Emit JS getter for a namespace attribute.
480- fn emit_js_namespace_getter (
481- namespace_name : String ,
482- attr_name : String ,
483- is_bigint ? : Bool = false ,
484- ) -> String {
485- let expr = "\{ namespace_name } .\{ attr_name } "
486- let expr = if is_bigint { "BigInt(\{ expr } )" } else { expr }
487- " get_\{ attr_name } : () => \{ expr } "
488- }
489-
490- ///|
491- /// Emit a complete JS module for a namespace
449+ /// Emit a complete JS module for a namespace.
450+ /// Reuses emit_js_method/emit_js_getter with is_static=true since
451+ /// namespace members are just static calls on the global namespace object.
492452fn emit_js_namespace_module (
493453 ns : @partial_merged .PartialMergedNamespace ,
494454) -> String {
@@ -508,21 +468,23 @@ fn emit_js_namespace_module(
508468 used_method_names ,
509469 )
510470 entries .push (
511- emit_js_namespace_method (
471+ emit_js_method (
512472 import_name ,
513- ns .name,
514473 op .name,
515474 op .arguments,
475+ true ,
516476 is_bigint = is_bigint_type (op .return_type),
477+ interface_name = ns .name,
517478 ),
518479 )
519480 }
520481 Attribute (attr ) =>
521482 entries .push (
522- emit_js_namespace_getter (
523- ns .name,
483+ emit_js_getter (
524484 attr .name,
485+ is_static = true ,
525486 is_bigint = is_bigint_type (attr .type_),
487+ interface_name = ns .name,
526488 ),
527489 )
528490 Const (_ ) => continue // Constants don't need JS runtime entries
0 commit comments