2025-04-19 23:12:19 -04:00

186 lines
5.1 KiB
JavaScript

/**
* @fileoverview Rule to define spacing before/after arrow function's arrow.
* @author Jxck
* @deprecated in ESLint v8.53.0
*/
'use strict';
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const astUtils = require('./utils/ast-utils');
//------------------------------------------------------------------------------
// 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: '10.0.0',
replacedBy: [
{
message:
'ESLint Stylistic now maintains deprecated stylistic core rules.',
url: 'https://eslint.style/guide/migration',
plugin: {
name: '@stylistic/eslint-plugin-js',
url: 'https://eslint.style/packages/js',
},
rule: {
name: 'arrow-spacing',
url: 'https://eslint.style/rules/js/arrow-spacing',
},
},
],
},
type: 'layout',
docs: {
description:
'Enforce consistent spacing before and after the arrow in arrow functions',
recommended: false,
url: 'https://eslint.org/docs/latest/rules/arrow-spacing',
},
fixable: 'whitespace',
schema: [
{
type: 'object',
properties: {
before: {
type: 'boolean',
default: true,
},
after: {
type: 'boolean',
default: true,
},
},
additionalProperties: false,
},
],
messages: {
expectedBefore: 'Missing space before =>.',
unexpectedBefore: 'Unexpected space before =>.',
expectedAfter: 'Missing space after =>.',
unexpectedAfter: 'Unexpected space after =>.',
},
},
create(context) {
// merge rules with default
const rule = Object.assign({}, context.options[0]);
rule.before = rule.before !== false;
rule.after = rule.after !== false;
const sourceCode = context.sourceCode;
/**
* Get tokens of arrow(`=>`) and before/after arrow.
* @param {ASTNode} node The arrow function node.
* @returns {Object} Tokens of arrow and before/after arrow.
*/
function getTokens(node) {
const arrow = sourceCode.getTokenBefore(node.body, astUtils.isArrowToken);
return {
before: sourceCode.getTokenBefore(arrow),
arrow,
after: sourceCode.getTokenAfter(arrow),
};
}
/**
* Count spaces before/after arrow(`=>`) token.
* @param {Object} tokens Tokens before/after arrow.
* @returns {Object} count of space before/after arrow.
*/
function countSpaces(tokens) {
const before = tokens.arrow.range[0] - tokens.before.range[1];
const after = tokens.after.range[0] - tokens.arrow.range[1];
return { before, after };
}
/**
* Determines whether space(s) before after arrow(`=>`) is satisfy rule.
* if before/after value is `true`, there should be space(s).
* if before/after value is `false`, there should be no space.
* @param {ASTNode} node The arrow function node.
* @returns {void}
*/
function spaces(node) {
const tokens = getTokens(node);
const countSpace = countSpaces(tokens);
if (rule.before) {
// should be space(s) before arrow
if (countSpace.before === 0) {
context.report({
node: tokens.before,
messageId: 'expectedBefore',
fix(fixer) {
return fixer.insertTextBefore(tokens.arrow, ' ');
},
});
}
} else {
// should be no space before arrow
if (countSpace.before > 0) {
context.report({
node: tokens.before,
messageId: 'unexpectedBefore',
fix(fixer) {
return fixer.removeRange([
tokens.before.range[1],
tokens.arrow.range[0],
]);
},
});
}
}
if (rule.after) {
// should be space(s) after arrow
if (countSpace.after === 0) {
context.report({
node: tokens.after,
messageId: 'expectedAfter',
fix(fixer) {
return fixer.insertTextAfter(tokens.arrow, ' ');
},
});
}
} else {
// should be no space after arrow
if (countSpace.after > 0) {
context.report({
node: tokens.after,
messageId: 'unexpectedAfter',
fix(fixer) {
return fixer.removeRange([
tokens.arrow.range[1],
tokens.after.range[0],
]);
},
});
}
}
}
return {
ArrowFunctionExpression: spaces,
};
},
};