mirror of
https://github.com/denoland/std.git
synced 2024-11-21 20:50:22 +00:00
chore: improve doc checker (#4782)
* chore: improve doc checker * tweaks * tweaks
This commit is contained in:
parent
aac208aae6
commit
16162ebcda
@ -1,11 +1,8 @@
|
||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
/**
|
||||
* This script checks that all exported functions have JSDoc comments with
|
||||
* `@param`, `@return`, and `@example` tags, according to the contributing
|
||||
* guidelines.
|
||||
*
|
||||
* @see {@link https://github.com/denoland/deno_std/blob/main/.github/CONTRIBUTING.md#documentation}
|
||||
* This script checks that all public symbols documentation aligns with the
|
||||
* {@link ./CONTRIBUTING.md#documentation | documentation guidelines}.
|
||||
*
|
||||
* TODO(iuioiua): Add support for classes and methods.
|
||||
*/
|
||||
@ -13,10 +10,14 @@ import {
|
||||
doc,
|
||||
type DocNodeBase,
|
||||
type DocNodeFunction,
|
||||
type JsDocTag,
|
||||
type JsDoc,
|
||||
type JsDocTagDocRequired,
|
||||
} from "@deno/doc";
|
||||
|
||||
type DocNodeWithJsDoc<T = DocNodeBase> = T & {
|
||||
jsDoc: JsDoc;
|
||||
};
|
||||
|
||||
const ENTRY_POINTS = [
|
||||
"../bytes/mod.ts",
|
||||
"../datetime/mod.ts",
|
||||
@ -46,36 +47,34 @@ function assert(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We only check functions that have JSDocs. We know that exported functions
|
||||
* have JSDocs thanks to `deno doc --lint`, which is used in the `lint:docs`
|
||||
* task.
|
||||
*/
|
||||
function isFunctionDoc(document: DocNodeBase): document is DocNodeFunction {
|
||||
return document.kind === "function" && document.jsDoc !== undefined;
|
||||
}
|
||||
|
||||
function isExported(document: DocNodeBase) {
|
||||
return document.declarationKind === "export";
|
||||
}
|
||||
|
||||
function assertHasTag(tags: JsDocTag[], kind: string, document: DocNodeBase) {
|
||||
const tag = tags.find((tag) => tag.kind === kind);
|
||||
assert(tag !== undefined, `Symbol must have a @${kind} tag`, document);
|
||||
function isFunctionDoc(
|
||||
document: DocNodeBase,
|
||||
): document is DocNodeWithJsDoc<DocNodeFunction> {
|
||||
return document.kind === "function" && document.jsDoc !== undefined;
|
||||
}
|
||||
|
||||
function assertHasReturnTag(document: DocNodeWithJsDoc) {
|
||||
const tag = document.jsDoc.tags?.find((tag) => tag.kind === "return");
|
||||
assert(tag !== undefined, "Symbol must have a @return tag", document);
|
||||
assert(
|
||||
// @ts-ignore doc is defined
|
||||
tag.doc !== undefined,
|
||||
`@${kind} tag must have a description`,
|
||||
"@return tag must have a description",
|
||||
document,
|
||||
);
|
||||
}
|
||||
|
||||
function assertHasParamTag(
|
||||
tags: JsDocTag[],
|
||||
document: DocNodeWithJsDoc,
|
||||
param: string,
|
||||
document: DocNodeBase,
|
||||
) {
|
||||
const tag = tags.find((tag) => tag.kind === "param" && tag.name === param);
|
||||
const tag = document.jsDoc.tags?.find((tag) =>
|
||||
tag.kind === "param" && tag.name === param
|
||||
);
|
||||
assert(
|
||||
tag !== undefined,
|
||||
`Symbol must have a @param tag for ${param}`,
|
||||
@ -89,9 +88,9 @@ function assertHasParamTag(
|
||||
);
|
||||
}
|
||||
|
||||
function assertHasExampleTag(tags: JsDocTag[], document: DocNodeBase) {
|
||||
tags = tags.filter((tag) => tag.kind === "example");
|
||||
if (tags.length === 0) {
|
||||
function assertHasExampleTag(document: DocNodeWithJsDoc) {
|
||||
const tags = document.jsDoc.tags?.filter((tag) => tag.kind === "example");
|
||||
if (tags === undefined || tags.length === 0) {
|
||||
throw new DocumentError("Symbol must have an @example tag", document);
|
||||
}
|
||||
for (const tag of (tags as JsDocTagDocRequired[])) {
|
||||
@ -130,11 +129,10 @@ function assertHasExampleTag(tags: JsDocTag[], document: DocNodeBase) {
|
||||
}
|
||||
|
||||
function assertHasTypeParamTags(
|
||||
tags: JsDocTag[],
|
||||
document: DocNodeWithJsDoc,
|
||||
typeParamName: string,
|
||||
document: DocNodeBase,
|
||||
) {
|
||||
const tag = tags.find((tag) =>
|
||||
const tag = document.jsDoc.tags?.find((tag) =>
|
||||
tag.kind === "template" && tag.name === typeParamName
|
||||
);
|
||||
assert(
|
||||
@ -150,28 +148,29 @@ function assertHasTypeParamTags(
|
||||
);
|
||||
}
|
||||
|
||||
function assertFunctionDocs(document: DocNodeFunction) {
|
||||
assert(
|
||||
document.jsDoc !== undefined,
|
||||
"Symbol must have a JSDoc block",
|
||||
document,
|
||||
);
|
||||
const { tags } = document.jsDoc;
|
||||
assert(tags !== undefined, "JSDoc block must have tags", document);
|
||||
/**
|
||||
* Asserts that a function document has:
|
||||
* - 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-returns | @returns} tag.
|
||||
* - At least one {@linkcode https://jsdoc.app/tags-example | @example} tag with
|
||||
* a code snippet that executes successfully.
|
||||
*/
|
||||
function assertFunctionDocs(document: DocNodeWithJsDoc<DocNodeFunction>) {
|
||||
for (const param of document.functionDef.params) {
|
||||
if (param.kind === "identifier") {
|
||||
assertHasParamTag(tags, param.name, document);
|
||||
assertHasParamTag(document, param.name);
|
||||
}
|
||||
if (param.kind === "assign") {
|
||||
// @ts-ignore Trust me
|
||||
assertHasParamTag(tags, param.left.name, document);
|
||||
assertHasParamTag(document, param.left.name);
|
||||
}
|
||||
}
|
||||
for (const typeParam of document.functionDef.typeParams) {
|
||||
assertHasTypeParamTags(tags, typeParam.name, document);
|
||||
assertHasTypeParamTags(document, typeParam.name);
|
||||
}
|
||||
assertHasTag(tags, "return", document);
|
||||
assertHasExampleTag(tags, document);
|
||||
assertHasReturnTag(document);
|
||||
assertHasExampleTag(document);
|
||||
}
|
||||
|
||||
async function checkDocs(specifier: string) {
|
||||
|
@ -19,7 +19,7 @@
|
||||
"lint:circular": "deno run --allow-env --allow-read --allow-net=deno.land,jsr.io ./_tools/check_circular_package_dependencies.ts",
|
||||
"lint:mod-exports": "deno run --allow-env --allow-read ./_tools/check_mod_exports.ts",
|
||||
"lint:tools-types": "deno check _tools/*.ts",
|
||||
"lint:docs": "deno run -A _tools/check_docs.ts && deno doc --lint collections/mod.ts bytes/mod.ts datetime/mod.ts internal/mod.ts media_types/mod.ts url/mod.ts",
|
||||
"lint:docs": "deno doc --lint collections/mod.ts bytes/mod.ts datetime/mod.ts internal/mod.ts media_types/mod.ts url/mod.ts && deno run -A _tools/check_docs.ts",
|
||||
"lint": "deno lint && deno task fmt:licence-headers --check && deno task lint:circular && deno task lint:deprecations && deno task lint:tools-types && deno task lint:mod-exports && deno task lint:docs",
|
||||
"typos": "typos -c ./.github/workflows/typos.toml",
|
||||
"build:crypto": "deno task --cwd crypto/_wasm wasmbuild",
|
||||
|
@ -4,8 +4,6 @@
|
||||
import { parseMediaType } from "./parse_media_type.ts";
|
||||
import { extensions } from "./_db.ts";
|
||||
|
||||
export { extensions };
|
||||
|
||||
/**
|
||||
* Returns the extensions known to be associated with the media type `type`, or
|
||||
* `undefined` if no extensions are found.
|
||||
|
Loading…
Reference in New Issue
Block a user