diff --git a/docs/rules/camelcase.md b/docs/rules/camelcase.md index cce3fd92470f..838cde911e06 100644 --- a/docs/rules/camelcase.md +++ b/docs/rules/camelcase.md @@ -14,6 +14,10 @@ This rule has an object option: * `"properties": "never"` does not check property names * `"ignoreDestructuring": false` (default) enforces camelcase style for destructured identifiers * `"ignoreDestructuring": true` does not check destructured identifiers +* `"allowLeadingUnderscores": true` (default) allow leading underscores, which is commonly used to flag private/protected identifiers +* `"allowLeadingUnderscores": false` does not allow leading underscores +* `"allowTrailingUnderscores": true` (default) allow trailing underscores, which is commonly used to flag private/protected identifiers +* `"allowTrailingUnderscores": false` does not allow trailing underscores ### properties: "always" @@ -151,6 +155,42 @@ var { category_id = 1 } = query; var { category_id: category_id } = query; ``` +### allowLeadingUnderscores: false + +Examples of **incorrect** code for this rule with the `{ "allowLeadingUnderscores": false }` option: + +```js +/*eslint camelcase: ["error", {allowLeadingUnderscores: false}]*/ + +var __leadingUnderscore = query; +``` + +Examples of **correct** code for this rule with the `{ "allowDestructuring": false }` option: + +```js +/*eslint camelcase: ["error", {allowDestructuring: false}]*/ + +var noLeadingUnderscore = query; +``` + +### allowTrailingUnderscores: false + +Examples of **incorrect** code for this rule with the `{ "allowTrailingUnderscores": false }` option: + +```js +/*eslint camelcase: ["error", {allowTrailingUnderscores: false}]*/ + +var trailingUnderscore__ = query; +``` + +Examples of **correct** code for this rule with the `{ "allowDestructuring": false }` option: + +```js +/*eslint camelcase: ["error", {allowDestructuring: false}]*/ + +var noTrailingUnderscore = query; +``` + ## When Not To Use It If you have established coding standards using a different naming convention (separating words with underscores), turn this rule off. diff --git a/lib/rules/camelcase.js b/lib/rules/camelcase.js index ec611662135c..13a14215570b 100644 --- a/lib/rules/camelcase.js +++ b/lib/rules/camelcase.js @@ -25,6 +25,12 @@ module.exports = { ignoreDestructuring: { type: "boolean" }, + allowLeadingUnderscores: { + type: "boolean" + }, + allowTrailingUnderscores: { + type: "boolean" + }, properties: { enum: ["always", "never"] } @@ -96,6 +102,8 @@ module.exports = { const options = context.options[0] || {}; let properties = options.properties || ""; const ignoreDestructuring = options.ignoreDestructuring || false; + const allowLeadingUnderscores = options.allowLeadingUnderscores !== false; + const allowTrailingUnderscores = options.allowTrailingUnderscores !== false; if (properties !== "always" && properties !== "never") { properties = "always"; @@ -105,12 +113,16 @@ module.exports = { Identifier(node) { - /* - * Leading and trailing underscores are commonly used to flag - * private/protected identifiers, strip them - */ - const name = node.name.replace(/^_+|_+$/g, ""), - effectiveParent = (node.parent.type === "MemberExpression") ? node.parent.parent : node.parent; + let name = node.name; + const effectiveParent = (node.parent.type === "MemberExpression") ? node.parent.parent : node.parent; + + // Strip leading and trailing underscores + if (allowLeadingUnderscores) { + name = name.replace(/^_+/g, ""); + } + if (allowTrailingUnderscores) { + name = name.replace(/_+$/g, ""); + } // MemberExpressions get special rules if (node.parent.type === "MemberExpression") { diff --git a/tests/lib/rules/camelcase.js b/tests/lib/rules/camelcase.js index f21459085060..28ff637d7a5e 100644 --- a/tests/lib/rules/camelcase.js +++ b/tests/lib/rules/camelcase.js @@ -184,6 +184,28 @@ ruleTester.run("camelcase", rule, { } ], invalid: [ + { + code: "__leadingUnderscores = null", + options: [{ allowLeadingUnderscores: false }], + errors: [ + { + messageId: "notCamelCase", + data: { name: "__leadingUnderscores" }, + type: "Identifier" + } + ] + }, + { + code: "trailingUnderscores__ = null", + options: [{ allowTrailingUnderscores: false }], + errors: [ + { + messageId: "notCamelCase", + data: { name: "trailingUnderscores__" }, + type: "Identifier" + } + ] + }, { code: "first_name = \"Nicholas\"", errors: [