@ttsc/lint 0.12.3 → 0.13.0

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 (74) hide show
  1. package/lib/defaultFormat.d.ts +10 -11
  2. package/lib/defaultFormat.js +10 -11
  3. package/lib/defaultFormat.js.map +1 -1
  4. package/lib/index.js +233 -135
  5. package/lib/index.js.map +1 -1
  6. package/lib/structures/ITtscLintConfig.d.ts +2 -2
  7. package/lib/structures/ITtscLintFormatConfig.d.ts +53 -55
  8. package/lib/structures/ITtscLintPluginConfig.d.ts +10 -77
  9. package/lib/structures/ITtscLintPluginMeta.d.ts +9 -1
  10. package/lib/structures/TtscLintRule.d.ts +10 -1
  11. package/lib/structures/TtscLintRuleMap.d.ts +2 -2
  12. package/lib/structures/TtscLintRuleOptions.d.ts +14 -0
  13. package/linthost/ast_helpers.go +80 -11
  14. package/linthost/compile.go +116 -112
  15. package/linthost/config.go +647 -687
  16. package/linthost/config_format.go +272 -247
  17. package/linthost/contrib_adapter.go +7 -0
  18. package/linthost/directives.go +116 -0
  19. package/linthost/dispatch.go +33 -33
  20. package/linthost/engine.go +156 -43
  21. package/linthost/fix.go +47 -27
  22. package/linthost/flags_gen.go +31 -0
  23. package/linthost/format.go +119 -3
  24. package/linthost/host.go +115 -5
  25. package/linthost/print_dispatch.go +128 -28
  26. package/linthost/print_doc.go +23 -0
  27. package/linthost/print_engine.go +168 -4
  28. package/linthost/print_nodes_array.go +17 -7
  29. package/linthost/print_nodes_call.go +138 -20
  30. package/linthost/print_nodes_function.go +353 -0
  31. package/linthost/print_nodes_imports.go +46 -29
  32. package/linthost/print_nodes_list.go +86 -5
  33. package/linthost/print_nodes_object.go +56 -11
  34. package/linthost/rules_arrays.go +5 -2
  35. package/linthost/rules_debugger.go +3 -2
  36. package/linthost/rules_dupes.go +7 -4
  37. package/linthost/rules_empty.go +3 -2
  38. package/linthost/rules_escape.go +35 -3
  39. package/linthost/rules_eval.go +3 -0
  40. package/linthost/rules_finally.go +11 -0
  41. package/linthost/rules_format_jsdoc.go +7 -0
  42. package/linthost/rules_format_print_width.go +270 -15
  43. package/linthost/rules_format_quotes.go +3 -0
  44. package/linthost/rules_format_sort_imports.go +4 -0
  45. package/linthost/rules_gap.go +75 -3
  46. package/linthost/rules_imports.go +5 -7
  47. package/linthost/rules_logic.go +75 -5
  48. package/linthost/rules_loops.go +4 -0
  49. package/linthost/rules_misc.go +4 -2
  50. package/linthost/rules_params.go +7 -11
  51. package/linthost/rules_problems.go +89 -22
  52. package/linthost/rules_promise.go +15 -0
  53. package/linthost/rules_protos.go +3 -2
  54. package/linthost/rules_self.go +6 -0
  55. package/linthost/rules_strings.go +10 -0
  56. package/linthost/rules_suggestions.go +174 -9
  57. package/linthost/rules_throw.go +2 -0
  58. package/linthost/rules_ts.go +13 -0
  59. package/linthost/rules_ts_extra.go +25 -8
  60. package/linthost/rules_var.go +15 -2
  61. package/package.json +3 -3
  62. package/plugin/main.go +4 -4
  63. package/rule/astutil/astutil.go +12 -0
  64. package/rule/rule.go +123 -123
  65. package/src/defaultFormat.ts +10 -11
  66. package/src/index.ts +257 -168
  67. package/src/structures/ITtscLintConfig.ts +2 -2
  68. package/src/structures/ITtscLintFormatConfig.ts +53 -55
  69. package/src/structures/ITtscLintPluginConfig.ts +10 -83
  70. package/src/structures/ITtscLintPluginMeta.ts +9 -1
  71. package/src/structures/TtscLintRule.ts +10 -1
  72. package/src/structures/TtscLintRuleMap.ts +17 -18
  73. package/src/structures/TtscLintRuleOptions.ts +15 -0
  74. package/linthost/eslint_runtime.go +0 -320
