JVM IR: handle JvmStatic in object as module phase

This allows to get rid of the situation where a JvmStatic function in
object can be seen in different states in different lowerings: unlowered
with a dispatch receiver parameter, declaration is lowered but calls are
not, and both declaration and calls are lowered.

Now it works like this:
1) JvmStatic functions in objects coming from dependencies are always
   loaded as lowered, without the extra dispatch receiver parameter. In
   psi2ir this is done via JVM-specific extension; in fir2ir it's done
   in place (but probably should be extracted to extension too).
2) Functions from sources are created as unlowered by both psi2ir and
   fir2ir, and are lowered in a module-wide phase at the beginning of
   JvmLower.
3) Calls to all JvmStatic functions from objects (from sources and
   dependencies) are lowered in the same phase at the beginning of
   JvmLower.

This ensures that all lowerings after the module-wide phase
`jvmStaticInObjectPhase`, which include all per-file phases, see all
JvmStatic functions in objects without the additional dispatch receiver
parameter, and calls do not have dispatch receiver either.

The only issue with this approach is that function/property reference
representation in reflection needs to have that dispatch receiver
parameter, and that is achieved via a hack in those lowerings, which
seems not too out of place anyway, given that they're handled specially
in kotlin-reflect as well.
This commit is contained in:
Alexander Udalov
2020-11-11 15:25:03 +01:00
parent 0a00cbefaf
commit 7117932623
13 changed files with 103 additions and 128 deletions
@@ -5,9 +5,9 @@
package org.jetbrains.kotlin.ir.declarations.lazy
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrBody
@@ -54,7 +54,7 @@ class IrLazyFunction(
override val initialSignatureFunction: IrFunction? by createInitialSignatureFunction()
override var dispatchReceiverParameter: IrValueParameter? by createReceiverParameter(descriptor.dispatchReceiverParameter)
override var dispatchReceiverParameter: IrValueParameter? by createReceiverParameter(descriptor.dispatchReceiverParameter, true)
override var extensionReceiverParameter: IrValueParameter? by createReceiverParameter(descriptor.extensionReceiverParameter)
@@ -34,9 +34,13 @@ interface IrLazyFunctionBase : IrLazyDeclarationBase, IrTypeParametersContainer
}
}
fun createReceiverParameter(parameter: ReceiverParameterDescriptor?): ReadWriteProperty<Any?, IrValueParameter?> =
fun createReceiverParameter(
parameter: ReceiverParameterDescriptor?,
functionDispatchReceiver: Boolean = false,
): ReadWriteProperty<Any?, IrValueParameter?> =
lazyVar {
typeTranslator.buildWithScope(this) {
if (functionDispatchReceiver && stubGenerator.extensions.isStaticFunction(descriptor)) null
else typeTranslator.buildWithScope(this) {
parameter?.generateReceiverParameterStub()?.also { it.parent = this@IrLazyFunctionBase }
}
}
@@ -259,6 +259,7 @@ val IrClass.isInterface get() = kind == ClassKind.INTERFACE
val IrClass.isClass get() = kind == ClassKind.CLASS
val IrClass.isObject get() = kind == ClassKind.OBJECT
val IrClass.isAnonymousObject get() = isClass && name == SpecialNames.NO_NAME_PROVIDED
val IrClass.isNonCompanionObject: Boolean get() = isObject && !isCompanion
val IrDeclarationWithName.fqNameWhenAvailable: FqName?
get() = when (val parent = parent) {
is IrDeclarationWithName -> parent.fqNameWhenAvailable?.child(name)
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrConstructor
@@ -21,6 +22,8 @@ open class StubGeneratorExtensions {
open fun isPropertyWithPlatformField(descriptor: PropertyDescriptor): Boolean = false
open fun isStaticFunction(descriptor: FunctionDescriptor): Boolean = false
open val enhancedNullability: EnhancedNullability
get() = EnhancedNullability