@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.
Files changed (25) hide show
  1. package/README.md +2 -1
  2. package/THIRD_PARTY_NOTICES.md +9 -0
  3. package/dist/cli.js +733 -35
  4. package/dist/configs/recommended-effect.js +767 -69
  5. package/dist/configs/recommended.js +535 -30
  6. package/dist/upstream/anti-slop.js +535 -30
  7. package/dist/upstream/effect.js +196 -3
  8. package/package.json +1 -1
  9. package/vendor/anti-slop/src/effect/index.ts +8 -0
  10. package/vendor/anti-slop/src/effect/rules/no-manual-effect-error-tag.ts +52 -0
  11. package/vendor/anti-slop/src/effect/rules/no-manual-tag-comparison.ts +45 -0
  12. package/vendor/anti-slop/src/effect/rules/no-manual-tagged-construction.ts +37 -0
  13. package/vendor/anti-slop/src/effect/rules/prefer-effect-match.ts +54 -0
  14. package/vendor/anti-slop/src/effect/shared/tagged-values.ts +97 -0
  15. package/vendor/anti-slop/src/index.ts +2 -0
  16. package/vendor/anti-slop/src/rules/no-known-value-widening.ts +2 -14
  17. package/vendor/anti-slop/src/rules/no-module-mocking.ts +3 -14
  18. package/vendor/anti-slop/src/rules/require-readable-spacing.ts +47 -0
  19. package/vendor/anti-slop/src/shared/reflect-method.ts +2 -13
  20. package/vendor/anti-slop/src/shared/scope.ts +15 -0
  21. package/vendor/anti-slop/src/vendor/eslint-stylistic/LICENSE +22 -0
  22. package/vendor/anti-slop/src/vendor/eslint-stylistic/UPSTREAM.md +28 -0
  23. package/vendor/anti-slop/src/vendor/eslint-stylistic/padding-line-ast.ts +51 -0
  24. package/vendor/anti-slop/src/vendor/eslint-stylistic/padding-line-between-statements.ts +906 -0
  25. package/vendor/anti-slop/src/vendor/eslint-stylistic/padding-line-options.d.ts +87 -0
@@ -829,14 +829,7 @@ function functionParameterBindingName(parameter, sourceCode) {
829
829
  return annotationStart === undefined ? sourceText : sourceText.slice(0, annotationStart - parameter.start).trimEnd();
830
830
  }
831
831
 
