@ttsc/lint 0.7.2 → 0.8.0-dev.20260505

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,73 +9,73 @@ type noExtraBooleanCast struct{}
9
9
 
10
10
  func (noExtraBooleanCast) Name() string { return "no-extra-boolean-cast" }
11
11
  func (noExtraBooleanCast) Visits() []shimast.Kind {
12
- return []shimast.Kind{shimast.KindCallExpression, shimast.KindPrefixUnaryExpression}
12
+ return []shimast.Kind{shimast.KindCallExpression, shimast.KindPrefixUnaryExpression}
13
13
  }
14
14
  func (noExtraBooleanCast) Check(ctx *Context, node *shimast.Node) {
15
- switch node.Kind {
16
- case shimast.KindCallExpression:
17
- call := node.AsCallExpression()
18
- if call == nil {
19
- return
20
- }
21
- if identifierText(call.Expression) != "Boolean" {
22
- return
23
- }
24
- if isInBooleanContext(node) {
25
- ctx.Report(node, "Redundant Boolean call.")
26
- }
27
- case shimast.KindPrefixUnaryExpression:
28
- outer := node.AsPrefixUnaryExpression()
29
- if outer == nil || outer.Operator != shimast.KindExclamationToken {
30
- return
31
- }
32
- operand := outer.Operand
33
- if operand == nil || operand.Kind != shimast.KindPrefixUnaryExpression {
34
- return
35
- }
36
- inner := operand.AsPrefixUnaryExpression()
37
- if inner == nil || inner.Operator != shimast.KindExclamationToken {
38
- return
39
- }
40
- if isInBooleanContext(node) {
41
- ctx.Report(node, "Redundant double negation.")
42
- }
43
- }
15
+ switch node.Kind {
16
+ case shimast.KindCallExpression:
17
+ call := node.AsCallExpression()
18
+ if call == nil {
19
+ return
20
+ }
21
+ if identifierText(call.Expression) != "Boolean" {
22
+ return
23
+ }
24
+ if isInBooleanContext(node) {
25
+ ctx.Report(node, "Redundant Boolean call.")
26
+ }
27
+ case shimast.KindPrefixUnaryExpression:
28
+ outer := node.AsPrefixUnaryExpression()
29
+ if outer == nil || outer.Operator != shimast.KindExclamationToken {
30
+ return
31
+ }
32
+ operand := outer.Operand
33
+ if operand == nil || operand.Kind != shimast.KindPrefixUnaryExpression {
34
+ return
35
+ }
36
+ inner := operand.AsPrefixUnaryExpression()
37
+ if inner == nil || inner.Operator != shimast.KindExclamationToken {
38
+ return
39
+ }
40
+ if isInBooleanContext(node) {
41
+ ctx.Report(node, "Redundant double negation.")
42
+ }
43
+ }
44
44
  }
45
45
 
46
46
  // isInBooleanContext walks up the parent chain to determine whether the
47
47
  // expression's value is consumed as a boolean (test of an if/while/for/
48
48
  // ternary, or operand of `!`).
49
49
  func isInBooleanContext(node *shimast.Node) bool {
50
- parent := node.Parent
51
- for parent != nil && parent.Kind == shimast.KindParenthesizedExpression {
52
- parent = parent.Parent
53
- }
54
- if parent == nil {
55
- return false
56
- }
57
- switch parent.Kind {
58
- case shimast.KindIfStatement:
59
- return parent.AsIfStatement().Expression == skipParents(node)
60
- case shimast.KindWhileStatement:
61
- return parent.AsWhileStatement().Expression == skipParents(node)
62
- case shimast.KindDoStatement:
63
- return parent.AsDoStatement().Expression == skipParents(node)
64
- case shimast.KindForStatement:
65
- return parent.AsForStatement().Condition == skipParents(node)
66
- case shimast.KindConditionalExpression:
67
- return parent.AsConditionalExpression().Condition == skipParents(node)
68
- case shimast.KindPrefixUnaryExpression:
69
- return parent.AsPrefixUnaryExpression().Operator == shimast.KindExclamationToken
70
- }
71
- return false
50
+ parent := node.Parent
51
+ for parent != nil && parent.Kind == shimast.KindParenthesizedExpression {
52
+ parent = parent.Parent
53
+ }
54
+ if parent == nil {
55
+ return false
56
+ }
57
+ switch parent.Kind {
58
+ case shimast.KindIfStatement:
59
+ return parent.AsIfStatement().Expression == skipParents(node)
60
+ case shimast.KindWhileStatement:
61
+ return parent.AsWhileStatement().Expression == skipParents(node)
62
+ case shimast.KindDoStatement:
63
+ return parent.AsDoStatement().Expression == skipParents(node)
64
+ case shimast.KindForStatement:
65
+ return parent.AsForStatement().Condition == skipParents(node)
66
+ case shimast.KindConditionalExpression:
67
+ return parent.AsConditionalExpression().Condition == skipParents(node)
68
+ case shimast.KindPrefixUnaryExpression:
69
+ return parent.AsPrefixUnaryExpression().Operator == shimast.KindExclamationToken
70
+ }
71
+ return false
72
72
  }
