11import * as ts from 'typescript' ;
22import * as Lint from 'tslint' ;
3- import * as utils from 'tsutils' ;
43import { AbstractIfStatementWalker } from '../src/walker' ;
54import { isElseIf } from '../src/utils' ;
5+ import { endsControlFlow } from 'tsutils' ;
66
77const FAIL_MESSAGE = `unnecessary else` ;
8- const FAIL_MESSAGE_BLOCK = `unnecessary else block` ;
98
109export class Rule extends Lint . Rules . AbstractRule {
1110 public apply ( sourceFile : ts . SourceFile ) : Lint . RuleFailure [ ] {
@@ -15,46 +14,8 @@ export class Rule extends Lint.Rules.AbstractRule {
1514
1615class IfWalker extends AbstractIfStatementWalker < void > {
1716 protected _checkIfStatement ( node : ts . IfStatement ) : void {
18- if ( isElseIf ( node ) )
19- return ;
20-
21- const elseStatement = node . elseStatement ;
22- if ( isElseStatement ( elseStatement ) && utils . endsControlFlow ( node . thenStatement ) ) {
23- if ( elseStatement !== undefined && utils . isBlock ( elseStatement ) && ! hasLocals ( elseStatement ) ) {
24- // remove else scope if safe: keep blocks where local variables change scope when unwrapped
25- const fixBlock = [
26- Lint . Replacement . deleteFromTo ( node . thenStatement . end , elseStatement . statements . pos ) , // removes `else {`
27- Lint . Replacement . deleteText ( elseStatement . end - 1 , 1 ) , // deletes ` }`
28- ] ;
29- this . addFailureAtNode ( node . getChildAt ( 5 /*else*/ , this . sourceFile ) , FAIL_MESSAGE_BLOCK , fixBlock ) ;
30- } else {
31- // remove else only
32- const fixElse = Lint . Replacement . deleteFromTo ( node . thenStatement . getEnd ( ) , elseStatement . getStart ( ) ) ;
33- this . addFailureAtNode ( node . getChildAt ( 5 /*else*/ , this . sourceFile ) , FAIL_MESSAGE , fixElse ) ;
34- }
35- }
36- }
37- }
38-
39- function isElseStatement ( node : ts . Statement | undefined ) : node is ts . Statement {
40- return node !== undefined ;
41- }
42-
43- function hasLocals ( node : ts . Block ) : boolean {
44- for ( const statement of node . statements ) {
45- switch ( statement . kind ) {
46- case ts . SyntaxKind . VariableStatement :
47- if ( utils . isBlockScopedVariableDeclarationList ( ( < ts . VariableStatement > statement ) . declarationList ) )
48- return true ;
49- break ;
50-
51- case ts . SyntaxKind . ClassDeclaration :
52- case ts . SyntaxKind . EnumDeclaration :
53- case ts . SyntaxKind . InterfaceDeclaration :
54- case ts . SyntaxKind . TypeAliasDeclaration :
55- return true ;
56- }
17+ const { elseStatement} = node ;
18+ if ( elseStatement !== undefined && ! isElseIf ( node ) && endsControlFlow ( node . thenStatement ) )
19+ this . _reportUnnecessaryElse ( elseStatement , FAIL_MESSAGE ) ;
5720 }
58-
59- return false ;
6021}
0 commit comments