Skip to content

Commit 5a7fdd5

Browse files
Adding support for @implements.
1 parent afa11d3 commit 5a7fdd5

29 files changed

+582
-81
lines changed

src/compiler/checker.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29853,7 +29853,14 @@ namespace ts {
2985329853
checkSignatureDeclaration(node);
2985429854
}
2985529855

29856-
function checkJSDocAugmentsTag(node: JSDocAugmentsTag): void {
29856+
function checkJSDocImplementsTag(node: JSDocHeritageTag): void {
29857+
const classLike = getJSDocHost(node);
29858+
if (!isClassDeclaration(classLike) && !isClassExpression(classLike)) {
29859+
error(classLike, Diagnostics.JSDoc_0_is_not_attached_to_a_class, idText(node.tagName));
29860+
return;
29861+
}
29862+
}
29863+
function checkJSDocAugmentsTag(node: JSDocHeritageTag): void {
2985729864
const classLike = getJSDocHost(node);
2985829865
if (!isClassDeclaration(classLike) && !isClassExpression(classLike)) {
2985929866
error(classLike, Diagnostics.JSDoc_0_is_not_attached_to_a_class, idText(node.tagName));
@@ -32113,7 +32120,7 @@ namespace ts {
3211332120
}
3211432121
}
3211532122

32116-
const implementedTypeNodes = getClassImplementsHeritageClauseElements(node);
32123+
const implementedTypeNodes = getEffectiveImplementsTypeNodes(node);
3211732124
if (implementedTypeNodes) {
3211832125
for (const typeRefNode of implementedTypeNodes) {
3211932126
if (!isEntityNameExpression(typeRefNode.expression)) {
@@ -33331,7 +33338,9 @@ namespace ts {
3333133338
case SyntaxKind.ImportType:
3333233339
return checkImportType(<ImportTypeNode>node);
3333333340
case SyntaxKind.JSDocAugmentsTag:
33334-
return checkJSDocAugmentsTag(node as JSDocAugmentsTag);
33341+
return checkJSDocAugmentsTag(node as JSDocHeritageTag);
33342+
case SyntaxKind.JSDocImplementsTag:
33343+
return checkJSDocImplementsTag(node as JSDocHeritageTag);
3333533344
case SyntaxKind.JSDocTypedefTag:
3333633345
case SyntaxKind.JSDocCallbackTag:
3333733346
case SyntaxKind.JSDocEnumTag:

src/compiler/emitter.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,8 +1511,9 @@ namespace ts {
15111511
case SyntaxKind.JSDocThisTag:
15121512
case SyntaxKind.JSDocEnumTag:
15131513
return emitJSDocSimpleTypedTag(node as JSDocTypeTag);
1514+
case SyntaxKind.JSDocImplementsTag:
15141515
case SyntaxKind.JSDocAugmentsTag:
1515-
return emitJSDocAugmentsTag(node as JSDocAugmentsTag);
1516+
return emitJSDocHeritageTag(node as JSDocHeritageTag);
15161517
case SyntaxKind.JSDocTemplateTag:
15171518
return emitJSDocTemplateTag(node as JSDocTemplateTag);
15181519
case SyntaxKind.JSDocTypedefTag:
@@ -3396,7 +3397,7 @@ namespace ts {
33963397
emitJSDocComment(tag.comment);
33973398
}
33983399

3399-
function emitJSDocAugmentsTag(tag: JSDocAugmentsTag) {
3400+
function emitJSDocHeritageTag(tag: JSDocHeritageTag) {
34003401
emitJSDocTagName(tag.tagName);
34013402
writeSpace();
34023403
writePunctuation("{");

src/compiler/parser.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -479,9 +479,10 @@ namespace ts {
479479
visitNode(cbNode, (<JSDocPropertyLikeTag>node).name));
480480
case SyntaxKind.JSDocAuthorTag:
481481
return visitNode(cbNode, (node as JSDocTag).tagName);
482+
case SyntaxKind.JSDocImplementsTag:
482483
case SyntaxKind.JSDocAugmentsTag:
483484
return visitNode(cbNode, (node as JSDocTag).tagName) ||
484-
visitNode(cbNode, (<JSDocAugmentsTag>node).class);
485+
visitNode(cbNode, (<JSDocHeritageTag>node).class);
485486
case SyntaxKind.JSDocTemplateTag:
486487
return visitNode(cbNode, (node as JSDocTag).tagName) ||
487488
visitNode(cbNode, (<JSDocTemplateTag>node).constraint) ||
@@ -6922,9 +6923,12 @@ namespace ts {
69226923
case "author":
69236924
tag = parseAuthorTag(start, tagName, margin);
69246925
break;
6926+
case "implements":
6927+
tag = parseHeritageTag(start, tagName, SyntaxKind.JSDocImplementsTag);
6928+
break;
69256929
case "augments":
69266930
case "extends":
6927-
tag = parseAugmentsTag(start, tagName);
6931+
tag = parseHeritageTag(start, tagName, SyntaxKind.JSDocAugmentsTag);
69286932
break;
69296933
case "class":
69306934
case "constructor":
@@ -7276,8 +7280,8 @@ namespace ts {
72767280
}
72777281
}
72787282

7279-
function parseAugmentsTag(start: number, tagName: Identifier): JSDocAugmentsTag {
7280-
const result = <JSDocAugmentsTag>createNode(SyntaxKind.JSDocAugmentsTag, start);
7283+
function parseHeritageTag(start: number, tagName: Identifier, kind: SyntaxKind.JSDocAugmentsTag | SyntaxKind.JSDocImplementsTag): JSDocHeritageTag {
7284+
const result = <JSDocHeritageTag>createNode(kind, start);
72817285
result.tagName = tagName;
72827286
result.class = parseExpressionWithTypeArgumentsForAugments();
72837287
return finishNode(result);

src/compiler/types.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,7 @@ namespace ts {
468468
JSDocSignature,
469469
JSDocTag,
470470
JSDocAugmentsTag,
471+
JSDocImplementsTag,
471472
JSDocAuthorTag,
472473
JSDocClassTag,
473474
JSDocPublicTag,
@@ -1973,7 +1974,7 @@ namespace ts {
19731974

19741975
export interface ExpressionWithTypeArguments extends NodeWithTypeArguments {
19751976
kind: SyntaxKind.ExpressionWithTypeArguments;
1976-
parent: HeritageClause | JSDocAugmentsTag;
1977+
parent: HeritageClause | JSDocHeritageTag;
19771978
expression: LeftHandSideExpression;
19781979
}
19791980

@@ -2638,11 +2639,11 @@ namespace ts {
26382639
}
26392640

26402641
/**
2642+
* Represents @augments @extends and @implements
26412643
* Note that `@extends` is a synonym of `@augments`.
2642-
* Both tags are represented by this interface.
26432644
*/
2644-
export interface JSDocAugmentsTag extends JSDocTag {
2645-
kind: SyntaxKind.JSDocAugmentsTag;
2645+
export interface JSDocHeritageTag extends JSDocTag {
2646+
kind: SyntaxKind.JSDocAugmentsTag | SyntaxKind.JSDocImplementsTag;
26462647
class: ExpressionWithTypeArguments & { expression: Identifier | PropertyAccessEntityNameExpression };
26472648
}
26482649

src/compiler/utilities.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2769,6 +2769,14 @@ namespace ts {
27692769
return heritageClause && heritageClause.types.length > 0 ? heritageClause.types[0] : undefined;
27702770
}
27712771

2772+
export function getEffectiveImplementsTypeNodes(node: ClassLikeDeclaration): undefined | readonly ExpressionWithTypeArguments[]{
2773+
if(isInJSFile(node)) {
2774+
return getJSDocImplementsTags(node).map(n => n.class);
2775+
}
2776+
else {
2777+
return getClassImplementsHeritageClauseElements(node);
2778+
}
2779+
}
27722780
export function getClassImplementsHeritageClauseElements(node: ClassLikeDeclaration) {
27732781
const heritageClause = getHeritageClause(node.heritageClauses, SyntaxKind.ImplementsKeyword);
27742782
return heritageClause ? heritageClause.types : undefined;

src/compiler/utilitiesPublic.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -667,10 +667,15 @@ namespace ts {
667667
}
668668

669669
/** Gets the JSDoc augments tag for the node if present */
670-
export function getJSDocAugmentsTag(node: Node): JSDocAugmentsTag | undefined {
670+
export function getJSDocAugmentsTag(node: Node): JSDocHeritageTag | undefined {
671671
return getFirstJSDocTag(node, isJSDocAugmentsTag);
672672
}
673673

674+
/** Gets the JSDoc implements tags for the node if present */
675+
export function getJSDocImplementsTags(node: Node): readonly JSDocHeritageTag[] {
676+
return getAllJSDocTags(node, isJSDocImplementsTag);
677+
}
678+
674679
/** Gets the JSDoc class tag for the node if present */
675680
export function getJSDocClassTag(node: Node): JSDocClassTag | undefined {
676681
return getFirstJSDocTag(node, isJSDocClassTag);
@@ -787,7 +792,12 @@ namespace ts {
787792
return find(getJSDocTags(node), predicate);
788793
}
789794

790-
/** Gets all JSDoc tags of a specified kind, or undefined if not present. */
795+
/** Gets all JSDoc tags that match a specified predicate */
796+
export function getAllJSDocTags<T extends JSDocTag>(node: Node, predicate: (tag: JSDocTag) => tag is T): readonly T[] {
797+
return getJSDocTags(node).filter(predicate);
798+
}
799+
800+
/** Gets all JSDoc tags of a specified kind */
791801
export function getAllJSDocTagsOfKind(node: Node, kind: SyntaxKind): readonly JSDocTag[] {
792802
return getJSDocTags(node).filter(doc => doc.kind === kind);
793803
}
@@ -1578,10 +1588,14 @@ namespace ts {
15781588
return node.kind === SyntaxKind.JSDocAuthorTag;
15791589
}
15801590

1581-
export function isJSDocAugmentsTag(node: Node): node is JSDocAugmentsTag {
1591+
export function isJSDocAugmentsTag(node: Node): node is JSDocHeritageTag {
15821592
return node.kind === SyntaxKind.JSDocAugmentsTag;
15831593
}
15841594

1595+
export function isJSDocImplementsTag(node: Node): node is JSDocHeritageTag {
1596+
return node.kind === SyntaxKind.JSDocImplementsTag;
1597+
}
1598+
15851599
export function isJSDocClassTag(node: Node): node is JSDocClassTag {
15861600
return node.kind === SyntaxKind.JSDocClassTag;
15871601
}

src/services/jsDoc.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,9 @@ namespace ts.JsDoc {
129129
function getCommentText(tag: JSDocTag): string | undefined {
130130
const { comment } = tag;
131131
switch (tag.kind) {
132+
case SyntaxKind.JSDocImplementsTag:
132133
case SyntaxKind.JSDocAugmentsTag:
133-
return withNode((tag as JSDocAugmentsTag).class);
134+
return withNode((tag as JSDocHeritageTag).class);
134135
case SyntaxKind.JSDocTemplateTag:
135136
return withList((tag as JSDocTemplateTag).typeParameters);
136137
case SyntaxKind.JSDocTypeTag:

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -383,29 +383,30 @@ declare namespace ts {
383383
JSDocSignature = 305,
384384
JSDocTag = 306,
385385
JSDocAugmentsTag = 307,
386-
JSDocAuthorTag = 308,
387-
JSDocClassTag = 309,
388-
JSDocPublicTag = 310,
389-
JSDocPrivateTag = 311,
390-
JSDocProtectedTag = 312,
391-
JSDocReadonlyTag = 313,
392-
JSDocCallbackTag = 314,
393-
JSDocEnumTag = 315,
394-
JSDocParameterTag = 316,
395-
JSDocReturnTag = 317,
396-
JSDocThisTag = 318,
397-
JSDocTypeTag = 319,
398-
JSDocTemplateTag = 320,
399-
JSDocTypedefTag = 321,
400-
JSDocPropertyTag = 322,
401-
SyntaxList = 323,
402-
NotEmittedStatement = 324,
403-
PartiallyEmittedExpression = 325,
404-
CommaListExpression = 326,
405-
MergeDeclarationMarker = 327,
406-
EndOfDeclarationMarker = 328,
407-
SyntheticReferenceExpression = 329,
408-
Count = 330,
386+
JSDocImplementsTag = 308,
387+
JSDocAuthorTag = 309,
388+
JSDocClassTag = 310,
389+
JSDocPublicTag = 311,
390+
JSDocPrivateTag = 312,
391+
JSDocProtectedTag = 313,
392+
JSDocReadonlyTag = 314,
393+
JSDocCallbackTag = 315,
394+
JSDocEnumTag = 316,
395+
JSDocParameterTag = 317,
396+
JSDocReturnTag = 318,
397+
JSDocThisTag = 319,
398+
JSDocTypeTag = 320,
399+
JSDocTemplateTag = 321,
400+
JSDocTypedefTag = 322,
401+
JSDocPropertyTag = 323,
402+
SyntaxList = 324,
403+
NotEmittedStatement = 325,
404+
PartiallyEmittedExpression = 326,
405+
CommaListExpression = 327,
406+
MergeDeclarationMarker = 328,
407+
EndOfDeclarationMarker = 329,
408+
SyntheticReferenceExpression = 330,
409+
Count = 331,
409410
FirstAssignment = 62,
410411
LastAssignment = 74,
411412
FirstCompoundAssignment = 63,
@@ -434,9 +435,9 @@ declare namespace ts {
434435
LastStatement = 241,
435436
FirstNode = 153,
436437
FirstJSDocNode = 294,
437-
LastJSDocNode = 322,
438+
LastJSDocNode = 323,
438439
FirstJSDocTagNode = 306,
439-
LastJSDocTagNode = 322,
440+
LastJSDocTagNode = 323,
440441
}
441442
export enum NodeFlags {
442443
None = 0,
@@ -1145,7 +1146,7 @@ declare namespace ts {
11451146
}
11461147
export interface ExpressionWithTypeArguments extends NodeWithTypeArguments {
11471148
kind: SyntaxKind.ExpressionWithTypeArguments;
1148-
parent: HeritageClause | JSDocAugmentsTag;
1149+
parent: HeritageClause | JSDocHeritageTag;
11491150
expression: LeftHandSideExpression;
11501151
}
11511152
export interface NewExpression extends PrimaryExpression, Declaration {
@@ -1625,11 +1626,11 @@ declare namespace ts {
16251626
kind: SyntaxKind.JSDocTag;
16261627
}
16271628
/**
1629+
* Represents @augments @extends and @implements
16281630
* Note that `@extends` is a synonym of `@augments`.
1629-
* Both tags are represented by this interface.
16301631
*/
1631-
export interface JSDocAugmentsTag extends JSDocTag {
1632-
kind: SyntaxKind.JSDocAugmentsTag;
1632+
export interface JSDocHeritageTag extends JSDocTag {
1633+
kind: SyntaxKind.JSDocAugmentsTag | SyntaxKind.JSDocImplementsTag;
16331634
class: ExpressionWithTypeArguments & {
16341635
expression: Identifier | PropertyAccessEntityNameExpression;
16351636
};
@@ -3493,7 +3494,9 @@ declare namespace ts {
34933494
*/
34943495
function hasJSDocParameterTags(node: FunctionLikeDeclaration | SignatureDeclaration): boolean;
34953496
/** Gets the JSDoc augments tag for the node if present */
3496-
function getJSDocAugmentsTag(node: Node): JSDocAugmentsTag | undefined;
3497+
function getJSDocAugmentsTag(node: Node): JSDocHeritageTag | undefined;
3498+
/** Gets the JSDoc implements tags for the node if present */
3499+
function getJSDocImplementsTags(node: Node): readonly JSDocHeritageTag[];
34973500
/** Gets the JSDoc class tag for the node if present */
34983501
function getJSDocClassTag(node: Node): JSDocClassTag | undefined;
34993502
/** Gets the JSDoc public tag for the node if present */
@@ -3535,7 +3538,9 @@ declare namespace ts {
35353538
function getJSDocReturnType(node: Node): TypeNode | undefined;
35363539
/** Get all JSDoc tags related to a node, including those on parent nodes. */
35373540
function getJSDocTags(node: Node): readonly JSDocTag[];
3538-
/** Gets all JSDoc tags of a specified kind, or undefined if not present. */
3541+
/** Gets all JSDoc tags that match a specified predicate */
3542+
function getAllJSDocTags<T extends JSDocTag>(node: Node, predicate: (tag: JSDocTag) => tag is T): readonly T[];
3543+
/** Gets all JSDoc tags of a specified kind */
35393544
function getAllJSDocTagsOfKind(node: Node, kind: SyntaxKind): readonly JSDocTag[];
35403545
/**
35413546
* Gets the effective type parameters. If the node was parsed in a
@@ -3710,7 +3715,8 @@ declare namespace ts {
37103715
function isJSDocVariadicType(node: Node): node is JSDocVariadicType;
37113716
function isJSDoc(node: Node): node is JSDoc;
37123717
function isJSDocAuthorTag(node: Node): node is JSDocAuthorTag;
3713-
function isJSDocAugmentsTag(node: Node): node is JSDocAugmentsTag;
3718+
function isJSDocAugmentsTag(node: Node): node is JSDocHeritageTag;
3719+
function isJSDocImplementsTag(node: Node): node is JSDocHeritageTag;
37143720
function isJSDocClassTag(node: Node): node is JSDocClassTag;
37153721
function isJSDocPublicTag(node: Node): node is JSDocPublicTag;
37163722
function isJSDocPrivateTag(node: Node): node is JSDocPrivateTag;

0 commit comments

Comments
 (0)