Skip to content

Add support for the @see tag #236

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 9 commits into from
May 20, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
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
31 changes: 31 additions & 0 deletions tsdoc/src/details/StandardTags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,36 @@ export class StandardTags {
standardization: Standardization.Extended
});

/**
* (Extended)
*
* Used to document another symbol or resource that may be related to the current item being documented.
*
* @remarks
*
* For example:
*
* ```ts
* /**
* * Link to the bar function.
* * @see {@link bar}
* */
* function foo() {}

* // Use the inline {@link} tag to include a link within a free-form description.
* /**
* * @see {@link foo} for further information.
* * @see {@link http://github.com|GitHub}
* */
* function bar() {}
* ```
*/
public static readonly see: TSDocTagDefinition = StandardTags._defineTag({
tagName: '@see',
syntaxKind: TSDocTagSyntaxKind.BlockTag,
standardization: Standardization.Extended
});

/**
* (Extended)
*
Expand Down Expand Up @@ -420,6 +450,7 @@ export class StandardTags {
StandardTags.remarks,
StandardTags.returns,
StandardTags.sealed,
StandardTags.see,
StandardTags.throws,
StandardTags.typeParam,
StandardTags.virtual
Expand Down
1 change: 1 addition & 0 deletions tsdoc/src/emitters/TSDocEmitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ export class TSDocEmitter {
docComment.typeParams,
docComment.returnsBlock,
...docComment.customBlocks,
...docComment.seeBlocks,
docComment.inheritDocTag
]);
if (docComment.modifierTagSet.nodes.length > 0) {
Expand Down
17 changes: 17 additions & 0 deletions tsdoc/src/nodes/DocComment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export class DocComment extends DocNode {
*/
public readonly modifierTagSet: StandardModifierTagSet;

private _seeBlocks: DocBlock[];
private _customBlocks: DocBlock[];

/**
Expand All @@ -106,6 +107,7 @@ export class DocComment extends DocNode {

this.modifierTagSet = new StandardModifierTagSet();

this._seeBlocks = []
this._customBlocks = [];
}

Expand All @@ -114,13 +116,27 @@ export class DocComment extends DocNode {
return DocNodeKind.Comment;
}

/**
* The collection of all `@see` DockBlockTag nodes belonging to this doc comment.
*/
public get seeBlocks(): ReadonlyArray<DocBlock> {
return this._seeBlocks;
}

/**
* The collection of all DocBlock nodes belonging to this doc comment.
*/
public get customBlocks(): ReadonlyArray<DocBlock> {
return this._customBlocks;
}

/**
* Append an item to the seeBlocks collection.
*/
public appendSeeBlock(block: DocBlock): void {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmm... this API feels weird to me. The original design is that the "core" tags (Standardization.Core) would get dedicated properties in the DocComment API, and then all other tags would go into the customBlocks array.

But this has a downside that any code relying on customBlocks will get broken by an update that promotes a block to being "core". And we seem to need helpers like appendSeeBlock() for each property.

Perhaps a better design would be to deprecate customBlocks and replace it with a collection blocks that simply includes ALL the blocks. Then helpers like seeBlocks would be a shorthand for something like this:

  public getBlocksOfType(tag: TSDocTagDefinition): ReadonlyArray<DocBlock> {
    return this._blocks.filter(x => x.blockTag.tagNameWithUpperCase === tag.tagNameWithUpperCase);
  }

  public get seeBlocks(): ReadonlyArray<DocBlock> {
    return this.getBlocksOfType(StandardTags.see);
  }

@hbergren Do you like this design better? If so we can implement it in a separate PR.

Copy link
Collaborator

@octogonz octogonz May 10, 2020

Choose a reason for hiding this comment

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

Looking more closely at the code, it seems that customBlocks is also used by TSDocEmitter when rearranging the blocks into a normalized order. The summary/remarks/params/returns are ordered first, then all the "custom blocks" can be emitted afterwards. I feel like we can find a better design for that, which avoids this problem of breaking the API whenever we promote a tag to be standardized.

But fixing that problem should probably be tackled separately from introducing DocComment.blocks to support the improvement proposed above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm... this API feels weird to me. Perhaps a better design would be to deprecate customBlocks and replace it with a collection blocks that simply includes ALL the blocks.

I think your proposed design is pretty solid. I'm happy to help implement that in a future PR.

How would that potentially work with TSDocEmitter? We ensure that the this._blocks property is ordered before it gets to TSDocEmitter?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's address this issue in a separate PR. When I started to prototype it, it has some design questions of its own. I am okay with temporarily introducing appendSeeBlock() to get this PR merged. We can mark the API as @internal for now.

this._seeBlocks.push(block);
}

/**
* Append an item to the customBlocks collection.
*/
Expand All @@ -139,6 +155,7 @@ export class DocComment extends DocNode {
this.typeParams.count > 0 ? this.typeParams : undefined,
this.returnsBlock,
...this.customBlocks,
...this.seeBlocks,
this.inheritDocTag,
...this.modifierTagSet.nodes
];
Expand Down
3 changes: 3 additions & 0 deletions tsdoc/src/parser/NodeParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,9 @@ export class NodeParser {
case StandardTags.returns.tagNameWithUpperCase:
docComment.returnsBlock = block;
break;
case StandardTags.see.tagNameWithUpperCase:
docComment.appendSeeBlock(block);
break;
default:
docComment.appendCustomBlock(block);
}
Expand Down