Fix some situations with duplicate imports (#589)

* Fix importing the same identifier from two modules

This needed a fix in two locations:

* First the generated descriptor function needed its hash to include the module
  that the import came from in order to generate unique descriptor functions.
* Second the generation of the JS shim needed to handle duplicate identifiers in
  a more uniform fashion, ensuring that imported names didn't clash.

* Fix importing the same name in two modules

Previously two descriptor functions with duplicate symbols were emitted, and now
only one function is emitted by using a global table to keep track of state
across macro invocations.
This commit is contained in:
Alex Crichton
2018-07-30 10:50:43 -07:00
committed by GitHub
parent 7fda07f797
commit d876475ce3
8 changed files with 241 additions and 85 deletions

View File

@ -353,10 +353,10 @@ impl<'a> ConvertToAst<()> for &'a mut syn::ItemStruct {
}
}
impl ConvertToAst<BindgenAttrs> for syn::ForeignItemFn {
impl<'a> ConvertToAst<(BindgenAttrs, &'a Option<String>)> for syn::ForeignItemFn {
type Target = ast::ImportKind;
fn convert(self, opts: BindgenAttrs) -> Self::Target {
fn convert(self, (opts, module): (BindgenAttrs, &'a Option<String>)) -> Self::Target {
let js_name = opts.js_name().unwrap_or(&self.ident).clone();
let wasm = function_from_decl(&js_name, self.decl, self.attrs, self.vis, false).0;
let catch = opts.catch();
@ -458,7 +458,7 @@ impl ConvertToAst<BindgenAttrs> for syn::ForeignItemFn {
ast::ImportFunctionKind::Normal => (0, "n"),
ast::ImportFunctionKind::Method { ref class, .. } => (1, &class[..]),
};
let data = (ns, &self.ident);
let data = (ns, &self.ident, module);
format!("__wbg_{}_{}", js_name, ShortHash(data))
};
ast::ImportKind::Function(ast::ImportFunction {
@ -803,7 +803,7 @@ impl MacroParse<BindgenAttrs> for syn::ItemForeignMod {
.map(|s| s.to_string());
let js_namespace = item_opts.js_namespace().or(opts.js_namespace()).cloned();
let mut kind = match item {
syn::ForeignItem::Fn(f) => f.convert(item_opts),
syn::ForeignItem::Fn(f) => f.convert((item_opts, &module)),
syn::ForeignItem::Type(t) => t.convert(()),
syn::ForeignItem::Static(s) => s.convert(item_opts),
_ => panic!("only foreign functions/types allowed for now"),