Copy more doc comments to JS/TS files, unescape comments (#2070)

* Copy more doc comments to JS/TS files, unescape comments

* Move unescape code to macro-support
This commit is contained in:
0xd4d
2020-04-13 20:51:32 +02:00
committed by GitHub
parent fc86589715
commit 826538922f
10 changed files with 179 additions and 28 deletions

View File

@ -66,9 +66,9 @@ pub struct ExportedClass {
is_inspectable: bool,
/// All readable properties of the class
readable_properties: Vec<String>,
/// Map from field name to type as a string plus whether it has a setter
/// Map from field name to type as a string, docs plus whether it has a setter
/// and it is optional
typescript_fields: HashMap<String, (String, bool, bool)>,
typescript_fields: HashMap<String, (String, String, bool, bool)>,
}
const INITIAL_HEAP_VALUES: &[&str] = &["undefined", "null", "true", "false"];
@ -798,7 +798,8 @@ impl<'a> Context<'a> {
let mut fields = class.typescript_fields.keys().collect::<Vec<_>>();
fields.sort(); // make sure we have deterministic output
for name in fields {
let (ty, has_setter, is_optional) = &class.typescript_fields[name];
let (ty, docs, has_setter, is_optional) = &class.typescript_fields[name];
ts_dst.push_str(docs);
ts_dst.push_str(" ");
if !has_setter {
ts_dst.push_str("readonly ");
@ -816,6 +817,7 @@ impl<'a> Context<'a> {
ts_dst.push_str("}\n");
self.export(&name, &dst, Some(&class.comments))?;
self.typescript.push_str(&class.comments);
self.typescript.push_str(&ts_dst);
Ok(())
@ -2901,10 +2903,23 @@ impl<'a> Context<'a> {
self.typescript
.push_str(&format!("export enum {} {{", enum_.name));
}
for (name, value) in enum_.variants.iter() {
for (name, value, comments) in enum_.variants.iter() {
let variant_docs = if comments.is_empty() {
String::new()
} else {
format_doc_comments(&comments, None)
};
if !variant_docs.is_empty() {
variants.push_str("\n");
variants.push_str(&variant_docs);
}
variants.push_str(&format!("{}:{},", name, value));
if enum_.generate_typescript {
self.typescript.push_str(&format!("\n {},", name));
self.typescript.push_str("\n");
if !variant_docs.is_empty() {
self.typescript.push_str(&variant_docs);
}
self.typescript.push_str(&format!(" {},", name));
}
}
if enum_.generate_typescript {
@ -3227,7 +3242,7 @@ impl ExportedClass {
fn push_getter(&mut self, docs: &str, field: &str, js: &str, ret_ty: Option<&str>) {
self.push_accessor(docs, field, js, "get ");
if let Some(ret_ty) = ret_ty {
self.push_accessor_ts(field, ret_ty);
self.push_accessor_ts(docs, field, ret_ty, false);
}
self.readable_properties.push(field.to_string());
}
@ -3244,20 +3259,30 @@ impl ExportedClass {
) {
self.push_accessor(docs, field, js, "set ");
if let Some(ret_ty) = ret_ty {
let (has_setter, is_optional) = self.push_accessor_ts(field, ret_ty);
*has_setter = true;
let is_optional = self.push_accessor_ts(docs, field, ret_ty, true);
*is_optional = might_be_optional_field;
}
}
fn push_accessor_ts(&mut self, field: &str, ret_ty: &str) -> (&mut bool, &mut bool) {
let (ty, has_setter, is_optional) = self
fn push_accessor_ts(
&mut self,
docs: &str,
field: &str,
ret_ty: &str,
is_setter: bool,
) -> &mut bool {
let (ty, accessor_docs, has_setter, is_optional) = self
.typescript_fields
.entry(field.to_string())
.or_insert_with(Default::default);
*ty = ret_ty.to_string();
(has_setter, is_optional)
// Deterministic output: always use the getter's docs if available
if !docs.is_empty() && (accessor_docs.is_empty() || !is_setter) {
*accessor_docs = docs.to_owned();
}
*has_setter |= is_setter;
is_optional
}
fn push_accessor(&mut self, docs: &str, field: &str, js: &str, prefix: &str) {

View File

@ -477,7 +477,8 @@ fn reset_indentation(s: &str) -> String {
dst.push_str(line);
}
dst.push_str("\n");
if line.ends_with('{') {
// Ignore { inside of comments and if it's an exported enum
if line.ends_with('{') && !line.starts_with('*') && !line.ends_with("Object.freeze({") {
indent += 1;
}
}

View File

@ -766,7 +766,13 @@ impl<'a> Context<'a> {
variants: enum_
.variants
.iter()
.map(|v| (v.name.to_string(), v.value))
.map(|v| {
(
v.name.to_string(),
v.value,
concatenate_comments(&v.comments),
)
})
.collect(),
generate_typescript: enum_.generate_typescript,
};
@ -1511,9 +1517,5 @@ fn verify_schema_matches<'a>(data: &'a [u8]) -> Result<Option<&'a str>, Error> {
}
fn concatenate_comments(comments: &[&str]) -> String {
comments
.iter()
.map(|s| s.trim_matches('"'))
.collect::<Vec<_>>()
.join("\n")
comments.iter().map(|&s| s).collect::<Vec<_>>().join("\n")
}

View File

@ -132,9 +132,9 @@ pub struct AuxEnum {
pub name: String,
/// The copied Rust comments to forward to JS
pub comments: String,
/// A list of variants with their name and value
/// A list of variants with their name, value and comments
/// and whether typescript bindings should be generated for each variant
pub variants: Vec<(String, u32)>,
pub variants: Vec<(String, u32, String)>,
/// Whether typescript bindings should be generated for this enum.
pub generate_typescript: bool,
}