@@ -4,10 +4,10 @@ import type { TtscLintSeverity } from "./TtscLintSeverity";
4
4
  * Prettier-style flat configuration for the `format/*` rules.
5
5
  *
6
6
  * The `format` block is the recommended way to enable formatting in
7
- * `@ttsc/lint`. Each key mirrors a Prettier option of the same name —
8
- * users coming from a `.prettierrc` can copy their config almost
9
- * verbatim. The block is opt-in by presence: a `lint.config.ts` with no
10
- * `format` field keeps every format rule off, exactly as before.
7
+ * `@ttsc/lint`. Each key mirrors a Prettier option of the same name — users
8
+ * coming from a `.prettierrc` can copy their config almost verbatim. The block
9
+ * is opt-in by presence: a `lint.config.ts` with no `format` field keeps every
10
+ * format rule off, exactly as before.
11
11
  *
12
12
  * Once present, the block configures a curated set of format rules at
13
13
  * Prettier-aligned defaults. `ttsc format` uses these rules to rewrite source.
@@ -19,37 +19,37 @@ import type { TtscLintSeverity } from "./TtscLintSeverity";
19
19
  * import type { ITtscLintConfig } from "@ttsc/lint";
20
20
  *
21
21
  * export default {
22
- * rules: { "no-var": "error" },
23
- * format: {
24
- * severity: "warning",
25
- * printWidth: 100,
26
- * singleQuote: true,
27
- * importOrder: ["<THIRD_PARTY_MODULES>", "^[./]"],
28
- * },
22
+ * rules: { "no-var": "error" },
23
+ * format: {
24
+ * severity: "warning",
25
+ * printWidth: 100,
26
+ * singleQuote: true,
27
+ * importOrder: ["<THIRD_PARTY_MODULES>", "^[./]"],
28
+ * },
29
29
  * } satisfies ITtscLintConfig;
30
30
  *
31
- * Deviations from Prettier:
32
- * - `endOfLine` is restricted to `"lf"` and `"crlf"`. Prettier's
33
- * `"cr"` and `"auto"` modes are intentionally unsupported — the
34
- * printer does not auto-detect terminators.
35
- * - Many Prettier knobs (`bracketSpacing`, `arrowParens`,
36
- * `quoteProps`, JSX-specific switches) are not yet implemented.
31
+ * Deviations from Prettier:
32
+ * - `endOfLine` is restricted to `"lf"` and `"crlf"`. Prettier's
33
+ * `"cr"` and `"auto"` modes are intentionally unsupported — the
34
+ * printer does not auto-detect terminators.
35
+ * - Many Prettier knobs (`bracketSpacing`, `arrowParens`,
36
+ * `quoteProps`, JSX-specific switches) are not yet implemented.
37
37
  *
38
- * Rule enablement matrix (when the `format` block is present):
38
+ * Rule enablement matrix (when the `format` block is present):
39
39
  *
40
- * - `format/semi` — always on. `semi: false` flips it to `prefer:
41
- * "never"`.
42
- * - `format/quotes` — always on. `singleQuote: true` flips to
43
- * `prefer: "single"`.
44
- * - `format/trailing-comma` — always on. `trailingComma: "none"`
45
- * disables the rule's edits without removing the surface.
46
- * - `format/print-width` — always on, driven by `printWidth`,
47
- * `tabWidth`, `useTabs`, `endOfLine`.
48
- * - `format/sort-imports` — opt-in. Setting `importOrder` enables it.
49
- * - `format/jsdoc` — opt-in. Setting `jsdoc` enables it.
40
+ * - `format/semi` — always on. `semi: false` flips it to `prefer:
41
+ * "never"`.
42
+ * - `format/quotes` — always on. `singleQuote: true` flips to
43
+ * `prefer: "single"`.
44
+ * - `format/trailing-comma` — always on. `trailingComma: "none"`
45
+ * disables the rule's edits without removing the surface.
46
+ * - `format/print-width` — always on, driven by `printWidth`,
47
+ * `tabWidth`, `useTabs`, `endOfLine`.
48
+ * - `format/sort-imports` — opt-in. Setting `importOrder` enables it.
49
+ * - `format/jsdoc` — opt-in. Setting `jsdoc` enables it.
50
50
  *
