KT-2987 java.lang.AbstractMethodError/java.lang.NoSuchMethodError for delegated class by parameterized parent

#KT-2987 Fixed
This commit is contained in:
Sergey Mashkov
2012-10-24 18:29:31 +04:00
committed by Alexander Udalov
parent c843d23416
commit edb8797fa6
4 changed files with 61 additions and 17 deletions
@@ -803,28 +803,32 @@ public class FunctionCodegen extends GenerationStateAware {
}
public void genDelegate(FunctionDescriptor functionDescriptor, CallableMemberDescriptor overriddenDescriptor, StackValue field) {
JvmMethodSignature jvmMethodSignature =
state.getTypeMapper().mapSignature(functionDescriptor.getName(), functionDescriptor);
genDelegate(functionDescriptor, overriddenDescriptor, field, jvmMethodSignature);
genDelegate(functionDescriptor, overriddenDescriptor, field,
typeMapper.mapSignature(functionDescriptor.getName(), functionDescriptor),
typeMapper.mapSignature(overriddenDescriptor.getName(), (FunctionDescriptor) overriddenDescriptor.getOriginal())
);
}
public void genDelegate(
CallableMemberDescriptor functionDescriptor,
CallableMemberDescriptor overriddenDescriptor,
StackValue field,
JvmMethodSignature jvmMethodSignature
JvmMethodSignature jvmDelegateMethodSignature,
JvmMethodSignature jvmOverriddenMethodSignature
) {
Method method = jvmMethodSignature.getAsmMethod();
Method overriddenMethod = jvmOverriddenMethodSignature.getAsmMethod();
Method delegateMethod = jvmDelegateMethodSignature.getAsmMethod();
int flags = ACC_PUBLIC | ACC_SYNTHETIC; // TODO.
final MethodVisitor mv = v.newMethod(null, flags, method.getName(), method.getDescriptor(), null, null);
final MethodVisitor mv = v.newMethod(null, flags, delegateMethod.getName(), delegateMethod.getDescriptor(), null, null);
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
genStubCode(mv);
}
else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
mv.visitCode();
Type[] argTypes = method.getArgumentTypes();
Type[] argTypes = overriddenMethod.getArgumentTypes();
InstructionAdapter iv = new InstructionAdapter(mv);
iv.load(0, OBJECT_TYPE);
field.put(field.type, iv);
@@ -832,10 +836,10 @@ public class FunctionCodegen extends GenerationStateAware {
Type argType = argTypes[i];
iv.load(reg, argType);
if (argType.getSort() == Type.OBJECT) {
StackValue.onStack(OBJECT_TYPE).put(method.getArgumentTypes()[i], iv);
StackValue.onStack(OBJECT_TYPE).put(overriddenMethod.getArgumentTypes()[i], iv);
}
else if (argType.getSort() == Type.ARRAY) {
StackValue.onStack(JAVA_ARRAY_GENERIC_TYPE).put(method.getArgumentTypes()[i], iv);
StackValue.onStack(JAVA_ARRAY_GENERIC_TYPE).put(overriddenMethod.getArgumentTypes()[i], iv);
}
//noinspection AssignmentToForLoopParameter
@@ -846,12 +850,15 @@ public class FunctionCodegen extends GenerationStateAware {
String internalName =
state.getTypeMapper().mapType(classDescriptor).getInternalName();
if (classDescriptor.getKind() == ClassKind.TRAIT) {
iv.invokeinterface(internalName, method.getName(), method.getDescriptor());
iv.invokeinterface(internalName, overriddenMethod.getName(), overriddenMethod.getDescriptor());
}
else {
iv.invokevirtual(internalName, method.getName(), method.getDescriptor());
iv.invokevirtual(internalName, overriddenMethod.getName(), overriddenMethod.getDescriptor());
}
iv.areturn(method.getReturnType());
StackValue.onStack(overriddenMethod.getReturnType()).put(delegateMethod.getReturnType(), iv);
iv.areturn(delegateMethod.getReturnType());
endVisit(mv, "delegate method", descriptorToDeclaration(bindingContext, functionDescriptor));
}
}
@@ -342,13 +342,14 @@ public class PropertyCodegen extends GenerationStateAware {
}
public void genDelegate(PropertyDescriptor declaration, PropertyDescriptor overriddenDescriptor, StackValue field) {
JvmPropertyAccessorSignature jvmPropertyAccessorSignature =
typeMapper.mapGetterSignature(declaration, OwnerKind.IMPLEMENTATION);
functionCodegen.genDelegate(declaration, overriddenDescriptor, field, jvmPropertyAccessorSignature.getJvmMethodSignature());
JvmMethodSignature getterSignature =
typeMapper.mapGetterSignature(declaration.getOriginal(), OwnerKind.IMPLEMENTATION).getJvmMethodSignature();
functionCodegen.genDelegate(declaration, overriddenDescriptor, field, getterSignature, getterSignature);
if (declaration.isVar()) {
jvmPropertyAccessorSignature = typeMapper.mapSetterSignature(declaration, OwnerKind.IMPLEMENTATION);
functionCodegen.genDelegate(declaration, overriddenDescriptor, field, jvmPropertyAccessorSignature.getJvmMethodSignature());
JvmMethodSignature setterSignature =
typeMapper.mapSetterSignature(declaration.getOriginal(), OwnerKind.IMPLEMENTATION).getJvmMethodSignature();
functionCodegen.genDelegate(declaration, overriddenDescriptor, field, setterSignature, setterSignature);
}
}
}
@@ -0,0 +1,31 @@
trait A<T> {
var zzzValue : T
fun zzz() : T
}
class Base<T> : A<T?> {
override var zzzValue : T? = null
override fun zzz() : T? = zzzValue
}
class X : A<String?> by Base<String?>()
fun box() : String {
(Base<String?>() as A<String?>).zzz()
if (X().zzz() != null) {
return "Fail"
}
val x = X()
x.zzzValue = "aa"
if (x.zzzValue != "aa") {
return "Fail 2";
}
if (x.zzz() != "aa") {
return "Fail 3";
}
return "OK"
}
@@ -110,6 +110,11 @@ public class ClassGenTest extends CodegenTestCase {
blackBoxFile("classes/delegation4.kt");
}
public void testInheritanceAndDelegationTyped() throws Exception {
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
blackBoxFile("classes/typedDelegation.kt");
}
public void testDelegationMethodsWithArgs() throws Exception {
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
blackBoxFile("classes/delegationMethodsWithArgs.kt");