mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-06-28 04:01:33 +00:00
Implement the local JS snippets RFC
This commit is an implementation of [RFC 6] which enables crates to inline local JS snippets into the final output artifact of `wasm-bindgen`. This is accompanied with a few minor breaking changes which are intended to be relatively minor in practice: * The `module` attribute disallows paths starting with `./` and `../`. It requires paths starting with `/` to actually exist on the filesystem. * The `--browser` flag no longer emits bundler-compatible code, but rather emits an ES module that can be natively loaded into a browser. Otherwise be sure to check out [the RFC][RFC 6] for more details, and otherwise this should implement at least the MVP version of the RFC! Notably at this time JS snippets with `--nodejs` or `--no-modules` are not supported and will unconditionally generate an error. [RFC 6]: https://github.com/rustwasm/rfcs/pull/6 Closes #1311
This commit is contained in:
@ -9,6 +9,7 @@ documentation = "https://docs.rs/wasm-bindgen"
|
||||
description = """
|
||||
The part of the implementation of the `#[wasm_bindgen]` attribute that is not in the shared backend crate
|
||||
"""
|
||||
edition = '2018'
|
||||
|
||||
[features]
|
||||
spans = ["wasm-bindgen-backend/spans"]
|
||||
|
@ -12,8 +12,8 @@ extern crate wasm_bindgen_backend as backend;
|
||||
extern crate wasm_bindgen_shared as shared;
|
||||
|
||||
use backend::{Diagnostic, TryToTokens};
|
||||
pub use parser::BindgenAttrs;
|
||||
use parser::MacroParse;
|
||||
pub use crate::parser::BindgenAttrs;
|
||||
use crate::parser::MacroParse;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::ToTokens;
|
||||
use quote::TokenStreamExt;
|
||||
|
@ -33,6 +33,7 @@ macro_rules! attrgen {
|
||||
(static_method_of, StaticMethodOf(Span, Ident)),
|
||||
(js_namespace, JsNamespace(Span, Ident)),
|
||||
(module, Module(Span, String, Span)),
|
||||
(inline_js, InlineJs(Span, String, Span)),
|
||||
(getter, Getter(Span, Option<Ident>)),
|
||||
(setter, Setter(Span, Option<Ident>)),
|
||||
(indexing_getter, IndexingGetter(Span)),
|
||||
@ -339,12 +340,12 @@ impl<'a> ConvertToAst<BindgenAttrs> for &'a mut syn::ItemStruct {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ConvertToAst<(BindgenAttrs, &'a Option<String>)> for syn::ForeignItemFn {
|
||||
impl<'a> ConvertToAst<(BindgenAttrs, &'a ast::ImportModule)> for syn::ForeignItemFn {
|
||||
type Target = ast::ImportKind;
|
||||
|
||||
fn convert(
|
||||
self,
|
||||
(opts, module): (BindgenAttrs, &'a Option<String>),
|
||||
(opts, module): (BindgenAttrs, &'a ast::ImportModule),
|
||||
) -> Result<Self::Target, Diagnostic> {
|
||||
let wasm = function_from_decl(
|
||||
&self.ident,
|
||||
@ -543,12 +544,12 @@ impl ConvertToAst<BindgenAttrs> for syn::ForeignItemType {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ConvertToAst<(BindgenAttrs, &'a Option<String>)> for syn::ForeignItemStatic {
|
||||
impl<'a> ConvertToAst<(BindgenAttrs, &'a ast::ImportModule)> for syn::ForeignItemStatic {
|
||||
type Target = ast::ImportKind;
|
||||
|
||||
fn convert(
|
||||
self,
|
||||
(opts, module): (BindgenAttrs, &'a Option<String>),
|
||||
(opts, module): (BindgenAttrs, &'a ast::ImportModule),
|
||||
) -> Result<Self::Target, Diagnostic> {
|
||||
if self.mutability.is_some() {
|
||||
bail_span!(self.mutability, "cannot import mutable globals yet")
|
||||
@ -1084,8 +1085,27 @@ impl MacroParse<BindgenAttrs> for syn::ItemForeignMod {
|
||||
));
|
||||
}
|
||||
}
|
||||
for mut item in self.items.into_iter() {
|
||||
if let Err(e) = item.macro_parse(program, &opts) {
|
||||
let module = match opts.module() {
|
||||
Some((name, span)) => {
|
||||
if opts.inline_js().is_some() {
|
||||
let msg = "cannot specify both `module` and `inline_js`";
|
||||
errors.push(Diagnostic::span_error(span, msg));
|
||||
}
|
||||
ast::ImportModule::Named(name.to_string(), span)
|
||||
}
|
||||
None => {
|
||||
match opts.inline_js() {
|
||||
Some((js, span)) => {
|
||||
let i = program.inline_js.len();
|
||||
program.inline_js.push(js.to_string());
|
||||
ast::ImportModule::Inline(i, span)
|
||||
}
|
||||
None => ast::ImportModule::None
|
||||
}
|
||||
}
|
||||
};
|
||||
for item in self.items.into_iter() {
|
||||
if let Err(e) = item.macro_parse(program, module.clone()) {
|
||||
errors.push(e);
|
||||
}
|
||||
}
|
||||
@ -1095,11 +1115,11 @@ impl MacroParse<BindgenAttrs> for syn::ItemForeignMod {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> MacroParse<&'a BindgenAttrs> for syn::ForeignItem {
|
||||
impl MacroParse<ast::ImportModule> for syn::ForeignItem {
|
||||
fn macro_parse(
|
||||
mut self,
|
||||
program: &mut ast::Program,
|
||||
opts: &'a BindgenAttrs,
|
||||
module: ast::ImportModule,
|
||||
) -> Result<(), Diagnostic> {
|
||||
let item_opts = {
|
||||
let attrs = match self {
|
||||
@ -1110,11 +1130,7 @@ impl<'a> MacroParse<&'a BindgenAttrs> for syn::ForeignItem {
|
||||
};
|
||||
BindgenAttrs::find(attrs)?
|
||||
};
|
||||
let module = item_opts
|
||||
.module()
|
||||
.or(opts.module())
|
||||
.map(|s| s.0.to_string());
|
||||
let js_namespace = item_opts.js_namespace().or(opts.js_namespace()).cloned();
|
||||
let js_namespace = item_opts.js_namespace().cloned();
|
||||
let kind = match self {
|
||||
syn::ForeignItem::Fn(f) => f.convert((item_opts, &module))?,
|
||||
syn::ForeignItem::Type(t) => t.convert(item_opts)?,
|
||||
|
Reference in New Issue
Block a user