mirror of
https://github.com/vector-im/element-call.git
synced 2026-10-16 23:45:50 +00:00
Add anti-slot skill
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import type { CreateRule, ESTree, SourceCode } from "@oxlint/plugins";
|
||||
|
||||
import createPaddingLineRule from "../vendor/eslint-stylistic/padding-line-between-statements.ts";
|
||||
|
||||
import type { NodeTestObject } from "../vendor/eslint-stylistic/padding-line-between-statements.ts";
|
||||
|
||||
/** A `const`/`let`/`var`/`using` declaration, optionally exported, written on one line. */
|
||||
function isSinglelineBinding(node: ESTree.Node): boolean {
|
||||
const declaration = node.type === "ExportNamedDeclaration" ? node.declaration : node;
|
||||
return declaration?.type === "VariableDeclaration" && node.loc.start.line === node.loc.end.line;
|
||||
}
|
||||
|
||||
/** Comments above a statement belong to it; a comment trailing the previous line does not. */
|
||||
function hasLeadingComment(node: ESTree.Node, sourceCode: SourceCode): boolean {
|
||||
const previousLine = sourceCode.getTokenBefore(node)?.loc.end.line;
|
||||
return sourceCode
|
||||
.getCommentsBefore(node)
|
||||
.some((comment) => comment.loc.start.line !== previousLine);
|
||||
}
|
||||
|
||||
const singlelineBinding: NodeTestObject = {
|
||||
test: (node) => isSinglelineBinding(node),
|
||||
};
|
||||
|
||||
const undocumentedSinglelineBinding: NodeTestObject = {
|
||||
test: (node, sourceCode) => isSinglelineBinding(node) && !hasLeadingComment(node, sourceCode),
|
||||
};
|
||||
|
||||
const paddingRule = createPaddingLineRule(
|
||||
[
|
||||
{ blankLine: "always", prev: "import", next: "*" },
|
||||
{ blankLine: "always", prev: "*", next: { selector: "Program > :not(ImportDeclaration)" } },
|
||||
{ blankLine: "always", prev: { selector: "Program > :not(ImportDeclaration)" }, next: "*" },
|
||||
{ blankLine: "always", prev: "*", next: ["function", "class", "interface", "type"] },
|
||||
{ blankLine: "always", prev: ["function", "class", "interface", "type"], next: "*" },
|
||||
{
|
||||
blankLine: "always",
|
||||
prev: "*",
|
||||
next: ["multiline-const", "multiline-let", "multiline-var", "multiline-using"],
|
||||
},
|
||||
{
|
||||
blankLine: "always",
|
||||
prev: ["multiline-const", "multiline-let", "multiline-var", "multiline-using"],
|
||||
next: "*",
|
||||
},
|
||||
{ blankLine: "always", prev: "*", next: ["return", "if", "switch", "try", "for", "while", "do"] },
|
||||
{ blankLine: "always", prev: "block-like", next: "*" },
|
||||
{ blankLine: "any", prev: "import", next: "import" },
|
||||
// Consecutive single-line bindings form one group at any scope, including
|
||||
// module scope. A binding with its own leading comment starts a new group.
|
||||
{ blankLine: "any", prev: "singleline-binding", next: "undocumented-singleline-binding" },
|
||||
{
|
||||
blankLine: "any",
|
||||
prev: {
|
||||
selector:
|
||||
':matches(TSDeclareFunction, ExportNamedDeclaration[declaration.type="TSDeclareFunction"])',
|
||||
},
|
||||
next: {
|
||||
selector:
|
||||
':matches(TSDeclareFunction, FunctionDeclaration, ExportNamedDeclaration[declaration.type="TSDeclareFunction"], ExportNamedDeclaration[declaration.type="FunctionDeclaration"])',
|
||||
},
|
||||
},
|
||||
],
|
||||
{
|
||||
"singleline-binding": singlelineBinding,
|
||||
"undocumented-singleline-binding": undocumentedSinglelineBinding,
|
||||
},
|
||||
);
|
||||
|
||||
/** Restore structural blank lines with whitespace-only fixes; keep single-line binding groups and overloads grouped. */
|
||||
export const requireReadableSpacingRule: CreateRule = {
|
||||
...paddingRule,
|
||||
meta: {
|
||||
...paddingRule.meta,
|
||||
docs: {
|
||||
description: "Require readable spacing between declarations and logical statement groups.",
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user