Skip to content

Add JSDoc's @inheritDoc Support for Static Class Members for TypeScript #46719

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 7 commits into from
May 9, 2022

Conversation

Zzzen
Copy link
Contributor

@Zzzen Zzzen commented Nov 7, 2021

Fixes #23215

@typescript-bot typescript-bot added the For Backlog Bug PRs that fix a backlog bug label Nov 7, 2021
@@ -52,6 +52,6 @@

verify.quickInfoAt("1", "constructor Bar(value: number): Bar", undefined); // constructors aren't actually inherited
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does anyone have ideas why constructors aren't actually inherited?

@orta orta requested a review from sandersn November 12, 2021 11:12
@sandersn
Copy link
Member

#23215 is kind of old, and it leaves a lot of questions underspecified.

  1. Is @inheritDoc required for inheritance? jsdoc.app says no.
  2. Are other tags allowed? jsdoc.app doesn't give an example with other tags, so maybe not.
  3. Are comments allowed? jsdoc.app also doesn't give an example with a comment on the derived method.
  4. If other tags are allowed, how are they integrated? The current method seems to combine the base and derived tags all together, which doesn't make sense for param tags; the parameter names might be the same, or they might be different.
  5. If the parameter names are the same, or if both base and derived have return tags, should the inherited tags replace the old one? Probably yes.
  6. Is the case of the tag important? Probably no.
  7. Why does this only work on static members?

Answering the inheritance questions seems like a lot of work. If I were writing this, I'd be very tempted to say that (1) the derived jsdoc must have @inheritdoc (2) the derived jsdoc must have no other tags or comments.

if (declaration.modifiers?.some(modifier => modifier.kind === SyntaxKind.StaticKeyword)) {
// For nodes like `class Foo extends Bar {}`, superTypeNode refers to an ExpressionWithTypeArguments with its expression being `Bar`.
const baseClassSymbol = checker.getSymbolAtLocation(isExpressionWithTypeArguments(superTypeNode) && !superTypeNode.typeArguments?.length ? superTypeNode.expression : superTypeNode);
const symbol = baseClassSymbol?.exports?.get(declaration.symbol.name as __String);
Copy link
Member

Choose a reason for hiding this comment

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

I think the usual way is getPropertiesOfType(getDeclaredTypeOfSymbol(s)) (though I'm not 100% sure)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated. It's actually getTypeOfSymbolAtLocation because we are looking for static members of class.

////abstract class BaseClass {
//// /**
//// * Useful description always applicable
//// *
Copy link
Member

Choose a reason for hiding this comment

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

The test needs to show what happens when there's a param tag for stuff, and what happens when there's a param tag for a parameter whose name is the same between base/derived.

//// }
////
//// /**
//// * @inheritDoc
Copy link
Member

Choose a reason for hiding this comment

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

What happens if there's comment text on someProperty? Is it discarded, appended, prepended, or is inheritdoc ignored?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They should be concatenated.

@sandersn sandersn self-assigned this Dec 8, 2021
@sandersn
Copy link
Member

@Zzzen Do you want to keep working on this? Otherwise I'd like to close it to reduce the number of open PRs.

@Zzzen
Copy link
Contributor Author

Zzzen commented Mar 26, 2022

Thanks for reminding me. And yes, I'm going to finish it.

@Zzzen
Copy link
Contributor Author

Zzzen commented Mar 26, 2022

jsdoc.app says that it is provided for compatibility with Closure Compiler, which is written in java. Haven't check the source code of Closure Compiler, I think they should work like javadoc.

Inherits (copies) documentation from the "nearest" inheritable class or implementable interface into the current doc comment at this tag's location. This allows you to write more general comments higher up the inheritance tree, and to write around the copied text.
This tag is valid only in these places in a doc comment:

  • In the main description block of a method. In this case, the main description is copied from a class or interface up the hierarchy.
  • In the text arguments of the @return, @param and @throws tags of a method. In this case, the tag text is copied from the corresponding tag up the hierarchy.

See Automatic Copying of Method Comments for a more precise description of how comments are found in the inheritance hierarchy. Note that if this tag is missing, the comment is or is not automatically inherited according to rules described in that section.

Copy link
Member

@sandersn sandersn left a comment

Choose a reason for hiding this comment

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

Couple of questions, although it's quite possible that neither are fixable in this PR.

Comment on lines +389 to +397
"text": "Applicable description always.",
"kind": "text"
},
{
"text": "\n",
"kind": "lineBreak"
},
{
"text": "text over tag",
Copy link
Member

Choose a reason for hiding this comment

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

I thought @inheritDoc was supposed to insert the inherited text at the location of the tag. Here, it looks like it's getting prepended.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's appended in webstorm. 😆
bf84f3616e55995c069ab812743a75c

Copy link
Member

@sandersn sandersn left a comment

Choose a reason for hiding this comment

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

It looks to me like @inheritDoc is dropping the subclass documentation in the new tests.

@Zzzen Zzzen force-pushed the jsDocInheritDoc branch from 1d9ba28 to dfea5d0 Compare April 16, 2022 09:27
Copy link
Member

@sandersn sandersn left a comment

Choose a reason for hiding this comment

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

This is OK as-is, but I don't want to merge until after 4.7 beta is over.

In the meantime, it's OK for

/**
 * over
 * @inheritDoc
 * under
 */

To produce "Base\nover\under", but I still think it'd be better to produce "over\nBase\under".

const symbol = checker.getPropertyOfType(checker.getTypeAtLocation(superTypeNode), declaration.symbol.name);
const baseType = checker.getTypeAtLocation(superTypeNode);
const symbol = isStaticMember
? find(checker.getExportsOfModule(baseType.symbol), s => s.escapedName === declaration.symbol.name)
Copy link
Member

@DanielRosenwasser DanielRosenwasser May 11, 2022

Choose a reason for hiding this comment

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

getExportsOfModule on the non-merged symbol of something that isn't a module? This doesn't seem right.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Backlog Bug PRs that fix a backlog bug
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Add JSDoc's @inheritDoc Support for Static Class Members for TypeScript
5 participants