@utoo/lint 0.2.7 → 0.2.8
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 +18 -0
- package/index.cjs +107 -6
- package/index.d.ts +9 -1
- package/index.js +107 -6
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -67,6 +67,24 @@ when a rule or a particular code shape cannot be fixed safely. The current
|
|
|
67
67
|
[rule status](https://github.com/fireairforce/utoo-lint/blob/main/docs/rule-status.md)
|
|
68
68
|
lists autofix coverage by rule.
|
|
69
69
|
|
|
70
|
+
## Suppression comments
|
|
71
|
+
|
|
72
|
+
Suppress a rule for the next line of code with `utlint-ignore`:
|
|
73
|
+
|
|
74
|
+
```js
|
|
75
|
+
// utlint-ignore no-debugger: generated breakpoint
|
|
76
|
+
debugger;
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Omit the rule ID to suppress all lint rules for the next line of code. Use
|
|
80
|
+
`utlint-ignore-all` before any code for a file-level suppression, or matching
|
|
81
|
+
`utlint-ignore-start` and `utlint-ignore-end` comments for a range. Line and
|
|
82
|
+
block comments are supported. Parse errors remain visible, and fixes from
|
|
83
|
+
suppressed diagnostics are not applied.
|
|
84
|
+
|
|
85
|
+
Native reports expose suppressed items in `suppressedDiagnostics`; the ESLint
|
|
86
|
+
compatibility API exposes them in `suppressedMessages`.
|
|
87
|
+
|
|
70
88
|
## Configuration
|
|
71
89
|
|
|
72
90
|
`utoo-lint` supports two canonical project config formats:
|
package/index.cjs
CHANGED
|
@@ -514,7 +514,7 @@ class UtooLint {
|
|
|
514
514
|
const results = reportToESLintResults(report, {
|
|
515
515
|
source: code,
|
|
516
516
|
filePath,
|
|
517
|
-
includeEmptyTextResult: report.files !== 0 || (report.diagnostics?.length ?? 0) > 0,
|
|
517
|
+
includeEmptyTextResult: report.files !== 0 || (report.diagnostics?.length ?? 0) > 0 || (report.suppressedDiagnostics?.length ?? 0) > 0,
|
|
518
518
|
ruleSeverityForFile: (filePath) => ruleSeverityMapForOptions(nativeOptions, filePath)
|
|
519
519
|
});
|
|
520
520
|
if (report.files !== 0) {
|
|
@@ -641,7 +641,7 @@ class CLIEngine {
|
|
|
641
641
|
const results = maybeFilterQuietResults(reportToESLintResults(report, {
|
|
642
642
|
source: code,
|
|
643
643
|
filePath: normalizeESLintFilePath(filePath, mergedOptions.cwd),
|
|
644
|
-
includeEmptyTextResult: report.files !== 0 || (report.diagnostics?.length ?? 0) > 0,
|
|
644
|
+
includeEmptyTextResult: report.files !== 0 || (report.diagnostics?.length ?? 0) > 0 || (report.suppressedDiagnostics?.length ?? 0) > 0,
|
|
645
645
|
ruleSeverityForFile: (filePath) => ruleSeverityMapForOptions(mergedOptions, filePath)
|
|
646
646
|
}), mergedOptions);
|
|
647
647
|
return resultsToCLIEngineReport(results);
|
|
@@ -842,6 +842,7 @@ function publicCliReport(report) {
|
|
|
842
842
|
files: report.files ?? 0,
|
|
843
843
|
filePaths: report.filePaths ?? [],
|
|
844
844
|
diagnostics: report.diagnostics ?? [],
|
|
845
|
+
suppressedDiagnostics: report.suppressedDiagnostics ?? [],
|
|
845
846
|
outputs: report.outputs ?? []
|
|
846
847
|
};
|
|
847
848
|
}
|
|
@@ -1140,7 +1141,7 @@ function lintFiles(paths, options = {}) {
|
|
|
1140
1141
|
const ignoredDiagnostics = ignoredLintPathDiagnostics(targets, options);
|
|
1141
1142
|
const lintPaths = filteredLintPaths(targets, options);
|
|
1142
1143
|
if (lintPaths.length === 0) {
|
|
1143
|
-
return { files: 0, filePaths: [], diagnostics: ignoredDiagnostics, exitCode: exitCodeForDiagnostics(ignoredDiagnostics) };
|
|
1144
|
+
return { files: 0, filePaths: [], diagnostics: ignoredDiagnostics, suppressedDiagnostics: [], exitCode: exitCodeForDiagnostics(ignoredDiagnostics) };
|
|
1144
1145
|
}
|
|
1145
1146
|
|
|
1146
1147
|
const configRuns = nativeConfigRunsForFiles(expandNativeConfigRunPaths(lintPaths, options), options);
|
|
@@ -1205,8 +1206,10 @@ function finalizeLintReport(report, ignoredDiagnostics, options) {
|
|
|
1205
1206
|
if (!options.deferDiagnosticConfigFiltering) {
|
|
1206
1207
|
report.filePaths = normalizeReportFilePaths(report.filePaths, options);
|
|
1207
1208
|
report.diagnostics = normalizeDiagnosticFilePaths(report.diagnostics, options);
|
|
1209
|
+
report.suppressedDiagnostics = normalizeDiagnosticFilePaths(report.suppressedDiagnostics, options);
|
|
1208
1210
|
report.outputs = normalizeReportOutputs(report.outputs, options);
|
|
1209
1211
|
report.diagnostics = normalizeReportDiagnostics(report.diagnostics, options);
|
|
1212
|
+
report.suppressedDiagnostics = normalizeReportDiagnostics(report.suppressedDiagnostics, options);
|
|
1210
1213
|
report.exitCode = exitCodeForDiagnostics(report.diagnostics);
|
|
1211
1214
|
}
|
|
1212
1215
|
return report;
|
|
@@ -1303,6 +1306,7 @@ function mergeNativeReports(reports) {
|
|
|
1303
1306
|
files: reports.reduce((count, item) => count + (item.files ?? 0), 0),
|
|
1304
1307
|
filePaths: reports.flatMap((item) => item.filePaths ?? []),
|
|
1305
1308
|
diagnostics: reports.flatMap((item) => item.diagnostics ?? []),
|
|
1309
|
+
suppressedDiagnostics: reports.flatMap((item) => item.suppressedDiagnostics ?? []),
|
|
1306
1310
|
outputs: reports.flatMap((item) => item.outputs ?? []),
|
|
1307
1311
|
exitCode: reports.some((item) => item.exitCode) ? 1 : 0
|
|
1308
1312
|
};
|
|
@@ -1335,6 +1339,7 @@ function lintText(code, options = {}) {
|
|
|
1335
1339
|
files: 0,
|
|
1336
1340
|
filePaths: [],
|
|
1337
1341
|
diagnostics,
|
|
1342
|
+
suppressedDiagnostics: [],
|
|
1338
1343
|
exitCode: exitCodeForDiagnostics(diagnostics)
|
|
1339
1344
|
};
|
|
1340
1345
|
}
|
|
@@ -1356,7 +1361,12 @@ function lintText(code, options = {}) {
|
|
|
1356
1361
|
...diagnostic,
|
|
1357
1362
|
filePath: requestedPath
|
|
1358
1363
|
}));
|
|
1364
|
+
report.suppressedDiagnostics = (report.suppressedDiagnostics ?? []).map((diagnostic) => ({
|
|
1365
|
+
...diagnostic,
|
|
1366
|
+
filePath: requestedPath
|
|
1367
|
+
}));
|
|
1359
1368
|
report.diagnostics = normalizeReportDiagnostics(report.diagnostics, options);
|
|
1369
|
+
report.suppressedDiagnostics = normalizeReportDiagnostics(report.suppressedDiagnostics, options);
|
|
1360
1370
|
report.exitCode = exitCodeForDiagnostics(report.diagnostics);
|
|
1361
1371
|
return report;
|
|
1362
1372
|
} finally {
|
|
@@ -1888,7 +1898,10 @@ class Linter {
|
|
|
1888
1898
|
config: calculatedConfig({ cwd: verifyOptions.cwd, noConfig: true, overrideConfig: config }, normalizedFilePath)
|
|
1889
1899
|
});
|
|
1890
1900
|
const customRuleFilter = applyDisableDirectives(customRuleMessages, sourceCode);
|
|
1891
|
-
this.suppressedMessages =
|
|
1901
|
+
this.suppressedMessages = [
|
|
1902
|
+
...(report.suppressedDiagnostics ?? []).map((diagnostic) => suppressedDiagnosticToESLintMessage(diagnostic, ruleSeverities)),
|
|
1903
|
+
...customRuleFilter.suppressedMessages
|
|
1904
|
+
];
|
|
1892
1905
|
this.times = { passes: [] };
|
|
1893
1906
|
this.fixPassCount = 0;
|
|
1894
1907
|
return [
|
|
@@ -2197,14 +2210,18 @@ function applyDisableDirectives(messages, sourceCode) {
|
|
|
2197
2210
|
const directives = sourceCode.getDisableDirectives()
|
|
2198
2211
|
.filter((directive) => directive.node?.loc?.start?.line)
|
|
2199
2212
|
.sort((left, right) => left.node.loc.start.line - right.node.loc.start.line);
|
|
2200
|
-
|
|
2213
|
+
const utlintDirectives = sourceCode.getAllComments()
|
|
2214
|
+
.map((comment) => utlintDirectiveFromComment(comment, sourceCode))
|
|
2215
|
+
.filter(Boolean)
|
|
2216
|
+
.sort((left, right) => left.node.range[0] - right.node.range[0]);
|
|
2217
|
+
if (directives.length === 0 && utlintDirectives.length === 0) {
|
|
2201
2218
|
return { messages, suppressedMessages: [] };
|
|
2202
2219
|
}
|
|
2203
2220
|
|
|
2204
2221
|
const kept = [];
|
|
2205
2222
|
const suppressed = [];
|
|
2206
2223
|
for (const message of messages) {
|
|
2207
|
-
const directive = disableDirectiveForMessage(message, directives);
|
|
2224
|
+
const directive = utlintDirectiveForMessage(message, utlintDirectives) ?? disableDirectiveForMessage(message, directives);
|
|
2208
2225
|
if (directive) {
|
|
2209
2226
|
suppressed.push({
|
|
2210
2227
|
...message,
|
|
@@ -2220,6 +2237,68 @@ function applyDisableDirectives(messages, sourceCode) {
|
|
|
2220
2237
|
return { messages: kept, suppressedMessages: suppressed };
|
|
2221
2238
|
}
|
|
2222
2239
|
|
|
2240
|
+
function utlintDirectiveFromComment(comment, sourceCode) {
|
|
2241
|
+
const match = String(comment?.value ?? "").trim().match(/^(utlint-ignore(?:-all|-start|-end)?)\b\s*(.*)$/u);
|
|
2242
|
+
if (!match) {
|
|
2243
|
+
return null;
|
|
2244
|
+
}
|
|
2245
|
+
|
|
2246
|
+
const [, type, tail] = match;
|
|
2247
|
+
const colon = tail.indexOf(":");
|
|
2248
|
+
const rawRuleId = (colon === -1 ? tail : tail.slice(0, colon)).trim();
|
|
2249
|
+
const justification = colon === -1 ? "" : tail.slice(colon + 1).trim();
|
|
2250
|
+
const nextToken = sourceCode.getAllTokens().find((token) => token.range?.[0] >= comment.range?.[1]);
|
|
2251
|
+
return {
|
|
2252
|
+
type,
|
|
2253
|
+
node: comment,
|
|
2254
|
+
ruleId: rawRuleId || null,
|
|
2255
|
+
justification,
|
|
2256
|
+
nextCodeLine: nextToken?.loc?.start?.line ?? null,
|
|
2257
|
+
topLevel: sourceCode.getAllTokens().every((token) => token.range?.[0] >= comment.range?.[0])
|
|
2258
|
+
};
|
|
2259
|
+
}
|
|
2260
|
+
|
|
2261
|
+
function utlintDirectiveForMessage(message, directives) {
|
|
2262
|
+
let allRulesRangeDepth = 0;
|
|
2263
|
+
let namedRuleRangeDepth = 0;
|
|
2264
|
+
let allRulesRangeDirective = null;
|
|
2265
|
+
let namedRuleRangeDirective = null;
|
|
2266
|
+
|
|
2267
|
+
for (const directive of directives) {
|
|
2268
|
+
if (directive.node.loc.start.line > message.line) {
|
|
2269
|
+
break;
|
|
2270
|
+
}
|
|
2271
|
+
if (directive.type === "utlint-ignore-start") {
|
|
2272
|
+
if (directive.ruleId == null) {
|
|
2273
|
+
allRulesRangeDirective ??= directive;
|
|
2274
|
+
allRulesRangeDepth += 1;
|
|
2275
|
+
} else if (directive.ruleId === message.ruleId) {
|
|
2276
|
+
namedRuleRangeDirective ??= directive;
|
|
2277
|
+
namedRuleRangeDepth += 1;
|
|
2278
|
+
}
|
|
2279
|
+
continue;
|
|
2280
|
+
}
|
|
2281
|
+
if (directive.type === "utlint-ignore-end") {
|
|
2282
|
+
if (directive.ruleId == null && allRulesRangeDepth > 0) {
|
|
2283
|
+
allRulesRangeDepth -= 1;
|
|
2284
|
+
if (allRulesRangeDepth === 0) allRulesRangeDirective = null;
|
|
2285
|
+
} else if (directive.ruleId === message.ruleId && namedRuleRangeDepth > 0) {
|
|
2286
|
+
namedRuleRangeDepth -= 1;
|
|
2287
|
+
if (namedRuleRangeDepth === 0) namedRuleRangeDirective = null;
|
|
2288
|
+
}
|
|
2289
|
+
continue;
|
|
2290
|
+
}
|
|
2291
|
+
if (directive.type === "utlint-ignore-all" && directive.topLevel && disableDirectiveMatchesRule(directive, message.ruleId)) {
|
|
2292
|
+
return directive;
|
|
2293
|
+
}
|
|
2294
|
+
if (directive.type === "utlint-ignore" && directive.nextCodeLine === message.line && disableDirectiveMatchesRule(directive, message.ruleId)) {
|
|
2295
|
+
return directive;
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
|
|
2299
|
+
return namedRuleRangeDirective ?? allRulesRangeDirective;
|
|
2300
|
+
}
|
|
2301
|
+
|
|
2223
2302
|
function disableDirectiveForMessage(message, directives) {
|
|
2224
2303
|
const active = {
|
|
2225
2304
|
all: null,
|
|
@@ -3695,6 +3774,18 @@ function reportToESLintResults(report, textOptions = {}) {
|
|
|
3695
3774
|
byFile.get(filePath).messages.push(diagnosticToESLintMessage(diagnostic, ruleSeverities));
|
|
3696
3775
|
}
|
|
3697
3776
|
|
|
3777
|
+
for (const diagnostic of report.suppressedDiagnostics ?? []) {
|
|
3778
|
+
const filePath = textOptions.filePath ?? normalizeESLintFilePath(diagnostic.filePath, textOptions.cwd);
|
|
3779
|
+
if (!byFile.has(filePath)) {
|
|
3780
|
+
byFile.set(filePath, emptyESLintResult(filePath, textOptions.source));
|
|
3781
|
+
}
|
|
3782
|
+
const ruleSeverities = textOptions.ruleSeverityForFile?.(filePath) ?? textOptions.ruleSeverities;
|
|
3783
|
+
if (diagnostic.ruleId && ruleSeverities?.get(diagnostic.ruleId) === 0) {
|
|
3784
|
+
continue;
|
|
3785
|
+
}
|
|
3786
|
+
byFile.get(filePath).suppressedMessages.push(suppressedDiagnosticToESLintMessage(diagnostic, ruleSeverities));
|
|
3787
|
+
}
|
|
3788
|
+
|
|
3698
3789
|
for (const fixed of report.outputs ?? []) {
|
|
3699
3790
|
const filePath = textOptions.filePath ?? normalizeESLintFilePath(fixed.filePath, textOptions.cwd);
|
|
3700
3791
|
if (!byFile.has(filePath)) {
|
|
@@ -4398,6 +4489,16 @@ function diagnosticToESLintMessage(diagnostic, ruleSeverities) {
|
|
|
4398
4489
|
return message;
|
|
4399
4490
|
}
|
|
4400
4491
|
|
|
4492
|
+
function suppressedDiagnosticToESLintMessage(diagnostic, ruleSeverities) {
|
|
4493
|
+
return {
|
|
4494
|
+
...diagnosticToESLintMessage(diagnostic, ruleSeverities),
|
|
4495
|
+
suppressions: [{
|
|
4496
|
+
kind: diagnostic.suppression?.kind ?? "directive",
|
|
4497
|
+
justification: diagnostic.suppression?.justification ?? ""
|
|
4498
|
+
}]
|
|
4499
|
+
};
|
|
4500
|
+
}
|
|
4501
|
+
|
|
4401
4502
|
function finalizeESLintResult(result) {
|
|
4402
4503
|
result.errorCount = 0;
|
|
4403
4504
|
result.warningCount = 0;
|
package/index.d.ts
CHANGED
|
@@ -9,10 +9,17 @@ export interface LintMessage {
|
|
|
9
9
|
nodeType?: string | null;
|
|
10
10
|
fix?: LintFix | LintFix[];
|
|
11
11
|
suggestions?: LintSuggestion[];
|
|
12
|
+
suppressions?: LintSuppression[];
|
|
12
13
|
}
|
|
13
14
|
|
|
14
|
-
export interface
|
|
15
|
+
export interface LintSuppression {
|
|
16
|
+
kind: "directive";
|
|
17
|
+
justification: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface LintDiagnostic extends Omit<LintMessage, "severity" | "suppressions"> {
|
|
15
21
|
severity: "warning" | "error";
|
|
22
|
+
suppression?: LintSuppression;
|
|
16
23
|
}
|
|
17
24
|
|
|
18
25
|
export interface LintFix {
|
|
@@ -42,6 +49,7 @@ export interface LintReport {
|
|
|
42
49
|
files: number;
|
|
43
50
|
filePaths: string[];
|
|
44
51
|
diagnostics: LintDiagnostic[];
|
|
52
|
+
suppressedDiagnostics: LintDiagnostic[];
|
|
45
53
|
outputs?: Array<{ filePath: string; output: string }>;
|
|
46
54
|
exitCode: number;
|
|
47
55
|
stderr?: string;
|
package/index.js
CHANGED
|
@@ -517,7 +517,7 @@ export class UtooLint {
|
|
|
517
517
|
const results = reportToESLintResults(report, {
|
|
518
518
|
source: code,
|
|
519
519
|
filePath,
|
|
520
|
-
includeEmptyTextResult: report.files !== 0 || (report.diagnostics?.length ?? 0) > 0,
|
|
520
|
+
includeEmptyTextResult: report.files !== 0 || (report.diagnostics?.length ?? 0) > 0 || (report.suppressedDiagnostics?.length ?? 0) > 0,
|
|
521
521
|
ruleSeverityForFile: (filePath) => ruleSeverityMapForOptions(nativeOptions, filePath)
|
|
522
522
|
});
|
|
523
523
|
if (report.files !== 0) {
|
|
@@ -635,7 +635,10 @@ export class Linter {
|
|
|
635
635
|
config: calculatedConfig({ cwd: verifyOptions.cwd, noConfig: true, overrideConfig: config }, normalizedFilePath)
|
|
636
636
|
});
|
|
637
637
|
const customRuleFilter = applyDisableDirectives(customRuleMessages, sourceCode);
|
|
638
|
-
this.suppressedMessages =
|
|
638
|
+
this.suppressedMessages = [
|
|
639
|
+
...(report.suppressedDiagnostics ?? []).map((diagnostic) => suppressedDiagnosticToESLintMessage(diagnostic, ruleSeverities)),
|
|
640
|
+
...customRuleFilter.suppressedMessages
|
|
641
|
+
];
|
|
639
642
|
this.times = { passes: [] };
|
|
640
643
|
this.fixPassCount = 0;
|
|
641
644
|
return [
|
|
@@ -944,14 +947,18 @@ function applyDisableDirectives(messages, sourceCode) {
|
|
|
944
947
|
const directives = sourceCode.getDisableDirectives()
|
|
945
948
|
.filter((directive) => directive.node?.loc?.start?.line)
|
|
946
949
|
.sort((left, right) => left.node.loc.start.line - right.node.loc.start.line);
|
|
947
|
-
|
|
950
|
+
const utlintDirectives = sourceCode.getAllComments()
|
|
951
|
+
.map((comment) => utlintDirectiveFromComment(comment, sourceCode))
|
|
952
|
+
.filter(Boolean)
|
|
953
|
+
.sort((left, right) => left.node.range[0] - right.node.range[0]);
|
|
954
|
+
if (directives.length === 0 && utlintDirectives.length === 0) {
|
|
948
955
|
return { messages, suppressedMessages: [] };
|
|
949
956
|
}
|
|
950
957
|
|
|
951
958
|
const kept = [];
|
|
952
959
|
const suppressed = [];
|
|
953
960
|
for (const message of messages) {
|
|
954
|
-
const directive = disableDirectiveForMessage(message, directives);
|
|
961
|
+
const directive = utlintDirectiveForMessage(message, utlintDirectives) ?? disableDirectiveForMessage(message, directives);
|
|
955
962
|
if (directive) {
|
|
956
963
|
suppressed.push({
|
|
957
964
|
...message,
|
|
@@ -967,6 +974,68 @@ function applyDisableDirectives(messages, sourceCode) {
|
|
|
967
974
|
return { messages: kept, suppressedMessages: suppressed };
|
|
968
975
|
}
|
|
969
976
|
|
|
977
|
+
function utlintDirectiveFromComment(comment, sourceCode) {
|
|
978
|
+
const match = String(comment?.value ?? "").trim().match(/^(utlint-ignore(?:-all|-start|-end)?)\b\s*(.*)$/u);
|
|
979
|
+
if (!match) {
|
|
980
|
+
return null;
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
const [, type, tail] = match;
|
|
984
|
+
const colon = tail.indexOf(":");
|
|
985
|
+
const rawRuleId = (colon === -1 ? tail : tail.slice(0, colon)).trim();
|
|
986
|
+
const justification = colon === -1 ? "" : tail.slice(colon + 1).trim();
|
|
987
|
+
const nextToken = sourceCode.getAllTokens().find((token) => token.range?.[0] >= comment.range?.[1]);
|
|
988
|
+
return {
|
|
989
|
+
type,
|
|
990
|
+
node: comment,
|
|
991
|
+
ruleId: rawRuleId || null,
|
|
992
|
+
justification,
|
|
993
|
+
nextCodeLine: nextToken?.loc?.start?.line ?? null,
|
|
994
|
+
topLevel: sourceCode.getAllTokens().every((token) => token.range?.[0] >= comment.range?.[0])
|
|
995
|
+
};
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
function utlintDirectiveForMessage(message, directives) {
|
|
999
|
+
let allRulesRangeDepth = 0;
|
|
1000
|
+
let namedRuleRangeDepth = 0;
|
|
1001
|
+
let allRulesRangeDirective = null;
|
|
1002
|
+
let namedRuleRangeDirective = null;
|
|
1003
|
+
|
|
1004
|
+
for (const directive of directives) {
|
|
1005
|
+
if (directive.node.loc.start.line > message.line) {
|
|
1006
|
+
break;
|
|
1007
|
+
}
|
|
1008
|
+
if (directive.type === "utlint-ignore-start") {
|
|
1009
|
+
if (directive.ruleId == null) {
|
|
1010
|
+
allRulesRangeDirective ??= directive;
|
|
1011
|
+
allRulesRangeDepth += 1;
|
|
1012
|
+
} else if (directive.ruleId === message.ruleId) {
|
|
1013
|
+
namedRuleRangeDirective ??= directive;
|
|
1014
|
+
namedRuleRangeDepth += 1;
|
|
1015
|
+
}
|
|
1016
|
+
continue;
|
|
1017
|
+
}
|
|
1018
|
+
if (directive.type === "utlint-ignore-end") {
|
|
1019
|
+
if (directive.ruleId == null && allRulesRangeDepth > 0) {
|
|
1020
|
+
allRulesRangeDepth -= 1;
|
|
1021
|
+
if (allRulesRangeDepth === 0) allRulesRangeDirective = null;
|
|
1022
|
+
} else if (directive.ruleId === message.ruleId && namedRuleRangeDepth > 0) {
|
|
1023
|
+
namedRuleRangeDepth -= 1;
|
|
1024
|
+
if (namedRuleRangeDepth === 0) namedRuleRangeDirective = null;
|
|
1025
|
+
}
|
|
1026
|
+
continue;
|
|
1027
|
+
}
|
|
1028
|
+
if (directive.type === "utlint-ignore-all" && directive.topLevel && disableDirectiveMatchesRule(directive, message.ruleId)) {
|
|
1029
|
+
return directive;
|
|
1030
|
+
}
|
|
1031
|
+
if (directive.type === "utlint-ignore" && directive.nextCodeLine === message.line && disableDirectiveMatchesRule(directive, message.ruleId)) {
|
|
1032
|
+
return directive;
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
return namedRuleRangeDirective ?? allRulesRangeDirective;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
970
1039
|
function disableDirectiveForMessage(message, directives) {
|
|
971
1040
|
const active = {
|
|
972
1041
|
all: null,
|
|
@@ -2477,7 +2546,7 @@ export class CLIEngine {
|
|
|
2477
2546
|
const results = maybeFilterQuietResults(reportToESLintResults(report, {
|
|
2478
2547
|
source: code,
|
|
2479
2548
|
filePath: normalizeESLintFilePath(filePath, mergedOptions.cwd),
|
|
2480
|
-
includeEmptyTextResult: report.files !== 0 || (report.diagnostics?.length ?? 0) > 0,
|
|
2549
|
+
includeEmptyTextResult: report.files !== 0 || (report.diagnostics?.length ?? 0) > 0 || (report.suppressedDiagnostics?.length ?? 0) > 0,
|
|
2481
2550
|
ruleSeverityForFile: (filePath) => ruleSeverityMapForOptions(mergedOptions, filePath)
|
|
2482
2551
|
}), mergedOptions);
|
|
2483
2552
|
return resultsToCLIEngineReport(results);
|
|
@@ -2678,6 +2747,7 @@ function publicCliReport(report) {
|
|
|
2678
2747
|
files: report.files ?? 0,
|
|
2679
2748
|
filePaths: report.filePaths ?? [],
|
|
2680
2749
|
diagnostics: report.diagnostics ?? [],
|
|
2750
|
+
suppressedDiagnostics: report.suppressedDiagnostics ?? [],
|
|
2681
2751
|
outputs: report.outputs ?? []
|
|
2682
2752
|
};
|
|
2683
2753
|
}
|
|
@@ -2976,7 +3046,7 @@ export function lintFiles(paths, options = {}) {
|
|
|
2976
3046
|
const ignoredDiagnostics = ignoredLintPathDiagnostics(targets, options);
|
|
2977
3047
|
const lintPaths = filteredLintPaths(targets, options);
|
|
2978
3048
|
if (lintPaths.length === 0) {
|
|
2979
|
-
return { files: 0, filePaths: [], diagnostics: ignoredDiagnostics, exitCode: exitCodeForDiagnostics(ignoredDiagnostics) };
|
|
3049
|
+
return { files: 0, filePaths: [], diagnostics: ignoredDiagnostics, suppressedDiagnostics: [], exitCode: exitCodeForDiagnostics(ignoredDiagnostics) };
|
|
2980
3050
|
}
|
|
2981
3051
|
|
|
2982
3052
|
const configRuns = nativeConfigRunsForFiles(expandNativeConfigRunPaths(lintPaths, options), options);
|
|
@@ -3041,8 +3111,10 @@ function finalizeLintReport(report, ignoredDiagnostics, options) {
|
|
|
3041
3111
|
if (!options.deferDiagnosticConfigFiltering) {
|
|
3042
3112
|
report.filePaths = normalizeReportFilePaths(report.filePaths, options);
|
|
3043
3113
|
report.diagnostics = normalizeDiagnosticFilePaths(report.diagnostics, options);
|
|
3114
|
+
report.suppressedDiagnostics = normalizeDiagnosticFilePaths(report.suppressedDiagnostics, options);
|
|
3044
3115
|
report.outputs = normalizeReportOutputs(report.outputs, options);
|
|
3045
3116
|
report.diagnostics = normalizeReportDiagnostics(report.diagnostics, options);
|
|
3117
|
+
report.suppressedDiagnostics = normalizeReportDiagnostics(report.suppressedDiagnostics, options);
|
|
3046
3118
|
report.exitCode = exitCodeForDiagnostics(report.diagnostics);
|
|
3047
3119
|
}
|
|
3048
3120
|
return report;
|
|
@@ -3139,6 +3211,7 @@ function mergeNativeReports(reports) {
|
|
|
3139
3211
|
files: reports.reduce((count, item) => count + (item.files ?? 0), 0),
|
|
3140
3212
|
filePaths: reports.flatMap((item) => item.filePaths ?? []),
|
|
3141
3213
|
diagnostics: reports.flatMap((item) => item.diagnostics ?? []),
|
|
3214
|
+
suppressedDiagnostics: reports.flatMap((item) => item.suppressedDiagnostics ?? []),
|
|
3142
3215
|
outputs: reports.flatMap((item) => item.outputs ?? []),
|
|
3143
3216
|
exitCode: reports.some((item) => item.exitCode) ? 1 : 0
|
|
3144
3217
|
};
|
|
@@ -3171,6 +3244,7 @@ export function lintText(code, options = {}) {
|
|
|
3171
3244
|
files: 0,
|
|
3172
3245
|
filePaths: [],
|
|
3173
3246
|
diagnostics,
|
|
3247
|
+
suppressedDiagnostics: [],
|
|
3174
3248
|
exitCode: exitCodeForDiagnostics(diagnostics)
|
|
3175
3249
|
};
|
|
3176
3250
|
}
|
|
@@ -3192,7 +3266,12 @@ export function lintText(code, options = {}) {
|
|
|
3192
3266
|
...diagnostic,
|
|
3193
3267
|
filePath: requestedPath
|
|
3194
3268
|
}));
|
|
3269
|
+
report.suppressedDiagnostics = (report.suppressedDiagnostics ?? []).map((diagnostic) => ({
|
|
3270
|
+
...diagnostic,
|
|
3271
|
+
filePath: requestedPath
|
|
3272
|
+
}));
|
|
3195
3273
|
report.diagnostics = normalizeReportDiagnostics(report.diagnostics, options);
|
|
3274
|
+
report.suppressedDiagnostics = normalizeReportDiagnostics(report.suppressedDiagnostics, options);
|
|
3196
3275
|
report.exitCode = exitCodeForDiagnostics(report.diagnostics);
|
|
3197
3276
|
return report;
|
|
3198
3277
|
} finally {
|
|
@@ -3698,6 +3777,18 @@ function reportToESLintResults(report, textOptions = {}) {
|
|
|
3698
3777
|
byFile.get(filePath).messages.push(diagnosticToESLintMessage(diagnostic, ruleSeverities));
|
|
3699
3778
|
}
|
|
3700
3779
|
|
|
3780
|
+
for (const diagnostic of report.suppressedDiagnostics ?? []) {
|
|
3781
|
+
const filePath = textOptions.filePath ?? normalizeESLintFilePath(diagnostic.filePath, textOptions.cwd);
|
|
3782
|
+
if (!byFile.has(filePath)) {
|
|
3783
|
+
byFile.set(filePath, emptyESLintResult(filePath, textOptions.source));
|
|
3784
|
+
}
|
|
3785
|
+
const ruleSeverities = textOptions.ruleSeverityForFile?.(filePath) ?? textOptions.ruleSeverities;
|
|
3786
|
+
if (diagnostic.ruleId && ruleSeverities?.get(diagnostic.ruleId) === 0) {
|
|
3787
|
+
continue;
|
|
3788
|
+
}
|
|
3789
|
+
byFile.get(filePath).suppressedMessages.push(suppressedDiagnosticToESLintMessage(diagnostic, ruleSeverities));
|
|
3790
|
+
}
|
|
3791
|
+
|
|
3701
3792
|
for (const fixed of report.outputs ?? []) {
|
|
3702
3793
|
const filePath = textOptions.filePath ?? normalizeESLintFilePath(fixed.filePath, textOptions.cwd);
|
|
3703
3794
|
if (!byFile.has(filePath)) {
|
|
@@ -4401,6 +4492,16 @@ function diagnosticToESLintMessage(diagnostic, ruleSeverities) {
|
|
|
4401
4492
|
return message;
|
|
4402
4493
|
}
|
|
4403
4494
|
|
|
4495
|
+
function suppressedDiagnosticToESLintMessage(diagnostic, ruleSeverities) {
|
|
4496
|
+
return {
|
|
4497
|
+
...diagnosticToESLintMessage(diagnostic, ruleSeverities),
|
|
4498
|
+
suppressions: [{
|
|
4499
|
+
kind: diagnostic.suppression?.kind ?? "directive",
|
|
4500
|
+
justification: diagnostic.suppression?.justification ?? ""
|
|
4501
|
+
}]
|
|
4502
|
+
};
|
|
4503
|
+
}
|
|
4504
|
+
|
|
4404
4505
|
function finalizeESLintResult(result) {
|
|
4405
4506
|
result.errorCount = 0;
|
|
4406
4507
|
result.warningCount = 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@utoo/lint",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.8",
|
|
4
4
|
"description": "Experimental JavaScript and TypeScript linter powered by Yuku",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -76,11 +76,11 @@
|
|
|
76
76
|
"use-at-your-own-risk.js"
|
|
77
77
|
],
|
|
78
78
|
"optionalDependencies": {
|
|
79
|
-
"@utoo/lint-darwin-arm64": "0.2.
|
|
80
|
-
"@utoo/lint-darwin-x64": "0.2.
|
|
81
|
-
"@utoo/lint-linux-arm64": "0.2.
|
|
82
|
-
"@utoo/lint-linux-x64": "0.2.
|
|
83
|
-
"@utoo/lint-win32-x64": "0.2.
|
|
79
|
+
"@utoo/lint-darwin-arm64": "0.2.8",
|
|
80
|
+
"@utoo/lint-darwin-x64": "0.2.8",
|
|
81
|
+
"@utoo/lint-linux-arm64": "0.2.8",
|
|
82
|
+
"@utoo/lint-linux-x64": "0.2.8",
|
|
83
|
+
"@utoo/lint-win32-x64": "0.2.8"
|
|
84
84
|
},
|
|
85
85
|
"dependencies": {
|
|
86
86
|
"jiti": "2.7.0"
|