de.unisb.cs.st.javalanche.mutation.bytecodeMutations.replaceIntegerConstant.RicMethodAdapter.java Source code

Java tutorial

Introduction

Here is the source code for de.unisb.cs.st.javalanche.mutation.bytecodeMutations.replaceIntegerConstant.RicMethodAdapter.java

Source

/*
 * Copyright (C) 2011 Saarland University
 * 
 * This file is part of Javalanche.
 * 
 * Javalanche is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Javalanche is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser Public License
 * along with Javalanche.  If not, see <http://www.gnu.org/licenses/>.
 */
package de.unisb.cs.st.javalanche.mutation.bytecodeMutations.replaceIntegerConstant;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import de.unisb.cs.st.javalanche.mutation.bytecodeMutations.AbstractMutationAdapter;
import de.unisb.cs.st.javalanche.mutation.bytecodeMutations.BytecodeTasks;
import de.unisb.cs.st.javalanche.mutation.bytecodeMutations.MutationCode;
import de.unisb.cs.st.javalanche.mutation.results.Mutation;
import de.unisb.cs.st.javalanche.mutation.results.Mutation.MutationType;
import de.unisb.cs.st.javalanche.mutation.results.persistence.MutationManager;
import de.unisb.cs.st.javalanche.mutation.results.persistence.QueryManager;

public class RicMethodAdapter extends AbstractMutationAdapter {

    private final MutationManager mutationManager;

    private static class ConstantMutations {

        private Mutation plus1;

        private Mutation minus1;

        private Mutation zero;

        private Mutation plus1FromDB;

        private Mutation minus1FromDB;

        private Mutation zeroFromDB;

        private boolean dbMutationsInitialized;

        public ConstantMutations(Mutation plus1, Mutation minus1, Mutation zero) {
            super();
            this.plus1 = plus1;
            this.minus1 = minus1;
            this.zero = zero;
        }

        private void initDbMutations() {
            if (!dbMutationsInitialized) {
                plus1FromDB = QueryManager.getMutationOrNull(plus1);
                minus1FromDB = QueryManager.getMutationOrNull(minus1);
                zeroFromDB = QueryManager.getMutationOrNull(zero);
                dbMutationsInitialized = true;
            }
        }

        /**
         * @return the minus1FromDB
         */
        public Mutation getMinus1FromDB() {
            if (!dbMutationsInitialized) {
                initDbMutations();
            }
            return minus1FromDB;
        }

        /**
         * @return the plus1FromDB
         */
        public Mutation getPlus1FromDB() {
            if (!dbMutationsInitialized) {
                initDbMutations();
            }
            return plus1FromDB;
        }

        /**
         * @return the zeroFromDB
         */
        public Mutation getZeroFromDB() {
            if (!dbMutationsInitialized) {
                initDbMutations();
            }
            return zeroFromDB;
        }

        /**
         * @return the minus1
         */
        public Mutation getMinus1() {
            return minus1;
        }

        /**
         * @return the plus1
         */
        public Mutation getPlus1() {
            return plus1;
        }

        /**
         * @return the zero
         */
        public Mutation getZero() {
            return zero;
        }

    }

    static Logger logger = Logger.getLogger(RicMethodAdapter.class);

    public RicMethodAdapter(MethodVisitor mv, String className, String methodName,
            Map<Integer, Integer> possibilities, MutationManager mutationManager, String desc) {
        super(mv, className.replace('/', '.'), methodName, possibilities, desc);
        this.mutationManager = mutationManager;
        logger.debug("MethodName:" + methodName);
    }

