Skip to content

Commit

Permalink
chore: refactor for define-prototype-method-handler
Browse files Browse the repository at this point in the history
  • Loading branch information
ota-meshi committed Nov 18, 2024
1 parent 6c07320 commit f4fe930
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 87 deletions.
135 changes: 49 additions & 86 deletions lib/util/define-prototype-method-handler/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,18 @@ const { getSourceCode } = require("eslint-compat-utils")

/**
* @typedef {import("estree").MemberExpression} MemberExpression
* @typedef {import("estree").Property} Property
* @typedef {import("estree").Expression} Expression
* @typedef {import("estree").Node} Node
* @typedef {import("eslint").Rule.RuleContext} RuleContext
* @typedef {import("eslint").Rule.ReportDescriptor} ReportDescriptor
*/
/**
* @typedef {object} CreateReportArgument
* @property {true | 'aggressive'} objectTypeResult
* @property {string} className
* @property {string} propertyName
* @property {MemberExpression} node
* @property {MemberExpression|Property} node
*/
/**
* @typedef {object} Options
Expand All @@ -29,7 +34,7 @@ const { getSourceCode } = require("eslint-compat-utils")
* @param {RuleContext} context The rule context.
* @param {Record<string, readonly string[]>} nameMap The method names to disallow. The key is class names and that value is method names.
* @param {Options} [options] The options.
* @returns {Record<string, (node: ASTNode) => void>} The defined handlers.
* @returns {Record<string, (node: Node) => void>} The defined handlers.
*/
function definePrototypeMethodHandler(context, nameMap, options) {
const sourceCode = getSourceCode(context)
Expand All @@ -40,6 +45,12 @@ function definePrototypeMethodHandler(context, nameMap, options) {
buildObjectTypeCheckerForTS(context, aggressiveResult) ||
buildObjectTypeChecker(context, aggressiveResult)

/**
* @param {MemberExpression|Property} node
* @param {string} className
* @param {string} propertyName
* @param {true | "aggressive"} objectTypeResult
*/
function report(node, className, propertyName, objectTypeResult) {
context.report({
node,
Expand All @@ -59,66 +70,44 @@ function definePrototypeMethodHandler(context, nameMap, options) {
})
}

// For performance
const nameMapEntries = Object.entries(nameMap)
/**
* @param {MemberExpression|Property} node
* @param {string} propertyName
* @param {Expression} objectNode
*/
// eslint-disable-next-line func-style
let verifyPropertyName = (node, propertyName, objectNode) => {
for (const [className, methodNames] of nameMapEntries) {
let objectTypeResult = undefined
if (
methodNames.includes(propertyName) &&
(objectTypeResult = objectTypeChecker(
node,
objectNode,
className,
))
) {
report(node, className, propertyName, objectTypeResult)
return
}
}
}
if (nameMapEntries.length === 1) {
// For performance
const [[className, methodNames]] = nameMapEntries
return {
/** @param {MemberExpression} node */
MemberExpression(node) {
const propertyName = getPropertyName(
verifyPropertyName = (node, propertyName, objectNode) => {
let objectTypeResult = undefined
if (
methodNames.includes(propertyName) &&
(objectTypeResult = objectTypeChecker(
node,
sourceCode.getScope(node),
)
if (propertyName == null) {
return
}
let objectTypeResult = undefined
if (
methodNames.includes(propertyName) &&
(objectTypeResult = objectTypeChecker(
node,
node.object,
className,
))
) {
report(node, className, propertyName, objectTypeResult)
}
},
/** @param {import("estree").Property} node */
[[
"VariableDeclarator > ObjectPattern.id > Property.properties",
"AssignmentExpression > ObjectPattern.left > Property.properties",
"AssignmentPattern > ObjectPattern.left > Property.properties",
].join(",")](node) {
const propertyName = getPropertyName(
node,
sourceCode.getScope(node),
)
if (propertyName == null) {
return
}
/** @type {import("estree").VariableDeclarator | import("estree").AssignmentExpression | import("estree").AssignmentPattern} */
const assignmentNode = node.parent.parent
const objectNode =
assignmentNode.type === "VariableDeclarator"
? assignmentNode.init
: assignmentNode.right
if (!objectNode) {
return
}
let objectTypeResult = undefined
if (
methodNames.includes(propertyName) &&
(objectTypeResult = objectTypeChecker(
node,
objectNode,
className,
))
) {
report(node, className, propertyName, objectTypeResult)
}
},
objectNode,
className,
))
) {
report(node, className, propertyName, objectTypeResult)
}
}
}

Expand All @@ -132,20 +121,7 @@ function definePrototypeMethodHandler(context, nameMap, options) {
if (propertyName == null) {
return
}
for (const [className, methodNames] of nameMapEntries) {
let objectTypeResult = undefined
if (
methodNames.includes(propertyName) &&
(objectTypeResult = objectTypeChecker(
node,
node.object,
className,
))
) {
report(node, className, propertyName, objectTypeResult)
return
}
}
verifyPropertyName(node, propertyName, node.object)
},
/** @param {import("estree").Property} node */
[[
Expand All @@ -169,20 +145,7 @@ function definePrototypeMethodHandler(context, nameMap, options) {
if (!objectNode) {
return
}
for (const [className, methodNames] of nameMapEntries) {
let objectTypeResult = undefined
if (
methodNames.includes(propertyName) &&
(objectTypeResult = objectTypeChecker(
node,
objectNode,
className,
))
) {
report(node, className, propertyName, objectTypeResult)
return
}
}
verifyPropertyName(node, propertyName, objectNode)
},
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/util/type-checker/object-type-checker.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ module.exports = { buildObjectTypeChecker, buildExpressionTypeProvider }
* Build object type checker.
* @param {RuleContext} context The rule context.
* @param {boolean | "aggressive"} aggressiveResult The value to return if the type cannot be determined.
* @returns {((memberAccessNode: MemberExpression|Property, objectNode: Expression, className: string) => boolean | "aggressive") | null} Returns an object type checker.
* @returns {((memberAccessNode: MemberExpression|Property, objectNode: Expression, className: string) => boolean | "aggressive")} Returns an object type checker.
*/
function buildObjectTypeChecker(context, aggressiveResult) {
const getType = buildExpressionTypeProvider(context)
Expand Down

0 comments on commit f4fe930

Please sign in to comment.