package fr.inria.diversify.logger.exception;
import com.google.common.collect.Sets;
import fr.inria.diversify.buildSystem.AbstractBuilder;
import fr.inria.diversify.diversification.InputProgram;
import fr.inria.diversify.logger.Comparator;
import fr.inria.diversify.logger.Diff;
import fr.inria.diversify.transformation.SingleTransformation;
import spoon.reflect.cu.SourcePosition;
import java.util.*;
/**
* User: Simon
* Date: 26/06/15
* Time: 16:12
*/
public class ExceptionComparator implements Comparator {
@Override
public void init(InputProgram originalInputProgram, AbstractBuilder originalBuilder) throws Exception {
}
@Override
public Diff compare(SingleTransformation transformation, String originalLogDir, String sosieLogDir) throws Exception {
ExceptionReader originalBuilder = new ExceptionReader(originalLogDir);
Collection<ExceptionPosition> originalExceptions = originalBuilder.load();
if(originalExceptions.size() == 0) {
return getEmptyDiff();
}
ExceptionReader sosieBuilder = new ExceptionReader(sosieLogDir);
Collection<ExceptionPosition> sosieExceptions = sosieBuilder.load();
ExceptionDiff diff = new ExceptionDiff();
for(ExceptionPosition oException : originalExceptions) {
ExceptionPosition sException = sosieExceptions.stream()
.filter(g -> g.getName().equals(oException.getName()))
.findFirst()
.get();
ExceptionDiff gDiff = oException.diff(sException);
if(gDiff.size() != 0) {
diff.merge(gDiff);
}
}
if(diff.size() != 0) {
//by test, methods only presnet in original traces xor sosie traces
Map<String, Set<String>> filter = diff(originalBuilder.methodCallByTest, sosieBuilder.methodCallByTest);
//keeping only diff found in methods present in original traces and sosie traces
for(String key : filter.keySet()) {
if(diff.throwsByTest.containsKey(key)) {
diff.throwsByTest.get(key).removeAll(filter.get(key));
}
if(diff.catchByTest.containsKey(key)) {
diff.catchByTest.get(key).removeAll(filter.get(key));
}
}
}
return diff;
}
// {1,2,3} {2,3,4} -> {1,4}
protected Map<String,Set<String>> diff(Map<String, Set<String>> map1, Map<String, Set<String>> map2) {
Map<String,Set<String>> map = new HashMap<>();
Set<String> keys = new HashSet<>();
keys.addAll(map1.keySet());
keys.addAll(map2.keySet());
for(String key : keys) {
if(map1.containsKey(key) && map2.containsKey(key)) {
Set<String> set1 = map1.get(key);
Set<String> set2 = map2.get(key);
Set<String> diff1 = new HashSet<>();
diff1.addAll(set1);
diff1.removeAll(set2);
Set<String> diff2 = new HashSet<>();
diff2.addAll(set2);
diff2.removeAll(set1);
if (!diff1.isEmpty() || !diff2.isEmpty()) {
map.put(key, diff1);
diff1.addAll(diff2);
}
}
}
return map;
}
@Override
public Collection<String> selectTest(SourcePosition position) {
return new LinkedList<>();
}
@Override
public Diff getEmptyDiff() {
return new ExceptionDiff();
}
}