8000 Update: Add ignored prop regex no-param-reassign (#11275) · eslint/eslint@aac3be4 · GitHub
[go: up one dir, main page]

Skip to content

Commit aac3be4

Browse files
lbennett-stackiilyavolodin
authored andcommitted
Update: Add ignored prop regex no-param-reassign (#11275)
Uses new `ignoredPropertyAssignmentsRegex` option.
1 parent e5382d6 commit aac3be4

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

docs/rules/no-param-reassign.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ function foo(bar) {
4242

4343
## Options
4444

45-
This rule takes one option, an object, with a boolean property `"props"` and an array `"ignorePropertyModificationsFor"`. `"props"` is `false` by default. If `"props"` is set to `true`, this rule warns against the modification of parameter properties unless they're included in `"ignorePropertyModificationsFor"`, which is an empty array by default.
45+
This rule takes one option, an object, with a boolean property `"props"`, and arrays `"ignorePropertyModificationsFor"` and `"ignorePropertyModificationsForRegex"`. `"props"` is `false` by default. If `"props"` is set to `true`, this rule warns against the modification of parameter properties unless they're included in `"ignorePropertyModificationsFor"` or `"ignorePropertyModificationsForRegex"`, which is an empty array by default.
4646

4747
### props
4848

@@ -124,6 +124,24 @@ function foo(bar) {
124124
}
125125
```
126126

127+
Examples of **correct** code for the `{ "props": true }` option with `"ignorePropertyModificationsForRegex"` set:
128+
129+
```js
130+
/*eslint no-param-reassign: ["error", { "props": true, "ignorePropertyModificationsForRegex": ["^bar"] }]*/
131+
132+
function foo(bar) {
133+
barVar.prop = "value";
134+
}
135+
136+
function foo(bar) {
137+
delete barrito.aaa;
138+
}
139+
140+
function foo(bar) {
141+
bar_.aaa++;
142+
}
143+
```
144+
127145

128146
## When Not To Use It
129147

lib/rules/no-param-reassign.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ module.exports = {
4545
type: "string"
4646
},
4747
uniqueItems: true
48+
},
49+
ignorePropertyModificationsForRegex: {
50+
type: "array",
51+
items: {
52+
type: "string"
53+
},
54+
uniqueItems: true
4855
}
4956
},
5057
additionalProperties: false
@@ -57,6 +64,7 @@ module.exports = {
5764
create(context) {
5865
const props = context.options[0] && context.options[0].props;
5966
const ignoredPropertyAssignmentsFor = context.options[0] && context.options[0].ignorePropertyModificationsFor || [];
67+
const ignoredPropertyAssignmentsForRegex = context.options[0] && context.options[0].ignorePropertyModificationsForRegex || [];
6068

6169
/**
6270
* Checks whether or not the reference modifies properties of its variable.
@@ -136,6 +144,19 @@ module.exports = {
136144
return false;
137145
}
138146

147+
/**
148+
* Tests that an identifier name matches any of the ignored property assignments.
149+
* First we test strings in ignoredPropertyAssignmentsFor.
150+
* Then we instantiate and test RegExp objects from ignoredPropertyAssignmentsForRegex strings.
151+
* @param {string} identifierName - A string that describes the name of an identifier to
152+
* ignore property assignments for.
153+
* @returns {boolean} Whether the string matches an ignored property assignment regular expression or not.
154+
*/
155+
function isIgnoredPropertyAssignment(identifierName) {
156+
return ignoredPropertyAssignmentsFor.includes(identifierName) ||
157+
ignoredPropertyAssignmentsForRegex.some(ignored => new RegExp(ignored, "u").test(identifierName));
158+
}
159+
139160
/**
140161
* Reports a reference if is non initializer and writable.
141162
* @param {Reference} reference A reference to check.
@@ -157,7 +178,7 @@ module.exports = {
157178
) {
158179
if (reference.isWrite()) {
159180
context.report({ node: identifier, message: "Assignment to function parameter '{{name}}'.", data: { name: identifier.name } });
160-
} else if (props && isModifyingProp(reference) && ignoredPropertyAssignmentsFor.indexOf(identifier.name) === -1) {
181+
} else if (props && isModifyingProp(reference) && !isIgnoredPropertyAssignment(identifier.name)) {
161182
context.report({ node: identifier, message: "Assignment to property of function parameter '{{name}}'.", data: { name: identifier.name } });
162183
}
163184
}

tests/lib/rules/no-param-reassign.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ ruleTester.run("no-param-reassign", rule, {
4545
{ code: "function foo(a) { for (a.b of arr); }", options: [{ props: true, ignorePropertyModificationsFor: ["a"] }], parserOptions: { ecmaVersion: 6 } },
4646
{ code: "function foo(a, z) { a.b = 0; x.y = 0; }", options: [{ props: true, ignorePropertyModificationsFor: ["a", "x"] }] },
4747
{ code: "function foo(a) { a.b.c = 0;}", options: [{ props: true, ignorePropertyModificationsFor: ["a"] }] },
48+
{ code: "function foo(aFoo) { aFoo.b = 0; }", options: [{ props: true, ignorePropertyModificationsForRegex: ["^a.*$"] }] },
49+
{ code: "function foo(aFoo) { ++aFoo.b; }", options: [{ props: true, ignorePropertyModificationsForRegex: ["^a.*$"] }] },
50+
{ code: "function foo(aFoo) { delete aFoo.b; }", options: [{ props: true, ignorePropertyModificationsForRegex: ["^a.*$"] }] },
51+
{ code: "function foo(a, z) { aFoo.b = 0; x.y = 0; }", options: [{ props: true, ignorePropertyModificationsForRegex: ["^a.*$", "^x.*$"] }] },
52+
{ code: "function foo(aFoo) { aFoo.b.c = 0;}", options: [{ props: true, ignorePropertyModificationsForRegex: ["^a.*$"] }] },
4853
{
4954
code: "function foo(a) { ({ [a]: variable } = value) }",
5055
options: [{ props: true }],
@@ -152,6 +157,18 @@ ruleTester.run("no-param-reassign", rule, {
152157
parserOptions: { ecmaVersion: 6 },
153158
errors: [{ message: "Assignment to property of function parameter 'bar'." }]
154159
},
160+
{
161+
code: "function foo(bar) { [bar.a] = []; }",
162+
options: [{ props: true, ignorePropertyModificationsForRegex: ["^a.*$"] }],
163+
parserOptions: { ecmaVersion: 6 },
164+
errors: [{ message: "Assignment to property of function parameter 'bar'." }]
165+
},
166+
{
167+
code: "function foo(bar) { [bar.a] = []; }",
168+
options: [{ props: true, ignorePropertyModificationsForRegex: ["^B.*$"] }],
169+
parserOptions: { ecmaVersion: 6 },
170+
errors: [{ message: "Assignment to property of function parameter 'bar'." }]
171+
},
155172
{
156173
code: "function foo(bar) { ({foo: bar.a} = {}); }",
157174
options: [{ props: true }],

0 commit comments

Comments
 (0)
0