    @Override
    public void visitInsn(int opcode) {
        if (mutationCode) {
            super.visitInsn(opcode);
            return;
        }
        switch (opcode) {
        case Opcodes.ICONST_M1:
            intConstant(-1);
            break;
        case Opcodes.ICONST_0:
            intConstant(0);
            break;
        case Opcodes.ICONST_1:
            intConstant(1);
            break;
        case Opcodes.ICONST_2:
            intConstant(2);
            break;
        case Opcodes.ICONST_3:
            intConstant(3);
            break;
        case Opcodes.ICONST_4:
            intConstant(4);
            break;
        case Opcodes.ICONST_5:
            intConstant(5);
            break;
        case Opcodes.LCONST_0:
            longConstant(0);
            break;
        case Opcodes.LCONST_1:
            longConstant(1);
            break;
        case Opcodes.FCONST_0:
            floatConstant(0);
            break;
        case Opcodes.FCONST_1:
            floatConstant(1);
            break;
        case Opcodes.FCONST_2:
            floatConstant(2);
            break;
        case Opcodes.DCONST_0:
            doubleConstant(0);
            break;
        case Opcodes.DCONST_1:
            doubleConstant(1);
            break;

        default:
            super.visitInsn(opcode);
            break;
        }
    }

    @Override
    public void visitLdcInsn(Object cst) {
        if (mutationCode) {
            super.visitLdcInsn(cst);
            return;
        }
        if (cst instanceof Integer) {
            Integer integerConstant = (Integer) cst;
            intConstant(integerConstant);
        } else if (cst instanceof Float) {
            Float floatConstant = (Float) cst;
            floatConstant(floatConstant);
        } else if (cst instanceof Long) {
            Long longConstant = (Long) cst;
            longConstant(longConstant);
        } else if (cst instanceof Double) {
            Double doubleConstant = (Double) cst;
            doubleConstant(doubleConstant);
        } else {
            mv.visitLdcInsn(cst);
        }
    }

    private void longConstant(final long longConstant) {
        List<Mutation> mutations = QueryManager.getMutations(className, methodName + desc, getLineNumber(),
                getPossibilityForLine(), MutationType.REPLACE_CONSTANT);
        addPossibilityForLine();
        boolean insert = false;
        MutationCode unmutated = new MutationCode(null) {

            @Override
            public void insertCodeBlock(MethodVisitor mv) {
                mv.visitLdcInsn(new Long(longConstant));
            }

        };

        List<MutationCode> mutationCode = new ArrayList<MutationCode>();
        for (final Mutation m : mutations) {
            if (mutationManager.shouldApplyMutation(m)) {
                insert = true;
                mutationCode.add(new MutationCode(m) {
                    @Override
                    public void insertCodeBlock(MethodVisitor mv) {
                        mv.visitLdcInsn(new Long(m.getOperatorAddInfo()));
                    }
                });
            }
        }
        if (insert) {
            logger.debug("Applying mutations for line: " + getLineNumber());
            BytecodeTasks.insertIfElse(mv, unmutated, mutationCode.toArray(new MutationCode[0]));
        } else {
            logger.debug("Applying no mutation for line: " + getLineNumber());
            super.visitLdcInsn(new Long(longConstant));
        }
    }

    private void floatConstant(final float floatConstant) {
        logger.debug("float constant for line: " + getLineNumber());
        List<Mutation> mutations = QueryManager.getMutations(className, methodName + desc, getLineNumber(),
                getPossibilityForLine(), MutationType.REPLACE_CONSTANT);
        addPossibilityForLine();
        boolean insert = false;
        MutationCode unmutated = new MutationCode(null) {

            @Override
            public void insertCodeBlock(MethodVisitor mv) {
                mv.visitLdcInsn(new Float(floatConstant));
            }

        };
        List<MutationCode> mutationCode = new ArrayList<MutationCode>();
        for (final Mutation m : mutations) {
            if (mutationManager.shouldApplyMutation(m)) {
                insert = true;
                mutationCode.add(new MutationCode(m) {
                    @Override
                    public void insertCodeBlock(MethodVisitor mv) {
                        mv.visitLdcInsn(new Float(m.getOperatorAddInfo()));
                    }
                });
            }
        }

        if (insert) {
            logger.debug("Applying mutations for line: " + getLineNumber());
            BytecodeTasks.insertIfElse(mv, unmutated, mutationCode.toArray(new MutationCode[0]));
        } else {
            logger.debug("Applying no mutation for line: " + getLineNumber());
            super.visitLdcInsn(new Float(floatConstant));
        }
    }

