[FIR] Make enum entry initializer lazy in RawFirBuilder

Third step for KT-52615

Merge-request: KT-MR-7769
Merged-by: Egor Kulikov <Egor.Kulikov@jetbrains.com>
This commit is contained in:
Egor Kulikov
2022-11-23 18:55:21 +00:00
committed by Space Team
parent 194d1cfccf
commit 3e8f7b8ee4
16 changed files with 328 additions and 176 deletions
@@ -101,6 +101,11 @@ public class LightTree2FirConverterTestCaseGenerated extends AbstractLightTree2F
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums2.kt");
}
@TestMetadata("enums3.kt")
public void testEnums3() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums3.kt");
}
@TestMetadata("expectActual.kt")
public void testExpectActual() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/expectActual.kt");
@@ -306,9 +306,7 @@ open class RawFirBuilder(
primaryConstructor?.valueParameters?.isEmpty() ?: owner.secondaryConstructors.let { constructors ->
constructors.isEmpty() || constructors.any { it.valueParameters.isEmpty() }
}
disabledLazyMode {
toFirEnumEntry(delegatedSelfType, ownerClassHasDefaultConstructor)
}
toFirEnumEntry(delegatedSelfType, ownerClassHasDefaultConstructor)
}
is KtProperty -> {
convertProperty(
@@ -1003,7 +1001,7 @@ open class RawFirBuilder(
}
}
private fun KtEnumEntry.toFirEnumEntry(
protected fun KtEnumEntry.toFirEnumEntry(
delegatedEnumSelfTypeRef: FirResolvedTypeRef,
ownerClassHasDefaultConstructor: Boolean
): FirDeclaration {
@@ -1026,49 +1024,55 @@ open class RawFirBuilder(
return@buildEnumEntry
}
extractAnnotationsTo(this)
initializer = withChildClassName(nameAsSafeName, isExpect = false) {
buildAnonymousObjectExpression {
val enumEntrySource = toFirSourceElement(KtFakeSourceElementKind.EnumInitializer)
source = enumEntrySource
anonymousObject = buildAnonymousObject {
initializer = buildOrLazyExpression(toFirSourceElement(KtFakeSourceElementKind.EnumInitializer)) {
withChildClassName(nameAsSafeName, isExpect = false) {
buildAnonymousObjectExpression {
val enumEntrySource = toFirSourceElement(KtFakeSourceElementKind.EnumInitializer)
source = enumEntrySource
moduleData = baseModuleData
origin = FirDeclarationOrigin.Source
classKind = ClassKind.ENUM_ENTRY
scopeProvider = this@RawFirBuilder.baseScopeProvider
symbol = FirAnonymousObjectSymbol()
status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL)
anonymousObject = buildAnonymousObject {
source = enumEntrySource
moduleData = baseModuleData
origin = FirDeclarationOrigin.Source
classKind = ClassKind.ENUM_ENTRY
scopeProvider = this@RawFirBuilder.baseScopeProvider
symbol = FirAnonymousObjectSymbol()
status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL)
val delegatedEntrySelfType = buildResolvedTypeRef {
type =
ConeClassLikeTypeImpl(this@buildAnonymousObject.symbol.toLookupTag(), emptyArray(), isNullable = false)
}
registerSelfType(delegatedEntrySelfType)
val delegatedEntrySelfType = buildResolvedTypeRef {
type =
ConeClassLikeTypeImpl(
this@buildAnonymousObject.symbol.toLookupTag(),
emptyArray(),
isNullable = false
)
}
registerSelfType(delegatedEntrySelfType)
superTypeRefs += delegatedEnumSelfTypeRef
val superTypeCallEntry = superTypeListEntries.firstIsInstanceOrNull<KtSuperTypeCallEntry>()
val correctedEnumSelfTypeRef = buildResolvedTypeRef {
source = superTypeCallEntry?.calleeExpression?.typeReference?.toFirSourceElement()
type = delegatedEnumSelfTypeRef.type
}
declarations += primaryConstructor.toFirConstructor(
superTypeCallEntry,
correctedEnumSelfTypeRef,
delegatedEntrySelfType,
owner = ktEnumEntry,
typeParameters,
containingClassIsExpectClass
)
// Use ANONYMOUS_OBJECT_NAME for the owner class id for enum entry declarations (see KT-42351)
withChildClassName(SpecialNames.ANONYMOUS, forceLocalContext = true, isExpect = false) {
for (declaration in ktEnumEntry.declarations) {
declarations += declaration.toFirDeclaration(
correctedEnumSelfTypeRef,
delegatedSelfType = delegatedEntrySelfType,
ktEnumEntry,
ownerClassBuilder = this,
ownerTypeParameters = emptyList()
)
superTypeRefs += delegatedEnumSelfTypeRef
val superTypeCallEntry = superTypeListEntries.firstIsInstanceOrNull<KtSuperTypeCallEntry>()
val correctedEnumSelfTypeRef = buildResolvedTypeRef {
source = superTypeCallEntry?.calleeExpression?.typeReference?.toFirSourceElement()
type = delegatedEnumSelfTypeRef.type
}
declarations += primaryConstructor.toFirConstructor(
superTypeCallEntry,
correctedEnumSelfTypeRef,
delegatedEntrySelfType,
owner = ktEnumEntry,
typeParameters,
containingClassIsExpectClass
)
// Use ANONYMOUS_OBJECT_NAME for the owner class id for enum entry declarations (see KT-42351)
withChildClassName(SpecialNames.ANONYMOUS, forceLocalContext = true, isExpect = false) {
for (declaration in ktEnumEntry.declarations) {
declarations += declaration.toFirDeclaration(
correctedEnumSelfTypeRef,
delegatedSelfType = delegatedEntrySelfType,
ktEnumEntry,
ownerClassBuilder = this,
ownerTypeParameters = emptyList()
)
}
}
}
}
@@ -29,20 +29,8 @@ FILE: annotation.kt
super<R|kotlin/Enum<My>|>()
}
@base() public final static enum entry FIRST: R|My| = object : R|My| {
private constructor(): R|<anonymous>| {
super<R|My|>()
}
}
@base() public final static enum entry SECOND: R|My| = object : R|My| {
private constructor(): R|<anonymous>| {
super<R|My|>()
}
}
@base() public final static enum entry FIRST: R|My| = LAZY_EXPRESSION
@base() public final static enum entry SECOND: R|My| = LAZY_EXPRESSION
public final static fun values(): R|kotlin/Array<My>| {
}
@@ -13,17 +13,7 @@ FILE: constructorInObject.kt
super<R|kotlin/Enum<B>|>()
}
public final static enum entry X: R|B| = object : R|B| {
private constructor(): R|<anonymous>| {
super<R|B|>()
}
public? constructor(): R|<anonymous>| {
super<R|B|>()
}
}
public final static enum entry X: R|B| = LAZY_EXPRESSION
public final static fun values(): R|kotlin/Array<B>| {
}
@@ -28,39 +28,9 @@ FILE: enums.kt
internal final? val r: Double = R|<local>/r|
internal get(): Double
public final static enum entry MERCURY: R|Planet| = object : R|Planet| {
private constructor(): R|<anonymous>| {
super<R|Planet|>(Double(1.0), Double(2.0))
}
public? open? override fun sayHello(): R|kotlin/Unit| {
println#(String(Hello!!!))
}
}
public final static enum entry VENERA: R|Planet| = object : R|Planet| {
private constructor(): R|<anonymous>| {
super<R|Planet|>(Double(3.0), Double(4.0))
}
public? open? override fun sayHello(): R|kotlin/Unit| {
println#(String(Ola!!!))
}
}
public final static enum entry EARTH: R|Planet| = object : R|Planet| {
private constructor(): R|<anonymous>| {
super<R|Planet|>(Double(5.0), Double(6.0))
}
public? open? override fun sayHello(): R|kotlin/Unit| {
println#(String(Privet!!!))
}
}
public final static enum entry MERCURY: R|Planet| = LAZY_EXPRESSION
public final static enum entry VENERA: R|Planet| = LAZY_EXPRESSION
public final static enum entry EARTH: R|Planet| = LAZY_EXPRESSION
public? final? val g: Double = LAZY_EXPRESSION
public? get(): Double
@@ -94,55 +64,13 @@ FILE: enums.kt
public? final? val signature: String = R|<local>/signature|
public? get(): String
public final static enum entry FIX_STACK_BEFORE_JUMP: R|PseudoInsn| = object : R|PseudoInsn| {
private constructor(): R|<anonymous>| {
super<R|PseudoInsn|>()
}
}
public final static enum entry FAKE_ALWAYS_TRUE_IFEQ: R|PseudoInsn| = object : R|PseudoInsn| {
private constructor(): R|<anonymous>| {
super<R|PseudoInsn|>(String(()I))
}
}
public final static enum entry FAKE_ALWAYS_FALSE_IFEQ: R|PseudoInsn| = object : R|PseudoInsn| {
private constructor(): R|<anonymous>| {
super<R|PseudoInsn|>(String(()I))
}
}
public final static enum entry SAVE_STACK_BEFORE_TRY: R|PseudoInsn| = object : R|PseudoInsn| {
private constructor(): R|<anonymous>| {
super<R|PseudoInsn|>()
}
}
public final static enum entry RESTORE_STACK_IN_TRY_CATCH: R|PseudoInsn| = object : R|PseudoInsn| {
private constructor(): R|<anonymous>| {
super<R|PseudoInsn|>()
}
}
public final static enum entry STORE_NOT_NULL: R|PseudoInsn| = object : R|PseudoInsn| {
private constructor(): R|<anonymous>| {
super<R|PseudoInsn|>()
}
}
public final static enum entry AS_NOT_NULL: R|PseudoInsn| = object : R|PseudoInsn| {
private constructor(): R|<anonymous>| {
super<R|PseudoInsn|>(String((Ljava/lang/Object;)Ljava/lang/Object;))
}
}
public final static enum entry FIX_STACK_BEFORE_JUMP: R|PseudoInsn| = LAZY_EXPRESSION
public final static enum entry FAKE_ALWAYS_TRUE_IFEQ: R|PseudoInsn| = LAZY_EXPRESSION
public final static enum entry FAKE_ALWAYS_FALSE_IFEQ: R|PseudoInsn| = LAZY_EXPRESSION
public final static enum entry SAVE_STACK_BEFORE_TRY: R|PseudoInsn| = LAZY_EXPRESSION
public final static enum entry RESTORE_STACK_IN_TRY_CATCH: R|PseudoInsn| = LAZY_EXPRESSION
public final static enum entry STORE_NOT_NULL: R|PseudoInsn| = LAZY_EXPRESSION
public final static enum entry AS_NOT_NULL: R|PseudoInsn| = LAZY_EXPRESSION
public? final? fun emit(): R|kotlin/Unit| { LAZY_BLOCK }
public final static fun values(): R|kotlin/Array<PseudoInsn>| {
@@ -21,28 +21,8 @@ FILE: enums2.kt
public? final? val x: Some = R|<local>/x|
public? get(): Some
public final static enum entry FIRST: R|SomeEnum| = object : R|SomeEnum| {
private constructor(): R|<anonymous>| {
super<R|SomeEnum|>(O1#)
}
public? open? override fun check(y: Some): Boolean {
^check Boolean(true)
}
}
public final static enum entry SECOND: R|SomeEnum| = object : R|SomeEnum| {
private constructor(): R|<anonymous>| {
super<R|SomeEnum|>(O2#)
}
public? open? override fun check(y: Some): Boolean {
^check ==(y#, O2#)
}
}
public final static enum entry FIRST: R|SomeEnum| = LAZY_EXPRESSION
public final static enum entry SECOND: R|SomeEnum| = LAZY_EXPRESSION
public? abstract fun check(y: Some): Boolean
public final static fun values(): R|kotlin/Array<SomeEnum>| {
@@ -0,0 +1,29 @@
class C {
init {
enum class Planet(val m: Double, internal val r: Double) {
MERCURY(1.0, 2.0) {
override fun sayHello() {
println("Hello!!!")
}
},
VENERA(3.0, 4.0) {
override fun sayHello() {
println("Ola!!!")
}
},
EARTH(5.0, 6.0) {
override fun sayHello() {
println("Privet!!!")
}
};
val g: Double = G * m / (r * r)
abstract fun sayHello()
companion object {
const val G = 6.67e-11
}
}
}
}
@@ -0,0 +1,80 @@
FILE: enums3.kt
public? final? class C : R|kotlin/Any| {
public? constructor(): R|C| {
super<R|kotlin/Any|>()
}
init {
local final? enum class Planet : R|kotlin/Enum<C.Planet>| {
private constructor(m: Double, r: Double): R|C.Planet| {
super<R|kotlin/Enum<C.Planet>|>()
}
public? final? val m: Double = R|<local>/m|
public? get(): Double
internal final? val r: Double = R|<local>/r|
internal get(): Double
public final static enum entry MERCURY: R|C.Planet| = object : R|C.Planet| {
private constructor(): R|<anonymous>| {
super<R|C.Planet|>(Double(1.0), Double(2.0))
}
public? open? override fun sayHello(): R|kotlin/Unit| {
println#(String(Hello!!!))
}
}
public final static enum entry VENERA: R|C.Planet| = object : R|C.Planet| {
private constructor(): R|<anonymous>| {
super<R|C.Planet|>(Double(3.0), Double(4.0))
}
public? open? override fun sayHello(): R|kotlin/Unit| {
println#(String(Ola!!!))
}
}
public final static enum entry EARTH: R|C.Planet| = object : R|C.Planet| {
private constructor(): R|<anonymous>| {
super<R|C.Planet|>(Double(5.0), Double(6.0))
}
public? open? override fun sayHello(): R|kotlin/Unit| {
println#(String(Privet!!!))
}
}
public? final? val g: Double = G#.times#(m#).div#(r#.times#(r#))
public? get(): Double
public? abstract fun sayHello(): R|kotlin/Unit|
local final? companion object Companion : R|kotlin/Any| {
private constructor(): R|C.Planet.Companion| {
super<R|kotlin/Any|>()
}
public? final? const val G: <implicit> = Double(6.67E-11)
public? get(): <implicit>
}
public final static fun values(): R|kotlin/Array<C.Planet>| {
}
public final static fun valueOf(value: R|kotlin/String|): R|C.Planet| {
}
public final static val entries: R|kotlin/enums/EnumEntries<C.Planet>|
public get(): R|kotlin/enums/EnumEntries<C.Planet>|
}
}
}
@@ -0,0 +1,80 @@
FILE: enums3.kt
public? final? class C : R|kotlin/Any| {
public? [ContainingClassKey=C] constructor(): R|C| {
super<R|kotlin/Any|>()
}
init {
local final? [ContainingClassKey=C] enum class Planet : R|kotlin/Enum<C.Planet>| {
private [ContainingClassKey=Planet] constructor([CorrespondingProperty=<local>/m] m: Double, [CorrespondingProperty=<local>/r] r: Double): R|C.Planet| {
super<R|kotlin/Enum<C.Planet>|>()
}
public? final? [IsFromPrimaryConstructor=true] val m: Double = R|<local>/m|
public? [ContainingClassKey=Planet] get(): Double
internal final? [IsFromPrimaryConstructor=true] val r: Double = R|<local>/r|
internal [ContainingClassKey=Planet] get(): Double
public final static [ContainingClassKey=Planet] enum entry MERCURY: R|C.Planet| = object : R|C.Planet| {
private [ContainingClassKey=<anonymous>] constructor(): R|<anonymous>| {
super<R|C.Planet|>(Double(1.0), Double(2.0))
}
public? open? override fun sayHello(): R|kotlin/Unit| {
println#(String(Hello!!!))
}
}
public final static [ContainingClassKey=Planet] enum entry VENERA: R|C.Planet| = object : R|C.Planet| {
private [ContainingClassKey=<anonymous>] constructor(): R|<anonymous>| {
super<R|C.Planet|>(Double(3.0), Double(4.0))
}
public? open? override fun sayHello(): R|kotlin/Unit| {
println#(String(Ola!!!))
}
}
public final static [ContainingClassKey=Planet] enum entry EARTH: R|C.Planet| = object : R|C.Planet| {
private [ContainingClassKey=<anonymous>] constructor(): R|<anonymous>| {
super<R|C.Planet|>(Double(5.0), Double(6.0))
}
public? open? override fun sayHello(): R|kotlin/Unit| {
println#(String(Privet!!!))
}
}
public? final? val g: Double = G#.times#(m#).div#(r#.times#(r#))
public? [ContainingClassKey=Planet] get(): Double
public? abstract fun sayHello(): R|kotlin/Unit|
local final? companion [ContainingClassKey=Planet] object Companion : R|kotlin/Any| {
private [ContainingClassKey=Companion] constructor(): R|C.Planet.Companion| {
super<R|kotlin/Any|>()
}
public? final? const val G: <implicit> = Double(6.67E-11)
public? [ContainingClassKey=Companion] get(): <implicit>
}
public final static [ContainingClassKey=Planet] fun values(): R|kotlin/Array<C.Planet>| {
}
public final static [ContainingClassKey=Planet] fun valueOf(value: R|kotlin/String|): R|C.Planet| {
}
public final static [ContainingClassKey=Planet] val entries: R|kotlin/enums/EnumEntries<C.Planet>|
public get(): R|kotlin/enums/EnumEntries<C.Planet>|
}
}
}
@@ -101,6 +101,11 @@ public class RawFirBuilderLazyBodiesTestCaseGenerated extends AbstractRawFirBuil
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums2.kt");
}
@TestMetadata("enums3.kt")
public void testEnums3() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums3.kt");
}
@TestMetadata("expectActual.kt")
public void testExpectActual() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/expectActual.kt");
@@ -101,6 +101,11 @@ public class RawFirBuilderTestCaseGenerated extends AbstractRawFirBuilderTestCas
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums2.kt");
}
@TestMetadata("enums3.kt")
public void testEnums3() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums3.kt");
}
@TestMetadata("expectActual.kt")
public void testExpectActual() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/expectActual.kt");
@@ -105,6 +105,12 @@ public class FirVisualizerForRawFirDataGenerated extends AbstractFirVisualizerTe
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums2.kt");
}
@Test
@TestMetadata("enums3.kt")
public void testEnums3() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums3.kt");
}
@Test
@TestMetadata("expectActual.kt")
public void testExpectActual() throws Exception {
@@ -105,6 +105,12 @@ public class PsiVisualizerForRawFirDataGenerated extends AbstractPsiVisualizerTe
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums2.kt");
}
@Test
@TestMetadata("enums3.kt")
public void testEnums3() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums3.kt");
}
@Test
@TestMetadata("expectActual.kt")
public void testExpectActual() throws Exception {