It's parameter is FQ-name of class (currently only from builtins) that added as supertype to annotated Java class.
Parameters of annotated class used as non-flexible arguments of added supertype, that helps to propagate more precise types when using in Kotlin.
Some standard JDK collections loaded as they annotated with PurelyImplements.
See tests for clarification.
Before: ArrayList<Int>.add(x: Int!) // possible to add null
After: ArrayList<Int>.add(x: Int) // impossible to add null
#KT-7628 Fixed
#KT-7835 Fixed
In most cases order doesn't matter as in supertype tree built from real code
types with same type constructors should be completely equal.
The only case when order does matter is when we artificially add more specific supertype closer to the root.
For example specific annotation adding non-platform supertype MutableMap<K, V> to ConcurrentHashMap
ConcurrentHashMap<K, V> extends ConcurrentMap<K!, V!> that extends java.util.Map<K!, V!> (mapped to kotlin.MutableMap<K!, V!>)
So we want in that case to use refined (more specific) version when checking subtypes:
ConcurrentHashMap<String, Int> should not be a subtype Map<String!, Int!> (and respectively Map<String?, Int?>)
It should be pure non-platform Map<String, Int> that can be found only with BFS
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<*>?
Parse TryCatchBlockNode's in generated bytecode, infer stack save/restore points.
Save stack to local variables before 'try'.
Restore stack after the beginning of try-block, catch-block, and default handler.
Integrate before/after inline markers rewriting (otherwise it'll break our stacks).
#KT-3309 Fixed
Sealed classes can be derived only by their own inner classes or objects.
Their constructors cannot be called explicitly, so compiler knows all their descendants.
Incompatible modifier checks (final, abstract). Impossible with interface, object, enum.
A pack of tests provided.
- generate fake jump instructions so that we can always analyze stack depths
- fix stack before break and continue by dropping excessive elements (e.g., *a*.foo(*b*, c?:continue))
- Analyzer rewritten in Kotlin, with more flexible control of CFG traversal
#Fixed KT-3340
#Fixed KT-4258
#Fixed KT-7941
A set of tests provided. Some external tests fixed accordingly.
Companion object creation changed accordingly.
Derived classes now can use base class with the private constructor.
Refactoring of AccessorForFunctionDescriptor.
Without this, the unrelated type specified on the LHS of a property reference
literal was considered to be an extension receiver of the candidate, and the
resolution was erroneously successul. This is only reproducible for properties,
because if we're trying to resolve an extension, we consider all properties
from the scope, even non-extensions, because there may be a property of an
extension-functional type (T.() -> R). (We don't do this for functions.)
#KT-7430 Fixed
#KT-7945 Fixed