UNPKG

eslint-plugin-sf-plugin

Version:
110 lines (109 loc) 6.67 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.noDuplicateShortCharacters = void 0; /* * Copyright (c) 2020, salesforce.com, inc. * All rights reserved. * Licensed under the BSD 3-Clause license. * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); const utils_1 = require("@typescript-eslint/utils"); const commands_1 = require("../shared/commands"); const flags_1 = require("../shared/flags"); exports.noDuplicateShortCharacters = eslint_utils_1.RuleCreator.withoutDocs({ meta: { docs: { description: 'Prevent duplicate use of short characters or conflicts between aliases and flags', recommended: 'recommended', }, messages: { flagCollision: 'Flag {{flag1}} has a name already in use as the name or alias of {{flag2}}', charCollision: 'Flags {{flag1}} and {{flag2}} share duplicate character {{char}}', aliasCollision: 'Flags {{flag1}} and {{flag2}} share alias {{alias}}', }, type: 'problem', schema: [], }, defaultOptions: [], create(context) { return (0, commands_1.isInCommandDirectory)(context) ? { PropertyDefinition(node) { var _a; // is "public static flags" property if ((0, commands_1.ancestorsContainsSfCommand)(context) && ((_a = node.value) === null || _a === void 0 ? void 0 : _a.type) === utils_1.AST_NODE_TYPES.ObjectExpression && (0, flags_1.isFlagsStaticProperty)(node)) { const previouslyUsed = new Map(); node.value.properties.filter(utils_1.ASTUtils.isNodeOfType(utils_1.AST_NODE_TYPES.Property)).forEach((flag) => { var _a, _b; // only if it has a char prop if (flag.value.type === utils_1.AST_NODE_TYPES.CallExpression && ((_b = (_a = flag.value.arguments) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.type) === utils_1.AST_NODE_TYPES.ObjectExpression) { const flagName = (0, flags_1.resolveFlagName)(flag); // 1. Has the flag name already been used? If so, mark the flag name as a problem if (previouslyUsed.has(flagName)) { context.report({ node: flag.key, messageId: 'flagCollision', data: { flag1: flagName, flag2: previouslyUsed.get(flagName), }, }); } else { previouslyUsed.set(flagName, flagName); } const flagProperties = flag.value.arguments[0].properties.filter(utils_1.ASTUtils.isNodeOfType(utils_1.AST_NODE_TYPES.Property)); // 2. has the char already been used? If so, mark the char as a problem const charNode = flagProperties.find((p) => (0, flags_1.flagPropertyIsNamed)('char')(p) && p.value.type === utils_1.AST_NODE_TYPES.Literal); if ((charNode === null || charNode === void 0 ? void 0 : charNode.value.type) === utils_1.AST_NODE_TYPES.Literal) { const char = charNode.value.value; if (previouslyUsed.has(char)) { context.report({ node: charNode, messageId: 'charCollision', data: { flag1: flagName, flag2: previouslyUsed.get(char), char, }, }); } else { previouslyUsed.set(char, flagName); } } // 3. is anything in this this flag's aliases already seen (alias or char)? If so, mark that alias as a problem const aliasesNode = flagProperties .filter((0, flags_1.flagPropertyIsNamed)('aliases')) .find((p) => p.value.type === utils_1.AST_NODE_TYPES.ArrayExpression); if ((aliasesNode === null || aliasesNode === void 0 ? void 0 : aliasesNode.value.type) === utils_1.AST_NODE_TYPES.ArrayExpression) { aliasesNode.value.elements.forEach((alias) => { if ((alias === null || alias === void 0 ? void 0 : alias.type) === utils_1.AST_NODE_TYPES.Literal) if (previouslyUsed.has(alias.value)) { context.report({ node: alias, messageId: 'aliasCollision', data: { flag1: flagName, flag2: previouslyUsed.get(alias.value), alias: alias.value, }, }); } else { previouslyUsed.set(alias.value, flagName); } }); } } }); } }, } : {}; }, });