73
73
 
74
74
  func skipParents(node *shimast.Node) *shimast.Node {
75
- for node != nil && node.Parent != nil && node.Parent.Kind == shimast.KindParenthesizedExpression {
76
- node = node.Parent
77
- }
78
- return node
75
+ for node != nil && node.Parent != nil && node.Parent.Kind == shimast.KindParenthesizedExpression {
76
+ node = node.Parent
77
+ }
78
+ return node
79
79
  }
80
80
 
81
81
  // no-unsafe-negation: `!a in b` and `!a instanceof b` — the parser
@@ -86,23 +86,23 @@ type noUnsafeNegation struct{}
86
86
  func (noUnsafeNegation) Name() string { return "no-unsafe-negation" }
87
87
  func (noUnsafeNegation) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBinaryExpression} }
88
88
  func (noUnsafeNegation) Check(ctx *Context, node *shimast.Node) {
89
- expr := node.AsBinaryExpression()
90
- if expr == nil || expr.OperatorToken == nil {
91
- return
92
- }
93
- switch expr.OperatorToken.Kind {
94
- case shimast.KindInKeyword, shimast.KindInstanceOfKeyword:
95
- default:
96
- return
97
- }
98
- if expr.Left == nil || expr.Left.Kind != shimast.KindPrefixUnaryExpression {
99
- return
100
- }
101
- prefix := expr.Left.AsPrefixUnaryExpression()
102
- if prefix == nil || prefix.Operator != shimast.KindExclamationToken {
103
- return
104
- }
105
- ctx.Report(node, "Unexpected negating the left operand of a relational operator.")
89
+ expr := node.AsBinaryExpression()
90
+ if expr == nil || expr.OperatorToken == nil {
91
+ return
92
+ }
93
+ switch expr.OperatorToken.Kind {
94
+ case shimast.KindInKeyword, shimast.KindInstanceOfKeyword:
95
+ default:
96
+ return
97
+ }
98
+ if expr.Left == nil || expr.Left.Kind != shimast.KindPrefixUnaryExpression {
99
+ return
100
+ }
101
+ prefix := expr.Left.AsPrefixUnaryExpression()
102
+ if prefix == nil || prefix.Operator != shimast.KindExclamationToken {
103
+ return
104
+ }
105
+ ctx.Report(node, "Unexpected negating the left operand of a relational operator.")
106
106
  }
107
107
 
108
108
  // eqeqeq: enforce `===` / `!==`. Default mode matches ESLint's `always`
@@ -113,16 +113,16 @@ type eqeqeq struct{}
113
113
  func (eqeqeq) Name() string { return "eqeqeq" }
114
114
  func (eqeqeq) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBinaryExpression} }
115
115
  func (eqeqeq) Check(ctx *Context, node *shimast.Node) {
116
- expr := node.AsBinaryExpression()
117
- if expr == nil || expr.OperatorToken == nil {
118
- return
119
- }
120
- switch expr.OperatorToken.Kind {
121
- case shimast.KindEqualsEqualsToken:
122
- ctx.ReportRange(expr.OperatorToken.Pos(), expr.OperatorToken.End(), "Expected '===' and instead saw '=='.")
123
- case shimast.KindExclamationEqualsToken:
124
- ctx.ReportRange(expr.OperatorToken.Pos(), expr.OperatorToken.End(), "Expected '!==' and instead saw '!='.")
125
- }
116
+ expr := node.AsBinaryExpression()
117
+ if expr == nil || expr.OperatorToken == nil {
118
+ return
119
+ }
120
+ switch expr.OperatorToken.Kind {
121
+ case shimast.KindEqualsEqualsToken:
122
+ ctx.ReportRange(expr.OperatorToken.Pos(), expr.OperatorToken.End(), "Expected '===' and instead saw '=='.")
123
+ case shimast.KindExclamationEqualsToken:
124
+ ctx.ReportRange(expr.OperatorToken.Pos(), expr.OperatorToken.End(), "Expected '!==' and instead saw '!='.")
125
+ }
126
126
  }
