Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 27 additions & 8 deletions crates/spidermonkey-embedding-splicer/src/bindgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,12 @@ pub fn componentize_bindgen(
// consolidate import specifiers and generate wrappers
// we do this separately because function index order matters
let mut import_bindings = Vec::new();
for (_, item) in bindgen.imports.iter() {
for (specifier, item) in bindgen.imports.iter() {
// this import binding order matters
import_bindings.push(binding_name(
import_bindings.push(binding_name_import(
&item.resource.func_name(&item.name),
&item.iface_name,
specifier,
));
}

Expand Down Expand Up @@ -204,7 +205,8 @@ pub fn componentize_bindgen(
let item = items.first().unwrap();
if let Some(resource) = resource {
let export_name = resource.to_upper_camel_case();
let binding_name = binding_name(&export_name, &item.iface_name);
let binding_name =
binding_name_import(&export_name, &item.iface_name, &item.binding_name);
if item.iface {
specifier_list.push(format!("{export_name}: import_{binding_name}"));
} else {
Expand All @@ -213,13 +215,12 @@ pub fn componentize_bindgen(
} else {
for BindingItem {
iface,
iface_name,
name,
binding_name,
..
} in items
{
let export_name = name.to_lower_camel_case();
let binding_name = binding_name(&export_name, iface_name);
if *iface {
specifier_list.push(format!("{export_name}: import_{binding_name}"));
} else {
Expand Down Expand Up @@ -654,11 +655,11 @@ impl JsBindgen<'_> {
let fn_name = func.item_name();
let fn_camel_name = fn_name.to_lower_camel_case();

use binding_name as binding_name_fn;
use binding_name_import as binding_name_fn;
Comment thread
vados-cosmonic marked this conversation as resolved.
Outdated

let (binding_name, resource) = match &func.kind {
FunctionKind::Freestanding => {
let binding_name = binding_name(&fn_camel_name, &iface_name);
let binding_name = binding_name_import(&fn_camel_name, &iface_name, &import_name);

uwrite!(self.src, "\nfunction import_{binding_name}");

Expand Down Expand Up @@ -702,7 +703,11 @@ impl JsBindgen<'_> {
func.params.len(),
&format!(
"$import_{}",
binding_name_fn(&resource.func_name(fn_name), &iface_name)
binding_name_fn(
&resource.func_name(fn_name),
&iface_name,
import_name.as_str()
)
),
StringEncoding::UTF8,
func,
Expand Down Expand Up @@ -1294,6 +1299,20 @@ fn binding_name(func_name: &str, iface_name: &Option<String>) -> String {
}
}

fn binding_name_import(func_name: &str, iface_name: &Option<String>, import_name: &str) -> String {
Comment thread
vados-cosmonic marked this conversation as resolved.
Outdated
if import_name != "<<INVALID>>" {
let valid_import = import_name
.chars()
.map(|c| if c.is_alphanumeric() { c } else { '_' })
.collect::<String>();
format!("{valid_import}${func_name}")
} else if let Some(iface_name) = iface_name {
format!("{iface_name}${func_name}")
} else {
func_name.to_string()
}
Comment thread
vados-cosmonic marked this conversation as resolved.
}

/// Extract success and error types from a given optional type, if it is a Result
pub fn get_result_types(
resolve: &Resolve,
Expand Down
2 changes: 2 additions & 0 deletions test/bindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ suite('Bindings', async () => {
if (impt.startsWith('wasi:')) continue;
if (impt.startsWith('[')) impt = impt.slice(impt.indexOf(']') + 1);
let importName = impt.split('/').pop();
if (name === 'import-duplicated-interface')
importName = impt.replace('/', '-').replace(':', '-');
Comment thread
vados-cosmonic marked this conversation as resolved.
Outdated
if (importName === 'test') importName = 'imports';
map[impt] = `../../cases/${name}/${importName}.js`;
}
Expand Down
3 changes: 3 additions & 0 deletions test/cases/import-duplicated-interface/local-hello-hello.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function hello(name) {
return `Hello 1.0.0, ${name}`
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export function hello(name) {
if (name) {
return `Hello 2.0.0, ${name}`
} else {
return undefined
}
}
14 changes: 14 additions & 0 deletions test/cases/import-duplicated-interface/source.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { hello as hello1 } from 'local:hello/hello';
import { hello as hello2 } from 'local:hello-second/hello';

export const exports = {
hello(str) {
if (str === 'hello') {
return `world ${str} (${hello1('world')})`;
}
if (str === 'hello-second') {
return `world ${str} (${hello2('world')})`;
}
return `world unknown ${str}`;
},
};
13 changes: 13 additions & 0 deletions test/cases/import-duplicated-interface/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { strictEqual } from 'node:assert';

export function test(instance) {
strictEqual(
instance.exports.hello('hello'),
'world hello (Hello 1.0.0, world)'
);
strictEqual(
instance.exports.hello('hello-second'),
'world hello-second (Hello 2.0.0, world)'
);
strictEqual(instance.exports.hello('unknown'), 'world unknown unknown');
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package local:hello-second;

interface hello {
hello: func(name: option<string>) -> option<string>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package local:hello;

interface hello {
hello: func(name: string) -> string;
}
10 changes: 10 additions & 0 deletions test/cases/import-duplicated-interface/wit/world.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package test:test;

world hello {
import local:hello/hello;
import local:hello-second/hello;

export exports: interface {
hello: func(name: string) -> string;
}
}