@@ -23,7 +23,7 @@ import { Rule } from "eslint";
2323import * as estree from "estree" ;
2424import { getParent , isIfStatement , isBlockStatement } from "../utils/nodes" ;
2525import { areEquivalent } from "../utils/equivalence" ;
26- import { collectIfBranches , takeWithoutBreak } from "../utils/conditions" ;
26+ import { collectIfBranches , takeWithoutBreak , collectSwitchBranches } from "../utils/conditions" ;
2727
2828const MESSAGE = "This {{type}}'s code block is the same as the block for the {{type}} on line {{line}}." ;
2929
@@ -41,7 +41,12 @@ const rule: Rule.RuleModule = {
4141 function visitIfStatement ( ifStmt : estree . IfStatement ) {
4242 const parent = getParent ( context ) ;
4343 if ( ! isIfStatement ( parent ) ) {
44- const { branches } = collectIfBranches ( ifStmt ) ;
44+ const { branches, endsWithElse } = collectIfBranches ( ifStmt ) ;
45+
46+ if ( allEquivalentWithoutDefault ( branches , endsWithElse ) ) {
47+ branches . slice ( 1 ) . forEach ( ( branch , i ) => reportIssue ( branch , branches [ i ] , "branch" ) ) ;
48+ return ;
49+ }
4550
4651 for ( let i = 1 ; i < branches . length ; i ++ ) {
4752 if ( hasRequiredSize ( [ branches [ i ] ] ) ) {
@@ -55,23 +60,27 @@ const rule: Rule.RuleModule = {
5560 }
5661 }
5762
58- function visitSwitchStatement ( { cases } : estree . SwitchStatement ) {
59- for ( let i = 1 ; i < cases . length ; i ++ ) {
60- const firstClauseWithoutBreak = takeWithoutBreak ( expandSingleBlockStatement ( cases [ i ] . consequent ) ) ;
63+ function visitSwitchStatement ( switchStmt : estree . SwitchStatement ) {
64+ const { cases } = switchStmt ;
65+ const { endsWithDefault } = collectSwitchBranches ( switchStmt ) ;
66+ const nonEmptyCases = cases
67+ . map ( c => takeWithoutBreak ( expandSingleBlockStatement ( c . consequent ) ) )
68+ . filter ( c => c . length > 0 ) ;
69+
70+ if ( allEquivalentWithoutDefault ( nonEmptyCases , endsWithDefault ) ) {
71+ cases . slice ( 1 ) . forEach ( ( caseStmt , i ) => reportIssue ( caseStmt , cases [ i ] , "case" ) ) ;
72+ return ;
73+ }
74+
75+ for ( let i = 1 ; i < nonEmptyCases . length ; i ++ ) {
76+ const firstClauseWithoutBreak = nonEmptyCases [ i ] ;
6177
6278 if ( hasRequiredSize ( firstClauseWithoutBreak ) ) {
6379 for ( let j = 0 ; j < i ; j ++ ) {
64- const secondClauseWithoutBreak = takeWithoutBreak ( expandSingleBlockStatement ( cases [ j ] . consequent ) ) ;
80+ const secondClauseWithoutBreak = nonEmptyCases [ j ] ;
6581
6682 if ( areEquivalent ( firstClauseWithoutBreak , secondClauseWithoutBreak , context . getSourceCode ( ) ) ) {
67- context . report ( {
68- message : MESSAGE ,
69- data : {
70- type : "case" ,
71- line : String ( cases [ j ] . loc ! . start . line ) ,
72- } ,
73- node : cases [ i ] ,
74- } ) ;
83+ reportIssue ( cases [ i ] , cases [ j ] , "case" ) ;
7584 break ;
7685 }
7786 }
@@ -93,14 +102,7 @@ const rule: Rule.RuleModule = {
93102 function compareIfBranches ( a : estree . Statement , b : estree . Statement ) {
94103 const equivalent = areEquivalent ( a , b , context . getSourceCode ( ) ) ;
95104 if ( equivalent && b . loc ) {
96- context . report ( {
97- message : MESSAGE ,
98- data : {
99- type : "branch" ,
100- line : String ( b . loc . start . line ) ,
101- } ,
102- node : a ,
103- } ) ;
105+ reportIssue ( a , b , "branch" ) ;
104106 }
105107 return equivalent ;
106108 }
@@ -114,6 +116,25 @@ const rule: Rule.RuleModule = {
114116 }
115117 return nodes ;
116118 }
119+
120+ function allEquivalentWithoutDefault ( branches : Array < estree . Node | estree . Node [ ] > , endsWithDefault : boolean ) {
121+ return (
122+ ! endsWithDefault &&
123+ branches . length > 1 &&
124+ branches . slice ( 1 ) . every ( ( branch , index ) => areEquivalent ( branch , branches [ index ] , context . getSourceCode ( ) ) )
125+ ) ;
126+ }
127+
128+ function reportIssue ( node : estree . Node , equivalentNode : estree . Node , type : string ) {
129+ context . report ( {
130+ message : MESSAGE ,
131+ data : {
132+ type,
133+ line : String ( equivalentNode . loc ! . start . line ) ,
134+ } ,
135+ node,
136+ } ) ;
137+ }
117138 } ,
118139} ;
119140
0 commit comments