|
|
- /**
- * @fileoverview Rule to require sorting of variables within a single Variable Declaration block
- * @author Ilya Volodin
- */
-
- "use strict";
-
- //------------------------------------------------------------------------------
- // Rule Definition
- //------------------------------------------------------------------------------
-
- /** @type {import('../shared/types').Rule} */
- module.exports = {
- meta: {
- type: "suggestion",
-
- docs: {
- description: "Require variables within the same declaration block to be sorted",
- recommended: false,
- url: "https://eslint.org/docs/latest/rules/sort-vars"
- },
-
- schema: [
- {
- type: "object",
- properties: {
- ignoreCase: {
- type: "boolean",
- default: false
- }
- },
- additionalProperties: false
- }
- ],
-
- fixable: "code",
-
- messages: {
- sortVars: "Variables within the same declaration block should be sorted alphabetically."
- }
- },
-
- create(context) {
-
- const configuration = context.options[0] || {},
- ignoreCase = configuration.ignoreCase || false,
- sourceCode = context.sourceCode;
-
- return {
- VariableDeclaration(node) {
- const idDeclarations = node.declarations.filter(decl => decl.id.type === "Identifier");
- const getSortableName = ignoreCase ? decl => decl.id.name.toLowerCase() : decl => decl.id.name;
- const unfixable = idDeclarations.some(decl => decl.init !== null && decl.init.type !== "Literal");
- let fixed = false;
-
- idDeclarations.slice(1).reduce((memo, decl) => {
- const lastVariableName = getSortableName(memo),
- currentVariableName = getSortableName(decl);
-
- if (currentVariableName < lastVariableName) {
- context.report({
- node: decl,
- messageId: "sortVars",
- fix(fixer) {
- if (unfixable || fixed) {
- return null;
- }
- return fixer.replaceTextRange(
- [idDeclarations[0].range[0], idDeclarations[idDeclarations.length - 1].range[1]],
- idDeclarations
-
- // Clone the idDeclarations array to avoid mutating it
- .slice()
-
- // Sort the array into the desired order
- .sort((declA, declB) => {
- const aName = getSortableName(declA);
- const bName = getSortableName(declB);
-
- return aName > bName ? 1 : -1;
- })
-
- // Build a string out of the sorted list of identifier declarations and the text between the originals
- .reduce((sourceText, identifier, index) => {
- const textAfterIdentifier = index === idDeclarations.length - 1
- ? ""
- : sourceCode.getText().slice(idDeclarations[index].range[1], idDeclarations[index + 1].range[0]);
-
- return sourceText + sourceCode.getText(identifier) + textAfterIdentifier;
- }, "")
-
- );
- }
- });
- fixed = true;
- return memo;
- }
- return decl;
-
- }, idDeclarations[0]);
- }
- };
- }
- };
|