refactor(path): always name the parameters (add param definition check in doc linter) (#6158)

This commit is contained in:
Efe 2024-10-30 03:39:19 +01:00 committed by GitHub
parent 24cd7cfd5b
commit 2d9e21267d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 53 additions and 6 deletions

View File

@ -19,6 +19,7 @@ import {
type DocNodeModuleDoc, type DocNodeModuleDoc,
type JsDoc, type JsDoc,
type JsDocTagDocRequired, type JsDocTagDocRequired,
type JsDocTagParam,
type Location, type Location,
type TsTypeDef, type TsTypeDef,
} from "@deno/doc"; } from "@deno/doc";
@ -182,6 +183,36 @@ function assertHasReturnTag(document: { jsDoc: JsDoc; location: Location }) {
} }
} }
/**
* Asserts that a @param tag has a corresponding function definition.
*/
function assertHasParamDefinition(
document: DocNodeWithJsDoc<DocNodeFunction | ClassMethodDef>,
param: JsDocTagParam,
) {
const paramDoc = document.functionDef.params.find((paramDoc) => {
if (paramDoc.kind === "identifier") {
return paramDoc.name === param.name;
} else if (paramDoc.kind === "rest" && paramDoc.arg.kind === "identifier") {
return paramDoc.arg.name === param.name;
} else if (
paramDoc.kind === "assign" && paramDoc.left.kind === "identifier"
) {
return paramDoc.left.name === param.name;
}
return false;
});
if (!paramDoc) {
diagnostics.push(
new DocumentError(
`@param ${param.name} must have a corresponding named function parameter definition.`,
document,
),
);
}
}
function assertHasParamTag( function assertHasParamTag(
document: { jsDoc: JsDoc; location: Location }, document: { jsDoc: JsDoc; location: Location },
param: string, param: string,
@ -295,6 +326,7 @@ function assertHasTypeParamTags(
* Asserts that a function document has: * Asserts that a function document has:
* - A `@typeParam` tag for each type parameter. * - A `@typeParam` tag for each type parameter.
* - A {@linkcode https://jsdoc.app/tags-param | @param} tag for each parameter. * - A {@linkcode https://jsdoc.app/tags-param | @param} tag for each parameter.
* - A parameter definition inside the function for each @param tag.
* - A {@linkcode https://jsdoc.app/tags-returns | @returns} tag. * - A {@linkcode https://jsdoc.app/tags-returns | @returns} tag.
* - At least one {@linkcode https://jsdoc.app/tags-example | @example} tag with * - At least one {@linkcode https://jsdoc.app/tags-example | @example} tag with
* a code snippet that executes successfully. * a code snippet that executes successfully.
@ -314,6 +346,17 @@ function assertFunctionDocs(
assertHasParamTag(document, param.left.name); assertHasParamTag(document, param.left.name);
} }
} }
const documentedParams = document.jsDoc.tags?.filter((
tag,
): tag is JsDocTagParam =>
// Filter nested definitions like options.root as it is still documenting options parameter
tag.kind === "param" && !tag.name.includes(".")
) ?? [];
for (const param of documentedParams) {
assertHasParamDefinition(document, param);
}
for (const typeParam of document.functionDef.typeParams) { for (const typeParam of document.functionDef.typeParams) {
assertHasTypeParamTags(document, typeParam.name); assertHasTypeParamTags(document, typeParam.name);
} }

View File

@ -26,8 +26,9 @@ export type { GlobOptions };
*/ */
export function joinGlobs( export function joinGlobs(
globs: string[], globs: string[],
{ extended = true, globstar = false }: GlobOptions = {}, options: Pick<GlobOptions, "globstar"> = {},
): string { ): string {
const { globstar = false } = options;
if (!globstar || globs.length === 0) { if (!globstar || globs.length === 0) {
return join(...globs); return join(...globs);
} }
@ -40,5 +41,5 @@ export function joinGlobs(
} }
} }
if (!joined) return "."; if (!joined) return ".";
return normalizeGlob(joined, { extended, globstar }); return normalizeGlob(joined, { globstar });
} }

View File

@ -25,8 +25,9 @@ export type { GlobOptions };
*/ */
export function normalizeGlob( export function normalizeGlob(
glob: string, glob: string,
{ globstar = false }: GlobOptions = {}, options: Pick<GlobOptions, "globstar"> = {},
): string { ): string {
const { globstar = false }: GlobOptions = options;
if (glob.match(/\0/g)) { if (glob.match(/\0/g)) {
throw new Error(`Glob contains invalid characters: "${glob}"`); throw new Error(`Glob contains invalid characters: "${glob}"`);
} }

View File

@ -27,8 +27,9 @@ export type { GlobOptions };
*/ */
export function joinGlobs( export function joinGlobs(
globs: string[], globs: string[],
{ extended = true, globstar = false }: GlobOptions = {}, options: Pick<GlobOptions, "globstar"> = {},
): string { ): string {
const { globstar = false } = options;
if (!globstar || globs.length === 0) { if (!globstar || globs.length === 0) {
return join(...globs); return join(...globs);
} }
@ -41,5 +42,5 @@ export function joinGlobs(
} }
} }
if (!joined) return "."; if (!joined) return ".";
return normalizeGlob(joined, { extended, globstar }); return normalizeGlob(joined, { globstar });
} }

View File

@ -25,8 +25,9 @@ export type { GlobOptions };
*/ */
export function normalizeGlob( export function normalizeGlob(
glob: string, glob: string,
{ globstar = false }: GlobOptions = {}, options: Pick<GlobOptions, "globstar"> = {},
): string { ): string {
const { globstar = false }: GlobOptions = options;
if (glob.match(/\0/g)) { if (glob.match(/\0/g)) {
throw new Error(`Glob contains invalid characters: "${glob}"`); throw new Error(`Glob contains invalid characters: "${glob}"`);
} }