Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to warn on undocumented items #1819

Merged
merged 11 commits into from
Jan 23, 2022
2 changes: 1 addition & 1 deletion .config/regconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"core": {
"workingDir": "dist/tmp/.reg",
"actualDir": "dist/tmp/__screenshots__",
"thresholdRate": 0.001,
"thresholdRate": 0.01,
"addIgnore": true,
"ximgdiff": {
"invocationType": "client"
Expand Down
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

### Features

- Added `--validation.notDocumented` option to warn on items that are not documented, #1817.
- Added new `cname` option for GitHub Pages custom domain support, #1803.
- `ReferenceType`s which reference an external symbol will now include `qualifiedName` and `package` in their serialized JSON.
- Added clickable anchor link for member titles, #1842.
- Added new `cname` option for GitHub Pages custom domain support, #1803

### Bug Fixes

Expand Down
9 changes: 9 additions & 0 deletions src/lib/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
} from "./utils/entry-point";
import { nicePath } from "./utils/paths";
import { hasBeenLoadedMultipleTimes } from "./utils/general";
import { validateDocumentation } from "./validation/documentation";

// eslint-disable-next-line @typescript-eslint/no-var-requires
const packageInfo = require("../../package.json") as {
Expand Down Expand Up @@ -416,6 +417,14 @@ export class Application extends ChildableComponent<
);
}

if (checks.notDocumented) {
validateDocumentation(
project,
this.logger,
this.options.getValue("requiredToBeDocumented")
);
}

// checks.invalidLink is currently handled when rendering by the MarkedLinksPlugin.
// It should really move here, but I'm putting that off until done refactoring the comment
// parsing so that we don't have duplicate parse logic all over the place.
Expand Down
2 changes: 1 addition & 1 deletion src/lib/models/ReflectionGroup.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ReflectionKind } from "./reflections/abstract";
import type { ReflectionKind } from "./reflections/kind";
import type { ReflectionCategory } from "./ReflectionCategory";
import type { DeclarationReflection } from ".";

Expand Down
74 changes: 1 addition & 73 deletions src/lib/models/reflections/abstract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { Comment } from "../comments/comment";
import { splitUnquotedString } from "./utils";
import type { ProjectReflection } from "./project";
import type { NeverIfInternal } from "../../utils";
import { ReflectionKind } from "./kind";

/**
* Holds all data models used by TypeDoc.
Expand Down Expand Up @@ -32,79 +33,6 @@ export function resetReflectionID() {
REFLECTION_ID = 0;
}

/**
* Defines the available reflection kinds.
*/
export enum ReflectionKind {
Project = 0x1,
Module = 0x2,
Namespace = 0x4,
Enum = 0x8,
EnumMember = 0x10,
Variable = 0x20,
Function = 0x40,
Class = 0x80,
Interface = 0x100,
Constructor = 0x200,
Property = 0x400,
Method = 0x800,
CallSignature = 0x1000,
IndexSignature = 0x2000,
ConstructorSignature = 0x4000,
Parameter = 0x8000,
TypeLiteral = 0x10000,
TypeParameter = 0x20000,
Accessor = 0x40000,
GetSignature = 0x80000,
SetSignature = 0x100000,
ObjectLiteral = 0x200000,
TypeAlias = 0x400000,
Event = 0x800000,
Reference = 0x1000000,
}

/** @hidden */
export namespace ReflectionKind {
export const All = ReflectionKind.Reference * 2 - 1;

export const ClassOrInterface =
ReflectionKind.Class | ReflectionKind.Interface;
export const VariableOrProperty =
ReflectionKind.Variable | ReflectionKind.Property;
export const FunctionOrMethod =
ReflectionKind.Function | ReflectionKind.Method;
export const ClassMember =
ReflectionKind.Accessor |
ReflectionKind.Constructor |
ReflectionKind.Method |
ReflectionKind.Property |
ReflectionKind.Event;
export const SomeSignature =
ReflectionKind.CallSignature |
ReflectionKind.IndexSignature |
ReflectionKind.ConstructorSignature |
ReflectionKind.GetSignature |
ReflectionKind.SetSignature;
export const SomeModule = ReflectionKind.Namespace | ReflectionKind.Module;
export const SomeType =
ReflectionKind.Interface |
ReflectionKind.TypeLiteral |
ReflectionKind.TypeParameter |
ReflectionKind.TypeAlias;
export const SomeValue =
ReflectionKind.Variable |
ReflectionKind.Function |
ReflectionKind.ObjectLiteral;

/** @internal */
export const Inheritable =
ReflectionKind.Accessor |
ReflectionKind.IndexSignature |
ReflectionKind.Property |
ReflectionKind.Method |
ReflectionKind.Constructor;
}

