[FIR] Add Fir2IrLazyField class
This class will be used to delay const evaluation of java fields until IR tree is built. #KT-57802
This commit is contained in:
+12
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
|
||||
import org.jetbrains.kotlin.fir.java.hasJvmFieldAnnotation
|
||||
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyClass
|
||||
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyConstructor
|
||||
@@ -624,6 +625,17 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
|
||||
val classId = (irParent as? IrClass)?.classId
|
||||
val containingClassLookupTag = classId?.toLookupTag()
|
||||
val signature = signatureComposer.composeSignature(field, containingClassLookupTag)
|
||||
|
||||
val parentIsExternal = irParent.isExternalParent()
|
||||
if (field is FirJavaField && field.isStatic && field.isFinal && parentIsExternal && signature != null) {
|
||||
// We are going to create IR for Java static final fields lazily because they can refer to some Kotlin const.
|
||||
// This way we delay const evaluation of Java fields until IR tree is fully built, and we can run IR interpreter.
|
||||
return lazyDeclarationsGenerator.createIrLazyField(field, signature, irParent!!, origin).apply {
|
||||
setParent(irParent)
|
||||
addDeclarationToParent(this, irParent)
|
||||
}
|
||||
}
|
||||
|
||||
return field.convertWithOffsets { startOffset, endOffset ->
|
||||
if (signature != null) {
|
||||
symbolTable.declareField(
|
||||
|
||||
+17
-4
@@ -11,13 +11,11 @@ import org.jetbrains.kotlin.fir.backend.convertWithOffsets
|
||||
import org.jetbrains.kotlin.fir.backend.irOrigin
|
||||
import org.jetbrains.kotlin.fir.backend.isStubPropertyForPureField
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyClass
|
||||
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyConstructor
|
||||
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyProperty
|
||||
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazySimpleFunction
|
||||
import org.jetbrains.kotlin.fir.lazy.*
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorPublicSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldPublicSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrPropertyPublicSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.util.IdSignature
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
@@ -116,4 +114,19 @@ class Fir2IrLazyDeclarationsGenerator(val components: Fir2IrComponents) : Fir2Ir
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun createIrLazyField(
|
||||
fir: FirField,
|
||||
signature: IdSignature,
|
||||
lazyParent: IrDeclarationParent,
|
||||
declarationOrigin: IrDeclarationOrigin
|
||||
): IrField {
|
||||
return fir.convertWithOffsets { startOffset, endOffset ->
|
||||
symbolTable.declareField(signature, symbolFactory = { IrFieldPublicSymbolImpl(signature) }) { symbol ->
|
||||
Fir2IrLazyField(
|
||||
components, startOffset, endOffset, declarationOrigin, fir, (lazyParent as? Fir2IrLazyClass)?.fir, symbol
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.lazy
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
||||
import org.jetbrains.kotlin.fir.backend.toIrConst
|
||||
import org.jetbrains.kotlin.fir.declarations.FirField
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isExternal
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isFinal
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||
import org.jetbrains.kotlin.fir.unwrapFakeOverrides
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.lazy.lazyVar
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class Fir2IrLazyField(
|
||||
private val components: Fir2IrComponents,
|
||||
override val startOffset: Int,
|
||||
override val endOffset: Int,
|
||||
override var origin: IrDeclarationOrigin,
|
||||
override val fir: FirField,
|
||||
val containingClass: FirRegularClass?,
|
||||
override val symbol: IrFieldSymbol,
|
||||
) : IrField(), AbstractFir2IrLazyDeclaration<FirField>, Fir2IrComponents by components {
|
||||
init {
|
||||
symbol.bind(this)
|
||||
}
|
||||
|
||||
override var annotations: List<IrConstructorCall> by createLazyAnnotations()
|
||||
override lateinit var parent: IrDeclarationParent
|
||||
|
||||
@ObsoleteDescriptorBasedAPI
|
||||
override val descriptor: PropertyDescriptor
|
||||
get() = symbol.descriptor
|
||||
|
||||
override var isExternal: Boolean
|
||||
get() = fir.isExternal
|
||||
set(_) = mutationNotSupported()
|
||||
|
||||
override var isFinal: Boolean
|
||||
get() = fir.isFinal
|
||||
set(_) = mutationNotSupported()
|
||||
|
||||
override var isStatic: Boolean
|
||||
get() = fir.isStatic
|
||||
set(_) = mutationNotSupported()
|
||||
|
||||
override var name: Name
|
||||
get() = fir.name
|
||||
set(_) = mutationNotSupported()
|
||||
|
||||
override var visibility: DescriptorVisibility = components.visibilityConverter.convertToDescriptorVisibility(fir.visibility)
|
||||
set(_) = mutationNotSupported()
|
||||
|
||||
override var type: IrType
|
||||
get() = with(typeConverter) { fir.returnTypeRef.toIrType() }
|
||||
set(_) = mutationNotSupported()
|
||||
|
||||
override var initializer: IrExpressionBody? by lazyVar(lock) {
|
||||
when (val initializer = fir.unwrapFakeOverrides().initializer) {
|
||||
is FirConstExpression<*> -> factory.createExpressionBody(initializer.toIrConst(type))
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
override var correspondingPropertySymbol: IrPropertySymbol?
|
||||
get() = null
|
||||
set(_) = mutationNotSupported()
|
||||
|
||||
override var metadata: MetadataSource?
|
||||
get() = null
|
||||
set(_) = error("We should never need to store metadata of external declarations.")
|
||||
}
|
||||
Reference in New Issue
Block a user