eslint: "no-unused-vars" cannot report all parameters of function

Tell us about your environment

  • ESLint Version: 4.13.1
  • Node Version: 8.9.3

What parser (default, Babel-ESLint, etc.) are you using? default

Please show your full configuration:

Configuration
{
  "parserOptions": {
    "ecmaVersion": 2017,
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true
    }
  },
  "env": {
    "es6": true,
    "node": true
  },
  "plugins": [
    "import",
    "eslint-comments"
  ],
  "rules": {
    "no-compare-neg-zero": 2,
    "no-cond-assign": [2, "except-parens"],
    "no-constant-condition": 2,
    "no-dupe-args": 2,
    "no-dupe-keys": 2,
    "no-duplicate-case": 2,
    "no-ex-assign": 2,
    "no-extra-boolean-cast": 2,
    "no-extra-parens": [2, "all", {
      "conditionalAssign": false,
      "returnAssign": false,
      "nestedBinaryExpressions": false,
      "ignoreJSX": "multi-line",
      "enforceForArrowConditionals": false
    }],
    "no-extra-semi": 2,
    "no-func-assign": 2,
    "no-inner-declarations": [2, "functions"],
    "no-obj-calls": 2,
    "no-regex-spaces": 1,
    "no-sparse-arrays": 2,
    "no-template-curly-in-string": 1,
    "no-unexpected-multiline": 2,
    "no-unreachable": 2,
    "no-unsafe-negation": 2,
    "use-isnan": 2,
    "valid-jsdoc": 1,
    "valid-typeof": 2,
    "accessor-pairs": 1,
    "array-callback-return": 2,
    "curly": 2,
    "default-case": 1,
    "dot-location": [2, "property"],
    "dot-notation": [2, { "allowKeywords": false }],
    "eqeqeq": 2,
    "guard-for-in": 2,
    "no-alert": 2,
    "no-caller": 2,
    "no-case-declarations": 2,
    "no-empty-function": 2,
    "no-empty-pattern": 2,
    "no-eq-null": 2,
    "no-eval": 2,
    "no-extend-native": 2,
    "no-extra-bind": 2,
    "no-extra-label": 2,
    "no-fallthrough": 2,
    "no-floating-decimal": 2,
    "no-global-assign": 2,
    "no-implicit-coercion": [2, { "allow": ["!!", "~"] }],
    "no-implied-eval": 2,
    "no-iterator": 2,
    "no-loop-func": 2,
    "no-multi-spaces": [2, { "ignoreEOLComments": true }],
    "no-multi-str": 2,
    "no-new": 2,
    "no-new-func": 2,
    "no-new-wrappers": 2,
    "no-octal": 2,
    "no-param-reassign": 2,
    "no-proto": 2,
    "no-redeclare": 2,
    "no-return-assign": 2,
    "no-self-assign": 2,
    "no-self-compare": 2,
    "no-throw-literal": 2,
    "no-unmodified-loop-condition": 2,
    "no-unused-expressions": [2, { "allowShortCircuit": true, "allowTernary": true }],
    "no-unused-labels": 2,
    "no-useless-call": 2,
    "no-useless-concat": 2,
    "no-useless-escape": 2,
    "no-useless-return": 2,
    "no-with": 2,
    "radix": 2,
    "require-await": 2,
    "wrap-iife": [2, "inside"],
    "yoda": [2, "never"],
    "no-catch-shadow": 2,
    "no-shadow": 2,
    "no-shadow-restricted-names": 2,
    "no-undef": 2,
    "no-undef-init": 2,
    "no-undefined": 1,
    "no-unused-vars": 1,
    "no-use-before-define": 2,
    "handle-callback-err": 1,
    "no-buffer-constructor": 2,
    "no-new-require": 2,
    "no-path-concat": 1,
    "array-bracket-newline": [2, "consistent"],
    "array-bracket-spacing": [2, "never"],
    "block-spacing": [2, "always"],
    "brace-style": [2, "1tbs"],
    "camelcase": 2,
    "comma-dangle": [2, "only-multiline"],
    "comma-spacing": 2,
    "comma-style": 2,
    "computed-property-spacing": [2, "never"],
    "eol-last": 2,
    "func-call-spacing": [2, "never"],
    "func-name-matching": 2,
    "function-paren-newline": [2, "consistent"],
    "implicit-arrow-linebreak": [2, "beside"],
    "indent": [2, 2],
    "jsx-quotes": [2, "prefer-double"],
    "key-spacing": [2, { "mode": "strict" }],
    "keyword-spacing": 2,
    "linebreak-style": [2, "unix"],
    "lines-between-class-members": [2, "always"],
    "max-len": [2, { "code": 80 }],
    "max-params": [2, 3],
    "max-statements-per-line": [2, { "max": 1 }],
    "multiline-ternary": [2, "always-multiline"],
    "new-cap": 2,
    "new-parens": 2,
    "newline-per-chained-call": 2,
    "no-array-constructor": 2,
    "no-bitwise": 2,
    "no-lonely-if": 2,
    "no-mixed-operators": [2, { "allowSamePrecedence": true }],
    "no-mixed-spaces-and-tabs": 2,
    "no-multiple-empty-lines": 2,
    "no-new-object": 2,
    "no-trailing-spaces": [2, { "ignoreComments": true }],
    "no-unneeded-ternary": 2,
    "no-whitespace-before-property": 2,
    "object-curly-newline": [2, { "consistent": true }],
    "object-curly-spacing": [2, "always", { "arraysInObjects": true, "objectsInObjects": true }],
    "operator-assignment": [1, "always"],
    "operator-linebreak": [2, "before"],
    "quote-props": [2, "as-needed", { "keywords": true }],
    "quotes": [2, "single", { "avoidEscape": true }],
    "semi": [2, "never"],
    "semi-spacing": 2,
    "space-before-blocks": [2, "always"],
    "space-before-function-paren": [2, "always"],
    "space-in-parens": [2, "never"],
    "space-infix-ops": 2,
    "space-unary-ops": 2,
    "spaced-comment": 2,
    "switch-colon-spacing": 2,
    "template-tag-spacing": [2, "never"],
    "arrow-body-style": [2, "as-needed"],
    "arrow-parens": [2, "as-needed"],
    "arrow-spacing": 2,
    "constructor-super": 2,
    "no-class-assign": 2,
    "no-confusing-arrow": [2, { "allowParens": true }],
    "no-const-assign": 2,
    "no-dupe-class-members": 2,
    "no-duplicate-imports": 2,
    "no-new-symbol": 2,
    "no-this-before-super": 2,
    "no-useless-computed-key": 2,
    "no-useless-constructor": 2,
    "no-useless-rename": 2,
    "no-var": 2,
    "object-shorthand": 2,
    "prefer-arrow-callback": 2,
    "prefer-const": 2,
    "prefer-destructuring": 2,
    "prefer-numeric-literals": 2,
    "prefer-rest-params": 2,
    "prefer-spread": 2,
    "prefer-template": 1,
    "rest-spread-spacing": [2, "never"],
    "template-curly-spacing": [2, "never"],

    "import/no-unresolved": [2, { "ignore": ["^@"] }],
    "import/named": 1,
    "import/default": 2,
    "import/namespace": 2,
    "import/no-absolute-path": 2,
    "import/no-dynamic-require": 1,
    "import/export": 2,
    "import/no-named-as-default": 2,
    "import/no-named-as-default-member": 1,
    "import/no-deprecated": 1,
    "import/no-extraneous-dependencies": [2, { "devDependencies": ["**/*.test.js", "**/*.spec.js"] }],
    "import/first": 2,
    "import/exports-last": 1,
    "import/newline-after-import": 2,
    "import/prefer-default-export": 2,

    "eslint-comments/disable-enable-pair": [1, { "allowWholeFile": true }],
    "eslint-comments/no-aggregating-enable": 1,
    "eslint-comments/no-duplicate-disable": 1,
    "eslint-comments/no-unused-disable": 1,
    "eslint-comments/no-unused-enable": 1
  }
}

