@@ -101,29 +101,41 @@ public interface TypeReifier {
101101 * </p>
102102 */
103103 default Type reify (final Object o ) {
104+ // Anys cannot be resolved
104105 if (o == null ) return new Any ();
105106
107+ // GenericTyped objects are easy - they know their type!
106108 if (o instanceof GenericTyped ) {
107109 // Object implements the GenericTyped interface; it explicitly declares
108110 // the generic type by which it wants to be known. This makes life easy!
109111 return ((GenericTyped ) o ).getType ();
110112 }
111113
114+ // Otherwise, we'll need to look at the class
112115 final Class <?> c = o .getClass ();
113- // Here we will store all of our object's resolved type variables.
114-
116+ // NB TypeToken.getTypes() returns all subtypes before all supertypes.
117+ // This means that if we write a TypeExtractor that works on a subtype
118+ // and a TypeExtractor that will work on the supertype, we will always use
119+ // the subtype TypeExtractor first because we'll encounter the subtype
120+ // first.
115121 for (final var token : TypeToken .of (c ).getTypes ()) {
116122 Optional <TypeExtractor > opt = getExtractor (token .getRawType ());
123+ // If token has a TypeExtractor
117124 if (opt .isPresent ()) {
125+ // Use it!
118126 return opt .get ().reify (this , o );
119127 }
120128 }
121129
130+ // Otherwise, we aren't going to gain any extra information
122131 final TypeVariable <?>[] typeVars = c .getTypeParameters ();
132+ // If the class has no type variables, just return it. Note that, for
133+ // extensibility reasons, this should happen after we check the type
134+ // extractors
123135 if (typeVars .length == 0 ) {
124136 return c ;
125137 }
126- // fill in any remaining unresolved type parameters with wildcards
138+ // Otherwise parameterize with all Anys
127139 final Map <TypeVariable <?>, Type > resolved = new HashMap <>();
128140 for (final TypeVariable <?> typeVar : typeVars ) {
129141 resolved .putIfAbsent (typeVar , Any .class );
0 commit comments