Repository: eslint/eslint (JavaScript)

Issue:
Assignment to ternary expression using function parameter as condition triggers no-param-reassign
<!--
    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).

    This template is for bug reports. If you are here for another reason, please see below:

    1. To propose a new rule: https://eslint.org/docs/developer-guide/contributing/new-rules
    2. To request a rule change: https://eslint.org/docs/developer-guide/contributing/rule-changes
    3. To request a change that is not a bug fix, rule change, or new rule: https://eslint.org/docs/developer-guide/contributing/changes
    4. If you have any questions, please stop by our chatroom: https://gitter.im/eslint/eslint

    Note that leaving sections blank will make it difficult for us to troubleshoot and we may have to close the issue.
-->

**Tell us about your environment**

* **ESLint Version:** 5.9.0
* **Node Version:** 8.12.0
* **npm Version:** 6.4.1

**What parser (default, Babel-ESLint, etc.) are you using?** babel-eslint

**Please show your full configuration:**

<details>
<summary>Configuration</summary>

<!-- Paste your configuration below: -->
```js
{
    "parser": "babel-eslint",
    "extends": "airbnb",
    "env": {
        "browser": true
    },
    "rules": {
        "jsx-a11y/click-events-have-key-events": "off",
        "jsx-a11y/no-static-element-interactions": "off",
        "react/jsx-one-expression-per-line": [true, { "allow": "literal" }],
        "no-restricted-syntax": ["error", "ForInStatement", "LabeledStatement", "WithStatement"]
    }
}
```

</details>

**What did you do? Please include the actual source code causing the issue, as well as the command that you used to run ESLint.**

<!-- Paste the source code below: -->
```js
function test(arg) {
  const array = [[1], [2]];
  (arg ? array[0] : array[1])[0] = 3;
  return array;
}
```

<!-- Paste the command you used to run ESLint: -->
```bash
yarn eslint src/
```

**What did you expect to happen?**
The above code should not emit lint errors.

**What actually happened? Please include the actual, raw output from ESLint.**
`error  Assignment to property of function parameter 'arg'     no-param-reassign`

**Are you willing to submit a pull request to fix this bug?**
Will try if possible.


Discussion:
Thanks for the report, I can reproduce this issue. It seems to only occur when using the `props: true` option.
Hi @zhouhaoyu, thanks for the issue!

I [can reproduce](https://eslint.org/demo/#eyJ0ZXh0IjoiLyogZXNsaW50IG5vLXBhcmFtLXJlYXNzaWduOiBbZXJyb3IsIHsgcHJvcHM6IHRydWUgfV0gKi9cblxuZnVuY3Rpb24gdGVzdChhcmcpIHtcbiAgY29uc3QgYXJyYXkgPSBbWzFdLCBbMl1dO1xuICAoYXJnID8gYXJyYXlbMF0gOiBhcnJheVsxXSlbMF0gPSAzO1xuICByZXR1cm4gYXJyYXk7XG59Iiwib3B0aW9ucyI6eyJwYXJzZXJPcHRpb25zIjp7ImVjbWFWZXJzaW9uIjo2LCJzb3VyY2VUeXBlIjoic2NyaXB0IiwiZWNtYUZlYXR1cmVzIjp7fX0sInJ1bGVzIjp7fSwiZW52Ijp7fX19) in the demo, so I'm marking this as accepted. Thanks also for the PR-- I'll review that shortly!



Patch:
diff --git a/lib/rules/no-param-reassign.js b/lib/rules/no-param-reassign.js
index 243bb6412cff..349345c148a7 100644
--- a/lib/rules/no-param-reassign.js
+++ b/lib/rules/no-param-reassign.js
@@ -107,6 +107,14 @@ module.exports = {
 
                         break;
 
+                    // EXCLUDES: e.g. (foo ? a : b).c = bar;
+                    case "ConditionalExpression":
+                        if (parent.test === node) {
+                            return false;
+                        }
+
+                        break;
+
                     // no default
                 }
 


Test patch:
diff --git a/tests/lib/rules/no-param-reassign.js b/tests/lib/rules/no-param-reassign.js
index 5d009c338f35..40156f481ec8 100644
--- a/tests/lib/rules/no-param-reassign.js
+++ b/tests/lib/rules/no-param-reassign.js
@@ -32,6 +32,8 @@ ruleTester.run("no-param-reassign", rule, {
         { code: "function foo(a) { bar(a.b).c = 0; }", options: [{ props: true }] },
         { code: "function foo(a) { data[a.b] = 0; }", options: [{ props: true }] },
         { code: "function foo(a) { +a.b; }", options: [{ props: true }] },
+        { code: "function foo(a) { (a ? [] : [])[0] = 1; }", options: [{ props: true }] },
+        { code: "function foo(a) { (a.b ? [] : [])[0] = 1; }", options: [{ props: true }] },
         { code: "function foo(a) { a.b = 0; }", options: [{ props: true, ignorePropertyModificationsFor: ["a"] }] },
         { code: "function foo(a) { ++a.b; }", options: [{ props: true, ignorePropertyModificationsFor: ["a"] }] },
         { code: "function foo(a) { delete a.b; }", options: [{ props: true, ignorePropertyModificationsFor: ["a"] }] },
@@ -87,6 +89,11 @@ ruleTester.run("no-param-reassign", rule, {
             options: [{ props: true }],
             errors: [{ message: "Assignment to property of function parameter 'bar'." }]
         },
+        {
+            code: "function foo(bar) { (bar ? bar : [])[0] = 1; }",
+            options: [{ props: true }],
+            errors: [{ message: "Assignment to property of function parameter 'bar'." }]
+        },
         {
             code: "function foo(bar) { [bar.a] = []; }",
             options: [{ props: true }],