Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Smarter enhancement of JSDoc comments with a JSDoc parser #4310

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Finished JSDoc parser
  • Loading branch information
RunDevelopment committed Nov 30, 2024
commit 8cc978c52c76cd230a0b9199ed7287a69cab14c6
54 changes: 46 additions & 8 deletions crates/cli-support/src/js/jsdoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,9 @@ impl std::fmt::Display for JsDocTag {
if let Some(ty) = &tag.ty {
write!(f, " {{{}}}", ty)?
}
if !tag.description.is_empty() {
if tag.description.starts_with(['\r', '\n']) {
write!(f, "{}", tag.description)?;
} else if !tag.description.is_empty() {
write!(f, " {}", tag.description)?;
}
}
Expand All @@ -214,12 +216,23 @@ impl ParamTag {
fn parse(tag_name: &str, rest: &str) -> Option<Self> {
let mut text = trim_left(rest);

let mut optional_by_type = false;

let mut ty = None;
if text.starts_with('{') {
ty = consume_type_script_expression(&text[1..]).map(|t| t.to_string());
let mut type_len = 0;
ty = consume_type_script_expression(&text[1..]).map(|mut t| {
type_len = t.len() + 2;
t = t.trim_matches(' ');
if t.ends_with('=') {
optional_by_type = true;
t = t[..t.len() - 1].trim_matches(' ');
}
t.to_string()
});

if let Some(ty) = &ty {
text = trim_left(&text[(ty.len() + 2)..]);
text = trim_left(&text[type_len..]);
} else {
// the type expression is not terminated, so the tag is not well-formed
return None;
Expand Down Expand Up @@ -267,7 +280,7 @@ impl ParamTag {
return None;
};
text = trim_left_space(&text[name.len()..]);
(Optionality::Required, name.to_string())
(if optional_by_type {Optionality::Optional} else {Optionality::Required}, name.to_string())
};

Some(Self {
Expand All @@ -282,14 +295,22 @@ impl ParamTag {

impl ReturnsTag {
fn parse(tag_name: &str, rest: &str) -> Option<Self> {
let mut text = trim_left(rest);
// A bit careful now, because we want to keep the initial new lines of
// the description.
let mut text ={let trimmed = trim_left(rest);
if trimmed.starts_with('{') {
trimmed
} else {
trim_left_space(rest)
}
};

let mut ty = None;
if text.starts_with('{') {
ty = consume_type_script_expression(&text[1..]).map(|t| t.to_string());

if let Some(ty) = &ty {
text = trim_left(&text[(ty.len() + 2)..]);
text = trim_left_space(&text[(ty.len() + 2)..]);
} else {
// the type expression is not terminated, so the tag is not well-formed
return None;
Expand Down Expand Up @@ -701,13 +722,29 @@ mod tests {
"@param {string} obj.name",
"@param {object[]} obj.locations",
"@param {string} obj.locations[].address",
"@param {string} [obj.locations[].address]",
"@param {} foo",
]);
// weird
suite.test_lines(&[
"@param {string} foo",
"@param{string}foo ",
"@param{string}[foo]",
"@param{string}[foo=]",
"@param { string } [ foo = 123 ]",
"@param { } [ foo = 123 ]",
]);
// weird types
suite.test_lines(&[
"@param {",
"string",
"} foo",
"@param {string // comment",
"| number} foo",
"@param { number = } foo",
"@param { = } foo",
"@param {{"," name: { first: string, last: string };","}} foo",
"@param {'}' | \"}\" | `}${{'}': \"}\"}}}`} foo",
]);
// alias
suite.test_lines(&[
Expand All @@ -723,10 +760,11 @@ mod tests {
suite.test_lines(&[
"@returns",
"@returns description",
"@returns\ndescription", // FIXME:
"@returns\ndescription",
"@returns {string}",
"@returns\n\n\n{number}",
"@returns {string} description",
"@returns {string}\ndescription", // FIXME:
"@returns {string}\ndescription",
]);
// weird
suite.test_lines(&[
Expand Down
181 changes: 177 additions & 4 deletions crates/cli-support/tests/snapshots/jsdoc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ Input: |
@param {string} obj.name
@param {object[]} obj.locations
@param {string} obj.locations[].address
@param {string} [obj.locations[].address]
@param {} foo

Output: |
Expand All @@ -138,6 +139,7 @@ Output: |
@param {string} obj.name
@param {object[]} obj.locations
@param {string} obj.locations[].address
@param {string} [obj.locations[].address]
@param {} foo

Ast: |
Expand Down Expand Up @@ -345,6 +347,17 @@ Ast: |
description: "",
},
),
Param(
ParamTag {
tag: "@param",
ty: Some(
"string",
),
name: "obj.locations[].address",
optional: Optional,
description: "",
},
),
Param(
ParamTag {
tag: "@param",
Expand All @@ -365,11 +378,17 @@ Input: |
@param {string} foo
@param{string}foo
@param{string}[foo]
@param{string}[foo=]
@param { string } [ foo = 123 ]
@param { } [ foo = 123 ]

Output: |
@param {string} foo
@param {string} foo
@param {string} [foo]
@param {string} [foo]
@param {string} [foo=123]
@param {} [foo=123]

Ast: |
JsDoc {
Expand Down Expand Up @@ -408,6 +427,144 @@ Ast: |
description: "",
},
),
Param(
ParamTag {
tag: "@param",
ty: Some(
"string",
),
name: "foo",
optional: Optional,
description: "",
},
),
Param(
ParamTag {
tag: "@param",
ty: Some(
"string",
),
name: "foo",
optional: OptionalWithDefault(
"123",
),
description: "",
},
),
Param(
ParamTag {
tag: "@param",
ty: Some(
"",
),
name: "foo",
optional: OptionalWithDefault(
"123",
),
description: "",
},
),
],
}

---

Input: |
@param {
string
} foo
@param {string // comment
| number} foo
@param { number = } foo
@param { = } foo
@param {{
name: { first: string, last: string };
}} foo
@param {'}' | "}" | `}${{'}': "}"}}}`} foo

Output: |
@param {
string
} foo
@param {string // comment
| number} foo
@param {number} [foo]
@param {} [foo]
@param {{
name: { first: string, last: string };
}} foo
@param {'}' | "}" | `}${{'}': "}"}}}`} foo

Ast: |
JsDoc {
description: None,
tags: [
Param(
ParamTag {
tag: "@param",
ty: Some(
"\nstring\n",
),
name: "foo",
optional: Required,
description: "",
},
),
Param(
ParamTag {
tag: "@param",
ty: Some(
"string // comment\n| number",
),
name: "foo",
optional: Required,
description: "",
},
),
Param(
ParamTag {
tag: "@param",
ty: Some(
"number",
),
name: "foo",
optional: Optional,
description: "",
},
),
Param(
ParamTag {
tag: "@param",
ty: Some(
"",
),
name: "foo",
optional: Optional,
description: "",
},
),
Param(
ParamTag {
tag: "@param",
ty: Some(
"{\n name: { first: string, last: string };\n}",
),
name: "foo",
optional: Required,
description: "",
},
),
Param(
ParamTag {
tag: "@param",
ty: Some(
"'}' | \"}\" | `}${{'}': \"}\"}}}`",
),
name: "foo",
optional: Required,
description: "",
},
),
],
}

Expand Down Expand Up @@ -480,17 +637,24 @@ Input: |
@returns
description
@returns {string}
@returns


{number}
@returns {string} description
@returns {string}
description

Output: |
@returns
@returns description
@returns description
@returns
description
@returns {string}
@returns {number}
@returns {string} description
@returns {string} description
@returns {string}
description

Ast: |
JsDoc {
Expand All @@ -514,7 +678,7 @@ Ast: |
ReturnsTag {
tag: "@returns",
ty: None,
description: "description",
description: "\ndescription",
},
),
Returns(
Expand All @@ -526,6 +690,15 @@ Ast: |
description: "",
},
),
Returns(
ReturnsTag {
tag: "@returns",
ty: Some(
"number",
),
description: "",
},
),
Returns(
ReturnsTag {
tag: "@returns",
Expand All @@ -541,7 +714,7 @@ Ast: |
ty: Some(
"string",
),
description: "description",
description: "\ndescription",
},
),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,11 @@ export function docme(arg: number): number;
* Regular documentation.
*/
export function i_has_docs(arg: number): number;
/**
* Regular documentation.
*
* @param [b=0] Description of `arg`.
* @param d Another description.
* @returns
*/
export function add(a: number, b?: number, c?: number, d?: number): number;
Loading