@ttsc/lint 0.7.1 → 0.7.3
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.
- package/README.md +62 -24
- package/lib/index.js.map +1 -1
- package/package.json +3 -3
- package/plugin/ast_helpers.go +158 -158
- package/plugin/compile.go +303 -303
- package/plugin/config.go +322 -322
- package/plugin/engine.go +152 -153
- package/plugin/host.go +128 -128
- package/plugin/main.go +21 -21
- package/plugin/rules_arrays.go +51 -51
- package/plugin/rules_console.go +22 -23
- package/plugin/rules_debugger.go +4 -4
- package/plugin/rules_dupes.go +134 -134
- package/plugin/rules_empty.go +68 -68
- package/plugin/rules_eval.go +28 -28
- package/plugin/rules_finally.go +91 -91
- package/plugin/rules_gap.go +188 -188
- package/plugin/rules_logic.go +268 -268
- package/plugin/rules_loops.go +89 -89
- package/plugin/rules_misc.go +43 -43
- package/plugin/rules_problems.go +396 -396
- package/plugin/rules_protos.go +17 -17
- package/plugin/rules_self.go +56 -56
- package/plugin/rules_strings.go +65 -65
- package/plugin/rules_suggestions.go +863 -863
- package/plugin/rules_throw.go +16 -16
- package/plugin/rules_ts.go +161 -161
- package/plugin/rules_ts_extra.go +467 -467
- package/plugin/rules_var.go +86 -86
- package/src/index.ts +1 -4
package/plugin/rules_loops.go
CHANGED
|
@@ -9,99 +9,99 @@ type forDirection struct{}
|
|
|
9
9
|
func (forDirection) Name() string { return "for-direction" }
|
|
10
10
|
func (forDirection) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindForStatement} }
|
|
11
11
|
func (forDirection) Check(ctx *Context, node *shimast.Node) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
12
|
+
loop := node.AsForStatement()
|
|
13
|
+
if loop == nil || loop.Condition == nil || loop.Incrementor == nil {
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
|
+
cond := loop.Condition
|
|
17
|
+
if cond.Kind != shimast.KindBinaryExpression {
|
|
18
|
+
return
|
|
19
|
+
}
|
|
20
|
+
bin := cond.AsBinaryExpression()
|
|
21
|
+
if bin == nil || bin.OperatorToken == nil {
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
leftName := identifierText(bin.Left)
|
|
25
|
+
rightName := identifierText(bin.Right)
|
|
26
|
+
if leftName == "" && rightName == "" {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
directionFromCondition := 0
|
|
30
|
+
switch bin.OperatorToken.Kind {
|
|
31
|
+
case shimast.KindLessThanToken, shimast.KindLessThanEqualsToken:
|
|
32
|
+
// `i < limit` requires increment
|
|
33
|
+
if leftName != "" {
|
|
34
|
+
directionFromCondition = +1
|
|
35
|
+
} else {
|
|
36
|
+
directionFromCondition = -1
|
|
37
|
+
}
|
|
38
|
+
case shimast.KindGreaterThanToken, shimast.KindGreaterThanEqualsToken:
|
|
39
|
+
if leftName != "" {
|
|
40
|
+
directionFromCondition = -1
|
|
41
|
+
} else {
|
|
42
|
+
directionFromCondition = +1
|
|
43
|
+
}
|
|
44
|
+
default:
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
counterName := leftName
|
|
48
|
+
if counterName == "" {
|
|
49
|
+
counterName = rightName
|
|
50
|
+
}
|
|
51
|
+
directionFromIncr := updateDirection(loop.Incrementor, counterName)
|
|
52
|
+
if directionFromIncr == 0 {
|
|
53
|
+
return
|
|
54
|
+
}
|
|
55
|
+
if directionFromIncr*directionFromCondition < 0 {
|
|
56
|
+
ctx.Report(loop.Incrementor, "The update clause in this loop moves the variable in the wrong direction.")
|
|
57
|
+
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
func updateDirection(node *shimast.Node, counter string) int {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
61
|
+
if node == nil || counter == "" {
|
|
62
|
+
return 0
|
|
63
|
+
}
|
|
64
|
+
switch node.Kind {
|
|
65
|
+
case shimast.KindPostfixUnaryExpression:
|
|
66
|
+
post := node.AsPostfixUnaryExpression()
|
|
67
|
+
if post == nil || identifierText(post.Operand) != counter {
|
|
68
|
+
return 0
|
|
69
|
+
}
|
|
70
|
+
switch post.Operator {
|
|
71
|
+
case shimast.KindPlusPlusToken:
|
|
72
|
+
return +1
|
|
73
|
+
case shimast.KindMinusMinusToken:
|
|
74
|
+
return -1
|
|
75
|
+
}
|
|
76
|
+
case shimast.KindPrefixUnaryExpression:
|
|
77
|
+
pre := node.AsPrefixUnaryExpression()
|
|
78
|
+
if pre == nil || identifierText(pre.Operand) != counter {
|
|
79
|
+
return 0
|
|
80
|
+
}
|
|
81
|
+
switch pre.Operator {
|
|
82
|
+
case shimast.KindPlusPlusToken:
|
|
83
|
+
return +1
|
|
84
|
+
case shimast.KindMinusMinusToken:
|
|
85
|
+
return -1
|
|
86
|
+
}
|
|
87
|
+
case shimast.KindBinaryExpression:
|
|
88
|
+
bin := node.AsBinaryExpression()
|
|
89
|
+
if bin == nil || bin.OperatorToken == nil {
|
|
90
|
+
return 0
|
|
91
|
+
}
|
|
92
|
+
if identifierText(bin.Left) != counter {
|
|
93
|
+
return 0
|
|
94
|
+
}
|
|
95
|
+
switch bin.OperatorToken.Kind {
|
|
96
|
+
case shimast.KindPlusEqualsToken:
|
|
97
|
+
return +1
|
|
98
|
+
case shimast.KindMinusEqualsToken:
|
|
99
|
+
return -1
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return 0
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
func init() {
|
|
106
|
-
|
|
106
|
+
Register(forDirection{})
|
|
107
107
|
}
|
package/plugin/rules_misc.go
CHANGED
|
@@ -10,39 +10,39 @@ type radix struct{}
|
|
|
10
10
|
func (radix) Name() string { return "radix" }
|
|
11
11
|
func (radix) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindCallExpression} }
|
|
12
12
|
func (radix) Check(ctx *Context, node *shimast.Node) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
13
|
+
call := node.AsCallExpression()
|
|
14
|
+
if call == nil {
|
|
15
|
+
return
|
|
16
|
+
}
|
|
17
|
+
name := callCalleeName(call)
|
|
18
|
+
if name != "parseInt" && name != "Number.parseInt" && !isMatchingPropertyAccess(call.Expression, "Number", "parseInt") {
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
args := 0
|
|
22
|
+
if call.Arguments != nil {
|
|
23
|
+
args = len(call.Arguments.Nodes)
|
|
24
|
+
}
|
|
25
|
+
if args == 0 {
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
if args == 1 {
|
|
29
|
+
ctx.Report(node, "Missing radix parameter.")
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
radixArg := call.Arguments.Nodes[1]
|
|
33
|
+
radixArg = stripParens(radixArg)
|
|
34
|
+
if radixArg == nil {
|
|
35
|
+
ctx.Report(node, "Missing radix parameter.")
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
if radixArg.Kind == shimast.KindNumericLiteral {
|
|
39
|
+
text := numericLiteralText(radixArg)
|
|
40
|
+
if text == "10" || text == "16" || text == "8" || text == "2" {
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
ctx.Report(radixArg, "Invalid radix parameter.")
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
// no-new-wrappers: `new String("")`, `new Number(0)`, `new Boolean(false)`
|
|
@@ -53,17 +53,17 @@ type noNewWrappers struct{}
|
|
|
53
53
|
func (noNewWrappers) Name() string { return "no-new-wrappers" }
|
|
54
54
|
func (noNewWrappers) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindNewExpression} }
|
|
55
55
|
func (noNewWrappers) Check(ctx *Context, node *shimast.Node) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
56
|
+
ne := node.AsNewExpression()
|
|
57
|
+
if ne == nil {
|
|
58
|
+
return
|
|
59
|
+
}
|
|
60
|
+
switch identifierText(ne.Expression) {
|
|
61
|
+
case "String", "Number", "Boolean":
|
|
62
|
+
ctx.Report(node, "Do not use "+identifierText(ne.Expression)+" as a constructor.")
|
|
63
|
+
}
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
func init() {
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
Register(radix{})
|
|
68
|
+
Register(noNewWrappers{})
|
|
69
69
|
}
|