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

Default type parameter of WalkContext and AbstractWalker to void #2600

Merged
merged 4 commits into from
Mar 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions docs/develop/custom-rules/walker-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,23 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

// Here, the options object type is `void` because we don't pass any options in this example.
// Here, the options object type is `void` (which is the default, so can be omitted) because we don't pass any options in this example.
function walk(ctx: Lint.WalkContext<void>) {
// Recursively walk the AST starting with root node, `ctx.sourceFile`.
// Call the function `cb` (defined below) for each child.
return ts.forEachChild(ctx.sourceFile, cb);

function cb(node: ts.Node): void {
// Stop recursing further into the AST by returning early. Here, we ignore type nodes.
if (node.kind >= ts.SyntaxKind.FirstTypeNode && node.kind <= ts.SyntaxKind.LastTypeNode) {
return;
}

// Add failures using the `WalkContext<T>` object. Here, we add a failure if we find the null keyword.
if (node.kind === ts.SyntaxKind.NullKeyword) {
return ctx.addFailureAtNode(node, Rule.FAILURE_STRING);
}

// Continue recursion into the AST by calling function `cb` for every child of the current node.
return ts.forEachChild(node, cb);
}
Expand Down Expand Up @@ -90,7 +90,7 @@ class NoMagicNumbersWalker extends Lint.AbstractWalker<Set<string>> {
return ts.forEachChild(node, cb);
}
};

