All files noExpressionStatementRule.ts

100% Statements 42/42
90.91% Branches 20/22
100% Functions 9/9
100% Lines 36/36
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 691x 1x   1x               3x 2x 2x 2x     3x     1x 1x   1x 3x 3x   1x   1x         3x 3x     1x 45x 6x 6x 6x 6x 6x 3x     45x     1x 6x 1x   5x 5x 2x     2x 1x     2x     1x  
import * as ts from "typescript";
import * as Lint from "tslint";
 
const OPTION_IGNORE_PREFIX = "ignore-prefix";
 
export interface Options {
  readonly ignorePrefix: string | string[] | undefined,
}
 
function parseOptions(options: any[]): Options { //tslint:disable-line
  let ignorePrefix: string | undefined;
  for (const o of options) {
    Eif (typeof o === "object" && o[OPTION_IGNORE_PREFIX] !== null) { //tslint:disable-line
      ignorePrefix = o[OPTION_IGNORE_PREFIX];
      break;
    }
  }
  return { ignorePrefix };
}
 
export class Rule extends Lint.Rules.AbstractRule {
  public static FAILURE_STRING = "Using expressions to cause side-effects not allowed.";
 
  public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
    const noExpressionStatementWalker = new NoExpressionStatementWalker(sourceFile, this.getOptions());
    return this.applyWithWalker(noExpressionStatementWalker);
  }
}
 
class NoExpressionStatementWalker extends Lint.RuleWalker {
 
  ignorePrefix: string | string[] | undefined;
 
  constructor(sourceFile: ts.SourceFile, options: Lint.IOptions) {
    super(sourceFile, options);
    Object.assign(this, parseOptions(options.ruleArguments));
  }
 
  public visitNode(node: ts.Node): void {
    if (node && node.kind === ts.SyntaxKind.ExpressionStatement) {
      const children = node.getChildren();
      const text = node.getText(this.getSourceFile());
      const isYield = children.every((n: ts.Node) => n.kind === ts.SyntaxKind.YieldExpression );
      const isIgnored = this.isIgnored(text);
      if (!isYield && !isIgnored) {
        this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING));
      }
    }
    super.visitNode(node);
  }
 
  private isIgnored(text: string): boolean {
    if (!this.ignorePrefix) {
      return false;
    }
    if (Array.isArray(this.ignorePrefix)) {
      if (this.ignorePrefix.find((pfx) => text.indexOf(pfx) === 0)) {
        return true;
      }
    } else {
      if (text.indexOf(this.ignorePrefix) === 0) {
        return true;
      }
    }
    return false;
  }
 
}