Initialize property metadata array before class body generation
Initialization of companion object members (e.g., delegate properties using provideDelegate convention) can depend on property metadata array, which in turn can be initialized before other class members. #KT-18902 Fixed Target versions 1.1.5
This commit is contained in:
@@ -348,9 +348,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateSyntheticParts() {
|
||||
protected void generateSyntheticPartsBeforeBody() {
|
||||
generatePropertyMetadataArrayFieldIfNeeded(classAsmType);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateSyntheticPartsAfterBody() {
|
||||
generateFieldForSingleton();
|
||||
|
||||
generateCompanionObjectBackingFieldCopies();
|
||||
|
||||
@@ -70,7 +70,7 @@ class InterfaceImplBodyCodegen(
|
||||
return classDescriptorImpl
|
||||
}
|
||||
|
||||
override fun generateSyntheticParts() {
|
||||
override fun generateSyntheticPartsAfterBody() {
|
||||
for (memberDescriptor in descriptor.defaultType.memberScope.getContributedDescriptors()) {
|
||||
if (memberDescriptor !is CallableMemberDescriptor) continue
|
||||
|
||||
|
||||
@@ -131,11 +131,18 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
public void generate() {
|
||||
generateDeclaration();
|
||||
|
||||
boolean shouldGenerateSyntheticParts =
|
||||
!(element instanceof KtClassOrObject) ||
|
||||
state.getGenerateDeclaredClassFilter().shouldGenerateClassMembers((KtClassOrObject) element);
|
||||
|
||||
if (shouldGenerateSyntheticParts) {
|
||||
generateSyntheticPartsBeforeBody();
|
||||
}
|
||||
|
||||
generateBody();
|
||||
|
||||
if (!(element instanceof KtClassOrObject) ||
|
||||
state.getGenerateDeclaredClassFilter().shouldGenerateClassMembers((KtClassOrObject) element)) {
|
||||
generateSyntheticParts();
|
||||
if (shouldGenerateSyntheticParts) {
|
||||
generateSyntheticPartsAfterBody();
|
||||
}
|
||||
|
||||
if (state.getClassBuilderMode().generateMetadata) {
|
||||
@@ -147,9 +154,12 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
|
||||
protected abstract void generateDeclaration();
|
||||
|
||||
protected void generateSyntheticPartsBeforeBody() {
|
||||
}
|
||||
|
||||
protected abstract void generateBody();
|
||||
|
||||
protected void generateSyntheticParts() {
|
||||
protected void generateSyntheticPartsAfterBody() {
|
||||
}
|
||||
|
||||
protected abstract void generateKotlinMetadataAnnotation();
|
||||
|
||||
@@ -186,7 +186,7 @@ class MultifileClassPartCodegen(
|
||||
}
|
||||
}
|
||||
|
||||
override fun generateSyntheticParts() {
|
||||
override fun generateSyntheticPartsAfterBody() {
|
||||
generateSyntheticAccessors()
|
||||
}
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateSyntheticParts() {
|
||||
protected void generateSyntheticPartsAfterBody() {
|
||||
generateSyntheticAccessors();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,10 +105,14 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateSyntheticParts() {
|
||||
protected void generateSyntheticPartsBeforeBody() {
|
||||
generatePropertyMetadataArrayFieldIfNeeded(classAsmType);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateSyntheticPartsAfterBody() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateKotlinMetadataAnnotation() {
|
||||
generateKotlinClassMetadataAnnotation(scriptDescriptor, true);
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class Delegate: ReadOnlyProperty<Test, String> {
|
||||
override fun getValue(thisRef: Test, property: KProperty<*>) = "OK"
|
||||
}
|
||||
|
||||
class Provider {
|
||||
operator fun provideDelegate(thisRef: Test, property: KProperty<*>) = Delegate()
|
||||
}
|
||||
|
||||
class Test {
|
||||
companion object {
|
||||
val instance = Test()
|
||||
}
|
||||
|
||||
val message by Provider()
|
||||
}
|
||||
|
||||
fun box() = Test.instance.message
|
||||
@@ -0,0 +1,21 @@
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class Delegate {
|
||||
operator fun getValue(thisRef: Test, property: KProperty<*>) = "OK"
|
||||
}
|
||||
|
||||
class Provider {
|
||||
operator fun provideDelegate(thisRef: Test, property: KProperty<*>) = Delegate()
|
||||
}
|
||||
|
||||
class Test {
|
||||
companion object {
|
||||
val instance = Test()
|
||||
}
|
||||
|
||||
val message by Provider()
|
||||
}
|
||||
|
||||
val x = Test.instance.message
|
||||
|
||||
// expected: x: OK
|
||||
+6
@@ -7030,6 +7030,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt18902.kt")
|
||||
public void testKt18902() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/provideDelegate/kt18902.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("local.kt")
|
||||
public void testLocal() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/provideDelegate/local.kt");
|
||||
|
||||
@@ -7030,6 +7030,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt18902.kt")
|
||||
public void testKt18902() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/provideDelegate/kt18902.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("local.kt")
|
||||
public void testLocal() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/provideDelegate/local.kt");
|
||||
|
||||
@@ -7030,6 +7030,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt18902.kt")
|
||||
public void testKt18902() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/provideDelegate/kt18902.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("local.kt")
|
||||
public void testLocal() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/provideDelegate/local.kt");
|
||||
|
||||
@@ -186,6 +186,12 @@ public class ScriptCodegenTestGenerated extends AbstractScriptCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelPropertyWithProvideDelegate.kts")
|
||||
public void testTopLevelPropertyWithProvideDelegate() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/script/topLevelPropertyWithProvideDelegate.kts");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelTypealias.kts")
|
||||
public void testTopLevelTypealias() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/script/topLevelTypealias.kts");
|
||||
|
||||
@@ -7810,6 +7810,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt18902.kt")
|
||||
public void testKt18902() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/provideDelegate/kt18902.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("local.kt")
|
||||
public void testLocal() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/provideDelegate/local.kt");
|
||||
|
||||
Reference in New Issue
Block a user