From cb1b60cd4c558bebb1a87419c0549750af63dca4 Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Fri, 16 Feb 2024 10:24:00 +0000 Subject: [PATCH 1/2] expand unmodifiable collection filter to field writes --- .../ReturnUnmodifiableCollection.java | 3 ++- ...turnUnmodifiableCollectionFactoryTest.java | 20 ++++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/build/intercept/defensive/ReturnUnmodifiableCollection.java b/pitest-entry/src/main/java/org/pitest/mutationtest/build/intercept/defensive/ReturnUnmodifiableCollection.java index efe9b2b5a..15ae2131a 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/build/intercept/defensive/ReturnUnmodifiableCollection.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/build/intercept/defensive/ReturnUnmodifiableCollection.java @@ -24,6 +24,7 @@ import static org.pitest.bytecode.analysis.InstructionMatchers.notAnInstruction; import static org.pitest.bytecode.analysis.OpcodeMatchers.ARETURN; import static org.pitest.bytecode.analysis.OpcodeMatchers.INVOKESTATIC; +import static org.pitest.bytecode.analysis.OpcodeMatchers.PUTFIELD; import static org.pitest.sequence.Result.result; public class ReturnUnmodifiableCollection extends RegionInterceptor { @@ -33,7 +34,7 @@ public class ReturnUnmodifiableCollection extends RegionInterceptor { static final SequenceMatcher DEFENSIVE_RETURN = QueryStart .any(AbstractInsnNode.class) .then(INVOKESTATIC.and(methodCallTo(ClassName.fromClass(Collections.class), n -> n.startsWith("unmodifiable"))).and(store(MUTATED_INSTRUCTION.write()))) - .then(ARETURN) + .then(ARETURN.or(PUTFIELD)) .zeroOrMore(QueryStart.match(anyInstruction())) .compile(QueryParams.params(AbstractInsnNode.class) .withIgnores(notAnInstruction().or(isA(LabelNode.class))) diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/build/intercept/defensive/ReturnUnmodifiableCollectionFactoryTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/build/intercept/defensive/ReturnUnmodifiableCollectionFactoryTest.java index c1a23ae57..a6aca16d1 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/build/intercept/defensive/ReturnUnmodifiableCollectionFactoryTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/build/intercept/defensive/ReturnUnmodifiableCollectionFactoryTest.java @@ -80,6 +80,14 @@ public void doesNotFilterOtherCode() { .verify(); } + @Test + public void filtersUnmodifiableStoresToFields() { + v.forClass(StoresToFields.class) + .forCodeMatching(INVOKESTATIC.asPredicate()) + .allMutantsAreFiltered() + .verify(); + } + @Test public void doesNotFilterOtherCallsToUnModifiableSet() { v.forClass(HasUnmodifiableSetNonReturn.class) @@ -89,6 +97,14 @@ public void doesNotFilterOtherCallsToUnModifiableSet() { } } +class StoresToFields { + final List ls; + + StoresToFields(List mod) { + ls = Collections.unmodifiableList(mod); + } +} + class HasUnmodifiableSetReturn { private final Set s = new HashSet<>(); @@ -122,12 +138,10 @@ public Map mutateMe(Map m) { class HasUnmodifiableSetNonReturn { private final Set s = new HashSet<>(); - private Set copy; - public Set dontMutateME(int i) { if (i != 1) { - copy = Collections.unmodifiableSet(s); + Set copy = Collections.unmodifiableSet(s); } return s; From 0dcf2632c2dd27fec4d90d96da8099b614ab4644 Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Fri, 16 Feb 2024 10:25:15 +0000 Subject: [PATCH 2/2] rename unmodifiable collection filter --- ...ctionFactory.java => UnmodifiableCollectionFactory.java} | 6 +++--- ...difiableCollection.java => UnmodifiableCollections.java} | 2 +- ...org.pitest.mutationtest.build.MutationInterceptorFactory | 2 +- ...oryTest.java => UnmodifiableCollectionsFactoryTest.java} | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) rename pitest-entry/src/main/java/org/pitest/mutationtest/build/intercept/defensive/{ReturnUnmodifiableCollectionFactory.java => UnmodifiableCollectionFactory.java} (72%) rename pitest-entry/src/main/java/org/pitest/mutationtest/build/intercept/defensive/{ReturnUnmodifiableCollection.java => UnmodifiableCollections.java} (97%) rename pitest-entry/src/test/java/org/pitest/mutationtest/build/intercept/defensive/{ReturnUnmodifiableCollectionFactoryTest.java => UnmodifiableCollectionsFactoryTest.java} (96%) diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/build/intercept/defensive/ReturnUnmodifiableCollectionFactory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/build/intercept/defensive/UnmodifiableCollectionFactory.java similarity index 72% rename from pitest-entry/src/main/java/org/pitest/mutationtest/build/intercept/defensive/ReturnUnmodifiableCollectionFactory.java rename to pitest-entry/src/main/java/org/pitest/mutationtest/build/intercept/defensive/UnmodifiableCollectionFactory.java index f00ff40d5..b1d2d7b2d 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/build/intercept/defensive/ReturnUnmodifiableCollectionFactory.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/build/intercept/defensive/UnmodifiableCollectionFactory.java @@ -5,10 +5,10 @@ import org.pitest.mutationtest.build.MutationInterceptorFactory; import org.pitest.plugin.Feature; -public class ReturnUnmodifiableCollectionFactory implements MutationInterceptorFactory { +public class UnmodifiableCollectionFactory implements MutationInterceptorFactory { @Override public MutationInterceptor createInterceptor(InterceptorParameters params) { - return new ReturnUnmodifiableCollection(); + return new UnmodifiableCollections(); } @Override @@ -20,6 +20,6 @@ public Feature provides() { @Override public String description() { - return "Filter mutations to defensive return wrappers such as unmodifiableCollection"; + return "Filter mutations to defensive wrappers such as unmodifiableCollection on return or field write"; } } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/build/intercept/defensive/ReturnUnmodifiableCollection.java b/pitest-entry/src/main/java/org/pitest/mutationtest/build/intercept/defensive/UnmodifiableCollections.java similarity index 97% rename from pitest-entry/src/main/java/org/pitest/mutationtest/build/intercept/defensive/ReturnUnmodifiableCollection.java rename to pitest-entry/src/main/java/org/pitest/mutationtest/build/intercept/defensive/UnmodifiableCollections.java index 15ae2131a..9239ec3fa 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/build/intercept/defensive/ReturnUnmodifiableCollection.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/build/intercept/defensive/UnmodifiableCollections.java @@ -27,7 +27,7 @@ import static org.pitest.bytecode.analysis.OpcodeMatchers.PUTFIELD; import static org.pitest.sequence.Result.result; -public class ReturnUnmodifiableCollection extends RegionInterceptor { +public class UnmodifiableCollections extends RegionInterceptor { static final Slot MUTATED_INSTRUCTION = Slot.create(AbstractInsnNode.class); diff --git a/pitest-entry/src/main/resources/META-INF/services/org.pitest.mutationtest.build.MutationInterceptorFactory b/pitest-entry/src/main/resources/META-INF/services/org.pitest.mutationtest.build.MutationInterceptorFactory index 441e2915d..72fa84776 100755 --- a/pitest-entry/src/main/resources/META-INF/services/org.pitest.mutationtest.build.MutationInterceptorFactory +++ b/pitest-entry/src/main/resources/META-INF/services/org.pitest.mutationtest.build.MutationInterceptorFactory @@ -24,7 +24,7 @@ org.pitest.mutationtest.build.intercept.equivalent.EquivalentReturnMutationFilte org.pitest.mutationtest.build.intercept.exclude.FirstLineInterceptorFactory org.pitest.mutationtest.build.intercept.equivalent.DivisionByMinusOneFilterFactory org.pitest.mutationtest.build.intercept.lombok.LombokFilter -org.pitest.mutationtest.build.intercept.defensive.ReturnUnmodifiableCollectionFactory +org.pitest.mutationtest.build.intercept.defensive.UnmodifiableCollectionFactory org.pitest.plugin.export.MutantExportFactory diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/build/intercept/defensive/ReturnUnmodifiableCollectionFactoryTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/build/intercept/defensive/UnmodifiableCollectionsFactoryTest.java similarity index 96% rename from pitest-entry/src/test/java/org/pitest/mutationtest/build/intercept/defensive/ReturnUnmodifiableCollectionFactoryTest.java rename to pitest-entry/src/test/java/org/pitest/mutationtest/build/intercept/defensive/UnmodifiableCollectionsFactoryTest.java index a6aca16d1..68806cb30 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/build/intercept/defensive/ReturnUnmodifiableCollectionFactoryTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/build/intercept/defensive/UnmodifiableCollectionsFactoryTest.java @@ -18,8 +18,8 @@ import static org.pitest.bytecode.analysis.OpcodeMatchers.INVOKESTATIC; -public class ReturnUnmodifiableCollectionFactoryTest { - private final MutationInterceptorFactory underTest = new ReturnUnmodifiableCollectionFactory(); +public class UnmodifiableCollectionsFactoryTest { + private final MutationInterceptorFactory underTest = new UnmodifiableCollectionFactory(); InterceptorVerifier v = VerifierStart.forInterceptorFactory(underTest) .usingMutator(new NullMutateEverything());