package fj; import fj.data.List; import static fj.data.List.unfold; import fj.data.Option; import static fj.data.Option.none; import static fj.data.Option.some; import fj.data.Tree; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; /** * A wrapper for a {@link java.lang.Class} that provides additional methods. * * @version %build.number% */ public final class Class { private final java.lang.Class c; private Class(final java.lang.Class c) { this.c = c; } /** * Returns the inheritance hierarchy of this class. * * @return The inheritance hierarchy of this class. */ public List> inheritance() { return unfold( new F, Option, java.lang.Class>>>() { public Option, java.lang.Class>> f( final java.lang.Class c) { if (c == null) return none(); else { final P2, java.lang.Class> p = new P2, java.lang.Class>() { public java.lang.Class _1() { return c; } @SuppressWarnings({"unchecked"}) public java.lang.Class _2() { return c.getSuperclass(); } }; return some(p); } } }, c).map(new F, Class>() { public Class f(final java.lang.Class c) { return clas(c); } }); } /** * Provides this class's type parameter information as a Tree of the type expression. * Only descends into Parameterized classes. Non-abstract classes, or classes that don't implement an interface, * are treated as raw types. Arrays, Type Variables, and Wildcards are treated as opaque Types. * * @return The rose tree representing the type expression for this class. */ public Tree classParameters() { return typeParameterTree(c); } /** * Provides this class's superclass type parameter information as a Tree of the type expression. * Only descends into Parameterized classes. Non-abstract classes, or classes that don't implement an interface, * are treated as raw types. Arrays, Type Variables, and Wildcards are treated as opaque Types. * * @return The Tree representing the type expression for this class's superclass. */ public Tree superclassParameters() { return typeParameterTree(c.getGenericSuperclass()); } /** * Provides this class's interface type parameter information as a list of trees. * * @return A list of trees representing the type expressions for this class's interfaces. */ public List> interfaceParameters() { List> ts = List.nil(); for (final Type t : c.getInterfaces()) { ts = ts.snoc(typeParameterTree(t)); } return ts; } /** * Provides type parameter information as a Tree of the type expression. * Only descends into Parameterized classes. Non-abstract classes, or classes that don't implement an interface, * are treated as raw types. Arrays, Type Variables, and Wildcards are treated as opaque Types. * * @param t The type (class) for which to get the generic type information. * @return Type parameter information as a rose tree of the type expression. */ public static Tree typeParameterTree(final Type t) { List> typeArgs = List.nil(); final Tree types; if (t instanceof ParameterizedType) { final ParameterizedType pt = (ParameterizedType) t; for (final Type arg : pt.getActualTypeArguments()) { typeArgs = typeArgs.snoc(typeParameterTree(arg)); } types = Tree.node(pt.getRawType(), typeArgs); } else { types = Tree.node(t, List.>nil()); } return types; } /** * Returns the underlying class. * * @return The underlying class. */ public java.lang.Class clas() { return c; } /** * Constructs a class from the given argument. * * @param c The argument to construct this class with. * @return A class from the given argument. */ public static Class clas(final java.lang.Class c) { return new Class(c); } }