import * as Lint from "tslint/lib"; import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { return this.applyWithFunction(sourceFile, ctx => walk(ctx)); } } function walk(ctx: Lint.WalkContext): void { ts.forEachChild(ctx.sourceFile, function recur(node) { if (ts.isCallExpression(node)) { checkCall(node); } ts.forEachChild(node, recur); }); function checkCall(node: ts.CallExpression) { if (!isDebugAssert(node.expression) || node.arguments.length < 2) { return; } const message = node.arguments[1]; if (!ts.isStringLiteral(message)) { ctx.addFailureAtNode(message, "Second argument to 'Debug.assert' should be a string literal."); } if (node.arguments.length < 3) { return; } const message2 = node.arguments[2]; if (!ts.isStringLiteral(message2) && !ts.isArrowFunction(message2)) { ctx.addFailureAtNode(message, "Third argument to 'Debug.assert' should be a string literal or arrow function."); } } function isDebugAssert(expr: ts.Node): boolean { return ts.isPropertyAccessExpression(expr) && isName(expr.expression, "Debug") && isName(expr.name, "assert"); } function isName(expr: ts.Node, text: string): boolean { return ts.isIdentifier(expr) && expr.text === text; } }