Use 'DefaultImpls' as owner for interface local delegated properties

#KT-19690 Fixed
This commit is contained in:
Mikhael Bogdanov
2017-08-16 16:35:31 +02:00
parent 905b8cc4e9
commit 97d46e76f5
7 changed files with 59 additions and 11 deletions
@@ -22,20 +22,14 @@ import org.jetbrains.kotlin.backend.common.bridges.firstSuperMethodFromKotlin
import org.jetbrains.kotlin.codegen.context.ClassContext import org.jetbrains.kotlin.codegen.context.ClassContext
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtPureClassOrObject import org.jetbrains.kotlin.psi.KtPureClassOrObject
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.org.objectweb.asm.MethodVisitor import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.Opcodes.* import org.jetbrains.org.objectweb.asm.Opcodes.*
import java.util.*
class InterfaceImplBodyCodegen( class InterfaceImplBodyCodegen(
aClass: KtPureClassOrObject, aClass: KtPureClassOrObject,
@@ -47,12 +41,14 @@ class InterfaceImplBodyCodegen(
private var isAnythingGenerated: Boolean = false private var isAnythingGenerated: Boolean = false
get() = (v as InterfaceImplClassBuilder).isAnythingGenerated get() = (v as InterfaceImplClassBuilder).isAnythingGenerated
private val defaultImplType = typeMapper.mapDefaultImpls(descriptor)
override fun generateDeclaration() { override fun generateDeclaration() {
val codegenFlags = ACC_PUBLIC or ACC_FINAL or ACC_SUPER val codegenFlags = ACC_PUBLIC or ACC_FINAL or ACC_SUPER
val flags = if (state.classBuilderMode == ClassBuilderMode.LIGHT_CLASSES) codegenFlags or ACC_STATIC else codegenFlags val flags = if (state.classBuilderMode == ClassBuilderMode.LIGHT_CLASSES) codegenFlags or ACC_STATIC else codegenFlags
v.defineClass( v.defineClass(
myClass.psiOrParent, state.classFileVersion, flags, myClass.psiOrParent, state.classFileVersion, flags,
typeMapper.mapDefaultImpls(descriptor).internalName, defaultImplType.internalName,
null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY
) )
v.visitSource(myClass.containingKtFile.name, null) v.visitSource(myClass.containingKtFile.name, null)
@@ -154,7 +150,7 @@ class InterfaceImplBodyCodegen(
override fun done() { override fun done() {
super.done() super.done()
if (!isAnythingGenerated) { if (!isAnythingGenerated) {
state.factory.removeClasses(setOf(typeMapper.mapDefaultImpls(descriptor).internalName)) state.factory.removeClasses(setOf(defaultImplType.internalName))
} }
} }
@@ -183,4 +179,8 @@ class InterfaceImplBodyCodegen(
return super.newMethod(origin, access, name, desc, signature, exceptions) return super.newMethod(origin, access, name, desc, signature, exceptions)
} }
} }
override fun generateSyntheticPartsBeforeBody() {
generatePropertyMetadataArrayFieldIfNeeded(defaultImplType)
}
} }
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor; import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
import org.jetbrains.kotlin.fileClasses.FileClasses; import org.jetbrains.kotlin.fileClasses.FileClasses;
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider; import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor; import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor;
import org.jetbrains.kotlin.load.kotlin.TypeMappingConfiguration; import org.jetbrains.kotlin.load.kotlin.TypeMappingConfiguration;
import org.jetbrains.kotlin.name.ClassId; import org.jetbrains.kotlin.name.ClassId;
@@ -440,9 +441,15 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
// The first "real" containing class (not a synthetic class for lambda) is the owner of the delegated property metadata // The first "real" containing class (not a synthetic class for lambda) is the owner of the delegated property metadata
if (!(descriptor instanceof SyntheticClassDescriptorForLambda)) { if (!(descriptor instanceof SyntheticClassDescriptorForLambda)) {
ClassId classId = DescriptorUtilsKt.getClassId(descriptor); ClassId classId = DescriptorUtilsKt.getClassId(descriptor);
return classId != null if (classId == null) {
? AsmUtil.asmTypeByClassId(classId) return CodegenBinding.getAsmType(bindingContext, descriptor);
: CodegenBinding.getAsmType(bindingContext, descriptor); }
return AsmUtil.asmTypeByClassId(
DescriptorUtils.isInterface(descriptor)
? classId.createNestedClassId(Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME))
: classId
);
} }
} }
@@ -0,0 +1,17 @@
//WITH_REFLECT
import kotlin.properties.Delegates
interface MyInterface {
fun something(): String {
var foo: String by Delegates.notNull();
foo = "OK"
return foo
}
}
fun box(): String {
return object : MyInterface {
}.something()
}
@@ -7012,6 +7012,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
doTest(fileName); doTest(fileName);
} }
@TestMetadata("kt19690.kt")
public void testKt19690() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/local/kt19690.kt");
doTest(fileName);
}
@TestMetadata("localVal.kt") @TestMetadata("localVal.kt")
public void testLocalVal() throws Exception { public void testLocalVal() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/local/localVal.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/local/localVal.kt");
@@ -7012,6 +7012,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("kt19690.kt")
public void testKt19690() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/local/kt19690.kt");
doTest(fileName);
}
@TestMetadata("localVal.kt") @TestMetadata("localVal.kt")
public void testLocalVal() throws Exception { public void testLocalVal() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/local/localVal.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/local/localVal.kt");
@@ -7012,6 +7012,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
doTest(fileName); doTest(fileName);
} }
@TestMetadata("kt19690.kt")
public void testKt19690() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/local/kt19690.kt");
doTest(fileName);
}
@TestMetadata("localVal.kt") @TestMetadata("localVal.kt")
public void testLocalVal() throws Exception { public void testLocalVal() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/local/localVal.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/local/localVal.kt");
@@ -7798,6 +7798,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("kt19690.kt")
public void testKt19690() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/local/kt19690.kt");
doTest(fileName);
}
@TestMetadata("localVal.kt") @TestMetadata("localVal.kt")
public void testLocalVal() throws Exception { public void testLocalVal() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/local/localVal.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/local/localVal.kt");