mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-04-25 06:02:13 +00:00
Allow web-sys to emit correct typescript declarations from webidl (#1998)
* Update to emit typescript names * Update to use NamedAnyref * Update incoming / outgoing * Remove added space * Remove comment * Add basic typescript tests for web-sys
This commit is contained in:
parent
9d55978af5
commit
ec1b9453c9
@ -181,6 +181,7 @@ pub struct ImportType {
|
|||||||
pub rust_name: Ident,
|
pub rust_name: Ident,
|
||||||
pub js_name: String,
|
pub js_name: String,
|
||||||
pub attrs: Vec<syn::Attribute>,
|
pub attrs: Vec<syn::Attribute>,
|
||||||
|
pub typescript_name: Option<String>,
|
||||||
pub doc_comment: Option<String>,
|
pub doc_comment: Option<String>,
|
||||||
pub instanceof_shim: String,
|
pub instanceof_shim: String,
|
||||||
pub is_type_of: Option<syn::Expr>,
|
pub is_type_of: Option<syn::Expr>,
|
||||||
|
@ -579,6 +579,21 @@ impl ToTokens for ast::ImportType {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let description = if let Some(typescript_name) = &self.typescript_name {
|
||||||
|
let typescript_name_len = typescript_name.len() as u32;
|
||||||
|
let typescript_name_chars = typescript_name.chars().map(|c| c as u32);
|
||||||
|
quote! {
|
||||||
|
use wasm_bindgen::describe::*;
|
||||||
|
inform(NAMED_ANYREF);
|
||||||
|
inform(#typescript_name_len);
|
||||||
|
#(inform(#typescript_name_chars);)*
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
JsValue::describe()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let is_type_of = self.is_type_of.as_ref().map(|is_type_of| {
|
let is_type_of = self.is_type_of.as_ref().map(|is_type_of| {
|
||||||
quote! {
|
quote! {
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -611,7 +626,7 @@ impl ToTokens for ast::ImportType {
|
|||||||
|
|
||||||
impl WasmDescribe for #rust_name {
|
impl WasmDescribe for #rust_name {
|
||||||
fn describe() {
|
fn describe() {
|
||||||
JsValue::describe();
|
#description
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ tys! {
|
|||||||
SLICE
|
SLICE
|
||||||
VECTOR
|
VECTOR
|
||||||
ANYREF
|
ANYREF
|
||||||
|
NAMED_ANYREF
|
||||||
ENUM
|
ENUM
|
||||||
RUST_STRUCT
|
RUST_STRUCT
|
||||||
CHAR
|
CHAR
|
||||||
@ -62,6 +63,7 @@ pub enum Descriptor {
|
|||||||
CachedString,
|
CachedString,
|
||||||
String,
|
String,
|
||||||
Anyref,
|
Anyref,
|
||||||
|
NamedAnyref(String),
|
||||||
Enum { hole: u32 },
|
Enum { hole: u32 },
|
||||||
RustStruct(String),
|
RustStruct(String),
|
||||||
Char,
|
Char,
|
||||||
@ -134,11 +136,13 @@ impl Descriptor {
|
|||||||
ANYREF => Descriptor::Anyref,
|
ANYREF => Descriptor::Anyref,
|
||||||
ENUM => Descriptor::Enum { hole: get(data) },
|
ENUM => Descriptor::Enum { hole: get(data) },
|
||||||
RUST_STRUCT => {
|
RUST_STRUCT => {
|
||||||
let name = (0..get(data))
|
let name = get_string(data);
|
||||||
.map(|_| char::from_u32(get(data)).unwrap())
|
|
||||||
.collect();
|
|
||||||
Descriptor::RustStruct(name)
|
Descriptor::RustStruct(name)
|
||||||
}
|
}
|
||||||
|
NAMED_ANYREF => {
|
||||||
|
let name = get_string(data);
|
||||||
|
Descriptor::NamedAnyref(name)
|
||||||
|
}
|
||||||
CHAR => Descriptor::Char,
|
CHAR => Descriptor::Char,
|
||||||
UNIT => Descriptor::Unit,
|
UNIT => Descriptor::Unit,
|
||||||
CLAMPED => Descriptor::_decode(data, true),
|
CLAMPED => Descriptor::_decode(data, true),
|
||||||
@ -200,6 +204,12 @@ fn get(a: &mut &[u32]) -> u32 {
|
|||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_string(data: &mut &[u32]) -> String {
|
||||||
|
(0..get(data))
|
||||||
|
.map(|_| char::from_u32(get(data)).unwrap())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
impl Closure {
|
impl Closure {
|
||||||
fn decode(data: &mut &[u32]) -> Closure {
|
fn decode(data: &mut &[u32]) -> Closure {
|
||||||
let shim_idx = get(data);
|
let shim_idx = get(data);
|
||||||
|
@ -1238,6 +1238,7 @@ fn adapter2ts(ty: &AdapterType, dst: &mut String) {
|
|||||||
adapter2ts(ty, dst);
|
adapter2ts(ty, dst);
|
||||||
dst.push_str(" | undefined");
|
dst.push_str(" | undefined");
|
||||||
}
|
}
|
||||||
|
AdapterType::NamedAnyref(name) => dst.push_str(name),
|
||||||
AdapterType::Struct(name) => dst.push_str(name),
|
AdapterType::Struct(name) => dst.push_str(name),
|
||||||
AdapterType::Function => dst.push_str("any"),
|
AdapterType::Function => dst.push_str("any"),
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,13 @@ impl InstructionBuilder<'_, '_> {
|
|||||||
&[AdapterType::I32],
|
&[AdapterType::I32],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Descriptor::NamedAnyref(name) => {
|
||||||
|
self.instruction(
|
||||||
|
&[AdapterType::NamedAnyref(name.clone())],
|
||||||
|
Instruction::I32FromAnyrefOwned,
|
||||||
|
&[AdapterType::I32]
|
||||||
|
)
|
||||||
|
}
|
||||||
Descriptor::RustStruct(class) => {
|
Descriptor::RustStruct(class) => {
|
||||||
self.instruction(
|
self.instruction(
|
||||||
&[AdapterType::Struct(class.clone())],
|
&[AdapterType::Struct(class.clone())],
|
||||||
@ -161,6 +168,13 @@ impl InstructionBuilder<'_, '_> {
|
|||||||
&[AdapterType::I32],
|
&[AdapterType::I32],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Descriptor::NamedAnyref(name) => {
|
||||||
|
self.instruction(
|
||||||
|
&[AdapterType::NamedAnyref(name.clone())],
|
||||||
|
Instruction::I32FromAnyrefBorrow,
|
||||||
|
&[AdapterType::I32],
|
||||||
|
);
|
||||||
|
}
|
||||||
Descriptor::String | Descriptor::CachedString => {
|
Descriptor::String | Descriptor::CachedString => {
|
||||||
// This allocation is cleaned up once it's received in Rust.
|
// This allocation is cleaned up once it's received in Rust.
|
||||||
self.instruction(
|
self.instruction(
|
||||||
@ -224,6 +238,15 @@ impl InstructionBuilder<'_, '_> {
|
|||||||
&[AdapterType::I32],
|
&[AdapterType::I32],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Descriptor::NamedAnyref(name) => {
|
||||||
|
self.instruction(
|
||||||
|
&[AdapterType::NamedAnyref(name.clone()).option()],
|
||||||
|
Instruction::I32FromOptionAnyref {
|
||||||
|
table_and_alloc: None,
|
||||||
|
},
|
||||||
|
&[AdapterType::I32],
|
||||||
|
);
|
||||||
|
}
|
||||||
Descriptor::I8 => self.in_option_sentinel(AdapterType::S8),
|
Descriptor::I8 => self.in_option_sentinel(AdapterType::S8),
|
||||||
Descriptor::U8 => self.in_option_sentinel(AdapterType::U8),
|
Descriptor::U8 => self.in_option_sentinel(AdapterType::U8),
|
||||||
Descriptor::I16 => self.in_option_sentinel(AdapterType::S16),
|
Descriptor::I16 => self.in_option_sentinel(AdapterType::S16),
|
||||||
|
@ -39,6 +39,13 @@ impl InstructionBuilder<'_, '_> {
|
|||||||
&[AdapterType::Anyref],
|
&[AdapterType::Anyref],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Descriptor::NamedAnyref(name) => {
|
||||||
|
self.instruction(
|
||||||
|
&[AdapterType::I32],
|
||||||
|
Instruction::AnyrefLoadOwned,
|
||||||
|
&[AdapterType::NamedAnyref(name.clone())],
|
||||||
|
);
|
||||||
|
}
|
||||||
Descriptor::I8 => self.outgoing_i32(AdapterType::S8),
|
Descriptor::I8 => self.outgoing_i32(AdapterType::S8),
|
||||||
Descriptor::U8 => self.outgoing_i32(AdapterType::U8),
|
Descriptor::U8 => self.outgoing_i32(AdapterType::U8),
|
||||||
Descriptor::I16 => self.outgoing_i32(AdapterType::S16),
|
Descriptor::I16 => self.outgoing_i32(AdapterType::S16),
|
||||||
@ -162,6 +169,13 @@ impl InstructionBuilder<'_, '_> {
|
|||||||
&[AdapterType::Anyref],
|
&[AdapterType::Anyref],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Descriptor::NamedAnyref(name) => {
|
||||||
|
self.instruction(
|
||||||
|
&[AdapterType::I32],
|
||||||
|
Instruction::TableGet,
|
||||||
|
&[AdapterType::NamedAnyref(name.clone())],
|
||||||
|
);
|
||||||
|
}
|
||||||
Descriptor::CachedString => self.cached_string(false, false)?,
|
Descriptor::CachedString => self.cached_string(false, false)?,
|
||||||
|
|
||||||
Descriptor::String => {
|
Descriptor::String => {
|
||||||
@ -227,6 +241,13 @@ impl InstructionBuilder<'_, '_> {
|
|||||||
&[AdapterType::Anyref.option()],
|
&[AdapterType::Anyref.option()],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Descriptor::NamedAnyref(name) => {
|
||||||
|
self.instruction(
|
||||||
|
&[AdapterType::I32],
|
||||||
|
Instruction::AnyrefLoadOwned,
|
||||||
|
&[AdapterType::NamedAnyref(name.clone()).option()],
|
||||||
|
);
|
||||||
|
}
|
||||||
Descriptor::I8 => self.out_option_sentinel(AdapterType::S8),
|
Descriptor::I8 => self.out_option_sentinel(AdapterType::S8),
|
||||||
Descriptor::U8 => self.out_option_sentinel(AdapterType::U8),
|
Descriptor::U8 => self.out_option_sentinel(AdapterType::U8),
|
||||||
Descriptor::I16 => self.out_option_sentinel(AdapterType::S16),
|
Descriptor::I16 => self.out_option_sentinel(AdapterType::S16),
|
||||||
@ -316,6 +337,13 @@ impl InstructionBuilder<'_, '_> {
|
|||||||
&[AdapterType::Anyref.option()],
|
&[AdapterType::Anyref.option()],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Descriptor::NamedAnyref(name) => {
|
||||||
|
self.instruction(
|
||||||
|
&[AdapterType::I32],
|
||||||
|
Instruction::TableGet,
|
||||||
|
&[AdapterType::NamedAnyref(name.clone()).option()],
|
||||||
|
);
|
||||||
|
}
|
||||||
Descriptor::CachedString => self.cached_string(true, false)?,
|
Descriptor::CachedString => self.cached_string(true, false)?,
|
||||||
Descriptor::String | Descriptor::Slice(_) => {
|
Descriptor::String | Descriptor::Slice(_) => {
|
||||||
let kind = arg.vector_kind().ok_or_else(|| {
|
let kind = arg.vector_kind().ok_or_else(|| {
|
||||||
|
@ -84,6 +84,7 @@ pub enum AdapterType {
|
|||||||
Vector(VectorKind),
|
Vector(VectorKind),
|
||||||
Option(Box<AdapterType>),
|
Option(Box<AdapterType>),
|
||||||
Struct(String),
|
Struct(String),
|
||||||
|
NamedAnyref(String),
|
||||||
Function,
|
Function,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,7 +323,7 @@ impl AdapterType {
|
|||||||
AdapterType::I64 => walrus::ValType::I64,
|
AdapterType::I64 => walrus::ValType::I64,
|
||||||
AdapterType::F32 => walrus::ValType::F32,
|
AdapterType::F32 => walrus::ValType::F32,
|
||||||
AdapterType::F64 => walrus::ValType::F64,
|
AdapterType::F64 => walrus::ValType::F64,
|
||||||
AdapterType::Anyref => walrus::ValType::Anyref,
|
AdapterType::Anyref | AdapterType::NamedAnyref(_) => walrus::ValType::Anyref,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -340,7 +341,7 @@ impl AdapterType {
|
|||||||
AdapterType::F32 => wit_walrus::ValType::F32,
|
AdapterType::F32 => wit_walrus::ValType::F32,
|
||||||
AdapterType::F64 => wit_walrus::ValType::F64,
|
AdapterType::F64 => wit_walrus::ValType::F64,
|
||||||
AdapterType::String => wit_walrus::ValType::String,
|
AdapterType::String => wit_walrus::ValType::String,
|
||||||
AdapterType::Anyref => wit_walrus::ValType::Anyref,
|
AdapterType::Anyref | AdapterType::NamedAnyref(_) => wit_walrus::ValType::Anyref,
|
||||||
|
|
||||||
AdapterType::I32 => wit_walrus::ValType::I32,
|
AdapterType::I32 => wit_walrus::ValType::I32,
|
||||||
AdapterType::I64 => wit_walrus::ValType::I64,
|
AdapterType::I64 => wit_walrus::ValType::I64,
|
||||||
|
@ -554,6 +554,7 @@ impl ConvertToAst<BindgenAttrs> for syn::ForeignItemType {
|
|||||||
instanceof_shim: shim,
|
instanceof_shim: shim,
|
||||||
is_type_of,
|
is_type_of,
|
||||||
rust_name: self.ident,
|
rust_name: self.ident,
|
||||||
|
typescript_name: None,
|
||||||
js_name,
|
js_name,
|
||||||
extends,
|
extends,
|
||||||
vendor_prefixes,
|
vendor_prefixes,
|
||||||
|
@ -6,6 +6,7 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasm-bindgen = { path = '../..' }
|
wasm-bindgen = { path = '../..' }
|
||||||
|
web-sys = { path = '../web-sys', features = [ 'HtmlElement', 'Node', 'Document' ] }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ['cdylib']
|
crate-type = ['cdylib']
|
||||||
|
@ -4,3 +4,4 @@ pub mod opt_args_and_ret;
|
|||||||
pub mod optional_fields;
|
pub mod optional_fields;
|
||||||
pub mod simple_fn;
|
pub mod simple_fn;
|
||||||
pub mod simple_struct;
|
pub mod simple_struct;
|
||||||
|
pub mod web_sys;
|
||||||
|
24
crates/typescript-tests/src/web_sys.rs
Normal file
24
crates/typescript-tests/src/web_sys.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
use web_sys::*;
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub struct DocStruct {
|
||||||
|
doc: Document,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
impl DocStruct {
|
||||||
|
pub fn new(doc: Document) -> Self {
|
||||||
|
Self { doc }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_doc(&self) -> Document {
|
||||||
|
self.doc.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn append_element(&self, element: &HtmlElement) {
|
||||||
|
self.doc.body().unwrap().append_child(element).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn append_many(&self, _: &HtmlElement, _: &HtmlElement, _: &HtmlElement) {}
|
||||||
|
}
|
26
crates/typescript-tests/src/web_sys.ts
Normal file
26
crates/typescript-tests/src/web_sys.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import * as wbg from "../pkg/typescript_tests";
|
||||||
|
|
||||||
|
const doc: Document = document;
|
||||||
|
|
||||||
|
const docStruct = wbg.DocStruct.new(doc);
|
||||||
|
|
||||||
|
const el: HTMLElement = document.createElement("a");
|
||||||
|
|
||||||
|
docStruct.append_element(el);
|
||||||
|
docStruct.append_many(el, el, el);
|
||||||
|
|
||||||
|
const newDoc = docStruct.get_doc();
|
||||||
|
|
||||||
|
// This test ensures that the correct Typescript types are
|
||||||
|
// used. If "newDoc" is "any", then "event" will cause the
|
||||||
|
// compilation to fail because of noImplicitAny.
|
||||||
|
newDoc.addEventListener("load", event => {
|
||||||
|
console.log(event);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Same as above, but testing that the param is a document.
|
||||||
|
const listener: Parameters<
|
||||||
|
Parameters<typeof wbg["DocStruct"]["new"]>[0]["addEventListener"]
|
||||||
|
>[1] = event => console.log(event);
|
||||||
|
|
||||||
|
newDoc.addEventListener("load", listener);
|
@ -568,6 +568,7 @@ impl<'src> FirstPassRecord<'src> {
|
|||||||
} else {
|
} else {
|
||||||
Some(syn::parse_quote! { |_| false })
|
Some(syn::parse_quote! { |_| false })
|
||||||
},
|
},
|
||||||
|
typescript_name: Some(name.to_string()),
|
||||||
extends: Vec::new(),
|
extends: Vec::new(),
|
||||||
vendor_prefixes: Vec::new(),
|
vendor_prefixes: Vec::new(),
|
||||||
};
|
};
|
||||||
|
@ -37,6 +37,7 @@ tys! {
|
|||||||
SLICE
|
SLICE
|
||||||
VECTOR
|
VECTOR
|
||||||
ANYREF
|
ANYREF
|
||||||
|
NAMED_ANYREF
|
||||||
ENUM
|
ENUM
|
||||||
RUST_STRUCT
|
RUST_STRUCT
|
||||||
CHAR
|
CHAR
|
||||||
|
Loading…
x
Reference in New Issue
Block a user