|
1 | | -* Add constructor generics support (ConstructorGenericsContext) |
2 | | -* Inlying contexts: generics context building for type "inside" known hierarchy: |
3 | | - "Drill down" case, when new generics context must be build for some type, using generics of current context. |
4 | | - For example, we have some generics context and analyzing class fields. Some field is MyType<T\> - generified with |
5 | | - current class's generic. Inlying context is building new hierarchy with extra known generics (for example for class MyType<String\>). |
| 1 | +### 3.0.0 (2018-06-19) |
| 2 | +* Add constructor generics support |
| 3 | +* Add inlying contexts support: generics context building for type "inside" of known hierarchy (field, method parameter etc): |
| 4 | + "Drill down" case, when target type could contain generics known in current hierarchy (e.g. field type MyType<T>) |
6 | 5 | Context methods: |
7 | | - - inlyingType(Type) = GenericsContext - universal inlying context builder (the same as GenericsResolver.resolve(class) if class does not have generics) |
| 6 | + - context.inlyingType(Type) = GenericsContext - universal inlying context builder (the same as GenericsResolver.resolve(class) if class does not have generics) |
8 | 7 | - context.fieldType(Field) - shortcut for fields (guarantee correct base type or error if type not in hierarchy) |
9 | 8 | - method(Method).returnType() - shortcut for method return type (guarantee correct base type) |
10 | 9 | - method(Method).parameterType(pos) - shortcut for method parameter type (guarantee correct base type) |
| 10 | + - constructor(Constructor).parameterType(pos) - shortcut fot constructor parameter |
11 | 11 | - returned context have reference to root context: GenericsContext.rootContext() |
12 | | -* Inlying context building for sub type: it's like inlying context (knowing type's root generics), but target type is |
13 | | - a subtype for current. Very special case, required for instance analysis: useful when not just type declarations, but |
14 | | - also actual instance is used for analysis: |
| 12 | +* Inlying context building for higher type then declared (e.g. in field or method). Very special case, required for |
| 13 | + instance analysis when not just type declarations, but also actual instance is used for analysis: |
15 | 14 | Suppose we have field MyType<String\> inside class. But we know that actual instance is MySpecificType<T, K\> extends MyType<T\>. |
16 | 15 | We need to build generics context for actual class (MySpecificType), but as we know base class type, we can track class generics |
17 | 16 | as MySpecificType<String, Object\> (partially tracked) |
18 | | - - inlyingTypeAs(Type, Class) = GenericsContext - universal inlying context building for target class |
| 17 | + - context.inlyingTypeAs(Type, Class) = GenericsContext - universal inlying context building for higher target class |
19 | 18 | - Shortcuts, by analogy with simple inlying contexts: fieldTypeAs(Field, Class), returnTypeAs(Class), parameterTypeAs(pos, Class) |
20 | | - - Tracks root type generics from known middle generics (e.g. Root<T\> extends Base<T\> when known Base<String\> will resolve to Root<String\>). |
| 19 | + - Target type generics tracking from known declared type generics (e.g. Root<T\> extends Base<T\> when known Base<String\> will resolve to Root<String\>). |
21 | 20 | Support composite generic declarations (and any hierarchy depth). |
22 | 21 | * Internal analysis logic opened as utilities (for low level usage without GenericsResolver) |
23 | 22 | - GenericsResolutionUtils - generics analysis logic (with access to analyzed type) |
24 | | - - GenericsTrackingUtils - root generics tracking from middle class's known generics (with access to analyzed types) |
25 | | - - TypeUtils - generic utilities on types (ignoring unknown generics) |
| 23 | + - GenericsTrackingUtils - root generics tracking from middle class's known generics |
| 24 | + - TypeUtils - generic utilities for types (ignoring unknown generics) |
26 | 25 | * Types deep comparison api: TypesWalker.walk(Type, Type, Visitor) could walk on two types side by side to check or compare actual classes on each level |
27 | 26 | Usages: |
28 | 27 | - TypeUtils.isCompatible(Type, Type) - deep types compatibility check |
|
35 | 34 | - Now all exceptions extend base type GenericsException (runtime) to simplify generic analysis errors interception (catch(GenericException ex)) |
36 | 35 | - General tracking exception: GenericsTrackingException - thrown on generics tracking problems |
37 | 36 | - General resolution exception: GenericsResolutionException - thrown on type hierarchy generics analysis problems |
38 | | - - WrongGenericsContextException thrown when supplied type contains generics incompatible with current class |
| 37 | + - WrongGenericsContextException thrown when supplied type contains generics incompatible with current hierarchy |
39 | 38 | (not reachable from current context) |
40 | 39 | - More informative error messages |
41 | 40 | - (breaking) UnknownGenericException moved to different package |
42 | 41 | - (breaking) NoGenericException removed. Was thrown for resolveGenericsOf(Type) methods when class does not declare generics. |
43 | | - Now empty list or null will be returned. |
| 42 | + Now empty list or null is returned. |
44 | 43 | * Context api improvements: |
45 | 44 | * Check all supplied types for compatibility with current class: throw exception when type contains generics |
46 | 45 | belonging to other class (avoid usage errors) |
|
50 | 49 | - ownerGenericsMap() - visible generics of outer class (if current is inner) |
51 | 50 | - methodGenericsMap() - method generics |
52 | 51 | - constructorGenericsMap() - constructor generics |
53 | | - - visibleGenericsMap() - all visible generics (type +owner +method) |
| 52 | + - visibleGenericsMap() - all visible generics (type +owner +method/constructor) |
54 | 53 | * Type resolution methods (return type with all generic variables replaced with known values): |
55 | 54 | - resolveType(Type) = Type |
56 | 55 | - Shortcuts: |
57 | 56 | - resolveFieldType(Field) - field type without generic variables |
58 | 57 | - resolveParameterType(pos) - (method context) parameter type without generic variables |
59 | 58 | - resolveReturnType() - (method context) return type without generic variables |
60 | 59 | - resolveTypeGenerics(Type) = Type[] |
61 | | - * Shortcuts for Field's type resolution (with automatic context tracking to avoid silly mistakes): |
| 60 | + * Shortcuts for common Field's resolutions: |
62 | 61 | - resolveFieldClass(Field) - field class |
63 | 62 | - resolveFieldGenerics(Field) - field's class generics (List<Class\>) |
64 | 63 | - resolveFieldGeneric(Field) - field's class generic (Class) |
65 | | - * More to string utilities: |
66 | | - - GenericsContext to string methods for context type: |
| 64 | + * More toString utilities: |
| 65 | + - GenericsContext toString methods for context type: |
67 | 66 | - toStringCurrentClassDeclaration() - current with resolved generics ("MyClass<Integer>") |
68 | 67 | - toStringCurrentClass() - current class with named generics ("MyClass<T>") |
69 | 68 | - toStringMethod() - method string with resolved generics ("void do(MyType)") |
70 | 69 | - toStringConstructor() - constructor string with resolved generics ("Some(Long)") |
71 | | - * (breaking) resolveGenericsOf() called on class will return upper bounds from generic declaration (previously returns empty map) |
| 70 | + * (breaking) resolveGenericsOf() called on Class will return upper bounds from generic declaration (previously returns empty map) |
72 | 71 | * Improved debugging support: |
73 | 72 | - Core context could be printed as string (class hierarchy with resolved generics): context.getGenericsInfo().toString() |
74 | 73 | - For customized context string rendering: context.getGenericsInfo().toStringHierarchy(TypeWriter) |
75 | | - - Direct toString() on context (GenericsContext) prints entire hierarchy with current position marker "<-- current" marker. |
76 | | - In intellij idea you can use "view" value link inside debugger to quickly overview current context (with resolved generics) and position |
77 | | -* Inner classes support (Outer<T\>.Inner, not static): outer class generics are resolved to avoid UnknownGenericException |
78 | | - - Used owner class (context.ownerClass()) generics: context.ownerGenericsMap() (empty map for not inner class) |
79 | | - - For inlying context building, root class may be used as generics source for inner class (if root class hierachy contains owner class). |
| 74 | + - Direct toString() on context (GenericsContext) prints entire hierarchy with current position marker ("<-- current"). |
| 75 | + In intellij idea, current context (with resolved generics) and position could be seen by using "view value" link inside debugger |
| 76 | +* Add inner classes support (Outer<T\>.Inner, not static) - outer class generics are resolved during hierarchy building: |
| 77 | + - GenericsInfo contains maps with both type generics and owner generics |
| 78 | + - context.ownerClass() returns owner class, visible owner generics are accessible with context.ownerGenericsMap() (empty map for not inner class) |
| 79 | + - For inlying context building, root class may be used as generics source for inner class (if root class hierarchy contains owner class). |
80 | 80 | This is not always true, but, for most cases, inner class is used inside owner and so generics resolution will be correct |
81 | 81 | * Improved bounds support: |
82 | 82 | - Support multiple upper bounds declaration: My<T extends A & B\> now stored as wildcard (? extends A & B) and used |
83 | | - for more precise checks (compatibility, assignability). As before, resolveClass("T") will use first upper bound (A). |
| 83 | + for more precise checks (e.g. compatibility, assignability checks). As before, resolveClass("T") will use first upper bound (A). |
84 | 84 | - (breaking) avoid upper bound wildcards (transform <? extends Something\> -> Something) as only type matter at runtime |
85 | | - affects GenericsUtils.resolveTypeVariables() |
| 85 | + Affects hierarchy resolution: root generics will not contain Wildcards as before, but just type |
86 | 86 |
|
87 | 87 | Compatibility notes: |
88 | 88 | * API did not changed, only new methods were added. |
|
0 commit comments