From 31d32555988dca786726420246efcd1589c07316 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sun, 28 Jul 2024 00:42:27 +0800 Subject: [PATCH] feat(`require-template`, `check-template-names`): add support `ClassDeclaration` --- .README/rules/check-template-names.md | 4 +- .README/rules/require-template.md | 4 +- docs/rules/check-template-names.md | 76 +++++++++- docs/rules/require-template.md | 72 ++++++++- src/rules/checkTemplateNames.js | 3 + src/rules/requireTemplate.js | 4 + test/rules/assertions/checkTemplateNames.js | 156 ++++++++++++++++++++ test/rules/assertions/requireTemplate.js | 136 +++++++++++++++++ 8 files changed, 447 insertions(+), 8 deletions(-) diff --git a/.README/rules/check-template-names.md b/.README/rules/check-template-names.md index 6c8b4fa3..34aaef77 100644 --- a/.README/rules/check-template-names.md +++ b/.README/rules/check-template-names.md @@ -3,8 +3,8 @@ Checks that any `@template` names are actually used in the connected `@typedef` or type alias. -Currently checks `FunctionDeclaration`, `TSInterfaceDeclaration` or -`TSTypeAliasDeclaration` such as: +Currently checks `ClassDeclaration`, `FunctionDeclaration`, +`TSInterfaceDeclaration` or `TSTypeAliasDeclaration` such as: ```ts /** diff --git a/.README/rules/require-template.md b/.README/rules/require-template.md index e8ca4577..f90cad4c 100644 --- a/.README/rules/require-template.md +++ b/.README/rules/require-template.md @@ -3,8 +3,8 @@ Checks to see that `@template` tags are present for any detected type parameters. -Currently checks `FunctionDeclaration`, `TSInterfaceDeclaration` or -`TSTypeAliasDeclaration` such as: +Currently checks `ClassDeclaration`, `FunctionDeclaration`, +`TSInterfaceDeclaration` or `TSTypeAliasDeclaration` such as: ```ts export type Pairs = [D, V | undefined]; diff --git a/docs/rules/check-template-names.md b/docs/rules/check-template-names.md index 091ae178..a990ca89 100644 --- a/docs/rules/check-template-names.md +++ b/docs/rules/check-template-names.md @@ -5,8 +5,8 @@ Checks that any `@template` names are actually used in the connected `@typedef` or type alias. -Currently checks `FunctionDeclaration`, `TSInterfaceDeclaration` or -`TSTypeAliasDeclaration` such as: +Currently checks `ClassDeclaration`, `FunctionDeclaration`, +`TSInterfaceDeclaration` or `TSTypeAliasDeclaration` such as: ```ts /** @@ -150,6 +150,46 @@ export default function identity(arg: Type): Type { return arg; } // Message: @template D not in use + +/** + * @template D + * @template V + */ +class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; +} +// Message: @template D not in use + +/** + * @template D + * @template V + */ +export class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; +} +// Message: @template D not in use + +/** + * @template D + * @template V + */ +export default class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; +} +// Message: @template D not in use + +/** + * @template D + * @template V + */ +export default class { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; +} +// Message: @template D not in use ```` @@ -243,5 +283,37 @@ export function identity(arg: Type): Type { export default function identity(arg: Type): Type { return arg; } + +/** + * @template NumType + */ +class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; +} + +/** + * @template NumType + */ +export class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; +} + +/** + * @template NumType + */ +export default class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; +} + +/** + * @template NumType + */ +export default class { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; +} ```` diff --git a/docs/rules/require-template.md b/docs/rules/require-template.md index b9109c09..581270a5 100644 --- a/docs/rules/require-template.md +++ b/docs/rules/require-template.md @@ -5,8 +5,8 @@ Checks to see that `@template` tags are present for any detected type parameters. -Currently checks `FunctionDeclaration`, `TSInterfaceDeclaration` or -`TSTypeAliasDeclaration` such as: +Currently checks `ClassDeclaration`, `FunctionDeclaration`, +`TSInterfaceDeclaration` or `TSTypeAliasDeclaration` such as: ```ts export type Pairs = [D, V | undefined]; @@ -163,6 +163,42 @@ export default function identity(arg: Type): Type { return arg; } // Message: Missing @template Type + +/** + * + */ +class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; +} +// Message: Missing @template NumType + +/** + * + */ +export class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; +} +// Message: Missing @template NumType + +/** + * + */ +export default class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; +} +// Message: Missing @template NumType + +/** + * + */ +export default class { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; +} +// Message: Missing @template NumType ```` @@ -255,5 +291,37 @@ export function identity(arg: Type): Type { export default function identity(arg: Type): Type { return arg; } + +/** + * @template NumType + */ +class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; +} + +/** + * @template NumType + */ +export class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; +} + +/** + * @template NumType + */ +export default class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; +} + +/** + * @template NumType + */ +export default class { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; +} ```` diff --git a/src/rules/checkTemplateNames.js b/src/rules/checkTemplateNames.js index 57ecd810..455c97da 100644 --- a/src/rules/checkTemplateNames.js +++ b/src/rules/checkTemplateNames.js @@ -21,6 +21,7 @@ export default iterateJsdoc(({ const usedNames = new Set(); /** * @param {import('@typescript-eslint/types').TSESTree.FunctionDeclaration| + * import('@typescript-eslint/types').TSESTree.ClassDeclaration| * import('@typescript-eslint/types').TSESTree.TSInterfaceDeclaration| * import('@typescript-eslint/types').TSESTree.TSTypeAliasDeclaration} aliasDeclaration */ @@ -52,6 +53,7 @@ export default iterateJsdoc(({ case 'ExportDefaultDeclaration': case 'ExportNamedDeclaration': switch (nde.declaration?.type) { + case 'ClassDeclaration': case 'FunctionDeclaration': case 'TSTypeAliasDeclaration': case 'TSInterfaceDeclaration': @@ -59,6 +61,7 @@ export default iterateJsdoc(({ break; } break; + case 'ClassDeclaration': case 'FunctionDeclaration': case 'TSTypeAliasDeclaration': case 'TSInterfaceDeclaration': diff --git a/src/rules/requireTemplate.js b/src/rules/requireTemplate.js index c06da7ed..8cdf8a59 100644 --- a/src/rules/requireTemplate.js +++ b/src/rules/requireTemplate.js @@ -36,6 +36,7 @@ export default iterateJsdoc(({ /** * @param {import('@typescript-eslint/types').TSESTree.FunctionDeclaration| + * import('@typescript-eslint/types').TSESTree.ClassDeclaration| * import('@typescript-eslint/types').TSESTree.TSInterfaceDeclaration| * import('@typescript-eslint/types').TSESTree.TSTypeAliasDeclaration} aliasDeclaration */ @@ -62,6 +63,7 @@ export default iterateJsdoc(({ switch (nde.type) { case 'ExportDefaultDeclaration': switch (nde.declaration?.type) { + case 'ClassDeclaration': case 'FunctionDeclaration': case 'TSInterfaceDeclaration': checkTypeParams(nde.declaration); @@ -70,6 +72,7 @@ export default iterateJsdoc(({ break; case 'ExportNamedDeclaration': switch (nde.declaration?.type) { + case 'ClassDeclaration': case 'FunctionDeclaration': case 'TSTypeAliasDeclaration': case 'TSInterfaceDeclaration': @@ -77,6 +80,7 @@ export default iterateJsdoc(({ break; } break; + case 'ClassDeclaration': case 'FunctionDeclaration': case 'TSTypeAliasDeclaration': case 'TSInterfaceDeclaration': diff --git a/test/rules/assertions/checkTemplateNames.js b/test/rules/assertions/checkTemplateNames.js index 91471bc9..87a05a1c 100644 --- a/test/rules/assertions/checkTemplateNames.js +++ b/test/rules/assertions/checkTemplateNames.js @@ -302,6 +302,106 @@ export default { parser: typescriptEslintParser }, }, + { + code: ` + /** + * @template D + * @template V + */ + class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; + } + `, + errors: [ + { + line: 3, + message: '@template D not in use', + }, + { + line: 4, + message: '@template V not in use', + }, + ], + languageOptions: { + parser: typescriptEslintParser + }, + }, + { + code: ` + /** + * @template D + * @template V + */ + export class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; + } + `, + errors: [ + { + line: 3, + message: '@template D not in use', + }, + { + line: 4, + message: '@template V not in use', + }, + ], + languageOptions: { + parser: typescriptEslintParser + }, + }, + { + code: ` + /** + * @template D + * @template V + */ + export default class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; + } + `, + errors: [ + { + line: 3, + message: '@template D not in use', + }, + { + line: 4, + message: '@template V not in use', + }, + ], + languageOptions: { + parser: typescriptEslintParser + }, + }, + { + code: ` + /** + * @template D + * @template V + */ + export default class { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; + } + `, + errors: [ + { + line: 3, + message: '@template D not in use', + }, + { + line: 4, + message: '@template V not in use', + }, + ], + languageOptions: { + parser: typescriptEslintParser + }, + }, ], valid: [ { @@ -450,5 +550,61 @@ export default { parser: typescriptEslintParser }, }, + { + code: ` + /** + * @template NumType + */ + class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; + } + `, + languageOptions: { + parser: typescriptEslintParser + }, + }, + { + code: ` + /** + * @template NumType + */ + export class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; + } + `, + languageOptions: { + parser: typescriptEslintParser + }, + }, + { + code: ` + /** + * @template NumType + */ + export default class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; + } + `, + languageOptions: { + parser: typescriptEslintParser + }, + }, + { + code: ` + /** + * @template NumType + */ + export default class { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; + } + `, + languageOptions: { + parser: typescriptEslintParser + }, + }, ], }; diff --git a/test/rules/assertions/requireTemplate.js b/test/rules/assertions/requireTemplate.js index 8ad9e530..c2f713a2 100644 --- a/test/rules/assertions/requireTemplate.js +++ b/test/rules/assertions/requireTemplate.js @@ -285,6 +285,86 @@ export default { parser: typescriptEslintParser }, }, + { + code: ` + /** + * + */ + class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; + } + `, + errors: [ + { + line: 2, + message: 'Missing @template NumType', + }, + ], + languageOptions: { + parser: typescriptEslintParser + }, + }, + { + code: ` + /** + * + */ + export class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; + } + `, + errors: [ + { + line: 2, + message: 'Missing @template NumType', + }, + ], + languageOptions: { + parser: typescriptEslintParser + }, + }, + { + code: ` + /** + * + */ + export default class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; + } + `, + errors: [ + { + line: 2, + message: 'Missing @template NumType', + }, + ], + languageOptions: { + parser: typescriptEslintParser + }, + }, + { + code: ` + /** + * + */ + export default class { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; + } + `, + errors: [ + { + line: 2, + message: 'Missing @template NumType', + }, + ], + languageOptions: { + parser: typescriptEslintParser + }, + }, ], valid: [ { @@ -432,5 +512,61 @@ export default { parser: typescriptEslintParser }, }, + { + code: ` + /** + * @template NumType + */ + class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; + } + `, + languageOptions: { + parser: typescriptEslintParser + }, + }, + { + code: ` + /** + * @template NumType + */ + export class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; + } + `, + languageOptions: { + parser: typescriptEslintParser + }, + }, + { + code: ` + /** + * @template NumType + */ + export default class GenericNumber { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; + } + `, + languageOptions: { + parser: typescriptEslintParser + }, + }, + { + code: ` + /** + * @template NumType + */ + export default class { + zeroValue: NumType; + add: (x: NumType, y: NumType) => NumType; + } + `, + languageOptions: { + parser: typescriptEslintParser + }, + }, ], };