| "use strict"; |
| var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { |
| if (k2 === undefined) k2 = k; |
| Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); |
| }) : (function(o, m, k, k2) { |
| if (k2 === undefined) k2 = k; |
| o[k2] = m[k]; |
| })); |
| var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { |
| Object.defineProperty(o, "default", { enumerable: true, value: v }); |
| }) : function(o, v) { |
| o["default"] = v; |
| }); |
| var __importStar = (this && this.__importStar) || function (mod) { |
| if (mod && mod.__esModule) return mod; |
| var result = {}; |
| if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); |
| __setModuleDefault(result, mod); |
| return result; |
| }; |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| const utils_1 = require("@typescript-eslint/utils"); |
| const scope_manager_1 = require("@typescript-eslint/scope-manager"); |
| const util = __importStar(require("../util")); |
| const naming_convention_utils_1 = require("./naming-convention-utils"); |
| // This essentially mirrors ESLint's `camelcase` rule |
| // note that that rule ignores leading and trailing underscores and only checks those in the middle of a variable name |
| const defaultCamelCaseAllTheThingsConfig = [ |
| { |
| selector: 'default', |
| format: ['camelCase'], |
| leadingUnderscore: 'allow', |
| trailingUnderscore: 'allow', |
| }, |
| { |
| selector: 'variable', |
| format: ['camelCase', 'UPPER_CASE'], |
| leadingUnderscore: 'allow', |
| trailingUnderscore: 'allow', |
| }, |
| { |
| selector: 'typeLike', |
| format: ['PascalCase'], |
| }, |
| ]; |
| exports.default = util.createRule({ |
| name: 'naming-convention', |
| meta: { |
| docs: { |
| description: 'Enforces naming conventions for everything across a codebase', |
| recommended: false, |
| // technically only requires type checking if the user uses "type" modifiers |
| requiresTypeChecking: true, |
| }, |
| type: 'suggestion', |
| messages: { |
| unexpectedUnderscore: '{{type}} name `{{name}}` must not have a {{position}} underscore.', |
| missingUnderscore: '{{type}} name `{{name}}` must have {{count}} {{position}} underscore(s).', |
| missingAffix: '{{type}} name `{{name}}` must have one of the following {{position}}es: {{affixes}}', |
| satisfyCustom: '{{type}} name `{{name}}` must {{regexMatch}} the RegExp: {{regex}}', |
| doesNotMatchFormat: '{{type}} name `{{name}}` must match one of the following formats: {{formats}}', |
| doesNotMatchFormatTrimmed: '{{type}} name `{{name}}` trimmed as `{{processedName}}` must match one of the following formats: {{formats}}', |
| }, |
| schema: naming_convention_utils_1.SCHEMA, |
| }, |
| defaultOptions: defaultCamelCaseAllTheThingsConfig, |
| create(contextWithoutDefaults) { |
| const context = contextWithoutDefaults.options && |
| contextWithoutDefaults.options.length > 0 |
| ? contextWithoutDefaults |
| : // only apply the defaults when the user provides no config |
| Object.setPrototypeOf({ |
| options: defaultCamelCaseAllTheThingsConfig, |
| }, contextWithoutDefaults); |
| const validators = (0, naming_convention_utils_1.parseOptions)(context); |
| // getParserServices(context, false) -- dirty hack to work around the docs checker test... |
| const compilerOptions = util |
| .getParserServices(context, true) |
| .program.getCompilerOptions(); |
| function handleMember(validator, node, modifiers) { |
| if (!validator) { |
| return; |
| } |
| const key = node.key; |
| if (requiresQuoting(key, compilerOptions.target)) { |
| modifiers.add(naming_convention_utils_1.Modifiers.requiresQuotes); |
| } |
| validator(key, modifiers); |
| } |
| function getMemberModifiers(node) { |
| const modifiers = new Set(); |
| if (node.accessibility) { |
| modifiers.add(naming_convention_utils_1.Modifiers[node.accessibility]); |
| } |
| else { |
| modifiers.add(naming_convention_utils_1.Modifiers.public); |
| } |
| if (node.static) { |
| modifiers.add(naming_convention_utils_1.Modifiers.static); |
| } |
| if ('readonly' in node && node.readonly) { |
| modifiers.add(naming_convention_utils_1.Modifiers.readonly); |
| } |
| if (node.type === utils_1.AST_NODE_TYPES.TSAbstractPropertyDefinition || |
| node.type === utils_1.AST_NODE_TYPES.TSAbstractMethodDefinition) { |
| modifiers.add(naming_convention_utils_1.Modifiers.abstract); |
| } |
| return modifiers; |
| } |
| const unusedVariables = util.collectUnusedVariables(context); |
| function isUnused(name, initialScope = context.getScope()) { |
| var _a; |
| let variable = null; |
| let scope = initialScope; |
| while (scope) { |
| variable = (_a = scope.set.get(name)) !== null && _a !== void 0 ? _a : null; |
| if (variable) { |
| break; |
| } |
| scope = scope.upper; |
| } |
| if (!variable) { |
| return false; |
| } |
| return unusedVariables.has(variable); |
| } |
| function isDestructured(id) { |
| var _a, _b, _c; |
| return ( |
| // `const { x }` |
| // does not match `const { x: y }` |
| (((_a = id.parent) === null || _a === void 0 ? void 0 : _a.type) === utils_1.AST_NODE_TYPES.Property && id.parent.shorthand) || |
| // `const { x = 2 }` |
| // does not match const `{ x: y = 2 }` |
| (((_b = id.parent) === null || _b === void 0 ? void 0 : _b.type) === utils_1.AST_NODE_TYPES.AssignmentPattern && |
| ((_c = id.parent.parent) === null || _c === void 0 ? void 0 : _c.type) === utils_1.AST_NODE_TYPES.Property && |
| id.parent.parent.shorthand)); |
| } |
| return { |
| // #region variable |
| VariableDeclarator(node) { |
| const validator = validators.variable; |
| if (!validator) { |
| return; |
| } |
| const identifiers = getIdentifiersFromPattern(node.id); |
| const baseModifiers = new Set(); |
| const parent = node.parent; |
| if ((parent === null || parent === void 0 ? void 0 : parent.type) === utils_1.AST_NODE_TYPES.VariableDeclaration) { |
| if (parent.kind === 'const') { |
| baseModifiers.add(naming_convention_utils_1.Modifiers.const); |
| } |
| if (isGlobal(context.getScope())) { |
| baseModifiers.add(naming_convention_utils_1.Modifiers.global); |
| } |
| } |
| identifiers.forEach(id => { |
| const modifiers = new Set(baseModifiers); |
| if (isDestructured(id)) { |
| modifiers.add(naming_convention_utils_1.Modifiers.destructured); |
| } |
| if (isExported(parent, id.name, context.getScope())) { |
| modifiers.add(naming_convention_utils_1.Modifiers.exported); |
| } |
| if (isUnused(id.name)) { |
| modifiers.add(naming_convention_utils_1.Modifiers.unused); |
| } |
| validator(id, modifiers); |
| }); |
| }, |
| // #endregion |
| // #region function |
| 'FunctionDeclaration, TSDeclareFunction, FunctionExpression'(node) { |
| const validator = validators.function; |
| if (!validator || node.id === null) { |
| return; |
| } |
| const modifiers = new Set(); |
| // functions create their own nested scope |
| const scope = context.getScope().upper; |
| if (isGlobal(scope)) { |
| modifiers.add(naming_convention_utils_1.Modifiers.global); |
| } |
| if (isExported(node, node.id.name, scope)) { |
| modifiers.add(naming_convention_utils_1.Modifiers.exported); |
| } |
| if (isUnused(node.id.name, scope)) { |
| modifiers.add(naming_convention_utils_1.Modifiers.unused); |
| } |
| validator(node.id, modifiers); |
| }, |
| // #endregion function |
| // #region parameter |
| 'FunctionDeclaration, TSDeclareFunction, TSEmptyBodyFunctionExpression, FunctionExpression, ArrowFunctionExpression'(node) { |
| const validator = validators.parameter; |
| if (!validator) { |
| return; |
| } |
| node.params.forEach(param => { |
| if (param.type === utils_1.AST_NODE_TYPES.TSParameterProperty) { |
| return; |
| } |
| const identifiers = getIdentifiersFromPattern(param); |
| identifiers.forEach(i => { |
| const modifiers = new Set(); |
| if (isDestructured(i)) { |
| modifiers.add(naming_convention_utils_1.Modifiers.destructured); |
| } |
| if (isUnused(i.name)) { |
| modifiers.add(naming_convention_utils_1.Modifiers.unused); |
| } |
| validator(i, modifiers); |
| }); |
| }); |
| }, |
| // #endregion parameter |
| // #region parameterProperty |
| TSParameterProperty(node) { |
| const validator = validators.parameterProperty; |
| if (!validator) { |
| return; |
| } |
| const modifiers = getMemberModifiers(node); |
| const identifiers = getIdentifiersFromPattern(node.parameter); |
| identifiers.forEach(i => { |
| validator(i, modifiers); |
| }); |
| }, |
| // #endregion parameterProperty |
| // #region property |
| ':not(ObjectPattern) > Property[computed = false][kind = "init"][value.type != "ArrowFunctionExpression"][value.type != "FunctionExpression"][value.type != "TSEmptyBodyFunctionExpression"]'(node) { |
| const modifiers = new Set([naming_convention_utils_1.Modifiers.public]); |
| handleMember(validators.objectLiteralProperty, node, modifiers); |
| }, |
| ':matches(PropertyDefinition, TSAbstractPropertyDefinition)[computed = false][value.type != "ArrowFunctionExpression"][value.type != "FunctionExpression"][value.type != "TSEmptyBodyFunctionExpression"]'(node) { |
| const modifiers = getMemberModifiers(node); |
| handleMember(validators.classProperty, node, modifiers); |
| }, |
| 'TSPropertySignature[computed = false]'(node) { |
| const modifiers = new Set([naming_convention_utils_1.Modifiers.public]); |
| if (node.readonly) { |
| modifiers.add(naming_convention_utils_1.Modifiers.readonly); |
| } |
| handleMember(validators.typeProperty, node, modifiers); |
| }, |
| // #endregion property |
| // #region method |
| [[ |
| 'Property[computed = false][kind = "init"][value.type = "ArrowFunctionExpression"]', |
| 'Property[computed = false][kind = "init"][value.type = "FunctionExpression"]', |
| 'Property[computed = false][kind = "init"][value.type = "TSEmptyBodyFunctionExpression"]', |
| ].join(', ')](node) { |
| const modifiers = new Set([naming_convention_utils_1.Modifiers.public]); |
| handleMember(validators.objectLiteralMethod, node, modifiers); |
| }, |
| [[ |
| ':matches(PropertyDefinition, TSAbstractPropertyDefinition)[computed = false][value.type = "ArrowFunctionExpression"]', |
| ':matches(PropertyDefinition, TSAbstractPropertyDefinition)[computed = false][value.type = "FunctionExpression"]', |
| ':matches(PropertyDefinition, TSAbstractPropertyDefinition)[computed = false][value.type = "TSEmptyBodyFunctionExpression"]', |
| ':matches(MethodDefinition, TSAbstractMethodDefinition)[computed = false][kind = "method"]', |
| ].join(', ')](node) { |
| const modifiers = getMemberModifiers(node); |
| handleMember(validators.classMethod, node, modifiers); |
| }, |
| 'TSMethodSignature[computed = false]'(node) { |
| const modifiers = new Set([naming_convention_utils_1.Modifiers.public]); |
| handleMember(validators.typeMethod, node, modifiers); |
| }, |
| // #endregion method |
| // #region accessor |
| 'Property[computed = false]:matches([kind = "get"], [kind = "set"])'(node) { |
| const modifiers = new Set([naming_convention_utils_1.Modifiers.public]); |
| handleMember(validators.accessor, node, modifiers); |
| }, |
| 'MethodDefinition[computed = false]:matches([kind = "get"], [kind = "set"])'(node) { |
| const modifiers = getMemberModifiers(node); |
| handleMember(validators.accessor, node, modifiers); |
| }, |
| // #endregion accessor |
| // #region enumMember |
| // computed is optional, so can't do [computed = false] |
| 'TSEnumMember[computed != true]'(node) { |
| const validator = validators.enumMember; |
| if (!validator) { |
| return; |
| } |
| const id = node.id; |
| const modifiers = new Set(); |
| if (requiresQuoting(id, compilerOptions.target)) { |
| modifiers.add(naming_convention_utils_1.Modifiers.requiresQuotes); |
| } |
| validator(id, modifiers); |
| }, |
| // #endregion enumMember |
| // #region class |
| 'ClassDeclaration, ClassExpression'(node) { |
| const validator = validators.class; |
| if (!validator) { |
| return; |
| } |
| const id = node.id; |
| if (id === null) { |
| return; |
| } |
| const modifiers = new Set(); |
| // classes create their own nested scope |
| const scope = context.getScope().upper; |
| if (node.abstract) { |
| modifiers.add(naming_convention_utils_1.Modifiers.abstract); |
| } |
| if (isExported(node, id.name, scope)) { |
| modifiers.add(naming_convention_utils_1.Modifiers.exported); |
| } |
| if (isUnused(id.name, scope)) { |
| modifiers.add(naming_convention_utils_1.Modifiers.unused); |
| } |
| validator(id, modifiers); |
| }, |
| // #endregion class |
| // #region interface |
| TSInterfaceDeclaration(node) { |
| const validator = validators.interface; |
| if (!validator) { |
| return; |
| } |
| const modifiers = new Set(); |
| const scope = context.getScope(); |
| if (isExported(node, node.id.name, scope)) { |
| modifiers.add(naming_convention_utils_1.Modifiers.exported); |
| } |
| if (isUnused(node.id.name, scope)) { |
| modifiers.add(naming_convention_utils_1.Modifiers.unused); |
| } |
| validator(node.id, modifiers); |
| }, |
| // #endregion interface |
| // #region typeAlias |
| TSTypeAliasDeclaration(node) { |
| const validator = validators.typeAlias; |
| if (!validator) { |
| return; |
| } |
| const modifiers = new Set(); |
| const scope = context.getScope(); |
| if (isExported(node, node.id.name, scope)) { |
| modifiers.add(naming_convention_utils_1.Modifiers.exported); |
| } |
| if (isUnused(node.id.name, scope)) { |
| modifiers.add(naming_convention_utils_1.Modifiers.unused); |
| } |
| validator(node.id, modifiers); |
| }, |
| // #endregion typeAlias |
| // #region enum |
| TSEnumDeclaration(node) { |
| const validator = validators.enum; |
| if (!validator) { |
| return; |
| } |
| const modifiers = new Set(); |
| // enums create their own nested scope |
| const scope = context.getScope().upper; |
| if (isExported(node, node.id.name, scope)) { |
| modifiers.add(naming_convention_utils_1.Modifiers.exported); |
| } |
| if (isUnused(node.id.name, scope)) { |
| modifiers.add(naming_convention_utils_1.Modifiers.unused); |
| } |
| validator(node.id, modifiers); |
| }, |
| // #endregion enum |
| // #region typeParameter |
| 'TSTypeParameterDeclaration > TSTypeParameter'(node) { |
| const validator = validators.typeParameter; |
| if (!validator) { |
| return; |
| } |
| const modifiers = new Set(); |
| const scope = context.getScope(); |
| if (isUnused(node.name.name, scope)) { |
| modifiers.add(naming_convention_utils_1.Modifiers.unused); |
| } |
| validator(node.name, modifiers); |
| }, |
| // #endregion typeParameter |
| }; |
| }, |
| }); |
| function getIdentifiersFromPattern(pattern) { |
| const identifiers = []; |
| const visitor = new scope_manager_1.PatternVisitor({}, pattern, id => identifiers.push(id)); |
| visitor.visit(pattern); |
| return identifiers; |
| } |
| function isExported(node, name, scope) { |
| var _a, _b; |
| if (((_a = node === null || node === void 0 ? void 0 : node.parent) === null || _a === void 0 ? void 0 : _a.type) === utils_1.AST_NODE_TYPES.ExportDefaultDeclaration || |
| ((_b = node === null || node === void 0 ? void 0 : node.parent) === null || _b === void 0 ? void 0 : _b.type) === utils_1.AST_NODE_TYPES.ExportNamedDeclaration) { |
| return true; |
| } |
| if (scope == null) { |
| return false; |
| } |
| const variable = scope.set.get(name); |
| if (variable) { |
| for (const ref of variable.references) { |
| const refParent = ref.identifier.parent; |
| if ((refParent === null || refParent === void 0 ? void 0 : refParent.type) === utils_1.AST_NODE_TYPES.ExportDefaultDeclaration || |
| (refParent === null || refParent === void 0 ? void 0 : refParent.type) === utils_1.AST_NODE_TYPES.ExportSpecifier) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| function isGlobal(scope) { |
| if (scope == null) { |
| return false; |
| } |
| return (scope.type === utils_1.TSESLint.Scope.ScopeType.global || |
| scope.type === utils_1.TSESLint.Scope.ScopeType.module); |
| } |
| function requiresQuoting(node, target) { |
| const name = node.type === utils_1.AST_NODE_TYPES.Identifier || |
| node.type === utils_1.AST_NODE_TYPES.PrivateIdentifier |
| ? node.name |
| : `${node.value}`; |
| return util.requiresQuoting(name, target); |
| } |
| //# sourceMappingURL=naming-convention.js.map |