UNPKG

3.27 kBJavaScriptView Raw
1/**
2 * @fileoverview Rule to
3 * @author Toru Nagashima
4 */
5
6"use strict";
7
8//------------------------------------------------------------------------------
9// Helpers
10//------------------------------------------------------------------------------
11
12/**
13 * Gets the variable object of `arguments` which is defined implicitly.
14 * @param {eslint-scope.Scope} scope - A scope to get.
15 * @returns {eslint-scope.Variable} The found variable object.
16 */
17function getVariableOfArguments(scope) {
18 const variables = scope.variables;
19
20 for (let i = 0; i < variables.length; ++i) {
21 const variable = variables[i];
22
23 if (variable.name === "arguments") {
24
25 /*
26 * If there was a parameter which is named "arguments", the implicit "arguments" is not defined.
27 * So does fast return with null.
28 */
29 return (variable.identifiers.length === 0) ? variable : null;
30 }
31 }
32
33 /* istanbul ignore next : unreachable */
34 return null;
35}
36
37/**
38 * Checks if the given reference is not normal member access.
39 *
40 * - arguments .... true // not member access
41 * - arguments[i] .... true // computed member access
42 * - arguments[0] .... true // computed member access
43 * - arguments.length .... false // normal member access
44 *
45 * @param {eslint-scope.Reference} reference - The reference to check.
46 * @returns {boolean} `true` if the reference is not normal member access.
47 */
48function isNotNormalMemberAccess(reference) {
49 const id = reference.identifier;
50 const parent = id.parent;
51
52 return !(
53 parent.type === "MemberExpression" &&
54 parent.object === id &&
55 !parent.computed
56 );
57}
58
59//------------------------------------------------------------------------------
60// Rule Definition
61//------------------------------------------------------------------------------
62
63module.exports = {
64 meta: {
65 docs: {
66 description: "require rest parameters instead of `arguments`",
67 category: "ECMAScript 6",
68 recommended: false,
69 url: "https://eslint.org/docs/rules/prefer-rest-params"
70 },
71
72 schema: []
73 },
74
75 create(context) {
76
77 /**
78 * Reports a given reference.
79 *
80 * @param {eslint-scope.Reference} reference - A reference to report.
81 * @returns {void}
82 */
83 function report(reference) {
84 context.report({
85 node: reference.identifier,
86 loc: reference.identifier.loc,
87 message: "Use the rest parameters instead of 'arguments'."
88 });
89 }
90
91 /**
92 * Reports references of the implicit `arguments` variable if exist.
93 *
94 * @returns {void}
95 */
96 function checkForArguments() {
97 const argumentsVar = getVariableOfArguments(context.getScope());
98
99 if (argumentsVar) {
100 argumentsVar
101 .references
102 .filter(isNotNormalMemberAccess)
103 .forEach(report);
104 }
105 }
106
107 return {
108 "FunctionDeclaration:exit": checkForArguments,
109 "FunctionExpression:exit": checkForArguments
110 };
111 }
112};