package fr.inria.diversify.processor.test; import fr.inria.diversify.util.Log; import spoon.processing.AbstractProcessor; import spoon.reflect.code.CtCodeSnippetExpression; import spoon.reflect.code.CtFieldAccess; import spoon.reflect.declaration.CtClass; import spoon.reflect.declaration.CtMethod; import spoon.reflect.declaration.CtType; import spoon.reflect.visitor.Query; import spoon.reflect.visitor.filter.TypeFilter; import java.util.*; import java.util.stream.Collectors; /** * Created by Simon on 17/12/14. */ public class GuavaProcessor extends AbstractProcessor<CtClass> { String testDirectory; public static Set<CtClass> ampclasses = new HashSet<>(); public GuavaProcessor(String testDirectory) { this.testDirectory = testDirectory; } public boolean isToBeProcessed(CtClass candidate) { return candidate.getPosition().getFile().getAbsolutePath().contains(testDirectory); } @Override public void process(CtClass element) { Map<CtMethod, List<CtMethod>> map = new HashMap<>(); for(Object o : element.getMethods()) { CtMethod mth = (CtMethod) o; List<CtMethod> amp = findAllAmp(mth); if(!amp.isEmpty()) { map.put(mth, amp); } } int count = 0; if(!map.isEmpty()) { Log.debug("GuavaProcessor: {}", element.getSimpleName()); } while (!map.isEmpty() && count < 151) { CtClass ampClass = this.getFactory().Core().clone(element); ampClass.setSimpleName("Test_"+count+"_"+element.getSimpleName()); count++; element.getPackage().addType(ampClass); ampClass.setParent(element.getPackage()); ampclasses.add(ampClass); for(Object o : Query.getElements(ampClass, new TypeFilter(CtFieldAccess.class))) { CtFieldAccess access = (CtFieldAccess) o; if(access.getVariable().getType().getSimpleName().equals(element.getSimpleName())) { CtCodeSnippetExpression newAccess = this.getFactory().Core().createCodeSnippetExpression(); newAccess.setValue(ampClass.getQualifiedName() + "." + access.getVariable().getSimpleName()); access.replace(newAccess); } } for(CtMethod originalMethod : map.keySet()) { try { if (!map.get(originalMethod).isEmpty()) { CtMethod ampMethod = this.getFactory().Core().clone(map.get(originalMethod).remove(0)); CtMethod toRemove = ampClass.getMethod(originalMethod.getSimpleName()); ampMethod.setSimpleName(originalMethod.getSimpleName()); ampClass.addMethod(ampMethod); for (CtMethod mth : TestProcessor.mutatedMethod) { CtMethod rm = ampClass.getMethod(mth.getSimpleName()); if(rm != null) { ampClass.removeMethod(rm); } } if(toRemove != null) { ampClass.removeMethod(toRemove); } ampClass.addMethod(ampMethod); } } catch (Exception e) { Log.debug(""); } } List<CtMethod> toRemove = map.keySet().stream() .filter(mth -> map.get(mth).isEmpty()) .collect(Collectors.toList()); toRemove.stream() .forEach(mth -> map.remove(mth)); } } protected List<CtMethod> findAllAmp(CtMethod method) { if(TestProcessor.mutatedMethod.contains(method)) { return new ArrayList<>(); } CtType<?> type = method.getDeclaringType(); String methodName = method.getSimpleName(); try { return TestProcessor.mutatedMethod.stream() .filter(mth -> mth.getDeclaringType().equals(type)) .filter(mth -> mth.getSimpleName().startsWith(methodName)) .filter(mth -> mth.getParameters().equals(method.getParameters())) .collect(Collectors.toList()); } catch (Exception e) { return new ArrayList<>(); } } }