Skip to content

Commit

Permalink
better-js-doc
Browse files Browse the repository at this point in the history
  • Loading branch information
Brendonovich committed Oct 4, 2023
1 parent 8eeec58 commit 4309920
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 47 deletions.
97 changes: 89 additions & 8 deletions src/lang/js_doc.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::borrow::Borrow;

use crate::*;

pub use super::ts::*;
Expand Down Expand Up @@ -32,13 +34,92 @@ fn format_comment_inner(

let inline_ts = datatype_inner(ctx.clone(), &typ.inner, type_map)?;

Ok(comments::js_doc_internal(
let mut builder = ts::comments::js_doc_builder(CommentFormatterArgs {
docs,
deprecated.as_ref(),
item.generics()
.into_iter()
.flatten()
.map(|generic| format!("@template {}", generic))
.chain([format!(r#"@typedef {{ {inline_ts} }} {name}"#).into()]),
))
deprecated: deprecated.as_ref(),
});

item.generics()
.into_iter()
.flatten()
.for_each(|generic| builder.push_generic(generic));

builder.push_internal(["@typedef { ", &inline_ts, " } ", &name]);

Ok(builder.build())
}

const START: &str = "/**\n";

pub struct Builder {
value: String,
}

impl Builder {
pub fn push(&mut self, line: &str) {
self.push_internal([line.trim()]);
}

pub(crate) fn push_internal<'a>(&mut self, parts: impl IntoIterator<Item = &'a str>) {
self.value.push_str(" * ");

for part in parts.into_iter() {
self.value.push_str(part);
}

self.value.push_str("\n");

Check warning on line 70 in src/lang/js_doc.rs

View workflow job for this annotation

GitHub Actions / clippy

calling `push_str()` using a single-character string literal

warning: calling `push_str()` using a single-character string literal --> src/lang/js_doc.rs:70:9 | 70 | self.value.push_str("\n"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `self.value.push('\n')` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#single_char_add_str = note: `#[warn(clippy::single_char_add_str)]` implied by `#[warn(clippy::all)]`
}

pub fn push_deprecated(&mut self, typ: &DeprecatedType) {
self.push_internal(
["@deprecated"].into_iter().chain(
match typ {
DeprecatedType::DeprecatedWithSince {
note: message,
since,
} => Some((since.as_ref(), message)),
_ => None,
}
.map(|(since, message)| {
[" ", message.trim()].into_iter().chain(
since
.map(|since| [" since ", since.trim()])
.into_iter()
.flatten(),
)
})
.into_iter()
.flatten(),
),
);
}

pub fn push_generic(&mut self, generic: &GenericType) {
self.push_internal(["@template ", generic.borrow()])
}

pub fn build(mut self) -> String {
if self.value == START {
return String::new();
}

self.value.push_str(" */\n");
self.value
}
}

impl Default for Builder {
fn default() -> Self {
Self {
value: START.to_string(),
}
}
}

impl<T: AsRef<str>> Extend<T> for Builder {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
for item in iter {
self.push(item.as_ref());
}
}
}
48 changes: 9 additions & 39 deletions src/lang/ts/comments.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use std::{borrow::Cow, iter};

use crate::DeprecatedType;
use crate::js_doc;

use super::{CommentFormatterArgs, CommentFormatterFn};

Expand All @@ -9,47 +7,19 @@ const _: CommentFormatterFn = js_doc;

/// Converts Typescript comments into JSDoc comments.
pub fn js_doc(arg: CommentFormatterArgs) -> String {
js_doc_internal(arg.docs, arg.deprecated, iter::empty())
js_doc_builder(arg).build()
}

pub(crate) fn js_doc_internal(
docs: &Cow<'static, str>,
deprecated: Option<&DeprecatedType>,
extra_lines: impl Iterator<Item = String>,
) -> String {
if docs.is_empty() && deprecated.is_none() {
return "".into();
}
pub(crate) fn js_doc_builder(arg: CommentFormatterArgs) -> js_doc::Builder {
let mut builder = js_doc::Builder::default();

let mut comment = String::with_capacity(docs.len());
comment.push_str("/**\n");
if !docs.is_empty() {
for line in docs.split('\n') {
comment.push_str(" * ");
comment.push_str(line.trim());
comment.push('\n');
}
if !arg.docs.is_empty() {
builder.extend(arg.docs.split('\n'));
}

if let Some(deprecated) = deprecated {
comment.push_str(" * @deprecated");
if let DeprecatedType::DeprecatedWithSince {
since,
note: message,
} = deprecated
{
comment.push_str(" ");
comment.push_str(message);
if let Some(since) = since {
comment.push_str(" since ");
comment.push_str(since);
}
}
comment.push('\n');
if let Some(deprecated) = arg.deprecated {
builder.push_deprecated(&deprecated);

Check warning on line 21 in src/lang/ts/comments.rs

View workflow job for this annotation

GitHub Actions / clippy

this expression creates a reference which is immediately dereferenced by the compiler

warning: this expression creates a reference which is immediately dereferenced by the compiler --> src/lang/ts/comments.rs:21:33 | 21 | builder.push_deprecated(&deprecated); | ^^^^^^^^^^^ help: change this to: `deprecated` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow note: the lint level is defined here --> src/lib.rs:3:9 | 3 | #![warn(clippy::all, clippy::unwrap_used, clippy::panic)] // TODO: missing_docs | ^^^^^^^^^^^ = note: `#[warn(clippy::needless_borrow)]` implied by `#[warn(clippy::all)]`
}

comment.extend(extra_lines);
comment.push_str(" */\n");

comment
builder
}

0 comments on commit 4309920

Please sign in to comment.