@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.
Files changed (28) hide show
  1. package/{go-plugin/go.mod → go.mod} +3 -3
  2. package/package.json +6 -7
  3. package/{go-plugin/lint → plugin}/ast_helpers.go +1 -1
  4. package/{go-plugin/lint → plugin}/compile.go +1 -1
  5. package/{go-plugin/lint → plugin}/config.go +1 -1
  6. package/{go-plugin/lint → plugin}/engine.go +6 -6
  7. package/{go-plugin/lint → plugin}/host.go +1 -1
  8. package/{go-plugin → plugin}/main.go +3 -5
  9. package/{go-plugin/lint → plugin}/rules_arrays.go +5 -3
  10. package/{go-plugin/lint → plugin}/rules_console.go +3 -3
  11. package/{go-plugin/lint → plugin}/rules_debugger.go +5 -5
  12. package/{go-plugin/lint → plugin}/rules_dupes.go +5 -5
  13. package/{go-plugin/lint → plugin}/rules_empty.go +4 -4
  14. package/{go-plugin/lint → plugin}/rules_eval.go +7 -5
  15. package/{go-plugin/lint → plugin}/rules_finally.go +3 -3
  16. package/{go-plugin/lint → plugin}/rules_logic.go +11 -11
  17. package/{go-plugin/lint → plugin}/rules_loops.go +3 -3
  18. package/{go-plugin/lint → plugin}/rules_misc.go +5 -5
  19. package/{go-plugin/lint → plugin}/rules_problems.go +41 -29
  20. package/{go-plugin/lint → plugin}/rules_protos.go +7 -5
  21. package/{go-plugin/lint → plugin}/rules_self.go +5 -5
  22. package/{go-plugin/lint → plugin}/rules_strings.go +11 -9
  23. package/{go-plugin/lint → plugin}/rules_suggestions.go +83 -61
  24. package/{go-plugin/lint → plugin}/rules_throw.go +3 -3
  25. package/{go-plugin/lint → plugin}/rules_ts.go +29 -19
  26. package/{go-plugin/lint → plugin}/rules_ts_extra.go +57 -35
  27. package/{go-plugin/lint → plugin}/rules_var.go +3 -3
  28. package/{index.cjs → src/index.cjs} +3 -2
@@ -1,11 +1,11 @@
1
- module github.com/samchon/ttsc/packages/lint/go-plugin
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 ./lint/host.go to avoid a transitive dependency on the
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-20260424234512-515d036f927a // indirect
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-plugin/go.mod",
21
- "go-plugin/main.go",
22
- "go-plugin/lint"
19
+ "src/index.cjs",
20
+ "go.mod",
21
+ "plugin"
23
22
  ],
24
23
  "repository": {
25
24
  "type": "git",
@@ -1,4 +1,4 @@
1
- package lint
1
+ package main
2
2
 
3
3
  import (
4
4
  "strings"
@@ -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 lint
12
+ package main
13
13
 
14
14
  import (
15
15
  "context"
@@ -1,4 +1,4 @@
1
- package lint
1
+ package main
2
2
 
3
3
  import (
4
4
  "encoding/json"
@@ -1,4 +1,4 @@
1
- // Package lint hosts the rule registry, the AST-walking engine, and the
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 lint
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 RuleConfig
150
- rules map[shimast.Kind][]Rule
151
- enabled map[string]Severity
152
- unknown []string
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 lint
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 lint.RunCheck(args[1:])
39
+ return RunCheck(args[1:])
42
40
  case "build":
43
- return lint.RunBuild(args[1:])
41
+ return RunBuild(args[1:])
44
42
  case "transform":
45
- return lint.RunTransform(args[1:])
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 lint
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 { return "no-sparse-arrays" }
11
- func (noSparseArrays) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindArrayLiteralExpression} }
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 lint
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 { return "no-console" }
12
- func (noConsole) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindCallExpression} }
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 lint
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 { return "no-debugger" }
10
- func (noDebugger) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindDebuggerStatement} }
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 { return "no-with" }
21
- func (noWith) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindWithStatement} }
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 lint
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 { return "no-duplicate-case" }
10
- func (noDuplicateCase) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindSwitchStatement} }
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 { return "no-dupe-keys" }
46
- func (noDupeKeys) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindObjectLiteralExpression} }
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 lint
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 { return "no-empty" }
11
- func (noEmpty) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBlock} }
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 { return "no-empty-function" }
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 lint
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 { return "no-eval" }
12
- func (noEval) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindCallExpression} }
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 { return "no-script-url" }
29
- func (noScriptURL) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindStringLiteral, shimast.KindNoSubstitutionTemplateLiteral} }
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 lint
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 { return "no-useless-catch" }
80
- func (noUselessCatch) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindCatchClause} }
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 lint
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 { return "no-unsafe-negation" }
87
- func (noUnsafeNegation) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBinaryExpression} }
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 { return "eqeqeq" }
114
- func (eqeqeq) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBinaryExpression} }
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 { return "use-isnan" }
133
- func (useIsnan) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBinaryExpression} }
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 { return "valid-typeof" }
153
- func (validTypeof) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBinaryExpression} }
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 { return "no-compare-neg-zero" }
198
- func (noCompareNegZero) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBinaryExpression} }
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 lint
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 { return "for-direction" }
10
- func (forDirection) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindForStatement} }
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 lint
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 { return "radix" }
11
- func (radix) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindCallExpression} }
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 { return "no-new-wrappers" }
54
- func (noNewWrappers) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindNewExpression} }
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 lint
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 { return "no-dupe-else-if" }
21
- func (noDupeElseIf) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindIfStatement} }
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 { return "no-ex-assign" }
57
- func (noExAssign) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindCatchClause} }
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 { return "no-empty-character-class" }
103
- func (noEmptyCharacterClass) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindRegularExpressionLiteral} }
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 { return "no-misleading-character-class" }
134
- func (noMisleadingCharacterClass) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindRegularExpressionLiteral} }
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 { return "no-loss-of-precision" }
176
- func (noLossOfPrecision) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindNumericLiteral} }
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 { return "no-class-assign" }
218
- func (noClassAssign) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindClassDeclaration} }
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 { return "no-func-assign" }
237
- func (noFuncAssign) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindFunctionDeclaration} }
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 { return "no-prototype-builtins" }
257
- func (noPrototypeBuiltins) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindCallExpression} }
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 { return "no-async-promise-executor" }
281
- func (noAsyncPromiseExecutor) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindNewExpression} }
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 { return "no-promise-executor-return" }
307
- func (noPromiseExecutorReturn) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindNewExpression} }
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 { return "no-control-regex" }
336
- func (noControlRegex) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindRegularExpressionLiteral} }
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 { return "no-irregular-whitespace" }
392
- func (noIrregularWhitespace) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindSourceFile} }
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 { return "no-fallthrough" }
425
- func (noFallthrough) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindSwitchStatement} }
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 { return "no-obj-calls" }
523
- func (noObjCalls) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindCallExpression, shimast.KindNewExpression} }
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 lint
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 { return "no-iterator" }
11
- func (noIterator) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindPropertyAccessExpression} }
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 { return "no-proto" }
28
- func (noProto) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindPropertyAccessExpression} }
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 lint
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 { return "no-self-assign" }
12
- func (noSelfAssign) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBinaryExpression} }
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 { return "no-self-compare" }
51
- func (noSelfCompare) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBinaryExpression} }
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 {