export enum ReflectionFlag {
None = 0,
Private = 1,
Expand Down
8 changes: 2 additions & 6 deletions src/lib/models/reflections/container.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import {
Reflection,
ReflectionKind,
TraverseCallback,
TraverseProperty,
} from "./abstract";
import { Reflection, TraverseCallback, TraverseProperty } from "./abstract";
import type { ReflectionCategory } from "../ReflectionCategory";
import type { ReflectionGroup } from "../ReflectionGroup";
import type { DeclarationReflection } from "./declaration";
import type { ReflectionKind } from "./kind";

export class ContainerReflection extends Reflection {
/**
Expand Down
4 changes: 2 additions & 2 deletions src/lib/models/reflections/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
export {
Reflection,
ReflectionKind,
ReflectionFlag,
TraverseProperty,
ReflectionFlags,
TraverseProperty,
} from "./abstract";
export type { Decorator, TraverseCallback } from "./abstract";
export { ContainerReflection } from "./container";
export { DeclarationReflection } from "./declaration";
export type { DeclarationHierarchy } from "./declaration";
export { ReflectionKind } from "./kind";
export { ParameterReflection } from "./parameter";
export { ProjectReflection } from "./project";
export { ReferenceReflection } from "./reference";
Expand Down
72 changes: 72 additions & 0 deletions src/lib/models/reflections/kind.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* Defines the available reflection kinds.
*/
export enum ReflectionKind {
Project = 0x1,
Module = 0x2,
Namespace = 0x4,
Enum = 0x8,
EnumMember = 0x10,
Variable = 0x20,
Function = 0x40,
Class = 0x80,
Interface = 0x100,
Constructor = 0x200,
Property = 0x400,
Method = 0x800,
CallSignature = 0x1000,
IndexSignature = 0x2000,
ConstructorSignature = 0x4000,
Parameter = 0x8000,
TypeLiteral = 0x10000,
TypeParameter = 0x20000,
Accessor = 0x40000,
GetSignature = 0x80000,
SetSignature = 0x100000,
ObjectLiteral = 0x200000,
TypeAlias = 0x400000,
Event = 0x800000,
Reference = 0x1000000,
}

/** @hidden */
export namespace ReflectionKind {
export const All = ReflectionKind.Reference * 2 - 1;

export const ClassOrInterface =
ReflectionKind.Class | ReflectionKind.Interface;
export const VariableOrProperty =
ReflectionKind.Variable | ReflectionKind.Property;
export const FunctionOrMethod =
ReflectionKind.Function | ReflectionKind.Method;
export const ClassMember =
ReflectionKind.Accessor |
ReflectionKind.Constructor |
ReflectionKind.Method |
ReflectionKind.Property |
ReflectionKind.Event;
export const SomeSignature =
ReflectionKind.CallSignature |
ReflectionKind.IndexSignature |
ReflectionKind.ConstructorSignature |
ReflectionKind.GetSignature |
ReflectionKind.SetSignature;
export const SomeModule = ReflectionKind.Namespace | ReflectionKind.Module;
export const SomeType =
ReflectionKind.Interface |
ReflectionKind.TypeLiteral |
ReflectionKind.TypeParameter |
ReflectionKind.TypeAlias;
export const SomeValue =
ReflectionKind.Variable |
ReflectionKind.Function |
ReflectionKind.ObjectLiteral;

/** @internal */
export const Inheritable =
ReflectionKind.Accessor |
ReflectionKind.IndexSignature |
ReflectionKind.Property |
ReflectionKind.Method |
ReflectionKind.Constructor;
}
3 changes: 2 additions & 1 deletion src/lib/models/reflections/project.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SourceFile, SourceDirectory } from "../sources/index";
import { Reflection, ReflectionKind, TraverseProperty } from "./abstract";
import { Reflection, TraverseProperty } from "./abstract";
import { ContainerReflection } from "./container";
import { splitUnquotedString } from "./utils";
import { ReferenceReflection } from "./reference";
Expand All @@ -10,6 +10,7 @@ import { IntrinsicType } from "../types";
import type { TypeParameterReflection } from "./type-parameter";
import { removeIfPresent } from "../../utils";
import type * as ts from "typescript";
import { ReflectionKind } from "./kind";

/**
* A reflection that represents the root of the project.
Expand Down
3 changes: 2 additions & 1 deletion src/lib/models/reflections/reference.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type * as ts from "typescript";
import { Reflection, ReflectionKind } from "./abstract";
import { Reflection } from "./abstract";
import { DeclarationReflection } from "./declaration";
import { ReflectionKind } from "./kind";
import type { ProjectReflection } from "./project";

/**
Expand Down
8 changes: 2 additions & 6 deletions src/lib/models/reflections/signature.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import { Type, ReflectionType, ReferenceType } from "../types";
import {
Reflection,
TraverseProperty,
TraverseCallback,
ReflectionKind,
} from "./abstract";
import { Reflection, TraverseProperty, TraverseCallback } from "./abstract";
import type { ParameterReflection } from "./parameter";
import type { TypeParameterReflection } from "./type-parameter";
import type { DeclarationReflection } from "./declaration";
import type { ReflectionKind } from "./kind";

export class SignatureReflection extends Reflection {
/**
Expand Down
3 changes: 2 additions & 1 deletion src/lib/models/reflections/type-parameter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Type } from "../types";
import { Reflection, ReflectionKind } from "./abstract";
import { Reflection } from "./abstract";
import type { DeclarationReflection } from "./declaration";
import { ReflectionKind } from "./kind";

export class TypeParameterReflection extends Reflection {
override parent?: DeclarationReflection;
Expand Down
6 changes: 6 additions & 0 deletions src/lib/utils/options/declaration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { LogLevel } from "../loggers";
import type { SortStrategy } from "../sort";
import { isAbsolute, join, resolve } from "path";
import type { EntryPointStrategy } from "../entry-point";
import type { ReflectionKind } from "../../models/reflections/kind";

export const EmitStrategy = {
true: true, // Alias for both, for backwards compatibility until 0.23
Expand Down Expand Up @@ -116,6 +117,7 @@ export interface TypeDocOptionMap {
/** @deprecated use validation.invalidLink */
listInvalidSymbolLinks: boolean;
validation: ValidationOptions;
requiredToBeDocumented: (keyof typeof ReflectionKind)[];
}

