Files
SnowLuma/.pnpm-store/v11/files/c2/ba91d63cf1a9572b0a91058e984f9323528397a81f24a81383ee1406e71348d1044764c5cc9eaf17ca9da24fff083929c1a850868bd7a1201c3a3b5fc8103f
TanTan 2a69b23b47
Dev Build / cleanup (push) Canceled after 0s
Dev Build / typecheck (push) Canceled after 0s
Dev Build / build (linux-arm64, ubuntu-24.04-arm, linux-arm64) (push) Canceled after 0s
Dev Build / build (linux-x64, ubuntu-latest, linux-x64) (push) Canceled after 0s
Dev Build / build (win-x64, windows-latest, win32-x64) (push) Canceled after 0s
Dev Build / dispatch-dev-docker (push) Skipped
docs: 仓库链接指向本镜像仓库
2026-11-13 09:27:07 +08:00

388 lines
15 KiB
Plaintext

import { K as isSingleLine, Y as isTopLevelExpressionStatement, Z as skipChainExpression, f as createRule, g as import_ast_utils, m as AST_NODE_TYPES, x as LINEBREAKS } from "../utils.js";
const CJS_EXPORT = /^(?:module\s*\.\s*)?exports(?:\s*\.|\s*\[|$)/u;
const CJS_IMPORT = /^require\(/u;
const LT = `[${Array.from(LINEBREAKS).join("")}]`;
const PADDING_LINE_SEQUENCE = new RegExp(String.raw`^(\s*?${LT})\s*${LT}(\s*;?)$`, "u");
function isSelectorOption(option) {
return typeof option === "object" && !Array.isArray(option);
}
function newKeywordTester(type, keyword) {
return { test(node, sourceCode) {
const isSameKeyword = sourceCode.getFirstToken(node)?.value === keyword;
const isSameType = Array.isArray(type) ? type.includes(node.type) : type === node.type;
return isSameKeyword && isSameType;
} };
}
function newNodeTypeTester(type) {
return { test: (node) => node.type === type };
}
function isIIFEStatement(node) {
if (node.type === AST_NODE_TYPES.ExpressionStatement) {
let expression = skipChainExpression(node.expression);
if (expression.type === AST_NODE_TYPES.UnaryExpression) expression = skipChainExpression(expression.argument);
if (expression.type === AST_NODE_TYPES.CallExpression) {
let node = expression.callee;
while (node.type === AST_NODE_TYPES.SequenceExpression) node = node.expressions[node.expressions.length - 1];
return (0, import_ast_utils.isFunction)(node);
}
}
return false;
}
function isCJSRequire(node) {
if (node.type === AST_NODE_TYPES.VariableDeclaration) {
const declaration = node.declarations[0];
if (declaration?.init) {
let call = declaration?.init;
while (call.type === AST_NODE_TYPES.MemberExpression) call = call.object;
if (call.type === AST_NODE_TYPES.CallExpression && call.callee.type === AST_NODE_TYPES.Identifier) return call.callee.name === "require";
}
}
return false;
}
function isBlockLikeStatement(node, sourceCode) {
if (node.type === AST_NODE_TYPES.DoWhileStatement && node.body.type === AST_NODE_TYPES.BlockStatement) return true;
if (isIIFEStatement(node)) return true;
const lastToken = sourceCode.getLastToken(node, import_ast_utils.isNotSemicolonToken);
const belongingNode = lastToken && (0, import_ast_utils.isClosingBraceToken)(lastToken) ? sourceCode.getNodeByRangeIndex(lastToken.range[0]) : null;
return !!belongingNode && (belongingNode.type === AST_NODE_TYPES.BlockStatement || belongingNode.type === AST_NODE_TYPES.SwitchStatement);
}
function isDirective(node, sourceCode) {
return isTopLevelExpressionStatement(node) && node.expression.type === AST_NODE_TYPES.Literal && typeof node.expression.value === "string" && !(0, import_ast_utils.isParenthesized)(node.expression, sourceCode);
}
function isDirectivePrologue(node, sourceCode) {
if (isDirective(node, sourceCode) && node.parent && "body" in node.parent && Array.isArray(node.parent.body)) {
for (const sibling of node.parent.body) {
if (sibling === node) break;
if (!isDirective(sibling, sourceCode)) return false;
}
return true;
}
return false;
}
function isCJSExport(node) {
if (node.type === AST_NODE_TYPES.ExpressionStatement) {
const expression = node.expression;
if (expression.type === AST_NODE_TYPES.AssignmentExpression) {
let left = expression.left;
if (left.type === AST_NODE_TYPES.MemberExpression) {
while (left.object.type === AST_NODE_TYPES.MemberExpression) left = left.object;
return left.object.type === AST_NODE_TYPES.Identifier && (left.object.name === "exports" || left.object.name === "module" && left.property.type === AST_NODE_TYPES.Identifier && left.property.name === "exports");
}
}
}
return false;
}
function isExpression(node, sourceCode) {
return node.type === AST_NODE_TYPES.ExpressionStatement && !isDirectivePrologue(node, sourceCode);
}
function getActualLastToken(node, sourceCode) {
const semiToken = sourceCode.getLastToken(node);
const prevToken = sourceCode.getTokenBefore(semiToken);
const nextToken = sourceCode.getTokenAfter(semiToken);
return prevToken && nextToken && prevToken.range[0] >= node.range[0] && (0, import_ast_utils.isSemicolonToken)(semiToken) && !(0, import_ast_utils.isTokenOnSameLine)(prevToken, semiToken) && (0, import_ast_utils.isTokenOnSameLine)(semiToken, nextToken) ? prevToken : semiToken;
}
function replacerToRemovePaddingLines(_, trailingSpaces, indentSpaces) {
return trailingSpaces + indentSpaces;
}
function getReportLoc(node, sourceCode) {
if (isSingleLine(node)) return node.loc;
const line = node.loc.start.line;
return {
start: node.loc.start,
end: {
line,
column: sourceCode.lines[line - 1].length
}
};
}
function verifyForAny() {}
function verifyForNever(context, _, nextNode, paddingLines) {
if (paddingLines.length === 0) return;
context.report({
node: nextNode,
messageId: "unexpectedBlankLine",
loc: getReportLoc(nextNode, context.sourceCode),
fix(fixer) {
if (paddingLines.length >= 2) return null;
const prevToken = paddingLines[0][0];
const nextToken = paddingLines[0][1];
const start = prevToken.range[1];
const end = nextToken.range[0];
const text = context.sourceCode.text.slice(start, end).replace(PADDING_LINE_SEQUENCE, replacerToRemovePaddingLines);
return fixer.replaceTextRange([start, end], text);
}
});
}
function verifyForAlways(context, prevNode, nextNode, paddingLines) {
if (paddingLines.length > 0) return;
context.report({
node: nextNode,
messageId: "expectedBlankLine",
loc: getReportLoc(nextNode, context.sourceCode),
fix(fixer) {
const sourceCode = context.sourceCode;
let prevToken = getActualLastToken(prevNode, sourceCode);
const nextToken = sourceCode.getFirstTokenBetween(prevToken, nextNode, {
includeComments: true,
filter(token) {
if ((0, import_ast_utils.isTokenOnSameLine)(prevToken, token)) {
prevToken = token;
return false;
}
return true;
}
}) || nextNode;
const insertText = (0, import_ast_utils.isTokenOnSameLine)(prevToken, nextToken) ? "\n\n" : "\n";
return fixer.insertTextAfter(prevToken, insertText);
}
});
}
const PaddingTypes = {
any: { verify: verifyForAny },
never: { verify: verifyForNever },
always: { verify: verifyForAlways }
};
const MaybeMultilineStatementType = {
"block-like": { test: isBlockLikeStatement },
"expression": { test: isExpression },
"return": newKeywordTester(AST_NODE_TYPES.ReturnStatement, "return"),
"export": newKeywordTester([
AST_NODE_TYPES.ExportAllDeclaration,
AST_NODE_TYPES.ExportDefaultDeclaration,
AST_NODE_TYPES.ExportNamedDeclaration
], "export"),
"var": newKeywordTester(AST_NODE_TYPES.VariableDeclaration, "var"),
"let": newKeywordTester(AST_NODE_TYPES.VariableDeclaration, "let"),
"const": newKeywordTester(AST_NODE_TYPES.VariableDeclaration, "const"),
"using": { test: (node) => node.type === "VariableDeclaration" && (node.kind === "using" || node.kind === "await using") },
"type": newKeywordTester(AST_NODE_TYPES.TSTypeAliasDeclaration, "type")
};
const StatementTypes = {
"*": { test: () => true },
"exports": { test: isCJSExport },
"require": { test: isCJSRequire },
"directive": { test: isDirectivePrologue },
"iife": { test: isIIFEStatement },
"block": newNodeTypeTester(AST_NODE_TYPES.BlockStatement),
"empty": newNodeTypeTester(AST_NODE_TYPES.EmptyStatement),
"function": newNodeTypeTester(AST_NODE_TYPES.FunctionDeclaration),
"ts-method": newNodeTypeTester(AST_NODE_TYPES.TSMethodSignature),
"break": newKeywordTester(AST_NODE_TYPES.BreakStatement, "break"),
"case": newKeywordTester(AST_NODE_TYPES.SwitchCase, "case"),
"class": newKeywordTester(AST_NODE_TYPES.ClassDeclaration, "class"),
"continue": newKeywordTester(AST_NODE_TYPES.ContinueStatement, "continue"),
"debugger": newKeywordTester(AST_NODE_TYPES.DebuggerStatement, "debugger"),
"default": newKeywordTester([AST_NODE_TYPES.SwitchCase, AST_NODE_TYPES.ExportDefaultDeclaration], "default"),
"do": newKeywordTester(AST_NODE_TYPES.DoWhileStatement, "do"),
"for": newKeywordTester([
AST_NODE_TYPES.ForStatement,
AST_NODE_TYPES.ForInStatement,
AST_NODE_TYPES.ForOfStatement
], "for"),
"if": newKeywordTester(AST_NODE_TYPES.IfStatement, "if"),
"import": newKeywordTester(AST_NODE_TYPES.ImportDeclaration, "import"),
"switch": newKeywordTester(AST_NODE_TYPES.SwitchStatement, "switch"),
"throw": newKeywordTester(AST_NODE_TYPES.ThrowStatement, "throw"),
"try": newKeywordTester(AST_NODE_TYPES.TryStatement, "try"),
"while": newKeywordTester([AST_NODE_TYPES.WhileStatement, AST_NODE_TYPES.DoWhileStatement], "while"),
"with": newKeywordTester(AST_NODE_TYPES.WithStatement, "with"),
"cjs-export": { test: (node, sourceCode) => node.type === "ExpressionStatement" && node.expression.type === "AssignmentExpression" && CJS_EXPORT.test(sourceCode.getText(node.expression.left)) },
"cjs-import": { test: (node, sourceCode) => node.type === "VariableDeclaration" && node.declarations.length > 0 && Boolean(node.declarations[0].init) && CJS_IMPORT.test(sourceCode.getText(node.declarations[0].init)) },
"enum": newKeywordTester(AST_NODE_TYPES.TSEnumDeclaration, "enum"),
"interface": newKeywordTester(AST_NODE_TYPES.TSInterfaceDeclaration, "interface"),
"function-overload": newNodeTypeTester(AST_NODE_TYPES.TSDeclareFunction),
...Object.fromEntries(Object.entries(MaybeMultilineStatementType).flatMap(([key, value]) => [
[key, value],
[`singleline-${key}`, {
...value,
test: (node, sourceCode) => value.test(node, sourceCode) && isSingleLine(node)
}],
[`multiline-${key}`, {
...value,
test: (node, sourceCode) => value.test(node, sourceCode) && !isSingleLine(node)
}]
]))
};
var padding_line_between_statements_default = createRule({
name: "padding-line-between-statements",
meta: {
type: "layout",
docs: { description: "Require or disallow padding lines between statements" },
fixable: "whitespace",
hasSuggestions: false,
schema: {
$defs: {
paddingType: {
type: "string",
enum: Object.keys(PaddingTypes)
},
statementType: {
type: "string",
enum: Object.keys(StatementTypes)
},
selectorOption: {
type: "object",
properties: {
selector: { type: "string" },
lineMode: {
type: "string",
enum: [
"any",
"singleline",
"multiline"
]
}
},
required: ["selector"],
additionalProperties: false
},
statementMatcher: { anyOf: [{ $ref: "#/$defs/statementType" }, { $ref: "#/$defs/selectorOption" }] },
statementOption: { anyOf: [{ $ref: "#/$defs/statementMatcher" }, {
type: "array",
items: { $ref: "#/$defs/statementMatcher" },
minItems: 1,
uniqueItems: true,
additionalItems: false
}] }
},
type: "array",
additionalItems: false,
items: {
type: "object",
properties: {
blankLine: { $ref: "#/$defs/paddingType" },
prev: { $ref: "#/$defs/statementOption" },
next: { $ref: "#/$defs/statementOption" }
},
additionalProperties: false,
required: [
"blankLine",
"prev",
"next"
]
}
},
defaultOptions: [],
messages: {
unexpectedBlankLine: "Unexpected blank line before this statement.",
expectedBlankLine: "Expected blank line before this statement."
}
},
create(context, options) {
const sourceCode = context.sourceCode;
const selectorMatchedNodes = /* @__PURE__ */ new Map();
const pendingPairs = [];
function collectSelectorOption(option) {
if (Array.isArray(option)) {
for (const item of option) collectSelectorOption(item);
return;
}
if (!isSelectorOption(option)) return;
selectorMatchedNodes.set(option.selector, /* @__PURE__ */ new Set());
}
for (const configure of options) {
collectSelectorOption(configure.prev);
collectSelectorOption(configure.next);
}
let scopeInfo = null;
function enterScope() {
scopeInfo = {
upper: scopeInfo,
prevNode: null
};
}
function exitScope() {
if (scopeInfo) scopeInfo = scopeInfo.upper;
}
function match(node, type) {
let innerStatementNode = node;
while (innerStatementNode.type === AST_NODE_TYPES.LabeledStatement) innerStatementNode = innerStatementNode.body;
if (Array.isArray(type)) return type.some(match.bind(null, innerStatementNode));
if (isSelectorOption(type)) {
if (!selectorMatchedNodes.get(type.selector)?.has(innerStatementNode)) return false;
const lineMode = type.lineMode;
if (lineMode === "singleline") return isSingleLine(innerStatementNode);
else if (lineMode === "multiline") return !isSingleLine(innerStatementNode);
return true;
} else return StatementTypes[type].test(innerStatementNode, sourceCode);
}
function getPaddingType(prevNode, nextNode) {
for (let i = options.length - 1; i >= 0; --i) {
const configure = options[i];
if (match(prevNode, configure.prev) && match(nextNode, configure.next)) return PaddingTypes[configure.blankLine];
}
return PaddingTypes.any;
}
function getPaddingLineSequences(prevNode, nextNode) {
const pairs = [];
let prevToken = getActualLastToken(prevNode, sourceCode);
if (nextNode.loc.start.line - prevToken.loc.end.line >= 2) do {
const token = sourceCode.getTokenAfter(prevToken, { includeComments: true });
if (token.loc.start.line - prevToken.loc.end.line >= 2) pairs.push([prevToken, token]);
prevToken = token;
} while (prevToken.range[0] < nextNode.range[0]);
return pairs;
}
function verify(node) {
if (!node.parent || ![
AST_NODE_TYPES.BlockStatement,
AST_NODE_TYPES.Program,
AST_NODE_TYPES.StaticBlock,
AST_NODE_TYPES.SwitchCase,
AST_NODE_TYPES.SwitchStatement,
AST_NODE_TYPES.TSInterfaceBody,
AST_NODE_TYPES.TSModuleBlock,
AST_NODE_TYPES.TSTypeLiteral
].includes(node.parent.type)) return;
const prevNode = scopeInfo.prevNode;
if (prevNode) pendingPairs.push({
prevNode,
nextNode: node
});
scopeInfo.prevNode = node;
}
function verifyPendingPairs() {
for (const { prevNode, nextNode } of pendingPairs) {
const type = getPaddingType(prevNode, nextNode);
const paddingLines = getPaddingLineSequences(prevNode, nextNode);
type.verify(context, prevNode, nextNode, paddingLines);
}
}
function verifyThenEnterScope(node) {
verify(node);
enterScope();
}
const selectorMatchListeners = Object.fromEntries(Array.from(selectorMatchedNodes.keys(), (selector) => [selector, (node) => {
selectorMatchedNodes.get(selector)?.add(node);
}]));
return {
"Program": enterScope,
"Program:exit": () => {
verifyPendingPairs();
exitScope();
},
"BlockStatement": enterScope,
"BlockStatement:exit": exitScope,
"SwitchStatement": enterScope,
"SwitchStatement:exit": exitScope,
"SwitchCase": verifyThenEnterScope,
"SwitchCase:exit": exitScope,
"StaticBlock": enterScope,
"StaticBlock:exit": exitScope,
"TSInterfaceBody": enterScope,
"TSInterfaceBody:exit": exitScope,
"TSModuleBlock": enterScope,
"TSModuleBlock:exit": exitScope,
"TSTypeLiteral": enterScope,
"TSTypeLiteral:exit": exitScope,
"TSDeclareFunction": verifyThenEnterScope,
"TSDeclareFunction:exit": exitScope,
"TSMethodSignature": verifyThenEnterScope,
"TSMethodSignature:exit": exitScope,
":statement": verify,
...selectorMatchListeners
};
}
});
export { padding_line_between_statements_default as t };