Skip to content

Commit 352521e

Browse files
refactor: disallow severity configuration by default (#62)
1 parent 0ba19d1 commit 352521e

8 files changed

Lines changed: 37 additions & 88 deletions

File tree

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ To enable TSSLint in VSCode, follow these steps:
6161

6262
### Create a Rule
6363

64-
To create a rule, you need to define a function that receives the context of the current diagnostic task. Within this function, you can call `reportError()` or `reportWarning()` to report an error.
64+
To create a rule, you need to define a function that receives the context of the current diagnostic task. Within this function, you can call `report()` to report an error.
6565

6666
As an example, let's create a `no-console` rule under `[project root]/rules/`.
6767

@@ -71,14 +71,14 @@ Here's the code for `[project root]/rules/noConsoleRule.ts`:
7171
import { defineRule } from '@tsslint/config';
7272

7373
export function create() {
74-
return defineRule(({ typescript: ts, sourceFile, reportWarning }) => {
74+
return defineRule(({ typescript: ts, sourceFile, report }) => {
7575
ts.forEachChild(sourceFile, function cb(node) {
7676
if (
7777
ts.isPropertyAccessExpression(node) &&
7878
ts.isIdentifier(node.expression) &&
7979
node.expression.text === 'console'
8080
) {
81-
reportWarning(
81+
report(
8282
`Calls to 'console.x' are not allowed.`,
8383
node.parent.getStart(sourceFile),
8484
node.parent.getEnd()
@@ -114,7 +114,7 @@ export default defineConfig({
114114
});
115115
```
116116

117-
After saving the config file, you will notice that `console.log` is now reporting errors in the editor. The error message will also display the specific line of code where the error occurred. Clicking on the error message will take you to line 11 in `noConsoleRule.ts`, where the `reportWarning()` code is located.
117+
After saving the config file, you will notice that `console.log` is now reporting errors in the editor. The error message will also display the specific line of code where the error occurred. Clicking on the error message will take you to line 11 in `noConsoleRule.ts`, where the `report()` code is located.
118118

119119
> Full example: https://github.com/johnsoncodehk/tsslint/tree/master/fixtures/define-a-rule
120120

fixtures/noConsoleRule.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { defineRule } from '@tsslint/config';
22

33
export function create() {
4-
return defineRule(({ typescript: ts, sourceFile, reportWarning }) => {
4+
return defineRule(({ typescript: ts, sourceFile, report }) => {
55
ts.forEachChild(sourceFile, function cb(node) {
66
if (
77
ts.isPropertyAccessExpression(node) &&
88
ts.isIdentifier(node.expression) &&
99
node.expression.text === 'console'
1010
) {
11-
reportWarning(
11+
report(
1212
`Calls to 'console.x' are not allowed.`,
1313
node.parent.getStart(sourceFile),
1414
node.parent.getEnd()

packages/core/index.ts

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -77,19 +77,19 @@ export function createLinter(
7777
? {
7878
...ctx,
7979
sourceFile: ctx.languageService.getProgram()!.getSourceFile(fileName)!,
80-
report: reportMessage,
81-
reportError,
82-
reportWarning,
83-
reportSuggestion,
80+
report,
81+
reportError: report,
82+
reportWarning: report,
83+
reportSuggestion: report,
8484
}
8585
: {
8686
...ctx,
8787
languageService: syntaxOnlyLanguageService,
8888
sourceFile: getNonBoundSourceFile(fileName),
89-
report: reportMessage,
90-
reportError,
91-
reportWarning,
92-
reportSuggestion,
89+
report,
90+
reportError: report,
91+
reportWarning: report,
92+
reportSuggestion: report,
9393
};
9494
const token = ctx.languageServiceHost.getCancellationToken?.();
9595
const configs = getConfigsForFile(fileName, cache?.[2]);
@@ -138,9 +138,9 @@ export function createLinter(
138138
rule2Mode.set(currentRuleId, true);
139139
shouldRetry = true;
140140
} else if (err instanceof Error) {
141-
report(ts.DiagnosticCategory.Error, err.stack ?? err.message, 0, 0, 0, err);
141+
report(err.stack ?? err.message, 0, 0, 0, err);
142142
} else {
143-
report(ts.DiagnosticCategory.Error, String(err), 0, 0, false);
143+
report(String(err), 0, 0, Number.MAX_VALUE);
144144
}
145145
}
146146

@@ -192,25 +192,9 @@ export function createLinter(
192192

193193
return diagnostics;
194194

195-
function reportMessage(message: string, start: number, end: number, stackOffset?: false | number) {
196-
return report(ts.DiagnosticCategory.Message, message, start, end, stackOffset);
197-
}
198-
199-
function reportError(message: string, start: number, end: number, stackOffset?: false | number) {
200-
return report(ts.DiagnosticCategory.Error, message, start, end, stackOffset);
201-
}
202-
203-
function reportWarning(message: string, start: number, end: number, stackOffset?: false | number) {
204-
return report(ts.DiagnosticCategory.Warning, message, start, end, stackOffset);
205-
}
206-
207-
function reportSuggestion(message: string, start: number, end: number, stackOffset?: false | number) {
208-
return report(ts.DiagnosticCategory.Suggestion, message, start, end, stackOffset);
209-
}
210-
211-
function report(category: ts.DiagnosticCategory, message: string, start: number, end: number, stackOffset: false | number = 2, err?: Error): Reporter {
195+
function report(message: string, start: number, end: number, stackOffset: number = 1, err?: Error): Reporter {
212196
const error: ts.DiagnosticWithLocation = {
213-
category,
197+
category: ts.DiagnosticCategory.Message,
214198
code: currentRuleId as any,
215199
messageText: message,
216200
file: rulesContext.sourceFile,
@@ -232,9 +216,7 @@ export function createLinter(
232216
});
233217
}
234218

235-
if (typeof stackOffset === 'number') {
236-
handleError(error, err ?? new Error(), stackOffset);
237-
}
219+
handleError(error, err ?? new Error(), stackOffset);
238220

239221
let lintResult = lintResults.get(fileName);
240222
if (!lintResult) {

packages/eslint/index.ts

Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -42,31 +42,20 @@ export async function convertRules(
4242
) {
4343
const rules: TSSLint.Rules = {};
4444
for (const [rule, severityOrOptions] of Object.entries(rulesConfig)) {
45-
let rawSeverity: 'off' | 'error' | 'warn' | 'suggestion' | 'message' | 0 | 1 | 2 | 3;
45+
let severity: boolean;
4646
let options: any[];
4747
if (Array.isArray(severityOrOptions)) {
48-
[rawSeverity, ...options] = severityOrOptions;
48+
[severity, ...options] = severityOrOptions;
4949
}
5050
else {
51-
rawSeverity = severityOrOptions;
51+
severity = severityOrOptions;
5252
options = [];
5353
}
54-
let tsSeverity: ts.DiagnosticCategory | undefined;
55-
if (rawSeverity === 'off' || rawSeverity === 0) {
56-
tsSeverity = undefined;
54+
// @ts-expect-error backward compatibility
55+
if (severity === 'off' || severity === 0) {
56+
severity = false;
5757
}
58-
else if (rawSeverity === 'warn' || rawSeverity === 1) {
59-
tsSeverity = 0 satisfies ts.DiagnosticCategory.Warning;
60-
}
61-
else if (rawSeverity === 'error' || rawSeverity === 2) {
62-
tsSeverity = 1 satisfies ts.DiagnosticCategory.Error;
63-
}
64-
else if (rawSeverity === 'suggestion') {
65-
tsSeverity = 2 satisfies ts.DiagnosticCategory.Suggestion;
66-
} else {
67-
tsSeverity = 3 satisfies ts.DiagnosticCategory.Message;
68-
}
69-
if (tsSeverity === undefined) {
58+
if (!severity) {
7059
rules[rule] = noop;
7160
continue;
7261
}
@@ -77,7 +66,6 @@ export async function convertRules(
7766
rules[rule] = convertRule(
7867
ruleModule,
7968
options,
80-
tsSeverity,
8169
{ id: rule, ...context }
8270
);
8371
}
@@ -133,11 +121,6 @@ async function getRule(pluginName: string | undefined, ruleName: string): Promis
133121
export function convertRule(
134122
eslintRule: ESLint.Rule.RuleModule,
135123
options: any[] = [],
136-
severity: ts.DiagnosticCategory =
137-
eslintRule.meta?.type === 'problem' ? 1 satisfies ts.DiagnosticCategory.Error
138-
: eslintRule.meta?.type === 'suggestion' ? 0 satisfies ts.DiagnosticCategory.Warning
139-
: eslintRule.meta?.type === 'layout' ? 2 satisfies ts.DiagnosticCategory.Suggestion
140-
: 3 satisfies ts.DiagnosticCategory.Message,
141124
context: Partial<ESLint.Rule.RuleContext> = {}
142125
): TSSLint.Rule {
143126
// ESLint internal scripts
@@ -154,11 +137,7 @@ export function convertRule(
154137
Traverser = require(require.resolve('./node_modules/eslint/lib/shared/traverser.js'));
155138
}
156139

157-
const tsslintRule: TSSLint.Rule = ({ typescript: ts, sourceFile, languageService, languageServiceHost, reportError, reportWarning, reportSuggestion }) => {
158-
const report =
159-
severity === ts.DiagnosticCategory.Error ? reportError
160-
: severity === ts.DiagnosticCategory.Warning ? reportWarning
161-
: reportSuggestion;
140+
const tsslintRule: TSSLint.Rule = ({ sourceFile, languageService, languageServiceHost, report }) => {
162141
const { sourceCode, eventQueue } = getEstree(
163142
sourceFile,
164143
languageService,
@@ -229,7 +208,7 @@ export function convertRule(
229208
}
230209
}
231210
} catch { }
232-
const reporter = report(message, start, end, 3);
211+
const reporter = report(message, start, end, 2);
233212
if (descriptor.fix) {
234213
// @ts-expect-error
235214
const textChanges = getTextChanges(descriptor.fix);

packages/eslint/lib/dtsGenerate.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ export async function generate(
1717
let dts = '';
1818
let defId = 0;
1919

20-
line(`export type S = 'off' | 'error' | 'warn' | 'suggestion' | 'message' | 0 | 1 | 2 | 3;`);
21-
line(`export type O<T extends any[]> = S | [S, ...options: T];`);
20+
line(`export type O<T extends any[]> = boolean | [boolean, ...options: T];`);
2221
line(``);
2322
line(`export interface ESLintRulesConfig {`);
2423
indentLevel++;

packages/eslint/lib/types.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
export type S = 'off' | 'error' | 'warn' | 'suggestion' | 'message' | 0 | 1 | 2 | 3;
2-
export type O<T extends any[]> = S | [S, ...options: T];
1+
export type O<T extends any[]> = boolean | [boolean, ...options: T];
32

43
export interface ESLintRulesConfig {
54
[key: string]: O<any[]>;

packages/tslint/index.ts

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,20 @@
11
import type * as TSSLint from '@tsslint/types';
22
import type * as TSLint from 'tslint';
3-
import type * as ts from 'typescript';
43

54
type TSLintRule = import('tslint/lib/language/rule/rule').RuleConstructor;
65

76
export function convertRule<T extends Partial<TSLintRule> | TSLintRule>(
87
Rule: T,
98
ruleArguments: any[] = [],
10-
severity: ts.DiagnosticCategory =
11-
!Rule.metadata || Rule.metadata.type === 'functionality' || Rule.metadata.type === 'typescript' ? 1 satisfies ts.DiagnosticCategory.Error
12-
: Rule.metadata.type === 'maintainability' || Rule.metadata.type === 'style' ? 0 satisfies ts.DiagnosticCategory.Warning
13-
: Rule.metadata.type === 'formatting' ? 2 satisfies ts.DiagnosticCategory.Suggestion
14-
: 3 satisfies ts.DiagnosticCategory.Message
159
): TSSLint.Rule {
1610
const rule = new (Rule as TSLintRule)({
1711
ruleName: Rule.metadata?.ruleName ?? 'unknown',
1812
ruleArguments,
19-
ruleSeverity: severity === 1 ? 'error' : severity === 2 ? 'warning' : 'off',
13+
ruleSeverity: 'warning',
2014
disabledIntervals: [],
2115
}) as TSLint.IRule | TSLint.ITypedRule;
22-
return ({ typescript: ts, sourceFile, languageService, reportError, reportWarning, reportSuggestion }) => {
16+
return ({ sourceFile, languageService, report }) => {
2317
let lastFailure: TSLint.RuleFailure | undefined;
24-
const report =
25-
severity === ts.DiagnosticCategory.Error ? reportError
26-
: severity === ts.DiagnosticCategory.Warning ? reportWarning
27-
: reportSuggestion;
2818
const onAddFailure = (failure: TSLint.RuleFailure) => {
2919
if (lastFailure === failure) {
3020
return;
@@ -34,7 +24,7 @@ export function convertRule<T extends Partial<TSLintRule> | TSLintRule>(
3424
failure.getFailure(),
3525
failure.getStartPosition().getPosition(),
3626
failure.getEndPosition().getPosition(),
37-
false
27+
Number.MAX_VALUE
3828
);
3929
if (failure.hasFix()) {
4030
const fix = failure.getFix();

packages/types/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,19 +44,19 @@ export interface RuleContext {
4444
languageServiceHost: LanguageServiceHost;
4545
languageService: LanguageService;
4646
sourceFile: SourceFile;
47-
report(message: string, start: number, end: number, stackOffset?: number | false): Reporter;
47+
report(message: string, start: number, end: number, stackOffset?: number): Reporter;
4848
/**
4949
* @deprecated Use `report` instead.
5050
*/
51-
reportError(message: string, start: number, end: number, stackOffset?: number | false): Reporter;
51+
reportError(message: string, start: number, end: number, stackOffset?: number): Reporter;
5252
/**
5353
* @deprecated Use `report` instead.
5454
*/
55-
reportWarning(message: string, start: number, end: number, stackOffset?: number | false): Reporter;
55+
reportWarning(message: string, start: number, end: number, stackOffset?: number): Reporter;
5656
/**
5757
* @deprecated Use `report` instead.
5858
*/
59-
reportSuggestion(message: string, start: number, end: number, stackOffset?: number | false): Reporter;
59+
reportSuggestion(message: string, start: number, end: number, stackOffset?: number): Reporter;
6060
}
6161

6262
export interface Reporter {

0 commit comments

Comments
 (0)