mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-04-01 18:01:06 +00:00
Fix TypeScript output for fields
This commit is contained in:
parent
ff0a50e31e
commit
cba1e70077
@ -51,7 +51,7 @@ pub struct Js2Rust<'a, 'b: 'a> {
|
|||||||
|
|
||||||
/// Typescript expression representing the type of the return value of this
|
/// Typescript expression representing the type of the return value of this
|
||||||
/// function.
|
/// function.
|
||||||
ret_ty: String,
|
pub ret_ty: String,
|
||||||
|
|
||||||
/// Expression used to generate the return value. The string "RET" in this
|
/// Expression used to generate the return value. The string "RET" in this
|
||||||
/// expression is replaced with the actual wasm invocation eventually.
|
/// expression is replaced with the actual wasm invocation eventually.
|
||||||
|
@ -58,6 +58,8 @@ pub struct ExportedClass {
|
|||||||
typescript: String,
|
typescript: String,
|
||||||
has_constructor: bool,
|
has_constructor: bool,
|
||||||
wrap_needed: bool,
|
wrap_needed: bool,
|
||||||
|
/// Map from field name to type as a string plus whether it has a setter
|
||||||
|
typescript_fields: HashMap<String, (String, bool)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const INITIAL_HEAP_VALUES: &[&str] = &["undefined", "null", "true", "false"];
|
const INITIAL_HEAP_VALUES: &[&str] = &["undefined", "null", "true", "false"];
|
||||||
@ -638,6 +640,19 @@ impl<'a> Context<'a> {
|
|||||||
ts_dst.push_str(" free(): void;");
|
ts_dst.push_str(" free(): void;");
|
||||||
dst.push_str(&class.contents);
|
dst.push_str(&class.contents);
|
||||||
ts_dst.push_str(&class.typescript);
|
ts_dst.push_str(&class.typescript);
|
||||||
|
|
||||||
|
let mut fields = class.typescript_fields.keys().collect::<Vec<_>>();
|
||||||
|
fields.sort(); // make sure we have deterministic output
|
||||||
|
for name in fields {
|
||||||
|
let (ty, readonly) = &class.typescript_fields[name];
|
||||||
|
if *readonly {
|
||||||
|
ts_dst.push_str("readonly ");
|
||||||
|
}
|
||||||
|
ts_dst.push_str(name);
|
||||||
|
ts_dst.push_str(": ");
|
||||||
|
ts_dst.push_str(ty);
|
||||||
|
ts_dst.push_str(";\n");
|
||||||
|
}
|
||||||
dst.push_str("}\n");
|
dst.push_str("}\n");
|
||||||
ts_dst.push_str("}\n");
|
ts_dst.push_str("}\n");
|
||||||
|
|
||||||
@ -1913,14 +1928,15 @@ impl<'a> Context<'a> {
|
|||||||
&format!("wasm.{}", wasm_name),
|
&format!("wasm.{}", wasm_name),
|
||||||
ExportedShim::Named(&wasm_name),
|
ExportedShim::Named(&wasm_name),
|
||||||
);
|
);
|
||||||
|
let ret_ty = j2r.ret_ty.clone();
|
||||||
let exported = require_class(&mut self.exported_classes, class);
|
let exported = require_class(&mut self.exported_classes, class);
|
||||||
let docs = format_doc_comments(&export.comments, Some(raw_docs));
|
let docs = format_doc_comments(&export.comments, Some(raw_docs));
|
||||||
match export.kind {
|
match export.kind {
|
||||||
AuxExportKind::Getter { .. } => {
|
AuxExportKind::Getter { .. } => {
|
||||||
exported.push(&docs, name, "get ", &js, &ts);
|
exported.push_field(name, &js, Some(&ret_ty), true);
|
||||||
}
|
}
|
||||||
AuxExportKind::Setter { .. } => {
|
AuxExportKind::Setter { .. } => {
|
||||||
exported.push(&docs, name, "set ", &js, &ts);
|
exported.push_field(name, &js, None, false);
|
||||||
}
|
}
|
||||||
AuxExportKind::StaticFunction { .. } => {
|
AuxExportKind::StaticFunction { .. } => {
|
||||||
exported.push(&docs, name, "static ", &js, &ts);
|
exported.push(&docs, name, "static ", &js, &ts);
|
||||||
@ -1983,7 +1999,7 @@ impl<'a> Context<'a> {
|
|||||||
bail!(
|
bail!(
|
||||||
"NPM dependencies have been specified in `{}` but \
|
"NPM dependencies have been specified in `{}` but \
|
||||||
this is only compatible with the `bundler` and `nodejs` targets",
|
this is only compatible with the `bundler` and `nodejs` targets",
|
||||||
path.display(),
|
path.display(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2164,6 +2180,31 @@ impl ExportedClass {
|
|||||||
self.typescript.push_str(ts);
|
self.typescript.push_str(ts);
|
||||||
self.typescript.push_str("\n");
|
self.typescript.push_str("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Used for adding a field to a class, mainly to ensure that TypeScript
|
||||||
|
/// generation is handled specially.
|
||||||
|
///
|
||||||
|
/// Note that the `ts` is optional and it's expected to just be the field
|
||||||
|
/// type, not the full signature. It's currently only available on getters,
|
||||||
|
/// but there currently has to always be at least a getter.
|
||||||
|
fn push_field(&mut self, field: &str, js: &str, ts: Option<&str>, getter: bool) {
|
||||||
|
if getter {
|
||||||
|
self.contents.push_str("get ");
|
||||||
|
} else {
|
||||||
|
self.contents.push_str("set ");
|
||||||
|
}
|
||||||
|
self.contents.push_str(field);
|
||||||
|
self.contents.push_str(js);
|
||||||
|
self.contents.push_str("\n");
|
||||||
|
let (ty, has_setter) = self
|
||||||
|
.typescript_fields
|
||||||
|
.entry(field.to_string())
|
||||||
|
.or_insert_with(Default::default);
|
||||||
|
if let Some(ts) = ts {
|
||||||
|
*ty = ts.to_string();
|
||||||
|
}
|
||||||
|
*has_setter = *has_setter || !getter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user