mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2024-11-28 14:27:36 +03:00
webidl: add support for constructors
This commit is contained in:
parent
400015a061
commit
c65cb51fba
@ -164,6 +164,10 @@ impl WebidlParse<()> for webidl::ast::NonPartialInterface {
|
||||
}),
|
||||
});
|
||||
|
||||
for extended_attribute in &self.extended_attributes {
|
||||
extended_attribute.webidl_parse(program, self)?;
|
||||
}
|
||||
|
||||
for member in &self.members {
|
||||
member.webidl_parse(program, &self.name)?;
|
||||
}
|
||||
@ -172,6 +176,61 @@ impl WebidlParse<()> for webidl::ast::NonPartialInterface {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> WebidlParse<&'a webidl::ast::NonPartialInterface> for webidl::ast::ExtendedAttribute {
|
||||
fn webidl_parse(
|
||||
&self,
|
||||
program: &mut backend::ast::Program,
|
||||
interface: &'a webidl::ast::NonPartialInterface,
|
||||
) -> Result<()> {
|
||||
let mut add_constructor = |arguments: &[webidl::ast::Argument]| {
|
||||
let self_ty = ident_ty(rust_ident(&interface.name));
|
||||
let kind = backend::ast::ImportFunctionKind::JsConstructor {
|
||||
class: interface.name.to_string(),
|
||||
ty: self_ty.clone(),
|
||||
};
|
||||
create_function(
|
||||
"new",
|
||||
arguments
|
||||
.iter()
|
||||
.map(|arg| (&*arg.name, &*arg.type_, arg.variadic)),
|
||||
kind,
|
||||
Some(self_ty),
|
||||
vec![backend::ast::BindgenAttr::Constructor],
|
||||
).map(|function| {
|
||||
program.imports.push(backend::ast::Import {
|
||||
module: None,
|
||||
version: None,
|
||||
js_namespace: None,
|
||||
kind: backend::ast::ImportKind::Function(function),
|
||||
})
|
||||
})
|
||||
};
|
||||
|
||||
match self {
|
||||
webidl::ast::ExtendedAttribute::ArgumentList(
|
||||
webidl::ast::ArgumentListExtendedAttribute { arguments, name },
|
||||
) if name == "Constructor" =>
|
||||
{
|
||||
add_constructor(&*arguments);
|
||||
}
|
||||
webidl::ast::ExtendedAttribute::NoArguments(webidl::ast::Other::Identifier(name))
|
||||
if name == "Constructor" =>
|
||||
{
|
||||
add_constructor(&[] as &[_]);
|
||||
}
|
||||
webidl::ast::ExtendedAttribute::ArgumentList(_)
|
||||
| webidl::ast::ExtendedAttribute::Identifier(_)
|
||||
| webidl::ast::ExtendedAttribute::IdentifierList(_)
|
||||
| webidl::ast::ExtendedAttribute::NamedArgumentList(_)
|
||||
| webidl::ast::ExtendedAttribute::NoArguments(_) => {
|
||||
warn!("Unsupported WebIDL extended attribute: {:?}", self);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> WebidlParse<&'a str> for webidl::ast::InterfaceMember {
|
||||
fn webidl_parse(&self, program: &mut backend::ast::Program, self_name: &'a str) -> Result<()> {
|
||||
match *self {
|
||||
|
File diff suppressed because one or more lines are too long
9
crates/webidl/tests/fixtures/Event.webidl
vendored
9
crates/webidl/tests/fixtures/Event.webidl
vendored
@ -13,6 +13,9 @@
|
||||
// TODO: don't include this here, use Performance.webidl instead
|
||||
typedef double DOMHighResTimeStamp;
|
||||
|
||||
// TODO: remove this when dicts are resolved
|
||||
typedef boolean EventInit;
|
||||
|
||||
[Constructor(DOMString type, optional EventInit eventInitDict),
|
||||
Exposed=(Window,Worker,System), ProbablyShortLivingWrapper]
|
||||
interface Event {
|
||||
@ -60,3 +63,9 @@ interface Event {
|
||||
optional boolean cancelable = false);
|
||||
attribute boolean cancelBubble;
|
||||
};
|
||||
|
||||
dictionary EventInit {
|
||||
boolean bubbles = false;
|
||||
boolean cancelable = false;
|
||||
boolean composed = false;
|
||||
};
|
||||
|
@ -1,15 +1,15 @@
|
||||
use super::project;
|
||||
|
||||
#[test]
|
||||
fn webidl() {
|
||||
fn method() {
|
||||
project()
|
||||
.file(
|
||||
"foo.webidl",
|
||||
r#"
|
||||
[Constructor(float value)]
|
||||
[Constructor(double value)]
|
||||
interface Foo {
|
||||
[Pure]
|
||||
boolean my_cmp(Foo bar);
|
||||
boolean myCmp(Foo bar);
|
||||
};
|
||||
"#,
|
||||
)
|
||||
@ -17,11 +17,10 @@ fn webidl() {
|
||||
"foo.ts",
|
||||
r#"
|
||||
export class Foo {
|
||||
value: number;
|
||||
constructor(value: number) {
|
||||
constructor(private value: number) {
|
||||
this.value = value;
|
||||
}
|
||||
my_cmp(other: Foo): boolean {
|
||||
myCmp(other: Foo): boolean {
|
||||
return this.value === other.value;
|
||||
}
|
||||
}
|
||||
@ -38,26 +37,82 @@ fn webidl() {
|
||||
|
||||
pub mod foo;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn call_my_cmp(first: &foo::Foo, second: foo::Foo) -> bool {
|
||||
first.my_cmp(second)
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"test.ts",
|
||||
r#"
|
||||
import * as assert from 'assert';
|
||||
import * as wasm from './out';
|
||||
import {Foo} from './foo';
|
||||
use foo::Foo;
|
||||
|
||||
export function test() {
|
||||
const pi = new Foo(3.14159);
|
||||
const e = new Foo(2.71828);
|
||||
assert.strictEqual(wasm.call_my_cmp(pi, pi), true);
|
||||
assert.strictEqual(wasm.call_my_cmp(pi, e), false);
|
||||
assert.strictEqual(wasm.call_my_cmp(e, pi), false);
|
||||
assert.strictEqual(wasm.call_my_cmp(e, e), true);
|
||||
#[wasm_bindgen]
|
||||
pub fn test() {
|
||||
let pi = Foo::new(3.14159);
|
||||
let e = Foo::new(2.71828);
|
||||
let tmp = pi.my_cmp(Foo::new(3.14159));
|
||||
assert!(tmp);
|
||||
let tmp =!pi.my_cmp(Foo::new(2.71828));
|
||||
assert!(tmp);
|
||||
let tmp = !e.my_cmp(Foo::new(3.14159));
|
||||
assert!(tmp);
|
||||
let tmp = e.my_cmp(Foo::new(2.71828));
|
||||
assert!(tmp);
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.test();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn property() {
|
||||
project()
|
||||
.file(
|
||||
"foo.webidl",
|
||||
r#"
|
||||
[Constructor(double value)]
|
||||
interface Foo {
|
||||
[Pure]
|
||||
attribute double value;
|
||||
};
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"foo.ts",
|
||||
r#"
|
||||
export class Foo {
|
||||
constructor(private _value: number) {
|
||||
this._value = _value;
|
||||
}
|
||||
|
||||
get value(): number {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
set value(_value: number) {
|
||||
this._value = _value;
|
||||
}
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
pub mod foo;
|
||||
|
||||
use foo::Foo;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn test() {
|
||||
let x = Foo::new(3.14159);
|
||||
let tmp = x.value() == 3.14159;
|
||||
assert!(tmp);
|
||||
let tmp = x.value() != 2.71828;
|
||||
assert!(tmp);
|
||||
x.set_value(2.71828);
|
||||
let tmp = x.value() != 3.14159;
|
||||
assert!(tmp);
|
||||
let tmp = x.value() == 2.71828;
|
||||
assert!(tmp);
|
||||
}
|
||||
"#,
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user