package fr.inria.diversify.transformation.query; import fr.inria.diversify.diversification.InputProgram; import fr.inria.diversify.transformation.Transformation; import fr.inria.diversify.util.Log; import org.reflections.Reflections; import spoon.reflect.code.*; import spoon.reflect.declaration.CtElement; import spoon.reflect.declaration.CtMethod; import spoon.reflect.declaration.CtVariable; import spoon.support.reflect.code.CtAssignmentImpl; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.*; import java.util.stream.Collectors; /** * Created by aelie on 03/02/15. */ public class SubClassReplaceQuery extends TransformationQuery { protected Map<CtNewClass,Class> instantiations; //protected List<Class> allClasses; Reflections reflections; public SubClassReplaceQuery(InputProgram inputProgram) { super(inputProgram); reflections = new Reflections(".*"); initFindInstantiationStatements(); } protected void initFindInstantiationStatements() { List<CtNewClass> newClasses = getInputProgram() .getAllElement(CtNewClass.class).stream() .map(operator -> (CtNewClass) operator) .collect(Collectors.toList()); instantiations = new HashMap<>(); for(CtNewClass newCl : newClasses) { try { Class staticType = null; CtElement parent = newCl.getParent(); if (parent instanceof CtVariable) { CtVariable var = (CtVariable) parent; staticType = var.getType().getActualClass(); } if (parent instanceof CtThrow) { } if (parent instanceof CtInvocation) { CtInvocation invocation = (CtInvocation) parent; if(!invocation.getTarget().equals(newCl)) { int position = invocation.getArguments().indexOf(newCl); Method mth = invocation.getExecutable().getActualMethod(); staticType = mth.getParameterTypes()[position]; } } if (parent instanceof CtNewClass) { CtNewClass newClass = (CtNewClass) parent; int position = newClass.getArguments().indexOf(newCl); Constructor constructor = newClass.getExecutable().getActualConstructor(); staticType = constructor.getParameterTypes()[position]; } if (parent instanceof CtReturn) { CtMethod mth = parent.getParent(CtMethod.class); staticType = mth.getType().getActualClass(); } if (parent instanceof CtAssignment) { CtAssignment assignment = (CtAssignment) parent; staticType = assignment.getAssigned().getType().getActualClass(); } if (parent instanceof CtConditional) { } if(staticType != null) { instantiations.put(newCl, staticType); } } catch (Exception e) { Log.debug(""); } } } protected boolean isDeclaration(CtCodeElement codeElement) { if (codeElement instanceof CtVariable) { return true; } return false; } protected boolean isInstantiation(CtCodeElement codeElement) { if (codeElement instanceof CtAssignmentImpl) { if (((CtAssignmentImpl) codeElement).getAssignment() instanceof CtNewClass) { return true; } } return false; } @Override public Transformation query() throws QueryException { Transformation result = null; // Random random = new Random(); //// CtAssignment transplant = null; // CtNewClass transplantationPoint = instantiations.get(random.nextInt(instantiations.size())); // try { // Set<Class> subClasses = getAllSubClass(getTypeOf(transplantationPoint)); // } catch (Exception e) { // e.printStackTrace(); // } return result; } protected Class getTypeOf(CtNewClass newClass) { return newClass.getType().getActualClass(); } // protected List<Class> getAllClasses() throws NoSuchFieldException, IllegalAccessException { // // if(allClasses == null) { // allClasses = getAllClasses(Thread.currentThread().getContextClassLoader()); // } // return allClasses; // } // // protected List<Class> getAllClasses(ClassLoader classLoader) throws NoSuchFieldException, IllegalAccessException { // Field f = ClassLoader.class.getDeclaredField("classes"); // f.setAccessible(true); // List<Class> classes = new LinkedList<>(); // // if(classLoader.getParent() != null) { // classes.addAll(getAllClasses(classLoader.getParent())); // } // classes.addAll((Vector<Class>) f.get(classLoader)); // return classes; // } // // protected Set<Class> getAllSubClass(Class superClass) throws NoSuchFieldException, IllegalAccessException { // // for(Class cl : getAllClasses()) { // try { // isSubClass(cl, superClass); // } catch ( Exception e) { // e.printStackTrace(); // Log.debug(""); // } // } // // return getAllClasses().stream() // .filter(cl -> isSubClass(cl, superClass)) // .collect(Collectors.toSet()); // } // // protected boolean isSubClass(Class subClass, Class superClass) { // if(subClass.equals(Object.class)) { // return false; // } // for(Class inter : subClass.getInterfaces()) { // if(inter.equals(superClass)) { // return true; // } // } // if(subClass.isInterface()) { // return false; // } else { // if(subClass.getSuperclass().equals(superClass)) { // return true; // } // return isSubClass(subClass.getSuperclass(), superClass); // } // } }