Skip to content

Commit

Permalink
feat(require-template, check-template-names): add support `Functi…
Browse files Browse the repository at this point in the history
…onDeclaration`
  • Loading branch information
brettz9 committed Jul 30, 2024
1 parent 320a1eb commit 28bc1cb
Show file tree
Hide file tree
Showing 8 changed files with 318 additions and 7 deletions.
3 changes: 2 additions & 1 deletion .README/rules/check-template-names.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
Checks that any `@template` names are actually used in the connected
`@typedef` or type alias.

Currently checks `TSInterfaceDeclaration` or `TSTypeAliasDeclaration` such as:
Currently checks `FunctionDeclaration`, `TSInterfaceDeclaration` or
`TSTypeAliasDeclaration` such as:

```ts
/**
Expand Down
3 changes: 2 additions & 1 deletion .README/rules/require-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
Checks to see that `@template` tags are present for any detected type
parameters.

Currently checks `TSInterfaceDeclaration` or `TSTypeAliasDeclaration` such as:
Currently checks `FunctionDeclaration`, `TSInterfaceDeclaration` or
`TSTypeAliasDeclaration` such as:

```ts
export type Pairs<D, V> = [D, V | undefined];
Expand Down
51 changes: 50 additions & 1 deletion docs/rules/check-template-names.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
Checks that any `@template` names are actually used in the connected
`@typedef` or type alias.

Currently checks `TSInterfaceDeclaration` or `TSTypeAliasDeclaration` such as:
Currently checks `FunctionDeclaration`, `TSInterfaceDeclaration` or
`TSTypeAliasDeclaration` such as:

```ts
/**
Expand Down Expand Up @@ -122,6 +123,33 @@ export default interface GenericIdentityFn<Type> {
(arg: Type): Type;
}
// Message: @template D not in use

/**
* @template D
* @template V
*/
function identity<Type>(arg: Type): Type {
return arg;
}
// Message: @template D not in use

/**
* @template D
* @template V
*/
export function identity<Type>(arg: Type): Type {
return arg;
}
// Message: @template D not in use

/**
* @template D
* @template V
*/
export default function identity<Type>(arg: Type): Type {
return arg;
}
// Message: @template D not in use
````


Expand Down Expand Up @@ -194,5 +222,26 @@ export interface GenericIdentityFn<Type> {
export default interface GenericIdentityFn<Type> {
(arg: Type): Type;
}

/**
* @template Type
*/
function identity<Type>(arg: Type): Type {
return arg;
}

/**
* @template Type
*/
export function identity<Type>(arg: Type): Type {
return arg;
}

/**
* @template Type
*/
export default function identity<Type>(arg: Type): Type {
return arg;
}
````

48 changes: 47 additions & 1 deletion docs/rules/require-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
Checks to see that `@template` tags are present for any detected type
parameters.

Currently checks `TSInterfaceDeclaration` or `TSTypeAliasDeclaration` such as:
Currently checks `FunctionDeclaration`, `TSInterfaceDeclaration` or
`TSTypeAliasDeclaration` such as:

```ts
export type Pairs<D, V> = [D, V | undefined];
Expand Down Expand Up @@ -138,6 +139,30 @@ export default interface GenericIdentityFn<Type> {
(arg: Type): Type;
}
// Message: Missing @template Type

/**
*
*/
function identity<Type>(arg: Type): Type {
return arg;
}
// Message: Missing @template Type

/**
*
*/
export function identity<Type>(arg: Type): Type {
return arg;
}
// Message: Missing @template Type

/**
*
*/
export default function identity<Type>(arg: Type): Type {
return arg;
}
// Message: Missing @template Type
````