// Start recursion for all children of `sourceFile`.
return ts.forEachChild(sourceFile, cb);
}
Expand All @@ -108,7 +108,7 @@ class NoMagicNumbersWalker extends Lint.AbstractWalker<Set<string>> {
## Migrating from RuleWalker to AbstractWalker

The main difference between `RuleWalker` and `AbstractWalker` is that you need to implement the AST recursion yourself. But why would you want to do that?
__Performance!__ `RuleWalker` wants to be "one walker to rule them all" (pun intended). It's easy to use but that convenience
__Performance!__ `RuleWalker` wants to be "one walker to rule them all" (pun intended). It's easy to use but that convenience
makes it slow by default. When implementing the walking yourself, you only need to do as much work as needed.

Besides that you *should* convert the `ruleArguments` to a useful format before passing it to `AbstractWalker` as seen above.
Expand All @@ -125,8 +125,8 @@ This table describes the equivalent methods between the two classes:
`this.appendText()` | `Lint.Replacement.appendText()`
`this.hasOption()` and `this.getOptions()` | use `this.options` directly
`this.getLineAndCharacterOfPosition()` | `ts.getLineAndCharacterOfPosition(this.sourceFile, ...)`
`this.getLimit()` | `this.sourceFile.end`
`this.getSourceFile()` | is available to be compatible, but prefer `this.sourceFile`
`this.getLimit()` | `this.sourceFile.end`
`this.getSourceFile()` | is available to be compatible, but prefer `this.sourceFile`
`this.getFailures()` | is available to be compatible, but prefer `this.failures`
`this.skip()` | just don't use it, it's a noop
`this.getRuleName()` | `this.ruleName`
2 changes: 1 addition & 1 deletion src/language/rule/abstractRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export abstract class AbstractRule implements IRule {

protected applyWithFunction(
sourceFile: ts.SourceFile,
walkFn: (ctx: WalkContext<void>) => void,
walkFn: (ctx: WalkContext) => void,
): RuleFailure[];
protected applyWithFunction<T>(
sourceFile: ts.SourceFile,
Expand Down
2 changes: 1 addition & 1 deletion src/language/walker/scopeAwareRuleWalker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { RuleWalker } from "./ruleWalker";
*
* For example, imagine a `no-break` rule that warns on `break` in `for` but not in `switch`:
*
* function walk(ctx: Lint.WalkContext<void>): void {
* function walk(ctx: Lint.WalkContext): void {
* let isInFor = false;
* ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {
* switch (node.kind) {
Expand Down
2 changes: 1 addition & 1 deletion src/language/walker/walkContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import * as ts from "typescript";

import { Fix, RuleFailure } from "../rule/rule";

export class WalkContext<T> {
export class WalkContext<T = void> {
public readonly failures: RuleFailure[] = [];

constructor(
Expand Down
2 changes: 1 addition & 1 deletion src/language/walker/walker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export interface IWalker {
getFailures(): RuleFailure[];
}

export abstract class AbstractWalker<T> extends WalkContext<T> implements IWalker {
export abstract class AbstractWalker<T = void> extends WalkContext<T> implements IWalker {
public abstract walk(sourceFile: ts.SourceFile): void;

public getSourceFile() {
Expand Down
2 changes: 1 addition & 1 deletion src/rules/adjacentOverloadSignaturesRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>): void {
function walk(ctx: Lint.WalkContext): void {
const { sourceFile } = ctx;
visitStatements(sourceFile.statements);
return ts.forEachChild(sourceFile, function cb(node: ts.Node): void {
Expand Down
2 changes: 1 addition & 1 deletion src/rules/banCommaOperatorRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>) {
function walk(ctx: Lint.WalkContext) {
return ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {
if (
isBinaryExpression(node) &&
Expand Down
2 changes: 1 addition & 1 deletion src/rules/banTsIgnoreRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>) {
function walk(ctx: Lint.WalkContext) {
const ignoreDiagnosticCommentRegEx = /^\s*\/\/\/?\s*@ts-ignore/;
forEachComment(ctx.sourceFile, (fullText, comment) => {
const commentText = fullText.slice(comment.pos, comment.end);
Expand Down
2 changes: 1 addition & 1 deletion src/rules/binaryExpressionOperandOrderRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>): void {
function walk(ctx: Lint.WalkContext): void {
ts.forEachChild(ctx.sourceFile, function cb(node) {
if (
isBinaryExpression(node) &&
Expand Down
2 changes: 1 addition & 1 deletion src/rules/callableTypesRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>) {
function walk(ctx: Lint.WalkContext) {
return ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {
if (
((isInterfaceDeclaration(node) && noSupertype(node)) || isTypeLiteralNode(node)) &&
Expand Down
2 changes: 1 addition & 1 deletion src/rules/classNameRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>) {
function walk(ctx: Lint.WalkContext) {
return ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {
if (
(isClassLikeDeclaration(node) && node.name !== undefined) ||
Expand Down
2 changes: 1 addition & 1 deletion src/rules/curlyRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walkAsNeeded(ctx: Lint.WalkContext<void>): void {
function walkAsNeeded(ctx: Lint.WalkContext): void {
ts.forEachChild(ctx.sourceFile, function cb(node) {
if (isBlock(node) && isBlockUnnecessary(node)) {
ctx.addFailureAt(node.statements.pos - 1, 1, Rule.FAILURE_STRING_AS_NEEDED);
Expand Down
2 changes: 1 addition & 1 deletion src/rules/deprecationRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export class Rule extends Lint.Rules.TypedRule {
}
}

function walk(ctx: Lint.WalkContext<void>, tc: ts.TypeChecker) {
function walk(ctx: Lint.WalkContext, tc: ts.TypeChecker) {
return ts.forEachChild(ctx.sourceFile, function cb(node): void {
if (isIdentifier(node)) {
if (!isDeclaration(node)) {
Expand Down
2 changes: 1 addition & 1 deletion src/rules/encodingRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>): void {
function walk(ctx: Lint.WalkContext): void {
const encoding = detectEncoding(ctx.sourceFile.fileName);
if (encoding !== "utf8") {
ctx.addFailure(0, 1, Rule.FAILURE_STRING(encoding));
Expand Down
2 changes: 1 addition & 1 deletion src/rules/forinRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>) {
function walk(ctx: Lint.WalkContext) {
return ts.forEachChild(ctx.sourceFile, function cb(node): void {
if (isForInStatement(node) && isBlock(node.statement) && !isFiltered(node.statement)) {
ctx.addFailureAtNode(node, Rule.FAILURE_STRING);
Expand Down
2 changes: 1 addition & 1 deletion src/rules/functionConstructorRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(context: Lint.WalkContext<void>): void {
function walk(context: Lint.WalkContext): void {
ts.forEachChild(context.sourceFile, function cb(node): void {
if (isFunctionCallOrNewExpression(node)) {
addFailureAtNode(node);
Expand Down
2 changes: 1 addition & 1 deletion src/rules/importSpacingRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

class Walker extends Lint.AbstractWalker<void> {
class Walker extends Lint.AbstractWalker {
public walk({ statements }: ts.SourceFile): void {
for (const statement of statements) {
if (!isImportDeclaration(statement)) {
Expand Down
2 changes: 1 addition & 1 deletion src/rules/interfaceOverTypeLiteralRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>): void {
function walk(ctx: Lint.WalkContext): void {
return ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {
if (isTypeAliasDeclaration(node) && isTypeLiteralNode(node.type)) {
const typeKeyword = getChildOfKind(node, ts.SyntaxKind.TypeKeyword, ctx.sourceFile)!;
Expand Down
2 changes: 1 addition & 1 deletion src/rules/labelPositionRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>): void {
function walk(ctx: Lint.WalkContext): void {
return ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {
if (isLabeledStatement(node) && !isLabelable(node.statement)) {
ctx.addFailureAtNode(node.label, Rule.FAILURE_STRING);
Expand Down
2 changes: 1 addition & 1 deletion src/rules/matchDefaultExportNameRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class Rule extends Lint.Rules.TypedRule {
}
}

function walk(ctx: Lint.WalkContext<void>, tc: ts.TypeChecker) {
function walk(ctx: Lint.WalkContext, tc: ts.TypeChecker) {
for (const statement of ctx.sourceFile.statements) {
if (
!isImportDeclaration(statement) ||
Expand Down
2 changes: 1 addition & 1 deletion src/rules/newParensRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>) {
function walk(ctx: Lint.WalkContext) {
return ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {
if (
node.kind === ts.SyntaxKind.NewExpression &&
Expand Down
2 changes: 1 addition & 1 deletion src/rules/newlineBeforeReturnRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

class NewlineBeforeReturnWalker extends Lint.AbstractWalker<void> {
class NewlineBeforeReturnWalker extends Lint.AbstractWalker {
public walk(sourceFile: ts.SourceFile) {
const cb = (node: ts.Node): void => {
if (node.kind === ts.SyntaxKind.ReturnStatement) {
Expand Down
2 changes: 1 addition & 1 deletion src/rules/newlinePerChainedCallRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

class NewlinePerChainedCallWalker extends Lint.AbstractWalker<void> {
class NewlinePerChainedCallWalker extends Lint.AbstractWalker {
public walk(sourceFile: ts.SourceFile) {
const checkForSameLine = (node: ts.Node): void => {
if (
Expand Down
2 changes: 1 addition & 1 deletion src/rules/noAngleBracketTypeAssertionRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>) {
function walk(ctx: Lint.WalkContext) {
return ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {
if (isTypeAssertion(node)) {
let { expression } = node;
Expand Down
2 changes: 1 addition & 1 deletion src/rules/noAnyRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>) {
function walk(ctx: Lint.WalkContext) {
return ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {
if (node.kind === ts.SyntaxKind.AnyKeyword) {
const start = node.end - 3;
Expand Down
2 changes: 1 addition & 1 deletion src/rules/noArgRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>) {
function walk(ctx: Lint.WalkContext) {
return ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {
if (
isPropertyAccessExpression(node) &&
Expand Down
2 changes: 1 addition & 1 deletion src/rules/noBitwiseRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>) {
function walk(ctx: Lint.WalkContext) {
return ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {
if (node.kind === ts.SyntaxKind.BinaryExpression) {
switch ((node as ts.BinaryExpression).operatorToken.kind) {
Expand Down
2 changes: 1 addition & 1 deletion src/rules/noBooleanLiteralCompareRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class Rule extends Lint.Rules.TypedRule {
}
}

function walk(ctx: Lint.WalkContext<void>, checker: ts.TypeChecker): void {
function walk(ctx: Lint.WalkContext, checker: ts.TypeChecker): void {
return ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {
if (utils.isBinaryExpression(node)) {
const cmp = getBooleanComparison(node, checker);
Expand Down
2 changes: 1 addition & 1 deletion src/rules/noConditionalAssignmentRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>) {
function walk(ctx: Lint.WalkContext) {
let checking = 0;
return ts.forEachChild(ctx.sourceFile, cb);

Expand Down
2 changes: 1 addition & 1 deletion src/rules/noConstructRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>) {
function walk(ctx: Lint.WalkContext) {
return ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {
if (isNewExpression(node) && node.expression.kind === ts.SyntaxKind.Identifier) {
switch ((node.expression as ts.Identifier).text) {
Expand Down
2 changes: 1 addition & 1 deletion src/rules/noDebuggerRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>) {
function walk(ctx: Lint.WalkContext) {
return ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {
if (node.kind === ts.SyntaxKind.DebuggerStatement) {
return ctx.addFailureAtNode(node, Rule.FAILURE_STRING);
Expand Down
2 changes: 1 addition & 1 deletion src/rules/noDefaultExportRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>) {
function walk(ctx: Lint.WalkContext) {
if (ctx.sourceFile.isDeclarationFile || !ts.isExternalModule(ctx.sourceFile)) {
return;
}
Expand Down
2 changes: 1 addition & 1 deletion src/rules/noDuplicateSuperRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>): void {
function walk(ctx: Lint.WalkContext): void {
return ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {
if (isConstructorDeclaration(node) && node.body !== undefined) {
getSuperForNode(node.body);
Expand Down
2 changes: 1 addition & 1 deletion src/rules/noDuplicateSwitchCaseRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>): void {
function walk(ctx: Lint.WalkContext): void {
ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {
if (node.kind === ts.SyntaxKind.CaseBlock) {
visitCaseBlock(node as ts.CaseBlock);
Expand Down
2 changes: 1 addition & 1 deletion src/rules/noDynamicDeleteRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(context: Lint.WalkContext<void>) {
function walk(context: Lint.WalkContext) {
function checkDeleteAccessExpression(node: ts.Expression | undefined): void {
if (node === undefined || !tsutils.isElementAccessExpression(node)) {
return;
Expand Down
2 changes: 1 addition & 1 deletion src/rules/noEmptyInterfaceRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>) {
function walk(ctx: Lint.WalkContext) {
return ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {
if (
isInterfaceDeclaration(node) &&
Expand Down
2 changes: 1 addition & 1 deletion src/rules/noEvalRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<void>) {
function walk(ctx: Lint.WalkContext) {
return ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {
if (
isCallExpression(node) &&
Expand Down
2 changes: 1 addition & 1 deletion src/rules/noForInArrayRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export class Rule extends Lint.Rules.TypedRule {
}
}

function walk(ctx: Lint.WalkContext<void>, checker: ts.TypeChecker) {
function walk(ctx: Lint.WalkContext, checker: ts.TypeChecker) {
return ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {
if (node.kind === ts.SyntaxKind.ForInStatement) {
const type = checker.getTypeAtLocation((node as ts.ForInStatement).expression);
Expand Down
2 changes: 1 addition & 1 deletion src/rules/noInferredEmptyObjectTypeRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export class Rule extends Lint.Rules.TypedRule {
}
}

class NoInferredEmptyObjectTypeRule extends Lint.AbstractWalker<void> {
class NoInferredEmptyObjectTypeRule extends Lint.AbstractWalker {
constructor(
sourceFile: ts.SourceFile,
ruleName: string,
Expand Down
Loading