|
|
@@ -1,701 +0,0 @@
|
|
|
-/**
|
|
|
- * @fileoverview Rule to enforce spacing before and after keywords.
|
|
|
- * @author Toru Nagashima
|
|
|
- * @deprecated in ESLint v8.53.0
|
|
|
- */
|
|
|
-
|
|
|
-"use strict";
|
|
|
-
|
|
|
-//------------------------------------------------------------------------------
|
|
|
-// Requirements
|
|
|
-//------------------------------------------------------------------------------
|
|
|
-
|
|
|
-const astUtils = require("./utils/ast-utils"),
|
|
|
- keywords = require("./utils/keywords");
|
|
|
-
|
|
|
-//------------------------------------------------------------------------------
|
|
|
-// Constants
|
|
|
-//------------------------------------------------------------------------------
|
|
|
-
|
|
|
-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;
|
|
|
-const KEYS = keywords.concat([
|
|
|
- "as",
|
|
|
- "async",
|
|
|
- "await",
|
|
|
- "from",
|
|
|
- "get",
|
|
|
- "let",
|
|
|
- "of",
|
|
|
- "set",
|
|
|
- "yield",
|
|
|
-]);
|
|
|
-
|
|
|
-// check duplications.
|
|
|
-(function () {
|
|
|
- KEYS.sort();
|
|
|
- for (let i = 1; i < KEYS.length; ++i) {
|
|
|
- if (KEYS[i] === KEYS[i - 1]) {
|
|
|
- throw new Error(
|
|
|
- `Duplication was found in the keyword list: ${KEYS[i]}`,
|
|
|
- );
|
|
|
- }
|
|
|
- }
|
|
|
-})();
|
|
|
-
|
|
|
-//------------------------------------------------------------------------------
|
|
|
-// Helpers
|
|
|
-//------------------------------------------------------------------------------
|
|
|
-
|
|
|
-/**
|
|
|
- * Checks whether or not a given token is a "Template" token ends with "${".
|
|
|
- * @param {Token} token A token to check.
|
|
|
- * @returns {boolean} `true` if the token is a "Template" token ends with "${".
|
|
|
- */
|
|
|
-function isOpenParenOfTemplate(token) {
|
|
|
- return token.type === "Template" && TEMPLATE_OPEN_PAREN.test(token.value);
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * Checks whether or not a given token is a "Template" token starts with "}".
|
|
|
- * @param {Token} token A token to check.
|
|
|
- * @returns {boolean} `true` if the token is a "Template" token starts with "}".
|
|
|
- */
|
|
|
-function isCloseParenOfTemplate(token) {
|
|
|
- return token.type === "Template" && TEMPLATE_CLOSE_PAREN.test(token.value);
|
|
|
-}
|
|
|
-
|
|
|
-//------------------------------------------------------------------------------
|
|
|
-// Rule Definition
|
|
|
-//------------------------------------------------------------------------------
|
|
|
-
|
|
|
-/** @type {import('../types').Rule.RuleModule} */
|
|
|
-module.exports = {
|
|
|
- meta: {
|
|
|
- deprecated: {
|
|
|
- message: "Formatting rules are being moved out of ESLint core.",
|
|
|
- url: "https://eslint.org/blog/2023/10/deprecating-formatting-rules/",
|
|
|
- deprecatedSince: "8.53.0",
|
|
|
- availableUntil: "11.0.0",
|
|
|
- replacedBy: [
|
|
|
- {
|
|
|
- message:
|
|
|
- "ESLint Stylistic now maintains deprecated stylistic core rules.",
|
|
|
- url: "https://eslint.style/guide/migration",
|
|
|
- plugin: {
|
|
|
- name: "@stylistic/eslint-plugin",
|
|
|
- url: "https://eslint.style",
|
|
|
- },
|
|
|
- rule: {
|
|
|
- name: "keyword-spacing",
|
|
|
- url: "https://eslint.style/rules/keyword-spacing",
|
|
|
- },
|
|
|
- },
|
|
|
- ],
|
|
|
- },
|
|
|
- type: "layout",
|
|
|
-
|
|
|
- docs: {
|
|
|
- description: "Enforce consistent spacing before and after keywords",
|
|
|
- recommended: false,
|
|
|
- url: "https://eslint.org/docs/latest/rules/keyword-spacing",
|
|
|
- },
|
|
|
-
|
|
|
- fixable: "whitespace",
|
|
|
-
|
|
|
- schema: [
|
|
|
- {
|
|
|
- type: "object",
|
|
|
- properties: {
|
|
|
- before: { type: "boolean", default: true },
|
|
|
- after: { type: "boolean", default: true },
|
|
|
- overrides: {
|
|
|
- type: "object",
|
|
|
- properties: KEYS.reduce((retv, key) => {
|
|
|
- retv[key] = {
|
|
|
- type: "object",
|
|
|
- properties: {
|
|
|
- before: { type: "boolean" },
|
|
|
- after: { type: "boolean" },
|
|
|
- },
|
|
|
- additionalProperties: false,
|
|
|
- };
|
|
|
- return retv;
|
|
|
- }, {}),
|
|
|
- additionalProperties: false,
|
|
|
- },
|
|
|
- },
|
|
|
- additionalProperties: false,
|
|
|
- },
|
|
|
- ],
|
|
|
- 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) {
|
|
|
- const sourceCode = context.sourceCode;
|
|
|
-
|
|
|
- const tokensToIgnore = new WeakSet();
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports a given token if there are not space(s) before the token.
|
|
|
- * @param {Token} token A token to report.
|
|
|
- * @param {RegExp} pattern A pattern of the previous token to check.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- 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) &&
|
|
|
- astUtils.isTokenOnSameLine(prevToken, token) &&
|
|
|
- !sourceCode.isSpaceBetweenTokens(prevToken, token)
|
|
|
- ) {
|
|
|
- context.report({
|
|
|
- loc: token.loc,
|
|
|
- messageId: "expectedBefore",
|
|
|
- data: token,
|
|
|
- fix(fixer) {
|
|
|
- return fixer.insertTextBefore(token, " ");
|
|
|
- },
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports a given token if there are space(s) before the token.
|
|
|
- * @param {Token} token A token to report.
|
|
|
- * @param {RegExp} pattern A pattern of the previous token to check.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- 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) &&
|
|
|
- astUtils.isTokenOnSameLine(prevToken, token) &&
|
|
|
- sourceCode.isSpaceBetweenTokens(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],
|
|
|
- ]);
|
|
|
- },
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports a given token if there are not space(s) after the token.
|
|
|
- * @param {Token} token A token to report.
|
|
|
- * @param {RegExp} pattern A pattern of the next token to check.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- 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) &&
|
|
|
- astUtils.isTokenOnSameLine(token, nextToken) &&
|
|
|
- !sourceCode.isSpaceBetweenTokens(token, nextToken)
|
|
|
- ) {
|
|
|
- context.report({
|
|
|
- loc: token.loc,
|
|
|
- messageId: "expectedAfter",
|
|
|
- data: token,
|
|
|
- fix(fixer) {
|
|
|
- return fixer.insertTextAfter(token, " ");
|
|
|
- },
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports a given token if there are space(s) after the token.
|
|
|
- * @param {Token} token A token to report.
|
|
|
- * @param {RegExp} pattern A pattern of the next token to check.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- 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) &&
|
|
|
- astUtils.isTokenOnSameLine(token, nextToken) &&
|
|
|
- sourceCode.isSpaceBetweenTokens(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],
|
|
|
- ]);
|
|
|
- },
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Parses the option object and determines check methods for each keyword.
|
|
|
- * @param {Object|undefined} options The option object to parse.
|
|
|
- * @returns {Object} - Normalized option object.
|
|
|
- * Keys are keywords (there are for every keyword).
|
|
|
- * Values are instances of `{"before": function, "after": function}`.
|
|
|
- */
|
|
|
- function parseOptions(options = {}) {
|
|
|
- const before = options.before !== false;
|
|
|
- const after = options.after !== false;
|
|
|
- const defaultValue = {
|
|
|
- before: before ? expectSpaceBefore : unexpectSpaceBefore,
|
|
|
- after: after ? expectSpaceAfter : unexpectSpaceAfter,
|
|
|
- };
|
|
|
- const overrides = (options && options.overrides) || {};
|
|
|
- const retv = Object.create(null);
|
|
|
-
|
|
|
- for (let i = 0; i < KEYS.length; ++i) {
|
|
|
- const key = KEYS[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(context.options[0]);
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports a given token if usage of spacing followed by the token is
|
|
|
- * invalid.
|
|
|
- * @param {Token} token A token to report.
|
|
|
- * @param {RegExp} [pattern] Optional. A pattern of the previous
|
|
|
- * token to check.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- function checkSpacingBefore(token, pattern) {
|
|
|
- checkMethodMap[token.value].before(token, pattern || PREV_TOKEN);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports a given token if usage of spacing preceded by the token is
|
|
|
- * invalid.
|
|
|
- * @param {Token} token A token to report.
|
|
|
- * @param {RegExp} [pattern] Optional. A pattern of the next
|
|
|
- * token to check.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- function checkSpacingAfter(token, pattern) {
|
|
|
- checkMethodMap[token.value].after(token, pattern || NEXT_TOKEN);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports a given token if usage of spacing around the token is invalid.
|
|
|
- * @param {Token} token A token to report.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- function checkSpacingAround(token) {
|
|
|
- checkSpacingBefore(token);
|
|
|
- checkSpacingAfter(token);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports the first token of a given node if the first token is a keyword
|
|
|
- * and usage of spacing around the token is invalid.
|
|
|
- * @param {ASTNode|null} node A node to report.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- function checkSpacingAroundFirstToken(node) {
|
|
|
- const firstToken = node && sourceCode.getFirstToken(node);
|
|
|
-
|
|
|
- if (firstToken && firstToken.type === "Keyword") {
|
|
|
- checkSpacingAround(firstToken);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports the first token of a given node if the first token is a keyword
|
|
|
- * and usage of spacing followed by the token is invalid.
|
|
|
- *
|
|
|
- * This is used for unary operators (e.g. `typeof`), `function`, and `super`.
|
|
|
- * Other rules are handling usage of spacing preceded by those keywords.
|
|
|
- * @param {ASTNode|null} node A node to report.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- function checkSpacingBeforeFirstToken(node) {
|
|
|
- const firstToken = node && sourceCode.getFirstToken(node);
|
|
|
-
|
|
|
- if (firstToken && firstToken.type === "Keyword") {
|
|
|
- checkSpacingBefore(firstToken);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports the previous token of a given node if the token is a keyword and
|
|
|
- * usage of spacing around the token is invalid.
|
|
|
- * @param {ASTNode|null} node A node to report.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- function checkSpacingAroundTokenBefore(node) {
|
|
|
- if (node) {
|
|
|
- const token = sourceCode.getTokenBefore(
|
|
|
- node,
|
|
|
- astUtils.isKeywordToken,
|
|
|
- );
|
|
|
-
|
|
|
- checkSpacingAround(token);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports `async` or `function` keywords of a given node if usage of
|
|
|
- * spacing around those keywords is invalid.
|
|
|
- * @param {ASTNode} node A node to report.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- function checkSpacingForFunction(node) {
|
|
|
- const firstToken = node && sourceCode.getFirstToken(node);
|
|
|
-
|
|
|
- if (
|
|
|
- firstToken &&
|
|
|
- ((firstToken.type === "Keyword" &&
|
|
|
- firstToken.value === "function") ||
|
|
|
- firstToken.value === "async")
|
|
|
- ) {
|
|
|
- checkSpacingBefore(firstToken);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports `class` and `extends` keywords of a given node if usage of
|
|
|
- * spacing around those keywords is invalid.
|
|
|
- * @param {ASTNode} node A node to report.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- function checkSpacingForClass(node) {
|
|
|
- checkSpacingAroundFirstToken(node);
|
|
|
- checkSpacingAroundTokenBefore(node.superClass);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports `if` and `else` keywords of a given node if usage of spacing
|
|
|
- * around those keywords is invalid.
|
|
|
- * @param {ASTNode} node A node to report.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- function checkSpacingForIfStatement(node) {
|
|
|
- checkSpacingAroundFirstToken(node);
|
|
|
- checkSpacingAroundTokenBefore(node.alternate);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports `try`, `catch`, and `finally` keywords of a given node if usage
|
|
|
- * of spacing around those keywords is invalid.
|
|
|
- * @param {ASTNode} node A node to report.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- function checkSpacingForTryStatement(node) {
|
|
|
- checkSpacingAroundFirstToken(node);
|
|
|
- checkSpacingAroundFirstToken(node.handler);
|
|
|
- checkSpacingAroundTokenBefore(node.finalizer);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports `do` and `while` keywords of a given node if usage of spacing
|
|
|
- * around those keywords is invalid.
|
|
|
- * @param {ASTNode} node A node to report.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- function checkSpacingForDoWhileStatement(node) {
|
|
|
- checkSpacingAroundFirstToken(node);
|
|
|
- checkSpacingAroundTokenBefore(node.test);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports `for` and `in` keywords of a given node if usage of spacing
|
|
|
- * around those keywords is invalid.
|
|
|
- * @param {ASTNode} node A node to report.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- function checkSpacingForForInStatement(node) {
|
|
|
- checkSpacingAroundFirstToken(node);
|
|
|
-
|
|
|
- const inToken = sourceCode.getTokenBefore(
|
|
|
- node.right,
|
|
|
- astUtils.isNotOpeningParenToken,
|
|
|
- );
|
|
|
- const previousToken = sourceCode.getTokenBefore(inToken);
|
|
|
-
|
|
|
- if (previousToken.type !== "PrivateIdentifier") {
|
|
|
- checkSpacingBefore(inToken);
|
|
|
- }
|
|
|
-
|
|
|
- checkSpacingAfter(inToken);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports `for` and `of` keywords of a given node if usage of spacing
|
|
|
- * around those keywords is invalid.
|
|
|
- * @param {ASTNode} node A node to report.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- function checkSpacingForForOfStatement(node) {
|
|
|
- if (node.await) {
|
|
|
- checkSpacingBefore(sourceCode.getFirstToken(node, 0));
|
|
|
- checkSpacingAfter(sourceCode.getFirstToken(node, 1));
|
|
|
- } else {
|
|
|
- checkSpacingAroundFirstToken(node);
|
|
|
- }
|
|
|
-
|
|
|
- const ofToken = sourceCode.getTokenBefore(
|
|
|
- node.right,
|
|
|
- astUtils.isNotOpeningParenToken,
|
|
|
- );
|
|
|
- const previousToken = sourceCode.getTokenBefore(ofToken);
|
|
|
-
|
|
|
- if (previousToken.type !== "PrivateIdentifier") {
|
|
|
- checkSpacingBefore(ofToken);
|
|
|
- }
|
|
|
-
|
|
|
- checkSpacingAfter(ofToken);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports `import`, `export`, `as`, and `from` keywords of a given node if
|
|
|
- * usage of spacing around those keywords is invalid.
|
|
|
- *
|
|
|
- * This rule handles the `*` token in module declarations.
|
|
|
- *
|
|
|
- * import*as A from "./a"; /*error Expected space(s) after "import".
|
|
|
- * error Expected space(s) before "as".
|
|
|
- * @param {ASTNode} node A node to report.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- 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 (node.source) {
|
|
|
- const fromToken = sourceCode.getTokenBefore(node.source);
|
|
|
-
|
|
|
- checkSpacingBefore(fromToken, PREV_TOKEN_M);
|
|
|
- checkSpacingAfter(fromToken, NEXT_TOKEN_M);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports `as` keyword of a given node if usage of spacing around this
|
|
|
- * keyword is invalid.
|
|
|
- * @param {ASTNode} node An `ImportSpecifier` node to check.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- function checkSpacingForImportSpecifier(node) {
|
|
|
- if (node.imported.range[0] !== node.local.range[0]) {
|
|
|
- const asToken = sourceCode.getTokenBefore(node.local);
|
|
|
-
|
|
|
- checkSpacingBefore(asToken, PREV_TOKEN_M);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports `as` keyword of a given node if usage of spacing around this
|
|
|
- * keyword is invalid.
|
|
|
- * @param {ASTNode} node An `ExportSpecifier` node to check.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- function checkSpacingForExportSpecifier(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);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports `as` keyword of a given node if usage of spacing around this
|
|
|
- * keyword is invalid.
|
|
|
- * @param {ASTNode} node A node to report.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- function checkSpacingForImportNamespaceSpecifier(node) {
|
|
|
- const asToken = sourceCode.getFirstToken(node, 1);
|
|
|
-
|
|
|
- checkSpacingBefore(asToken, PREV_TOKEN_M);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports `static`, `get`, and `set` keywords of a given node if usage of
|
|
|
- * spacing around those keywords is invalid.
|
|
|
- * @param {ASTNode} node A node to report.
|
|
|
- * @throws {Error} If unable to find token get, set, or async beside method name.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- function checkSpacingForProperty(node) {
|
|
|
- if (node.static) {
|
|
|
- checkSpacingAroundFirstToken(node);
|
|
|
- }
|
|
|
- if (
|
|
|
- node.kind === "get" ||
|
|
|
- node.kind === "set" ||
|
|
|
- ((node.method || node.type === "MethodDefinition") &&
|
|
|
- node.value.async)
|
|
|
- ) {
|
|
|
- const token = sourceCode.getTokenBefore(node.key, tok => {
|
|
|
- switch (tok.value) {
|
|
|
- case "get":
|
|
|
- case "set":
|
|
|
- case "async":
|
|
|
- return true;
|
|
|
- default:
|
|
|
- return false;
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- if (!token) {
|
|
|
- throw new Error(
|
|
|
- "Failed to find token get, set, or async beside method name",
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- checkSpacingAround(token);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Reports `await` keyword of a given node if usage of spacing before
|
|
|
- * this keyword is invalid.
|
|
|
- * @param {ASTNode} node A node to report.
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
- function checkSpacingForAwaitExpression(node) {
|
|
|
- checkSpacingBefore(sourceCode.getFirstToken(node));
|
|
|
- }
|
|
|
-
|
|
|
- return {
|
|
|
- // Statements
|
|
|
- DebuggerStatement: checkSpacingAroundFirstToken,
|
|
|
- WithStatement: checkSpacingAroundFirstToken,
|
|
|
-
|
|
|
- // Statements - Control flow
|
|
|
- BreakStatement: checkSpacingAroundFirstToken,
|
|
|
- ContinueStatement: checkSpacingAroundFirstToken,
|
|
|
- ReturnStatement: checkSpacingAroundFirstToken,
|
|
|
- ThrowStatement: checkSpacingAroundFirstToken,
|
|
|
- TryStatement: checkSpacingForTryStatement,
|
|
|
-
|
|
|
- // Statements - Choice
|
|
|
- IfStatement: checkSpacingForIfStatement,
|
|
|
- SwitchStatement: checkSpacingAroundFirstToken,
|
|
|
- SwitchCase: checkSpacingAroundFirstToken,
|
|
|
-
|
|
|
- // Statements - Loops
|
|
|
- DoWhileStatement: checkSpacingForDoWhileStatement,
|
|
|
- ForInStatement: checkSpacingForForInStatement,
|
|
|
- ForOfStatement: checkSpacingForForOfStatement,
|
|
|
- ForStatement: checkSpacingAroundFirstToken,
|
|
|
- WhileStatement: checkSpacingAroundFirstToken,
|
|
|
-
|
|
|
- // Statements - Declarations
|
|
|
- ClassDeclaration: checkSpacingForClass,
|
|
|
- ExportNamedDeclaration: checkSpacingForModuleDeclaration,
|
|
|
- ExportDefaultDeclaration: checkSpacingForModuleDeclaration,
|
|
|
- ExportAllDeclaration: checkSpacingForModuleDeclaration,
|
|
|
- FunctionDeclaration: checkSpacingForFunction,
|
|
|
- ImportDeclaration: checkSpacingForModuleDeclaration,
|
|
|
- VariableDeclaration: checkSpacingAroundFirstToken,
|
|
|
-
|
|
|
- // Expressions
|
|
|
- ArrowFunctionExpression: checkSpacingForFunction,
|
|
|
- AwaitExpression: checkSpacingForAwaitExpression,
|
|
|
- ClassExpression: checkSpacingForClass,
|
|
|
- FunctionExpression: checkSpacingForFunction,
|
|
|
- NewExpression: checkSpacingBeforeFirstToken,
|
|
|
- Super: checkSpacingBeforeFirstToken,
|
|
|
- ThisExpression: checkSpacingBeforeFirstToken,
|
|
|
- UnaryExpression: checkSpacingBeforeFirstToken,
|
|
|
- YieldExpression: checkSpacingBeforeFirstToken,
|
|
|
-
|
|
|
- // Others
|
|
|
- ImportSpecifier: checkSpacingForImportSpecifier,
|
|
|
- ExportSpecifier: checkSpacingForExportSpecifier,
|
|
|
- ImportNamespaceSpecifier: checkSpacingForImportNamespaceSpecifier,
|
|
|
- MethodDefinition: checkSpacingForProperty,
|
|
|
- PropertyDefinition: checkSpacingForProperty,
|
|
|
- StaticBlock: checkSpacingAroundFirstToken,
|
|
|
- Property: checkSpacingForProperty,
|
|
|
-
|
|
|
- // To avoid conflicts with `space-infix-ops`, e.g. `a > this.b`
|
|
|
- "BinaryExpression[operator='>']"(node) {
|
|
|
- const operatorToken = sourceCode.getTokenBefore(
|
|
|
- node.right,
|
|
|
- astUtils.isNotOpeningParenToken,
|
|
|
- );
|
|
|
-
|
|
|
- tokensToIgnore.add(operatorToken);
|
|
|
- },
|
|
|
- };
|
|
|
- },
|
|
|
-};
|