1
- import { TSESTree , AST_NODE_TYPES } from '@typescript-eslint/typescript-estree' ;
1
+ import { AST_NODE_TYPES , TSESTree } from '@typescript-eslint/typescript-estree' ;
2
2
import baseRule from 'eslint/lib/rules/no-extra-parens' ;
3
3
import * as util from '../util' ;
4
4
@@ -22,10 +22,204 @@ export default util.createRule<Options, MessageIds>({
22
22
create ( context ) {
23
23
const rules = baseRule . create ( context ) ;
24
24
25
+ function binaryExp (
26
+ node : TSESTree . BinaryExpression | TSESTree . LogicalExpression ,
27
+ ) {
28
+ const rule = rules . BinaryExpression as ( n : typeof node ) => void ;
29
+
30
+ // makes the rule think it should skip the left or right
31
+ if ( node . left . type === AST_NODE_TYPES . TSAsExpression ) {
32
+ return rule ( {
33
+ ...node ,
34
+ left : {
35
+ ...node . left ,
36
+ type : AST_NODE_TYPES . BinaryExpression as any ,
37
+ } ,
38
+ } ) ;
39
+ }
40
+ if ( node . right . type === AST_NODE_TYPES . TSAsExpression ) {
41
+ return rule ( {
42
+ ...node ,
43
+ right : {
44
+ ...node . right ,
45
+ type : AST_NODE_TYPES . BinaryExpression as any ,
46
+ } ,
47
+ } ) ;
48
+ }
49
+
50
+ return rule ( node ) ;
51
+ }
52
+ function callExp ( node : TSESTree . CallExpression | TSESTree . NewExpression ) {
53
+ const rule = rules . CallExpression as ( n : typeof node ) => void ;
54
+
55
+ if ( node . callee . type === AST_NODE_TYPES . TSAsExpression ) {
56
+ // reduces the precedence of the node so the rule thinks it needs to be wrapped
57
+ return rule ( {
58
+ ...node ,
59
+ callee : {
60
+ ...node . callee ,
61
+ type : AST_NODE_TYPES . SequenceExpression as any ,
62
+ } ,
63
+ } ) ;
64
+ }
65
+
66
+ return rule ( node ) ;
67
+ }
68
+ function unaryUpdateExpression (
69
+ node : TSESTree . UnaryExpression | TSESTree . UpdateExpression ,
70
+ ) {
71
+ const rule = rules . UnaryExpression as ( n : typeof node ) => void ;
72
+
73
+ if ( node . argument . type === AST_NODE_TYPES . TSAsExpression ) {
74
+ // reduces the precedence of the node so the rule thinks it needs to be wrapped
75
+ return rule ( {
76
+ ...node ,
77
+ argument : {
78
+ ...node . argument ,
79
+ type : AST_NODE_TYPES . SequenceExpression as any ,
80
+ } ,
81
+ } ) ;
82
+ }
83
+
84
+ return rule ( node ) ;
85
+ }
86
+
25
87
return Object . assign ( { } , rules , {
26
- MemberExpression ( node : TSESTree . MemberExpression ) {
27
- if ( node . object . type !== AST_NODE_TYPES . TSAsExpression ) {
28
- return rules . MemberExpression ( node ) ;
88
+ // ArrayExpression
89
+ ArrowFunctionExpression ( node ) {
90
+ if ( node . body . type !== AST_NODE_TYPES . TSAsExpression ) {
91
+ return rules . ArrowFunctionExpression ( node ) ;
92
+ }
93
+ } ,
94
+ // AssignmentExpression
95
+ // AwaitExpression
96
+ BinaryExpression : binaryExp ,
97
+ CallExpression : callExp ,
98
+ // ClassDeclaration
99
+ // ClassExpression
100
+ ConditionalExpression ( node ) {
101
+ // reduces the precedence of the node so the rule thinks it needs to be wrapped
102
+ if ( node . test . type === AST_NODE_TYPES . TSAsExpression ) {
103
+ return rules . ConditionalExpression ( {
104
+ ...node ,
105
+ test : {
106
+ ...node . test ,
107
+ type : AST_NODE_TYPES . SequenceExpression as any ,
108
+ } ,
109
+ } ) ;
110
+ }
111
+ if ( node . consequent . type === AST_NODE_TYPES . TSAsExpression ) {
112
+ return rules . ConditionalExpression ( {
113
+ ...node ,
114
+ consequent : {
115
+ ...node . consequent ,
116
+ type : AST_NODE_TYPES . SequenceExpression as any ,
117
+ } ,
118
+ } ) ;
119
+ }
120
+ if ( node . alternate . type === AST_NODE_TYPES . TSAsExpression ) {
121
+ // reduces the precedence of the node so the rule thinks it needs to be rapped
122
+ return rules . ConditionalExpression ( {
123
+ ...node ,
124
+ alternate : {
125
+ ...node . alternate ,
126
+ type : AST_NODE_TYPES . SequenceExpression as any ,
127
+ } ,
128
+ } ) ;
129
+ }
130
+ return rules . ConditionalExpression ( node ) ;
131
+ } ,
132
+ // DoWhileStatement
133
+ 'ForInStatement, ForOfStatement' (
134
+ node : TSESTree . ForInStatement | TSESTree . ForOfStatement ,
135
+ ) {
136
+ if ( node . right . type === AST_NODE_TYPES . TSAsExpression ) {
137
+ // makes the rule skip checking of the right
138
+ return rules [ 'ForInStatement, ForOfStatement' ] ( {
139
+ ...node ,
140
+ type : AST_NODE_TYPES . ForOfStatement as any ,
141
+ right : {
142
+ ...node . right ,
143
+ type : AST_NODE_TYPES . SequenceExpression as any ,
144
+ } ,
145
+ } ) ;
146
+ }
147
+
148
+ return rules [ 'ForInStatement, ForOfStatement' ] ( node ) ;
149
+ } ,
150
+ ForStatement ( node ) {
151
+ // make the rule skip the piece by removing it entirely
152
+ if ( node . init && node . init . type === AST_NODE_TYPES . TSAsExpression ) {
153
+ return rules . ForStatement ( {
154
+ ...node ,
155
+ init : null ,
156
+ } ) ;
157
+ }
158
+ if ( node . test && node . test . type === AST_NODE_TYPES . TSAsExpression ) {
159
+ return rules . ForStatement ( {
160
+ ...node ,
161
+ test : null ,
162
+ } ) ;
163
+ }
164
+ if ( node . update && node . update . type === AST_NODE_TYPES . TSAsExpression ) {
165
+ return rules . ForStatement ( {
166
+ ...node ,
167
+ update : null ,
168
+ } ) ;
169
+ }
170
+
171
+ return rules . ForStatement ( node ) ;
172
+ } ,
173
+ // IfStatement
174
+ LogicalExpression : binaryExp ,
175
+ MemberExpression ( node ) {
176
+ if ( node . object . type === AST_NODE_TYPES . TSAsExpression ) {
177
+ // reduces the precedence of the node so the rule thinks it needs to be wrapped
178
+ return rules . MemberExpression ( {
179
+ ...node ,
180
+ object : {
181
+ ...node . object ,
182
+ type : AST_NODE_TYPES . SequenceExpression as any ,
183
+ } ,
184
+ } ) ;
185
+ }
186
+
187
+ return rules . MemberExpression ( node ) ;
188
+ } ,
189
+ NewExpression : callExp ,
190
+ // ObjectExpression
191
+ // ReturnStatement
192
+ // SequenceExpression
193
+ SpreadElement ( node ) {
194
+ if ( node . argument . type !== AST_NODE_TYPES . TSAsExpression ) {
195
+ return rules . SpreadElement ( node ) ;
196
+ }
197
+ } ,
198
+ SwitchCase ( node ) {
199
+ if ( node . test . type !== AST_NODE_TYPES . TSAsExpression ) {
200
+ return rules . SwitchCase ( node ) ;
201
+ }
202
+ } ,
203
+ // SwitchStatement
204
+ ThrowStatement ( node ) {
205
+ if (
206
+ node . argument &&
207
+ node . argument . type !== AST_NODE_TYPES . TSAsExpression
208
+ ) {
209
+ return rules . ThrowStatement ( node ) ;
210
+ }
211
+ } ,
212
+ UnaryExpression : unaryUpdateExpression ,
213
+ UpdateExpression : unaryUpdateExpression ,
214
+ // VariableDeclarator
215
+ // WhileStatement
216
+ // WithStatement - i'm not going to even bother implementing this terrible and never used feature
217
+ YieldExpression ( node ) {
218
+ if (
219
+ node . argument &&
220
+ node . argument . type !== AST_NODE_TYPES . TSAsExpression
221
+ ) {
222
+ return rules . YieldExpression ( node ) ;
29
223
}
30
224
} ,
31
225
} ) ;
0 commit comments