127
127
 
128
128
  // use-isnan: `x === NaN` is always false. Use `Number.isNaN(x)`.
@@ -132,16 +132,16 @@ type useIsnan struct{}
132
132
  func (useIsnan) Name() string { return "use-isnan" }
133
133
  func (useIsnan) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBinaryExpression} }
134
134
  func (useIsnan) Check(ctx *Context, node *shimast.Node) {
135
- expr := node.AsBinaryExpression()
136
- if expr == nil || expr.OperatorToken == nil {
137
- return
138
- }
139
- if !isComparisonOperator(expr.OperatorToken.Kind) {
140
- return
141
- }
142
- if identifierText(expr.Left) == "NaN" || identifierText(expr.Right) == "NaN" {
143
- ctx.Report(node, "Use the isNaN function to compare with NaN.")
144
- }
135
+ expr := node.AsBinaryExpression()
136
+ if expr == nil || expr.OperatorToken == nil {
137
+ return
138
+ }
139
+ if !isComparisonOperator(expr.OperatorToken.Kind) {
140
+ return
141
+ }
142
+ if identifierText(expr.Left) == "NaN" || identifierText(expr.Right) == "NaN" {
143
+ ctx.Report(node, "Use the isNaN function to compare with NaN.")
144
+ }
145
145
  }
146
146
 
147
147
  // valid-typeof: typeof expressions can only be compared to known type
@@ -152,41 +152,41 @@ type validTypeof struct{}
152
152
  func (validTypeof) Name() string { return "valid-typeof" }
153
153
  func (validTypeof) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBinaryExpression} }
154
154
  func (validTypeof) Check(ctx *Context, node *shimast.Node) {
155
- expr := node.AsBinaryExpression()
156
- if expr == nil || expr.OperatorToken == nil {
157
- return
158
- }
159
- if !isComparisonOperator(expr.OperatorToken.Kind) {
160
- return
161
- }
162
- left := stripParens(expr.Left)
163
- right := stripParens(expr.Right)
164
- var literal *shimast.Node
165
- if left != nil && left.Kind == shimast.KindTypeOfExpression {
166
- literal = right
167
- } else if right != nil && right.Kind == shimast.KindTypeOfExpression {
168
- literal = left
169
- } else {
170
- return
171
- }
172
- if literal == nil {
173
- return
174
- }
175
- value := stringLiteralText(literal)
176
- if value == "" {
177
- return
178
- }
179
- if !isValidTypeofString(value) {
180
- ctx.Report(literal, "Invalid typeof comparison value.")
181
- }
155
+ expr := node.AsBinaryExpression()
156
+ if expr == nil || expr.OperatorToken == nil {
157
+ return
158
+ }
159
+ if !isComparisonOperator(expr.OperatorToken.Kind) {
160
+ return
161
+ }
162
+ left := stripParens(expr.Left)
163
+ right := stripParens(expr.Right)
164
+ var literal *shimast.Node
165
+ if left != nil && left.Kind == shimast.KindTypeOfExpression {
166
+ literal = right
167
+ } else if right != nil && right.Kind == shimast.KindTypeOfExpression {
168
+ literal = left
169
+ } else {
170
+ return
171
+ }
172
+ if literal == nil {
173
+ return
174
+ }
175
+ value := stringLiteralText(literal)
176
+ if value == "" {
177
+ return
178
+ }
179
+ if !isValidTypeofString(value) {
180
+ ctx.Report(literal, "Invalid typeof comparison value.")
181
+ }
182
182
  }
183
183
 
184
184
  func isValidTypeofString(value string) bool {
185
- switch value {
186
- case "undefined", "object", "boolean", "number", "string", "function", "symbol", "bigint":
187
- return true
188
- }
189
- return false
185
+ switch value {
186
+ case "undefined", "object", "boolean", "number", "string", "function", "symbol", "bigint":
187
+ return true
188
+ }
189
+ return false
190
190
  }
191
191
 
192
192
  // no-compare-neg-zero: `x === -0`. Comparison ignores the sign — use
@@ -197,27 +197,27 @@ type noCompareNegZero struct{}
197
197
  func (noCompareNegZero) Name() string { return "no-compare-neg-zero" }
198
198
  func (noCompareNegZero) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBinaryExpression} }
