Skip to content

Commit

Permalink
feat: Support multiple internal/deprecated tags.
Browse files Browse the repository at this point in the history
  • Loading branch information
cartant committed Mar 19, 2021
1 parent 750e6d0 commit 20eb236
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 49 deletions.
24 changes: 13 additions & 11 deletions source/rules/no-deprecated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { TSESTree as es } from "@typescript-eslint/experimental-utils";
import { getParent, getParserServices } from "eslint-etc";
import * as ts from "typescript";
import { findTaggedNames } from "../tag";
import { getTag, isDeclaration } from "../tslint-tag";
import { getTags, isDeclaration } from "../tslint-tag";
import { ruleCreator } from "../utils";

const deprecatedNamesByProgram = new WeakMap<ts.Program, Set<string>>();
Expand Down Expand Up @@ -92,16 +92,18 @@ const rule = ruleCreator({
) {
return;
}
const tag = getTag("deprecated", identifier, typeChecker);
if (tag !== undefined) {
context.report({
data: {
comment: tag.trim().replace(/[\n\r\s\t]+/g, " "),
name: identifier.text,
},
messageId: "forbidden",
node,
});
const tags = getTags("deprecated", identifier, typeChecker);
if (tags.length > 0) {
for (const tag of tags) {
context.report({
data: {
comment: tag.trim().replace(/[\n\r\s\t]+/g, " "),
name: identifier.text,
},
messageId: "forbidden",
node,
});
}
}
},
};
Expand Down
21 changes: 13 additions & 8 deletions source/rules/no-internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { TSESTree as es } from "@typescript-eslint/experimental-utils";
import { getParent, getParserServices } from "eslint-etc";
import * as ts from "typescript";
import { findTaggedNames } from "../tag";
import { getTag, isDeclaration } from "../tslint-tag";
import { getTags, isDeclaration } from "../tslint-tag";
import { ruleCreator } from "../utils";

// https://api-extractor.com/pages/tsdoc/tag_internal/
Expand Down Expand Up @@ -94,13 +94,18 @@ const rule = ruleCreator({
) {
return;
}
const comment = getTag("internal", identifier, typeChecker);
if (comment !== undefined) {
context.report({
data: { comment, name: identifier.text },
messageId: "forbidden",
node,
});
const tags = getTags("internal", identifier, typeChecker);
if (tags.length > 0) {
for (const tag of tags) {
context.report({
data: {
comment: tag.trim().replace(/[\n\r\s\t]+/g, " "),
name: identifier.text,
},
messageId: "forbidden",
node,
});
}
}
},
};
Expand Down
60 changes: 30 additions & 30 deletions source/tslint-tag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,18 @@ function getCallExpresion(
: undefined;
}

export function getTag(
export function getTags(
tagName: string,
node: ts.Identifier,
tc: ts.TypeChecker
): string | undefined {
): string[] {
const callExpression = getCallExpresion(node);
if (callExpression !== undefined) {
const result = getSignatureTag(
const result = getSignatureTags(
tagName,
tc.getResolvedSignature(callExpression)
);
if (result !== undefined) {
if (result.length > 0) {
return result;
}
}
Expand Down Expand Up @@ -119,51 +119,49 @@ export function getTag(
// stop here to avoid collecting JsDoc of all overload signatures
(callExpression !== undefined && isFunctionOrMethod(symbol.declarations))
) {
return undefined;
return [];
}
return getSymbolTag(tagName, symbol);
return getSymbolTags(tagName, symbol);
}

function findTag(tagName: string, tags: ts.JSDocTagInfo[]): string | undefined {
function findTags(tagName: string, tags: ts.JSDocTagInfo[]): string[] {
const result: string[] = [];
for (const tag of tags) {
if (tag.name === tagName) {
return tag.text === undefined ? "" : tag.text;
result.push(tag.text === undefined ? "" : tag.text);
}
}
return undefined;
return result;
}

function getSymbolTag(tagName: string, symbol: ts.Symbol): string | undefined {
function getSymbolTags(tagName: string, symbol: ts.Symbol): string[] {
if (symbol.getJsDocTags !== undefined) {
return findTag(tagName, symbol.getJsDocTags());
return findTags(tagName, symbol.getJsDocTags());
}
// for compatibility with typescript@<2.3.0
return getDeprecationFromDeclarations(tagName, symbol.declarations);
return getDeprecationsFromDeclarations(tagName, symbol.declarations);
}

function getSignatureTag(
tagName: string,
signature?: ts.Signature
): string | undefined {
function getSignatureTags(tagName: string, signature?: ts.Signature): string[] {
if (signature === undefined) {
return undefined;
return [];
}
if (signature.getJsDocTags !== undefined) {
return findTag(tagName, signature.getJsDocTags());
return findTags(tagName, signature.getJsDocTags());
}

// for compatibility with typescript@<2.3.0
return signature.declaration === undefined
? undefined
: getDeprecationFromDeclaration(tagName, signature.declaration);
? []
: getDeprecationsFromDeclaration(tagName, signature.declaration);
}

function getDeprecationFromDeclarations(
function getDeprecationsFromDeclarations(
tagName: string,
declarations?: ts.Declaration[]
): string | undefined {
): string[] {
if (declarations === undefined) {
return undefined;
return [];
}
let declaration: ts.Node;
for (declaration of declarations) {
Expand All @@ -176,29 +174,31 @@ function getDeprecationFromDeclarations(
if (tsutils.isVariableDeclarationList(declaration)) {
declaration = declaration.parent;
}
const result = getDeprecationFromDeclaration(tagName, declaration);
if (result !== undefined) {
const result = getDeprecationsFromDeclaration(tagName, declaration);
if (result.length > 0) {
return result;
}
}
return undefined;
return [];
}

function getDeprecationFromDeclaration(
function getDeprecationsFromDeclaration(
tagName: string,
declaration: ts.Node
): string | undefined {
): string[] {
const result: string[] = [];
for (const comment of tsutils.getJsDoc(declaration)) {
if (comment.tags === undefined) {
continue;
}
console.log(comment.tags);
for (const tag of comment.tags) {
if (tag.tagName.text === tagName) {
return tag.comment === undefined ? "" : tag.comment;
result.push(tag.comment === undefined ? "" : tag.comment);
}
}
}
return undefined;
return result;
}

function isFunctionOrMethod(declarations?: ts.Declaration[]) {
Expand Down
13 changes: 13 additions & 0 deletions tests/rules/no-deprecated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,5 +349,18 @@ ruleTester({ comments: true, types: true }).run("no-deprecated", rule, {
~~~~ [forbidden { "comment": "Don't use this function", "name": "func" }]
`
),
fromFixture(
stripIndent`
// Multiple deprecated tags
/**
* @deprecated This function is slow
* @deprecated This function is buggy
*/
declare function func(): void;
func();
~~~~ [forbidden { "comment": "This function is slow", "name": "func" }]
~~~~ [forbidden { "comment": "This function is buggy", "name": "func" }]
`
),
],
});
13 changes: 13 additions & 0 deletions tests/rules/no-internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,5 +325,18 @@ ruleTester({ comments: true, types: true }).run("no-internal", rule, {
],
}
),
fromFixture(
stripIndent`
// Multiple internal tags
/**
* @internal This function is internal
* @internal This function is experimental
*/
declare function func(): void;
func();
~~~~ [forbidden { "comment": "This function is internal", "name": "func" }]
~~~~ [forbidden { "comment": "This function is experimental", "name": "func" }]
`
),
],
});

0 comments on commit 20eb236

Please sign in to comment.