Skip to content

Commit a07e853

Browse files
committed
Add some validation to ensure property setters/getters are documented correctly
1 parent 5b01496 commit a07e853

File tree

6 files changed

+41
-6
lines changed

6 files changed

+41
-6
lines changed

apps/api-extractor/src/api/ExtractorMessageId.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,17 @@ export const enum ExtractorMessageId {
8585
/**
8686
* "The `@link` reference could not be resolved".
8787
*/
88-
UnresolvedLink = 'ae-unresolved-link'
88+
UnresolvedLink = 'ae-unresolved-link',
89+
90+
/**
91+
* "The doc comment for the property ___ must appear on the getter, not the setter.".
92+
*/
93+
SetterWithDocs = 'ae-setter-with-docs',
94+
95+
/**
96+
* "The property ___ has a setter but no getter.".
97+
*/
98+
MissingGetter = 'ae-missing-getter',
8999
}
90100

91101
export const allExtractorMessageIds: Set<string> = new Set<string>([
@@ -102,5 +112,7 @@ export const allExtractorMessageIds: Set<string> = new Set<string>([
102112
'ae-unresolved-inheritdoc-reference',
103113
'ae-unresolved-inheritdoc-base',
104114
'ae-cyclic-inherit-doc',
105-
'ae-unresolved-link'
115+
'ae-unresolved-link',
116+
'ae-setter-with-docs',
117+
'ae-missing-getter'
106118
]);

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,14 +528,24 @@ export class Collector {
528528

529529
// For a getter/setter pair, make the setter ancillary to the getter
530530
if (astDeclaration.declaration.kind === ts.SyntaxKind.SetAccessor) {
531+
let foundGetter: boolean = false;
531532
for (const getterAstDeclaration of astDeclaration.astSymbol.astDeclarations) {
532533
if (getterAstDeclaration.declaration.kind === ts.SyntaxKind.GetAccessor) {
533534
const getterMetadata: DeclarationMetadata = getterAstDeclaration.metadata as DeclarationMetadata;
534535

535536
// Associate it with the getter
536537
getterMetadata.addAncillaryDeclaration(astDeclaration);
538+
539+
foundGetter = true;
537540
}
538541
}
542+
543+
if (!foundGetter) {
544+
this.messageRouter.addAnalyzerIssue(
545+
ExtractorMessageId.MissingGetter,
546+
`The property "${astDeclaration.astSymbol.localName}" has a setter but no getter.`,
547+
astDeclaration);
548+
}
539549
}
540550
}
541551

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,20 @@ export class DocCommentEnhancer {
127127
);
128128

129129
}
130+
return;
131+
}
132+
133+
if (astDeclaration.declaration.kind === ts.SyntaxKind.SetAccessor) {
134+
if (metadata.tsdocComment) {
135+
this._collector.messageRouter.addAnalyzerIssue(ExtractorMessageId.SetterWithDocs,
136+
`The doc comment for the property "${astDeclaration.astSymbol.localName}"`
137+
+ ` must appear on the getter, not the setter.`,
138+
astDeclaration);
139+
}
140+
return;
141+
}
130142

131-
} else if (metadata.tsdocComment) {
143+
if (metadata.tsdocComment) {
132144
// Require the summary to contain at least 10 non-spacing characters
133145
metadata.needsDocumentation = !tsdoc.PlainTextEmitter.hasAnyTextContent(
134146
metadata.tsdocComment.summarySection, 10);

apps/api-extractor/src/generators/ApiReportGenerator.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,8 @@ export class ApiReportGenerator {
404404
}
405405
}
406406

407-
if (declarationMetadata.needsDocumentation) {
407+
// Note that ancillary declarations aren't supposed to have documentation
408+
if (declarationMetadata.needsDocumentation && !declarationMetadata.isAncillary) {
408409
footerParts.push('(undocumented)');
409410
}
410411

common/reviews/api/api-extractor-model.api.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -627,9 +627,7 @@ export class ExcerptToken {
627627

628628
// @public (undocumented)
629629
export const enum ExcerptTokenKind {
630-
// (undocumented)
631630
Content = "Content",
632-
// (undocumented)
633631
Reference = "Reference"
634632
}
635633

common/reviews/api/api-extractor.api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,11 @@ export const enum ExtractorMessageId {
119119
InternalMissingUnderscore = "ae-internal-missing-underscore",
120120
InternalMixedReleaseTag = "ae-internal-mixed-release-tag",
121121
MisplacedPackageTag = "ae-misplaced-package-tag",
122+
MissingGetter = "ae-missing-getter",
122123
MissingReleaseTag = "ae-missing-release-tag",
123124
PreapprovedBadReleaseTag = "ae-preapproved-bad-release-tag",
124125
PreapprovedUnsupportedType = "ae-preapproved-unsupported-type",
126+
SetterWithDocs = "ae-setter-with-docs",
125127
UnresolvedInheritDocBase = "ae-unresolved-inheritdoc-base",
126128
UnresolvedInheritDocReference = "ae-unresolved-inheritdoc-reference",
127129
UnresolvedLink = "ae-unresolved-link"

0 commit comments

Comments
 (0)