199
199
  func (noCompareNegZero) Check(ctx *Context, node *shimast.Node) {
200
- expr := node.AsBinaryExpression()
201
- if expr == nil || expr.OperatorToken == nil {
202
- return
203
- }
204
- if !isComparisonOperator(expr.OperatorToken.Kind) {
205
- return
206
- }
207
- if isNegZero(expr.Left) || isNegZero(expr.Right) {
208
- ctx.Report(node, "Do not use the '-0' literal in comparisons.")
209
- }
200
+ expr := node.AsBinaryExpression()
201
+ if expr == nil || expr.OperatorToken == nil {
202
+ return
203
+ }
204
+ if !isComparisonOperator(expr.OperatorToken.Kind) {
205
+ return
206
+ }
207
+ if isNegZero(expr.Left) || isNegZero(expr.Right) {
208
+ ctx.Report(node, "Do not use the '-0' literal in comparisons.")
209
+ }
210
210
  }
211
211
 
212
212
  func isNegZero(node *shimast.Node) bool {
213
- if node == nil || node.Kind != shimast.KindPrefixUnaryExpression {
214
- return false
215
- }
216
- prefix := node.AsPrefixUnaryExpression()
217
- if prefix == nil || prefix.Operator != shimast.KindMinusToken || prefix.Operand == nil {
218
- return false
219
- }
220
- return numericLiteralText(prefix.Operand) == "0"
213
+ if node == nil || node.Kind != shimast.KindPrefixUnaryExpression {
214
+ return false
215
+ }
216
+ prefix := node.AsPrefixUnaryExpression()
217
+ if prefix == nil || prefix.Operator != shimast.KindMinusToken || prefix.Operand == nil {
218
+ return false
219
+ }
220
+ return numericLiteralText(prefix.Operand) == "0"
221
221
  }
222
222
 
223
223
  // no-cond-assign: `if (a = b)` is almost always a typo for `if (a == b)`.
@@ -228,72 +228,72 @@ type noCondAssign struct{}
228
228
 
229
229
  func (noCondAssign) Name() string { return "no-cond-assign" }
230
230
  func (noCondAssign) Visits() []shimast.Kind {
231
- return []shimast.Kind{
232
- shimast.KindIfStatement,
233
- shimast.KindWhileStatement,
234
- shimast.KindDoStatement,
235
- shimast.KindForStatement,
236
- shimast.KindConditionalExpression,
237
- }
231
+ return []shimast.Kind{
232
+ shimast.KindIfStatement,
233
+ shimast.KindWhileStatement,
234
+ shimast.KindDoStatement,
235
+ shimast.KindForStatement,
236
+ shimast.KindConditionalExpression,
237
+ }
238
238
  }
239
239
  func (noCondAssign) Check(ctx *Context, node *shimast.Node) {
240
- var test *shimast.Node
241
- switch node.Kind {
242
- case shimast.KindIfStatement:
243
- test = node.AsIfStatement().Expression
244
- case shimast.KindWhileStatement:
245
- test = node.AsWhileStatement().Expression
246
- case shimast.KindDoStatement:
247
- test = node.AsDoStatement().Expression
248
- case shimast.KindForStatement:
249
- test = node.AsForStatement().Condition
250
- case shimast.KindConditionalExpression:
251
- test = node.AsConditionalExpression().Condition
252
- }
253
- if test == nil {
254
- return
255
- }
256
- // `except-parens`: an explicitly parenthesized assignment is OK.
257
- if test.Kind == shimast.KindParenthesizedExpression {
258
- return
259
- }
260
- if isAssignmentExpression(test) {
261
- ctx.Report(test, "Expected a conditional expression and instead saw an assignment.")
262
- }
240
+ var test *shimast.Node
241
+ switch node.Kind {
242
+ case shimast.KindIfStatement:
243
+ test = node.AsIfStatement().Expression
244
+ case shimast.KindWhileStatement:
245
+ test = node.AsWhileStatement().Expression
246
+ case shimast.KindDoStatement:
247
+ test = node.AsDoStatement().Expression
248
+ case shimast.KindForStatement:
249
+ test = node.AsForStatement().Condition
250
+ case shimast.KindConditionalExpression:
251
+ test = node.AsConditionalExpression().Condition
252
+ }
253
+ if test == nil {
254
+ return
255
+ }
256
+ // `except-parens`: an explicitly parenthesized assignment is OK.
257
+ if test.Kind == shimast.KindParenthesizedExpression {
258
+ return
259
+ }
260
+ if isAssignmentExpression(test) {
261
+ ctx.Report(test, "Expected a conditional expression and instead saw an assignment.")
262
+ }
263
263
  }
