package javaf.syb; import javaf.prelude.*; import java.lang.reflect.*; import java.util.List; public class Transformation { /** * Apply an action if possible. */ public static <X> Action<Object> orIdentity(final Action<X> a) { return new Action<Object>() { @SuppressWarnings("unchecked") public void apply(Object x) { try { a.apply((X)x); } catch (ClassCastException _) { // Do nothing } } }; } /** * Apply a transformation to all immediate sub-objects. */ public static Action<Object> all(final Action<Object> a) { return new Action<Object>() { @SuppressWarnings("rawtypes") public void apply(Object x) { // Special case for lists if (x instanceof List) for (Object o : (List)x) a.apply(o); else { // Regular case based on getters for (Method m : x.getClass().getDeclaredMethods()) { if (m.getName().startsWith("get") && m.getParameterTypes().length == 0) { try { a.apply(m.invoke(x, new Object[]{})); } catch (IllegalAccessException e) { // assert "DEAD CODE" } catch (IllegalArgumentException e) { // assert "DEAD CODE" } catch (InvocationTargetException e) { // assert "DEAD CODE" } } } } } }; } /** * Apply a function to each and every sub-object in bottom-up manner. */ public static Action<Object> everywhere(final Action<Object> a) { return new Action<Object>() { public void apply(Object x) { all(everywhere(a)).apply(x); a.apply(x); } }; } }