package fr.inria.diversify.transformation.other; import fr.inria.diversify.codeFragment.VariableVisitor; import fr.inria.diversify.transformation.SpoonTransformation; import fr.inria.diversify.util.Log; import org.json.JSONException; import org.json.JSONObject; import spoon.reflect.code.*; import spoon.reflect.cu.CompilationUnit; import spoon.reflect.cu.SourcePosition; import spoon.reflect.declaration.CtConstructor; import spoon.reflect.declaration.CtElement; import java.util.*; import java.util.stream.Collectors; /** * Created by Simon on 02/04/14. */ @Deprecated public class ShuffleStmtTransformation extends SpoonTransformation<CtBlock, CtElement> { List<CtStatement> newOrderStmt; public ShuffleStmtTransformation() { name = "shuffleStmt"; type = "foo"; } @Override public void addSourceCode() throws Exception { logInfo(); if(newOrderStmt == null) buildNewOrder(); SourcePosition sp = transformationPoint.getStatement(0).getPosition(); CompilationUnit compileUnit = sp.getCompilationUnit(); // if(transformationPoint.getParent() instanceof CtConstructor) // compileUnit.addSourceCodeFragment(new SourceCodeFragment(compileUnit.nextLineIndex(sp.getSourceStart()), "/**", 0)); // else // compileUnit.addSourceCodeFragment(new SourceCodeFragment(compileUnit.beginOfLineIndex(sp.getSourceStart()), "/**", 0)); String stmtsString = newOrderStmt.stream() .map(stmt -> stmt.toString()) .collect(Collectors.joining(";\n")).toString(); Log.debug("new order\n: {}",stmtsString); sp = transformationPoint.getLastStatement().getPosition(); compileUnit = sp.getCompilationUnit(); // compileUnit.addSourceCodeFragment(new SourceCodeFragment( // compileUnit.nextLineIndex(sp.getSourceEnd()), "**/\n"+stmtsString+";\n", 0)); } public void buildNewOrder() { newOrderStmt = new ArrayList<>(); List<CtStatement> stmts = new ArrayList<CtStatement>(transformationPoint.getStatements()); Collections.shuffle(stmts); Set<String> localVar = getLocalVariableName(transformationPoint.getStatements()); CtStatement ret = stmts.stream() .filter(stmt -> stmt instanceof CtReturn) .findAny().orElse(null); stmts.remove(ret); CtStatement superStmt = stmts.stream() .filter(stmt -> stmt instanceof CtSuperAccess) .findAny().orElse(null); stmts.remove(superStmt); if(superStmt != null) newOrderStmt.add(superStmt); Random r = new Random(); while (stmts.size() > 0) { int randomIndex = r.nextInt(stmts.size()); CtStatement stmt = stmts.get(randomIndex); int index = getStmtIndex(stmt, localVar); if(index != -1) { newOrderStmt.add(index, stmt); stmts.remove(randomIndex); } } if(ret != null) newOrderStmt.add(ret); } protected int getStmtIndex(CtStatement stmt , Set<String> localVar) { VariableVisitor query = new VariableVisitor(false); stmt.accept(query); Set<String> localVarUsed = query.getVariableReferences().stream() .map(var -> var.getDeclaration().getSimpleName()) .filter(a -> localVar.contains(a)) .collect(Collectors.toSet()); List<CtStatement> stmts = new ArrayList<>(); if(localVarUsed.isEmpty()) return 0; for(int i = 0; i <= newOrderStmt.size(); i++) { Set<String> currentLocalVar = getLocalVariableName(stmts); if (currentLocalVar.containsAll(localVarUsed)) return i; if(i < newOrderStmt.size()) stmts.add(newOrderStmt.get(i)); } return -1; } protected Set<String> getLocalVariableName(List<CtStatement> stmts) { return stmts.stream() .filter(stmt -> stmt instanceof CtLocalVariable) .map(var -> ((CtLocalVariable)var).getSimpleName()) .collect(Collectors.toSet()); } public int[] newOrderIndex() { int size = newOrderStmt.size(); int[] newOrderIndex = new int[size]; for(int i = 0; i < size; i++) { int index = 0; for(Object stmt : transformationPoint.getStatements()) { if(newOrderStmt.get(i).toString().equals(stmt.toString())){ newOrderIndex[i] = index; break; } index++; } } return newOrderIndex; } public JSONObject toJSONObject() throws JSONException { JSONObject object = super.toJSONObject(); object.put("newStmtOrder", Arrays.toString(newOrderIndex())); return object; } public void buildNewOrder(int[] array) { newOrderStmt = new ArrayList<>(); for(int i : array) { newOrderStmt.add(transformationPoint.getStatement(i)); } } }