-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
WebIDL binding generator #42
Comments
cc @spastorino, I think you mentioned you were interested in this! |
@alexcrichton This seems like a cool idea, but I wonder if this crate is the right place for this. I would think that this crate would offer the minimal amount of wrapping between JS and Rust/Wasm. Bindings to specific browser APIs would then be built on top of this in another crate. Just my gut feeling! |
Oh sorry yeah to be clear I don't think that these bindings will live in the extern crate webapi;
use webabi::alert;
use webabi::console;
fn foo() {
console::log("foo");
alert("bar");
} I was thinking that this repo would be a good place for the development though as it's pretty coupled to the features of |
FWIW, these look to be two versions of the same crate. The |
So, ideally, one would be able to pull in just the webidl APIs they require, and not everything all at once. Have you thought at all about how to do this @alexcrichton ? My first thought is that there would be different crates for different classes, but there are definitely circular dependencies here. If I depend on a crate with |
This seems to hold true from a couple initial experiences! 🎉 |
Oh yeah for sure I was thinking there's be a suite of crates but it's true we'd have to put anything with circular dependencies in the same crate. That being said like the |
The generators I implemented here are almost entirely independent of WebGL (ie. it would be very easy to re-purpose for other APIs) and are also designed to support multiple back-ends (although only a stdweb-based back-end is implemented right now). |
@alexcrichton I did some similar work a while back and one of the things I found is that the WebIDL files aren't always representative of the real web. In fact I know that Microsoft went to huge pains to get the definition files in TypeScript to match reality rather than the spec. They also continue to update monthly. It might be better to write a TypeScript definition parser and use what is here: https://github.com/Microsoft/TypeScript/tree/master/src/lib I would be very excited to help work on this. I am already using this project and loving it. I am also a huge fan of TypeScript. There are also already many JS modules with either definitions built in or in DefinitelyTyped so it would be amazing if Rust users could tap into that. I think it makes a lot of sense to think of things in a Rust <-> TypeScript kind of way given Rust is statically typed and that TypeScript is transparently compatible with JavaScript. |
@corbinu oh fascinating! That actually would sync up well with https://github.com/alexcrichton/wasm-bindgen/issues/18 and otherwise make it easy to import any library rather than just the native WebIDL ones. I think regardless of whether we end up using a WebIDL-based generation process it'd be fantastic to have a Typescript one as well. If you'd be excited to help out on this I'd be excited to help you :). I think the basic goal for something like this would be to have a tool that slurps up typescript (and maybe some configuration) and spits out |
@alexcrichton For sure sorry wasn't trying to rain on this effort. Just have seen it tried before. Yes for sure thats exactly what I am thinking. I will move this over to #18. |
Oh no worries at all! I just figured it'd be good to do both, but I agree with your reasoning that it may be best to start with a Typescript -> Rust generator as that'll work for any library, not just Web ones! |
For sure I once it that is working we could possibly use dom.generated.d.ts to enhance the stdweb also. Maybe we should have a separate issue just called something like "Two way type interop?" that would cover everything. |
Sounds good to me! |
Certain WebIDL capabilities such as [NewObject] are not replicated in TypeScript declarations- and some of these attributes carry information that may present an opportunity for improved binding typing in strict languages such as Rust. Is it possible that similar attributes could be represented in TypeScript via decorative wrappers/aliases? type NewObject<T> = T;
type Nat = number;
class NatNumberedObject {
constructor(number: Nat);
number: Nat;
}
function createNatNumberedObject(number: Nat): NewObject<NumberedObject> {
return NatNumberedObject(number);
} The above definitions could provide |
@Dessix fwiw I definitely think we will want some form of attributes or tweaking parsed files as I imagine we probably won't be able to use everything literally as-is, but hopefully lots can be! |
I have also developed a library weedle to parse WebIDL definitions which I made just for the sake of generating these bindings (and a learning exercise at parsers). I am also thinking to try to build binding generator & I have a question about it. How do you think this approach would be? Other ideas? |
Oh nice @csharad! I think for a first pass I'd be fine with avoiding exposing exceptions and we could add |
That sound fine right now. But how would you approach catching exceptions in the future? A stricter typed exception (which the idl don't define) or a catch all exception object? |
Currently there's not a great implementation of inheritance or anything like that with wasm-bindgen, so the only way to catch an exception is to have the |
there is also |
@sendilkumarn Yes, there is. Difference between the two would be pretty much none (other than weedle using nom). Also, I developed it just for the sake of learning. |
While experimenting with webidl binding generation, I came across two problems & a suggestion:
Checking Importing the bindings lib without using any functionality causes problems on the browser, as in debug mode compiler does not remove unused bindings making the generated bindings unusable. One way would be to make sure bindgen selects the appropriate type on that particular browser.
We could pass additional metadata to type statements.
Otherwise, I could always create |
@csharad oh man this looks like some awesome progress! I'll try an answer some questions
It's true yeah that
Aha I'm not too too surprised! One option here is to use the
Aha a good point! Want to open a dedicated issue for this? |
Yeah, not working in the macro. Created an issue at #193.
Yeah, It worked! Though I'll have to use it everywhere 'cause I don't have a way to know whats what.
Opened at #194 |
@csharad oh it's actually somewhat critical that we don't use I think it's fine to use that in a few odd places but we predominantly do not want to use JS shims via |
@csharad can you share your fork / repo / location of where you're working on this? |
I've just landed the |
This is now more-or-less done! In the sense that this issue itself isn't too useful any more and further work items are tracked at
frontend:webidl
|
The
#[wasm_bindgen]
attribute is pretty feature-ful right now and notably allows importing a class from JS and using it in Rust. Unfortunately though it's a pretty manual process to write this out for web apis, so it'd be great to do this automatically!Thankfully there's this awesome thing called WebIDL which is a programmatic description of APIs available on the web. There's even two parsers on crates.io for WebIDL!
I think it'd be pretty neat if a WebIDL generator were added to this repo to automatically generate
#[wasm_bindgen]
decorated bindings. In that sense I'd imagine that we could auto-generate a bunch of*-sys
crates which provide bindings for all the web-related functionality JS has to offer. At that point working with the DOM or other web APIs should be as simple asextern crate foo
!An issue like this certainly has a lot of design questions to explore as I'm sure WebIDL is far richer than what
#[wasm_bindgen]
supports today. We'll need to add features to#[wasm_bindgen]
along the way as well as probably developing idioms to map JS to Rust, but I think it'd be great to at least start out with some simple APIs to see how it goes.For example the README has an example:
but it'd be awesome if we could automatically generate this binding from a WebIDL file and place it in a crate to use. Once we have the "hello world" variants working we should hopefully have enough information to inform the next phase of design questions.
The text was updated successfully, but these errors were encountered: