@timmo001/oxlint-rules 0.3.1 → 0.3.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.
- package/README.md +2 -1
- package/THIRD_PARTY_NOTICES.md +9 -0
- package/dist/cli.js +733 -35
- package/dist/configs/recommended-effect.js +767 -69
- package/dist/configs/recommended.js +535 -30
- package/dist/upstream/anti-slop.js +535 -30
- package/dist/upstream/effect.js +196 -3
- package/package.json +1 -1
- package/vendor/anti-slop/src/effect/index.ts +8 -0
- package/vendor/anti-slop/src/effect/rules/no-manual-effect-error-tag.ts +52 -0
- package/vendor/anti-slop/src/effect/rules/no-manual-tag-comparison.ts +45 -0
- package/vendor/anti-slop/src/effect/rules/no-manual-tagged-construction.ts +37 -0
- package/vendor/anti-slop/src/effect/rules/prefer-effect-match.ts +54 -0
- package/vendor/anti-slop/src/effect/shared/tagged-values.ts +97 -0
- package/vendor/anti-slop/src/index.ts +2 -0
- package/vendor/anti-slop/src/rules/no-known-value-widening.ts +2 -14
- package/vendor/anti-slop/src/rules/no-module-mocking.ts +3 -14
- package/vendor/anti-slop/src/rules/require-readable-spacing.ts +47 -0
- package/vendor/anti-slop/src/shared/reflect-method.ts +2 -13
- package/vendor/anti-slop/src/shared/scope.ts +15 -0
- package/vendor/anti-slop/src/vendor/eslint-stylistic/LICENSE +22 -0
- package/vendor/anti-slop/src/vendor/eslint-stylistic/UPSTREAM.md +28 -0
- package/vendor/anti-slop/src/vendor/eslint-stylistic/padding-line-ast.ts +51 -0
- package/vendor/anti-slop/src/vendor/eslint-stylistic/padding-line-between-statements.ts +906 -0
- package/vendor/anti-slop/src/vendor/eslint-stylistic/padding-line-options.d.ts +87 -0
|
@@ -110,8 +110,149 @@ var effect_default = timmoEffectPlugin;
|
|
|
110
110
|
// vendor/anti-slop/src/effect/index.ts
|
|
111
111
|
import { eslintCompatPlugin as eslintCompatPlugin2 } from "@oxlint/plugins";
|
|
112
112
|
|
|
113
|
-
// vendor/anti-slop/src/effect/rules/no-
|
|
113
|
+
// vendor/anti-slop/src/effect/rules/no-manual-effect-error-tag.ts
|
|
114
114
|
import { defineRule as defineRule2 } from "@oxlint/plugins";
|
|
115
|
+
|
|
116
|
+
// vendor/anti-slop/src/effect/shared/tagged-values.ts
|
|
117
|
+
var equalityOperators = new Set(["==", "===", "!=", "!=="]);
|
|
118
|
+
var broadEffectCatchMethods = new Set(["catch", "catchAll", "catchIf"]);
|
|
119
|
+
var isStringLiteral = (node) => node?.type === "Literal" && typeof node.value === "string";
|
|
120
|
+
var isTagMember = (node) => node?.type === "MemberExpression" && (!node.computed && node.property.type === "Identifier" && node.property.name === "_tag" || node.computed && isStringLiteral(node.property) && node.property.value === "_tag");
|
|
121
|
+
var tagMemberFromComparison = (node) => {
|
|
122
|
+
if (!equalityOperators.has(node.operator))
|
|
123
|
+
return;
|
|
124
|
+
if (isTagMember(node.left) && isStringLiteral(node.right))
|
|
125
|
+
return node.left;
|
|
126
|
+
if (isTagMember(node.right) && isStringLiteral(node.left))
|
|
127
|
+
return node.right;
|
|
128
|
+
return;
|
|
129
|
+
};
|
|
130
|
+
var isBroadEffectCatchCall = (node) => node?.type === "CallExpression" && node.callee.type === "MemberExpression" && node.callee.object.type === "Identifier" && node.callee.object.name === "Effect" && !node.callee.computed && node.callee.property.type === "Identifier" && broadEffectCatchMethods.has(node.callee.property.name);
|
|
131
|
+
var isInsideBroadEffectHandler = (node) => {
|
|
132
|
+
let current = node.parent;
|
|
133
|
+
while (current !== null && current !== undefined) {
|
|
134
|
+
if (current.type === "ArrowFunctionExpression" || current.type === "FunctionExpression") {
|
|
135
|
+
return isBroadEffectCatchCall(current.parent) && current.parent.arguments.includes(current);
|
|
136
|
+
}
|
|
137
|
+
current = current.parent;
|
|
138
|
+
}
|
|
139
|
+
return false;
|
|
140
|
+
};
|
|
141
|
+
var isReasonTagMember = (node) => node.object.type === "MemberExpression" && (!node.object.computed && node.object.property.type === "Identifier" && node.object.property.name === "reason" || node.object.computed && isStringLiteral(node.object.property) && node.object.property.value === "reason");
|
|
142
|
+
var propertyName = (property) => {
|
|
143
|
+
if (!property.computed && property.key.type === "Identifier") {
|
|
144
|
+
return property.key.name;
|
|
145
|
+
}
|
|
146
|
+
if (property.key.type === "Literal" && typeof property.key.value === "string") {
|
|
147
|
+
return property.key.value;
|
|
148
|
+
}
|
|
149
|
+
return;
|
|
150
|
+
};
|
|
151
|
+
var isMatchPatternObject = (node) => {
|
|
152
|
+
const call = node.parent;
|
|
153
|
+
if (call?.type !== "CallExpression" || !call.arguments.includes(node)) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
const callee = call.callee;
|
|
157
|
+
return callee.type === "MemberExpression" && callee.object.type === "Identifier" && callee.object.name === "Match" && !callee.computed && callee.property.type === "Identifier" && (callee.property.name === "when" || callee.property.name === "not");
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
// vendor/anti-slop/src/effect/rules/no-manual-effect-error-tag.ts
|
|
161
|
+
var noManualEffectErrorTagRule = defineRule2({
|
|
162
|
+
meta: {
|
|
163
|
+
type: "problem",
|
|
164
|
+
docs: {
|
|
165
|
+
description: "Use Effect tagged error handlers instead of manually branching on `_tag` in a catch handler."
|
|
166
|
+
},
|
|
167
|
+
messages: {
|
|
168
|
+
tag: "Use Effect.catchTag or Effect.catchTags instead of manually discriminating a tagged error in a broad Effect catch handler.",
|
|
169
|
+
reason: "Use Effect.catchReason or Effect.catchReasons instead of manually discriminating a tagged `reason` in a broad Effect catch handler."
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
createOnce(context) {
|
|
173
|
+
return {
|
|
174
|
+
BinaryExpression(node) {
|
|
175
|
+
const tagMember = tagMemberFromComparison(node);
|
|
176
|
+
if (tagMember === undefined || !isInsideBroadEffectHandler(node)) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
context.report({
|
|
180
|
+
node,
|
|
181
|
+
messageId: isReasonTagMember(tagMember) ? "reason" : "tag"
|
|
182
|
+
});
|
|
183
|
+
},
|
|
184
|
+
SwitchStatement(node) {
|
|
185
|
+
if (!isTagMember(node.discriminant) || !isInsideBroadEffectHandler(node)) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
context.report({
|
|
189
|
+
node,
|
|
190
|
+
messageId: isReasonTagMember(node.discriminant) ? "reason" : "tag"
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
// vendor/anti-slop/src/effect/rules/no-manual-tag-comparison.ts
|
|
198
|
+
import { defineRule as defineRule3 } from "@oxlint/plugins";
|
|
199
|
+
var noManualTagComparisonRule = defineRule3({
|
|
200
|
+
meta: {
|
|
201
|
+
type: "problem",
|
|
202
|
+
docs: {
|
|
203
|
+
description: "Use Effect Match or Predicate helpers instead of manually branching on `_tag`."
|
|
204
|
+
},
|
|
205
|
+
messages: {
|
|
206
|
+
manualComparison: "Use Match.tag/Match.tags for tagged-value branching, or Predicate.isTagged for a simple reusable predicate.",
|
|
207
|
+
manualSwitch: "Use Match.value(value).pipe(Match.tag/Match.tags/Match.tagsExhaustive) or the tagged enum `$match` helper instead of switching on `_tag`."
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
createOnce(context) {
|
|
211
|
+
return {
|
|
212
|
+
BinaryExpression(node) {
|
|
213
|
+
if (tagMemberFromComparison(node) === undefined || isInsideBroadEffectHandler(node)) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
context.report({ node, messageId: "manualComparison" });
|
|
217
|
+
},
|
|
218
|
+
SwitchStatement(node) {
|
|
219
|
+
if (!isTagMember(node.discriminant) || isInsideBroadEffectHandler(node)) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
context.report({ node, messageId: "manualSwitch" });
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
// vendor/anti-slop/src/effect/rules/no-manual-tagged-construction.ts
|
|
229
|
+
import { defineRule as defineRule4 } from "@oxlint/plugins";
|
|
230
|
+
var noManualTaggedConstructionRule = defineRule4({
|
|
231
|
+
meta: {
|
|
232
|
+
type: "problem",
|
|
233
|
+
docs: {
|
|
234
|
+
description: "Construct tagged values with their existing Effect constructor instead of writing `_tag` manually."
|
|
235
|
+
},
|
|
236
|
+
messages: {
|
|
237
|
+
manualConstruction: "Use the existing Schema tagged `.make`, tagged class/error constructor, or Data.taggedEnum variant constructor instead of writing a literal `_tag` object."
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
createOnce(context) {
|
|
241
|
+
return {
|
|
242
|
+
ObjectExpression(node) {
|
|
243
|
+
if (isMatchPatternObject(node))
|
|
244
|
+
return;
|
|
245
|
+
const tag = node.properties.find((property) => property.type === "Property" && propertyName(property) === "_tag" && isStringLiteral(property.value));
|
|
246
|
+
if (tag !== undefined) {
|
|
247
|
+
context.report({ node: tag, messageId: "manualConstruction" });
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
// vendor/anti-slop/src/effect/rules/no-service-constructor-imports.ts
|
|
255
|
+
import { defineRule as defineRule5 } from "@oxlint/plugins";
|
|
115
256
|
var SERVICE_CONSTRUCTOR_NAME = /^make[A-Z]/u;
|
|
116
257
|
var TEST_FILE = /\.(?:test|spec)\.[cm]?[jt]sx?$/u;
|
|
117
258
|
function isProjectLocalImport(source) {
|
|
@@ -122,7 +263,7 @@ function getImportedName(specifier) {
|
|
|
122
263
|
return specifier.imported.name;
|
|
123
264
|
return specifier.imported.value;
|
|
124
265
|
}
|
|
125
|
-
var noServiceConstructorImportsRule =
|
|
266
|
+
var noServiceConstructorImportsRule = defineRule5({
|
|
126
267
|
meta: {
|
|
127
268
|
type: "problem",
|
|
128
269
|
docs: {
|
|
@@ -155,11 +296,63 @@ var noServiceConstructorImportsRule = defineRule2({
|
|
|
155
296
|
}
|
|
156
297
|
});
|
|
157
298
|
|
|
299
|
+
// vendor/anti-slop/src/effect/rules/prefer-effect-match.ts
|
|
300
|
+
import { defineRule as defineRule6 } from "@oxlint/plugins";
|
|
301
|
+
var equalityOperators2 = new Set(["==", "===", "!=", "!=="]);
|
|
302
|
+
var preferEffectMatchRule = defineRule6({
|
|
303
|
+
meta: {
|
|
304
|
+
type: "problem",
|
|
305
|
+
docs: {
|
|
306
|
+
description: "Use Match from Effect for chained literal ternaries over the same value."
|
|
307
|
+
},
|
|
308
|
+
messages: {
|
|
309
|
+
preferMatch: "Use Match from Effect instead of a chained literal ternary."
|
|
310
|
+
}
|
|
311
|
+
},
|
|
312
|
+
createOnce(context) {
|
|
313
|
+
const isLiteral = (node) => node.type === "Literal" || node.type === "TemplateLiteral" && node.expressions.length === 0;
|
|
314
|
+
const comparedValue = (node) => {
|
|
315
|
+
if (node.type !== "BinaryExpression" || !equalityOperators2.has(node.operator)) {
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
if (isLiteral(node.left))
|
|
319
|
+
return context.sourceCode.getText(node.right);
|
|
320
|
+
if (isLiteral(node.right))
|
|
321
|
+
return context.sourceCode.getText(node.left);
|
|
322
|
+
return;
|
|
323
|
+
};
|
|
324
|
+
return {
|
|
325
|
+
ConditionalExpression(node) {
|
|
326
|
+
if (node.parent?.type === "ConditionalExpression")
|
|
327
|
+
return;
|
|
328
|
+
const value = comparedValue(node.test);
|
|
329
|
+
if (value === undefined)
|
|
330
|
+
return;
|
|
331
|
+
let alternate = node.alternate;
|
|
332
|
+
let literalChecks = 1;
|
|
333
|
+
while (alternate.type === "ConditionalExpression") {
|
|
334
|
+
if (comparedValue(alternate.test) !== value)
|
|
335
|
+
return;
|
|
336
|
+
literalChecks += 1;
|
|
337
|
+
alternate = alternate.alternate;
|
|
338
|
+
}
|
|
339
|
+
if (literalChecks > 1) {
|
|
340
|
+
context.report({ node, messageId: "preferMatch" });
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
|
|
158
347
|
// vendor/anti-slop/src/effect/index.ts
|
|
159
348
|
var antiSlopEffectPlugin = eslintCompatPlugin2({
|
|
160
349
|
meta: { name: "anti-slop-effect" },
|
|
161
350
|
rules: {
|
|
162
|
-
"no-
|
|
351
|
+
"no-manual-effect-error-tag": noManualEffectErrorTagRule,
|
|
352
|
+
"no-manual-tag-comparison": noManualTagComparisonRule,
|
|
353
|
+
"no-manual-tagged-construction": noManualTaggedConstructionRule,
|
|
354
|
+
"no-service-constructor-imports": noServiceConstructorImportsRule,
|
|
355
|
+
"prefer-effect-match": preferEffectMatchRule
|
|
163
356
|
}
|
|
164
357
|
});
|
|
165
358
|
var effect_default2 = antiSlopEffectPlugin;
|
|
@@ -172,7 +365,7 @@ function enablePluginRules(namespace, plugin) {
|
|
|
172
365
|
import { eslintCompatPlugin as eslintCompatPlugin3 } from "@oxlint/plugins";
|
|
173
366
|
|
|
174
367
|
// vendor/anti-slop/src/rules/no-array-filter-map.ts
|
|
175
|
-
import { defineRule as
|
|
368
|
+
import { defineRule as defineRule7 } from "@oxlint/plugins";
|
|
176
369
|
|
|
177
370
|
// vendor/anti-slop/src/shared/array-method.ts
|
|
178
371
|
function unwrapArrayExpression(node) {
|
|
@@ -247,7 +440,7 @@ function isKnownArrayExpression(sourceCode, node, visited = new Set) {
|
|
|
247
440
|
}
|
|
248
441
|
|
|
249
442
|
// vendor/anti-slop/src/rules/no-array-filter-map.ts
|
|
250
|
-
var noArrayFilterMapRule =
|
|
443
|
+
var noArrayFilterMapRule = defineRule7({
|
|
251
444
|
meta: {
|
|
252
445
|
type: "suggestion",
|
|
253
446
|
docs: { description: "Disallow adjacent array filter/map passes in favor of lazy iterator helpers or a single transformation." },
|
|
@@ -276,7 +469,7 @@ var noArrayFilterMapRule = defineRule3({
|
|
|
276
469
|
});
|
|
277
470
|
|
|
278
471
|
// vendor/anti-slop/src/rules/no-reduce-accumulator-copy.ts
|
|
279
|
-
import { defineRule as
|
|
472
|
+
import { defineRule as defineRule8 } from "@oxlint/plugins";
|
|
280
473
|
function enclosingReducer(node) {
|
|
281
474
|
let parent = node.parent;
|
|
282
475
|
while (parent !== null) {
|
|
@@ -326,7 +519,7 @@ function isGlobalCopyOwner(sourceCode, node, name) {
|
|
|
326
519
|
const variable = resolveArrayBinding(sourceCode, node);
|
|
327
520
|
return variable === null || variable.defs.length === 0;
|
|
328
521
|
}
|
|
329
|
-
var noReduceAccumulatorCopyRule =
|
|
522
|
+
var noReduceAccumulatorCopyRule = defineRule8({
|
|
330
523
|
meta: {
|
|
331
524
|
type: "problem",
|
|
332
525
|
docs: { description: "Disallow copying growing reducer accumulators with Object.assign, Array.from, or array copy methods." },
|
|
@@ -367,7 +560,7 @@ var noReduceAccumulatorCopyRule = defineRule4({
|
|
|
367
560
|
});
|
|
368
561
|
|
|
369
562
|
// vendor/anti-slop/src/rules/no-chained-type-assertions.ts
|
|
370
|
-
import { defineRule as
|
|
563
|
+
import { defineRule as defineRule9 } from "@oxlint/plugins";
|
|
371
564
|
function isTypeAssertionExpression(node) {
|
|
372
565
|
return node.type === "TSAsExpression" || node.type === "TSTypeAssertion";
|
|
373
566
|
}
|
|
@@ -402,7 +595,7 @@ function isForbiddenAssertionChain(node) {
|
|
|
402
595
|
}
|
|
403
596
|
return assertionCount > 1 && hasNonConstAssertion;
|
|
404
597
|
}
|
|
405
|
-
var noChainedTypeAssertionsRule =
|
|
598
|
+
var noChainedTypeAssertionsRule = defineRule9({
|
|
406
599
|
meta: {
|
|
407
600
|
type: "problem",
|
|
408
601
|
docs: {
|
|
@@ -426,7 +619,7 @@ var noChainedTypeAssertionsRule = defineRule5({
|
|
|
426
619
|
});
|
|
427
620
|
|
|
428
621
|
// vendor/anti-slop/src/rules/no-conditional-empty-object-spread.ts
|
|
429
|
-
import { defineRule as
|
|
622
|
+
import { defineRule as defineRule10 } from "@oxlint/plugins";
|
|
430
623
|
function unwrapParentheses(node) {
|
|
431
624
|
let current = node;
|
|
432
625
|
while (current.type === "ParenthesizedExpression") {
|
|
@@ -441,7 +634,7 @@ function isConditionalEmptyObjectSpread(node) {
|
|
|
441
634
|
const conditional = unwrapParentheses(node);
|
|
442
635
|
return conditional.type === "ConditionalExpression" && (isEmptyObjectExpression(conditional.consequent) || isEmptyObjectExpression(conditional.alternate));
|
|
443
636
|
}
|
|
444
|
-
var noConditionalEmptyObjectSpreadRule =
|
|
637
|
+
var noConditionalEmptyObjectSpreadRule = defineRule10({
|
|
445
638
|
meta: {
|
|
446
639
|
type: "suggestion",
|
|
447
640
|
docs: {
|
|
@@ -465,7 +658,7 @@ var noConditionalEmptyObjectSpreadRule = defineRule6({
|
|
|
465
658
|
});
|
|
466
659
|
|
|
467
660
|
// vendor/anti-slop/src/rules/no-known-value-widening.ts
|
|
468
|
-
import { defineRule as
|
|
661
|
+
import { defineRule as defineRule11 } from "@oxlint/plugins";
|
|
469
662
|
|
|
470
663
|
// vendor/anti-slop/src/shared/lexical-type-parameters.ts
|
|
471
664
|
function isNode(value) {
|
|
@@ -994,14 +1187,7 @@ function functionParameterBindingName(parameter, sourceCode) {
|
|
|
994
1187
|
return annotationStart === undefined ? sourceText : sourceText.slice(0, annotationStart - parameter.start).trimEnd();
|
|
995
1188
|
}
|
|
996
1189
|
|
|
997
|
-
// vendor/anti-slop/src/
|
|
998
|
-
function unwrapExpression(expression) {
|
|
999
|
-
let current = expression;
|
|
1000
|
-
while (current.type === "ParenthesizedExpression" || current.type === "TSAsExpression" || current.type === "TSSatisfiesExpression" || current.type === "TSTypeAssertion" || current.type === "TSNonNullExpression") {
|
|
1001
|
-
current = current.expression;
|
|
1002
|
-
}
|
|
1003
|
-
return current;
|
|
1004
|
-
}
|
|
1190
|
+
// vendor/anti-slop/src/shared/scope.ts
|
|
1005
1191
|
function resolveVariable2(sourceCode, identifier) {
|
|
1006
1192
|
let scope = sourceCode.getScope(identifier);
|
|
1007
1193
|
while (scope !== null) {
|
|
@@ -1012,6 +1198,15 @@ function resolveVariable2(sourceCode, identifier) {
|
|
|
1012
1198
|
}
|
|
1013
1199
|
return null;
|
|
1014
1200
|
}
|
|
1201
|
+
|
|
1202
|
+
// vendor/anti-slop/src/rules/no-known-value-widening.ts
|
|
1203
|
+
function unwrapExpression(expression) {
|
|
1204
|
+
let current = expression;
|
|
1205
|
+
while (current.type === "ParenthesizedExpression" || current.type === "TSAsExpression" || current.type === "TSSatisfiesExpression" || current.type === "TSTypeAssertion" || current.type === "TSNonNullExpression") {
|
|
1206
|
+
current = current.expression;
|
|
1207
|
+
}
|
|
1208
|
+
return current;
|
|
1209
|
+
}
|
|
1015
1210
|
function variableDeclarator(variable) {
|
|
1016
1211
|
if (variable.defs.length !== 1)
|
|
1017
1212
|
return null;
|
|
@@ -1164,7 +1359,7 @@ function isDictionaryAccumulatorTarget(destination) {
|
|
|
1164
1359
|
function hasParentAssertion(node) {
|
|
1165
1360
|
return node.parent?.type === "TSAsExpression" || node.parent?.type === "TSTypeAssertion";
|
|
1166
1361
|
}
|
|
1167
|
-
var noKnownValueWideningRule =
|
|
1362
|
+
var noKnownValueWideningRule = defineRule11({
|
|
1168
1363
|
meta: {
|
|
1169
1364
|
type: "problem",
|
|
1170
1365
|
docs: {
|
|
@@ -1277,18 +1472,8 @@ var noKnownValueWideningRule = defineRule7({
|
|
|
1277
1472
|
});
|
|
1278
1473
|
|
|
1279
1474
|
// vendor/anti-slop/src/rules/no-module-mocking.ts
|
|
1280
|
-
import { defineRule as
|
|
1475
|
+
import { defineRule as defineRule12 } from "@oxlint/plugins";
|
|
1281
1476
|
var moduleMockMethods = new Set(["doMock", "mock", "unstable_mockModule"]);
|
|
1282
|
-
function resolveVariable3(sourceCode, identifier) {
|
|
1283
|
-
let scope = sourceCode.getScope(identifier);
|
|
1284
|
-
while (scope !== null) {
|
|
1285
|
-
const variable = scope.set.get(identifier.name);
|
|
1286
|
-
if (variable !== undefined)
|
|
1287
|
-
return variable;
|
|
1288
|
-
scope = scope.upper;
|
|
1289
|
-
}
|
|
1290
|
-
return null;
|
|
1291
|
-
}
|
|
1292
1477
|
function importedName(node) {
|
|
1293
1478
|
if (node.type !== "ImportSpecifier")
|
|
1294
1479
|
return null;
|
|
@@ -1300,7 +1485,7 @@ function isTestFrameworkObject(sourceCode, expression) {
|
|
|
1300
1485
|
if ((expression.name === "vi" || expression.name === "jest") && sourceCode.isGlobalReference(expression)) {
|
|
1301
1486
|
return true;
|
|
1302
1487
|
}
|
|
1303
|
-
const variable =
|
|
1488
|
+
const variable = resolveVariable2(sourceCode, expression);
|
|
1304
1489
|
if (variable === null || variable.defs.length === 0) {
|
|
1305
1490
|
return expression.name === "vi" || expression.name === "jest";
|
|
1306
1491
|
}
|
|
@@ -1322,7 +1507,7 @@ function moduleMockCall(sourceCode, callee) {
|
|
|
1322
1507
|
const method = callee.computed ? property.type === "Literal" && (property.value === "doMock" || property.value === "mock" || property.value === "unstable_mockModule") ? property.value : null : property.type === "Identifier" ? property.name : null;
|
|
1323
1508
|
return method !== null && moduleMockMethods.has(method);
|
|
1324
1509
|
}
|
|
1325
|
-
var noModuleMockingRule =
|
|
1510
|
+
var noModuleMockingRule = defineRule12({
|
|
1326
1511
|
meta: {
|
|
1327
1512
|
type: "problem",
|
|
1328
1513
|
docs: {
|
|
@@ -1346,8 +1531,8 @@ var noModuleMockingRule = defineRule8({
|
|
|
1346
1531
|
});
|
|
1347
1532
|
|
|
1348
1533
|
// vendor/anti-slop/src/rules/no-object-parameters.ts
|
|
1349
|
-
import { defineRule as
|
|
1350
|
-
var noObjectParametersRule =
|
|
1534
|
+
import { defineRule as defineRule13 } from "@oxlint/plugins";
|
|
1535
|
+
var noObjectParametersRule = defineRule13({
|
|
1351
1536
|
meta: {
|
|
1352
1537
|
type: "problem",
|
|
1353
1538
|
docs: {
|
|
@@ -1400,25 +1585,15 @@ var noObjectParametersRule = defineRule9({
|
|
|
1400
1585
|
});
|
|
1401
1586
|
|
|
1402
1587
|
// vendor/anti-slop/src/rules/no-reflect-apply.ts
|
|
1403
|
-
import { defineRule as
|
|
1588
|
+
import { defineRule as defineRule14 } from "@oxlint/plugins";
|
|
1404
1589
|
|
|
1405
1590
|
// vendor/anti-slop/src/shared/reflect-method.ts
|
|
1406
|
-
function resolveVariable4(sourceCode, identifier) {
|
|
1407
|
-
let scope = sourceCode.getScope(identifier);
|
|
1408
|
-
while (scope !== null) {
|
|
1409
|
-
const variable = scope.set.get(identifier.name);
|
|
1410
|
-
if (variable !== undefined)
|
|
1411
|
-
return variable;
|
|
1412
|
-
scope = scope.upper;
|
|
1413
|
-
}
|
|
1414
|
-
return null;
|
|
1415
|
-
}
|
|
1416
1591
|
function isGlobalReflect(sourceCode, expression) {
|
|
1417
1592
|
if (expression.type !== "Identifier" || expression.name !== "Reflect")
|
|
1418
1593
|
return false;
|
|
1419
1594
|
if (sourceCode.isGlobalReference(expression))
|
|
1420
1595
|
return true;
|
|
1421
|
-
const variable =
|
|
1596
|
+
const variable = resolveVariable2(sourceCode, expression);
|
|
1422
1597
|
return variable === null || variable.defs.length === 0;
|
|
1423
1598
|
}
|
|
1424
1599
|
function isGlobalReflectMethodCall(sourceCode, callee, methodName) {
|
|
@@ -1431,7 +1606,7 @@ function isGlobalReflectMethodCall(sourceCode, callee, methodName) {
|
|
|
1431
1606
|
}
|
|
1432
1607
|
|
|
1433
1608
|
// vendor/anti-slop/src/rules/no-reflect-apply.ts
|
|
1434
|
-
var noReflectApplyRule =
|
|
1609
|
+
var noReflectApplyRule = defineRule14({
|
|
1435
1610
|
meta: {
|
|
1436
1611
|
type: "problem",
|
|
1437
1612
|
docs: {
|
|
@@ -1455,8 +1630,8 @@ var noReflectApplyRule = defineRule10({
|
|
|
1455
1630
|
});
|
|
1456
1631
|
|
|
1457
1632
|
// vendor/anti-slop/src/rules/no-reflect-get.ts
|
|
1458
|
-
import { defineRule as
|
|
1459
|
-
var noReflectGetRule =
|
|
1633
|
+
import { defineRule as defineRule15 } from "@oxlint/plugins";
|
|
1634
|
+
var noReflectGetRule = defineRule15({
|
|
1460
1635
|
meta: {
|
|
1461
1636
|
type: "problem",
|
|
1462
1637
|
docs: {
|
|
@@ -1480,7 +1655,7 @@ var noReflectGetRule = defineRule11({
|
|
|
1480
1655
|
});
|
|
1481
1656
|
|
|
1482
1657
|
// vendor/anti-slop/src/rules/no-runtime-typeof.ts
|
|
1483
|
-
import { defineRule as
|
|
1658
|
+
import { defineRule as defineRule16 } from "@oxlint/plugins";
|
|
1484
1659
|
function isRuntimeFunction(node) {
|
|
1485
1660
|
return node.type === "ArrowFunctionExpression" || node.type === "FunctionDeclaration" || node.type === "FunctionExpression";
|
|
1486
1661
|
}
|
|
@@ -1503,7 +1678,7 @@ function isExistenceProbe(node) {
|
|
|
1503
1678
|
const other = parent.left === node ? parent.right : parent.left;
|
|
1504
1679
|
return other.type === "Literal" && other.value === "undefined";
|
|
1505
1680
|
}
|
|
1506
|
-
var noRuntimeTypeofRule =
|
|
1681
|
+
var noRuntimeTypeofRule = defineRule16({
|
|
1507
1682
|
meta: {
|
|
1508
1683
|
type: "problem",
|
|
1509
1684
|
docs: {
|
|
@@ -1537,7 +1712,7 @@ var noRuntimeTypeofRule = defineRule12({
|
|
|
1537
1712
|
});
|
|
1538
1713
|
|
|
1539
1714
|
// vendor/anti-slop/src/rules/no-shape-in-symbol-names.ts
|
|
1540
|
-
import { defineRule as
|
|
1715
|
+
import { defineRule as defineRule17 } from "@oxlint/plugins";
|
|
1541
1716
|
var FORBIDDEN_SYMBOL_NAME = "shape";
|
|
1542
1717
|
function containsForbiddenSymbolName(name) {
|
|
1543
1718
|
return name.toLowerCase().includes(FORBIDDEN_SYMBOL_NAME);
|
|
@@ -1548,7 +1723,7 @@ function isBorrowedMemberName(node) {
|
|
|
1548
1723
|
return false;
|
|
1549
1724
|
return parent.property === node && parent.computed === false;
|
|
1550
1725
|
}
|
|
1551
|
-
var noForbiddenTermInSymbolNamesRule =
|
|
1726
|
+
var noForbiddenTermInSymbolNamesRule = defineRule17({
|
|
1552
1727
|
meta: {
|
|
1553
1728
|
type: "problem",
|
|
1554
1729
|
docs: {
|
|
@@ -1577,12 +1752,12 @@ var noForbiddenTermInSymbolNamesRule = defineRule13({
|
|
|
1577
1752
|
});
|
|
1578
1753
|
|
|
1579
1754
|
// vendor/anti-slop/src/rules/no-unknown-parameters.ts
|
|
1580
|
-
import { defineRule as
|
|
1755
|
+
import { defineRule as defineRule18 } from "@oxlint/plugins";
|
|
1581
1756
|
function isTypePredicateSubject(owner, parameterName) {
|
|
1582
1757
|
const predicate = owner.returnType?.typeAnnotation;
|
|
1583
1758
|
return predicate?.type === "TSTypePredicate" && predicate.parameterName.type === "Identifier" && predicate.parameterName.name === parameterName;
|
|
1584
1759
|
}
|
|
1585
|
-
var noUnknownParametersRule =
|
|
1760
|
+
var noUnknownParametersRule = defineRule18({
|
|
1586
1761
|
meta: {
|
|
1587
1762
|
type: "problem",
|
|
1588
1763
|
docs: {
|
|
@@ -1626,8 +1801,8 @@ var noUnknownParametersRule = defineRule14({
|
|
|
1626
1801
|
});
|
|
1627
1802
|
|
|
1628
1803
|
// vendor/anti-slop/src/rules/no-unknown-returns.ts
|
|
1629
|
-
import { defineRule as
|
|
1630
|
-
var noUnknownReturnsRule =
|
|
1804
|
+
import { defineRule as defineRule19 } from "@oxlint/plugins";
|
|
1805
|
+
var noUnknownReturnsRule = defineRule19({
|
|
1631
1806
|
meta: {
|
|
1632
1807
|
type: "problem",
|
|
1633
1808
|
docs: {
|
|
@@ -1680,8 +1855,8 @@ var noUnknownReturnsRule = defineRule15({
|
|
|
1680
1855
|
});
|
|
1681
1856
|
|
|
1682
1857
|
// vendor/anti-slop/src/rules/no-unknown-type-aliases.ts
|
|
1683
|
-
import { defineRule as
|
|
1684
|
-
var noUnknownTypeAliasesRule =
|
|
1858
|
+
import { defineRule as defineRule20 } from "@oxlint/plugins";
|
|
1859
|
+
var noUnknownTypeAliasesRule = defineRule20({
|
|
1685
1860
|
meta: {
|
|
1686
1861
|
type: "problem",
|
|
1687
1862
|
docs: {
|
|
@@ -1719,7 +1894,7 @@ var noUnknownTypeAliasesRule = defineRule16({
|
|
|
1719
1894
|
});
|
|
1720
1895
|
|
|
1721
1896
|
// vendor/anti-slop/src/rules/no-unsafe-dictionary-type.ts
|
|
1722
|
-
import { defineRule as
|
|
1897
|
+
import { defineRule as defineRule21 } from "@oxlint/plugins";
|
|
1723
1898
|
var typeNodeKinds = new Set([
|
|
1724
1899
|
"JSDocNonNullableType",
|
|
1725
1900
|
"JSDocNullableType",
|
|
@@ -1806,7 +1981,7 @@ function shouldReportType(node, environment) {
|
|
|
1806
1981
|
}
|
|
1807
1982
|
return true;
|
|
1808
1983
|
}
|
|
1809
|
-
var noUnsafeDictionaryTypeRule =
|
|
1984
|
+
var noUnsafeDictionaryTypeRule = defineRule21({
|
|
1810
1985
|
meta: {
|
|
1811
1986
|
type: "problem",
|
|
1812
1987
|
docs: {
|
|
@@ -1848,7 +2023,7 @@ var noUnsafeDictionaryTypeRule = defineRule17({
|
|
|
1848
2023
|
});
|
|
1849
2024
|
|
|
1850
2025
|
// vendor/anti-slop/src/rules/no-widen-then-assert.ts
|
|
1851
|
-
import { defineRule as
|
|
2026
|
+
import { defineRule as defineRule22 } from "@oxlint/plugins";
|
|
1852
2027
|
var functionBoundaryTypes = new Set([
|
|
1853
2028
|
"ArrowFunctionExpression",
|
|
1854
2029
|
"FunctionDeclaration",
|
|
@@ -2044,7 +2219,7 @@ function assertionIsNarrower(sourceText, broadKind, evidence, assertedType) {
|
|
|
2044
2219
|
return isDefinitelyObjectType(assertedType);
|
|
2045
2220
|
return isDefinitelyNarrowerRecordType(assertedType);
|
|
2046
2221
|
}
|
|
2047
|
-
var noWidenThenAssertRule =
|
|
2222
|
+
var noWidenThenAssertRule = defineRule22({
|
|
2048
2223
|
meta: {
|
|
2049
2224
|
type: "problem",
|
|
2050
2225
|
docs: {
|
|
@@ -2083,8 +2258,530 @@ var noWidenThenAssertRule = defineRule18({
|
|
|
2083
2258
|
}
|
|
2084
2259
|
});
|
|
2085
2260
|
|
|
2261
|
+
// vendor/anti-slop/src/vendor/eslint-stylistic/padding-line-ast.ts
|
|
2262
|
+
var LINEBREAKS = new Set([`\r
|
|
2263
|
+
`, "\r", `
|
|
2264
|
+
`, "\u2028", "\u2029"]);
|
|
2265
|
+
var isClosingBraceToken = (token) => token.type === "Punctuator" && token.value === "}";
|
|
2266
|
+
var isSemicolonToken = (token) => token.type === "Punctuator" && token.value === ";";
|
|
2267
|
+
var isNotSemicolonToken = (token) => !isSemicolonToken(token);
|
|
2268
|
+
var isTokenOnSameLine = (left, right) => left.loc.end.line === right.loc.start.line;
|
|
2269
|
+
var isFunction = (node) => node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression";
|
|
2270
|
+
var isSingleLine = (node) => node.loc.start.line === node.loc.end.line;
|
|
2271
|
+
var skipChainExpression = (node) => node.type === "ChainExpression" ? node.expression : node;
|
|
2272
|
+
var isTopLevelExpressionStatement = (node) => node.type === "ExpressionStatement" && (node.parent.type === "Program" || node.parent.type === "BlockStatement" && isFunction(node.parent.parent));
|
|
2273
|
+
function isParenthesized(node, sourceCode) {
|
|
2274
|
+
const before = sourceCode.getTokenBefore(node);
|
|
2275
|
+
const after = sourceCode.getTokenAfter(node);
|
|
2276
|
+
return before?.value === "(" && after?.value === ")";
|
|
2277
|
+
}
|
|
2278
|
+
|
|
2279
|
+
// vendor/anti-slop/src/vendor/eslint-stylistic/padding-line-between-statements.ts
|
|
2280
|
+
var CJS_EXPORT = /^(?:module\s*\.\s*)?exports(?:\s*\.|\s*\[|$)/u;
|
|
2281
|
+
var CJS_IMPORT = /^require\(/u;
|
|
2282
|
+
var LT = `[${Array.from(LINEBREAKS).join("")}]`;
|
|
2283
|
+
var PADDING_LINE_SEQUENCE = new RegExp(String.raw`^(\s*?${LT})\s*${LT}(\s*;?)$`, "u");
|
|
2284
|
+
function isSelectorOption(option) {
|
|
2285
|
+
return typeof option === "object" && !Array.isArray(option);
|
|
2286
|
+
}
|
|
2287
|
+
function newKeywordTester(type, keyword) {
|
|
2288
|
+
return {
|
|
2289
|
+
test(node, sourceCode) {
|
|
2290
|
+
const isSameKeyword = sourceCode.getFirstToken(node)?.value === keyword;
|
|
2291
|
+
const isSameType = Array.isArray(type) ? type.includes(node.type) : type === node.type;
|
|
2292
|
+
return isSameKeyword && isSameType;
|
|
2293
|
+
}
|
|
2294
|
+
};
|
|
2295
|
+
}
|
|
2296
|
+
function newNodeTypeTester(type) {
|
|
2297
|
+
return {
|
|
2298
|
+
test: (node) => node.type === type
|
|
2299
|
+
};
|
|
2300
|
+
}
|
|
2301
|
+
function isIIFEStatement(node) {
|
|
2302
|
+
if (node.type === "ExpressionStatement") {
|
|
2303
|
+
let expression = skipChainExpression(node.expression);
|
|
2304
|
+
if (expression.type === "UnaryExpression")
|
|
2305
|
+
expression = skipChainExpression(expression.argument);
|
|
2306
|
+
if (expression.type === "CallExpression") {
|
|
2307
|
+
let node = expression.callee;
|
|
2308
|
+
while (node.type === "SequenceExpression") {
|
|
2309
|
+
const lastExpression = node.expressions.at(-1);
|
|
2310
|
+
if (lastExpression === undefined)
|
|
2311
|
+
throw new Error("Padding rule invariant: sequence expression is empty");
|
|
2312
|
+
node = lastExpression;
|
|
2313
|
+
}
|
|
2314
|
+
return isFunction(node);
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
return false;
|
|
2318
|
+
}
|
|
2319
|
+
function isCJSRequire(node) {
|
|
2320
|
+
if (node.type === "VariableDeclaration") {
|
|
2321
|
+
const declaration = node.declarations[0];
|
|
2322
|
+
if (declaration?.init) {
|
|
2323
|
+
let call = declaration?.init;
|
|
2324
|
+
while (call.type === "MemberExpression")
|
|
2325
|
+
call = call.object;
|
|
2326
|
+
if (call.type === "CallExpression" && call.callee.type === "Identifier") {
|
|
2327
|
+
return call.callee.name === "require";
|
|
2328
|
+
}
|
|
2329
|
+
}
|
|
2330
|
+
}
|
|
2331
|
+
return false;
|
|
2332
|
+
}
|
|
2333
|
+
function isBlockLikeStatement(node, sourceCode) {
|
|
2334
|
+
if (node.type === "DoWhileStatement" && node.body.type === "BlockStatement") {
|
|
2335
|
+
return true;
|
|
2336
|
+
}
|
|
2337
|
+
if (isIIFEStatement(node))
|
|
2338
|
+
return true;
|
|
2339
|
+
const lastToken = sourceCode.getLastToken(node, isNotSemicolonToken);
|
|
2340
|
+
const belongingNode = lastToken && isClosingBraceToken(lastToken) ? sourceCode.getNodeByRangeIndex(lastToken.range[0]) : null;
|
|
2341
|
+
return !!belongingNode && (belongingNode.type === "BlockStatement" || belongingNode.type === "SwitchStatement");
|
|
2342
|
+
}
|
|
2343
|
+
function isDirective(node, sourceCode) {
|
|
2344
|
+
return isTopLevelExpressionStatement(node) && node.expression.type === "Literal" && typeof node.expression.value === "string" && !isParenthesized(node.expression, sourceCode);
|
|
2345
|
+
}
|
|
2346
|
+
function isDirectivePrologue(node, sourceCode) {
|
|
2347
|
+
if (isDirective(node, sourceCode) && node.parent && "body" in node.parent && Array.isArray(node.parent.body)) {
|
|
2348
|
+
for (const sibling of node.parent.body) {
|
|
2349
|
+
if (sibling === node)
|
|
2350
|
+
break;
|
|
2351
|
+
if (!isDirective(sibling, sourceCode))
|
|
2352
|
+
return false;
|
|
2353
|
+
}
|
|
2354
|
+
return true;
|
|
2355
|
+
}
|
|
2356
|
+
return false;
|
|
2357
|
+
}
|
|
2358
|
+
function isCJSExport(node) {
|
|
2359
|
+
if (node.type === "ExpressionStatement") {
|
|
2360
|
+
const expression = node.expression;
|
|
2361
|
+
if (expression.type === "AssignmentExpression") {
|
|
2362
|
+
let left = expression.left;
|
|
2363
|
+
if (left.type === "MemberExpression") {
|
|
2364
|
+
while (left.object.type === "MemberExpression")
|
|
2365
|
+
left = left.object;
|
|
2366
|
+
return left.object.type === "Identifier" && (left.object.name === "exports" || left.object.name === "module" && left.property.type === "Identifier" && left.property.name === "exports");
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2370
|
+
return false;
|
|
2371
|
+
}
|
|
2372
|
+
function isExpression(node, sourceCode) {
|
|
2373
|
+
return node.type === "ExpressionStatement" && !isDirectivePrologue(node, sourceCode);
|
|
2374
|
+
}
|
|
2375
|
+
function getActualLastToken(node, sourceCode) {
|
|
2376
|
+
const semiToken = sourceCode.getLastToken(node);
|
|
2377
|
+
const prevToken = sourceCode.getTokenBefore(semiToken);
|
|
2378
|
+
const nextToken = sourceCode.getTokenAfter(semiToken);
|
|
2379
|
+
const isSemicolonLessStyle = prevToken && nextToken && prevToken.range[0] >= node.range[0] && isSemicolonToken(semiToken) && !isTokenOnSameLine(prevToken, semiToken) && isTokenOnSameLine(semiToken, nextToken);
|
|
2380
|
+
return isSemicolonLessStyle ? prevToken : semiToken;
|
|
2381
|
+
}
|
|
2382
|
+
function replacerToRemovePaddingLines(_, trailingSpaces, indentSpaces) {
|
|
2383
|
+
return trailingSpaces + indentSpaces;
|
|
2384
|
+
}
|
|
2385
|
+
function getReportLoc(node, sourceCode) {
|
|
2386
|
+
if (isSingleLine(node))
|
|
2387
|
+
return node.loc;
|
|
2388
|
+
const line = node.loc.start.line;
|
|
2389
|
+
const sourceLine = sourceCode.lines[line - 1];
|
|
2390
|
+
if (sourceLine === undefined)
|
|
2391
|
+
throw new Error("Padding rule invariant: statement source line is missing");
|
|
2392
|
+
return {
|
|
2393
|
+
start: node.loc.start,
|
|
2394
|
+
end: {
|
|
2395
|
+
line,
|
|
2396
|
+
column: sourceLine.length
|
|
2397
|
+
}
|
|
2398
|
+
};
|
|
2399
|
+
}
|
|
2400
|
+
function verifyForAny() {}
|
|
2401
|
+
function verifyForNever(context, _, nextNode, paddingLines) {
|
|
2402
|
+
if (paddingLines.length === 0)
|
|
2403
|
+
return;
|
|
2404
|
+
context.report({
|
|
2405
|
+
node: nextNode,
|
|
2406
|
+
messageId: "unexpectedBlankLine",
|
|
2407
|
+
loc: getReportLoc(nextNode, context.sourceCode),
|
|
2408
|
+
fix(fixer) {
|
|
2409
|
+
if (paddingLines.length >= 2)
|
|
2410
|
+
return null;
|
|
2411
|
+
const paddingPair = paddingLines[0];
|
|
2412
|
+
if (paddingPair === undefined)
|
|
2413
|
+
throw new Error("Padding rule invariant: reported padding pair is missing");
|
|
2414
|
+
const [prevToken, nextToken] = paddingPair;
|
|
2415
|
+
const start = prevToken.range[1];
|
|
2416
|
+
const end = nextToken.range[0];
|
|
2417
|
+
const text = context.sourceCode.text.slice(start, end).replace(PADDING_LINE_SEQUENCE, replacerToRemovePaddingLines);
|
|
2418
|
+
return fixer.replaceTextRange([start, end], text);
|
|
2419
|
+
}
|
|
2420
|
+
});
|
|
2421
|
+
}
|
|
2422
|
+
function verifyForAlways(context, prevNode, nextNode, paddingLines) {
|
|
2423
|
+
if (paddingLines.length > 0)
|
|
2424
|
+
return;
|
|
2425
|
+
context.report({
|
|
2426
|
+
node: nextNode,
|
|
2427
|
+
messageId: "expectedBlankLine",
|
|
2428
|
+
loc: getReportLoc(nextNode, context.sourceCode),
|
|
2429
|
+
fix(fixer) {
|
|
2430
|
+
const sourceCode = context.sourceCode;
|
|
2431
|
+
let prevToken = getActualLastToken(prevNode, sourceCode);
|
|
2432
|
+
const nextToken = sourceCode.getFirstTokenBetween(prevToken, nextNode, {
|
|
2433
|
+
includeComments: true,
|
|
2434
|
+
filter(token) {
|
|
2435
|
+
if (isTokenOnSameLine(prevToken, token)) {
|
|
2436
|
+
prevToken = token;
|
|
2437
|
+
return false;
|
|
2438
|
+
}
|
|
2439
|
+
return true;
|
|
2440
|
+
}
|
|
2441
|
+
}) || nextNode;
|
|
2442
|
+
const insertText = isTokenOnSameLine(prevToken, nextToken) ? `
|
|
2443
|
+
|
|
2444
|
+
` : `
|
|
2445
|
+
`;
|
|
2446
|
+
return fixer.insertTextAfter(prevToken, insertText);
|
|
2447
|
+
}
|
|
2448
|
+
});
|
|
2449
|
+
}
|
|
2450
|
+
var PaddingTypes = {
|
|
2451
|
+
any: { verify: verifyForAny },
|
|
2452
|
+
never: { verify: verifyForNever },
|
|
2453
|
+
always: { verify: verifyForAlways }
|
|
2454
|
+
};
|
|
2455
|
+
var MaybeMultilineStatementType = {
|
|
2456
|
+
"block-like": { test: isBlockLikeStatement },
|
|
2457
|
+
expression: { test: isExpression },
|
|
2458
|
+
return: newKeywordTester("ReturnStatement", "return"),
|
|
2459
|
+
export: newKeywordTester([
|
|
2460
|
+
"ExportAllDeclaration",
|
|
2461
|
+
"ExportDefaultDeclaration",
|
|
2462
|
+
"ExportNamedDeclaration"
|
|
2463
|
+
], "export"),
|
|
2464
|
+
var: newKeywordTester("VariableDeclaration", "var"),
|
|
2465
|
+
let: newKeywordTester("VariableDeclaration", "let"),
|
|
2466
|
+
const: newKeywordTester("VariableDeclaration", "const"),
|
|
2467
|
+
using: {
|
|
2468
|
+
test: (node) => node.type === "VariableDeclaration" && (node.kind === "using" || node.kind === "await using")
|
|
2469
|
+
},
|
|
2470
|
+
type: newKeywordTester("TSTypeAliasDeclaration", "type")
|
|
2471
|
+
};
|
|
2472
|
+
var StatementTypes = {
|
|
2473
|
+
"*": { test: () => true },
|
|
2474
|
+
exports: { test: isCJSExport },
|
|
2475
|
+
require: { test: isCJSRequire },
|
|
2476
|
+
directive: { test: isDirectivePrologue },
|
|
2477
|
+
iife: { test: isIIFEStatement },
|
|
2478
|
+
block: newNodeTypeTester("BlockStatement"),
|
|
2479
|
+
empty: newNodeTypeTester("EmptyStatement"),
|
|
2480
|
+
function: newNodeTypeTester("FunctionDeclaration"),
|
|
2481
|
+
"ts-method": newNodeTypeTester("TSMethodSignature"),
|
|
2482
|
+
break: newKeywordTester("BreakStatement", "break"),
|
|
2483
|
+
case: newKeywordTester("SwitchCase", "case"),
|
|
2484
|
+
class: newKeywordTester("ClassDeclaration", "class"),
|
|
2485
|
+
continue: newKeywordTester("ContinueStatement", "continue"),
|
|
2486
|
+
debugger: newKeywordTester("DebuggerStatement", "debugger"),
|
|
2487
|
+
default: newKeywordTester(["SwitchCase", "ExportDefaultDeclaration"], "default"),
|
|
2488
|
+
do: newKeywordTester("DoWhileStatement", "do"),
|
|
2489
|
+
for: newKeywordTester([
|
|
2490
|
+
"ForStatement",
|
|
2491
|
+
"ForInStatement",
|
|
2492
|
+
"ForOfStatement"
|
|
2493
|
+
], "for"),
|
|
2494
|
+
if: newKeywordTester("IfStatement", "if"),
|
|
2495
|
+
import: newKeywordTester("ImportDeclaration", "import"),
|
|
2496
|
+
switch: newKeywordTester("SwitchStatement", "switch"),
|
|
2497
|
+
throw: newKeywordTester("ThrowStatement", "throw"),
|
|
2498
|
+
try: newKeywordTester("TryStatement", "try"),
|
|
2499
|
+
while: newKeywordTester(["WhileStatement", "DoWhileStatement"], "while"),
|
|
2500
|
+
with: newKeywordTester("WithStatement", "with"),
|
|
2501
|
+
"cjs-export": {
|
|
2502
|
+
test: (node, sourceCode) => node.type === "ExpressionStatement" && node.expression.type === "AssignmentExpression" && CJS_EXPORT.test(sourceCode.getText(node.expression.left))
|
|
2503
|
+
},
|
|
2504
|
+
"cjs-import": {
|
|
2505
|
+
test: (node, sourceCode) => node.type === "VariableDeclaration" && node.declarations.length > 0 && node.declarations[0]?.init != null && CJS_IMPORT.test(sourceCode.getText(node.declarations[0].init))
|
|
2506
|
+
},
|
|
2507
|
+
enum: newKeywordTester("TSEnumDeclaration", "enum"),
|
|
2508
|
+
interface: newKeywordTester("TSInterfaceDeclaration", "interface"),
|
|
2509
|
+
"function-overload": newNodeTypeTester("TSDeclareFunction"),
|
|
2510
|
+
...Object.fromEntries(Object.entries(MaybeMultilineStatementType).flatMap(([key, value]) => [
|
|
2511
|
+
[key, value],
|
|
2512
|
+
[
|
|
2513
|
+
`singleline-${key}`,
|
|
2514
|
+
{
|
|
2515
|
+
...value,
|
|
2516
|
+
test: (node, sourceCode) => value.test(node, sourceCode) && isSingleLine(node)
|
|
2517
|
+
}
|
|
2518
|
+
],
|
|
2519
|
+
[
|
|
2520
|
+
`multiline-${key}`,
|
|
2521
|
+
{
|
|
2522
|
+
...value,
|
|
2523
|
+
test: (node, sourceCode) => value.test(node, sourceCode) && !isSingleLine(node)
|
|
2524
|
+
}
|
|
2525
|
+
]
|
|
2526
|
+
]))
|
|
2527
|
+
};
|
|
2528
|
+
function createPaddingLineRule(options) {
|
|
2529
|
+
return {
|
|
2530
|
+
meta: {
|
|
2531
|
+
type: "layout",
|
|
2532
|
+
docs: {
|
|
2533
|
+
description: "Require or disallow padding lines between statements"
|
|
2534
|
+
},
|
|
2535
|
+
fixable: "whitespace",
|
|
2536
|
+
hasSuggestions: false,
|
|
2537
|
+
schema: {
|
|
2538
|
+
$defs: {
|
|
2539
|
+
paddingType: {
|
|
2540
|
+
type: "string",
|
|
2541
|
+
enum: Object.keys(PaddingTypes)
|
|
2542
|
+
},
|
|
2543
|
+
statementType: {
|
|
2544
|
+
type: "string",
|
|
2545
|
+
enum: Object.keys(StatementTypes)
|
|
2546
|
+
},
|
|
2547
|
+
selectorOption: {
|
|
2548
|
+
type: "object",
|
|
2549
|
+
properties: {
|
|
2550
|
+
selector: {
|
|
2551
|
+
type: "string"
|
|
2552
|
+
},
|
|
2553
|
+
lineMode: {
|
|
2554
|
+
type: "string",
|
|
2555
|
+
enum: ["any", "singleline", "multiline"]
|
|
2556
|
+
}
|
|
2557
|
+
},
|
|
2558
|
+
required: ["selector"],
|
|
2559
|
+
additionalProperties: false
|
|
2560
|
+
},
|
|
2561
|
+
statementMatcher: {
|
|
2562
|
+
anyOf: [
|
|
2563
|
+
{ $ref: "#/$defs/statementType" },
|
|
2564
|
+
{ $ref: "#/$defs/selectorOption" }
|
|
2565
|
+
]
|
|
2566
|
+
},
|
|
2567
|
+
statementOption: {
|
|
2568
|
+
anyOf: [
|
|
2569
|
+
{ $ref: "#/$defs/statementMatcher" },
|
|
2570
|
+
{
|
|
2571
|
+
type: "array",
|
|
2572
|
+
items: { $ref: "#/$defs/statementMatcher" },
|
|
2573
|
+
minItems: 1,
|
|
2574
|
+
uniqueItems: true,
|
|
2575
|
+
additionalItems: false
|
|
2576
|
+
}
|
|
2577
|
+
]
|
|
2578
|
+
}
|
|
2579
|
+
},
|
|
2580
|
+
type: "array",
|
|
2581
|
+
additionalItems: false,
|
|
2582
|
+
items: {
|
|
2583
|
+
type: "object",
|
|
2584
|
+
properties: {
|
|
2585
|
+
blankLine: { $ref: "#/$defs/paddingType" },
|
|
2586
|
+
prev: { $ref: "#/$defs/statementOption" },
|
|
2587
|
+
next: { $ref: "#/$defs/statementOption" }
|
|
2588
|
+
},
|
|
2589
|
+
additionalProperties: false,
|
|
2590
|
+
required: ["blankLine", "prev", "next"]
|
|
2591
|
+
}
|
|
2592
|
+
},
|
|
2593
|
+
messages: {
|
|
2594
|
+
unexpectedBlankLine: "Unexpected blank line before this statement.",
|
|
2595
|
+
expectedBlankLine: "Expected blank line before this statement."
|
|
2596
|
+
}
|
|
2597
|
+
},
|
|
2598
|
+
create(context) {
|
|
2599
|
+
const sourceCode = context.sourceCode;
|
|
2600
|
+
const selectorMatchedNodes = new Map;
|
|
2601
|
+
const pendingPairs = [];
|
|
2602
|
+
function collectSelectorOption(option) {
|
|
2603
|
+
if (Array.isArray(option)) {
|
|
2604
|
+
for (const item of option)
|
|
2605
|
+
collectSelectorOption(item);
|
|
2606
|
+
return;
|
|
2607
|
+
}
|
|
2608
|
+
if (!isSelectorOption(option))
|
|
2609
|
+
return;
|
|
2610
|
+
selectorMatchedNodes.set(option.selector, new Set);
|
|
2611
|
+
}
|
|
2612
|
+
for (const configure of options) {
|
|
2613
|
+
collectSelectorOption(configure.prev);
|
|
2614
|
+
collectSelectorOption(configure.next);
|
|
2615
|
+
}
|
|
2616
|
+
let scopeInfo = null;
|
|
2617
|
+
function enterScope() {
|
|
2618
|
+
scopeInfo = {
|
|
2619
|
+
upper: scopeInfo,
|
|
2620
|
+
prevNode: null
|
|
2621
|
+
};
|
|
2622
|
+
}
|
|
2623
|
+
function exitScope() {
|
|
2624
|
+
if (scopeInfo)
|
|
2625
|
+
scopeInfo = scopeInfo.upper;
|
|
2626
|
+
}
|
|
2627
|
+
function match(node, type) {
|
|
2628
|
+
let innerStatementNode = node;
|
|
2629
|
+
while (innerStatementNode.type === "LabeledStatement")
|
|
2630
|
+
innerStatementNode = innerStatementNode.body;
|
|
2631
|
+
if (Array.isArray(type))
|
|
2632
|
+
return type.some(match.bind(null, innerStatementNode));
|
|
2633
|
+
if (isSelectorOption(type)) {
|
|
2634
|
+
const matchedNodes = selectorMatchedNodes.get(type.selector);
|
|
2635
|
+
if (!matchedNodes?.has(innerStatementNode))
|
|
2636
|
+
return false;
|
|
2637
|
+
const lineMode = type.lineMode;
|
|
2638
|
+
if (lineMode === "singleline")
|
|
2639
|
+
return isSingleLine(innerStatementNode);
|
|
2640
|
+
else if (lineMode === "multiline")
|
|
2641
|
+
return !isSingleLine(innerStatementNode);
|
|
2642
|
+
return true;
|
|
2643
|
+
} else {
|
|
2644
|
+
const statementType = StatementTypes[type];
|
|
2645
|
+
if (statementType === undefined)
|
|
2646
|
+
throw new Error(`Padding rule invariant: unsupported statement type ${type}`);
|
|
2647
|
+
return statementType.test(innerStatementNode, sourceCode);
|
|
2648
|
+
}
|
|
2649
|
+
}
|
|
2650
|
+
function getPaddingType(prevNode, nextNode) {
|
|
2651
|
+
for (let i = options.length - 1;i >= 0; --i) {
|
|
2652
|
+
const configure = options[i];
|
|
2653
|
+
if (configure === undefined)
|
|
2654
|
+
throw new Error("Padding rule invariant: configuration entry is missing");
|
|
2655
|
+
if (match(prevNode, configure.prev) && match(nextNode, configure.next)) {
|
|
2656
|
+
return PaddingTypes[configure.blankLine];
|
|
2657
|
+
}
|
|
2658
|
+
}
|
|
2659
|
+
return PaddingTypes.any;
|
|
2660
|
+
}
|
|
2661
|
+
function getPaddingLineSequences(prevNode, nextNode) {
|
|
2662
|
+
const pairs = [];
|
|
2663
|
+
let prevToken = getActualLastToken(prevNode, sourceCode);
|
|
2664
|
+
if (nextNode.loc.start.line - prevToken.loc.end.line >= 2) {
|
|
2665
|
+
do {
|
|
2666
|
+
const token = sourceCode.getTokenAfter(prevToken, {
|
|
2667
|
+
includeComments: true
|
|
2668
|
+
});
|
|
2669
|
+
if (token.loc.start.line - prevToken.loc.end.line >= 2)
|
|
2670
|
+
pairs.push([prevToken, token]);
|
|
2671
|
+
prevToken = token;
|
|
2672
|
+
} while (prevToken.range[0] < nextNode.range[0]);
|
|
2673
|
+
}
|
|
2674
|
+
return pairs;
|
|
2675
|
+
}
|
|
2676
|
+
function verify(node) {
|
|
2677
|
+
if (!node.parent || ![
|
|
2678
|
+
"BlockStatement",
|
|
2679
|
+
"Program",
|
|
2680
|
+
"StaticBlock",
|
|
2681
|
+
"SwitchCase",
|
|
2682
|
+
"SwitchStatement",
|
|
2683
|
+
"TSInterfaceBody",
|
|
2684
|
+
"TSModuleBlock",
|
|
2685
|
+
"TSTypeLiteral"
|
|
2686
|
+
].includes(node.parent.type)) {
|
|
2687
|
+
return;
|
|
2688
|
+
}
|
|
2689
|
+
const prevNode = scopeInfo.prevNode;
|
|
2690
|
+
if (prevNode)
|
|
2691
|
+
pendingPairs.push({ prevNode, nextNode: node });
|
|
2692
|
+
scopeInfo.prevNode = node;
|
|
2693
|
+
}
|
|
2694
|
+
function verifyPendingPairs() {
|
|
2695
|
+
for (const { prevNode, nextNode } of pendingPairs) {
|
|
2696
|
+
const type = getPaddingType(prevNode, nextNode);
|
|
2697
|
+
const paddingLines = getPaddingLineSequences(prevNode, nextNode);
|
|
2698
|
+
type.verify(context, prevNode, nextNode, paddingLines);
|
|
2699
|
+
}
|
|
2700
|
+
}
|
|
2701
|
+
function verifyThenEnterScope(node) {
|
|
2702
|
+
verify(node);
|
|
2703
|
+
enterScope();
|
|
2704
|
+
}
|
|
2705
|
+
const selectorMatchListeners = Object.fromEntries(Array.from(selectorMatchedNodes.keys(), (selector) => [
|
|
2706
|
+
selector,
|
|
2707
|
+
(node) => {
|
|
2708
|
+
selectorMatchedNodes.get(selector)?.add(node);
|
|
2709
|
+
}
|
|
2710
|
+
]));
|
|
2711
|
+
return {
|
|
2712
|
+
Program: enterScope,
|
|
2713
|
+
"Program:exit": () => {
|
|
2714
|
+
verifyPendingPairs();
|
|
2715
|
+
exitScope();
|
|
2716
|
+
},
|
|
2717
|
+
BlockStatement: enterScope,
|
|
2718
|
+
"BlockStatement:exit": exitScope,
|
|
2719
|
+
SwitchStatement: enterScope,
|
|
2720
|
+
"SwitchStatement:exit": exitScope,
|
|
2721
|
+
SwitchCase: verifyThenEnterScope,
|
|
2722
|
+
"SwitchCase:exit": exitScope,
|
|
2723
|
+
StaticBlock: enterScope,
|
|
2724
|
+
"StaticBlock:exit": exitScope,
|
|
2725
|
+
TSInterfaceBody: enterScope,
|
|
2726
|
+
"TSInterfaceBody:exit": exitScope,
|
|
2727
|
+
TSModuleBlock: enterScope,
|
|
2728
|
+
"TSModuleBlock:exit": exitScope,
|
|
2729
|
+
TSTypeLiteral: enterScope,
|
|
2730
|
+
"TSTypeLiteral:exit": exitScope,
|
|
2731
|
+
TSDeclareFunction: verifyThenEnterScope,
|
|
2732
|
+
"TSDeclareFunction:exit": exitScope,
|
|
2733
|
+
TSMethodSignature: verifyThenEnterScope,
|
|
2734
|
+
"TSMethodSignature:exit": exitScope,
|
|
2735
|
+
":statement": verify,
|
|
2736
|
+
...selectorMatchListeners
|
|
2737
|
+
};
|
|
2738
|
+
}
|
|
2739
|
+
};
|
|
2740
|
+
}
|
|
2741
|
+
|
|
2742
|
+
// vendor/anti-slop/src/rules/require-readable-spacing.ts
|
|
2743
|
+
var paddingRule = createPaddingLineRule([
|
|
2744
|
+
{ blankLine: "always", prev: "import", next: "*" },
|
|
2745
|
+
{ blankLine: "always", prev: "*", next: { selector: "Program > :not(ImportDeclaration)" } },
|
|
2746
|
+
{ blankLine: "always", prev: { selector: "Program > :not(ImportDeclaration)" }, next: "*" },
|
|
2747
|
+
{ blankLine: "always", prev: "*", next: ["function", "class", "interface", "type"] },
|
|
2748
|
+
{ blankLine: "always", prev: ["function", "class", "interface", "type"], next: "*" },
|
|
2749
|
+
{
|
|
2750
|
+
blankLine: "always",
|
|
2751
|
+
prev: "*",
|
|
2752
|
+
next: ["multiline-const", "multiline-let", "multiline-var", "multiline-using"]
|
|
2753
|
+
},
|
|
2754
|
+
{
|
|
2755
|
+
blankLine: "always",
|
|
2756
|
+
prev: ["multiline-const", "multiline-let", "multiline-var", "multiline-using"],
|
|
2757
|
+
next: "*"
|
|
2758
|
+
},
|
|
2759
|
+
{ blankLine: "always", prev: "*", next: ["return", "if", "switch", "try", "for", "while", "do"] },
|
|
2760
|
+
{ blankLine: "always", prev: "block-like", next: "*" },
|
|
2761
|
+
{ blankLine: "any", prev: "import", next: "import" },
|
|
2762
|
+
{
|
|
2763
|
+
blankLine: "any",
|
|
2764
|
+
prev: {
|
|
2765
|
+
selector: ':matches(TSDeclareFunction, ExportNamedDeclaration[declaration.type="TSDeclareFunction"])'
|
|
2766
|
+
},
|
|
2767
|
+
next: {
|
|
2768
|
+
selector: ':matches(TSDeclareFunction, FunctionDeclaration, ExportNamedDeclaration[declaration.type="TSDeclareFunction"], ExportNamedDeclaration[declaration.type="FunctionDeclaration"])'
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
2771
|
+
]);
|
|
2772
|
+
var requireReadableSpacingRule = {
|
|
2773
|
+
...paddingRule,
|
|
2774
|
+
meta: {
|
|
2775
|
+
...paddingRule.meta,
|
|
2776
|
+
docs: {
|
|
2777
|
+
description: "Require readable spacing between declarations and logical statement groups."
|
|
2778
|
+
},
|
|
2779
|
+
schema: []
|
|
2780
|
+
}
|
|
2781
|
+
};
|
|
2782
|
+
|
|
2086
2783
|
// vendor/anti-slop/src/rules/require-safety-comment-for-type-assertion.ts
|
|
2087
|
-
import { defineRule as
|
|
2784
|
+
import { defineRule as defineRule23 } from "@oxlint/plugins";
|
|
2088
2785
|
var DEFAULT_SAFETY_MARKERS = ["SAFETY"];
|
|
2089
2786
|
var commentOwnerKinds = new Set([
|
|
2090
2787
|
"ExpressionStatement",
|
|
@@ -2127,7 +2824,7 @@ function hasSafetyComment(sourceCode, node, pattern) {
|
|
|
2127
2824
|
current = current.parent;
|
|
2128
2825
|
}
|
|
2129
2826
|
}
|
|
2130
|
-
var requireSafetyCommentForTypeAssertionRule =
|
|
2827
|
+
var requireSafetyCommentForTypeAssertionRule = defineRule23({
|
|
2131
2828
|
meta: {
|
|
2132
2829
|
type: "problem",
|
|
2133
2830
|
docs: {
|
|
@@ -2196,6 +2893,7 @@ var antiSlopPlugin = eslintCompatPlugin3({
|
|
|
2196
2893
|
"no-unknown-returns": noUnknownReturnsRule,
|
|
2197
2894
|
"no-unknown-type-aliases": noUnknownTypeAliasesRule,
|
|
2198
2895
|
"no-widen-then-assert": noWidenThenAssertRule,
|
|
2896
|
+
"require-readable-spacing": requireReadableSpacingRule,
|
|
2199
2897
|
"require-safety-comment-for-type-assertion": requireSafetyCommentForTypeAssertionRule
|
|
2200
2898
|
}
|
|
2201
2899
|
});
|
|
@@ -2204,7 +2902,7 @@ var src_default = antiSlopPlugin;
|
|
|
2204
2902
|
import { eslintCompatPlugin as eslintCompatPlugin4 } from "@oxlint/plugins";
|
|
2205
2903
|
|
|
2206
2904
|
// src/generic/rules/prefer-event-parameter-type.ts
|
|
2207
|
-
import { defineRule as
|
|
2905
|
+
import { defineRule as defineRule24 } from "@oxlint/plugins";
|
|
2208
2906
|
function nearestEnclosingFunction2(node) {
|
|
2209
2907
|
let current = node.parent;
|
|
2210
2908
|
while (current) {
|
|
@@ -2231,7 +2929,7 @@ function assertedEventParameter(node) {
|
|
|
2231
2929
|
property
|
|
2232
2930
|
};
|
|
2233
2931
|
}
|
|
2234
|
-
var preferEventParameterTypeRule =
|
|
2932
|
+
var preferEventParameterTypeRule = defineRule24({
|
|
2235
2933
|
meta: {
|
|
2236
2934
|
type: "suggestion",
|
|
2237
2935
|
docs: {
|