Skip to content
This repository was archived by the owner on Mar 25, 2021. It is now read-only.

Commit 88226fd

Browse files
Josh Goldbergajafff
authored andcommitted
Converted completed-docs rule to use a function instead of a walker (#3466)
1 parent 5a9cacc commit 88226fd

File tree

2 files changed

+75
-85
lines changed

2 files changed

+75
-85
lines changed

src/rules/completed-docs/exclusionFactory.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@ import { Exclusion } from "./exclusion";
2323
import { IInputExclusionDescriptors, InputExclusionDescriptor } from "./exclusionDescriptors";
2424
import { ITagExclusionDescriptor, TagExclusion } from "./tagExclusion";
2525

26+
export type ExclusionsMap = Map<DocType, Array<Exclusion<any>>>;
27+
2628
export class ExclusionFactory {
27-
public constructExclusionsMap(ruleArguments: IInputExclusionDescriptors[]): Map<DocType, Array<Exclusion<any>>> {
28-
const exclusionsMap: Map<DocType, Array<Exclusion<any>>> = new Map();
29+
public constructExclusionsMap(ruleArguments: IInputExclusionDescriptors[]): ExclusionsMap {
30+
const exclusionsMap: ExclusionsMap = new Map();
2931

3032
for (const ruleArgument of ruleArguments) {
3133
this.addRequirements(exclusionsMap, ruleArgument);
@@ -34,7 +36,7 @@ export class ExclusionFactory {
3436
return exclusionsMap;
3537
}
3638

37-
private addRequirements(exclusionsMap: Map<DocType, Array<Exclusion<any>>>, descriptors: IInputExclusionDescriptors) {
39+
private addRequirements(exclusionsMap: ExclusionsMap, descriptors: IInputExclusionDescriptors) {
3840
if (typeof descriptors === "string") {
3941
exclusionsMap.set(descriptors, this.createRequirementsForDocType(descriptors, {}));
4042
return;

src/rules/completedDocsRule.ts

Lines changed: 70 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@ import { isVariableDeclarationList, isVariableStatement } from "tsutils";
1919
import * as ts from "typescript";
2020

2121
import * as Lint from "../index";
22-
import { Exclusion } from "./completed-docs/exclusion";
2322
import { IInputExclusionDescriptors } from "./completed-docs/exclusionDescriptors";
24-
import { ExclusionFactory } from "./completed-docs/exclusionFactory";
23+
import { ExclusionFactory, ExclusionsMap } from "./completed-docs/exclusionFactory";
2524

2625
export const ALL = "all";
2726

@@ -291,14 +290,12 @@ export class Rule extends Lint.Rules.TypedRule {
291290

292291
public applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): Lint.RuleFailure[] {
293292
const options = this.getOptions();
294-
const completedDocsWalker = new CompletedDocsWalker(sourceFile, options, program);
293+
const exclusionsMap = this.getExclusionsMap(options.ruleArguments);
295294

296-
completedDocsWalker.setExclusionsMap(this.getExclusionsMap(options.ruleArguments));
297-
298-
return this.applyWithWalker(completedDocsWalker);
295+
return this.applyWithFunction(sourceFile, walk, exclusionsMap, program.getTypeChecker());
299296
}
300297

301-
private getExclusionsMap(ruleArguments: Array<DocType | IInputExclusionDescriptors>): Map<DocType, Array<Exclusion<any>>> {
298+
private getExclusionsMap(ruleArguments: Array<DocType | IInputExclusionDescriptors>): ExclusionsMap {
302299
if (ruleArguments.length === 0) {
303300
ruleArguments = [Rule.defaultArguments];
304301
}
@@ -307,76 +304,67 @@ export class Rule extends Lint.Rules.TypedRule {
307304
}
308305
}
309306

310-
class CompletedDocsWalker extends Lint.ProgramAwareRuleWalker {
311-
private static modifierAliases: { [i: string]: string } = {
312-
export: "exported",
313-
};
307+
const modifierAliases: { [i: string]: string } = {
308+
export: "exported",
309+
};
314310

315-
private exclusionsMap: Map<DocType, Array<Exclusion<any>>>;
311+
function walk(context: Lint.WalkContext<ExclusionsMap>, typeChecker: ts.TypeChecker) {
312+
return ts.forEachChild(context.sourceFile, cb);
316313

317-
public setExclusionsMap(exclusionsMap: Map<DocType, Array<Exclusion<any>>>): void {
318-
this.exclusionsMap = exclusionsMap;
319-
}
314+
function cb(node: ts.Node): void {
315+
switch (node.kind) {
316+
case ts.SyntaxKind.ClassDeclaration:
317+
checkNode(node as ts.ClassDeclaration, ARGUMENT_CLASSES);
318+
break;
320319

321-
public visitClassDeclaration(node: ts.ClassDeclaration): void {
322-
this.checkNode(node, ARGUMENT_CLASSES);
323-
super.visitClassDeclaration(node);
324-
}
320+
case ts.SyntaxKind.EnumDeclaration:
321+
checkNode(node as ts.EnumDeclaration, ARGUMENT_ENUMS);
322+
break;
325323

326-
public visitEnumDeclaration(node: ts.EnumDeclaration): void {
327-
this.checkNode(node, ARGUMENT_ENUMS);
328-
super.visitEnumDeclaration(node);
329-
}
324+
case ts.SyntaxKind.EnumMember:
325+
// Enum members don't have modifiers, so use the parent
326+
// enum declaration when checking the requirements.
327+
checkNode(node as ts.EnumMember, ARGUMENT_ENUM_MEMBERS, node.parent);
328+
break;
330329

331-
public visitEnumMember(node: ts.EnumMember): void {
332-
// Enum members don't have modifiers, so use the parent
333-
// enum declaration when checking the requirements.
334-
this.checkNode(node, ARGUMENT_ENUM_MEMBERS, node.parent);
335-
super.visitEnumMember(node);
336-
}
330+
case ts.SyntaxKind.FunctionDeclaration:
331+
checkNode(node as ts.FunctionDeclaration, ARGUMENT_FUNCTIONS);
332+
break;
337333

338-
public visitFunctionDeclaration(node: ts.FunctionDeclaration): void {
339-
this.checkNode(node, ARGUMENT_FUNCTIONS);
340-
super.visitFunctionDeclaration(node);
341-
}
334+
case ts.SyntaxKind.InterfaceDeclaration:
335+
checkNode(node as ts.InterfaceDeclaration, ARGUMENT_INTERFACES);
336+
break;
342337

343-
public visitInterfaceDeclaration(node: ts.InterfaceDeclaration): void {
344-
this.checkNode(node, ARGUMENT_INTERFACES);
345-
super.visitInterfaceDeclaration(node);
346-
}
338+
case ts.SyntaxKind.MethodDeclaration:
339+
checkNode(node as ts.MethodDeclaration, ARGUMENT_METHODS);
340+
break;
347341

348-
public visitMethodDeclaration(node: ts.MethodDeclaration): void {
349-
this.checkNode(node, ARGUMENT_METHODS);
350-
super.visitMethodDeclaration(node);
351-
}
342+
case ts.SyntaxKind.ModuleDeclaration:
343+
checkNode(node as ts.ModuleDeclaration, ARGUMENT_NAMESPACES);
344+
break;
352345

353-
public visitModuleDeclaration(node: ts.ModuleDeclaration): void {
354-
this.checkNode(node, ARGUMENT_NAMESPACES);
355-
super.visitModuleDeclaration(node);
356-
}
346+
case ts.SyntaxKind.PropertyDeclaration:
347+
checkNode(node as ts.PropertyDeclaration, ARGUMENT_PROPERTIES);
348+
break;
357349

358-
public visitPropertyDeclaration(node: ts.PropertyDeclaration): void {
359-
this.checkNode(node, ARGUMENT_PROPERTIES);
360-
super.visitPropertyDeclaration(node);
361-
}
350+
case ts.SyntaxKind.TypeAliasDeclaration:
351+
checkNode(node as ts.TypeAliasDeclaration, ARGUMENT_TYPES);
352+
break;
362353

363-
public visitTypeAliasDeclaration(node: ts.TypeAliasDeclaration): void {
364-
this.checkNode(node, ARGUMENT_TYPES);
365-
super.visitTypeAliasDeclaration(node);
366-
}
354+
case ts.SyntaxKind.VariableDeclaration:
355+
checkVariable(node as ts.VariableDeclaration);
356+
}
367357

368-
public visitVariableDeclaration(node: ts.VariableDeclaration): void {
369-
this.checkVariable(node);
370-
super.visitVariableDeclaration(node);
358+
return ts.forEachChild(node, cb);
371359
}
372360

373-
private checkNode(node: ts.NamedDeclaration, nodeType: DocType, requirementNode: ts.Node = node): void {
361+
function checkNode(node: ts.NamedDeclaration, nodeType: DocType, requirementNode: ts.Node = node): void {
374362
const { name } = node;
375363
if (name === undefined) {
376364
return;
377365
}
378366

379-
const exclusions = this.exclusionsMap.get(nodeType);
367+
const exclusions = context.options.get(nodeType);
380368
if (exclusions === undefined) {
381369
return;
382370
}
@@ -387,16 +375,16 @@ class CompletedDocsWalker extends Lint.ProgramAwareRuleWalker {
387375
}
388376
}
389377

390-
const symbol = this.getTypeChecker().getSymbolAtLocation(name);
378+
const symbol = typeChecker.getSymbolAtLocation(name);
391379
if (symbol === undefined) {
392380
return;
393381
}
394382

395383
const comments = symbol.getDocumentationComment();
396-
this.checkComments(node, this.describeNode(nodeType), comments, requirementNode);
384+
checkComments(node, describeNode(nodeType), comments, requirementNode);
397385
}
398386

399-
private checkVariable(node: ts.VariableDeclaration) {
387+
function checkVariable(node: ts.VariableDeclaration) {
400388
// Only check variables in variable declaration lists
401389
// and not variables in catch clauses and for loops.
402390
const list = node.parent!;
@@ -414,41 +402,41 @@ class CompletedDocsWalker extends Lint.ProgramAwareRuleWalker {
414402
switch (statement.parent!.kind) {
415403
case ts.SyntaxKind.SourceFile:
416404
case ts.SyntaxKind.ModuleBlock:
417-
this.checkNode(node, ARGUMENT_VARIABLES, statement);
405+
checkNode(node, ARGUMENT_VARIABLES, statement);
418406
}
419407
}
420408

421-
private checkComments(node: ts.Node, nodeDescriptor: string, comments: ts.SymbolDisplayPart[], requirementNode: ts.Node) {
409+
function checkComments(node: ts.Node, nodeDescriptor: string, comments: ts.SymbolDisplayPart[], requirementNode: ts.Node) {
422410
if (comments.map((comment: ts.SymbolDisplayPart) => comment.text).join("").trim() === "") {
423-
this.addDocumentationFailure(node, nodeDescriptor, requirementNode);
411+
addDocumentationFailure(node, nodeDescriptor, requirementNode);
424412
}
425413
}
426414

427-
private addDocumentationFailure(node: ts.Node, nodeType: string, requirementNode: ts.Node): void {
415+
function addDocumentationFailure(node: ts.Node, nodeType: string, requirementNode: ts.Node): void {
428416
const start = node.getStart();
429417
const width = node.getText().split(/\r|\n/g)[0].length;
430-
const description = this.describeDocumentationFailure(requirementNode, nodeType);
418+
const description = describeDocumentationFailure(requirementNode, nodeType);
431419

432-
this.addFailureAt(start, width, description);
420+
context.addFailureAt(start, width, description);
433421
}
422+
}
434423

435-
private describeDocumentationFailure(node: ts.Node, nodeType: string): string {
436-
let description = Rule.FAILURE_STRING_EXIST;
437-
438-
if (node.modifiers !== undefined) {
439-
description += `${node.modifiers.map((modifier) => this.describeModifier(modifier.kind)).join(" ")} `;
440-
}
424+
function describeDocumentationFailure(node: ts.Node, nodeType: string): string {
425+
let description = Rule.FAILURE_STRING_EXIST;
441426

442-
return `${description}${nodeType}.`;
427+
if (node.modifiers !== undefined) {
428+
description += `${node.modifiers.map((modifier) => describeModifier(modifier.kind)).join(" ")} `;
443429
}
444430

445-
private describeModifier(kind: ts.SyntaxKind) {
446-
const description = ts.SyntaxKind[kind].toLowerCase().split("keyword")[0];
447-
const alias = CompletedDocsWalker.modifierAliases[description];
448-
return alias !== undefined ? alias : description;
449-
}
431+
return `${description}${nodeType}.`;
432+
}
450433

451-
private describeNode(nodeType: DocType): string {
452-
return nodeType.replace("-", " ");
453-
}
434+
function describeModifier(kind: ts.SyntaxKind) {
435+
const description = ts.SyntaxKind[kind].toLowerCase().split("keyword")[0];
436+
const alias = modifierAliases[description];
437+
return alias !== undefined ? alias : description;
438+
}
439+
440+
function describeNode(nodeType: DocType): string {
441+
return nodeType.replace("-", " ");
454442
}

0 commit comments

Comments
 (0)