What did you do? Please include the actual source code causing the issue, as well as the command that you used to run ESLint.

Define a function which it has several unused parameters.

function fn (a, b, c) {
  // do nothing
}
fn()

What did you expect to happen?

For the example above, ESLint should report all parameters is unused.

What actually happened? Please include the actual, raw output from ESLint.

ESLint just reported the last parameter (for the example above that is c) is unused, previous parameters haven’t been reported. image

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 5
  • Comments: 21 (21 by maintainers)

Most upvoted comments

I’ll champion.

@eslint/eslint-team Could we get two more 👍s? Right now, no-unused-vars reports only the last parameter that is unused, even if earlier parameters are also unused. This is confusing and inconsistent with how we generally implement other rules and I think it needs to change.

I’ve run my examples through the ESLint demo page.

Everything looks good on the “all” setting.

For the “after-used” setting, I think the first two examples have a bug (only c is reported in the first example, and only e is reported in the second example).

So I’m now absolutely convinced we have a bug here.

I think we might have a bug here.

It’s true that the default setting for this rule is to only report unused args after the last used arg. However, we need to make sure all of them are reported.

function one(a, b, c) {
    // none used: Should report a, b, and c (even with the "after-used" setting)
}

function two(a, b, c, d, e) {
    doSomething(c);
    // a/b/d/e unused: Should report a/b/d/e in "all" setting, and d/e in "after-used" setting)
}

function three(a, b, c) {
    doSomething(c);
    // a/b unused: Should report a/b in "all" setting, and should not report in "after-used" setting)
}

If the actual rule isn’t following these patterns, I think we have a bug. I’m going to reopen for now.

I feel that it would make more sense from a UX standpoint to consider “all” and “after-used” as keywords to define what potentially unused arguments should be reported (i.e., report all of them, or only the ones after the last used argument?). Then we should report all such arguments that are unused and that match the constraint set by all/after-used.

Reporting only a subset doesn’t make sense to me. It’s not a great experience to get a warning for one unused argument, then remove it and rerun the linter to get another warning, etc. Might as well report all of them at once so the user only has to look at the parameter list once, holistically.

@nzakas Please let me know if I’m missing or misunderstanding something.

On Jan 29, 2018 9:26 AM, “Nicholas C. Zakas” notifications@github.com wrote:

According to the docs https://eslint.org/docs/rules/no-unused-vars., after-used behaves like this:

only the last argument must be used. This allows you, for instance, to have two named parameters to a function and as long as you use the second argument, ESLint will not warn you about the first.

So the key is whether or not the last argument is used. So @g-plane https://github.com/g-plane, I believe the fix in your example would be to warn that e is unused.

— You are receiving this because you were assigned. Reply to this email directly, view it on GitHub https://github.com/eslint/eslint/issues/9750#issuecomment-361280433, or mute the thread https://github.com/notifications/unsubscribe-auth/AARWeswbuGW4dqIimSSeq0fNdA4KSZ0Aks5tPeMigaJpZM4RJ44x .