All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.pitest.mutationtest.build.intercept.defensive.UnmodifiableCollections Maven / Gradle / Ivy

There is a newer version: 1.17.1
Show newest version
package org.pitest.mutationtest.build.intercept.defensive;

import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.LabelNode;
import org.pitest.bytecode.analysis.MethodTree;
import org.pitest.classinfo.ClassName;
import org.pitest.mutationtest.build.intercept.Region;
import org.pitest.mutationtest.build.intercept.RegionInterceptor;
import org.pitest.sequence.Context;
import org.pitest.sequence.Match;
import org.pitest.sequence.QueryParams;
import org.pitest.sequence.QueryStart;
import org.pitest.sequence.SequenceMatcher;
import org.pitest.sequence.Slot;
import org.pitest.sequence.SlotWrite;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import static org.pitest.bytecode.analysis.InstructionMatchers.anyInstruction;
import static org.pitest.bytecode.analysis.InstructionMatchers.isA;
import static org.pitest.bytecode.analysis.InstructionMatchers.methodCallTo;
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 UnmodifiableCollections extends RegionInterceptor {

    static final Slot MUTATED_INSTRUCTION = Slot.create(AbstractInsnNode.class);

    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.or(PUTFIELD))
            .zeroOrMore(QueryStart.match(anyInstruction()))
            .compile(QueryParams.params(AbstractInsnNode.class)
                    .withIgnores(notAnInstruction().or(isA(LabelNode.class)))
            );


    @Override
    protected List computeRegions(MethodTree method) {
        Context context = Context.start();
        return DEFENSIVE_RETURN.contextMatches(method.instructions(), context).stream()
                .map(c -> c.retrieve(MUTATED_INSTRUCTION.read()).get())
                .map(n -> new Region(n, n))
                .collect(Collectors.toList());
    }

    private static Match store(SlotWrite slot) {
        return (c,n) -> result(true, c.store(slot, n));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy