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) 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. /// Generate the actual function.
/// ///
/// The `prefix` specified is typically the string "function" but may be /// 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 /// 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 /// generated function shim and the second is a TypeScript signature of the
/// JS expression. /// 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 let js_args = self
.js_arguments .js_arguments
.iter() .iter()
@ -417,6 +425,6 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
"{} {}({}): {};\n", "{} {}({}): {};\n",
prefix, self.js_name, ts_args, self.ret_ty 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 { struct ClassField {
comments: String, comments: Vec<String>,
name: String, name: String,
readonly: bool, readonly: bool,
} }
@ -55,7 +55,6 @@ pub struct SubContext<'a, 'b: 'a> {
impl<'a> Context<'a> { impl<'a> Context<'a> {
fn export(&mut self, name: &str, contents: &str, comments: Option<String>) { fn export(&mut self, name: &str, contents: &str, comments: Option<String>) {
let contents = contents;
let contents = contents.trim(); let contents = contents.trim();
if let Some(ref c) = comments { if let Some(ref c) = comments {
self.globals.push_str(c); self.globals.push_str(c);
@ -596,14 +595,14 @@ impl<'a> Context<'a> {
)); ));
cx.finish("", &format!("wasm.{}", wasm_setter)).0 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) .method(true, false)
.ret(&Some(descriptor))? .ret(&Some(descriptor))?
.finish("", &format!("wasm.{}", wasm_getter)); .finish("", &format!("wasm.{}", wasm_getter));
if !dst.ends_with("\n") { if !dst.ends_with("\n") {
dst.push_str("\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("get ");
dst.push_str(&field.name); dst.push_str(&field.name);
dst.push_str(&get); dst.push_str(&get);
@ -1653,11 +1652,11 @@ impl<'a, 'b> SubContext<'a, 'b> {
.exported_classes .exported_classes
.entry(s.name.clone()) .entry(s.name.clone())
.or_insert_with(Default::default); .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 { class.fields.extend(s.fields.iter().map(|f| ClassField {
name: f.name.clone(), name: f.name.clone(),
readonly: f.readonly, 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, 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())? .process(descriptor.unwrap_function())?
.finish("function", &format!("wasm.{}", export.function.name)); .finish("function", &format!("wasm.{}", export.function.name));
self.cx.export( self.cx.export(
&export.function.name, &export.function.name,
&js, &js,
Some(format_doc_comments(&export.comments)), Some(format_doc_comments(&export.comments, Some(js_doc))),
); );
self.cx.globals.push_str("\n"); self.cx.globals.push_str("\n");
self.cx.typescript.push_str("export "); self.cx.typescript.push_str("export ");
@ -1701,10 +1700,11 @@ impl<'a, 'b> SubContext<'a, 'b> {
Some(d) => d, 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) .method(export.method, export.consumed)
.process(descriptor.unwrap_function())? .process(descriptor.unwrap_function())?
.finish("", &format!("wasm.{}", wasm_name)); .finish("", &format!("wasm.{}", wasm_name));
let class = self let class = self
.cx .cx
.exported_classes .exported_classes
@ -1712,7 +1712,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
.or_insert(ExportedClass::default()); .or_insert(ExportedClass::default());
class class
.contents .contents
.push_str(&format_doc_comments(&export.comments)); .push_str(&format_doc_comments(&export.comments, Some(js_doc)));
if !export.method { if !export.method {
class.contents.push_str("static "); class.contents.push_str("static ");
class.typescript.push_str("static "); class.typescript.push_str("static ");
@ -1960,7 +1960,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
self.cx.export( self.cx.export(
&enum_.name, &enum_.name,
&format!("Object.freeze({{ {} }})", variants), &format!("Object.freeze({{ {} }})", variants),
Some(format_doc_comments(&enum_.comments)), Some(format_doc_comments(&enum_.comments, None)),
); );
self.cx self.cx
.typescript .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 let body: String = comments
.iter() .iter()
.map(|c| format!("*{}\n", c.trim_matches('"'))) .map(|c| format!("*{}\n", c.trim_matches('"')))
.collect(); .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() { if let Some((f, mutable)) = arg.stack_closure() {
let (js, _ts) = { let (js, _ts, _js_doc) = {
let mut builder = Js2Rust::new("", self.cx); let mut builder = Js2Rust::new("", self.cx);
if mutable { if mutable {
builder builder
@ -179,7 +179,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
} }
if let Some(closure) = arg.ref_closure() { if let Some(closure) = arg.ref_closure() {
let (js, _ts) = { let (js, _ts, _js_doc) = {
let mut builder = Js2Rust::new("", self.cx); let mut builder = Js2Rust::new("", self.cx);
if closure.mutable { if closure.mutable {
builder builder

View File

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

View File

@ -41,7 +41,8 @@ fn works() {
p.gen_bindings(); p.gen_bindings();
let js = p.read_js(); let js = p.read_js();
let comments = extract_doc_comments(&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 /// Pull out all lines in a js string that start with