264
264
 
265
265
  func isAssignmentExpression(node *shimast.Node) bool {
266
- if node == nil || node.Kind != shimast.KindBinaryExpression {
267
- return false
268
- }
269
- expr := node.AsBinaryExpression()
270
- if expr == nil || expr.OperatorToken == nil {
271
- return false
272
- }
273
- return isAssignmentOperator(expr.OperatorToken.Kind)
266
+ if node == nil || node.Kind != shimast.KindBinaryExpression {
267
+ return false
268
+ }
269
+ expr := node.AsBinaryExpression()
270
+ if expr == nil || expr.OperatorToken == nil {
271
+ return false
272
+ }
273
+ return isAssignmentOperator(expr.OperatorToken.Kind)
274
274
  }
275
275
 
276
276
  func isAssignmentOperator(kind shimast.Kind) bool {
277
- switch kind {
278
- case shimast.KindEqualsToken,
279
- shimast.KindPlusEqualsToken,
280
- shimast.KindMinusEqualsToken,
281
- shimast.KindAsteriskEqualsToken,
282
- shimast.KindAsteriskAsteriskEqualsToken,
283
- shimast.KindSlashEqualsToken,
284
- shimast.KindPercentEqualsToken,
285
- shimast.KindLessThanLessThanEqualsToken,
286
- shimast.KindGreaterThanGreaterThanEqualsToken,
287
- shimast.KindGreaterThanGreaterThanGreaterThanEqualsToken,
288
- shimast.KindAmpersandEqualsToken,
289
- shimast.KindBarEqualsToken,
290
- shimast.KindCaretEqualsToken,
291
- shimast.KindAmpersandAmpersandEqualsToken,
292
- shimast.KindBarBarEqualsToken,
293
- shimast.KindQuestionQuestionEqualsToken:
294
- return true
295
- }
296
- return false
277
+ switch kind {
278
+ case shimast.KindEqualsToken,
279
+ shimast.KindPlusEqualsToken,
280
+ shimast.KindMinusEqualsToken,
281
+ shimast.KindAsteriskEqualsToken,
282
+ shimast.KindAsteriskAsteriskEqualsToken,
283
+ shimast.KindSlashEqualsToken,
284
+ shimast.KindPercentEqualsToken,
285
+ shimast.KindLessThanLessThanEqualsToken,
286
+ shimast.KindGreaterThanGreaterThanEqualsToken,
287
+ shimast.KindGreaterThanGreaterThanGreaterThanEqualsToken,
288
+ shimast.KindAmpersandEqualsToken,
289
+ shimast.KindBarEqualsToken,
290
+ shimast.KindCaretEqualsToken,
291
+ shimast.KindAmpersandAmpersandEqualsToken,
292
+ shimast.KindBarBarEqualsToken,
293
+ shimast.KindQuestionQuestionEqualsToken:
294
+ return true
295
+ }
296
+ return false
297
297
  }
298
298
 
299
299
  // no-constant-condition: `if (true)`, `while (1)`, `if (literal)`. Often
@@ -303,79 +303,79 @@ type noConstantCondition struct{}
303
303
 
304
304
  func (noConstantCondition) Name() string { return "no-constant-condition" }
305
305
  func (noConstantCondition) Visits() []shimast.Kind {
306
- return []shimast.Kind{
307
- shimast.KindIfStatement,
308
- shimast.KindWhileStatement,
309
- shimast.KindDoStatement,
310
- shimast.KindForStatement,
311
- shimast.KindConditionalExpression,
312
- }
306
+ return []shimast.Kind{
307
+ shimast.KindIfStatement,
308
+ shimast.KindWhileStatement,
309
+ shimast.KindDoStatement,
310
+ shimast.KindForStatement,
311
+ shimast.KindConditionalExpression,
312
+ }
313
313
  }