832
- // vendor/anti-slop/src/rules/no-known-value-widening.ts
833
- function unwrapExpression(expression) {
834
- let current = expression;
835
- while (current.type === "ParenthesizedExpression" || current.type === "TSAsExpression" || current.type === "TSSatisfiesExpression" || current.type === "TSTypeAssertion" || current.type === "TSNonNullExpression") {
836
- current = current.expression;
837
- }
838
- return current;
839
- }
832
+ // vendor/anti-slop/src/shared/scope.ts
840
833
  function resolveVariable(sourceCode, identifier) {
841
834
  let scope = sourceCode.getScope(identifier);
842
835
  while (scope !== null) {
@@ -847,6 +840,15 @@ function resolveVariable(sourceCode, identifier) {
847
840
  }
848
841
  return null;
849
842
  }
843
+
844
+ // vendor/anti-slop/src/rules/no-known-value-widening.ts
845
+ function unwrapExpression(expression) {
846
+ let current = expression;
847
+ while (current.type === "ParenthesizedExpression" || current.type === "TSAsExpression" || current.type === "TSSatisfiesExpression" || current.type === "TSTypeAssertion" || current.type === "TSNonNullExpression") {
848
+ current = current.expression;
849
+ }
850
+ return current;
851
+ }
850
852
  function variableDeclarator(variable) {
851
853
  if (variable.defs.length !== 1)
852
854
  return null;
@@ -1114,16 +1116,6 @@ var noKnownValueWideningRule = defineRule5({
1114
1116
  // vendor/anti-slop/src/rules/no-module-mocking.ts
1115
1117
  import { defineRule as defineRule6 } from "@oxlint/plugins";
1116
1118
  var moduleMockMethods = new Set(["doMock", "mock", "unstable_mockModule"]);
1117
- function resolveVariable2(sourceCode, identifier) {
1118
- let scope = sourceCode.getScope(identifier);
1119
- while (scope !== null) {
1120
- const variable = scope.set.get(identifier.name);
1121
- if (variable !== undefined)
1122
- return variable;
1123
- scope = scope.upper;
1124
- }
1125
- return null;
1126
- }
1127
1119
  function importedName(node) {
1128
1120
  if (node.type !== "ImportSpecifier")
1129
1121
  return null;
@@ -1135,7 +1127,7 @@ function isTestFrameworkObject(sourceCode, expression) {
1135
1127
  if ((expression.name === "vi" || expression.name === "jest") && sourceCode.isGlobalReference(expression)) {
1136
1128
  return true;
1137
1129
  }
1138
- const variable = resolveVariable2(sourceCode, expression);
1130
+ const variable = resolveVariable(sourceCode, expression);
1139
1131
  if (variable === null || variable.defs.length === 0) {
1140
1132
  return expression.name === "vi" || expression.name === "jest";
1141
1133
  }
@@ -1238,22 +1230,12 @@ var noObjectParametersRule = defineRule7({
1238
1230
  import { defineRule as defineRule8 } from "@oxlint/plugins";
1239
1231
 
1240
1232
  // vendor/anti-slop/src/shared/reflect-method.ts
1241
- function resolveVariable3(sourceCode, identifier) {
1242
- let scope = sourceCode.getScope(identifier);
1243
- while (scope !== null) {
1244
- const variable = scope.set.get(identifier.name);
1245
- if (variable !== undefined)
1246
- return variable;
1247
- scope = scope.upper;
1248
- }
1249
- return null;
1250
- }
1251
1233
  function isGlobalReflect(sourceCode, expression) {
1252
1234
  if (expression.type !== "Identifier" || expression.name !== "Reflect")
1253
1235
  return false;
1254
1236
  if (sourceCode.isGlobalReference(expression))
1255
1237
  return true;
1256
- const variable = resolveVariable3(sourceCode, expression);
1238
+ const variable = resolveVariable(sourceCode, expression);
1257
1239
  return variable === null || variable.defs.length === 0;
1258
1240
  }
1259
1241
  function isGlobalReflectMethodCall(sourceCode, callee, methodName) {
@@ -1918,6 +1900,528 @@ var noWidenThenAssertRule = defineRule16({
1918
1900
  }
1919
1901
  });
1920
1902
 
1903
+ // vendor/anti-slop/src/vendor/eslint-stylistic/padding-line-ast.ts
1904
+ var LINEBREAKS = new Set([`\r
1905
+ `, "\r", `
1906
+ `, "\u2028", "\u2029"]);
1907
+ var isClosingBraceToken = (token) => token.type === "Punctuator" && token.value === "}";
1908
+ var isSemicolonToken = (token) => token.type === "Punctuator" && token.value === ";";
1909
+ var isNotSemicolonToken = (token) => !isSemicolonToken(token);
1910
+ var isTokenOnSameLine = (left, right) => left.loc.end.line === right.loc.start.line;
1911
+ var isFunction = (node) => node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression";
1912
+ var isSingleLine = (node) => node.loc.start.line === node.loc.end.line;
1913
+ var skipChainExpression = (node) => node.type === "ChainExpression" ? node.expression : node;
1914
+ var isTopLevelExpressionStatement = (node) => node.type === "ExpressionStatement" && (node.parent.type === "Program" || node.parent.type === "BlockStatement" && isFunction(node.parent.parent));
1915
+ function isParenthesized(node, sourceCode) {
1916
+ const before = sourceCode.getTokenBefore(node);
1917
+ const after = sourceCode.getTokenAfter(node);
1918
+ return before?.value === "(" && after?.value === ")";
1919
+ }
1920
+
1921
+ // vendor/anti-slop/src/vendor/eslint-stylistic/padding-line-between-statements.ts
1922
+ var CJS_EXPORT = /^(?:module\s*\.\s*)?exports(?:\s*\.|\s*\[|$)/u;
1923
+ var CJS_IMPORT = /^require\(/u;
1924
+ var LT = `[${Array.from(LINEBREAKS).join("")}]`;
1925
+ var PADDING_LINE_SEQUENCE = new RegExp(String.raw`^(\s*?${LT})\s*${LT}(\s*;?)$`, "u");
1926
+ function isSelectorOption(option) {
1927
+ return typeof option === "object" && !Array.isArray(option);
1928
+ }
1929
+ function newKeywordTester(type, keyword) {
1930
+ return {
1931
+ test(node, sourceCode) {
1932
+ const isSameKeyword = sourceCode.getFirstToken(node)?.value === keyword;
1933
+ const isSameType = Array.isArray(type) ? type.includes(node.type) : type === node.type;
1934
+ return isSameKeyword && isSameType;
1935
+ }
1936
+ };
1937
+ }
1938
+ function newNodeTypeTester(type) {
1939
+ return {
1940
+ test: (node) => node.type === type
1941
+ };
1942
+ }
1943
+ function isIIFEStatement(node) {
1944
+ if (node.type === "ExpressionStatement") {
1945
+ let expression = skipChainExpression(node.expression);
1946
+ if (expression.type === "UnaryExpression")
1947
+ expression = skipChainExpression(expression.argument);
1948
+ if (expression.type === "CallExpression") {
1949
+ let node = expression.callee;
1950
+ while (node.type === "SequenceExpression") {
1951
+ const lastExpression = node.expressions.at(-1);
1952
+ if (lastExpression === undefined)
1953
+ throw new Error("Padding rule invariant: sequence expression is empty");
1954
+ node = lastExpression;
1955
+ }
1956
+ return isFunction(node);
1957
+ }
1958
+ }
1959
+ return false;
1960
+ }
1961
+ function isCJSRequire(node) {
1962
+ if (node.type === "VariableDeclaration") {
1963
+ const declaration = node.declarations[0];
1964
+ if (declaration?.init) {
1965
+ let call = declaration?.init;
1966
+ while (call.type === "MemberExpression")
1967
+ call = call.object;
1968
+ if (call.type === "CallExpression" && call.callee.type === "Identifier") {
1969
+ return call.callee.name === "require";
1970
+ }
1971
+ }
1972
+ }
1973
+ return false;
1974
+ }
1975
+ function isBlockLikeStatement(node, sourceCode) {
1976
+ if (node.type === "DoWhileStatement" && node.body.type === "BlockStatement") {
1977
+ return true;
1978
+ }
1979
+ if (isIIFEStatement(node))
1980
+ return true;
1981
+ const lastToken = sourceCode.getLastToken(node, isNotSemicolonToken);
1982
+ const belongingNode = lastToken && isClosingBraceToken(lastToken) ? sourceCode.getNodeByRangeIndex(lastToken.range[0]) : null;
1983
+ return !!belongingNode && (belongingNode.type === "BlockStatement" || belongingNode.type === "SwitchStatement");
1984
+ }
1985
+ function isDirective(node, sourceCode) {
1986
+ return isTopLevelExpressionStatement(node) && node.expression.type === "Literal" && typeof node.expression.value === "string" && !isParenthesized(node.expression, sourceCode);
1987
+ }
1988
+ function isDirectivePrologue(node, sourceCode) {
1989
+ if (isDirective(node, sourceCode) && node.parent && "body" in node.parent && Array.isArray(node.parent.body)) {
1990
+ for (const sibling of node.parent.body) {
1991
+ if (sibling === node)
1992
+ break;
1993
+ if (!isDirective(sibling, sourceCode))
1994
+ return false;
1995
+ }
1996
+ return true;
1997
+ }
1998
+ return false;
1999
+ }
2000
+ function isCJSExport(node) {
2001
+ if (node.type === "ExpressionStatement") {
2002
+ const expression = node.expression;
2003
+ if (expression.type === "AssignmentExpression") {
2004
+ let left = expression.left;
2005
+ if (left.type === "MemberExpression") {
2006
+ while (left.object.type === "MemberExpression")
2007
+ left = left.object;
2008
+ return left.object.type === "Identifier" && (left.object.name === "exports" || left.object.name === "module" && left.property.type === "Identifier" && left.property.name === "exports");
2009
+ }
2010
+ }
2011
+ }
2012
+ return false;
2013
+ }
2014
+ function isExpression(node, sourceCode) {
2015
+ return node.type === "ExpressionStatement" && !isDirectivePrologue(node, sourceCode);
2016
+ }
2017
+ function getActualLastToken(node, sourceCode) {
2018
+ const semiToken = sourceCode.getLastToken(node);
2019
+ const prevToken = sourceCode.getTokenBefore(semiToken);
2020
+ const nextToken = sourceCode.getTokenAfter(semiToken);
2021
+ const isSemicolonLessStyle = prevToken && nextToken && prevToken.range[0] >= node.range[0] && isSemicolonToken(semiToken) && !isTokenOnSameLine(prevToken, semiToken) && isTokenOnSameLine(semiToken, nextToken);
2022
+ return isSemicolonLessStyle ? prevToken : semiToken;
2023
+ }
2024
+ function replacerToRemovePaddingLines(_, trailingSpaces, indentSpaces) {
2025
+ return trailingSpaces + indentSpaces;
2026
+ }
2027
+ function getReportLoc(node, sourceCode) {
2028
+ if (isSingleLine(node))
2029
+ return node.loc;
2030
+ const line = node.loc.start.line;
2031
+ const sourceLine = sourceCode.lines[line - 1];
2032
+ if (sourceLine === undefined)
2033
+ throw new Error("Padding rule invariant: statement source line is missing");
2034
+ return {
2035
+ start: node.loc.start,
2036
+ end: {
2037
+ line,
2038
+ column: sourceLine.length
2039
+ }
2040
+ };
2041
+ }
2042
+ function verifyForAny() {}
2043
+ function verifyForNever(context, _, nextNode, paddingLines) {
2044
+ if (paddingLines.length === 0)
2045
+ return;
2046
+ context.report({
2047
+ node: nextNode,
2048
+ messageId: "unexpectedBlankLine",
2049
+ loc: getReportLoc(nextNode, context.sourceCode),
2050
+ fix(fixer) {
2051
+ if (paddingLines.length >= 2)
2052
+ return null;
2053
+ const paddingPair = paddingLines[0];
2054
+ if (paddingPair === undefined)
2055
+ throw new Error("Padding rule invariant: reported padding pair is missing");
2056
+ const [prevToken, nextToken] = paddingPair;
2057
+ const start = prevToken.range[1];
2058
+ const end = nextToken.range[0];
2059
+ const text = context.sourceCode.text.slice(start, end).replace(PADDING_LINE_SEQUENCE, replacerToRemovePaddingLines);
2060
+ return fixer.replaceTextRange([start, end], text);
2061
+ }
2062
+ });
2063
+ }
2064
+ function verifyForAlways(context, prevNode, nextNode, paddingLines) {
2065
+ if (paddingLines.length > 0)
2066
+ return;
2067
+ context.report({
2068
+ node: nextNode,
2069
+ messageId: "expectedBlankLine",
2070
+ loc: getReportLoc(nextNode, context.sourceCode),
2071
+ fix(fixer) {
2072
+ const sourceCode = context.sourceCode;
2073
+ let prevToken = getActualLastToken(prevNode, sourceCode);
2074
+ const nextToken = sourceCode.getFirstTokenBetween(prevToken, nextNode, {
2075
+ includeComments: true,
2076
+ filter(token) {
2077
+ if (isTokenOnSameLine(prevToken, token)) {
2078
+ prevToken = token;
2079
+ return false;
2080
+ }
2081
+ return true;
2082
+ }
2083
+ }) || nextNode;
2084
+ const insertText = isTokenOnSameLine(prevToken, nextToken) ? `
2085
+
2086
+ ` : `
2087
+ `;
2088
+ return fixer.insertTextAfter(prevToken, insertText);
2089
+ }
2090
+ });
2091
+ }
2092
+ var PaddingTypes = {
2093
+ any: { verify: verifyForAny },
2094
+ never: { verify: verifyForNever },
2095
+ always: { verify: verifyForAlways }
2096
+ };
2097
+ var MaybeMultilineStatementType = {
2098
+ "block-like": { test: isBlockLikeStatement },
2099
+ expression: { test: isExpression },
2100
+ return: newKeywordTester("ReturnStatement", "return"),
2101
+ export: newKeywordTester([
2102
+ "ExportAllDeclaration",
2103
+ "ExportDefaultDeclaration",
2104
+ "ExportNamedDeclaration"
2105
+ ], "export"),
2106
+ var: newKeywordTester("VariableDeclaration", "var"),
2107
+ let: newKeywordTester("VariableDeclaration", "let"),
2108
+ const: newKeywordTester("VariableDeclaration", "const"),
2109
+ using: {
2110
+ test: (node) => node.type === "VariableDeclaration" && (node.kind === "using" || node.kind === "await using")
2111
+ },
2112
+ type: newKeywordTester("TSTypeAliasDeclaration", "type")
2113
+ };
2114
+ var StatementTypes = {
2115
+ "*": { test: () => true },
2116
+ exports: { test: isCJSExport },
2117
+ require: { test: isCJSRequire },
2118
+ directive: { test: isDirectivePrologue },
2119
+ iife: { test: isIIFEStatement },
2120
+ block: newNodeTypeTester("BlockStatement"),
2121
+ empty: newNodeTypeTester("EmptyStatement"),
2122
+ function: newNodeTypeTester("FunctionDeclaration"),
2123
+ "ts-method": newNodeTypeTester("TSMethodSignature"),
2124
+ break: newKeywordTester("BreakStatement", "break"),
2125
+ case: newKeywordTester("SwitchCase", "case"),
2126
+ class: newKeywordTester("ClassDeclaration", "class"),
2127
+ continue: newKeywordTester("ContinueStatement", "continue"),
2128
+ debugger: newKeywordTester("DebuggerStatement", "debugger"),
2129
+ default: newKeywordTester(["SwitchCase", "ExportDefaultDeclaration"], "default"),
2130
+ do: newKeywordTester("DoWhileStatement", "do"),
2131
+ for: newKeywordTester([
2132
+ "ForStatement",
2133
+ "ForInStatement",
2134
+ "ForOfStatement"
2135
+ ], "for"),
2136
+ if: newKeywordTester("IfStatement", "if"),
2137
+ import: newKeywordTester("ImportDeclaration", "import"),
2138
+ switch: newKeywordTester("SwitchStatement", "switch"),
2139
+ throw: newKeywordTester("ThrowStatement", "throw"),
2140
+ try: newKeywordTester("TryStatement", "try"),
2141
+ while: newKeywordTester(["WhileStatement", "DoWhileStatement"], "while"),
2142
+ with: newKeywordTester("WithStatement", "with"),
2143
+ "cjs-export": {
2144
+ test: (node, sourceCode) => node.type === "ExpressionStatement" && node.expression.type === "AssignmentExpression" && CJS_EXPORT.test(sourceCode.getText(node.expression.left))
2145
+ },
2146
+ "cjs-import": {
2147
+ test: (node, sourceCode) => node.type === "VariableDeclaration" && node.declarations.length > 0 && node.declarations[0]?.init != null && CJS_IMPORT.test(sourceCode.getText(node.declarations[0].init))
2148
+ },
2149
+ enum: newKeywordTester("TSEnumDeclaration", "enum"),
2150
+ interface: newKeywordTester("TSInterfaceDeclaration", "interface"),
2151
+ "function-overload": newNodeTypeTester("TSDeclareFunction"),
2152
+ ...Object.fromEntries(Object.entries(MaybeMultilineStatementType).flatMap(([key, value]) => [
2153
+ [key, value],
2154
+ [
2155
+ `singleline-${key}`,
2156
+ {
2157
+ ...value,
2158
+ test: (node, sourceCode) => value.test(node, sourceCode) && isSingleLine(node)
2159
+ }
2160
+ ],
2161
+ [
2162
+ `multiline-${key}`,
2163
+ {
2164
+ ...value,
2165
+ test: (node, sourceCode) => value.test(node, sourceCode) && !isSingleLine(node)
2166
+ }
2167
+ ]
2168
+ ]))
2169
+ };
2170
+ function createPaddingLineRule(options) {
2171
+ return {
2172
+ meta: {
2173
+ type: "layout",
2174
+ docs: {
2175
+ description: "Require or disallow padding lines between statements"
2176
+ },
2177
+ fixable: "whitespace",
2178
+ hasSuggestions: false,
2179
+ schema: {
2180
+ $defs: {
2181
+ paddingType: {
2182
+ type: "string",
2183
+ enum: Object.keys(PaddingTypes)
2184
+ },
2185
+ statementType: {
2186
+ type: "string",
2187
+ enum: Object.keys(StatementTypes)
2188
+ },
2189
+ selectorOption: {
2190
+ type: "object",
2191
+ properties: {
2192
+ selector: {
2193
+ type: "string"
2194
+ },
2195
+ lineMode: {
2196
+ type: "string",
2197
+ enum: ["any", "singleline", "multiline"]
2198
+ }
2199
+ },
2200
+ required: ["selector"],
2201
+ additionalProperties: false
2202
+ },
2203
+ statementMatcher: {
2204
+ anyOf: [
2205
+ { $ref: "#/$defs/statementType" },
2206
+ { $ref: "#/$defs/selectorOption" }
2207
+ ]
2208
+ },
2209
+ statementOption: {
2210
+ anyOf: [
2211
+ { $ref: "#/$defs/statementMatcher" },
2212
+ {
2213
+ type: "array",
2214
+ items: { $ref: "#/$defs/statementMatcher" },
2215
+ minItems: 1,
2216
+ uniqueItems: true,
2217
+ additionalItems: false
2218
+ }
2219
+ ]
2220
+ }
2221
+ },
2222
+ type: "array",
2223
+ additionalItems: false,
2224
+ items: {
2225
+ type: "object",
2226
+ properties: {
2227
+ blankLine: { $ref: "#/$defs/paddingType" },
2228
+ prev: { $ref: "#/$defs/statementOption" },
2229
+ next: { $ref: "#/$defs/statementOption" }
2230
+ },
2231
+ additionalProperties: false,
2232
+ required: ["blankLine", "prev", "next"]
2233
+ }
2234
+ },
2235
+ messages: {
2236
+ unexpectedBlankLine: "Unexpected blank line before this statement.",
2237
+ expectedBlankLine: "Expected blank line before this statement."
2238
+ }
2239
+ },
2240
+ create(context) {
2241
+ const sourceCode = context.sourceCode;
2242
+ const selectorMatchedNodes = new Map;
2243
+ const pendingPairs = [];
2244
+ function collectSelectorOption(option) {
2245
+ if (Array.isArray(option)) {
2246
+ for (const item of option)
2247
+ collectSelectorOption(item);
2248
+ return;
2249
+ }
2250
+ if (!isSelectorOption(option))
2251
+ return;
2252
+ selectorMatchedNodes.set(option.selector, new Set);
2253
+ }
2254
+ for (const configure of options) {
2255
+ collectSelectorOption(configure.prev);
2256
+ collectSelectorOption(configure.next);
2257
+ }
2258
+ let scopeInfo = null;
2259
+ function enterScope() {
2260
+ scopeInfo = {
2261
+ upper: scopeInfo,
2262
+ prevNode: null
2263
+ };
2264
+ }
2265
+ function exitScope() {
2266
+ if (scopeInfo)
2267
+ scopeInfo = scopeInfo.upper;
2268
+ }
2269
+ function match(node, type) {
2270
+ let innerStatementNode = node;
2271
+ while (innerStatementNode.type === "LabeledStatement")
2272
+ innerStatementNode = innerStatementNode.body;
2273
+ if (Array.isArray(type))
2274
+ return type.some(match.bind(null, innerStatementNode));
2275
+ if (isSelectorOption(type)) {
2276
+ const matchedNodes = selectorMatchedNodes.get(type.selector);
2277
+ if (!matchedNodes?.has(innerStatementNode))
2278
+ return false;
2279
+ const lineMode = type.lineMode;
2280
+ if (lineMode === "singleline")
2281
+ return isSingleLine(innerStatementNode);
2282
+ else if (lineMode === "multiline")
2283
+ return !isSingleLine(innerStatementNode);
2284
+ return true;
2285
+ } else {
2286
+ const statementType = StatementTypes[type];
2287
+ if (statementType === undefined)
2288
+ throw new Error(`Padding rule invariant: unsupported statement type ${type}`);
2289
+ return statementType.test(innerStatementNode, sourceCode);
2290
+ }
2291
+ }
2292
+ function getPaddingType(prevNode, nextNode) {
2293
+ for (let i = options.length - 1;i >= 0; --i) {
2294
+ const configure = options[i];
2295
+ if (configure === undefined)
2296
+ throw new Error("Padding rule invariant: configuration entry is missing");
2297
+ if (match(prevNode, configure.prev) && match(nextNode, configure.next)) {
2298
+ return PaddingTypes[configure.blankLine];
2299
+ }
2300
+ }
2301
+ return PaddingTypes.any;
2302
+ }
2303
+ function getPaddingLineSequences(prevNode, nextNode) {
2304
+ const pairs = [];
2305
+ let prevToken = getActualLastToken(prevNode, sourceCode);
2306
+ if (nextNode.loc.start.line - prevToken.loc.end.line >= 2) {
2307
+ do {
2308
+ const token = sourceCode.getTokenAfter(prevToken, {
2309
+ includeComments: true
2310
+ });
2311
+ if (token.loc.start.line - prevToken.loc.end.line >= 2)
2312
+ pairs.push([prevToken, token]);
2313
+ prevToken = token;
2314
+ } while (prevToken.range[0] < nextNode.range[0]);
2315
+ }
2316
+ return pairs;
2317
+ }
2318
+ function verify(node) {
2319
+ if (!node.parent || ![
2320
+ "BlockStatement",
2321
+ "Program",
2322
+ "StaticBlock",
2323
+ "SwitchCase",
2324
+ "SwitchStatement",
2325
+ "TSInterfaceBody",
2326
+ "TSModuleBlock",
2327
+ "TSTypeLiteral"
2328
+ ].includes(node.parent.type)) {
2329
+ return;
2330
+ }
2331
+ const prevNode = scopeInfo.prevNode;
2332
+ if (prevNode)
2333
+ pendingPairs.push({ prevNode, nextNode: node });
2334
+ scopeInfo.prevNode = node;
2335
+ }
2336
+ function verifyPendingPairs() {
2337
+ for (const { prevNode, nextNode } of pendingPairs) {
2338
+ const type = getPaddingType(prevNode, nextNode);
2339
+ const paddingLines = getPaddingLineSequences(prevNode, nextNode);
2340
+ type.verify(context, prevNode, nextNode, paddingLines);
2341
+ }
2342
+ }
2343
+ function verifyThenEnterScope(node) {
2344
+ verify(node);
2345
+ enterScope();
2346
+ }
2347
+ const selectorMatchListeners = Object.fromEntries(Array.from(selectorMatchedNodes.keys(), (selector) => [
2348
+ selector,
2349
+ (node) => {
2350
+ selectorMatchedNodes.get(selector)?.add(node);
2351
+ }
2352
+ ]));
2353
+ return {
2354
+ Program: enterScope,
2355
+ "Program:exit": () => {
2356
+ verifyPendingPairs();
2357
+ exitScope();
2358
+ },
2359
+ BlockStatement: enterScope,
2360
+ "BlockStatement:exit": exitScope,
2361
+ SwitchStatement: enterScope,
2362
+ "SwitchStatement:exit": exitScope,
2363
+ SwitchCase: verifyThenEnterScope,
2364
+ "SwitchCase:exit": exitScope,
2365
+ StaticBlock: enterScope,
2366
+ "StaticBlock:exit": exitScope,
2367
+ TSInterfaceBody: enterScope,
2368
+ "TSInterfaceBody:exit": exitScope,
2369
+ TSModuleBlock: enterScope,
2370
+ "TSModuleBlock:exit": exitScope,
2371
+ TSTypeLiteral: enterScope,
2372
+ "TSTypeLiteral:exit": exitScope,
2373
+ TSDeclareFunction: verifyThenEnterScope,
2374
+ "TSDeclareFunction:exit": exitScope,
2375
+ TSMethodSignature: verifyThenEnterScope,
2376
+ "TSMethodSignature:exit": exitScope,
2377
+ ":statement": verify,
2378
+ ...selectorMatchListeners
2379
+ };
2380
+ }
2381
+ };
2382
+ }
2383
+
2384
+ // vendor/anti-slop/src/rules/require-readable-spacing.ts
2385
+ var paddingRule = createPaddingLineRule([
2386
+ { blankLine: "always", prev: "import", next: "*" },
2387
+ { blankLine: "always", prev: "*", next: { selector: "Program > :not(ImportDeclaration)" } },
2388
+ { blankLine: "always", prev: { selector: "Program > :not(ImportDeclaration)" }, next: "*" },
2389
+ { blankLine: "always", prev: "*", next: ["function", "class", "interface", "type"] },
2390
+ { blankLine: "always", prev: ["function", "class", "interface", "type"], next: "*" },
2391
+ {
2392
+ blankLine: "always",
2393
+ prev: "*",
2394
+ next: ["multiline-const", "multiline-let", "multiline-var", "multiline-using"]
2395
+ },
2396
+ {
2397
+ blankLine: "always",
2398
+ prev: ["multiline-const", "multiline-let", "multiline-var", "multiline-using"],
2399
+ next: "*"
2400
+ },
2401
+ { blankLine: "always", prev: "*", next: ["return", "if", "switch", "try", "for", "while", "do"] },
2402
+ { blankLine: "always", prev: "block-like", next: "*" },
2403
+ { blankLine: "any", prev: "import", next: "import" },
2404
+ {
2405
+ blankLine: "any",
2406
+ prev: {
2407
+ selector: ':matches(TSDeclareFunction, ExportNamedDeclaration[declaration.type="TSDeclareFunction"])'
2408
+ },
2409
+ next: {
2410
+ selector: ':matches(TSDeclareFunction, FunctionDeclaration, ExportNamedDeclaration[declaration.type="TSDeclareFunction"], ExportNamedDeclaration[declaration.type="FunctionDeclaration"])'
2411
+ }
2412
+ }
2413
+ ]);
2414
+ var requireReadableSpacingRule = {
2415
+ ...paddingRule,
2416
+ meta: {
2417
+ ...paddingRule.meta,
2418
+ docs: {
2419
+ description: "Require readable spacing between declarations and logical statement groups."
2420
+ },
2421
+ schema: []
2422
+ }
2423
+ };
2424
+
1921
2425
  // vendor/anti-slop/src/rules/require-safety-comment-for-type-assertion.ts
1922
2426
  import { defineRule as defineRule17 } from "@oxlint/plugins";
1923
2427
  var DEFAULT_SAFETY_MARKERS = ["SAFETY"];
@@ -2031,6 +2535,7 @@ var antiSlopPlugin = eslintCompatPlugin({
2031
2535
  "no-unknown-returns": noUnknownReturnsRule,
2032
2536
  "no-unknown-type-aliases": noUnknownTypeAliasesRule,
2033
2537
  "no-widen-then-assert": noWidenThenAssertRule,
2538
+ "require-readable-spacing": requireReadableSpacingRule,
2034
2539
  "require-safety-comment-for-type-assertion": requireSafetyCommentForTypeAssertionRule
2035
2540
  }
2036
2541
  });