Reported in #1191 the fix requires us to get a bit creative I think. The
general gist is that a block like this:
#[wasm_bindgen]
impl Foo {
pub fn foo() {}
}
was previously expanded all in one go. Now, however, it's expanded into:
impl Foo {
#[__wasm_bindgen_class_marker(Foo = "Foo")]
pub fn foo() {}
}
// goop generated by orginal #[wasm_bindgen]
This method of expansion takes advantage of rustc's recursive expansion
feature. It also allows us to expand `impl` blocks and allow inner items
to not be fully expanded yet, such as still having `#[cfg]` attributes
(like in the original bug report).
We use theinternal `__wasm_bindgen_class_marker` to indicate that we're
parsing an `ImplItemMethod` unconditionally, and then generation
proceeds as usual. The only final catch is that when we're expanding in
an `impl` block we have to generate tokens for the `Program`
(wasm-bindgen injected goop like the custom section) inside the body
of the function itself instead of next to it. Otherwise we'd get syntax
errors inside of impl blocks!
Closes#1191
This commit adds a new attribute to `#[wasm_bindgen]`: `start`. The
`start` attribute can be used to indicate that a function should be
executed when the module is loaded, configuring the `start` function of
the wasm executable. While this doesn't necessarily literally configure
the `start` section, it does its best!
Only one crate in a crate graph may indicate `#[wasm_bindgen(start)]`,
so it's not recommended to be used in libraries but only end-user
applications. Currently this still must be used with the `crate-type =
["cdylib"]` annotation in `Cargo.toml`.
The implementation here is somewhat tricky because of the circular
dependency between our generated JS and the wasm file that we emit. This
circular dependency makes running initialization routines (like the
`start` shim) particularly fraught with complications because one may
need to run before the other but bundlers may not necessarily respect
it. Workarounds have been implemented for various emission strategies,
for example calling the start function directly after exports are wired
up with `--no-modules` and otherwise working around what appears to be
a Webpack bug with initializers running in a different order than we'd
like. In any case, this in theory doesn't show up to the end user!
Closes#74
This commit implements a system that will assert that all
`#[wasm_bindgen]` attributes are actually used during compilation. This
should help ensure that we don't sneak in stray attributes that don't
actually end up having any meaning, and hopefully make it a bit easier
to learn `#[wasm_bindgen]`!
If the setter doesn't start with `set_*` then we currently panic, but
panicking is bad! Instead let's thread through structured errors to make
sure they make their way to the top
This commit is a large-ish scale reorganization of our examples. The
main goal here is to have a dedicated section of the guide for example,
and all examples will be listed there. Each example's `README` is now
just boilerplate pointing at the guide along with a blurb about how to
run it.
Some examples like `math` and `smorgasboard` have been deleted as they
didn't really serve much purpose, and others like `closures` have been
rewritten with `web-sys` instead of hand-bound bindings.
Overall it's hoped that this puts us in a good and consistent state for
our examples, with all of them being described in the guide, excerpts
are in the guide, and they're all relatively idiomatically using
`web-sys`.
* Make ConvertToAst trait fallible
It's got some panics, and we'll be switching those to errors!
* First example of a diagnostic-driven error
Add a diagnostic-driven error `#[wasm_bindgen]` being attached to public
functions, and add some macros to boot to make it easier to generate errors!
* Result-ify `src/parser.rs`
This commit converts all of `src/parser.rs` away from panics to using
`Diagnostic` instead. Along the way this adds a test case per changed `panic!`,
ensuring that we don't regress in these areas!
This commit starts to add infrastructure for targeted diagnostics in the
`#[wasm_bindgen]` attribute, intended eventually at providing much better errors
as they'll be pointing to exactly the code in question rather than always to a
`#[wasm_bindgen]` attribute.
The general changes are are:
* A new `Diagnostic` error type is added to the backend. A `Diagnostic` is
created with a textual error or with a span, and it can also be created from a
list of diagnostics. A `Diagnostic` implements `ToTokens` which emits a bunch
of invocations of `compile_error!` that will cause rustc to later generate
errors.
* Fallible implementations of `ToTokens` have switched to using a new trait,
`TryToTokens`, which returns a `Result` to use `?` with.
* The `MacroParse` trait has changed to returning a `Result` to propagate errors
upwards.
* A new `ui-tests` crate was added which uses `compiletest_rs` to add UI tests.
These UI tests will verify that our output improves over time and does not
regress. This test suite is added to CI as a new builder as well.
* No `Diagnostic` instances are created just yet, everything continues to panic
and return `Ok`, with the one exception of the top-level invocations of
`syn::parse` which now create a `Diagnostic` and pass it along.
This commit does not immediately improve diagnostics but the intention is that
it is laying the groundwork for improving diagnostics over time. It should
ideally be much easier to contribute improved diagnostics after this commit!
cc #601