Expand Down Expand Up @@ -209,5 +234,26 @@ export interface GenericIdentityFn<Type> {
export default interface GenericIdentityFn<Type> {
(arg: Type): Type;
}

/**
* @template Type
*/
function identity<Type>(arg: Type): Type {
return arg;
}

/**
* @template Type
*/
export function identity<Type>(arg: Type): Type {
return arg;
}

/**
* @template Type
*/
export default function identity<Type>(arg: Type): Type {
return arg;
}
````

7 changes: 5 additions & 2 deletions src/rules/checkTemplateNames.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ export default iterateJsdoc(({

const usedNames = new Set();
/**
* @param {import('@typescript-eslint/types').TSESTree.TSInterfaceDeclaration|
* @param {import('@typescript-eslint/types').TSESTree.FunctionDeclaration|
* import('@typescript-eslint/types').TSESTree.TSInterfaceDeclaration|
* import('@typescript-eslint/types').TSESTree.TSTypeAliasDeclaration} aliasDeclaration
*/
const checkParameters = (aliasDeclaration) => {
Expand Down Expand Up @@ -51,12 +52,14 @@ export default iterateJsdoc(({
case 'ExportDefaultDeclaration':
case 'ExportNamedDeclaration':
switch (nde.declaration?.type) {
case 'FunctionDeclaration':
case 'TSTypeAliasDeclaration':
case 'TSInterfaceDeclaration':
checkParameters(nde.declaration);
checkParameters(nde.declaration);
break;
}
break;
case 'FunctionDeclaration':
case 'TSTypeAliasDeclaration':
case 'TSInterfaceDeclaration':
checkParameters(nde);
Expand Down
6 changes: 5 additions & 1 deletion src/rules/requireTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ export default iterateJsdoc(({
}

/**
* @param {import('@typescript-eslint/types').TSESTree.TSInterfaceDeclaration|
* @param {import('@typescript-eslint/types').TSESTree.FunctionDeclaration|
* import('@typescript-eslint/types').TSESTree.TSInterfaceDeclaration|
* import('@typescript-eslint/types').TSESTree.TSTypeAliasDeclaration} aliasDeclaration
*/
const checkTypeParams = (aliasDeclaration) => {
Expand All @@ -61,19 +62,22 @@ export default iterateJsdoc(({
switch (nde.type) {
case 'ExportDefaultDeclaration':
switch (nde.declaration?.type) {
case 'FunctionDeclaration':
case 'TSInterfaceDeclaration':
checkTypeParams(nde.declaration);
break;
}
break;
case 'ExportNamedDeclaration':
switch (nde.declaration?.type) {
case 'FunctionDeclaration':
case 'TSTypeAliasDeclaration':
case 'TSInterfaceDeclaration':
checkTypeParams(nde.declaration);
break;
}
break;
case 'FunctionDeclaration':
case 'TSTypeAliasDeclaration':
case 'TSInterfaceDeclaration':
checkTypeParams(nde);
Expand Down
111 changes: 111 additions & 0 deletions test/rules/assertions/checkTemplateNames.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,78 @@ export default {
parser: typescriptEslintParser
},
},
{
code: `
/**
* @template D
* @template V
*/
function identity<Type>(arg: Type): Type {
return arg;
}
`,
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 function identity<Type>(arg: Type): Type {
return arg;
}
`,
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 function identity<Type>(arg: Type): Type {
return arg;
}
`,
errors: [
{
line: 3,
message: '@template D not in use',
},
{
line: 4,
message: '@template V not in use',
},
],
languageOptions: {
parser: typescriptEslintParser
},
},
],
valid: [
{
Expand Down Expand Up @@ -339,5 +411,44 @@ export default {
parser: typescriptEslintParser
},
},
{
code: `
/**
* @template Type
*/
function identity<Type>(arg: Type): Type {
return arg;
}
`,
languageOptions: {
parser: typescriptEslintParser
},
},
{
code: `
/**
* @template Type
*/
export function identity<Type>(arg: Type): Type {
return arg;
}
`,
languageOptions: {
parser: typescriptEslintParser
},
},
{
code: `
/**
* @template Type
*/
export default function identity<Type>(arg: Type): Type {
return arg;
}
`,
languageOptions: {
parser: typescriptEslintParser
},
},
],
};
Loading

0 comments on commit 28bc1cb

Please sign in to comment.