mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2024-12-24 02:23:11 +03:00
Adds support for #[wasm_bindgen(typescript_custom_section)].
This commit is contained in:
parent
fc0d6528fc
commit
90193eab51
@ -22,6 +22,8 @@ pub struct Program {
|
|||||||
/// objects" in the sense that they represent a JS object with a particular
|
/// objects" in the sense that they represent a JS object with a particular
|
||||||
/// shape in JIT parlance.
|
/// shape in JIT parlance.
|
||||||
pub dictionaries: Vec<Dictionary>,
|
pub dictionaries: Vec<Dictionary>,
|
||||||
|
/// custom typescript sections to be included in the definition file
|
||||||
|
pub typescript_custom_sections: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A rust to js interface. Allows interaction with rust objects/functions
|
/// A rust to js interface. Allows interaction with rust objects/functions
|
||||||
|
@ -46,6 +46,7 @@ fn shared_program<'a>(prog: &'a ast::Program, intern: &'a Interner)
|
|||||||
imports: prog.imports.iter()
|
imports: prog.imports.iter()
|
||||||
.map(|a| shared_import(a, intern))
|
.map(|a| shared_import(a, intern))
|
||||||
.collect::<Result<Vec<_>, _>>()?,
|
.collect::<Result<Vec<_>, _>>()?,
|
||||||
|
typescript_custom_sections: prog.typescript_custom_sections.iter().map(|x| -> &'a str { &x }).collect(),
|
||||||
// version: shared::version(),
|
// version: shared::version(),
|
||||||
// schema_version: shared::SCHEMA_VERSION.to_string(),
|
// schema_version: shared::SCHEMA_VERSION.to_string(),
|
||||||
})
|
})
|
||||||
|
@ -2143,6 +2143,10 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
|||||||
for s in self.program.structs.iter() {
|
for s in self.program.structs.iter() {
|
||||||
self.generate_struct(s)?;
|
self.generate_struct(s)?;
|
||||||
}
|
}
|
||||||
|
for s in self.program.typescript_custom_sections.iter() {
|
||||||
|
self.cx.typescript.push_str(s);
|
||||||
|
self.cx.typescript.push_str("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -207,6 +207,13 @@ impl BindgenAttrs {
|
|||||||
_ => false,
|
_ => false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn typescript_custom_section(&self) -> bool {
|
||||||
|
self.attrs.iter().any(|a| match *a {
|
||||||
|
BindgenAttr::TypescriptCustomSection => true,
|
||||||
|
_ => false,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for BindgenAttrs {
|
impl Parse for BindgenAttrs {
|
||||||
@ -244,6 +251,7 @@ pub enum BindgenAttr {
|
|||||||
Extends(syn::Path),
|
Extends(syn::Path),
|
||||||
VendorPrefix(Ident),
|
VendorPrefix(Ident),
|
||||||
Variadic,
|
Variadic,
|
||||||
|
TypescriptCustomSection,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for BindgenAttr {
|
impl Parse for BindgenAttr {
|
||||||
@ -334,6 +342,9 @@ impl Parse for BindgenAttr {
|
|||||||
};
|
};
|
||||||
return Ok(BindgenAttr::JsName(val, span));
|
return Ok(BindgenAttr::JsName(val, span));
|
||||||
}
|
}
|
||||||
|
if attr == "typescript_custom_section" {
|
||||||
|
return Ok(BindgenAttr::TypescriptCustomSection);
|
||||||
|
}
|
||||||
|
|
||||||
Err(original.error("unknown attribute"))
|
Err(original.error("unknown attribute"))
|
||||||
}
|
}
|
||||||
@ -810,11 +821,20 @@ impl<'a> MacroParse<(Option<BindgenAttrs>, &'a mut TokenStream)> for syn::Item {
|
|||||||
e.to_tokens(tokens);
|
e.to_tokens(tokens);
|
||||||
e.macro_parse(program, ())?;
|
e.macro_parse(program, ())?;
|
||||||
}
|
}
|
||||||
_ => bail_span!(
|
syn::Item::Const(mut c) => {
|
||||||
self,
|
let opts = match opts {
|
||||||
"#[wasm_bindgen] can only be applied to a function, \
|
Some(opts) => opts,
|
||||||
struct, enum, impl, or extern block"
|
None => BindgenAttrs::find(&mut c.attrs)?,
|
||||||
),
|
};
|
||||||
|
c.macro_parse(program, opts)?;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
bail_span!(
|
||||||
|
self,
|
||||||
|
"#[wasm_bindgen] can only be applied to a function, \
|
||||||
|
struct, enum, impl, or extern block",
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -992,6 +1012,29 @@ impl MacroParse<()> for syn::ItemEnum {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl MacroParse<BindgenAttrs> for syn::ItemConst {
|
||||||
|
fn macro_parse(self, program: &mut ast::Program, opts: BindgenAttrs) -> Result<(), Diagnostic> {
|
||||||
|
// Shortcut
|
||||||
|
if !opts.typescript_custom_section() {
|
||||||
|
bail_span!(self, "#[wasm_bindgen] will not work on constants unless you are defining a #[wasm_bindgen(typescript_custom_section)].");
|
||||||
|
}
|
||||||
|
|
||||||
|
match *self.expr {
|
||||||
|
syn::Expr::Lit(syn::ExprLit {
|
||||||
|
lit: syn::Lit::Str(litstr),
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
|
program.typescript_custom_sections.push(litstr.value());
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
bail_span!(self, "Expected a string literal to be used with #[wasm_bindgen(typescript_custom_section)].");
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl MacroParse<BindgenAttrs> for syn::ItemForeignMod {
|
impl MacroParse<BindgenAttrs> for syn::ItemForeignMod {
|
||||||
fn macro_parse(self, program: &mut ast::Program, opts: BindgenAttrs) -> Result<(), Diagnostic> {
|
fn macro_parse(self, program: &mut ast::Program, opts: BindgenAttrs) -> Result<(), Diagnostic> {
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
|
@ -12,6 +12,7 @@ struct Program<'a> {
|
|||||||
enums: Vec<Enum<'a>>,
|
enums: Vec<Enum<'a>>,
|
||||||
imports: Vec<Import<'a>>,
|
imports: Vec<Import<'a>>,
|
||||||
structs: Vec<Struct<'a>>,
|
structs: Vec<Struct<'a>>,
|
||||||
|
typescript_custom_sections: Vec<&'a str>,
|
||||||
// version: &'a str,
|
// version: &'a str,
|
||||||
// schema_version: &'a str,
|
// schema_version: &'a str,
|
||||||
}
|
}
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
- [`constructor`](./reference/attributes/on-rust-exports/constructor.md)
|
- [`constructor`](./reference/attributes/on-rust-exports/constructor.md)
|
||||||
- [`js_name = Blah`](./reference/attributes/on-rust-exports/js_name.md)
|
- [`js_name = Blah`](./reference/attributes/on-rust-exports/js_name.md)
|
||||||
- [`readonly`](./reference/attributes/on-rust-exports/readonly.md)
|
- [`readonly`](./reference/attributes/on-rust-exports/readonly.md)
|
||||||
|
- [`typescript_custom_section`](./reference/attributes/on-rust-exports/typescript_custom_section.md)
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
# `typescript_custom_section`
|
||||||
|
|
||||||
|
When added to a `const` `&'static str`, it will append the contents of the
|
||||||
|
string to the `.d.ts` file exported by `wasm-bindgen-cli` (when the
|
||||||
|
`--typescript` flag is enabled).
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[wasm_bindgen(typescript_custom_section)]
|
||||||
|
const TS_APPEND_CONTENT: &'static str = r#"
|
||||||
|
|
||||||
|
export type Coords = { "latitude": number, "longitude": number, };
|
||||||
|
|
||||||
|
"#;
|
||||||
|
```
|
||||||
|
|
||||||
|
The primary target for this feature is for code generation. For example, you
|
||||||
|
can author a macro that allows you to export a TypeScript definition alongside
|
||||||
|
the definition of a struct or Rust type.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[derive(MyTypescriptExport)]
|
||||||
|
struct Coords {
|
||||||
|
latitude: u32,
|
||||||
|
longitude: u32,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The proc_derive_macro "MyTypescriptExport" can export its own
|
||||||
|
`#[wasm_bindgen(typescript_custom_section)]` section, which would then be
|
||||||
|
picked up by wasm-bindgen-cli. This would be equivalent to the contents of
|
||||||
|
the TS_APPEND_CONTENT string in the first example.
|
||||||
|
|
||||||
|
This feature allows plain data objects to be typechecked in Rust and in
|
||||||
|
TypeScript by outputing a type definition generated at compile time.
|
Loading…
Reference in New Issue
Block a user