314
314
  func (noConstantCondition) Check(ctx *Context, node *shimast.Node) {
315
- var test *shimast.Node
316
- switch node.Kind {
317
- case shimast.KindIfStatement:
318
- test = node.AsIfStatement().Expression
319
- case shimast.KindWhileStatement:
320
- test = node.AsWhileStatement().Expression
321
- case shimast.KindDoStatement:
322
- test = node.AsDoStatement().Expression
323
- case shimast.KindForStatement:
324
- test = node.AsForStatement().Condition
325
- case shimast.KindConditionalExpression:
326
- test = node.AsConditionalExpression().Condition
327
- }
328
- test = stripParens(test)
329
- if test == nil {
330
- return // covers `for (;;)` — omitted condition is idiomatic.
331
- }
332
- // Allow `while (true)` since it's a common deliberate idiom.
333
- if node.Kind == shimast.KindWhileStatement {
334
- if v, ok := isLiteralBoolean(test); ok && v {
335
- return
336
- }
337
- }
338
- if isConstantTruthyOrFalsy(test) {
339
- ctx.Report(test, "Unexpected constant condition.")
340
- }
315
+ var test *shimast.Node
316
+ switch node.Kind {
317
+ case shimast.KindIfStatement:
318
+ test = node.AsIfStatement().Expression
319
+ case shimast.KindWhileStatement:
320
+ test = node.AsWhileStatement().Expression
321
+ case shimast.KindDoStatement:
322
+ test = node.AsDoStatement().Expression
323
+ case shimast.KindForStatement:
324
+ test = node.AsForStatement().Condition
325
+ case shimast.KindConditionalExpression:
326
+ test = node.AsConditionalExpression().Condition
327
+ }
328
+ test = stripParens(test)
329
+ if test == nil {
330
+ return // covers `for (;;)` — omitted condition is idiomatic.
331
+ }
332
+ // Allow `while (true)` since it's a common deliberate idiom.
333
+ if node.Kind == shimast.KindWhileStatement {
334
+ if v, ok := isLiteralBoolean(test); ok && v {
335
+ return
336
+ }
337
+ }
338
+ if isConstantTruthyOrFalsy(test) {
339
+ ctx.Report(test, "Unexpected constant condition.")
340
+ }
341
341
  }
342
342
 
343
343
  func isConstantTruthyOrFalsy(node *shimast.Node) bool {
344
- if node == nil {
345
- return false
346
- }
347
- switch node.Kind {
348
- case
349
- shimast.KindNumericLiteral,
350
- shimast.KindBigIntLiteral,
351
- shimast.KindStringLiteral,
352
- shimast.KindNoSubstitutionTemplateLiteral,
353
- shimast.KindRegularExpressionLiteral,
354
- shimast.KindTrueKeyword,
355
- shimast.KindFalseKeyword,
356
- shimast.KindNullKeyword,
357
- shimast.KindArrayLiteralExpression,
358
- shimast.KindObjectLiteralExpression,
359
- shimast.KindArrowFunction,
360
- shimast.KindFunctionExpression:
361
- return true
362
- case shimast.KindPrefixUnaryExpression:
363
- prefix := node.AsPrefixUnaryExpression()
364
- if prefix == nil {
365
- return false
366
- }
367
- return isConstantTruthyOrFalsy(prefix.Operand)
368
- }
369
- return false
344
+ if node == nil {
345
+ return false
346
+ }
347
+ switch node.Kind {
348
+ case
349
+ shimast.KindNumericLiteral,
350
+ shimast.KindBigIntLiteral,
351
+ shimast.KindStringLiteral,
352
+ shimast.KindNoSubstitutionTemplateLiteral,
353
+ shimast.KindRegularExpressionLiteral,
354
+ shimast.KindTrueKeyword,
355
+ shimast.KindFalseKeyword,
356
+ shimast.KindNullKeyword,
357
+ shimast.KindArrayLiteralExpression,
358
+ shimast.KindObjectLiteralExpression,
359
+ shimast.KindArrowFunction,
360
+ shimast.KindFunctionExpression:
361
+ return true
362
+ case shimast.KindPrefixUnaryExpression:
363
+ prefix := node.AsPrefixUnaryExpression()
364
+ if prefix == nil {
365
+ return false
366
+ }
367
+ return isConstantTruthyOrFalsy(prefix.Operand)
368
+ }
369
+ return false
370
370
  }
371
371
 
372
372
  func init() {
373
- Register(noExtraBooleanCast{})
374
- Register(noUnsafeNegation{})
375
- Register(eqeqeq{})
376
- Register(useIsnan{})
377
- Register(validTypeof{})
378
- Register(noCompareNegZero{})
379
- Register(noCondAssign{})
380
- Register(noConstantCondition{})
373
+ Register(noExtraBooleanCast{})
374
+ Register(noUnsafeNegation{})
375
+ Register(eqeqeq{})
376
+ Register(useIsnan{})
377
+ Register(validTypeof{})
378
+ Register(noCompareNegZero{})
379
+ Register(noCondAssign{})
380
+ Register(noConstantCondition{})
381
381
  }