55 lines
2 KiB
TypeScript
55 lines
2 KiB
TypeScript
import * as Lint from "tslint/lib";
|
|
import * as ts from "typescript";
|
|
|
|
export class Rule extends Lint.Rules.AbstractRule {
|
|
public static POSTFIX_FAILURE_STRING = "Don't use '++' or '--' postfix operators outside statements or for loops.";
|
|
public static PREFIX_FAILURE_STRING = "Don't use '++' or '--' prefix operators.";
|
|
|
|
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
|
|
return this.applyWithFunction(sourceFile, walk);
|
|
}
|
|
}
|
|
|
|
function walk(ctx: Lint.WalkContext<void>): void {
|
|
ts.forEachChild(ctx.sourceFile, recur);
|
|
function recur(node: ts.Node): void {
|
|
switch (node.kind) {
|
|
case ts.SyntaxKind.PrefixUnaryExpression:
|
|
const { operator } = node as ts.PrefixUnaryExpression;
|
|
if (operator === ts.SyntaxKind.PlusPlusToken || operator === ts.SyntaxKind.MinusMinusToken) {
|
|
check(node as ts.PrefixUnaryExpression);
|
|
}
|
|
break;
|
|
|
|
case ts.SyntaxKind.PostfixUnaryExpression:
|
|
check(node as ts.PostfixUnaryExpression);
|
|
break;
|
|
}
|
|
}
|
|
|
|
function check(node: ts.UnaryExpression): void {
|
|
if (!isAllowedLocation(node.parent!)) {
|
|
ctx.addFailureAtNode(node, Rule.POSTFIX_FAILURE_STRING);
|
|
}
|
|
}
|
|
}
|
|
|
|
function isAllowedLocation(node: ts.Node): boolean {
|
|
switch (node.kind) {
|
|
// Can be a statement
|
|
case ts.SyntaxKind.ExpressionStatement:
|
|
return true;
|
|
|
|
// Can be directly in a for-statement
|
|
case ts.SyntaxKind.ForStatement:
|
|
return true;
|
|
|
|
// Can be in a comma operator in a for statement (`for (let a = 0, b = 10; a < b; a++, b--)`)
|
|
case ts.SyntaxKind.BinaryExpression:
|
|
return (node as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.CommaToken &&
|
|
node.parent!.kind === ts.SyntaxKind.ForStatement;
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
}
|