Skip to content

Commit

Permalink
update accessor-pairs
Browse files Browse the repository at this point in the history
  • Loading branch information
mysticatea committed Jun 13, 2020
1 parent a574e27 commit 9125cf1
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 31 deletions.
15 changes: 1 addition & 14 deletions lib/rules/accessor-pairs.js
Expand Up @@ -86,16 +86,6 @@ function isAccessorKind(node) {
return node.kind === "get" || node.kind === "set";
}

/**
* Checks whether or not a given node is an `Identifier` node which was named a given name.
* @param {ASTNode} node A node to check.
* @param {string} name An expected name of the node.
* @returns {boolean} `true` if the node is an `Identifier` node which was named as expected.
*/
function isIdentifier(node, name) {
return node.type === "Identifier" && node.name === name;
}

/**
* Checks whether or not a given node is an argument of a specified method call.
* @param {ASTNode} node A node to check.
Expand All @@ -109,10 +99,7 @@ function isArgumentOfMethodCall(node, index, object, property) {

return (
parent.type === "CallExpression" &&
parent.callee.type === "MemberExpression" &&
parent.callee.computed === false &&
isIdentifier(parent.callee.object, object) &&
isIdentifier(parent.callee.property, property) &&
astUtils.isSpecificMemberAccess(parent.callee, object, property) &&
parent.arguments[index] === node
);
}
Expand Down
65 changes: 48 additions & 17 deletions lib/rules/utils/ast-utils.js
Expand Up @@ -9,6 +9,7 @@
// Requirements
//------------------------------------------------------------------------------

const eslintUtils = require("eslint-utils");
const esutils = require("esutils");
const espree = require("espree");
const lodash = require("lodash");
Expand Down Expand Up @@ -166,20 +167,56 @@ function isCallee(node) {
return node.parent.type === "CallExpression" && node.parent.callee === node;
}

/**
* Check if the `actual` is an expected value.
* @param {string} actual The string value to check.
* @param {string | RegExp} expected The expected string value or pattern.
* @returns {boolean} `true` if the `actual` is an expected value.
*/
function checkText(actual, expected) {
return typeof expected === "string"
? actual === expected
: expected.test(actual);
}

/**
* Check if a given node is member access with a given object name and property name pair.
* This is regardless of optional or not.
* @param {ASTNode} node The node to check.
* @param {string | RegExp | null} objectName The expected name or the expected pattern of the object name. If this is nullish, this method doesn't check object.
* @param {string | RegExp | null} propertyName The expected name or the expected pattern of the property name. If this is nullish, this method doesn't check property.
* @returns {boolean} `true` if the node is member access with the object name and property name pair.
* The node is a `MemberExpression` or `ChainExpression`.
*/
function isSpecificMemberAccess(node, objectName, propertyName) {
const checkNode = node.type === "ChainExpression" ? node.expression : node;

if (checkNode.type !== "MemberExpression") {
return false;
}

if (objectName && checkNode.object.type === "Identifier" && !checkText(checkNode.object.name, objectName)) {
return false;
}

if (propertyName) {
const actualPropertyName = eslintUtils.getPropertyName(checkNode);

if (typeof actualPropertyName !== "string" || !checkText(actualPropertyName, propertyName)) {
return false;
}
}

return true;
}

/**
* Checks whether or not a node is `Reflect.apply`.
* @param {ASTNode} node A node to check.
* @returns {boolean} Whether or not the node is a `Reflect.apply`.
*/
function isReflectApply(node) {
return (
node.type === "MemberExpression" &&
node.object.type === "Identifier" &&
node.object.name === "Reflect" &&
node.property.type === "Identifier" &&
node.property.name === "apply" &&
node.computed === false
);
return isSpecificMemberAccess(node, "Reflect", "apply");
}

/**
Expand All @@ -188,14 +225,7 @@ function isReflectApply(node) {
* @returns {boolean} Whether or not the node is a `Array.from`.
*/
function isArrayFromMethod(node) {
return (
node.type === "MemberExpression" &&
node.object.type === "Identifier" &&
arrayOrTypedArrayPattern.test(node.object.name) &&
node.property.type === "Identifier" &&
node.property.name === "from" &&
node.computed === false
);
return isSpecificMemberAccess(node, arrayOrTypedArrayPattern, "from");
}

/**
Expand Down Expand Up @@ -1590,5 +1620,6 @@ module.exports = {

isLogicalExpression,
isCoalesceExpression,
isMixedLogicalAndCoalesceExpressions
isMixedLogicalAndCoalesceExpressions,
isSpecificMemberAccess
};
40 changes: 40 additions & 0 deletions tests/lib/rules/accessor-pairs.js
Expand Up @@ -1087,6 +1087,46 @@ ruleTester.run("accessor-pairs", rule, {
code: "Object.create(null, {foo: {set: function(value) {}}});",
errors: [{ message: "Getter is not present in property descriptor.", type: "ObjectExpression" }]
},
{
code: "var o = {d: 1};\n Object?.defineProperty(o, 'c', \n{set: function(value) {\n val = value; \n} \n});",
parserOptions: { ecmaVersion: 2020 },
errors: [{ message: "Getter is not present in property descriptor.", type: "ObjectExpression" }]
},
{
code: "Reflect?.defineProperty(obj, 'foo', {set: function(value) {}});",
parserOptions: { ecmaVersion: 2020 },
errors: [{ message: "Getter is not present in property descriptor.", type: "ObjectExpression" }]
},
{
code: "Object?.defineProperties(obj, {foo: {set: function(value) {}}});",
parserOptions: { ecmaVersion: 2020 },
errors: [{ message: "Getter is not present in property descriptor.", type: "ObjectExpression" }]
},
{
code: "Object?.create(null, {foo: {set: function(value) {}}});",
parserOptions: { ecmaVersion: 2020 },
errors: [{ message: "Getter is not present in property descriptor.", type: "ObjectExpression" }]
},
{
code: "var o = {d: 1};\n (Object?.defineProperty)(o, 'c', \n{set: function(value) {\n val = value; \n} \n});",
parserOptions: { ecmaVersion: 2020 },
errors: [{ message: "Getter is not present in property descriptor.", type: "ObjectExpression" }]
},
{
code: "(Reflect?.defineProperty)(obj, 'foo', {set: function(value) {}});",
parserOptions: { ecmaVersion: 2020 },
errors: [{ message: "Getter is not present in property descriptor.", type: "ObjectExpression" }]
},
{
code: "(Object?.defineProperties)(obj, {foo: {set: function(value) {}}});",
parserOptions: { ecmaVersion: 2020 },
errors: [{ message: "Getter is not present in property descriptor.", type: "ObjectExpression" }]
},
{
code: "(Object?.create)(null, {foo: {set: function(value) {}}});",
parserOptions: { ecmaVersion: 2020 },
errors: [{ message: "Getter is not present in property descriptor.", type: "ObjectExpression" }]
},

//------------------------------------------------------------------------------
// Classes
Expand Down

0 comments on commit 9125cf1

Please sign in to comment.