Previoisly, there were two places where mapping had happened:
- toConeKotlinTypeWithNullability
- enhancePossiblyFlexible
The first one was used for supertypes and bounds and the second one
was used for other signature parts
The main idea is to perform type mapping once to a flexible type,
and then use it as it's needed (it's lower bound, or for the further ehnancement)
Also, this commit fixes flexibility for type arguments, see the tests
Really, this commit implements early J2K mapping for all Java types.
It's questionable and probably wrong at least for super-types,
because, for example, we cannot resolve spliterator() in classes
derived from java.lang.Iterable
Before this commit, we created type parameter symbols each time
when type parameter was referenced or created.
In this commit, we introduced class-bound Java type parameter stack
and use it to find referenced type parameter symbol.
So now they are created only when Java type parameter is created
Java nullability annotations may generate types that currently are not denotable in Kotlin:
class Java {
void <F> foo(@NotNull F f) {}
}
Type of given value parameter should be not nullable under any substitution:
String/String?/String! because of annotation contract.
NB: Currently there is no full analogues for such types in pure kotlin
Before this commit old type parameters were inserted into new descriptor,
and that broke a simple contract: desc.child.getContainingDeclaration() == desc.
We use `doSubstitute` here because it does exactly what we need:
1. creates full copy of descriptor
2. copies method's type parameters (with new containing declaration) and properly substitute to them in value parameters, return type and etc.
But we had to customize `doSubstitute`: add some parameters like `newReturnType`
NOTE: Strange testData change.
(Mutable)List<in T!>! after substitution becomes MutableList<in T!>..List<*>?.
But it's not wrong because List<in T> behaves exactly as List<*>, and the same happens when substituing Java class scope:
public class A<E> {
<T> void foo(List<? super T> x) {}
}
Kotlin:
A.foo(), type of first value parameter --- (Mutable)List<in T!>
A<String>().foo(), type of first value parameter --- MutableList<in T!>..List<*>?