    private void doubleConstant(final double doubleConstant) {
        logger.debug("double constant for line: " + getLineNumber());
        List<Mutation> mutations = QueryManager.getMutations(className, methodName + desc, getLineNumber(),
                getPossibilityForLine(), MutationType.REPLACE_CONSTANT);
        addPossibilityForLine();
        boolean insert = false;
        MutationCode unmutated = new MutationCode(null) {

            @Override
            public void insertCodeBlock(MethodVisitor mv) {
                mv.visitLdcInsn(new Double(doubleConstant));
            }

        };
        List<MutationCode> mutationCode = new ArrayList<MutationCode>();
        for (final Mutation m : mutations) {
            if (mutationManager.shouldApplyMutation(m)) {
                insert = true;
                mutationCode.add(new MutationCode(m) {
                    @Override
                    public void insertCodeBlock(MethodVisitor mv) {
                        mv.visitLdcInsn(new Double(m.getOperatorAddInfo()));
                    }
                });
            }
        }

        if (insert) {
            logger.debug("Applying mutations for line: " + getLineNumber());
            BytecodeTasks.insertIfElse(mv, unmutated, mutationCode.toArray(new MutationCode[0]));
        } else {
            logger.debug("Applying no mutation for line: " + getLineNumber());
            super.visitLdcInsn(new Double(doubleConstant));
        }
    }

    private void intConstant(final int intConstant) {
        List<Mutation> mutations = QueryManager.getMutations(className, methodName + desc, getLineNumber(),
                getPossibilityForLine(), MutationType.REPLACE_CONSTANT);
        addPossibilityForLine();
        boolean insert = false;
        MutationCode unmutated = new MutationCode(null) {

            @Override
            public void insertCodeBlock(MethodVisitor mv) {
                mv.visitLdcInsn(new Integer(intConstant));
            }

        };

        List<MutationCode> mutationCode = new ArrayList<MutationCode>();
        for (final Mutation m : mutations) {

            if (mutationManager.shouldApplyMutation(m)) {
                insert = true;
                mutationCode.add(new MutationCode(m) {

                    @Override
                    public void insertCodeBlock(MethodVisitor mv) {
                        mv.visitLdcInsn(Integer.valueOf(m.getOperatorAddInfo()));
                    }
                });
            }
        }

        if (insert) {
            logger.debug("Applying mutations for line: " + getLineNumber());
            BytecodeTasks.insertIfElse(mv, unmutated, mutationCode.toArray(new MutationCode[0]));
        } else {
            logger.debug("Applying no mutation for line: " + getLineNumber());
            super.visitLdcInsn(new Integer(intConstant));
        }
    }

    @Override
    public void visitIntInsn(int opcode, int operand) {
        if (mutationCode) {
            super.visitIntInsn(opcode, operand);
            return;
        }
        if (opcode == Opcodes.BIPUSH || opcode == Opcodes.SIPUSH) {
            intConstant(operand);
        } else {
            super.visitIntInsn(opcode, operand);
        }
    }

    // private static ConstantMutations getConstantMutations(String className,
    // String methodName, int lineNumber, int mutationForLine,
    // boolean isClassInit, String[] values) {
    // Mutation mutationPlus = new Mutation(className, methodName, lineNumber,
    // mutationForLine, MutationType.REPLACE_CONSTANT);
    // mutationPlus.setOperatorAddInfo(values[0]);
    // Mutation mutationMinus = new Mutation(className, methodName,
    // lineNumber, mutationForLine, MutationType.REPLACE_CONSTANT);
    // mutationMinus.setOperatorAddInfo(values[1]);
    // Mutation mutationZero = new Mutation(className, methodName, lineNumber,
    // mutationForLine, MutationType.REPLACE_CONSTANT);
    // mutationZero.setOperatorAddInfo(values[2]);
    // return new ConstantMutations(mutationPlus, mutationMinus, mutationZero);
    //
    // }
}