Cast arguments to proper types when generating delegates
Also minor refactoring in a couple places to adopt this style
This commit is contained in:
@@ -57,7 +57,6 @@ import static org.jetbrains.jet.codegen.CodegenUtil.*;
|
||||
import static org.jetbrains.jet.codegen.binding.CodegenBinding.isLocalFun;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.callableDescriptorToDeclaration;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration;
|
||||
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.JAVA_ARRAY_GENERIC_TYPE;
|
||||
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
||||
|
||||
/**
|
||||
@@ -772,20 +771,13 @@ public class FunctionCodegen extends GenerationStateAware {
|
||||
|
||||
Type[] argTypes = overridden.getArgumentTypes();
|
||||
Type[] originalArgTypes = jvmSignature.getArgumentTypes();
|
||||
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
iv.load(0, OBJECT_TYPE);
|
||||
for (int i = 0, reg = 1; i < argTypes.length; i++) {
|
||||
Type argType = argTypes[i];
|
||||
iv.load(reg, argType);
|
||||
if (argType.getSort() == Type.OBJECT) {
|
||||
StackValue.onStack(OBJECT_TYPE).put(originalArgTypes[i], iv);
|
||||
}
|
||||
else if (argType.getSort() == Type.ARRAY) {
|
||||
StackValue.onStack(JAVA_ARRAY_GENERIC_TYPE).put(originalArgTypes[i], iv);
|
||||
}
|
||||
|
||||
StackValue.local(reg, argTypes[i]).put(originalArgTypes[i], iv);
|
||||
//noinspection AssignmentToForLoopParameter
|
||||
reg += argType.getSize();
|
||||
reg += argTypes[i].getSize();
|
||||
}
|
||||
|
||||
iv.invokevirtual(state.getTypeMapper().mapType(
|
||||
@@ -828,22 +820,16 @@ public class FunctionCodegen extends GenerationStateAware {
|
||||
else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||
mv.visitCode();
|
||||
|
||||
Type[] argTypes = overriddenMethod.getArgumentTypes();
|
||||
Type[] argTypes = delegateMethod.getArgumentTypes();
|
||||
Type[] originalArgTypes = overriddenMethod.getArgumentTypes();
|
||||
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
iv.load(0, OBJECT_TYPE);
|
||||
field.put(field.type, iv);
|
||||
for (int i = 0, reg = 1; i < argTypes.length; i++) {
|
||||
Type argType = argTypes[i];
|
||||
iv.load(reg, argType);
|
||||
if (argType.getSort() == Type.OBJECT) {
|
||||
StackValue.onStack(OBJECT_TYPE).put(overriddenMethod.getArgumentTypes()[i], iv);
|
||||
}
|
||||
else if (argType.getSort() == Type.ARRAY) {
|
||||
StackValue.onStack(JAVA_ARRAY_GENERIC_TYPE).put(overriddenMethod.getArgumentTypes()[i], iv);
|
||||
}
|
||||
|
||||
StackValue.local(reg, argTypes[i]).put(originalArgTypes[i], iv);
|
||||
//noinspection AssignmentToForLoopParameter
|
||||
reg += argType.getSize();
|
||||
reg += argTypes[i].getSize();
|
||||
}
|
||||
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) overriddenDescriptor.getContainingDeclaration();
|
||||
|
||||
@@ -1273,14 +1273,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
Type[] argTypes = function.getArgumentTypes();
|
||||
List<Type> originalArgTypes = jvmSignature.getValueParameterTypes();
|
||||
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
iv.load(0, OBJECT_TYPE);
|
||||
for (int i = 0, reg = 1; i < argTypes.length; i++) {
|
||||
Type argType = argTypes[i];
|
||||
iv.load(reg, argType);
|
||||
StackValue.coerce(argType, originalArgTypes.get(i), iv);
|
||||
StackValue.local(reg, argTypes[i]).put(originalArgTypes.get(i), iv);
|
||||
//noinspection AssignmentToForLoopParameter
|
||||
reg += argType.getSize();
|
||||
reg += argTypes[i].getSize();
|
||||
}
|
||||
|
||||
JetType jetType = CodegenUtil.getSuperClass(declaration);
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
trait A<T> {
|
||||
fun foo(t: T): String
|
||||
}
|
||||
|
||||
class Derived(a: A<Int>) : A<Int> by a
|
||||
|
||||
fun box(): String {
|
||||
val o = object : A<Int> {
|
||||
override fun foo(t: Int) = if (t == 42) "OK" else "Fail $t"
|
||||
}
|
||||
return Derived(o).foo(42)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
trait A<T: Number> {
|
||||
fun foo(t: T): String
|
||||
}
|
||||
|
||||
class Derived(a: A<Int>) : A<Int> by a
|
||||
|
||||
fun box(): String {
|
||||
val o = object : A<Int> {
|
||||
override fun foo(t: Int) = if (t == 42) "OK" else "Fail $t"
|
||||
}
|
||||
return Derived(o).foo(42)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
trait A<T, U> {
|
||||
fun foo(t: T, u: U): String
|
||||
}
|
||||
|
||||
class Derived(a: A<Long, Int>) : A<Long, Int> by a
|
||||
|
||||
fun box(): String {
|
||||
val o = object : A<Long, Int> {
|
||||
override fun foo(t: Long, u: Int) = if (t == u.toLong()) "OK" else "Fail $t $u"
|
||||
}
|
||||
return Derived(o).foo(42, 42)
|
||||
}
|
||||
@@ -120,6 +120,21 @@ public class ClassGenTest extends CodegenTestCase {
|
||||
blackBoxFile("classes/delegationMethodsWithArgs.kt");
|
||||
}
|
||||
|
||||
public void testDelegationGenericArg() {
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||
blackBoxFile("classes/delegationGenericArg.kt");
|
||||
}
|
||||
|
||||
public void testDelegationGenericLongArg() {
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||
blackBoxFile("classes/delegationGenericLongArg.kt");
|
||||
}
|
||||
|
||||
public void testDelegationGenericArgUpperBound() {
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||
blackBoxFile("classes/delegationGenericArgUpperBound.kt");
|
||||
}
|
||||
|
||||
public void testFunDelegation() throws Exception {
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||
blackBoxFile("classes/funDelegation.jet");
|
||||
|
||||
Reference in New Issue
Block a user