package spoon.test.method_overriding; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.BiFunction; import org.junit.Test; import spoon.reflect.declaration.CtMethod; import spoon.reflect.factory.Factory; import spoon.reflect.visitor.filter.TypeFilter; import spoon.testing.utils.ModelUtils; import static org.junit.Assert.*; public class MethodOverriddingTest { @Test public void testMethodOverride() { checkMethodOverride((m1, m2)->m1.isOverriding(m2)); } @Test public void testMethodOverrideByReference() { checkMethodOverride((m1, m2)->m1.getReference().isOverriding(m2.getReference())); } private void checkMethodOverride(BiFunction<CtMethod<?>, CtMethod<?>, Boolean> isOverriding) { Factory factory = ModelUtils.build(new File("src/test/java/spoon/test/method_overriding/testclasses").listFiles()); Map<String, List<CtMethod>> methodsByName = new HashMap<>(); factory.getModel().getRootPackage().filterChildren(new TypeFilter<>(CtMethod.class)).forEach((CtMethod m)->{ List<CtMethod> methods = methodsByName.get(m.getSimpleName()); if(methods==null) { methods = new ArrayList<>(); methodsByName.put(m.getSimpleName(), methods); } methods.add(m); }); assertTrue(methodsByName.size()>0); for (Map.Entry<String, List<CtMethod>> e : methodsByName.entrySet()) { combine(e.getValue(), 0, isOverriding); } } private void combine(List<CtMethod> value, int start, BiFunction<CtMethod<?>, CtMethod<?>, Boolean> isOverriding) { CtMethod m1 = value.get(start); if(start+1<value.size()) { for (CtMethod m2 : value.subList(start+1, value.size())) { if(m1.getDeclaringType().isSubtypeOf(m2.getDeclaringType().getReference())) { checkOverride(m1, m2, isOverriding); } else if(m2.getDeclaringType().isSubtypeOf(m1.getDeclaringType().getReference())) { checkOverride(m2, m1, isOverriding); } else { checkNotOverride(m1, m2, isOverriding); } } combine(value, start+1, isOverriding); } } private void checkOverride(CtMethod m1, CtMethod m2, BiFunction<CtMethod<?>, CtMethod<?>, Boolean> isOverriding) { assertTrue(descr(m1)+" overriding "+descr(m2), isOverriding.apply(m1, m2)); assertFalse(descr(m2)+" NOT overriding "+descr(m1), isOverriding.apply(m2, m1)); } private void checkNotOverride(CtMethod m1, CtMethod m2, BiFunction<CtMethod<?>, CtMethod<?>, Boolean> isOverriding) { assertFalse(descr(m1)+" NOT overriding "+descr(m2), isOverriding.apply(m1, m2)); assertFalse(descr(m2)+" NOT overriding "+descr(m1), isOverriding.apply(m2, m1)); } private String descr(CtMethod m) { return m.getDeclaringType().getSimpleName()+"#"+m.getSimpleName(); } }