package fr.inria.diversify.processor.main; import fr.inria.diversify.diversification.InputProgram; import fr.inria.diversify.transformation.Transformation; import fr.inria.diversify.transformation.ast.ASTTransformation; import spoon.reflect.code.*; import spoon.reflect.visitor.Query; import spoon.reflect.visitor.filter.TypeFilter; /** * User: Simon * Date: 10/07/15 * Time: 11:01 */ public class TransformationUsedProcessor extends AbstractLoggingInstrumenter<CtStatement> { protected ASTTransformation transformation; public TransformationUsedProcessor(InputProgram inputProgram, Transformation transformation) { super(inputProgram); this.transformation = (ASTTransformation) transformation; } @Override public boolean isToBeProcessed(CtStatement candidate) { return !transformation.getName().equals("delete") && transformation.getCopyTransplant().toString().equals(candidate.toString()); } public void process(CtStatement stmtTrans) { String transformationName = transformation.getName(); if(transformationName.equals("add")) { CtIf ctIf = (CtIf) stmtTrans; pprocess(((CtBlock) ctIf.getThenStatement()).getLastStatement()); } else { pprocess(stmtTrans); } } protected void pprocess(CtStatement stmtTrans) { int count = 0; for(Object object : Query.getElements(stmtTrans, new TypeFilter(CtIf.class))) { CtIf ctIf = (CtIf) object; // int branchId = idBranch(methodId); CtStatement stmt = ctIf.getThenStatement(); if (!(stmt instanceof CtBlock)) { CtBlock block = getFactory().Core().createBlock(); block.setParent(stmt.getParent()); block.addStatement(stmt); ctIf.setThenStatement(block); } addBlockSnippet(ctIf.getThenStatement(), "t" + count); count++; if (ctIf.getElseStatement() != null) { stmt = ctIf.getElseStatement(); if (!(stmt instanceof CtBlock)) { CtBlock block = getFactory().Core().createBlock(); block.setParent(stmt.getParent()); block.addStatement(stmt); ctIf.setElseStatement(block); } addBlockSnippet(ctIf.getElseStatement(), "e" + count); count++; } } for(Object object : Query.getElements(stmtTrans, new TypeFilter(CtLoop.class))) { CtLoop ctLoop = (CtLoop) object; CtStatement stmt = ctLoop.getBody(); if (!(stmt instanceof CtBlock)) { CtBlock block = getFactory().Core().createBlock(); if (stmt != null) { block.setParent(stmt.getParent()); block.addStatement(stmt); } else { block.setParent(ctLoop); } ctLoop.setBody(block); } addBlockSnippet(ctLoop.getBody(), "l" + count); count++; } for(Object object : Query.getElements(stmtTrans, new TypeFilter(CtCatch.class))) { CtCatch ctCatch = (CtCatch) object; CtStatement stmt = ctCatch.getBody(); if (!(stmt instanceof CtBlock)) { CtBlock block = getFactory().Core().createBlock(); block.setParent(stmt.getParent()); block.addStatement(stmt); ctCatch.setBody(block); } addBlockSnippet(ctCatch.getBody(), "c" + count); count++; } if(count == 0) { stmtTrans.insertBefore(getFactory().Code().createCodeSnippetStatement(getLogger() + ".logTransformation(Thread.currentThread(),\"b\");")); } } protected void addBlockSnippet(CtStatement ctBlock, String branchId) { CtCodeSnippetStatement snippet = getFactory().Code().createCodeSnippetStatement(getLogger() + ".logTransformation(Thread.currentThread(),\""+branchId+"\")"); ((CtBlock) ctBlock).insertBegin(snippet); } // protected int idBranch(int methodId) { // if(!blockIds.containsKey(methodId)) { // blockIds.put(methodId, 0); // } // blockIds.put(methodId, blockIds.get(methodId) + 1); // return blockIds.get(methodId); // } }