Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a raw_module attribute to #[wasm_bindgen] #1353

Merged
merged 1 commit into from
Mar 18, 2019
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 5 additions & 0 deletions crates/backend/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ pub struct Import {
pub enum ImportModule {
None,
Named(String, Span),
RawNamed(String, Span),
Inline(usize, Span),
}

Expand All @@ -96,6 +97,10 @@ impl Hash for ImportModule {
2u8.hash(h);
idx.hash(h);
}
ImportModule::RawNamed(name, _) => {
3u8.hash(h);
name.hash(h);
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/backend/src/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ fn shared_import<'a>(i: &'a ast::Import, intern: &'a Interner) -> Result<Import<
ast::ImportModule::Named(m, span) => {
ImportModule::Named(intern.resolve_import_module(m, *span)?)
}
ast::ImportModule::RawNamed(m, _span) => ImportModule::RawNamed(intern.intern_str(m)),
ast::ImportModule::Inline(idx, _) => ImportModule::Inline(*idx as u32),
ast::ImportModule::None => ImportModule::None,
},
Expand Down
13 changes: 8 additions & 5 deletions crates/cli-support/src/js/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2836,6 +2836,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
// not sure how to import them.
let is_local_snippet = match import.module {
decode::ImportModule::Named(s) => self.cx.local_modules.contains_key(s),
decode::ImportModule::RawNamed(_) => false,
decode::ImportModule::Inline(_) => true,
decode::ImportModule::None => false,
};
Expand Down Expand Up @@ -2921,11 +2922,13 @@ impl<'a, 'b> SubContext<'a, 'b> {
name,
field,
},
decode::ImportModule::Named(module) => Import::Module {
module,
name,
field,
},
decode::ImportModule::Named(module) | decode::ImportModule::RawNamed(module) => {
Import::Module {
module,
name,
field,
}
}
decode::ImportModule::Inline(idx) => {
let offset = *self
.cx
Expand Down
37 changes: 21 additions & 16 deletions crates/macro-support/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ macro_rules! attrgen {
(static_method_of, StaticMethodOf(Span, Ident)),
(js_namespace, JsNamespace(Span, Ident)),
(module, Module(Span, String, Span)),
(raw_module, RawModule(Span, String, Span)),
(inline_js, InlineJs(Span, String, Span)),
(getter, Getter(Span, Option<Ident>)),
(setter, Setter(Span, Option<Ident>)),
Expand Down Expand Up @@ -1085,24 +1086,28 @@ impl MacroParse<BindgenAttrs> for syn::ItemForeignMod {
));
}
}
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)
let module = if let Some((name, span)) = opts.module() {
if opts.inline_js().is_some() {
let msg = "cannot specify both `module` and `inline_js`";
errors.push(Diagnostic::span_error(span, msg));
}
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
}
if opts.raw_module().is_some() {
let msg = "cannot specify both `module` and `raw_module`";
errors.push(Diagnostic::span_error(span, msg));
}
ast::ImportModule::Named(name.to_string(), span)
} else if let Some((name, span)) = opts.raw_module() {
if opts.inline_js().is_some() {
let msg = "cannot specify both `raw_module` and `inline_js`";
errors.push(Diagnostic::span_error(span, msg));
}
ast::ImportModule::RawNamed(name.to_string(), span)
} else if let Some((js, span)) = opts.inline_js() {
let i = program.inline_js.len();
program.inline_js.push(js.to_string());
ast::ImportModule::Inline(i, span)
} else {
ast::ImportModule::None
};
for item in self.items.into_iter() {
if let Err(e) = item.macro_parse(program, module.clone()) {
Expand Down
1 change: 1 addition & 0 deletions crates/shared/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ macro_rules! shared_api {
enum ImportModule<'a> {
None,
Named(&'a str),
RawNamed(&'a str),
Inline(u32),
}

Expand Down
1 change: 1 addition & 0 deletions guide/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
- [`js_namespace`](./reference/attributes/on-js-imports/js_namespace.md)
- [`method`](./reference/attributes/on-js-imports/method.md)
- [`module = "blah"`](./reference/attributes/on-js-imports/module.md)
- [`raw_module = "blah"`](./reference/attributes/on-js-imports/raw_module.md)
- [`static_method_of = Blah`](./reference/attributes/on-js-imports/static_method_of.md)
- [`structural`](./reference/attributes/on-js-imports/structural.md)
- [`variadic`](./reference/attributes/on-js-imports/variadic.md)
Expand Down
5 changes: 5 additions & 0 deletions guide/src/reference/attributes/on-js-imports/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,8 @@ generates JavaScript import glue like:
```js
let illmatic = this.illmatic;
```

Note that if the string specified with `module` starts with `./`, `../`, or `/`
then it's interpreted as a path to a [local JS snippet](../../js-snippets.html).
If this doesn't work for your use case you might be interested in the
[`raw_module` attribute](raw_module.html)
19 changes: 19 additions & 0 deletions guide/src/reference/attributes/on-js-imports/raw_module.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# `raw_module = "blah"`

This attribute performs exactly the same purpose as the [`module`
attribute](module.html) on JS imports, but it does not attempt to interpret
paths starting with `./`, `../`, or `/` as JS snippets. For example:

```rust
#[wasm_bindgen(raw_module = "./some/js/file.js")]
extern "C" {
fn the_function();
}
```

Note that if you use this attribute with a relative or absolute path, it's
likely up to the final bundler or project to assign meaning to that path. This
typically means that the JS file or module will be resolved relative to the
final location of the wasm file itself. That means that `raw_module` is likely
unsuitable for libraries on crates.io, but may be usable within end-user
applications.