@ttsc/lint 0.5.0-dev.20260429 → 0.5.0-dev.20260429-2
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/{go-plugin/go.mod → go.mod} +3 -3
- package/package.json +6 -7
- package/{go-plugin/lint → plugin}/ast_helpers.go +1 -1
- package/{go-plugin/lint → plugin}/compile.go +1 -1
- package/{go-plugin/lint → plugin}/config.go +1 -1
- package/{go-plugin/lint → plugin}/engine.go +6 -6
- package/{go-plugin/lint → plugin}/host.go +1 -1
- package/{go-plugin → plugin}/main.go +3 -5
- package/{go-plugin/lint → plugin}/rules_arrays.go +5 -3
- package/{go-plugin/lint → plugin}/rules_console.go +3 -3
- package/{go-plugin/lint → plugin}/rules_debugger.go +5 -5
- package/{go-plugin/lint → plugin}/rules_dupes.go +5 -5
- package/{go-plugin/lint → plugin}/rules_empty.go +4 -4
- package/{go-plugin/lint → plugin}/rules_eval.go +7 -5
- package/{go-plugin/lint → plugin}/rules_finally.go +3 -3
- package/{go-plugin/lint → plugin}/rules_logic.go +11 -11
- package/{go-plugin/lint → plugin}/rules_loops.go +3 -3
- package/{go-plugin/lint → plugin}/rules_misc.go +5 -5
- package/{go-plugin/lint → plugin}/rules_problems.go +41 -29
- package/{go-plugin/lint → plugin}/rules_protos.go +7 -5
- package/{go-plugin/lint → plugin}/rules_self.go +5 -5
- package/{go-plugin/lint → plugin}/rules_strings.go +11 -9
- package/{go-plugin/lint → plugin}/rules_suggestions.go +83 -61
- package/{go-plugin/lint → plugin}/rules_throw.go +3 -3
- package/{go-plugin/lint → plugin}/rules_ts.go +29 -19
- package/{go-plugin/lint → plugin}/rules_ts_extra.go +57 -35
- package/{go-plugin/lint → plugin}/rules_var.go +3 -3
- package/{index.cjs → src/index.cjs} +3 -2
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
module github.com/samchon/ttsc/packages/lint
|
|
1
|
+
module github.com/samchon/ttsc/packages/lint
|
|
2
2
|
|
|
3
3
|
go 1.26
|
|
4
4
|
|
|
5
5
|
// The plugin depends only on the `microsoft/typescript-go/shim/*`
|
|
6
6
|
// modules so that `go mod tidy` works against the public proxy. The
|
|
7
7
|
// bootstrap glue (Program creation, diagnostic rendering, emit) is
|
|
8
|
-
// inlined under ./
|
|
8
|
+
// inlined under ./plugin/host.go to avoid a transitive dependency on the
|
|
9
9
|
// in-tree `github.com/samchon/ttsc/packages/ttsc` module — that module
|
|
10
10
|
// has no public version tag and would only resolve through ttsc's
|
|
11
11
|
// scratch-dir go.work overlay, which conflicts with go.mod-level
|
|
@@ -30,7 +30,7 @@ require (
|
|
|
30
30
|
require (
|
|
31
31
|
github.com/go-json-experiment/json v0.0.0-20260214004413-d219187c3433 // indirect
|
|
32
32
|
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
|
|
33
|
-
github.com/microsoft/typescript-go v0.0.0-
|
|
33
|
+
github.com/microsoft/typescript-go v0.0.0-20260428010401-3499951dbc49 // indirect
|
|
34
34
|
github.com/zeebo/xxh3 v1.1.0 // indirect
|
|
35
35
|
golang.org/x/sync v0.20.0 // indirect
|
|
36
36
|
golang.org/x/sys v0.42.0 // indirect
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ttsc/lint",
|
|
3
|
-
"version": "0.5.0-dev.20260429",
|
|
3
|
+
"version": "0.5.0-dev.20260429-2",
|
|
4
4
|
"description": "Reference ttsc plugin: ESLint-style lint rules hosted in the same Program/Checker as the type-check pass.",
|
|
5
|
-
"main": "index.cjs",
|
|
5
|
+
"main": "src/index.cjs",
|
|
6
6
|
"exports": {
|
|
7
|
-
".": "./index.cjs",
|
|
7
|
+
".": "./src/index.cjs",
|
|
8
8
|
"./package.json": "./package.json"
|
|
9
9
|
},
|
|
10
10
|
"keywords": [
|
|
@@ -16,10 +16,9 @@
|
|
|
16
16
|
],
|
|
17
17
|
"files": [
|
|
18
18
|
"README.md",
|
|
19
|
-
"index.cjs",
|
|
20
|
-
"go
|
|
21
|
-
"
|
|
22
|
-
"go-plugin/lint"
|
|
19
|
+
"src/index.cjs",
|
|
20
|
+
"go.mod",
|
|
21
|
+
"plugin"
|
|
23
22
|
],
|
|
24
23
|
"repository": {
|
|
25
24
|
"type": "git",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
// The split between this file and `engine.go` is deliberate: the engine
|
|
10
10
|
// is pure (rules + AST traversal), and this file owns every side effect
|
|
11
11
|
// (process flags, stderr/stdout, emit, exit codes).
|
|
12
|
-
package
|
|
12
|
+
package main
|
|
13
13
|
|
|
14
14
|
import (
|
|
15
15
|
"context"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// The lint plugin hosts the rule registry, the AST-walking engine, and the
|
|
2
2
|
// orchestration glue that the `@ttsc/lint` native plugin uses to run rules
|
|
3
3
|
// against a tsgo Program.
|
|
4
4
|
//
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
// and may not retain references to the previous file. This keeps the
|
|
16
16
|
// engine concurrent-friendly even though the v0 implementation runs
|
|
17
17
|
// serially.
|
|
18
|
-
package
|
|
18
|
+
package main
|
|
19
19
|
|
|
20
20
|
import (
|
|
21
21
|
"sort"
|
|
@@ -146,10 +146,10 @@ func AllRuleNames() []string {
|
|
|
146
146
|
// Engine binds a rule configuration to a Program and walks the AST once
|
|
147
147
|
// per source file, dispatching each visited node to its interested rules.
|
|
148
148
|
type Engine struct {
|
|
149
|
-
config
|
|
150
|
-
rules
|
|
151
|
-
enabled
|
|
152
|
-
unknown
|
|
149
|
+
config RuleConfig
|
|
150
|
+
rules map[shimast.Kind][]Rule
|
|
151
|
+
enabled map[string]Severity
|
|
152
|
+
unknown []string
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
// NewEngine returns an engine configured for `config`. Rules whose
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// ttsc's runtime-generated go.work overlay. Instead, this file inlines a
|
|
8
8
|
// minimal Program/Checker bootstrap (the same pattern documented in
|
|
9
9
|
// 03-tsgo.md and used by every other source-plugin reference fixture).
|
|
10
|
-
package
|
|
10
|
+
package main
|
|
11
11
|
|
|
12
12
|
import (
|
|
13
13
|
"context"
|
|
@@ -18,8 +18,6 @@ package main
|
|
|
18
18
|
import (
|
|
19
19
|
"fmt"
|
|
20
20
|
"os"
|
|
21
|
-
|
|
22
|
-
"github.com/samchon/ttsc/packages/lint/go-plugin/lint"
|
|
23
21
|
)
|
|
24
22
|
|
|
25
23
|
const version = "0.0.1"
|
|
@@ -38,11 +36,11 @@ func run(args []string) int {
|
|
|
38
36
|
fmt.Fprintf(os.Stdout, "@ttsc/lint %s\n", version)
|
|
39
37
|
return 0
|
|
40
38
|
case "check":
|
|
41
|
-
return
|
|
39
|
+
return RunCheck(args[1:])
|
|
42
40
|
case "build":
|
|
43
|
-
return
|
|
41
|
+
return RunBuild(args[1:])
|
|
44
42
|
case "transform":
|
|
45
|
-
return
|
|
43
|
+
return RunTransform(args[1:])
|
|
46
44
|
default:
|
|
47
45
|
fmt.Fprintf(os.Stderr, "@ttsc/lint: unknown command %q\n", args[0])
|
|
48
46
|
return 2
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package
|
|
1
|
+
package main
|
|
2
2
|
|
|
3
3
|
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
4
4
|
|
|
@@ -7,8 +7,10 @@ import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
|
7
7
|
// https://eslint.org/docs/latest/rules/no-sparse-arrays
|
|
8
8
|
type noSparseArrays struct{}
|
|
9
9
|
|
|
10
|
-
func (noSparseArrays) Name() string
|
|
11
|
-
func (noSparseArrays) Visits() []shimast.Kind
|
|
10
|
+
func (noSparseArrays) Name() string { return "no-sparse-arrays" }
|
|
11
|
+
func (noSparseArrays) Visits() []shimast.Kind {
|
|
12
|
+
return []shimast.Kind{shimast.KindArrayLiteralExpression}
|
|
13
|
+
}
|
|
12
14
|
func (noSparseArrays) Check(ctx *Context, node *shimast.Node) {
|
|
13
15
|
arr := node.AsArrayLiteralExpression()
|
|
14
16
|
if arr == nil || arr.Elements == nil {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package
|
|
1
|
+
package main
|
|
2
2
|
|
|
3
3
|
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
4
4
|
|
|
@@ -8,8 +8,8 @@ import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
|
8
8
|
// https://eslint.org/docs/latest/rules/no-console
|
|
9
9
|
type noConsole struct{}
|
|
10
10
|
|
|
11
|
-
func (noConsole) Name() string
|
|
12
|
-
func (noConsole) Visits() []shimast.Kind
|
|
11
|
+
func (noConsole) Name() string { return "no-console" }
|
|
12
|
+
func (noConsole) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindCallExpression} }
|
|
13
13
|
func (noConsole) Check(ctx *Context, node *shimast.Node) {
|
|
14
14
|
call := node.AsCallExpression()
|
|
15
15
|
if call == nil || call.Expression == nil {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package
|
|
1
|
+
package main
|
|
2
2
|
|
|
3
3
|
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
4
4
|
|
|
@@ -6,8 +6,8 @@ import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
|
6
6
|
// https://eslint.org/docs/latest/rules/no-debugger
|
|
7
7
|
type noDebugger struct{}
|
|
8
8
|
|
|
9
|
-
func (noDebugger) Name() string
|
|
10
|
-
func (noDebugger) Visits() []shimast.Kind
|
|
9
|
+
func (noDebugger) Name() string { return "no-debugger" }
|
|
10
|
+
func (noDebugger) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindDebuggerStatement} }
|
|
11
11
|
func (noDebugger) Check(ctx *Context, node *shimast.Node) {
|
|
12
12
|
ctx.Report(node, "Unexpected `debugger` statement.")
|
|
13
13
|
}
|
|
@@ -17,8 +17,8 @@ func (noDebugger) Check(ctx *Context, node *shimast.Node) {
|
|
|
17
17
|
// https://eslint.org/docs/latest/rules/no-with
|
|
18
18
|
type noWith struct{}
|
|
19
19
|
|
|
20
|
-
func (noWith) Name() string
|
|
21
|
-
func (noWith) Visits() []shimast.Kind
|
|
20
|
+
func (noWith) Name() string { return "no-with" }
|
|
21
|
+
func (noWith) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindWithStatement} }
|
|
22
22
|
func (noWith) Check(ctx *Context, node *shimast.Node) {
|
|
23
23
|
ctx.Report(node, "Unexpected `with` statement.")
|
|
24
24
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package
|
|
1
|
+
package main
|
|
2
2
|
|
|
3
3
|
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
4
4
|
|
|
@@ -6,8 +6,8 @@ import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
|
6
6
|
// https://eslint.org/docs/latest/rules/no-duplicate-case
|
|
7
7
|
type noDuplicateCase struct{}
|
|
8
8
|
|
|
9
|
-
func (noDuplicateCase) Name() string
|
|
10
|
-
func (noDuplicateCase) Visits() []shimast.Kind
|
|
9
|
+
func (noDuplicateCase) Name() string { return "no-duplicate-case" }
|
|
10
|
+
func (noDuplicateCase) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindSwitchStatement} }
|
|
11
11
|
func (noDuplicateCase) Check(ctx *Context, node *shimast.Node) {
|
|
12
12
|
sw := node.AsSwitchStatement()
|
|
13
13
|
if sw == nil || sw.CaseBlock == nil {
|
|
@@ -42,8 +42,8 @@ func (noDuplicateCase) Check(ctx *Context, node *shimast.Node) {
|
|
|
42
42
|
// https://eslint.org/docs/latest/rules/no-dupe-keys
|
|
43
43
|
type noDupeKeys struct{}
|
|
44
44
|
|
|
45
|
-
func (noDupeKeys) Name() string
|
|
46
|
-
func (noDupeKeys) Visits() []shimast.Kind
|
|
45
|
+
func (noDupeKeys) Name() string { return "no-dupe-keys" }
|
|
46
|
+
func (noDupeKeys) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindObjectLiteralExpression} }
|
|
47
47
|
func (noDupeKeys) Check(ctx *Context, node *shimast.Node) {
|
|
48
48
|
obj := node.AsObjectLiteralExpression()
|
|
49
49
|
if obj == nil || obj.Properties == nil {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package
|
|
1
|
+
package main
|
|
2
2
|
|
|
3
3
|
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
4
4
|
|
|
@@ -7,8 +7,8 @@ import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
|
7
7
|
// https://eslint.org/docs/latest/rules/no-empty
|
|
8
8
|
type noEmpty struct{}
|
|
9
9
|
|
|
10
|
-
func (noEmpty) Name() string
|
|
11
|
-
func (noEmpty) Visits() []shimast.Kind
|
|
10
|
+
func (noEmpty) Name() string { return "no-empty" }
|
|
11
|
+
func (noEmpty) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBlock} }
|
|
12
12
|
func (noEmpty) Check(ctx *Context, node *shimast.Node) {
|
|
13
13
|
block := node.AsBlock()
|
|
14
14
|
if block == nil || block.Statements == nil {
|
|
@@ -31,7 +31,7 @@ func (noEmpty) Check(ctx *Context, node *shimast.Node) {
|
|
|
31
31
|
// https://eslint.org/docs/latest/rules/no-empty-function
|
|
32
32
|
type noEmptyFunction struct{}
|
|
33
33
|
|
|
34
|
-
func (noEmptyFunction) Name() string
|
|
34
|
+
func (noEmptyFunction) Name() string { return "no-empty-function" }
|
|
35
35
|
func (noEmptyFunction) Visits() []shimast.Kind {
|
|
36
36
|
return []shimast.Kind{
|
|
37
37
|
shimast.KindFunctionDeclaration,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package
|
|
1
|
+
package main
|
|
2
2
|
|
|
3
3
|
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
4
4
|
|
|
@@ -8,8 +8,8 @@ import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
|
8
8
|
// https://eslint.org/docs/latest/rules/no-eval
|
|
9
9
|
type noEval struct{}
|
|
10
10
|
|
|
11
|
-
func (noEval) Name() string
|
|
12
|
-
func (noEval) Visits() []shimast.Kind
|
|
11
|
+
func (noEval) Name() string { return "no-eval" }
|
|
12
|
+
func (noEval) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindCallExpression} }
|
|
13
13
|
func (noEval) Check(ctx *Context, node *shimast.Node) {
|
|
14
14
|
call := node.AsCallExpression()
|
|
15
15
|
if call == nil {
|
|
@@ -25,8 +25,10 @@ func (noEval) Check(ctx *Context, node *shimast.Node) {
|
|
|
25
25
|
// https://eslint.org/docs/latest/rules/no-script-url
|
|
26
26
|
type noScriptURL struct{}
|
|
27
27
|
|
|
28
|
-
func (noScriptURL) Name() string
|
|
29
|
-
func (noScriptURL) Visits() []shimast.Kind
|
|
28
|
+
func (noScriptURL) Name() string { return "no-script-url" }
|
|
29
|
+
func (noScriptURL) Visits() []shimast.Kind {
|
|
30
|
+
return []shimast.Kind{shimast.KindStringLiteral, shimast.KindNoSubstitutionTemplateLiteral}
|
|
31
|
+
}
|
|
30
32
|
func (noScriptURL) Check(ctx *Context, node *shimast.Node) {
|
|
31
33
|
text := stringLiteralText(node)
|
|
32
34
|
if isJavaScriptURL(text) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package
|
|
1
|
+
package main
|
|
2
2
|
|
|
3
3
|
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
4
4
|
|
|
@@ -76,8 +76,8 @@ func keywordOfControl(node *shimast.Node) string {
|
|
|
76
76
|
// https://eslint.org/docs/latest/rules/no-useless-catch
|
|
77
77
|
type noUselessCatch struct{}
|
|
78
78
|
|
|
79
|
-
func (noUselessCatch) Name() string
|
|
80
|
-
func (noUselessCatch) Visits() []shimast.Kind
|
|
79
|
+
func (noUselessCatch) Name() string { return "no-useless-catch" }
|
|
80
|
+
func (noUselessCatch) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindCatchClause} }
|
|
81
81
|
func (noUselessCatch) Check(ctx *Context, node *shimast.Node) {
|
|
82
82
|
clause := node.AsCatchClause()
|
|
83
83
|
if clause == nil || clause.VariableDeclaration == nil || clause.Block == nil {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package
|
|
1
|
+
package main
|
|
2
2
|
|
|
3
3
|
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
4
4
|
|
|
@@ -83,8 +83,8 @@ func skipParents(node *shimast.Node) *shimast.Node {
|
|
|
83
83
|
// https://eslint.org/docs/latest/rules/no-unsafe-negation
|
|
84
84
|
type noUnsafeNegation struct{}
|
|
85
85
|
|
|
86
|
-
func (noUnsafeNegation) Name() string
|
|
87
|
-
func (noUnsafeNegation) Visits() []shimast.Kind
|
|
86
|
+
func (noUnsafeNegation) Name() string { return "no-unsafe-negation" }
|
|
87
|
+
func (noUnsafeNegation) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBinaryExpression} }
|
|
88
88
|
func (noUnsafeNegation) Check(ctx *Context, node *shimast.Node) {
|
|
89
89
|
expr := node.AsBinaryExpression()
|
|
90
90
|
if expr == nil || expr.OperatorToken == nil {
|
|
@@ -110,8 +110,8 @@ func (noUnsafeNegation) Check(ctx *Context, node *shimast.Node) {
|
|
|
110
110
|
// https://eslint.org/docs/latest/rules/eqeqeq
|
|
111
111
|
type eqeqeq struct{}
|
|
112
112
|
|
|
113
|
-
func (eqeqeq) Name() string
|
|
114
|
-
func (eqeqeq) Visits() []shimast.Kind
|
|
113
|
+
func (eqeqeq) Name() string { return "eqeqeq" }
|
|
114
|
+
func (eqeqeq) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBinaryExpression} }
|
|
115
115
|
func (eqeqeq) Check(ctx *Context, node *shimast.Node) {
|
|
116
116
|
expr := node.AsBinaryExpression()
|
|
117
117
|
if expr == nil || expr.OperatorToken == nil {
|
|
@@ -129,8 +129,8 @@ func (eqeqeq) Check(ctx *Context, node *shimast.Node) {
|
|
|
129
129
|
// https://eslint.org/docs/latest/rules/use-isnan
|
|
130
130
|
type useIsnan struct{}
|
|
131
131
|
|
|
132
|
-
func (useIsnan) Name() string
|
|
133
|
-
func (useIsnan) Visits() []shimast.Kind
|
|
132
|
+
func (useIsnan) Name() string { return "use-isnan" }
|
|
133
|
+
func (useIsnan) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBinaryExpression} }
|
|
134
134
|
func (useIsnan) Check(ctx *Context, node *shimast.Node) {
|
|
135
135
|
expr := node.AsBinaryExpression()
|
|
136
136
|
if expr == nil || expr.OperatorToken == nil {
|
|
@@ -149,8 +149,8 @@ func (useIsnan) Check(ctx *Context, node *shimast.Node) {
|
|
|
149
149
|
// https://eslint.org/docs/latest/rules/valid-typeof
|
|
150
150
|
type validTypeof struct{}
|
|
151
151
|
|
|
152
|
-
func (validTypeof) Name() string
|
|
153
|
-
func (validTypeof) Visits() []shimast.Kind
|
|
152
|
+
func (validTypeof) Name() string { return "valid-typeof" }
|
|
153
|
+
func (validTypeof) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBinaryExpression} }
|
|
154
154
|
func (validTypeof) Check(ctx *Context, node *shimast.Node) {
|
|
155
155
|
expr := node.AsBinaryExpression()
|
|
156
156
|
if expr == nil || expr.OperatorToken == nil {
|
|
@@ -194,8 +194,8 @@ func isValidTypeofString(value string) bool {
|
|
|
194
194
|
// https://eslint.org/docs/latest/rules/no-compare-neg-zero
|
|
195
195
|
type noCompareNegZero struct{}
|
|
196
196
|
|
|
197
|
-
func (noCompareNegZero) Name() string
|
|
198
|
-
func (noCompareNegZero) Visits() []shimast.Kind
|
|
197
|
+
func (noCompareNegZero) Name() string { return "no-compare-neg-zero" }
|
|
198
|
+
func (noCompareNegZero) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBinaryExpression} }
|
|
199
199
|
func (noCompareNegZero) Check(ctx *Context, node *shimast.Node) {
|
|
200
200
|
expr := node.AsBinaryExpression()
|
|
201
201
|
if expr == nil || expr.OperatorToken == nil {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package
|
|
1
|
+
package main
|
|
2
2
|
|
|
3
3
|
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
4
4
|
|
|
@@ -6,8 +6,8 @@ import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
|
6
6
|
// https://eslint.org/docs/latest/rules/for-direction
|
|
7
7
|
type forDirection struct{}
|
|
8
8
|
|
|
9
|
-
func (forDirection) Name() string
|
|
10
|
-
func (forDirection) Visits() []shimast.Kind
|
|
9
|
+
func (forDirection) Name() string { return "for-direction" }
|
|
10
|
+
func (forDirection) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindForStatement} }
|
|
11
11
|
func (forDirection) Check(ctx *Context, node *shimast.Node) {
|
|
12
12
|
loop := node.AsForStatement()
|
|
13
13
|
if loop == nil || loop.Condition == nil || loop.Incrementor == nil {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package
|
|
1
|
+
package main
|
|
2
2
|
|
|
3
3
|
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
4
4
|
|
|
@@ -7,8 +7,8 @@ import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
|
7
7
|
// https://eslint.org/docs/latest/rules/radix
|
|
8
8
|
type radix struct{}
|
|
9
9
|
|
|
10
|
-
func (radix) Name() string
|
|
11
|
-
func (radix) Visits() []shimast.Kind
|
|
10
|
+
func (radix) Name() string { return "radix" }
|
|
11
|
+
func (radix) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindCallExpression} }
|
|
12
12
|
func (radix) Check(ctx *Context, node *shimast.Node) {
|
|
13
13
|
call := node.AsCallExpression()
|
|
14
14
|
if call == nil {
|
|
@@ -50,8 +50,8 @@ func (radix) Check(ctx *Context, node *shimast.Node) {
|
|
|
50
50
|
// https://eslint.org/docs/latest/rules/no-new-wrappers
|
|
51
51
|
type noNewWrappers struct{}
|
|
52
52
|
|
|
53
|
-
func (noNewWrappers) Name() string
|
|
54
|
-
func (noNewWrappers) Visits() []shimast.Kind
|
|
53
|
+
func (noNewWrappers) Name() string { return "no-new-wrappers" }
|
|
54
|
+
func (noNewWrappers) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindNewExpression} }
|
|
55
55
|
func (noNewWrappers) Check(ctx *Context, node *shimast.Node) {
|
|
56
56
|
ne := node.AsNewExpression()
|
|
57
57
|
if ne == nil {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// fast and predictable. Rules that require scope binding or
|
|
6
6
|
// flow-sensitive analysis are intentionally not implemented here —
|
|
7
7
|
// those are upstream's job.
|
|
8
|
-
package
|
|
8
|
+
package main
|
|
9
9
|
|
|
10
10
|
import (
|
|
11
11
|
"strings"
|
|
@@ -17,8 +17,8 @@ import (
|
|
|
17
17
|
// unreachable.
|
|
18
18
|
type noDupeElseIf struct{}
|
|
19
19
|
|
|
20
|
-
func (noDupeElseIf) Name() string
|
|
21
|
-
func (noDupeElseIf) Visits() []shimast.Kind
|
|
20
|
+
func (noDupeElseIf) Name() string { return "no-dupe-else-if" }
|
|
21
|
+
func (noDupeElseIf) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindIfStatement} }
|
|
22
22
|
func (noDupeElseIf) Check(ctx *Context, node *shimast.Node) {
|
|
23
23
|
// Only fire on the *outermost* if; the recursion below scans the
|
|
24
24
|
// chain once.
|
|
@@ -53,8 +53,8 @@ func (noDupeElseIf) Check(ctx *Context, node *shimast.Node) {
|
|
|
53
53
|
// binding silently throws away the error.
|
|
54
54
|
type noExAssign struct{}
|
|
55
55
|
|
|
56
|
-
func (noExAssign) Name() string
|
|
57
|
-
func (noExAssign) Visits() []shimast.Kind
|
|
56
|
+
func (noExAssign) Name() string { return "no-ex-assign" }
|
|
57
|
+
func (noExAssign) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindCatchClause} }
|
|
58
58
|
func (noExAssign) Check(ctx *Context, node *shimast.Node) {
|
|
59
59
|
clause := node.AsCatchClause()
|
|
60
60
|
if clause == nil || clause.VariableDeclaration == nil || clause.Block == nil {
|
|
@@ -99,8 +99,10 @@ func walkAssignments(root *shimast.Node, name string, report func(*shimast.Node)
|
|
|
99
99
|
// no-empty-character-class: `/[]/` matches nothing.
|
|
100
100
|
type noEmptyCharacterClass struct{}
|
|
101
101
|
|
|
102
|
-
func (noEmptyCharacterClass) Name() string
|
|
103
|
-
func (noEmptyCharacterClass) Visits() []shimast.Kind
|
|
102
|
+
func (noEmptyCharacterClass) Name() string { return "no-empty-character-class" }
|
|
103
|
+
func (noEmptyCharacterClass) Visits() []shimast.Kind {
|
|
104
|
+
return []shimast.Kind{shimast.KindRegularExpressionLiteral}
|
|
105
|
+
}
|
|
104
106
|
func (noEmptyCharacterClass) Check(ctx *Context, node *shimast.Node) {
|
|
105
107
|
src := nodeText(ctx.File, node)
|
|
106
108
|
if hasEmptyCharClass(src) {
|
|
@@ -130,8 +132,10 @@ func hasEmptyCharClass(src string) bool {
|
|
|
130
132
|
// no-misleading-character-class: `/[👍]/` — surrogate pairs in regex.
|
|
131
133
|
type noMisleadingCharacterClass struct{}
|
|
132
134
|
|
|
133
|
-
func (noMisleadingCharacterClass) Name() string
|
|
134
|
-
func (noMisleadingCharacterClass) Visits() []shimast.Kind
|
|
135
|
+
func (noMisleadingCharacterClass) Name() string { return "no-misleading-character-class" }
|
|
136
|
+
func (noMisleadingCharacterClass) Visits() []shimast.Kind {
|
|
137
|
+
return []shimast.Kind{shimast.KindRegularExpressionLiteral}
|
|
138
|
+
}
|
|
135
139
|
func (noMisleadingCharacterClass) Check(ctx *Context, node *shimast.Node) {
|
|
136
140
|
src := nodeText(ctx.File, node)
|
|
137
141
|
if regexHasSurrogatePair(src) {
|
|
@@ -172,8 +176,8 @@ func regexHasSurrogatePair(src string) bool {
|
|
|
172
176
|
// that.
|
|
173
177
|
type noLossOfPrecision struct{}
|
|
174
178
|
|
|
175
|
-
func (noLossOfPrecision) Name() string
|
|
176
|
-
func (noLossOfPrecision) Visits() []shimast.Kind
|
|
179
|
+
func (noLossOfPrecision) Name() string { return "no-loss-of-precision" }
|
|
180
|
+
func (noLossOfPrecision) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindNumericLiteral} }
|
|
177
181
|
func (noLossOfPrecision) Check(ctx *Context, node *shimast.Node) {
|
|
178
182
|
source := strings.TrimSpace(nodeText(ctx.File, node))
|
|
179
183
|
if source == "" {
|
|
@@ -214,8 +218,8 @@ func numericLiteralLosesPrecision(text string) bool {
|
|
|
214
218
|
// no-class-assign: assigning to a class declaration's name.
|
|
215
219
|
type noClassAssign struct{}
|
|
216
220
|
|
|
217
|
-
func (noClassAssign) Name() string
|
|
218
|
-
func (noClassAssign) Visits() []shimast.Kind
|
|
221
|
+
func (noClassAssign) Name() string { return "no-class-assign" }
|
|
222
|
+
func (noClassAssign) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindClassDeclaration} }
|
|
219
223
|
func (noClassAssign) Check(ctx *Context, node *shimast.Node) {
|
|
220
224
|
decl := node.AsClassDeclaration()
|
|
221
225
|
if decl == nil || decl.Name() == nil {
|
|
@@ -233,8 +237,8 @@ func (noClassAssign) Check(ctx *Context, node *shimast.Node) {
|
|
|
233
237
|
// no-func-assign: same idea, but for function declarations.
|
|
234
238
|
type noFuncAssign struct{}
|
|
235
239
|
|
|
236
|
-
func (noFuncAssign) Name() string
|
|
237
|
-
func (noFuncAssign) Visits() []shimast.Kind
|
|
240
|
+
func (noFuncAssign) Name() string { return "no-func-assign" }
|
|
241
|
+
func (noFuncAssign) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindFunctionDeclaration} }
|
|
238
242
|
func (noFuncAssign) Check(ctx *Context, node *shimast.Node) {
|
|
239
243
|
decl := node.AsFunctionDeclaration()
|
|
240
244
|
if decl == nil || decl.Name() == nil {
|
|
@@ -253,8 +257,8 @@ func (noFuncAssign) Check(ctx *Context, node *shimast.Node) {
|
|
|
253
257
|
// `Object.prototype.hasOwnProperty.call(obj, x)` or `Object.hasOwn`.
|
|
254
258
|
type noPrototypeBuiltins struct{}
|
|
255
259
|
|
|
256
|
-
func (noPrototypeBuiltins) Name() string
|
|
257
|
-
func (noPrototypeBuiltins) Visits() []shimast.Kind
|
|
260
|
+
func (noPrototypeBuiltins) Name() string { return "no-prototype-builtins" }
|
|
261
|
+
func (noPrototypeBuiltins) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindCallExpression} }
|
|
258
262
|
func (noPrototypeBuiltins) Check(ctx *Context, node *shimast.Node) {
|
|
259
263
|
call := node.AsCallExpression()
|
|
260
264
|
if call == nil || call.Expression == nil {
|
|
@@ -277,8 +281,10 @@ func (noPrototypeBuiltins) Check(ctx *Context, node *shimast.Node) {
|
|
|
277
281
|
// no-async-promise-executor: `new Promise(async (resolve) => {...})`.
|
|
278
282
|
type noAsyncPromiseExecutor struct{}
|
|
279
283
|
|
|
280
|
-
func (noAsyncPromiseExecutor) Name() string
|
|
281
|
-
func (noAsyncPromiseExecutor) Visits() []shimast.Kind
|
|
284
|
+
func (noAsyncPromiseExecutor) Name() string { return "no-async-promise-executor" }
|
|
285
|
+
func (noAsyncPromiseExecutor) Visits() []shimast.Kind {
|
|
286
|
+
return []shimast.Kind{shimast.KindNewExpression}
|
|
287
|
+
}
|
|
282
288
|
func (noAsyncPromiseExecutor) Check(ctx *Context, node *shimast.Node) {
|
|
283
289
|
ne := node.AsNewExpression()
|
|
284
290
|
if ne == nil || identifierText(ne.Expression) != "Promise" {
|
|
@@ -303,8 +309,10 @@ func (noAsyncPromiseExecutor) Check(ctx *Context, node *shimast.Node) {
|
|
|
303
309
|
// thrown away.
|
|
304
310
|
type noPromiseExecutorReturn struct{}
|
|
305
311
|
|
|
306
|
-
func (noPromiseExecutorReturn) Name() string
|
|
307
|
-
func (noPromiseExecutorReturn) Visits() []shimast.Kind
|
|
312
|
+
func (noPromiseExecutorReturn) Name() string { return "no-promise-executor-return" }
|
|
313
|
+
func (noPromiseExecutorReturn) Visits() []shimast.Kind {
|
|
314
|
+
return []shimast.Kind{shimast.KindNewExpression}
|
|
315
|
+
}
|
|
308
316
|
func (noPromiseExecutorReturn) Check(ctx *Context, node *shimast.Node) {
|
|
309
317
|
ne := node.AsNewExpression()
|
|
310
318
|
if ne == nil || identifierText(ne.Expression) != "Promise" {
|
|
@@ -332,8 +340,10 @@ func (noPromiseExecutorReturn) Check(ctx *Context, node *shimast.Node) {
|
|
|
332
340
|
// counterpart.
|
|
333
341
|
type noControlRegex struct{}
|
|
334
342
|
|
|
335
|
-
func (noControlRegex) Name() string
|
|
336
|
-
func (noControlRegex) Visits() []shimast.Kind
|
|
343
|
+
func (noControlRegex) Name() string { return "no-control-regex" }
|
|
344
|
+
func (noControlRegex) Visits() []shimast.Kind {
|
|
345
|
+
return []shimast.Kind{shimast.KindRegularExpressionLiteral}
|
|
346
|
+
}
|
|
337
347
|
func (noControlRegex) Check(ctx *Context, node *shimast.Node) {
|
|
338
348
|
src := nodeText(ctx.File, node)
|
|
339
349
|
if regexContainsControl(src) {
|
|
@@ -388,8 +398,8 @@ func hexDigit(b byte) int {
|
|
|
388
398
|
// accepts them but copy-paste into source is almost always a mistake.
|
|
389
399
|
type noIrregularWhitespace struct{}
|
|
390
400
|
|
|
391
|
-
func (noIrregularWhitespace) Name() string
|
|
392
|
-
func (noIrregularWhitespace) Visits() []shimast.Kind
|
|
401
|
+
func (noIrregularWhitespace) Name() string { return "no-irregular-whitespace" }
|
|
402
|
+
func (noIrregularWhitespace) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindSourceFile} }
|
|
393
403
|
func (noIrregularWhitespace) Check(ctx *Context, node *shimast.Node) {
|
|
394
404
|
if ctx.File == nil {
|
|
395
405
|
return
|
|
@@ -421,8 +431,8 @@ func isIrregularWhitespace(r rune) bool {
|
|
|
421
431
|
// without an explicit `break` / `return` / `throw` / `continue`.
|
|
422
432
|
type noFallthrough struct{}
|
|
423
433
|
|
|
424
|
-
func (noFallthrough) Name() string
|
|
425
|
-
func (noFallthrough) Visits() []shimast.Kind
|
|
434
|
+
func (noFallthrough) Name() string { return "no-fallthrough" }
|
|
435
|
+
func (noFallthrough) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindSwitchStatement} }
|
|
426
436
|
func (noFallthrough) Check(ctx *Context, node *shimast.Node) {
|
|
427
437
|
sw := node.AsSwitchStatement()
|
|
428
438
|
if sw == nil || sw.CaseBlock == nil {
|
|
@@ -519,8 +529,10 @@ func (noInnerDeclarations) Check(ctx *Context, node *shimast.Node) {
|
|
|
519
529
|
// callables. ESLint catches a small list.
|
|
520
530
|
type noObjCalls struct{}
|
|
521
531
|
|
|
522
|
-
func (noObjCalls) Name() string
|
|
523
|
-
func (noObjCalls) Visits() []shimast.Kind
|
|
532
|
+
func (noObjCalls) Name() string { return "no-obj-calls" }
|
|
533
|
+
func (noObjCalls) Visits() []shimast.Kind {
|
|
534
|
+
return []shimast.Kind{shimast.KindCallExpression, shimast.KindNewExpression}
|
|
535
|
+
}
|
|
524
536
|
func (noObjCalls) Check(ctx *Context, node *shimast.Node) {
|
|
525
537
|
var callee *shimast.Node
|
|
526
538
|
if node.Kind == shimast.KindCallExpression {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package
|
|
1
|
+
package main
|
|
2
2
|
|
|
3
3
|
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
4
4
|
|
|
@@ -7,8 +7,10 @@ import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
|
7
7
|
// https://eslint.org/docs/latest/rules/no-iterator
|
|
8
8
|
type noIterator struct{}
|
|
9
9
|
|
|
10
|
-
func (noIterator) Name() string
|
|
11
|
-
func (noIterator) Visits() []shimast.Kind
|
|
10
|
+
func (noIterator) Name() string { return "no-iterator" }
|
|
11
|
+
func (noIterator) Visits() []shimast.Kind {
|
|
12
|
+
return []shimast.Kind{shimast.KindPropertyAccessExpression}
|
|
13
|
+
}
|
|
12
14
|
func (noIterator) Check(ctx *Context, node *shimast.Node) {
|
|
13
15
|
access := node.AsPropertyAccessExpression()
|
|
14
16
|
if access == nil {
|
|
@@ -24,8 +26,8 @@ func (noIterator) Check(ctx *Context, node *shimast.Node) {
|
|
|
24
26
|
// https://eslint.org/docs/latest/rules/no-proto
|
|
25
27
|
type noProto struct{}
|
|
26
28
|
|
|
27
|
-
func (noProto) Name() string
|
|
28
|
-
func (noProto) Visits() []shimast.Kind
|
|
29
|
+
func (noProto) Name() string { return "no-proto" }
|
|
30
|
+
func (noProto) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindPropertyAccessExpression} }
|
|
29
31
|
func (noProto) Check(ctx *Context, node *shimast.Node) {
|
|
30
32
|
access := node.AsPropertyAccessExpression()
|
|
31
33
|
if access == nil {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package
|
|
1
|
+
package main
|
|
2
2
|
|
|
3
3
|
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
4
4
|
|
|
@@ -8,8 +8,8 @@ import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
|
8
8
|
// https://eslint.org/docs/latest/rules/no-self-assign
|
|
9
9
|
type noSelfAssign struct{}
|
|
10
10
|
|
|
11
|
-
func (noSelfAssign) Name() string
|
|
12
|
-
func (noSelfAssign) Visits() []shimast.Kind
|
|
11
|
+
func (noSelfAssign) Name() string { return "no-self-assign" }
|
|
12
|
+
func (noSelfAssign) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBinaryExpression} }
|
|
13
13
|
func (noSelfAssign) Check(ctx *Context, node *shimast.Node) {
|
|
14
14
|
expr := node.AsBinaryExpression()
|
|
15
15
|
if expr == nil || expr.OperatorToken == nil {
|
|
@@ -47,8 +47,8 @@ func isAssignableLeftHand(node *shimast.Node) bool {
|
|
|
47
47
|
// https://eslint.org/docs/latest/rules/no-self-compare
|
|
48
48
|
type noSelfCompare struct{}
|
|
49
49
|
|
|
50
|
-
func (noSelfCompare) Name() string
|
|
51
|
-
func (noSelfCompare) Visits() []shimast.Kind
|
|
50
|
+
func (noSelfCompare) Name() string { return "no-self-compare" }
|
|
51
|
+
func (noSelfCompare) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBinaryExpression} }
|
|
52
52
|
func (noSelfCompare) Check(ctx *Context, node *shimast.Node) {
|
|
53
53
|
expr := node.AsBinaryExpression()
|
|
54
54
|
if expr == nil || expr.OperatorToken == nil {
|