package fr.inria.diversify.statistic; import fr.inria.diversify.codeFragment.CodeFragmentList; import fr.inria.diversify.codeFragment.CodeFragment; import fr.inria.diversify.codeFragment.Statement; import fr.inria.diversify.coverage.ICoverageReport; import fr.inria.diversify.transformation.*; import fr.inria.diversify.transformation.ast.ASTAdd; import fr.inria.diversify.transformation.ast.ASTDelete; import fr.inria.diversify.transformation.ast.ASTReplace; import fr.inria.diversify.util.Log; import spoon.reflect.code.CtStatement; import spoon.reflect.declaration.CtElement; import spoon.reflect.factory.Factory; import spoon.reflect.reference.CtVariableReference; import java.math.BigInteger; import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** * User: Simon * Date: 5/29/13 * Time: 2:14 PM */ public class ComputeAllPossibleTransformation { protected List<CodeFragment> codeFragments; protected boolean subType; public ComputeAllPossibleTransformation(CodeFragmentList list, ICoverageReport coverageReport) { Log.debug("nb of statement: {}:", list.size()); codeFragments = list.stream() .filter(fragment -> coverageReport.codeFragmentCoverage(fragment) != 0) .collect(Collectors.toList()); Log.debug("nb of statement: {}:", codeFragments.size()); } public long numberOfNotDiversification() throws InterruptedException { final List<Object> list = new LinkedList<Object>(); ExecutorService pool = Executors.newFixedThreadPool(50); for (CodeFragment cf1 : codeFragments) { final CodeFragment cfTmp = cf1; pool.submit(new Runnable() { @Override public void run() { if(findCandidate(cfTmp, false ,subType).isEmpty()) synchronized (list) {list.add(true);} } }); } pool.shutdown(); pool.awaitTermination(10, TimeUnit.DAYS); return list.size(); } static BigInteger max = new BigInteger("0"); public BigInteger numberOfNotDiversification(CodeFragment cf) { BigInteger nb = new BigInteger("0"); for (CodeFragment cf2 : findCandidate(cf, false, subType)) { BigInteger tmp = getNumberOfVarMapping(cf, cf2); nb = nb.add(tmp); if(max.compareTo(tmp) < 0) { max = tmp; Log.debug("{}\ntransplantationPoint: {}\n {}",tmp, cf.getInputContext().equalString() ,cf); Log.debug("replace/add:{}\n{}\n", cf2.getInputContext().equalString(), cf2); } } return nb; } public BigInteger numberOfDiversification() throws InterruptedException { final List<Object> list = new LinkedList<Object>(); ExecutorService pool = Executors.newFixedThreadPool(50); for (CodeFragment cf1 : codeFragments) { final CodeFragment cfTmp = cf1; pool.submit(new Runnable() { @Override public void run() { BigInteger nb = new BigInteger("0"); for (CodeFragment cf2 : findCandidate(cfTmp, false, subType)) { nb = nb.add(getNumberOfVarMapping(cfTmp,cf2)); } synchronized (list) {list.add(nb);} } }); } pool.shutdown(); pool.awaitTermination(10, TimeUnit.SECONDS); BigInteger result = new BigInteger("0"); for(Object number : list) result = result.add((BigInteger)number); return result; } public List<CodeFragment> findCandidate(CodeFragment cf, boolean varNameMatch, boolean subType) { List<CodeFragment> list = new ArrayList<CodeFragment>(); for (CodeFragment statement : codeFragments) if (cf.isReplaceableBy(statement, varNameMatch, subType) && !statement.equalString().equals(cf.equalString())) list.add(statement); return list; } protected BigInteger getNumberOfVarMapping(CodeFragment before, CodeFragment after) { BigInteger nb = new BigInteger("1"); for (CtVariableReference<?> variable : after.getInputContext().getVar()) { BigInteger tmp = new BigInteger(before.getInputContext().allCandidate(variable.getType(), subType).size()+""); nb = nb.multiply(tmp); } return nb; } public Set<SingleTransformation> getAllReplace() throws InterruptedException { final Set<SingleTransformation> allReplace = new HashSet<SingleTransformation>(); ExecutorService pool = Executors.newFixedThreadPool(50); for (CodeFragment cf1 : codeFragments) { final CodeFragment cfTmp = cf1; pool.submit(new Runnable() { @Override public void run() { for (CodeFragment cf2 : findCandidate(cfTmp, false, subType)) { for (Map<String, String> varMapping : getAllVarMapping(cfTmp, cf2)) { ASTReplace r = new ASTReplace(); CtStatement tmp = (CtStatement) copyElem(cf2.getCtCodeFragment()); r.setTransplantationPoint(cfTmp); r.setTransplant(new Statement(tmp)); r.setVarMapping(varMapping); synchronized (allReplace) { allReplace.add(r); } } } } }); } pool.shutdown(); pool.awaitTermination(10, TimeUnit.SECONDS); return allReplace; } public Set<SingleTransformation> getAllDelete() { Set<SingleTransformation> allReplace = new HashSet<SingleTransformation>(); for (CodeFragment cf1 : codeFragments) { ASTDelete r = new ASTDelete(); r.setTransplantationPoint(cf1); allReplace.add(r); } return allReplace; } public Set<SingleTransformation> getAllAdd() throws InterruptedException { final Set<SingleTransformation> allReplace = new HashSet<SingleTransformation>(); ExecutorService pool = Executors.newFixedThreadPool(50); for (CodeFragment cf1 : codeFragments) { final CodeFragment cfTmp = cf1; pool.submit(new Runnable() { @Override public void run() { for (CodeFragment cf2 : findCandidate(cfTmp, false, subType)) { for (Map<String,String> varMapping : getAllVarMapping(cfTmp,cf2)) { ASTAdd r = new ASTAdd(); CtStatement tmp = (CtStatement) copyElem(cf2.getCtCodeFragment()); r.setTransplantationPoint(cfTmp); r.setTransplant(new Statement(tmp)); r.setVarMapping(varMapping); synchronized (allReplace) { allReplace.add(r); } } } } }); } pool.shutdown(); pool.awaitTermination(10, TimeUnit.SECONDS); return allReplace; } public BigInteger getAllAdd2() throws InterruptedException { BigInteger result = new BigInteger("0"); BigInteger tmp; for(CodeFragment cf1 : codeFragments) { for(CodeFragment cf2 : findCandidate(cf1, false, subType)) { tmp = getNumberOfVarMapping(cf1, cf2); result = result.add(tmp); if (max.compareTo(tmp) < 0) { max = tmp; Log.debug("{} {} {}", tmp, cf1.getInputContext().size(), cf2.getInputContext().size()); d_nbAllVarMapping(cf1,cf2); Log.debug("{}\ntransplantationPoint: {}\n {}", tmp, cf1.getInputContext().equalString(), cf1); Log.debug("replace/add:{}\n{}\n", cf2.getInputContext().equalString(), cf2); Log.debug("____________________________"); } } } return result; } protected List<Map<String, String>> getAllVarMapping(CodeFragment before, CodeFragment after) { List<List<String>> vars = new ArrayList<List<String>>(); for (CtVariableReference<?> variable : after.getInputContext().getVar()) { List<String> mapping = new ArrayList<String>(); vars.add(mapping); for (Object candidate : before.getInputContext().allCandidate(variable.getType(), subType)) mapping.add(variable.toString()+"==="+candidate.toString() ); } return computeVarMapping(vars); } protected long nbAllVarMapping(CodeFragment before, CodeFragment after) { long nb = 1; for (CtVariableReference<?> variable : after.getInputContext().getVar()) { nb = nb * before.getInputContext().allCandidate(variable.getType(), subType).size(); } return nb; } protected long d_nbAllVarMapping(CodeFragment before, CodeFragment after) { long nb = 1; for (CtVariableReference<?> variable : after.getInputContext().getVar()) { Log.debug("{}: {} = {} * {}",variable, (nb * before.getInputContext().allCandidate(variable.getType(), subType).size()), nb , before.getInputContext().allCandidate(variable.getType(), subType).size()); nb = nb * before.getInputContext().allCandidate(variable.getType(), subType).size(); } return nb; } protected List<Map<String, String>> computeVarMapping(List<List<String>> vars) { List<Map<String, String>> map = new ArrayList<Map<String, String>>(); if(vars.isEmpty()) return map; if(vars.size() == 1) { for(String var : vars.get(0)) { String[] mapping = var.split("==="); if(mapping.length == 2) { Map<String,String> tmp = new HashMap<String, String>(); tmp.put(mapping[0],mapping[1]); map.add(tmp); } } } else { List<String> currentVar = vars.get(0); vars.remove(currentVar); List<Map<String, String>> currentMapping = computeVarMapping(vars); for(String var : currentVar) { String[] mapping = var.split("==="); for (Map<String,String> m : currentMapping) { try { HashMap<String, String> tmp = new HashMap<String, String>(m); if(mapping.length == 0) tmp.put("",""); else tmp.put(mapping[0],mapping[1]); map.add(tmp); } catch (Exception e) {} } } return map; } return map; } protected CtElement copyElem(CtElement elem) { Factory factory = elem.getFactory(); CtElement tmp = factory.Core().clone(elem); tmp.setParent(elem.getParent()); return tmp; } }