Skip to content

Commit

Permalink
fix(check-template-names): check for param and returns tags; fixes #…
Browse files Browse the repository at this point in the history
  • Loading branch information
brettz9 committed Jul 30, 2024
1 parent 31e0a35 commit 12fca71
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 29 deletions.
12 changes: 12 additions & 0 deletions docs/rules/check-template-names.md
Original file line number Diff line number Diff line change
Expand Up @@ -315,5 +315,17 @@ export default class <NumType> {
zeroValue: NumType;
add: (x: NumType, y: NumType) => NumType;
}

/**
* Uses the provided callback to group the given array into the keys of a map.
* Based on the array grouping proposal: https://github.com/tc39/proposal-array-grouping/
*
* @template T
* @param {T[]} array
* @param {(value: T, index: number) => string} callbackFn
* @returns {Map<string, T[]>}
*/
export function mapGroupBy(array, callbackFn) {
}
````

80 changes: 51 additions & 29 deletions src/rules/checkTemplateNames.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,60 @@ export default iterateJsdoc(({
const templateTags = utils.getTags('template');

const usedNames = new Set();
/**
* @param {string} potentialType
*/
const checkForUsedTypes = (potentialType) => {
let parsedType;
try {
parsedType = mode === 'permissive' ?
tryParseType(/** @type {string} */ (potentialType)) :
parseType(/** @type {string} */ (potentialType), mode);
} catch {
return;
}

traverse(parsedType, (nde) => {
const {
type,
value,
} = /** @type {import('jsdoc-type-pratt-parser').NameResult} */ (nde);
if (type === 'JsdocTypeName' && (/^[A-Z]$/).test(value)) {
usedNames.add(value);
}
});
};

/**
* @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
* @param {boolean} [checkParamsAndReturns]
*/
const checkParameters = (aliasDeclaration) => {
const checkParameters = (aliasDeclaration, checkParamsAndReturns) => {
/* c8 ignore next -- Guard */
const {params} = aliasDeclaration.typeParameters ?? {params: []};
for (const {name: {name}} of params) {
usedNames.add(name);
}
if (checkParamsAndReturns) {
const paramName = /** @type {string} */ (utils.getPreferredTagName({
tagName: 'param',
}));
const paramTags = utils.getTags(paramName);
for (const paramTag of paramTags) {
checkForUsedTypes(paramTag.type);
}

const returnsName = /** @type {string} */ (utils.getPreferredTagName({
tagName: 'returns',
}));
const returnsTags = utils.getTags(returnsName);
for (const returnsTag of returnsTags) {
checkForUsedTypes(returnsTag.type);
}
}
for (const tag of templateTags) {
const {name} = tag;
const names = name.split(/,\s*/);
Expand All @@ -53,16 +95,20 @@ export default iterateJsdoc(({
case 'ExportDefaultDeclaration':
case 'ExportNamedDeclaration':
switch (nde.declaration?.type) {
case 'ClassDeclaration':
case 'FunctionDeclaration':
checkParameters(nde.declaration, true);
break;
case 'ClassDeclaration':
case 'TSTypeAliasDeclaration':
case 'TSInterfaceDeclaration':
checkParameters(nde.declaration);
break;
}
break;
case 'ClassDeclaration':
case 'FunctionDeclaration':
checkParameters(nde, true);
break;
case 'ClassDeclaration':
case 'TSTypeAliasDeclaration':
case 'TSInterfaceDeclaration':
checkParameters(nde);
Expand All @@ -76,37 +122,13 @@ export default iterateJsdoc(({
return;
}

/**
* @param {string} potentialType
*/
const checkForUsedTypes = (potentialType) => {
let parsedType;
try {
parsedType = mode === 'permissive' ?
tryParseType(/** @type {string} */ (potentialType)) :
parseType(/** @type {string} */ (potentialType), mode);
} catch {
return;
}

traverse(parsedType, (nde) => {
const {
type,
value,
} = /** @type {import('jsdoc-type-pratt-parser').NameResult} */ (nde);
if (type === 'JsdocTypeName' && (/^[A-Z]$/).test(value)) {
usedNames.add(value);
}
});
};

const potentialTypedefType = typedefTags[0].type;
checkForUsedTypes(potentialTypedefType);

const tagName = /** @type {string} */ (utils.getPreferredTagName({
const propertyName = /** @type {string} */ (utils.getPreferredTagName({
tagName: 'property',
}));
const propertyTags = utils.getTags(tagName);
const propertyTags = utils.getTags(propertyName);
for (const propertyTag of propertyTags) {
checkForUsedTypes(propertyTag.type);
}
Expand Down
18 changes: 18 additions & 0 deletions test/rules/assertions/checkTemplateNames.js
Original file line number Diff line number Diff line change
Expand Up @@ -606,5 +606,23 @@ export default {
parser: typescriptEslintParser
},
},
{
code: `
/**
* Uses the provided callback to group the given array into the keys of a map.
* Based on the array grouping proposal: https://github.com/tc39/proposal-array-grouping/
*
* @template T
* @param {T[]} array
* @param {(value: T, index: number) => string} callbackFn
* @returns {Map<string, T[]>}
*/
export function mapGroupBy(array, callbackFn) {
}
`,
languageOptions: {
parser: typescriptEslintParser
},
},
],
};

0 comments on commit 12fca71

Please sign in to comment.