Support properties in compatibility mode

This commit is contained in:
Mikhael Bogdanov
2018-05-29 14:36:30 +02:00
parent 0498c3b765
commit ad717d5335
7 changed files with 188 additions and 0 deletions
@@ -757,6 +757,23 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
@Override
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
if (accessorForCallableDescriptor.getAccessorKind() == AccessorKind.JVM_DEFAULT_COMPATIBILITY) {
markLineNumberForElement(element.getPsiOrParent(), codegen.v);
PropertyDescriptor descriptor = unwrapFakeOverrideToAnyDeclaration(original).getOriginal();
if (descriptor != original) {
descriptor = (PropertyDescriptor) descriptor
.copy(original.getContainingDeclaration(), descriptor.getModality(), descriptor.getVisibility(),
descriptor.getKind(), false);
}
boolean isGetter = callableDescriptor instanceof PropertyGetterDescriptor;
PropertyAccessorDescriptor originalAccessor = isGetter ? descriptor.getGetter(): descriptor.getSetter();
PropertyAccessorDescriptor accessorDescriptor = isGetter ? accessor.getGetter() : accessor.getSetter();
generateMethodCallTo(originalAccessor, accessorDescriptor, codegen.v)
.coerceTo(signature.getReturnType(), null, codegen.v);
codegen.v.areturn(signature.getReturnType());
return;
}
AccessorKind fieldAccessorKind = accessor instanceof AccessorForPropertyBackingField
? accessor.getAccessorKind() : null;
boolean syntheticBackingField = fieldAccessorKind == AccessorKind.FIELD_FROM_LOCAL;
@@ -0,0 +1,43 @@
// !API_VERSION: 1.3
// !JVM_DEFAULT_MODE: compatibility
// FILE: Simple.java
public interface Simple extends KInterface2 {
default String test() {
return KInterface2.DefaultImpls.getBar(this);
}
}
// FILE: Foo.java
public class Foo implements Simple {
}
// FILE: main.kt
// JVM_TARGET: 1.8
// WITH_RUNTIME
interface KInterface<T> {
val foo: T
@JvmDefault
val bar: T
get() = foo
}
interface KInterface2 : KInterface<String> {
@JvmDefault
override val foo: String
get() = "OK"
}
fun box(): String {
val result = Foo().test()
if (result != "OK") return "fail 1: ${result}"
return Foo().bar
}
@@ -0,0 +1,40 @@
// !API_VERSION: 1.3
// !JVM_DEFAULT_MODE: compatibility
// FILE: Simple.java
public interface Simple extends KInterface2 {
default String test() {
return KInterface2.DefaultImpls.getBar(this);
}
}
// FILE: Foo.java
public class Foo implements Simple {
public String getBar() {
return "fail";
}
}
// FILE: main.kt
// JVM_TARGET: 1.8
// WITH_RUNTIME
interface KInterface<T> {
val foo: T
@JvmDefault
val bar: T
get() = foo
}
interface KInterface2 : KInterface<String> {
@JvmDefault
override val foo: String
get() = "OK"
}
fun box(): String {
return Foo().test()
}
@@ -0,0 +1,42 @@
// !API_VERSION: 1.3
// !JVM_DEFAULT_MODE: compatibility
// FILE: Simple.java
public interface Simple extends KInterface3 {
default String test() {
return KInterface3.DefaultImpls.getBar(this);
}
}
// FILE: Foo.java
public class Foo implements Simple {
}
// FILE: main.kt
// JVM_TARGET: 1.8
// WITH_RUNTIME
interface KInterface<T> {
val foo: T
@JvmDefault
val bar: T
get() = foo
}
interface KInterface2 : KInterface<String> {
@JvmDefault
override val foo: String
get() = "OK"
}
interface KInterface3 : KInterface2 {
}
fun box(): String {
return Foo().test()
}
@@ -0,0 +1,26 @@
// !API_VERSION: 1.3
// !JVM_DEFAULT_MODE: compatibility
// JVM_TARGET: 1.8
// WITH_RUNTIME
interface KInterface {
@JvmDefault
var bar: String
get() = "OK"
set(field) {}
}
interface KInterface2 : KInterface {
}
// 1 INVOKESTATIC KInterface2.access\$getBar\$jd
// 1 INVOKESTATIC KInterface2.access\$setBar\$jd
// 1 INVOKESTATIC KInterface.access\$getBar\$jd
// 1 INVOKESTATIC KInterface.access\$setBar\$jd
// 1 INVOKESPECIAL KInterface2.getBar
// 1 INVOKESPECIAL KInterface2.setBar
// 1 INVOKESPECIAL KInterface.getBar
// 1 INVOKESPECIAL KInterface.setBar
@@ -508,6 +508,21 @@ public class BlackBoxWithJava8CodegenTestGenerated extends AbstractBlackBoxCodeg
runTest("compiler/testData/codegen/java8/box/jvm8/defaults/compatibility/bridge3.kt");
}
@TestMetadata("bridgeWithProperties.kt")
public void testBridgeWithProperties() throws Exception {
runTest("compiler/testData/codegen/java8/box/jvm8/defaults/compatibility/bridgeWithProperties.kt");
}
@TestMetadata("bridgeWithProperties2.kt")
public void testBridgeWithProperties2() throws Exception {
runTest("compiler/testData/codegen/java8/box/jvm8/defaults/compatibility/bridgeWithProperties2.kt");
}
@TestMetadata("bridgeWithProperties3.kt")
public void testBridgeWithProperties3() throws Exception {
runTest("compiler/testData/codegen/java8/box/jvm8/defaults/compatibility/bridgeWithProperties3.kt");
}
@TestMetadata("defaultArgs.kt")
public void testDefaultArgs() throws Exception {
runTest("compiler/testData/codegen/java8/box/jvm8/defaults/compatibility/defaultArgs.kt");
@@ -90,6 +90,11 @@ public class BytecodeTextJava8TestGenerated extends AbstractBytecodeTextTest {
public void testSimpleFunctionWithAbstractOverride() throws Exception {
runTest("compiler/testData/codegen/java8/bytecodeText/jvmDefault/compatibility/simpleFunctionWithAbstractOverride.kt");
}
@TestMetadata("simpleProperty.kt")
public void testSimpleProperty() throws Exception {
runTest("compiler/testData/codegen/java8/bytecodeText/jvmDefault/compatibility/simpleProperty.kt");
}
}
}
}