--- /dev/null
+/**
+ * @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
+ };
+ }
+};