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

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

RunDevelopment
Copy link
Contributor

Resolves #4223.
Resolves #1847.

This PR improves the type information is added to JSDoc comments. Instead of just adding @param and @returns tags to existing JSDoc comments, WBG will now parse the existing comment and add type information to existing tags (if any). This makes skip_jsdoc virtually unnecessary, since WBG won't generate tag that conflict with existing tags anymore. (Note that skip_jsdoc still has niche use cases.)

Example:

/// Some comment
/// @param a This is the first parameter.
#[wasm_bindgen]
pub fn foo(a: u32, b: &str) -> u32 { ... }
/**
 * Some comment
 * @param {number} a This is the first parameter.
 * @param {string} b
 * @returns {number}
 */
export function foo(a, b) { ... }

This behavior can be turned off with skip_jsdoc

/// Some comment
/// @param a This is the first parameter.
#[wasm_bindgen]
pub fn foo(a: u32, b: &str) -> u32 { ... }
/**
 * Some comment
 * @param a This is the first parameter.
 */
export function foo(a, b) { ... }

With the new smarter behavior, users documenting their code with standard JSDoc/TSDoc can now use @param/@returns tags without having WBG mess it up or having to using skip_jsdoc and duplicating the type info. WBG's JSDoc comment enhancement now works together with our users.

Moving forward, I believe that we should teach people to WBG will automatically add type information for them, and they should not manually add type info to @param and @returns tags at all. This has several advantages, one being that users don't get any ideas about trying to declare custom types as @param {1 | 2 | 3} arg, which does not affect the TS types. Once we have a way for users to declare custom TS type annotations, they will just work with the new JSDoc enhancements.


The main complexity of this PR is:

  1. The new JSDoc parser. I made a custom JSDoc parser in around 600 LoC (including comments).
  2. Functionality for modifying the parsed JSDoc AST. This is the logic for actually adding type info to existing JSDoc and is around 150 LoC (including comments).
  3. Testing the parser. The parser needs to handle a lot of edge cases, so I added a new snapshot test for it.

The parser is written in a way that makes any string valid JSDoc. This can also be seen by the signature of the parsing function: fn parse(comment: &str) -> JsDoc. The doc comment on the function explains how this is done. In generally, I extensively documented the parser. If you have any question regarding how the parser works, the answer is probably in a comment.

For the tags that are supported, the implementation is fairly complete. The parser supports all sorts of mean constructs like multiple-line TS types, comments in TS types, default values, and argument paths (e.g. @param {number} arg0.age). So it's fairly complete for what it supports. See the snapshot test for many more examples.

Comment on lines +459 to +460
/// A version trim_start that ignores text direction.
fn trim_left(s: &str) -> &str {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made three functions for trimming, because I don't understand the text direction behavior of trim_start. JSDoc is inherently left to right, so I don't know how this will interact with Arabic text.

Am I just paranoid here? Should I just use the std functions?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant