JVM_IR: deal with JvmStatic in imported IR

This commit is contained in:
Georgy Bronnikov
2021-05-13 11:07:35 +03:00
committed by TeamCityServer
parent 96ce124268
commit 931733f8cc
9 changed files with 65 additions and 41 deletions
@@ -25,8 +25,6 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.name.Name
class IrLoweringContext(backendContext: BackendContext) : IrGeneratorContextBase(backendContext.irBuiltIns)
class DeclarationIrBuilder(
generatorContext: IrGeneratorContext,
symbol: IrSymbol,
@@ -59,12 +57,19 @@ open class VariableRemapper(val mapping: Map<IrValueParameter, IrValueDeclaratio
mapping[value]
}
fun IrBuiltIns.createIrBuilder(
symbol: IrSymbol,
startOffset: Int = UNDEFINED_OFFSET,
endOffset: Int = UNDEFINED_OFFSET
) =
DeclarationIrBuilder(IrGeneratorContextBase(this), symbol, startOffset, endOffset)
fun BackendContext.createIrBuilder(
symbol: IrSymbol,
startOffset: Int = UNDEFINED_OFFSET,
endOffset: Int = UNDEFINED_OFFSET
) =
DeclarationIrBuilder(IrLoweringContext(this), symbol, startOffset, endOffset)
irBuiltIns.createIrBuilder(symbol, startOffset, endOffset)
fun <T : IrBuilder> T.at(element: IrElement) = this.at(element.startOffset, element.endOffset)
@@ -7,8 +7,10 @@ package org.jetbrains.kotlin.backend.jvm
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
import org.jetbrains.kotlin.backend.common.ir.createParameterDeclarations
import org.jetbrains.kotlin.backend.jvm.lower.SingletonObjectJvmStaticTransformer
import org.jetbrains.kotlin.backend.jvm.serialization.deserializeClassFromByteArray
import org.jetbrains.kotlin.backend.jvm.serialization.deserializeIrFileFromByteArray
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.FilteredAnnotations
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
@@ -24,8 +26,11 @@ import org.jetbrains.kotlin.ir.expressions.IrDelegatingConstructorCall
import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl
import org.jetbrains.kotlin.ir.symbols.impl.DescriptorlessExternalPackageFragmentSymbol
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
@@ -98,29 +103,47 @@ open class JvmGeneratorExtensionsImpl(private val generateFacades: Boolean = tru
}
}
@Volatile
private var cachedFields: CachedFieldsForObjectInstances? = null
override fun getCachedFields(irFactory: IrFactory, languageVersionSettings: LanguageVersionSettings): CachedFieldsForObjectInstances {
cachedFields?.let { return it }
synchronized(this) {
cachedFields?.let { return it }
cachedFields = CachedFieldsForObjectInstances(irFactory, languageVersionSettings)
return cachedFields!!
}
}
override fun deserializeLazyClass(
irClass: IrLazyClass,
moduleDescriptor: ModuleDescriptor,
irBuiltIns: IrBuiltIns,
symbolTable: SymbolTable,
stubGenerator: DeclarationStubGenerator,
parent: IrDeclarationParent,
allowErrorNodes: Boolean
): Boolean {
val serializedIr = (irClass.source as? KotlinJvmBinarySourceElement)?.binaryClass?.classHeader?.serializedIr ?: return false
deserializeClassFromByteArray(serializedIr, moduleDescriptor, irBuiltIns, symbolTable, parent, allowErrorNodes)
deserializeClassFromByteArray(
serializedIr, stubGenerator.moduleDescriptor, stubGenerator.irBuiltIns, stubGenerator.symbolTable, parent, allowErrorNodes
)
ExternalDependenciesGenerator(stubGenerator.symbolTable, listOf(stubGenerator)).generateUnboundSymbolsAsDependencies()
val cachedFields = getCachedFields(stubGenerator.irBuiltIns.irFactory, stubGenerator.irBuiltIns.languageVersionSettings)
irClass.transform(SingletonObjectJvmStaticTransformer(stubGenerator.irBuiltIns, cachedFields), null)
return true
}
override fun deserializeFacadeClass(
irClass: IrClass,
moduleDescriptor: ModuleDescriptor,
irBuiltIns: IrBuiltIns,
symbolTable: SymbolTable,
stubGenerator: DeclarationStubGenerator,
parent: IrDeclarationParent,
allowErrorNodes: Boolean
): Boolean {
val serializedIr = (irClass.source as? JvmPackagePartSource)?.knownJvmBinaryClass?.classHeader?.serializedIr ?: return false
deserializeIrFileFromByteArray(serializedIr, moduleDescriptor, irBuiltIns, symbolTable, irClass, allowErrorNodes)
deserializeIrFileFromByteArray(
serializedIr, stubGenerator.moduleDescriptor, stubGenerator.irBuiltIns, stubGenerator.symbolTable, irClass, allowErrorNodes
)
ExternalDependenciesGenerator(stubGenerator.symbolTable, listOf(stubGenerator)).generateUnboundSymbolsAsDependencies()
val cachedFields = getCachedFields(stubGenerator.irBuiltIns.irFactory, stubGenerator.irBuiltIns.languageVersionSettings)
irClass.transform(SingletonObjectJvmStaticTransformer(stubGenerator.irBuiltIns, cachedFields), null)
return true
}
@@ -67,7 +67,9 @@ class JvmBackendContext(
val methodSignatureMapper = MethodSignatureMapper(this)
internal val innerClassesSupport = JvmInnerClassesSupport(irFactory)
internal val cachedDeclarations = JvmCachedDeclarations(this, CachedFieldsForObjectInstances(irFactory, state.languageVersionSettings))
internal val cachedDeclarations = JvmCachedDeclarations(
this, generatorExtensions.getCachedFields(irFactory, state.languageVersionSettings)
)
override val mapping: Mapping = DefaultMapping()
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.DeserializableClass
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
import org.jetbrains.kotlin.name.Name
class JvmFileFacadeClass(
@@ -30,15 +29,7 @@ class JvmFileFacadeClass(
override fun loadIr(): Boolean {
irLoaded?.let { return it }
irLoaded = stubGenerator.extensions.deserializeFacadeClass(
this,
stubGenerator.moduleDescriptor,
stubGenerator.irBuiltIns,
stubGenerator.symbolTable,
parent,
allowErrorNodes = false
)
ExternalDependenciesGenerator(stubGenerator.symbolTable, listOf(stubGenerator)).generateUnboundSymbolsAsDependencies()
return irLoaded as Boolean
irLoaded = stubGenerator.extensions.deserializeFacadeClass(this, stubGenerator, parent, allowErrorNodes = false)
return irLoaded!!
}
}
@@ -5,12 +5,16 @@
package org.jetbrains.kotlin.backend.jvm
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrFactory
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
interface JvmGeneratorExtensions {
val classNameOverride: MutableMap<IrClass, JvmClassName>
val rawTypeAnnotationConstructor: IrConstructor?
fun getCachedFields(irFactory: IrFactory, languageVersionSettings: LanguageVersionSettings): CachedFieldsForObjectInstances
}
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.backend.jvm.ir
import org.jetbrains.kotlin.backend.common.ir.ir2string
import org.jetbrains.kotlin.backend.common.lower.IrLoweringContext
import org.jetbrains.kotlin.backend.jvm.*
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineOnly
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
@@ -22,6 +21,7 @@ import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.PsiIrFileEntry
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
import org.jetbrains.kotlin.ir.builders.IrGeneratorContextBase
import org.jetbrains.kotlin.ir.builders.Scope
import org.jetbrains.kotlin.ir.builders.declarations.buildProperty
import org.jetbrains.kotlin.ir.declarations.*
@@ -191,7 +191,7 @@ class JvmIrBuilder(
startOffset: Int = UNDEFINED_OFFSET,
endOffset: Int = UNDEFINED_OFFSET
) : IrBuilderWithScope(
IrLoweringContext(backendContext),
IrGeneratorContextBase(backendContext.irBuiltIns),
Scope(symbol),
startOffset,
endOffset
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.ir.*
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase
import org.jetbrains.kotlin.backend.jvm.CachedFieldsForObjectInstances
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.codegen.isEffectivelyInlineOnly
@@ -41,7 +42,9 @@ internal val jvmStaticInCompanionPhase = makeIrFilePhase(
private class JvmStaticInObjectLowering(val context: JvmBackendContext) : FileLoweringPass {
override fun lower(irFile: IrFile) =
irFile.transformChildrenVoid(SingletonObjectJvmStaticTransformer(context))
irFile.transformChildrenVoid(
SingletonObjectJvmStaticTransformer(context.irBuiltIns, context.cachedDeclarations.fieldsForObjectInstances)
)
}
private class JvmStaticInCompanionLowering(val context: JvmBackendContext) : FileLoweringPass {
@@ -64,7 +67,7 @@ internal fun IrDeclaration.isJvmStaticInObject(): Boolean =
private fun IrExpression.coerceToUnit(irBuiltIns: IrBuiltIns) =
IrTypeOperatorCallImpl(startOffset, endOffset, irBuiltIns.unitType, IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, irBuiltIns.unitType, this)
private fun IrMemberAccessExpression<*>.makeStatic(context: JvmBackendContext, replaceCallee: IrSimpleFunction?) =
private fun IrMemberAccessExpression<*>.makeStatic(irBuiltIns: IrBuiltIns, replaceCallee: IrSimpleFunction?) =
dispatchReceiver?.let { receiver ->
dispatchReceiver = null
val newCall = if (replaceCallee != null) irCall(this@makeStatic as IrCall, replaceCallee) else this@makeStatic
@@ -73,13 +76,16 @@ private fun IrMemberAccessExpression<*>.makeStatic(context: JvmBackendContext, r
newCall
} else {
IrBlockImpl(startOffset, endOffset, newCall.type).apply {
statements += receiver.coerceToUnit(context.irBuiltIns) // evaluate for side effects
statements += receiver.coerceToUnit(irBuiltIns) // evaluate for side effects
statements += newCall
}
}
} ?: this
private class SingletonObjectJvmStaticTransformer(val context: JvmBackendContext) : IrElementTransformerVoid() {
class SingletonObjectJvmStaticTransformer(
private val irBuiltIns: IrBuiltIns,
private val cachedFields: CachedFieldsForObjectInstances
) : IrElementTransformerVoid() {
override fun visitClass(declaration: IrClass): IrStatement {
if (declaration.isNonCompanionObject) {
for (function in declaration.simpleFunctions()) {
@@ -87,9 +93,7 @@ private class SingletonObjectJvmStaticTransformer(val context: JvmBackendContext
// dispatch receiver parameter is already null for synthetic property annotation methods
function.dispatchReceiverParameter?.let { oldDispatchReceiverParameter ->
function.dispatchReceiverParameter = null
function.replaceThisByStaticReference(
context.cachedDeclarations.fieldsForObjectInstances, declaration, oldDispatchReceiverParameter
)
function.replaceThisByStaticReference(cachedFields, declaration, oldDispatchReceiverParameter)
}
}
}
@@ -102,7 +106,7 @@ private class SingletonObjectJvmStaticTransformer(val context: JvmBackendContext
expression.transformChildrenVoid(this)
val callee = expression.symbol.owner
if (callee is IrDeclaration && callee.isJvmStaticInObject()) {
return expression.makeStatic(context, replaceCallee = null)
return expression.makeStatic(irBuiltIns, replaceCallee = null)
}
return expression
}
@@ -146,7 +150,7 @@ private class CompanionObjectJvmStaticTransformer(val context: JvmBackendContext
return when {
shouldReplaceWithStaticCall(callee) -> {
val (staticProxy, _) = context.cachedDeclarations.getStaticAndCompanionDeclaration(callee)
expression.makeStatic(context, staticProxy)
expression.makeStatic(context.irBuiltIns, staticProxy)
}
callee.symbol == context.ir.symbols.indyLambdaMetafactoryIntrinsic -> {
val implFunRef = expression.getValueArgument(1) as? IrFunctionReference
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.DeserializableClass
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
import org.jetbrains.kotlin.ir.util.TypeTranslator
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.metadata.ProtoBuf
@@ -34,18 +34,14 @@ open class StubGeneratorExtensions {
open fun deserializeLazyClass(
irClass: IrLazyClass,
moduleDescriptor: ModuleDescriptor,
irBuiltIns: IrBuiltIns,
symbolTable: SymbolTable,
stubGenerator: DeclarationStubGenerator,
parent: IrDeclarationParent,
allowErrorNodes: Boolean,
): Boolean = false
open fun deserializeFacadeClass(
irClass: IrClass,
moduleDescriptor: ModuleDescriptor,
irBuiltIns: IrBuiltIns,
symbolTable: SymbolTable,
stubGenerator: DeclarationStubGenerator,
parent: IrDeclarationParent,
allowErrorNodes: Boolean,
): Boolean = false