package fr.inria.diversify.transformation.query; import fr.inria.diversify.diversification.InputProgram; import fr.inria.diversify.coverage.ICoverageReport; import fr.inria.diversify.transformation.Transformation; import fr.inria.diversify.transformation.mutation.*; import spoon.reflect.code.BinaryOperatorKind; import spoon.reflect.code.CtBinaryOperator; import spoon.reflect.code.CtLocalVariable; import spoon.reflect.code.CtReturn; import java.util.Arrays; import java.util.List; import java.util.Random; import java.util.stream.Collectors; /** * User: Simon * Date: 12/02/14 * Time: 14:31 */ public class MutationQuery extends TransformationQuery { protected ICoverageReport coverageReport; protected List<CtBinaryOperator> binaryOperators; protected List<CtReturn> returns; protected List<CtLocalVariable> inlineConstant; protected static List<BinaryOperatorKind> negateConditional = Arrays.asList( new BinaryOperatorKind[]{BinaryOperatorKind.EQ, BinaryOperatorKind.NE, BinaryOperatorKind.LE, BinaryOperatorKind.GT, BinaryOperatorKind.LT, BinaryOperatorKind.GE}); protected static List<BinaryOperatorKind> conditionalBoundary = Arrays.asList( new BinaryOperatorKind[]{BinaryOperatorKind.LT, BinaryOperatorKind.GT,BinaryOperatorKind.LE, BinaryOperatorKind.GE}); protected static List<BinaryOperatorKind> math = Arrays.asList( new BinaryOperatorKind[]{BinaryOperatorKind.PLUS, BinaryOperatorKind.MINUS,BinaryOperatorKind.MUL, BinaryOperatorKind.DIV,BinaryOperatorKind.MOD, BinaryOperatorKind.BITAND, BinaryOperatorKind.BITOR, BinaryOperatorKind.SL,BinaryOperatorKind.SR, BinaryOperatorKind.USR}); public MutationQuery(InputProgram inputProgram) { super(inputProgram); this.coverageReport = inputProgram.getCoverageReport(); init(); } protected void init() { binaryOperators = getInputProgram().getAllElement(CtBinaryOperator.class).stream() .map(operator -> (CtBinaryOperator)operator) .collect(Collectors.toList()); returns = getInputProgram().getAllElement(CtReturn.class).stream() .map(operator -> (CtReturn)operator) .collect(Collectors.toList()); inlineConstant = getInputProgram().getAllElement(CtLocalVariable.class).stream() .map(operator -> (CtLocalVariable)operator) .collect(Collectors.toList()); } @Override public Transformation query() { try { Random r = new Random(); int i = r.nextInt(8); Transformation t = null; switch (i) { case 0: t = getNegateConditionalMutation(); break; case 1: t = getConditionalBoundaryMutation(); break; case 2: case 3: case 4: t = getMathMutation(); break; case 5: t = getRemoveConditionalMutation(); break; case 6: t = getReturnValueMutation(); break; case 7: t = getInlineConstantMutation(); break; } return t; } catch ( Exception e ) { throw new RuntimeException(e); } } public NegateConditionalMutation getNegateConditionalMutation() throws Exception { NegateConditionalMutation mutation = new NegateConditionalMutation(); Random r = new Random(); CtBinaryOperator operator = binaryOperators.get(r.nextInt(binaryOperators.size())); while (coverageReport.elementCoverage(operator) == 0 || !negateConditional.contains(operator.getKind())) { operator = binaryOperators.get(r.nextInt(binaryOperators.size())); } mutation.setTransformationPoint(operator); return mutation; } public ConditionalBoundaryMutation getConditionalBoundaryMutation() throws Exception { ConditionalBoundaryMutation mutation = new ConditionalBoundaryMutation(); Random r = new Random(); CtBinaryOperator operator = binaryOperators.get(r.nextInt(binaryOperators.size())); while (coverageReport.elementCoverage(operator) == 0 || !conditionalBoundary.contains(operator.getKind())) { operator = binaryOperators.get(r.nextInt(binaryOperators.size())); } mutation.setTransformationPoint(operator); return mutation; } public MathMutation getMathMutation() throws Exception { MathMutation mutation = new MathMutation(); Random r = new Random(); CtBinaryOperator operator = binaryOperators.get(r.nextInt(binaryOperators.size())); while (coverageReport.elementCoverage(operator) == 0 || !math.contains(operator.getKind())) { operator = binaryOperators.get(r.nextInt(binaryOperators.size())); } mutation.setTransformationPoint(operator); return mutation; } public RemoveConditionalMutation getRemoveConditionalMutation() throws Exception { RemoveConditionalMutation mutation = new RemoveConditionalMutation(); Random r = new Random(); CtBinaryOperator operator = binaryOperators.get(r.nextInt(binaryOperators.size())); while (coverageReport.elementCoverage(operator) == 0) { operator = binaryOperators.get(r.nextInt(binaryOperators.size())); } mutation.setTransformationPoint(operator); return mutation; } public ReturnValueMutation getReturnValueMutation() { ReturnValueMutation mutation = new ReturnValueMutation(); Random r = new Random(); CtReturn ret = returns.get(r.nextInt(returns.size())); while (coverageReport.elementCoverage(ret) == 0) { ret = returns.get(r.nextInt(returns.size())); } mutation.setTransformationPoint(ret); return mutation; } public InlineConstantMutation getInlineConstantMutation() { InlineConstantMutation mutation = new InlineConstantMutation(); Random r = new Random(); CtLocalVariable ret = inlineConstant.get(r.nextInt(inlineConstant.size())); while (coverageReport.elementCoverage(ret) == 0) { ret = inlineConstant.get(r.nextInt(inlineConstant.size())); } mutation.setTransformationPoint(ret); return mutation; } }