Skip to content

Commit 2bcc407

Browse files
committedFeb 24, 2025··
fix(immutable-data): make ignoreMapsAndSets option actually work (#936)
1 parent 37fa1ef commit 2bcc407

File tree

3 files changed

+88
-54
lines changed

3 files changed

+88
-54
lines changed
 

Diff for: ‎src/rules/immutable-data.ts

+56-54
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ function checkCallExpression(
526526
};
527527
}
528528

529-
const { ignoreImmediateMutation } = optionsToUse;
529+
const { ignoreImmediateMutation, ignoreMapsAndSets } = optionsToUse;
530530

531531
// Array mutation?
532532
if (
@@ -559,65 +559,67 @@ function checkCallExpression(
559559
}
560560
}
561561

562-
// Set mutation?
563-
if (
564-
setMutatorMethods.has(node.callee.property.name) &&
565-
(!ignoreImmediateMutation || !isInChainCallAndFollowsNew(node.callee, context)) &&
566-
isSetType(context, getTypeOfNode(node.callee.object, context))
567-
) {
568-
if (ignoreNonConstDeclarations === false) {
569-
return {
570-
context,
571-
descriptors: [{ node, messageId: "set" }],
572-
};
573-
}
574-
const rootIdentifier = findRootIdentifier(node.callee.object);
562+
if (!ignoreMapsAndSets) {
563+
// Set mutation?
575564
if (
576-
rootIdentifier === undefined ||
577-
!isDefinedByMutableVariable(
578-
rootIdentifier,
579-
context,
580-
(variableNode) =>
581-
ignoreNonConstDeclarations === true ||
582-
!ignoreNonConstDeclarations.treatParametersAsConst ||
583-
shouldIgnorePattern(variableNode, context, ignoreIdentifierPattern, ignoreAccessorPattern),
584-
)
565+
setMutatorMethods.has(node.callee.property.name) &&
566+
(!ignoreImmediateMutation || !isInChainCallAndFollowsNew(node.callee, context)) &&
567+
isSetType(context, getTypeOfNode(node.callee.object, context))
585568
) {
586-
return {
587-
context,
588-
descriptors: [{ node, messageId: "set" }],
589-
};
569+
if (ignoreNonConstDeclarations === false) {
570+
return {
571+
context,
572+
descriptors: [{ node, messageId: "set" }],
573+
};
574+
}
575+
const rootIdentifier = findRootIdentifier(node.callee.object);
576+
if (
577+
rootIdentifier === undefined ||
578+
!isDefinedByMutableVariable(
579+
rootIdentifier,
580+
context,
581+
(variableNode) =>
582+
ignoreNonConstDeclarations === true ||
583+
!ignoreNonConstDeclarations.treatParametersAsConst ||
584+
shouldIgnorePattern(variableNode, context, ignoreIdentifierPattern, ignoreAccessorPattern),
585+
)
586+
) {
587+
return {
588+
context,
589+
descriptors: [{ node, messageId: "set" }],
590+
};
591+
}
590592
}
591-
}
592593

593-
// Map mutation?
594-
if (
595-
mapMutatorMethods.has(node.callee.property.name) &&
596-
(!ignoreImmediateMutation || !isInChainCallAndFollowsNew(node.callee, context)) &&
597-
isMapType(context, getTypeOfNode(node.callee.object, context))
598-
) {
599-
if (ignoreNonConstDeclarations === false) {
600-
return {
601-
context,
602-
descriptors: [{ node, messageId: "map" }],
603-
};
604-
}
605-
const rootIdentifier = findRootIdentifier(node.callee.object);
594+
// Map mutation?
606595
if (
607-
rootIdentifier === undefined ||
608-
!isDefinedByMutableVariable(
609-
rootIdentifier,
610-
context,
611-
(variableNode) =>
612-
ignoreNonConstDeclarations === true ||
613-
!ignoreNonConstDeclarations.treatParametersAsConst ||
614-
shouldIgnorePattern(variableNode, context, ignoreIdentifierPattern, ignoreAccessorPattern),
615-
)
596+
mapMutatorMethods.has(node.callee.property.name) &&
597+
(!ignoreImmediateMutation || !isInChainCallAndFollowsNew(node.callee, context)) &&
598+
isMapType(context, getTypeOfNode(node.callee.object, context))
616599
) {
617-
return {
618-
context,
619-
descriptors: [{ node, messageId: "map" }],
620-
};
600+
if (ignoreNonConstDeclarations === false) {
601+
return {
602+
context,
603+
descriptors: [{ node, messageId: "map" }],
604+
};
605+
}
606+
const rootIdentifier = findRootIdentifier(node.callee.object);
607+
if (
608+
rootIdentifier === undefined ||
609+
!isDefinedByMutableVariable(
610+
rootIdentifier,
611+
context,
612+
(variableNode) =>
613+
ignoreNonConstDeclarations === true ||
614+
!ignoreNonConstDeclarations.treatParametersAsConst ||
615+
shouldIgnorePattern(variableNode, context, ignoreIdentifierPattern, ignoreAccessorPattern),
616+
)
617+
) {
618+
return {
619+
context,
620+
descriptors: [{ node, messageId: "map" }],
621+
};
622+
}
621623
}
622624
}
623625

Diff for: ‎tests/rules/immutable-data/map.test.ts

+16
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,22 @@ describe(name, () => {
2828
expect(invalidResult.messages).toMatchSnapshot();
2929
});
3030

31+
it("doesn't report mutating map methods when ignoring maps and sets", () => {
32+
valid({
33+
code: dedent`
34+
const x = new Map([[5, 6]]);
35+
x.set(4, 8);
36+
x.delete(4);
37+
x.clear();
38+
`,
39+
options: [
40+
{
41+
ignoreMapsAndSets: true,
42+
},
43+
],
44+
});
45+
});
46+
3147
it("doesn't report non-mutating map methods", () => {
3248
valid(dedent`
3349
const x = new Map([[5, 6]]);

Diff for: ‎tests/rules/immutable-data/set.test.ts

+16
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,22 @@ describe(name, () => {
2828
expect(invalidResult.messages).toMatchSnapshot();
2929
});
3030

31+
it("doesn't report mutating set methods when ignoring maps and sets", () => {
32+
valid({
33+
code: dedent`
34+
const x = new Set([5, 6]);
35+
x.add(4);
36+
x.delete(4);
37+
x.clear();
38+
`,
39+
options: [
40+
{
41+
ignoreMapsAndSets: true,
42+
},
43+
],
44+
});
45+
});
46+
3147
it("doesn't report non-mutating set methods", () => {
3248
valid(dedent`
3349
const x = new Set([5, 6]);

0 commit comments

Comments
 (0)
Please sign in to comment.