| /** |
| * @fileoverview Rule to |
| * @author Toru Nagashima |
| */ |
| |
| "use strict"; |
| |
| //------------------------------------------------------------------------------ |
| // Helpers |
| //------------------------------------------------------------------------------ |
| |
| /** |
| * Gets the variable object of `arguments` which is defined implicitly. |
| * @param {eslint-scope.Scope} scope - A scope to get. |
| * @returns {eslint-scope.Variable} The found variable object. |
| */ |
| function getVariableOfArguments(scope) { |
| const variables = scope.variables; |
| |
| for (let i = 0; i < variables.length; ++i) { |
| const variable = variables[i]; |
| |
| if (variable.name === "arguments") { |
| |
| /* |
| * If there was a parameter which is named "arguments", the implicit "arguments" is not defined. |
| * So does fast return with null. |
| */ |
| return (variable.identifiers.length === 0) ? variable : null; |
| } |
| } |
| |
| /* istanbul ignore next : unreachable */ |
| return null; |
| } |
| |
| /** |
| * Checks if the given reference is not normal member access. |
| * |
| * - arguments .... true // not member access |
| * - arguments[i] .... true // computed member access |
| * - arguments[0] .... true // computed member access |
| * - arguments.length .... false // normal member access |
| * |
| * @param {eslint-scope.Reference} reference - The reference to check. |
| * @returns {boolean} `true` if the reference is not normal member access. |
| */ |
| function isNotNormalMemberAccess(reference) { |
| const id = reference.identifier; |
| const parent = id.parent; |
| |
| return !( |
| parent.type === "MemberExpression" && |
| parent.object === id && |
| !parent.computed |
| ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| // Rule Definition |
| //------------------------------------------------------------------------------ |
| |
| module.exports = { |
| meta: { |
| type: "suggestion", |
| |
| docs: { |
| description: "require rest parameters instead of `arguments`", |
| category: "ECMAScript 6", |
| recommended: false, |
| url: "https://eslint.org/docs/rules/prefer-rest-params" |
| }, |
| |
| schema: [] |
| }, |
| |
| create(context) { |
| |
| /** |
| * Reports a given reference. |
| * |
| * @param {eslint-scope.Reference} reference - A reference to report. |
| * @returns {void} |
| */ |
| function report(reference) { |
| context.report({ |
| node: reference.identifier, |
| loc: reference.identifier.loc, |
| message: "Use the rest parameters instead of 'arguments'." |
| }); |
| } |
| |
| /** |
| * Reports references of the implicit `arguments` variable if exist. |
| * |
| * @returns {void} |
| */ |
| function checkForArguments() { |
| const argumentsVar = getVariableOfArguments(context.getScope()); |
| |
| if (argumentsVar) { |
| argumentsVar |
| .references |
| .filter(isNotNormalMemberAccess) |
| .forEach(report); |
| } |
| } |
| |
| return { |
| "FunctionDeclaration:exit": checkForArguments, |
| "FunctionExpression:exit": checkForArguments |
| }; |
| } |
| }; |