51
- * Format findings produced from this block are off by default. Set `severity`
52
- * only when a project intentionally wants check-time format diagnostics.
51
+ * Format findings produced from this block are off by default. Set `severity`
52
+ * only when a project intentionally wants check-time format diagnostics.
53
53
  */
54
54
  export interface ITtscLintFormatConfig {
55
55
  /**
@@ -64,33 +64,33 @@ export interface ITtscLintFormatConfig {
64
64
  severity?: TtscLintSeverity;
65
65
 
66
66
  /**
67
- * Insert trailing semicolons on ASI-terminated statements. Mirrors
68
- * Prettier's `semi`. `false` flips the rule to require *no*
69
- * trailing semicolon (rare; matches prettier's `semi: false`).
67
+ * Insert trailing semicolons on ASI-terminated statements. Mirrors Prettier's
68
+ * `semi`. `false` flips the rule to require _no_ trailing semicolon (rare;
69
+ * matches prettier's `semi: false`).
70
70
  *
71
71
  * @default true
72
72
  */
73
73
  semi?: boolean;
74
74
 
75
75
  /**
76
- * Prefer single-quoted strings. Mirrors Prettier's `singleQuote`.
77
- * `false` means double quotes (Prettier's default).
76
+ * Prefer single-quoted strings. Mirrors Prettier's `singleQuote`. `false`
77
+ * means double quotes (Prettier's default).
78
78
  *
79
79
  * @default false
80
80
  */
81
81
  singleQuote?: boolean;
82
82
 
83
83
  /**
84
- * Trailing-comma policy. Mirrors Prettier's `trailingComma`. The
85
- * `"none"` mode disables the rule's edits.
84
+ * Trailing-comma policy. Mirrors Prettier's `trailingComma`. The `"none"`
85
+ * mode disables the rule's edits.
86
86
  *
87
87
  * @default "all"
88
88
  */
89
89
  trailingComma?: "all" | "es5" | "none";
90
90
 
91
91
  /**
92
- * Maximum column width before broken-form layout is chosen.
93
- * Mirrors Prettier's `printWidth`.
92
+ * Maximum column width before broken-form layout is chosen. Mirrors
93
+ * Prettier's `printWidth`.
94
94
  *
95
95
  * @default 80
96
96
  */
@@ -111,20 +111,19 @@ export interface ITtscLintFormatConfig {
111
111
  useTabs?: boolean;
112
112
 
113
113
  /**
114
- * Line terminator the printer emits on reflow. `@ttsc/lint`
115
- * supports `"lf"` and `"crlf"`. Prettier's `"cr"` and `"auto"` are
116
- * intentionally unsupported because the printer does not
117
- * auto-detect line endings.
114
+ * Line terminator the printer emits on reflow. `@ttsc/lint` supports `"lf"`
115
+ * and `"crlf"`. Prettier's `"cr"` and `"auto"` are intentionally unsupported
116
+ * because the printer does not auto-detect line endings.
118
117
  *
119
118
  * @default "lf"
120
119
  */
121
120
  endOfLine?: "lf" | "crlf";
122
121
 
123
122
  /**
124
- * Group order for `format/sort-imports`. Setting this enables the
125
- * rule; mirrors `@trivago/prettier-plugin-sort-imports`'
126
- * `importOrder`. The `<THIRD_PARTY_MODULES>` literal is the
127
- * catch-all placeholder for specifiers that match no other group.
123
+ * Group order for `format/sort-imports`. Setting this enables the rule;
124
+ * mirrors `@trivago/prettier-plugin-sort-imports`' `importOrder`. The
125
+ * `<THIRD_PARTY_MODULES>` literal is the catch-all placeholder for specifiers
126
+ * that match no other group.
128
127
  */
129
128
  importOrder?: readonly ("<THIRD_PARTY_MODULES>" | (string & {}))[];
130
129
 
@@ -136,8 +135,7 @@ export interface ITtscLintFormatConfig {
136
135
  importOrderSeparation?: boolean;
137
136
 
138
137
  /**
139
- * Sort named import specifiers alphabetically within each
140
- * declaration.
138
+ * Sort named import specifiers alphabetically within each declaration.
141
139
  *
142
140
  * @default true
143
141
  */
@@ -151,13 +149,13 @@ export interface ITtscLintFormatConfig {
151
149
  importOrderCaseInsensitive?: boolean;
152
150
 
153
151
  /**
154
- * Enable `format/jsdoc`. Pass `true` to turn it on with built-in
155
- * defaults, or an object to customize:
152
+ * Enable `format/jsdoc`. Pass `true` to turn it on with built-in defaults, or
153
+ * an object to customize:
156
154
  *
157
- * - `tagSynonyms` — extra `from → to` rewrites layered on the
158
- * built-in synonym table.
159
- * - `sortTags` — sort JSDoc tags into canonical order (reserved;
160
- * today's MVP only rewrites tag names).
155
+ * - `tagSynonyms` — extra `from → to` rewrites layered on the built-in synonym
156
+ * table.
157
+ * - `sortTags` — sort JSDoc tags into canonical order (reserved; today's MVP
158
+ * only rewrites tag names).
161
159
  *
162
160
  * @default false (off)
163
161
  */
@@ -1,6 +1,3 @@
1
- import type { ITtscLintFormatConfig } from "./ITtscLintFormatConfig";
2
- import type { TtscLintRuleMap } from "./TtscLintRuleMap";
3
-
4
1
  /** `compilerOptions.plugins[]` entry shape consumed by `@ttsc/lint`. */
5
2
  export interface ITtscLintPluginConfig {
6
3
  /** Set to `false` to keep the entry while disabling this plugin. */
@@ -10,94 +7,24 @@ export interface ITtscLintPluginConfig {
10
7
  transform?: string;
11
8
 
12
9
  /**
13
- * Inline rule severity map applied to the project.
14
- *
15
- * Mirrors the `rules` field of an ESLint flat-config entry. When set, the
16
- * sidecar uses this map directly and does NOT consult any `lint.config.*`
17
- * file (use `extends` for that). Combine with `plugins` to register
18
- * contributor rule namespaces in the same entry.
19
- *
20
- * ```jsonc
21
- * {
22
- * "transform": "@ttsc/lint",
23
- * "rules": { "no-var": "error", "prefer-const": "warning" }
24
- * }
25
- * ```
26
- */
27
- rules?: TtscLintRuleMap;
28
-
29
- /**
30
- * Path to a standalone lint config file whose rules should be applied to this
31
- * project. Relative paths are resolved from the tsconfig directory. Accepts
32
- * the usual `lint.config.*` / `ttsc-lint.config.*` / `eslint.config.*`
33
- * extensions.
34
- *
35
- * Mirrors the `extends` field of an ESLint flat-config entry — "inherit this
36
- * file's configuration".
37
- *
38
- * ```jsonc
39
- * {
40
- * "transform": "@ttsc/lint",
41
- * "extends": "./lint.config.ts"
42
- * }
43
- * ```
44
- *
45
- * `rules` and `extends` are mutually exclusive on a single plugin entry; the
46
- * sidecar surfaces a loud error when both are set.
47
- */
48
- extends?: string;
49
-
50
- /**
51
- * Contributor lint plugins to compile into the `@ttsc/lint` binary.
10
+ * Path to the lint config file, overriding auto-discovery.
52
11
  *
53
- * Each entry maps a namespace (rule-name prefix) to an npm specifier or
54
- * relative path. The factory resolves the package, reads its exported
55
- * `ITtscLintPlugin` descriptor, and forwards the Go source directory to
56
- * ttsc's plugin builder via the `contributors` field.
12
+ * Relative paths are resolved from the tsconfig directory; absolute paths are
13
+ * used as-is. Accepts the usual `lint.config.*` / `ttsc-lint.config.*`
14
+ * extensions (`.ts`, `.cts`, `.mts`, `.js`, `.cjs`, `.mjs`, `.json`).
57
15
  *
58
- * ```jsonc
59
- * {
60
- * "transform": "@ttsc/lint",
61
- * "plugins": { "demo": "ttsc-lint-plugin-demo" },
62
- * "rules": { "demo/no-todo-comment": "error" }
63
- * }
64
- * ```
65
- */
66
- plugins?: Record<string, string>;
67
-
68
- /**
69
- * Prettier-style flat configuration for the `format/*` rules. Sibling of
70
- * `rules`. See {@link ITtscLintFormatConfig} for the full surface.
16
+ * When omitted, `@ttsc/lint` discovers a `lint.config.*` /
17
+ * `ttsc-lint.config.*` file by walking upward from the tsconfig directory.
71
18
  *
72
19
  * ```jsonc
73
20
  * {
74
21
  * "transform": "@ttsc/lint",
75
- * "format": { "printWidth": 100, "singleQuote": true }
22
+ * "configFile": "./lint.config.ts"
76
23
  * }
77
24
  * ```
78
25
  *
79
- * Combines with `rules` (per-rule overrides win on collision). Cannot be
80
- * combined with `extends` on the same plugin entry put format options
81
- * inside the extends-target lint.config.ts instead.
26
+ * Every rule, format, and plugin setting lives in the config file — the
27
+ * tsconfig plugin entry carries nothing but this pointer.
82
28
  */
83
- format?: ITtscLintFormatConfig;
84
-
85
- /**
86
- * Inline rule map or path to a standalone lint config file.
87
- *
88
- * @deprecated Use `rules` for inline severity maps or `extends` for a config
89
- * file path. The sidecar maps a legacy `config` entry onto the appropriate
90
- * new field and emits a one-time stderr deprecation notice. Removed in a
91
- * future minor.
92
- *
93
- * The legacy shape is intentionally narrower than `rules`/`extends`: a string
94
- * (file path) or a flat rule-name → severity map. The Go-side parser only
95
- * accepts those two shapes; widening the TS type to the full config object
96
- * would silently let unsupported nested shapes pass type-checking and fail
97
- * at runtime.
98
- */
99
- config?: string | TtscLintRuleMap;
100
-
101
- /** Extra plugin-owned fields are passed through unchanged. */
102
- [key: string]: unknown;
29
+ configFile?: string;
103
30
  }
@@ -1,4 +1,12 @@
1
- /** Plugin-level metadata shared with the diagnostic surface. */
1
+ /**
2
+ * Plugin-level metadata exposed on `ITtscLintPlugin.meta`.
3
+ *
4
+ * All fields are optional. When `namespace` is absent, `@ttsc/lint` falls back
5
+ * to the key used in the tsconfig `plugins` map (or `lint.config.*` `plugins`
6
+ * object) as the rule-name prefix. `name` and `version` are purely
7
+ * informational — they appear in diagnostic messages and are not validated at
8
+ * build time.
9
+ */
2
10
  export interface ITtscLintPluginMeta {
3
11
  /** Plugin package name as published on npm. */
4
12
  name?: string;
@@ -1,9 +1,18 @@
1
1
  /**
2
- * Lint rule names understood by the `@ttsc/lint` native sidecar.
2
+ * Union of every built-in lint rule name understood by the `@ttsc/lint` native
3
+ * sidecar.
3
4
  *
4
5
  * These names intentionally mirror familiar ESLint / TypeScript-ESLint rule
5
6
  * names so a `compilerOptions.plugins[]` entry can configure native linting
6
7
  * without introducing a separate lint config file.
8
+ *
9
+ * The `format/*` members at the bottom of the union are applied by `ttsc
10
+ * format`; their severity also controls whether `ttsc check` surfaces
11
+ * unformatted code as a diagnostic.
12
+ *
13
+ * This type is used as the key constraint in `TtscLintRuleMap` for rules that
14
+ * carry no per-rule options. Rules with typed option objects are additionally
15
+ * listed in `ITtscLintRuleOptionsMap`.
7
16
  */
8
17
  export type TtscLintRule =
9
18
  | "adjacent-overload-signatures"
@@ -11,8 +11,8 @@ import type { TtscLintSeverity } from "./TtscLintSeverity";
11
11
  * `[severity, options]`, with the options type picked per rule key.
12
12
  * - Every other built-in rule accepts `severity` or `[severity]`.
13
13
  * - Namespaced contributor plugin rules accept `severity`, `[severity]`, or
14
- * `[severity, unknownOptions]` because the host type surface no longer
15
- * knows contributor rule schemas.
14
+ * `[severity, unknownOptions]` because the host type surface no longer knows
15
+ * contributor rule schemas.
16
16
  *
17
17
  * Splitting the two halves (instead of folding them into one mapped type with a
18
18
  * conditional value) keeps TypeScript's contextual typing intact inside the
@@ -38,19 +38,18 @@ import type { TtscLintSeverity } from "./TtscLintSeverity";
38
38
  * splits each negative case into its own const to keep every branch
39
39
  * load-bearing.
40
40
  */
41
- export type TtscLintRuleMap =
42
- {
43
- [K in keyof ITtscLintRuleOptionsMap]?:
44
- | TtscLintSeverity
45
- | readonly [TtscLintSeverity]
46
- | readonly [TtscLintSeverity, ITtscLintRuleOptionsMap[K]];
47
- } & {
48
- [K in Exclude<TtscLintRule, keyof ITtscLintRuleOptionsMap>]?:
49
- | TtscLintSeverity
50
- | readonly [TtscLintSeverity];
51
- } & {
52
- [K in `${string}/${string}`]?:
53
- | TtscLintSeverity
54
- | readonly [TtscLintSeverity]
55
- | readonly [TtscLintSeverity, unknown];
56
- };
41
+ export type TtscLintRuleMap = {
42
+ [K in keyof ITtscLintRuleOptionsMap]?:
43
+ | TtscLintSeverity
44
+ | readonly [TtscLintSeverity]
45
+ | readonly [TtscLintSeverity, ITtscLintRuleOptionsMap[K]];
46
+ } & {
47
+ [K in Exclude<TtscLintRule, keyof ITtscLintRuleOptionsMap>]?:
48
+ | TtscLintSeverity
49
+ | readonly [TtscLintSeverity];
50
+ } & {
51
+ [K in `${string}/${string}`]?:
52
+ | TtscLintSeverity
53
+ | readonly [TtscLintSeverity]
54
+ | readonly [TtscLintSeverity, unknown];
55
+ };
@@ -99,6 +99,21 @@ export interface ITtscLintPrintWidthRuleOptions {
99
99
  * @default "lf"
100
100
  */
101
101
  endOfLine?: "lf" | "crlf";
102
+
103
+ /**
104
+ * Trailing-comma policy the reflow honors when it breaks a list across
105
+ * lines. Mirrors prettier's `trailingComma` and must match the
106
+ * `format/trailing-comma` rule's `mode`; otherwise the two rules
107
+ * disagree on every cascade pass and oscillate against each other.
108
+ *
109
+ * When a `format` block is configured, `format.trailingComma` is mirrored
110
+ * into this option automatically. Set it directly only when overriding
111
+ * the print-width rule via a `rules` tuple — see the conflict-resolution
112
+ * notes in the README.
113
+ *
114
+ * @default "all"
115
+ */
116
+ trailingComma?: "all" | "es5" | "none";
102
117
  }
103
118
 
104
119
  /** `format/jsdoc` rule options. */