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) Canceled after 0s
312 lines
12 KiB
Plaintext
312 lines
12 KiB
Plaintext
import { b as KEYWORDS, f as createRule, g as import_ast_utils, m as AST_NODE_TYPES, z as isKeywordToken } from "../utils.js";
|
|
const PREV_TOKEN = /^[)\]}>]$/u;
|
|
const NEXT_TOKEN = /^(?:[([{<~!]|\+\+?|--?)$/u;
|
|
const PREV_TOKEN_M = /^[)\]}>*]$/u;
|
|
const NEXT_TOKEN_M = /^[{*]$/u;
|
|
const TEMPLATE_OPEN_PAREN = /\$\{$/u;
|
|
const TEMPLATE_CLOSE_PAREN = /^\}/u;
|
|
const CHECK_TYPE = /^(?:JSXElement|RegularExpression|String|Template|PrivateIdentifier)$/u;
|
|
var keyword_spacing_default = createRule({
|
|
name: "keyword-spacing",
|
|
meta: {
|
|
type: "layout",
|
|
docs: { description: "Enforce consistent spacing before and after keywords" },
|
|
fixable: "whitespace",
|
|
schema: [{
|
|
type: "object",
|
|
properties: {
|
|
before: { type: "boolean" },
|
|
after: { type: "boolean" },
|
|
overrides: {
|
|
type: "object",
|
|
properties: KEYWORDS.reduce((retv, key) => {
|
|
retv[key] = {
|
|
type: "object",
|
|
properties: {
|
|
before: { type: "boolean" },
|
|
after: { type: "boolean" }
|
|
},
|
|
additionalProperties: false
|
|
};
|
|
return retv;
|
|
}, {}),
|
|
additionalProperties: false
|
|
}
|
|
},
|
|
additionalProperties: false
|
|
}],
|
|
defaultOptions: [{
|
|
before: true,
|
|
after: true,
|
|
overrides: {}
|
|
}],
|
|
messages: {
|
|
expectedBefore: "Expected space(s) before \"{{value}}\".",
|
|
expectedAfter: "Expected space(s) after \"{{value}}\".",
|
|
unexpectedBefore: "Unexpected space(s) before \"{{value}}\".",
|
|
unexpectedAfter: "Unexpected space(s) after \"{{value}}\"."
|
|
}
|
|
},
|
|
create(context, [options]) {
|
|
const sourceCode = context.sourceCode;
|
|
const tokensToIgnore = /* @__PURE__ */ new WeakSet();
|
|
function isOpenParenOfTemplate(token) {
|
|
return token.type === "Template" && TEMPLATE_OPEN_PAREN.test(token.value);
|
|
}
|
|
function isCloseParenOfTemplate(token) {
|
|
return token.type === "Template" && TEMPLATE_CLOSE_PAREN.test(token.value);
|
|
}
|
|
function expectSpaceBefore(token, pattern) {
|
|
const prevToken = sourceCode.getTokenBefore(token);
|
|
if (prevToken && (CHECK_TYPE.test(prevToken.type) || pattern.test(prevToken.value)) && !isOpenParenOfTemplate(prevToken) && !tokensToIgnore.has(prevToken) && (0, import_ast_utils.isTokenOnSameLine)(prevToken, token) && !sourceCode.isSpaceBetween(prevToken, token)) context.report({
|
|
loc: token.loc,
|
|
messageId: "expectedBefore",
|
|
data: token,
|
|
fix(fixer) {
|
|
return fixer.insertTextBefore(token, " ");
|
|
}
|
|
});
|
|
}
|
|
function unexpectSpaceBefore(token, pattern) {
|
|
const prevToken = sourceCode.getTokenBefore(token);
|
|
if (prevToken && (CHECK_TYPE.test(prevToken.type) || pattern.test(prevToken.value)) && !isOpenParenOfTemplate(prevToken) && !tokensToIgnore.has(prevToken) && (0, import_ast_utils.isTokenOnSameLine)(prevToken, token) && sourceCode.isSpaceBetween(prevToken, token)) context.report({
|
|
loc: {
|
|
start: prevToken.loc.end,
|
|
end: token.loc.start
|
|
},
|
|
messageId: "unexpectedBefore",
|
|
data: token,
|
|
fix(fixer) {
|
|
return fixer.removeRange([prevToken.range[1], token.range[0]]);
|
|
}
|
|
});
|
|
}
|
|
function expectSpaceAfter(token, pattern) {
|
|
const nextToken = sourceCode.getTokenAfter(token);
|
|
if (nextToken && (CHECK_TYPE.test(nextToken.type) || pattern.test(nextToken.value)) && !isCloseParenOfTemplate(nextToken) && !tokensToIgnore.has(nextToken) && (0, import_ast_utils.isTokenOnSameLine)(token, nextToken) && !sourceCode.isSpaceBetween(token, nextToken)) context.report({
|
|
loc: token.loc,
|
|
messageId: "expectedAfter",
|
|
data: token,
|
|
fix(fixer) {
|
|
return fixer.insertTextAfter(token, " ");
|
|
}
|
|
});
|
|
}
|
|
function unexpectSpaceAfter(token, pattern) {
|
|
const nextToken = sourceCode.getTokenAfter(token);
|
|
if (nextToken && (CHECK_TYPE.test(nextToken.type) || pattern.test(nextToken.value)) && !isCloseParenOfTemplate(nextToken) && !tokensToIgnore.has(nextToken) && (0, import_ast_utils.isTokenOnSameLine)(token, nextToken) && sourceCode.isSpaceBetween(token, nextToken)) context.report({
|
|
loc: {
|
|
start: token.loc.end,
|
|
end: nextToken.loc.start
|
|
},
|
|
messageId: "unexpectedAfter",
|
|
data: token,
|
|
fix(fixer) {
|
|
return fixer.removeRange([token.range[1], nextToken.range[0]]);
|
|
}
|
|
});
|
|
}
|
|
function parseOptions(options) {
|
|
const { before, after, overrides } = options;
|
|
const defaultValue = {
|
|
before: before ? expectSpaceBefore : unexpectSpaceBefore,
|
|
after: after ? expectSpaceAfter : unexpectSpaceAfter
|
|
};
|
|
const retv = Object.create(null);
|
|
for (let i = 0; i < KEYWORDS.length; ++i) {
|
|
const key = KEYWORDS[i];
|
|
const override = overrides[key];
|
|
if (override) {
|
|
const thisBefore = "before" in override ? override.before : before;
|
|
const thisAfter = "after" in override ? override.after : after;
|
|
retv[key] = {
|
|
before: thisBefore ? expectSpaceBefore : unexpectSpaceBefore,
|
|
after: thisAfter ? expectSpaceAfter : unexpectSpaceAfter
|
|
};
|
|
} else retv[key] = defaultValue;
|
|
}
|
|
return retv;
|
|
}
|
|
const checkMethodMap = parseOptions(options);
|
|
function checkSpacingBefore(token, pattern) {
|
|
checkMethodMap[token.value].before(token, pattern || PREV_TOKEN);
|
|
}
|
|
function checkSpacingAfter(token, pattern) {
|
|
checkMethodMap[token.value].after(token, pattern || NEXT_TOKEN);
|
|
}
|
|
function checkSpacingAround(token) {
|
|
checkSpacingBefore(token);
|
|
checkSpacingAfter(token);
|
|
}
|
|
function checkSpacingAroundFirstToken(node) {
|
|
const firstToken = node && sourceCode.getFirstToken(node);
|
|
if (!firstToken) return;
|
|
if (!isKeywordToken(firstToken)) if (node.type === "VariableDeclaration") {
|
|
if (node.kind !== "using" && node.kind !== "await using" || firstToken.type !== "Identifier") return;
|
|
} else return;
|
|
checkSpacingAround(firstToken);
|
|
}
|
|
function checkSpacingBeforeFirstToken(node) {
|
|
const firstToken = node && sourceCode.getFirstToken(node);
|
|
if (isKeywordToken(firstToken)) checkSpacingBefore(firstToken);
|
|
}
|
|
function checkSpacingAroundTokenBefore(node) {
|
|
if (node) {
|
|
const token = sourceCode.getTokenBefore(node, isKeywordToken);
|
|
if (token) checkSpacingAround(token);
|
|
}
|
|
}
|
|
function checkSpacingForFunction(node) {
|
|
const firstToken = node && sourceCode.getFirstToken(node);
|
|
if (firstToken && (isKeywordToken(firstToken) && firstToken.value === "function" || firstToken.value === "async")) checkSpacingBefore(firstToken);
|
|
}
|
|
function checkSpacingForClass(node) {
|
|
checkSpacingAroundFirstToken(node);
|
|
checkSpacingAroundTokenBefore(node.superClass);
|
|
}
|
|
function checkSpacingForModuleDeclaration(node) {
|
|
const firstToken = sourceCode.getFirstToken(node);
|
|
checkSpacingBefore(firstToken, PREV_TOKEN_M);
|
|
checkSpacingAfter(firstToken, NEXT_TOKEN_M);
|
|
if (node.type === "ExportDefaultDeclaration") checkSpacingAround(sourceCode.getTokenAfter(firstToken));
|
|
if (node.type === "ExportAllDeclaration" && node.exported) {
|
|
const asToken = sourceCode.getTokenBefore(node.exported);
|
|
checkSpacingBefore(asToken, PREV_TOKEN_M);
|
|
checkSpacingAfter(asToken, NEXT_TOKEN_M);
|
|
}
|
|
if ("source" in node && node.source) {
|
|
const fromToken = sourceCode.getTokenBefore(node.source);
|
|
checkSpacingBefore(fromToken, PREV_TOKEN_M);
|
|
checkSpacingAfter(fromToken, NEXT_TOKEN_M);
|
|
if (node.attributes) {
|
|
const withToken = sourceCode.getTokenAfter(node.source);
|
|
if (isKeywordToken(withToken)) checkSpacingAround(withToken);
|
|
}
|
|
}
|
|
if (node.type !== "ExportDefaultDeclaration") checkSpacingForTypeKeywordInImportExport(node);
|
|
}
|
|
function checkSpacingForTypeKeywordInImportExport(node) {
|
|
let kind;
|
|
switch (node.type) {
|
|
case AST_NODE_TYPES.ImportDeclaration:
|
|
kind = node.importKind;
|
|
break;
|
|
case AST_NODE_TYPES.ExportAllDeclaration:
|
|
case AST_NODE_TYPES.ExportNamedDeclaration:
|
|
kind = node.exportKind;
|
|
break;
|
|
}
|
|
if (kind !== "type") return;
|
|
const typeToken = sourceCode.getFirstToken(node, { skip: 1 });
|
|
if (!(0, import_ast_utils.isTypeKeyword)(typeToken)) return;
|
|
checkSpacingBefore(typeToken, PREV_TOKEN_M);
|
|
checkSpacingAfter(typeToken, NEXT_TOKEN_M);
|
|
}
|
|
function checkSpacingForProperty(node) {
|
|
if ("static" in node && node.static) checkSpacingAroundFirstToken(node);
|
|
if (node.kind === "get" || node.kind === "set" || ("method" in node && node.method || node.type === "MethodDefinition") && "async" in node.value && node.value.async || node.type === AST_NODE_TYPES.AccessorProperty) {
|
|
const token = sourceCode.getTokenBefore(node.key, (tok) => {
|
|
switch (tok.value) {
|
|
case "get":
|
|
case "set":
|
|
case "async":
|
|
case "accessor": return true;
|
|
default: return false;
|
|
}
|
|
});
|
|
if (!token) throw new Error("Failed to find token get, set, or async beside method name");
|
|
checkSpacingAround(token);
|
|
}
|
|
}
|
|
return {
|
|
DebuggerStatement: checkSpacingAroundFirstToken,
|
|
WithStatement: checkSpacingAroundFirstToken,
|
|
BreakStatement: checkSpacingAroundFirstToken,
|
|
ContinueStatement: checkSpacingAroundFirstToken,
|
|
ReturnStatement: checkSpacingAroundFirstToken,
|
|
ThrowStatement: checkSpacingAroundFirstToken,
|
|
TryStatement(node) {
|
|
checkSpacingAroundFirstToken(node);
|
|
if (node.handler) if (node.handler.param) checkSpacingBeforeFirstToken(node.handler);
|
|
else checkSpacingAroundFirstToken(node.handler);
|
|
checkSpacingAroundTokenBefore(node.finalizer);
|
|
},
|
|
IfStatement(node) {
|
|
checkSpacingAroundFirstToken(node);
|
|
checkSpacingAroundTokenBefore(node.alternate);
|
|
},
|
|
SwitchStatement: checkSpacingAroundFirstToken,
|
|
SwitchCase: checkSpacingAroundFirstToken,
|
|
DoWhileStatement(node) {
|
|
checkSpacingAroundFirstToken(node);
|
|
checkSpacingAroundTokenBefore(node.test);
|
|
},
|
|
ForInStatement(node) {
|
|
checkSpacingAroundFirstToken(node);
|
|
const inToken = sourceCode.getTokenBefore(node.right, import_ast_utils.isNotOpeningParenToken);
|
|
if (sourceCode.getTokenBefore(inToken).type !== "PrivateIdentifier") checkSpacingBefore(inToken);
|
|
checkSpacingAfter(inToken);
|
|
},
|
|
ForOfStatement(node) {
|
|
if (node.await) {
|
|
checkSpacingBefore(sourceCode.getFirstToken(node, 0));
|
|
checkSpacingAfter(sourceCode.getFirstToken(node, 1));
|
|
} else checkSpacingAroundFirstToken(node);
|
|
const ofToken = sourceCode.getTokenBefore(node.right, import_ast_utils.isNotOpeningParenToken);
|
|
if (sourceCode.getTokenBefore(ofToken).type !== "PrivateIdentifier") checkSpacingBefore(ofToken);
|
|
checkSpacingAfter(ofToken);
|
|
},
|
|
ForStatement: checkSpacingAroundFirstToken,
|
|
WhileStatement: checkSpacingAroundFirstToken,
|
|
ClassDeclaration: checkSpacingForClass,
|
|
ExportNamedDeclaration: checkSpacingForModuleDeclaration,
|
|
ExportDefaultDeclaration: checkSpacingForModuleDeclaration,
|
|
ExportAllDeclaration: checkSpacingForModuleDeclaration,
|
|
FunctionDeclaration: checkSpacingForFunction,
|
|
ImportDeclaration: checkSpacingForModuleDeclaration,
|
|
VariableDeclaration: checkSpacingAroundFirstToken,
|
|
ArrowFunctionExpression: checkSpacingForFunction,
|
|
AwaitExpression(node) {
|
|
checkSpacingBefore(sourceCode.getFirstToken(node));
|
|
},
|
|
ClassExpression: checkSpacingForClass,
|
|
FunctionExpression: checkSpacingForFunction,
|
|
NewExpression: checkSpacingBeforeFirstToken,
|
|
Super: checkSpacingBeforeFirstToken,
|
|
ThisExpression: checkSpacingBeforeFirstToken,
|
|
UnaryExpression: checkSpacingBeforeFirstToken,
|
|
YieldExpression: checkSpacingBeforeFirstToken,
|
|
ImportSpecifier(node) {
|
|
if (node.imported.range[0] !== node.local.range[0]) checkSpacingBefore(sourceCode.getTokenBefore(node.local), PREV_TOKEN_M);
|
|
},
|
|
ExportSpecifier(node) {
|
|
if (node.local.range[0] !== node.exported.range[0]) {
|
|
const asToken = sourceCode.getTokenBefore(node.exported);
|
|
checkSpacingBefore(asToken, PREV_TOKEN_M);
|
|
checkSpacingAfter(asToken, NEXT_TOKEN_M);
|
|
}
|
|
},
|
|
ImportNamespaceSpecifier(node) {
|
|
checkSpacingBefore(sourceCode.getFirstToken(node, 1), PREV_TOKEN_M);
|
|
},
|
|
MethodDefinition: checkSpacingForProperty,
|
|
PropertyDefinition: checkSpacingForProperty,
|
|
AccessorProperty: checkSpacingForProperty,
|
|
StaticBlock: checkSpacingAroundFirstToken,
|
|
Property: checkSpacingForProperty,
|
|
BinaryExpression(node) {
|
|
if (node.operator !== ">") return;
|
|
const operatorToken = sourceCode.getTokenBefore(node.right, import_ast_utils.isNotOpeningParenToken);
|
|
tokensToIgnore.add(operatorToken);
|
|
},
|
|
TSAsExpression(node) {
|
|
checkSpacingAround(sourceCode.getTokenAfter(node.expression, (token) => token.value === "as"));
|
|
},
|
|
TSSatisfiesExpression(node) {
|
|
checkSpacingAround(sourceCode.getTokenAfter(node.expression, (token) => token.value === "satisfies"));
|
|
}
|
|
};
|
|
}
|
|
});
|
|
export { keyword_spacing_default as t };
|