export type ValidationOptions = {
Expand All @@ -128,6 +130,10 @@ export type ValidationOptions = {
* If set, TypeDoc will produce warnings about \{&amp;link\} tags which will produce broken links.
*/
invalidLink: boolean;
/**
* If set, TypeDoc will produce warnings about declarations that do not have doc comments
*/
notDocumented: boolean;
};

/**
Expand Down
36 changes: 36 additions & 0 deletions src/lib/utils/options/sources/typedoc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ParameterType, ParameterHint, EmitStrategy } from "../declaration";
import { BUNDLED_THEMES, Theme } from "shiki";
import { SORT_STRATEGIES } from "../../sort";
import { EntryPointStrategy } from "../../entry-point";
import { ReflectionKind } from "../../../models/reflections/kind";

export function addTypeDocOptions(options: Pick<Options, "addDeclaration">) {
options.addDeclaration({
Expand Down Expand Up @@ -342,6 +343,40 @@ export function addTypeDocOptions(options: Pick<Options, "addDeclaration">) {
help: "A list of types which should not produce 'referenced but not documented' warnings.",
type: ParameterType.Array,
});
options.addDeclaration({
name: "requiredToBeDocumented",
help: "A list of reflection kinds that must be documented",
type: ParameterType.Array,
validate(values) {
// this is good enough because the values of the ReflectionKind enum are all numbers
const validValues = Object.values(ReflectionKind).filter(
(v) => typeof v === "string"
);

for (const kind of values) {
if (validValues.includes(kind)) {
throw new Error(
`'${kind}' is an invalid value for 'requiredToBeDocumented'. Must be one of: ${validValues.join(
", "
)}`
);
}
}
},
defaultValue: [
"Enum",
"EnumMember",
"Variable",
"Function",
"Class",
"Interface",
"Property",
"Method",
"GetSignature",
"SetSignature",
"TypeAlias",
],
});

options.addDeclaration({
name: "validation",
Expand All @@ -350,6 +385,7 @@ export function addTypeDocOptions(options: Pick<Options, "addDeclaration">) {
defaults: {
notExported: true,
invalidLink: false,
notDocumented: false,
},
});
}
2 changes: 1 addition & 1 deletion src/lib/utils/sort.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @module
*/

import { ReflectionKind } from "../models/reflections/abstract";
import { ReflectionKind } from "../models/reflections/kind";
import type { DeclarationReflection } from "../models/reflections/declaration";

export const SORT_STRATEGIES = [
Expand Down