-
Notifications
You must be signed in to change notification settings - Fork 253
/
Class.java
125 lines (113 loc) · 4.03 KB
/
Class.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package fj;
import fj.data.List;
import static fj.data.List.unfold;
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.
*/
public final class Class<T> {
private final java.lang.Class<T> c;
private Class(final java.lang.Class<T> c) {
this.c = c;
}
/**
* Returns the inheritance hierarchy of this class.
*
* @return The inheritance hierarchy of this class.
*/
public List<Class<? super T>> inheritance() {
return unfold(
(java.lang.Class<? super T> c2) -> {
if (c2 == null)
return none();
else {
final P2<java.lang.Class<? super T>, java.lang.Class<? super T>> p =
new P2<java.lang.Class<? super T>, java.lang.Class<? super T>>() {
public java.lang.Class<? super T> _1() {
return c2;
}
@SuppressWarnings("unchecked")
public java.lang.Class<? super T> _2() {
return c2.getSuperclass();
}
};
return some(p);
}
}, c).map(Class::clas);
}
/**
* 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<Type> 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<Type> 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<Tree<Type>> interfaceParameters() {
List<Tree<Type>> 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<Type> typeParameterTree(final Type t) {
List<Tree<Type>> typeArgs = List.nil();
final Tree<Type> 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<T> 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 <T> Class<T> clas(final java.lang.Class<T> c) {
return new Class<>(c);
}
}