Repository: eslint/eslint (js)

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.

Pull request description:
Fix: no-param-reassign - ignore parameter used as condition in ternary operator
<!--
    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
-->

**What is the purpose of this pull request?**

- [x] Bug fix #11236 

<!--
    If the item you've checked above has a template, please paste the template questions below and answer them. (If this pull request is addressing an issue, you can just paste a link to the issue here instead.)
-->



<!--
    Please ensure your pull request is ready:

    - Read the pull request guide (https://eslint.org/docs/developer-guide/contributing/pull-requests)
    - Include tests for this change
    - Update documentation for this change (if appropriate)
-->

<!--
    The following is required for all pull requests:
-->

**What changes did you make? (Give an overview)**

Added case of `ConditionalExpression` (ternary operator) in rule `no-param-reassign` when checking modification to parameters.

Parameter used in condition of ternary operator will now be ignored.

`(arg ? a : b).c = 3;` should no longer trigger the rule.

**Is there anything you'd like reviewers to focus on?**




Patch:
diff --git a/lib/rules/no-param-reassign.js b/lib/rules/no-param-reassign.js
index 243bb6412..349345c14 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 5d009c338..40156f481 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 }],