Merge pull request #430 from FreeMasen/js_docs

Js docs
This commit is contained in:
Nick Fitzgerald 2018-07-10 10:08:41 -07:00 committed by GitHub
commit 42938792c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 35 additions and 19 deletions

View File

@ -368,6 +368,14 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
Ok(self)
}
pub fn js_doc_comments(&self) -> String {
let mut ret: String = self.js_arguments.iter().map(|a| {
format!("@param {{{}}} {}\n", a.1, a.0)
}).collect();
ret.push_str(&format!("@returns {{{}}}", self.ret_ty));
ret
}
/// Generate the actual function.
///
/// The `prefix` specified is typically the string "function" but may be
@ -377,7 +385,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
/// Returns two strings, the first of which is the JS expression for the
/// generated function shim and the second is a TypeScript signature of the
/// JS expression.
pub fn finish(&self, prefix: &str, invoc: &str) -> (String, String) {
pub fn finish(&self, prefix: &str, invoc: &str) -> (String, String, String) {
let js_args = self
.js_arguments
.iter()
@ -417,6 +425,6 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
"{} {}({}): {};\n",
prefix, self.js_name, ts_args, self.ret_ty
);
(js, ts)
(js, ts, self.js_doc_comments())
}
}

View File

@ -43,7 +43,7 @@ pub struct ExportedClass {
}
struct ClassField {
comments: String,
comments: Vec<String>,
name: String,
readonly: bool,
}
@ -55,7 +55,6 @@ pub struct SubContext<'a, 'b: 'a> {
impl<'a> Context<'a> {
fn export(&mut self, name: &str, contents: &str, comments: Option<String>) {
let contents = contents;
let contents = contents.trim();
if let Some(ref c) = comments {
self.globals.push_str(c);
@ -596,14 +595,14 @@ impl<'a> Context<'a> {
));
cx.finish("", &format!("wasm.{}", wasm_setter)).0
};
let (get, _ts) = Js2Rust::new(&field.name, self)
let (get, _ts, js_doc) = Js2Rust::new(&field.name, self)
.method(true, false)
.ret(&Some(descriptor))?
.finish("", &format!("wasm.{}", wasm_getter));
if !dst.ends_with("\n") {
dst.push_str("\n");
}
dst.push_str(&field.comments);
dst.push_str(&format_doc_comments(&field.comments, Some(js_doc)));
dst.push_str("get ");
dst.push_str(&field.name);
dst.push_str(&get);
@ -1653,11 +1652,11 @@ impl<'a, 'b> SubContext<'a, 'b> {
.exported_classes
.entry(s.name.clone())
.or_insert_with(Default::default);
class.comments = format_doc_comments(&s.comments);
class.comments = format_doc_comments(&s.comments, None);
class.fields.extend(s.fields.iter().map(|f| ClassField {
name: f.name.clone(),
readonly: f.readonly,
comments: format_doc_comments(&f.comments),
comments: f.comments.clone(),
}));
}
@ -1674,13 +1673,13 @@ impl<'a, 'b> SubContext<'a, 'b> {
Some(d) => d,
};
let (js, ts) = Js2Rust::new(&export.function.name, self.cx)
let (js, ts, js_doc) = Js2Rust::new(&export.function.name, self.cx)
.process(descriptor.unwrap_function())?
.finish("function", &format!("wasm.{}", export.function.name));
self.cx.export(
&export.function.name,
&js,
Some(format_doc_comments(&export.comments)),
Some(format_doc_comments(&export.comments, Some(js_doc))),
);
self.cx.globals.push_str("\n");
self.cx.typescript.push_str("export ");
@ -1701,10 +1700,11 @@ impl<'a, 'b> SubContext<'a, 'b> {
Some(d) => d,
};
let (js, ts) = Js2Rust::new(&export.function.name, self.cx)
let (js, ts, js_doc) = Js2Rust::new(&export.function.name, self.cx)
.method(export.method, export.consumed)
.process(descriptor.unwrap_function())?
.finish("", &format!("wasm.{}", wasm_name));
let class = self
.cx
.exported_classes
@ -1712,7 +1712,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
.or_insert(ExportedClass::default());
class
.contents
.push_str(&format_doc_comments(&export.comments));
.push_str(&format_doc_comments(&export.comments, Some(js_doc)));
if !export.method {
class.contents.push_str("static ");
class.typescript.push_str("static ");
@ -1960,7 +1960,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
self.cx.export(
&enum_.name,
&format!("Object.freeze({{ {} }})", variants),
Some(format_doc_comments(&enum_.comments)),
Some(format_doc_comments(&enum_.comments, None)),
);
self.cx
.typescript
@ -2011,10 +2011,17 @@ impl<'a, 'b> SubContext<'a, 'b> {
}
}
fn format_doc_comments(comments: &Vec<String>) -> String {
fn format_doc_comments(comments: &Vec<String>, js_doc_comments: Option<String>) -> String {
let body: String = comments
.iter()
.map(|c| format!("*{}\n", c.trim_matches('"')))
.collect();
format!("/**\n{}*/\n", body)
let doc = if let Some(docs) = js_doc_comments {
docs.lines()
.map(|l| format!("* {} \n", l))
.collect()
} else {
String::new()
};
format!("/**\n{}{}*/\n", body, doc)
}

View File

@ -142,7 +142,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
}
if let Some((f, mutable)) = arg.stack_closure() {
let (js, _ts) = {
let (js, _ts, _js_doc) = {
let mut builder = Js2Rust::new("", self.cx);
if mutable {
builder
@ -179,7 +179,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
}
if let Some(closure) = arg.ref_closure() {
let (js, _ts) = {
let (js, _ts, _js_doc) = {
let mut builder = Js2Rust::new("", self.cx);
if closure.mutable {
builder

View File

@ -443,7 +443,7 @@ fn reset_indentation(s: &str) -> String {
for line in s.lines() {
let line = line.trim();
if line.starts_with('}') || line.ends_with('}') {
if line.starts_with('}') || (line.ends_with('}') && !line.starts_with('*')) {
indent = indent.saturating_sub(1);
}
let extra = if line.starts_with(':') || line.starts_with('?') { 1 } else { 0 };

View File

@ -41,7 +41,8 @@ fn works() {
p.gen_bindings();
let js = p.read_js();
let comments = extract_doc_comments(&js);
assert!(comments.iter().all(|c| c == "This comment should exist"));
assert!(comments.iter().all(|c| c == "This comment should exist" ||
c.starts_with("@")));
}
/// Pull out all lines in a js string that start with