github-pages-deploy-action/node_modules/eslint/lib/rules/no-underscore-dangle.js

278 lines
10 KiB
JavaScript
Raw Normal View History

2020-03-07 11:45:40 +08:00
/**
2020-09-13 06:19:45 +08:00
* @fileoverview Rule to flag dangling underscores in variable declarations.
2020-03-07 11:45:40 +08:00
* @author Matt DuVall <http://www.mattduvall.com>
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = {
meta: {
type: "suggestion",
docs: {
description: "disallow dangling underscores in identifiers",
category: "Stylistic Issues",
recommended: false,
url: "https://eslint.org/docs/rules/no-underscore-dangle"
},
schema: [
{
type: "object",
properties: {
allow: {
type: "array",
items: {
type: "string"
}
},
allowAfterThis: {
type: "boolean",
default: false
},
allowAfterSuper: {
type: "boolean",
default: false
},
2020-03-31 20:40:00 +08:00
allowAfterThisConstructor: {
type: "boolean",
default: false
},
2020-03-07 11:45:40 +08:00
enforceInMethodNames: {
type: "boolean",
default: false
2020-09-13 06:19:45 +08:00
},
allowFunctionParams: {
type: "boolean",
default: true
2020-03-07 11:45:40 +08:00
}
},
additionalProperties: false
}
2020-05-15 05:33:08 +08:00
],
messages: {
unexpectedUnderscore: "Unexpected dangling '_' in '{{identifier}}'."
}
2020-03-07 11:45:40 +08:00
},
create(context) {
const options = context.options[0] || {};
const ALLOWED_VARIABLES = options.allow ? options.allow : [];
const allowAfterThis = typeof options.allowAfterThis !== "undefined" ? options.allowAfterThis : false;
const allowAfterSuper = typeof options.allowAfterSuper !== "undefined" ? options.allowAfterSuper : false;
2020-03-31 20:40:00 +08:00
const allowAfterThisConstructor = typeof options.allowAfterThisConstructor !== "undefined" ? options.allowAfterThisConstructor : false;
2020-03-07 11:45:40 +08:00
const enforceInMethodNames = typeof options.enforceInMethodNames !== "undefined" ? options.enforceInMethodNames : false;
2020-09-13 06:19:45 +08:00
const allowFunctionParams = typeof options.allowFunctionParams !== "undefined" ? options.allowFunctionParams : true;
2020-03-07 11:45:40 +08:00
//-------------------------------------------------------------------------
// Helpers
//-------------------------------------------------------------------------
/**
* Check if identifier is present inside the allowed option
* @param {string} identifier name of the node
* @returns {boolean} true if its is present
* @private
*/
function isAllowed(identifier) {
return ALLOWED_VARIABLES.some(ident => ident === identifier);
}
/**
2020-09-13 06:19:45 +08:00
* Check if identifier has a dangling underscore
2020-03-31 20:40:00 +08:00
* @param {string} identifier name of the node
2020-03-07 11:45:40 +08:00
* @returns {boolean} true if its is present
* @private
*/
2020-09-13 06:19:45 +08:00
function hasDanglingUnderscore(identifier) {
2020-03-07 11:45:40 +08:00
const len = identifier.length;
return identifier !== "_" && (identifier[0] === "_" || identifier[len - 1] === "_");
}
/**
* Check if identifier is a special case member expression
2020-03-31 20:40:00 +08:00
* @param {string} identifier name of the node
2020-03-07 11:45:40 +08:00
* @returns {boolean} true if its is a special case
* @private
*/
function isSpecialCaseIdentifierForMemberExpression(identifier) {
return identifier === "__proto__";
}
/**
* Check if identifier is a special case variable expression
2020-03-31 20:40:00 +08:00
* @param {string} identifier name of the node
2020-03-07 11:45:40 +08:00
* @returns {boolean} true if its is a special case
* @private
*/
function isSpecialCaseIdentifierInVariableExpression(identifier) {
// Checks for the underscore library usage here
return identifier === "_";
}
2020-03-31 20:40:00 +08:00
/**
* Check if a node is a member reference of this.constructor
* @param {ASTNode} node node to evaluate
* @returns {boolean} true if it is a reference on this.constructor
* @private
*/
function isThisConstructorReference(node) {
return node.object.type === "MemberExpression" &&
node.object.property.name === "constructor" &&
node.object.object.type === "ThisExpression";
}
2020-03-07 11:45:40 +08:00
/**
2020-09-13 06:19:45 +08:00
* Check if function parameter has a dangling underscore.
* @param {ASTNode} node function node to evaluate
* @returns {void}
* @private
*/
function checkForDanglingUnderscoreInFunctionParameters(node) {
if (!allowFunctionParams) {
node.params.forEach(param => {
const { type } = param;
let nodeToCheck;
if (type === "RestElement") {
nodeToCheck = param.argument;
} else if (type === "AssignmentPattern") {
nodeToCheck = param.left;
} else {
nodeToCheck = param;
}
if (nodeToCheck.type === "Identifier") {
const identifier = nodeToCheck.name;
if (hasDanglingUnderscore(identifier) && !isAllowed(identifier)) {
context.report({
node: param,
messageId: "unexpectedUnderscore",
data: {
identifier
}
});
}
}
});
}
}
/**
* Check if function has a dangling underscore
2020-03-07 11:45:40 +08:00
* @param {ASTNode} node node to evaluate
* @returns {void}
* @private
*/
2020-09-13 06:19:45 +08:00
function checkForDanglingUnderscoreInFunction(node) {
if (node.type === "FunctionDeclaration" && node.id) {
2020-03-07 11:45:40 +08:00
const identifier = node.id.name;
2020-09-13 06:19:45 +08:00
if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier) && !isAllowed(identifier)) {
2020-03-07 11:45:40 +08:00
context.report({
node,
2020-05-15 05:33:08 +08:00
messageId: "unexpectedUnderscore",
2020-03-07 11:45:40 +08:00
data: {
identifier
}
});
}
}
2020-09-13 06:19:45 +08:00
checkForDanglingUnderscoreInFunctionParameters(node);
2020-03-07 11:45:40 +08:00
}
/**
2020-09-13 06:19:45 +08:00
* Check if variable expression has a dangling underscore
2020-03-07 11:45:40 +08:00
* @param {ASTNode} node node to evaluate
* @returns {void}
* @private
*/
2020-09-13 06:19:45 +08:00
function checkForDanglingUnderscoreInVariableExpression(node) {
2020-03-07 11:45:40 +08:00
const identifier = node.id.name;
2020-09-13 06:19:45 +08:00
if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier) &&
2020-03-07 11:45:40 +08:00
!isSpecialCaseIdentifierInVariableExpression(identifier) && !isAllowed(identifier)) {
context.report({
node,
2020-05-15 05:33:08 +08:00
messageId: "unexpectedUnderscore",
2020-03-07 11:45:40 +08:00
data: {
identifier
}
});
}
}
/**
2020-09-13 06:19:45 +08:00
* Check if member expression has a dangling underscore
2020-03-07 11:45:40 +08:00
* @param {ASTNode} node node to evaluate
* @returns {void}
* @private
*/
2020-09-13 06:19:45 +08:00
function checkForDanglingUnderscoreInMemberExpression(node) {
2020-03-07 11:45:40 +08:00
const identifier = node.property.name,
isMemberOfThis = node.object.type === "ThisExpression",
2020-03-31 20:40:00 +08:00
isMemberOfSuper = node.object.type === "Super",
isMemberOfThisConstructor = isThisConstructorReference(node);
2020-03-07 11:45:40 +08:00
2020-09-13 06:19:45 +08:00
if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier) &&
2020-03-07 11:45:40 +08:00
!(isMemberOfThis && allowAfterThis) &&
!(isMemberOfSuper && allowAfterSuper) &&
2020-03-31 20:40:00 +08:00
!(isMemberOfThisConstructor && allowAfterThisConstructor) &&
2020-03-07 11:45:40 +08:00
!isSpecialCaseIdentifierForMemberExpression(identifier) && !isAllowed(identifier)) {
context.report({
node,
2020-05-15 05:33:08 +08:00
messageId: "unexpectedUnderscore",
2020-03-07 11:45:40 +08:00
data: {
identifier
}
});
}
}
/**
2020-09-13 06:19:45 +08:00
* Check if method declaration or method property has a dangling underscore
2020-03-07 11:45:40 +08:00
* @param {ASTNode} node node to evaluate
* @returns {void}
* @private
*/
2020-09-13 06:19:45 +08:00
function checkForDanglingUnderscoreInMethod(node) {
2020-03-07 11:45:40 +08:00
const identifier = node.key.name;
const isMethod = node.type === "MethodDefinition" || node.type === "Property" && node.method;
2020-09-13 06:19:45 +08:00
if (typeof identifier !== "undefined" && enforceInMethodNames && isMethod && hasDanglingUnderscore(identifier) && !isAllowed(identifier)) {
2020-03-07 11:45:40 +08:00
context.report({
node,
2020-05-15 05:33:08 +08:00
messageId: "unexpectedUnderscore",
2020-03-07 11:45:40 +08:00
data: {
identifier
}
});
}
}
//--------------------------------------------------------------------------
// Public API
//--------------------------------------------------------------------------
return {
2020-09-13 06:19:45 +08:00
FunctionDeclaration: checkForDanglingUnderscoreInFunction,
VariableDeclarator: checkForDanglingUnderscoreInVariableExpression,
MemberExpression: checkForDanglingUnderscoreInMemberExpression,
MethodDefinition: checkForDanglingUnderscoreInMethod,
Property: checkForDanglingUnderscoreInMethod,
FunctionExpression: checkForDanglingUnderscoreInFunction,
ArrowFunctionExpression: checkForDanglingUnderscoreInFunction
2020-03-07 11:45:40 +08:00
};
}
};