This fixes a bunch of missing overridden symbols in IR.
This is also required for fixing KT-59921 in the following commit
where we need to keep all overridden symbols of intersection overrides
so that we can enhance them properly.
#KT-57300 Fixed
#KT-57299 Fixed
#KT-59921
#KT-57300
#KT-62788
#KT-64271
#KT-64382
We drop Kotlin function 'remove' or 'getOrDefault' from JvmMappedScope,
if it has platform-dependent annotation, and the bound Java class scope
does not contain a function with the same signature.
#KT-57268 Fixed
Types based on type parameters which have both hasEnhancedNullability
and hasFlexibleNullability were incorrectly converted to IR: only
`@EnhancedNullability` annotation was added to the IR type. This means
that the nullability of the type started to matter, which is incorrect
because the type is supposed to be flexible.
This backfired in the IR fake override builder mode, where nullability
of methods inherited from both Kotlin maps and Java maps clashed, which
resulted in the exception from FakeOverrideRebuilder.
If the type is both flexible and enhanced, we're now adding
`@FlexibleNullability` to the IR type. Note that `@EnhancedNullability`
is not needed because it only affects primitive types which need to be
handled as wrapper types on JVM, but `@FlexibleNullability` already has
that effect.
IR still slightly differs from K1 for collection subclasses, which can
be seen for example in the changed IR text tests. This is to be
investigated later.
The change in tests is needed because the `kt48495*.kt` tests are now
passing on K2 in the IR fake override builder mode, while failing on the
vanilla K2.
This is related to KT-61370 but does not entirely fix it, although
curiously it fixes all remaining tests which were muted because of it.
In Kotlin subclasses of `MutableCollection<Int>`, the method
`remove(Int)` has its argument boxed, so that it wouldn't clash with the
method from `java.util.List`. So `JavaOverrideChecker` should understand
that a Java method `boolean remove(java.lang.Integer)` overrides it,
otherwise platform declaration clash was reported.
The code is adapted from `forceSingleValueParameterBoxing` in K1's
`methodSignatureMapping.kt`.
The test has been moved and adapted from diagnostic to codegen box
tests, to check correct backend execution + runtime.
#KT-62316 Fixed
`FakeOverrideBuilder.provideFakeOverrides` recursively changes overrides
for all superclasses in the hierarchy, including lazy IR, which is a lot
of extra work.
Also it leads to some tests failing in the IR fake override builder mode
because it changes correct fake overrides of Java classes to incorrect
ones. Those tests are unmuted but it doesn't mean they are fixed -- most
likely we'll generate fake overrides via IR for lazy IR too, at which
point they'll start to fail again.
This big refactoring is needed to cleanup building of overrides
mappings and prevent creating redundant intersection overrides in
cases when there is no need in them:
```kotlin
interface A {
fun foo()
}
interface B {
fun foo()
}
interface C : A, B {
override fun foo()
}
```
Before this refactoring there was next override tree:
C.foo
intersection override (A.foo, B.foo)
A.foo
B.foo
Also this commit fixes special mapping of overrides in jvm scopes
for declarations which have kotlin builtins in supertypes with
special java mapping rules (collections, for example)
We are going to deprecate `WITH_RUNTIME` directive. The main reason
behind this change is that `WITH_STDLIB` directive better describes
its meaning, specifically it will add kotlin stdlib to test's classpath.
Special getter names (like Collection.size()) can be used only in Java
classes with all-java super-types
Because if there is a kotlin class (not interface) in
the middle, we 'materialize' special getters to properties.
For subclasses of `AbstractMutableList<Int>` which are not inline
classes, the special bridge `remove` had a parameter of type `Int`
(mapped to JVM primitive int) before this fix. The hack in
`MethodSignatureMapper` changed this type to `Int?`, yet the body of the
special bridge still loaded it as non-nullable, which resulted in
incorrect bytecode.
It looks like a part of this hack in `BridgeLowering` was made only for
inline classes which are subclasses of mutable collections. Supposedly
it should be extended to non-inline classes, so that `remove` special
bridge would have consistent IR by the time it reaches codegen.
#KT-46516 Fixed
- Add utilities to add new attribute to ConeAttributes
- Get rid of FlexibleNullability attribute (it can be easily inferred
for any flexible type at any moment)
- Fix determining of EnhancedNullability attribute
The difference is how we deal with intermediate fake overrides
E.g., in case
interface A { /* $1 */ fun foo() }
interface B : A {
/* $2 */ fake_override fun foo()
}
interface C : B {
/* $3 */ override fun foo()
}
We've got FIR declarations only for $1 and $3, but we've got
a fake override for $2 in IR.
Previously, override $3 had $1 as its overridden IR symbol, just because
FIR declaration of $3 doesn't know anything about $2.
Now, when generating IR for $2, we save the necessary information
and using it for $3, so it has $2 as overridden.
So, it's consistent with the overridden structure of FE 1.0 and this
structure is necessary prerequisite for proper building of bridges
for special built-ins.