Skip to content

Simplify getJSDocCommentAndTags #24997

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

Merged
merged 3 commits into from
Jun 19, 2018
Merged

Conversation

sandersn
Copy link
Member

@sandersn sandersn commented Jun 15, 2018

Previously, getJSDocCommentAndTags could recur up to four times if any of four predicates matched. However, to avoid duplicates, the predicates have been tuned to be mutually exclusive, which means that the recursion can be turned into a while loop. The while loop is much simpler and safer, since it is guaranteed to only walk up the tree one time. In addition, the extra check that adds jsdoc from initializers only runs once, before the loop, further reducing the opportunity for duplicate jsdocs.

I thought about further simplifying the code that gets the next node to check, but to know when to stop the loop, I'd need a predicate that is as complicated as the code in getNextJSDocCommentLocation, so I kept the existing code, just reordering it for compactness.

Note that this change reverses the order of multiple jsdocs for a single parameter or function expression, since those can have 3 and 2 locations, respectively. I don't think this is a problem because such cases are likely to be (1) rare (2) a mistake. I filed #24996 to make duplicated jsdocs an error.

Fixes #25067

Previously, getJSDocCommentAndTags could recur up to four times if any
of four predicates matched. However, to avoid duplicates, the predicates
have been tuned to be mutually exclusive, which means that the recursion
can be turned into a while loop. The while loop is much simpler and
safer, since it is guaranteed to only walk up the tree one time. In
addition, the extra check that adds jsdoc from initializers only runs
once, before the loop, further reducing the opportunity for duplicate
jsdocs.

I thought about further simplifying the code that gets the next node to
check, but to know when to stop the loop, I'd need a predicate that is
as complicated as the code in `getNextJSDocCommentLocation`, so I kept
the existing code, just reordering it for compactness.
@sandersn sandersn requested a review from a user June 15, 2018 18:27
}
else if (parent.parent && parent.parent.parent &&
(getSingleVariableOfVariableStatement(parent.parent.parent) ||
getSingleInitializerOfVariableStatementOrPropertyDeclaration(parent.parent.parent) === node ||
Copy link

Choose a reason for hiding this comment

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

Why do we test for both parent.parent and parent.parent.parent versions of this? Doesn't this mean we would add jsdoc for a child of an initializer?

@sandersn
Copy link
Member Author

The parent.parent.parent check catches

  1. Variable declarations with no initializers: /** doc */ var f: () => void; and
/**
 * @callback FooHandler2
 * @param {string=} eventName
 * @param {string} [eventName2]
 */
/**
 * @type {FooHandler2} callback
 */
var t2;

The parent.parent check catches

  1. Variable declaration names. /** @type {x} */ var z = y should use the type x, not the type of y.

I'll think about which other things might also follow this code path. If I can construct a broken test case, then I'll see about tightening these predicates.

@sandersn
Copy link
Member Author

We won't add jsdoc for the child of an initializer because parent.parent.parent is still only the VariableDeclarationList of VariableStatement. Still, it's not actually correct to treat the type annotation for a declaration as a type annotation for the initializer too; instead, the initializer is supposed to get a contextual type that comes from the variable declaration.

Hmm, actually, I uncovered another oddity in getContextualSignature: it checks the jsdoc type annotation before actually looking for a contextual type. Removing this check breaks a few things, but those things should be using the standard path through getEffectiveTypeAnnotationNode.

I'd like to merge this and deal with any fallout first, and then I'll further simplify+tighten the checking afterward, starting with the odd jsdoc handling in getContextualSignature.

@sandersn sandersn merged commit 03fff50 into master Jun 19, 2018
@sandersn sandersn deleted the simplify-getJSDocCommentAndTags branch June 19, 2018 17:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant