Skip to content

Commit

Permalink
feat(require-template): check callback/function tag block content
Browse files Browse the repository at this point in the history
  • Loading branch information
brettz9 committed Aug 2, 2024
1 parent 058018b commit 116b3e8
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 23 deletions.
4 changes: 2 additions & 2 deletions .README/rules/require-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ or

Note that in the latter TypeScript-flavor JavaScript example, there is no way
for us to firmly distinguish between `D` and `V` as type parameters or as some
other identifiers, so we use an algorithm that any single capital letters
are assumed to be templates.
other identifiers, so we use an algorithm that assumes that any single capital
letters are templates.

## Options

Expand Down
35 changes: 33 additions & 2 deletions docs/rules/require-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ or

Note that in the latter TypeScript-flavor JavaScript example, there is no way
for us to firmly distinguish between `D` and `V` as type parameters or as some
other identifiers, so we use an algorithm that any single capital letters
are assumed to be templates.
other identifiers, so we use an algorithm that assumes that any single capital
letters are templates.

<a name="user-content-require-template-options"></a>
<a name="require-template-options"></a>
Expand Down Expand Up @@ -199,6 +199,18 @@ export default class <NumType> {
add: (x: NumType, y: NumType) => NumType;
}
// Message: Missing @template NumType

/**
* @callback
* @param {[D, V | undefined]} someParam
*/
// Message: Missing @template D

/**
* @callback
* @returns {[D, V | undefined]}
*/
// Message: Missing @template D
````


Expand Down Expand Up @@ -323,5 +335,24 @@ export default class <NumType> {
zeroValue: NumType;
add: (x: NumType, y: NumType) => NumType;
}

/**
* @callback
* @template D
* @template V
* @param {[D, V | undefined]} someParam
*/

/**
* @callback
* @template D
* @template V
* @returns {[D, V | undefined]}
*/

/**
* @callback
* @returns {[Something | undefined]}
*/
````

54 changes: 35 additions & 19 deletions src/rules/requireTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,6 @@ export default iterateJsdoc(({
}
};

const typedefTags = utils.getTags('typedef');
if (!typedefTags.length || typedefTags.length >= 2) {
handleTypes();
return;
}

const usedNameToTag = new Map();

/**
Expand Down Expand Up @@ -124,23 +118,45 @@ export default iterateJsdoc(({
});
};

const potentialTypedef = typedefTags[0];
checkForUsedTypes(potentialTypedef);
/**
* @param {string[]} tagNames
*/
const checkTagsAndTemplates = (tagNames) => {
for (const tagName of tagNames) {
const preferredTagName = /** @type {string} */ (utils.getPreferredTagName({
tagName,
}));
const matchingTags = utils.getTags(preferredTagName);
for (const matchingTag of matchingTags) {
checkForUsedTypes(matchingTag);
}
}

// Could check against whitelist/blacklist
for (const usedName of usedNames) {
if (!templateNames.includes(usedName)) {
report(`Missing @template ${usedName}`, null, usedNameToTag.get(usedName));
}
}
};

const tagName = /** @type {string} */ (utils.getPreferredTagName({
tagName: 'property',
}));
const propertyTags = utils.getTags(tagName);
for (const propertyTag of propertyTags) {
checkForUsedTypes(propertyTag);
const callbackTags = utils.getTags('callback');
const functionTags = utils.getTags('function');
if (callbackTags.length || functionTags.length) {
checkTagsAndTemplates(['param', 'returns']);
return;
}

// Could check against whitelist/blacklist
for (const usedName of usedNames) {
if (!templateNames.includes(usedName)) {
report(`Missing @template ${usedName}`, null, usedNameToTag.get(usedName));
}
const typedefTags = utils.getTags('typedef');
if (!typedefTags.length || typedefTags.length >= 2) {
handleTypes();
return;
}

const potentialTypedef = typedefTags[0];
checkForUsedTypes(potentialTypedef);

checkTagsAndTemplates(['property']);
}, {
iterateAllJsdocs: true,
meta: {
Expand Down
64 changes: 64 additions & 0 deletions test/rules/assertions/requireTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,42 @@ export default {
parser: typescriptEslintParser
},
},
{
code: `
/**
* @callback
* @param {[D, V | undefined]} someParam
*/
`,
errors: [
{
line: 4,
message: 'Missing @template D',
},
{
line: 4,
message: 'Missing @template V',
},
],
},
{
code: `
/**
* @callback
* @returns {[D, V | undefined]}
*/
`,
errors: [
{
line: 4,
message: 'Missing @template D',
},
{
line: 4,
message: 'Missing @template V',
},
],
},
],
valid: [
{
Expand Down Expand Up @@ -568,5 +604,33 @@ export default {
parser: typescriptEslintParser
},
},
{
code: `
/**
* @callback
* @template D
* @template V
* @param {[D, V | undefined]} someParam
*/
`,
},
{
code: `
/**
* @callback
* @template D
* @template V
* @returns {[D, V | undefined]}
*/
`,
},
{
code: `
/**
* @callback
* @returns {[Something | undefined]}
*/
`,
},
],
};

0 comments on commit 116b3e8

Please sign in to comment.