Cast arguments to proper types when generating delegates

Also minor refactoring in a couple places to adopt this style
This commit is contained in:
Alexander Udalov
2012-10-26 18:09:13 +04:00
parent 4cfe68da1e
commit 288e3a7b40
6 changed files with 62 additions and 26 deletions
@@ -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");