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