Allow js_name attribute to accept a string

This commit is contained in:
Michael Hoffmann 2018-08-05 00:17:30 +02:00 committed by Alex Crichton
parent 63ee9a024d
commit 21c36d3902
4 changed files with 114 additions and 18 deletions

View File

@ -116,7 +116,7 @@ pub struct ImportStatic {
pub ty: syn::Type,
pub shim: Ident,
pub rust_name: Ident,
pub js_name: Ident,
pub js_name: String,
}
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
@ -143,7 +143,7 @@ pub struct ImportEnum {
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
pub struct Function {
pub name: Ident,
pub name: String,
pub arguments: Vec<syn::ArgCaptured>,
pub ret: Option<syn::Type>,
pub rust_attrs: Vec<syn::Attribute>,

View File

@ -149,11 +149,11 @@ impl BindgenAttrs {
}
/// Get the first js_name attribute
fn js_name(&self) -> Option<&Ident> {
fn js_name(&self) -> Option<&str> {
self.attrs
.iter()
.filter_map(|a| match a {
BindgenAttr::JsName(s) => Some(s),
BindgenAttr::JsName(s) => Some(&s[..]),
_ => None,
})
.next()
@ -200,7 +200,7 @@ pub enum BindgenAttr {
Setter(Option<Ident>),
Structural,
Readonly,
JsName(Ident),
JsName(String),
JsClass(String),
}
@ -267,8 +267,12 @@ impl syn::synom::Synom for BindgenAttr {
do_parse!(
call!(term, "js_name") >>
punct!(=) >>
ns: call!(term2ident) >>
(ns)
name: alt!(
syn!(syn::LitStr) => { |s| s.value() }
|
call!(term2ident) => { |s| s.to_string() }
) >>
(name)
)=> { BindgenAttr::JsName }
|
do_parse!(
@ -365,9 +369,10 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a Option<String>)> for syn::ForeignItemFn
fn convert(self, (opts, module): (BindgenAttrs, &'a Option<String>))
-> Result<Self::Target, Diagnostic>
{
let js_name = opts.js_name().unwrap_or(&self.ident).clone();
let default_name = self.ident.to_string();
let js_name = opts.js_name().unwrap_or(&default_name);
let wasm = function_from_decl(
&js_name,
js_name,
self.decl.clone(),
self.attrs.clone(),
self.vis.clone(),
@ -475,7 +480,9 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a Option<String>)> for syn::ForeignItemFn
ast::ImportFunctionKind::Method { ref class, .. } => (1, &class[..]),
};
let data = (ns, &self.ident, module);
format!("__wbg_{}_{}", js_name, ShortHash(data))
format!("__wbg_{}_{}",
js_name.chars().filter(|c| c.is_ascii_alphanumeric()).collect::<String>(),
ShortHash(data))
};
Ok(ast::ImportKind::Function(ast::ImportFunction {
function: wasm,
@ -510,13 +517,16 @@ impl ConvertToAst<BindgenAttrs> for syn::ForeignItemStatic {
if self.mutability.is_some() {
bail_span!(self.mutability, "cannot import mutable globals yet")
}
let js_name = opts.js_name().unwrap_or(&self.ident);
let shim = format!("__wbg_static_accessor_{}_{}", js_name, self.ident);
let default_name = self.ident.to_string();
let js_name = opts.js_name().unwrap_or(&default_name);
let shim = format!("__wbg_static_accessor_{}_{}",
js_name.chars().filter(|c| c.is_ascii_alphanumeric()).collect::<String>(),
self.ident);
Ok(ast::ImportKind::Static(ast::ImportStatic {
ty: *self.ty,
vis: self.vis,
rust_name: self.ident.clone(),
js_name: js_name.clone(),
js_name: js_name.to_string(),
shim: Ident::new(&shim, Span::call_site()),
}))
}
@ -537,14 +547,15 @@ impl ConvertToAst<BindgenAttrs> for syn::ItemFn {
bail_span!(self.unsafety, "can only #[wasm_bindgen] safe functions");
}
let name = attrs.js_name().unwrap_or(&self.ident);
let default_name = self.ident.to_string();
let name = attrs.js_name().unwrap_or(&default_name);
Ok(function_from_decl(name, self.decl, self.attrs, self.vis, false, None)?.0)
}
}
/// Construct a function (and gets the self type if appropriate) for our AST from a syn function.
fn function_from_decl(
name: &Ident,
name: &str,
decl: Box<syn::FnDecl>,
attrs: Vec<syn::Attribute>,
vis: syn::Visibility,
@ -619,7 +630,7 @@ fn function_from_decl(
Ok((
ast::Function {
name: name.clone(),
name: name.to_string(),
arguments,
ret,
rust_vis: vis,
@ -782,7 +793,7 @@ impl<'a, 'b> MacroParse<()> for (&'a Ident, &'b mut syn::ImplItem) {
};
let (function, method_self) = function_from_decl(
opts.js_name().unwrap_or(&method.sig.ident),
opts.js_name().unwrap_or(&method.sig.ident.to_string()),
Box::new(method.sig.decl.clone()),
method.attrs.clone(),
method.vis.clone(),

View File

@ -563,7 +563,7 @@ impl<'a> FirstPassRecord<'a> {
name.to_snake_case()
}
);
let name = raw_ident(name);
let name = name.to_string();
let arguments = self.webidl_arguments_to_syn_arg_captured(arguments.into_iter(), &kind)?;

View File

@ -36,6 +36,91 @@ fn unused_imports_not_generated() {
assert!(!contents.contains("foo"), "found `foo` in {}", contents);
}
#[test]
fn rename_with_string() {
project()
.file(
"src/lib.rs",
r#"
#![feature(use_extern_macros)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")]
extern {
#[wasm_bindgen(js_name = "baz$")]
fn foo();
}
#[wasm_bindgen]
pub fn run() {
foo();
}
"#,
)
.file(
"test.js",
r#"
import * as wasm from "./out";
import * as assert from "assert";
let called = false;
export function baz$() {
called = true;
}
export function test() {
wasm.run();
assert.strictEqual(called, true);
}
"#,
)
.test();
}
#[test]
fn rename_static_with_string() {
project()
.debug(false)
.file(
"src/lib.rs",
r#"
#![feature(use_extern_macros)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "./test")]
extern {
#[wasm_bindgen(js_name = "$foo")]
static FOO: JsValue;
}
#[wasm_bindgen]
pub fn run() {
assert_eq!(FOO.as_f64(), Some(1.0));
}
"#,
)
.file(
"test.js",
r#"
import { run } from "./out";
export const $foo = 1.0;
export function test() {
run();
}
"#,
)
.test();
}
#[test]
fn versions() {
project()