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.codegen.binding.CodegenBinding.isLocalFun;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.callableDescriptorToDeclaration; 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.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; 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[] argTypes = overridden.getArgumentTypes();
Type[] originalArgTypes = jvmSignature.getArgumentTypes(); Type[] originalArgTypes = jvmSignature.getArgumentTypes();
InstructionAdapter iv = new InstructionAdapter(mv); InstructionAdapter iv = new InstructionAdapter(mv);
iv.load(0, OBJECT_TYPE); iv.load(0, OBJECT_TYPE);
for (int i = 0, reg = 1; i < argTypes.length; i++) { for (int i = 0, reg = 1; i < argTypes.length; i++) {
Type argType = argTypes[i]; StackValue.local(reg, argTypes[i]).put(originalArgTypes[i], iv);
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);
}
//noinspection AssignmentToForLoopParameter //noinspection AssignmentToForLoopParameter
reg += argType.getSize(); reg += argTypes[i].getSize();
} }
iv.invokevirtual(state.getTypeMapper().mapType( iv.invokevirtual(state.getTypeMapper().mapType(
@@ -828,22 +820,16 @@ public class FunctionCodegen extends GenerationStateAware {
else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
mv.visitCode(); mv.visitCode();
Type[] argTypes = overriddenMethod.getArgumentTypes(); Type[] argTypes = delegateMethod.getArgumentTypes();
Type[] originalArgTypes = overriddenMethod.getArgumentTypes();
InstructionAdapter iv = new InstructionAdapter(mv); InstructionAdapter iv = new InstructionAdapter(mv);
iv.load(0, OBJECT_TYPE); iv.load(0, OBJECT_TYPE);
field.put(field.type, iv); field.put(field.type, iv);
for (int i = 0, reg = 1; i < argTypes.length; i++) { for (int i = 0, reg = 1; i < argTypes.length; i++) {
Type argType = argTypes[i]; StackValue.local(reg, argTypes[i]).put(originalArgTypes[i], iv);
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);
}
//noinspection AssignmentToForLoopParameter //noinspection AssignmentToForLoopParameter
reg += argType.getSize(); reg += argTypes[i].getSize();
} }
ClassDescriptor classDescriptor = (ClassDescriptor) overriddenDescriptor.getContainingDeclaration(); ClassDescriptor classDescriptor = (ClassDescriptor) overriddenDescriptor.getContainingDeclaration();
@@ -1273,14 +1273,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
Type[] argTypes = function.getArgumentTypes(); Type[] argTypes = function.getArgumentTypes();
List<Type> originalArgTypes = jvmSignature.getValueParameterTypes(); List<Type> originalArgTypes = jvmSignature.getValueParameterTypes();
InstructionAdapter iv = new InstructionAdapter(mv); InstructionAdapter iv = new InstructionAdapter(mv);
iv.load(0, OBJECT_TYPE); iv.load(0, OBJECT_TYPE);
for (int i = 0, reg = 1; i < argTypes.length; i++) { for (int i = 0, reg = 1; i < argTypes.length; i++) {
Type argType = argTypes[i]; StackValue.local(reg, argTypes[i]).put(originalArgTypes.get(i), iv);
iv.load(reg, argType);
StackValue.coerce(argType, originalArgTypes.get(i), iv);
//noinspection AssignmentToForLoopParameter //noinspection AssignmentToForLoopParameter
reg += argType.getSize(); reg += argTypes[i].getSize();
} }
JetType jetType = CodegenUtil.getSuperClass(declaration); 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"); 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 { public void testFunDelegation() throws Exception {
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
blackBoxFile("classes/funDelegation.jet"); blackBoxFile("classes/funDelegation.jet");