/**
 * This file has functions that enable walking the nodes
 * and just providing a CheckNodeFunction that returns invalid
 * nodes. It enables a more functional style of programming rules
 * using the CheckNodeFunction as an expression that returns errors.
 */ import * as ts from "typescript" ; import * as Lint from "tslint" ; import { parseOptions as defaultParseOptions } from "./options" ; export interface CheckNodeFunction < TOptions > { ( node , ctx ) : CheckNodeResult ; } export interface CheckTypedNodeFunction < TOptions > { ( node , ctx , checker ) : CheckNodeResult ; } export interface InvalidNode { readonly node : ts . Node ; readonly replacements : Array < Lint . Replacement > ; } export function createInvalidNode ( node , replacements ) { return { node , replacements } ; } export interface CheckNodeResult { invalidNodes : ReadonlyArray < InvalidNode > ; skipChildren ? : boolean ; } export function walk < TOptions > ( ctx , checkNode , failureString ) { return ts . forEachChild ( ctx . sourceFile , cb ) ; function cb ( node ) { const { invalidNodes , skipChildren } = checkNode ( node , ctx ) ; reportInvalidNodes ( invalidNodes , ctx , failureString ) ; if ( skipChildren ) { return ; } return ts . forEachChild ( node , cb ) ; } } export function walkTyped < TOptions > ( ctx , checkTypedNode , checker , failureString ) { return ts . forEachChild ( ctx . sourceFile , cb ) ; function cb ( node ) { const { invalidNodes , skipChildren } = checkTypedNode ( node , ctx , checker ) ; reportInvalidNodes ( invalidNodes , ctx , failureString ) ; if ( skipChildren ) { return ; } return ts . forEachChild ( node , cb ) ; } } export function createCheckNodeRule < TOptions > ( checkNode , failureString , parseOptions = defaultParseOptions ) { return class Rule extends Lint . Rules . AbstractRule { public apply ( sourceFile ) { return this . applyWithFunction ( sourceFile , ( ctx ) => walk ( ctx , checkNode , failureString ) , parseOptions ( this . ruleArguments ) ) ; } } ; } export function createCheckNodeTypedRule < TOptions > ( checkTypedNode , failureString , parseOptions = defaultParseOptions ) { return class Rule extends Lint . Rules . TypedRule { public applyWithProgram ( sourceFile , program ) { return this . applyWithFunction ( sourceFile , ( ctx , checker ) => walkTyped ( ctx , checkTypedNode , checker , failureString ) , parseOptions ( this . ruleArguments ) , program . getTypeChecker ( ) ) ; } } ; } function reportInvalidNodes < TOptions > ( invalidNodes , ctx , failureString ) { invalidNodes . forEach ( invalidNode => ctx . addFailureAtNode ( invalidNode . node , failureString , invalidNode . replacements ) ) ; }