@ttsc/lint 0.28.6 → 0.30.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.
package/README.md CHANGED
@@ -1185,6 +1185,8 @@ func init() { rule.RegisterProject(noCycles{}) }
1185
1185
 
1186
1186
  Each project rule runs once per loaded Program, before file rules. `ctx.Identity` includes the invocation cwd, logical and physical config paths and roots, an optional explicit project root, the plugin-config origin, and a lifecycle id. `Report` marks the rule failed and emits one project finding; `Fail` marks it failed without a finding. Later file rules can call `ctx.ProjectResult(name)` and distinguish `absent`, `off`, `not_evaluated`, `passed`, and `failed`.
1187
1187
 
1188
+ `ctx.ReportSeverity(rule.SeverityWarn, message)` overrides the level of one project finding. An off rule or off finding remains silent. A warning still marks the project result failed, while only an error fails the command. Snapshots retain each finding's severity, and duplicate messages keep the strongest reported level. Hosts implementing only `ProjectReporter` receive the message at the rule's configured level; `ProjectSeverityReporter` is the optional extension for individual levels.
1189
+
1188
1190
  When a project rule reads local files outside the TypeScript Program, implement `rule.ProjectInputRule` so watch and editor hosts can observe exactly those inputs:
1189
1191
 
1190
1192
  ```go
@@ -50,7 +50,8 @@ type projectReporter struct {
50
50
  mu sync.Mutex
51
51
  active bool
52
52
  failed bool
53
- messages map[string]struct{}
53
+ messages map[string]publicrule.Severity
54
+ severity publicrule.Severity
54
55
  state any
55
56
  }
56
57
 
@@ -66,19 +67,27 @@ func (r *projectReporter) Fail() {
66
67
  }
67
68
 
68
69
  func (r *projectReporter) Report(message string) {
70
+ if r != nil {
71
+ r.ReportSeverity(r.severity, message)
72
+ }
73
+ }
74
+
75
+ func (r *projectReporter) ReportSeverity(severity publicrule.Severity, message string) {
69
76
  if r == nil {
70
77
  return
71
78
  }
72
79
  r.mu.Lock()
73
80
  defer r.mu.Unlock()
74
- if !r.active {
81
+ if !r.active || severity == publicrule.SeverityOff {
75
82
  return
76
83
  }
77
84
  r.failed = true
78
85
  if r.messages == nil {
79
- r.messages = map[string]struct{}{}
86
+ r.messages = map[string]publicrule.Severity{}
87
+ }
88
+ if severity > r.messages[message] {
89
+ r.messages[message] = severity
80
90
  }
81
- r.messages[message] = struct{}{}
82
91
  }
83
92
 
84
93
  func (r *projectReporter) SetState(state any) {
@@ -120,7 +129,7 @@ func (r *projectReporter) snapshotLocked(close bool) publicrule.ProjectRuleResul
120
129
  }
121
130
  findings := make([]publicrule.ProjectFinding, 0, len(messages))
122
131
  for _, message := range messages {
123
- findings = append(findings, publicrule.ProjectFinding{Message: message})
132
+ findings = append(findings, publicrule.ProjectFinding{Message: message, Severity: r.messages[message]})
124
133
  }
125
134
  return publicrule.NewProjectRuleResult(status, r.state, findings, r)
126
135
  }
@@ -144,7 +153,7 @@ func (c *projectCycle) finalize() []*Finding {
144
153
  for _, finding := range result.Findings {
145
154
  c.findings = append(c.findings, &Finding{
146
155
  Rule: name,
147
- Severity: entry.severity,
156
+ Severity: Severity(finding.Severity),
148
157
  Message: finding.Message,
149
158
  })
150
159
  }
@@ -193,7 +202,7 @@ func (e *Engine) evaluateProject(
193
202
  if adapter.declinesTypeChecker {
194
203
  ruleChecker = nil
195
204
  }
196
- reporter := &projectReporter{active: true}
205
+ reporter := &projectReporter{active: true, severity: publicrule.Severity(setting.Severity)}
197
206
  context := publicrule.NewProjectContext(
198
207
  identity,
199
208
  sources,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttsc/lint",
3
- "version": "0.28.6",
3
+ "version": "0.30.0",
4
4
  "description": "Reference ttsc plugin: ESLint-style lint rules over the TypeScript-Go Program used by the type-check pass.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -37,7 +37,7 @@
37
37
  "@types/node": "^25.3.0",
38
38
  "rimraf": "^6.1.2",
39
39
  "typescript": "^7.0.2",
40
- "ttsc": "0.28.6"
40
+ "ttsc": "0.30.0"
41
41
  },
42
42
  "repository": {
43
43
  "type": "git",
package/rule/project.go CHANGED
@@ -36,7 +36,8 @@ const (
36
36
  // ProjectFinding is a non-file finding retained in a project rule's cycle
37
37
  // result. Project findings never contain edits or source ranges.
38
38
  type ProjectFinding struct {
39
- Message string
39
+ Message string
40
+ Severity Severity
40
41
  }
41
42
 
42
43
  // ProjectRuleResult is one snapshot of a named project rule in the current
@@ -169,6 +170,13 @@ type ProjectReporter interface {
169
170
  Report(message string)
170
171
  }
171
172
 
173
+ // ProjectSeverityReporter optionally accepts a severity for each finding.
174
+ // Reporting still marks the rule failed, including for warnings, so consumers
175
+ // cannot treat an incomplete project result as a clean one.
176
+ type ProjectSeverityReporter interface {
177
+ ReportSeverity(severity Severity, message string)
178
+ }
179
+
172
180
  // ProjectContext contains the immutable inputs for one project-rule check.
173
181
  //
174
182
  // Sources is a defensive copy of the user sources the host read for this cycle:
@@ -256,6 +264,19 @@ func (c *ProjectContext) Report(message string) {
256
264
  c.reporter.Report(message)
257
265
  }
258
266
 
267
+ // ReportSeverity records a finding at an explicit level. An off rule or off
268
+ // finding remains silent. Hosts without this extension use the rule's level.
269
+ func (c *ProjectContext) ReportSeverity(severity Severity, message string) {
270
+ if c == nil || c.reporter == nil || c.Severity == SeverityOff || severity == SeverityOff {
271
+ return
272
+ }
273
+ if reporter, ok := c.reporter.(ProjectSeverityReporter); ok {
274
+ reporter.ReportSeverity(severity, message)
275
+ } else {
276
+ c.reporter.Report(message)
277
+ }
278
+ }
279
+
259
280
  var projectRegistry []ProjectRule
260
281
 
261
282
  // RegisterProject adds a contributor project rule to the global registry.