Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR:
VariableTypeInfo#getBounds()
for ProbeJS, (using#asClass()
is making ProbeJS unable to handle cases likeT extends A & B & C
)TypeConsolidatorTest
for testing how it works on method param / method return type / field .TypeInfo#consolidate(Map<VariableTypeInfo, TypeInfo>)
The most fundamental method in type consolidating.
Almost all TypeInfo implementation is returning itself or passing the mapping to its components. Only
VariableTypeInfo
will try to map itself to another, consolidated type.Implementations are carefully tweaked to make simple types always skip type consolidating, and make complex types (
T[]
,Class<String>
, ...) skip type consolidating if it's proven to be unnecessary.Type Consolidation Mapping
aka the
Map<VariableTypeInfo, TypeInfo>
inTypeInfo#consolidate(...)
. It can be obtained viaTypeConsolidator#getMapping(Class)
, or construct it yourself.TypeConsolidator#getMapping(Class)
assuming that we have these classes as a rather extreme case:
and we're trying to get mapping for
D.class
, thenTypeConsolidator#getMapping(Class)
will work like thisTc -> Td
Tb -> A<Td>
Ta -> Tc
Ta -> Td
(becauseTa -> Tc
andTc -> Td
)Ta -> Td
,Tb -> A<Td>
,Tc -> Td
This mapping can map EVERY type variables used by D's super class/interfaces to types used by D itself, this is important for performance because we only need to apply the mapping once, and no mapping from super classes are required.
2-Stage Type Consolidation
assuming that for class D we have these methods:
Stage 1
The first type consolidation will happen at type initialization, for example for field:
Type consolidation in this stage will remove all usages of type variables from super classes / interfaces.
class D after this stage:
Stage 2
This type consolidation will only apply to types with generics. It will be applied to
Function<String, String>
, orSupplier<SomeEnum>
, but notItemStack
or raw typeMap
because there's no generic.Type consolidation in this stage will map type variables to actual types.
Let's say we already have an instance of D, named
d
, via a methodD<Byte> createD();
.When trying to invoke
d.setD(...)
, the actual typeByte
will be used to create another mapping:Td -> Byte
.apply the mapping we just created, then the method
setD
will be:You can verify that it's working because other type related features like type wrappers will be functional on generics after this PR.
Notes
for Pruno:
#asClass()
is making ProbeJS unable to handle cases likeT extends A & B & C
, tryVariableTypeInfo#getBounds()
getGenericTypeReplacement()
will be redundant if this PR is merged. TryTypeConsolidator#getMapping(Class)
if you still need something similarVariableTypeInfo
more usable for type dumpers #53 is basically completely overwritten, hope you don't mindabout Generics in method/constructor, for example:
It's NOT supported yet, supporting this will require finding the common super class of all related types, which can be performance expensive