Simplify MultifileClassPartCodegen, remove related tests and change some
tests to use const val instead of val because backing fields for const
properties are stored in the facade, not parts
#KT-23701 Fixed
* if enum class has abstract members, then it is ABSTRACT
* otherwise, if enum class has entries with members, then it is OPEN
* otherwise, it is FINAL.
In case of the same class defined in different modules they contain
different descriptors instances in their scope that might lead
to failing assertion in findConcreteSuperDeclaration
because there are overridden from different modules
It might happen even in the compiler because of different built-in modules
defined for sources-module and for dependencies' one
^KT-29320 Fixed
In many other places, e.g. org.jetbrains.kotlin.codegen.ClassBodyCodegen#generateDelegatesToDefaultImpl
we implicitly assume that whenever we use a default interface method
our target is 1.8
But here, we don't and it might lead to exception in org.jetbrains.kotlin.backend.common.bridges.BridgesKt#findConcreteSuperDeclaration
when actual target is 1.6 and we extend some AbstractMap implementation
with JDK8 (i.e., with @PlatformDependent getOrDefault)
In case we extending some Map specialization with non-trivial type arguments,
e.g. Map<String, String> from Kotlin point-of-view it has
"remove(String, String)" signature while in Java it's "remove(Object, Object)".
So, we generate an override "remove(String, String)" in first Kotlin class of the hierarchy,
which body delegates to "super.remove(Object, Object)"
Also, we generate a final override for "remove(Object, Object)" to allow
for Java inheritors choose only the version with String while overriding.
The main idea of the fix is to make mayBeUsedAsSuperImplementation
return true in case of PlatformDependent annotations.
Otherwise, we weren't able to choose the impl from the java.util.Map
as a delegate in our bridge.
Another part of the fix is overriding `isDeclaration`:
it was necessary because otherwise bridge-generation algorithm
was assuming that there's already an actual declaration
in the first sub-class (TestMap) in the test and we need to
delegate to the latter instead of the method from the interface
^KT-26069 Fixed
Make a separate subclass for DescriptorBasedFunctionHandle
to allow customize the behavior without complex abstract concepts
like `areDeclarationAndDefinitionSame`
- Give it more clear name mayBeUsedAsSuperImplementation
because defining if it can be used as super-implementation
this is what it used for
- The meaning is negated, so it's needed to negate its usages and impls
- Also, reuse it in findSuperImplementationForStubDelegation
ASM has logic that splits exception tables in MethodWriter.computeAllFrames:
// Loop over all the basic blocks and visit the stack map frames that must be stored in the
// StackMapTable attribute. Also replace unreachable code with NOP* ATHROW, and remove it from
// exception handler ranges.
...
firstHandler = Handler.removeRange(firstHandler, basicBlock, nextBasicBlock);
...
https://gitlab.ow2.org/asm/asm/issues/317867
#KT-28546 Fixed
Proper SMAP support for default values from expect declarations is required.
Default value in expect declaration could has line number that
exceed line count in actual file that causes an error
#KT-23739 Fixed
#KT-29174 Open
Original problem is that lowered ir closures doesn't meet inliner expectations
about captured variable position in inlining method.
E.g.: Call 'foo(valueParam) { capturedParam }' to
inline function 'foo' with declaration
inline fun foo(valueParam: Foo, inlineParamWithCaptured: Bar.() ->) ....
is reorganized through inlining to equivalent call foo(valueParam, capturedParam1, cp2 ...).
But lowered closure for lambda parameter has totally different parameters order:
fun loweredLambda$x(extensionReceiver, captured1, cp2..., valueParam1, vp2...)
So before inlining lowered closure should be transformed to
fun loweredLambda$x(extensionReceiver, valueParam1, vp2..., captured1, cp2..)
#KT-28547 Fixed
In general case parameter type could differ from actual default lambda type.
E.g.: fun inlineFun(s: (Child) -> Base = { a: Base -> a as Child}),
where type of default lambda is '(Base) -> Child'.
In such case we should find somehow actual invoke method in bytecode knowing
only name, number of parameters and that's actual invoke is non-synthetic
regardless of bridge one.
#KT-21946 Fixed