Skip to content

Commit 8f23e2d

Browse files
authored
Merge pull request #4498 from Josmithr/dont-mark-external-items-as-undocumented
fix(api-extractor): Don't mark items documented with {@inheritdoc} references to package-external items as "undocumented"
2 parents 2701cc2 + c6eb774 commit 8f23e2d

File tree

10 files changed

+445
-25
lines changed

10 files changed

+445
-25
lines changed

apps/api-extractor/src/collector/ApiItemMetadata.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,19 @@ export class ApiItemMetadata {
7575
*/
7676
public tsdocComment: tsdoc.DocComment | undefined;
7777

78-
// Assigned by DocCommentEnhancer
78+
/**
79+
* Tracks whether or not the associated API item is known to be missing sufficient documentation.
80+
*
81+
* @remarks
82+
*
83+
* An "undocumented" item is one whose TSDoc comment which either does not contain a summary comment block, or
84+
* has an `@inheritDoc` tag that resolves to another "undocumented" API member.
85+
*
86+
* If there is any ambiguity (e.g. if an `@inheritDoc` comment points to an external API member, whose documentation,
87+
* we can't parse), "undocumented" will be `false`.
88+
*
89+
* @remarks Assigned by {@link DocCommentEnhancer}.
90+
*/
7991
public undocumented: boolean = true;
8092

8193
public docCommentEnhancerVisitorState: VisitorState = VisitorState.Unvisited;

apps/api-extractor/src/enhancers/DocCommentEnhancer.ts

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -131,16 +131,43 @@ export class DocCommentEnhancer {
131131
);
132132
}
133133
return;
134-
}
135-
136-
if (metadata.tsdocComment) {
137-
// Require the summary to contain at least 10 non-spacing characters
138-
metadata.undocumented = !tsdoc.PlainTextEmitter.hasAnyTextContent(
139-
metadata.tsdocComment.summarySection,
140-
10
141-
);
142134
} else {
143-
metadata.undocumented = true;
135+
// For non-constructor items, we will determine whether or not the item is documented as follows:
136+
// 1. If it contains a summary section with at least 10 characters, then it is considered "documented".
137+
// 2. If it contains an @inheritDoc tag, then it *may* be considered "documented", depending on whether or not
138+
// the tag resolves to a "documented" API member.
139+
// - Note: for external members, we cannot currently determine this, so we will consider the "documented"
140+
// status to be unknown.
141+
if (metadata.tsdocComment) {
142+
if (tsdoc.PlainTextEmitter.hasAnyTextContent(metadata.tsdocComment.summarySection, 10)) {
143+
// If the API item has a summary comment block (with at least 10 characters), mark it as "documented".
144+
metadata.undocumented = false;
145+
} else if (metadata.tsdocComment.inheritDocTag) {
146+
if (
147+
this._refersToDeclarationInWorkingPackage(
148+
metadata.tsdocComment.inheritDocTag.declarationReference
149+
)
150+
) {
151+
// If the API item has an `@inheritDoc` comment that points to an API item in the working package,
152+
// then the documentation contents should have already been copied from the target via `_applyInheritDoc`.
153+
// The continued existence of the tag indicates that the declaration reference was invalid, and not
154+
// documentation contents could be copied.
155+
// An analyzer issue will have already been logged for this.
156+
// We will treat such an API as "undocumented".
157+
metadata.undocumented = true;
158+
} else {
159+
// If the API item has an `@inheritDoc` comment that points to an external API item, we cannot currently
160+
// determine whether or not the target is "documented", so we cannot say definitively that this is "undocumented".
161+
metadata.undocumented = false;
162+
}
163+
} else {
164+
// If the API item has neither a summary comment block, nor an `@inheritDoc` comment, mark it as "undocumented".
165+
metadata.undocumented = true;
166+
}
167+
} else {
168+
// If there is no tsdoc comment at all, mark "undocumented".
169+
metadata.undocumented = true;
170+
}
144171
}
145172
}
146173

@@ -157,10 +184,7 @@ export class DocCommentEnhancer {
157184
// Is it referring to the working package? If not, we don't do any link validation, because
158185
// AstReferenceResolver doesn't support it yet (but ModelReferenceResolver does of course).
159186
// Tracked by: https://github.com/microsoft/rushstack/issues/1195
160-
if (
161-
node.codeDestination.packageName === undefined ||
162-
node.codeDestination.packageName === this._collector.workingPackage.name
163-
) {
187+
if (this._refersToDeclarationInWorkingPackage(node.codeDestination)) {
164188
const referencedAstDeclaration: AstDeclaration | ResolverFailure =
165189
this._collector.astReferenceResolver.resolve(node.codeDestination);
166190

@@ -196,14 +220,8 @@ export class DocCommentEnhancer {
196220
return;
197221
}
198222

199-
// Is it referring to the working package?
200-
if (
201-
!(
202-
inheritDocTag.declarationReference.packageName === undefined ||
203-
inheritDocTag.declarationReference.packageName === this._collector.workingPackage.name
204-
)
205-
) {
206-
// It's referencing an external package, so skip this inheritDoc tag, since AstReferenceResolver doesn't
223+
if (!this._refersToDeclarationInWorkingPackage(inheritDocTag.declarationReference)) {
224+
// The `@inheritDoc` tag is referencing an external package. Skip it, since AstReferenceResolver doesn't
207225
// support it yet. As a workaround, this tag will get handled later by api-documenter.
208226
// Tracked by: https://github.com/microsoft/rushstack/issues/1195
209227
return;
@@ -249,4 +267,16 @@ export class DocCommentEnhancer {
249267

250268
targetDocComment.inheritDocTag = undefined;
251269
}
270+
271+
/**
272+
* Determines whether or not the provided declaration reference points to an item in the working package.
273+
*/
274+
private _refersToDeclarationInWorkingPackage(
275+
declarationReference: tsdoc.DocDeclarationReference | undefined
276+
): boolean {
277+
return (
278+
declarationReference?.packageName === undefined ||
279+
declarationReference.packageName === this._collector.workingPackage.name
280+
);
281+
}
252282
}

build-tests/api-extractor-scenarios/etc/docReferences/api-extractor-scenarios.api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export namespace MyNamespace {
2323
}
2424
}
2525

26-
// @public (undocumented)
26+
// @public
2727
export function succeedForNow(): void;
2828

2929
// @public

0 commit comments

Comments
 (0)