fix couple of bugs in constructor signature serialization/parsing

This commit is contained in:
Stepan Koltsov
2012-01-23 22:49:46 +04:00
parent 8dd62f124a
commit f21ad2f536
10 changed files with 70 additions and 16 deletions
@@ -362,7 +362,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
CodegenContext.ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor, typeMapper);
Method constructorMethod;
JvmMethodSignature constructorMethod;
CallableMethod callableMethod;
if (constructorDescriptor == null) {
@@ -387,23 +387,22 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
signatureWriter.writeVoidReturn();
JvmMethodSignature jvmMethodSignature = signatureWriter.makeJvmMethodSignature("<init>");
constructorMethod = jvmMethodSignature.getAsmMethod();
callableMethod = new CallableMethod("", jvmMethodSignature, Opcodes.INVOKESPECIAL);
constructorMethod = signatureWriter.makeJvmMethodSignature("<init>");
callableMethod = new CallableMethod("", constructorMethod, Opcodes.INVOKESPECIAL);
}
else {
callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, kind);
constructorMethod = callableMethod.getSignature().getAsmMethod();
constructorMethod = callableMethod.getSignature();
}
ObjectOrClosureCodegen closure = context.closure;
if(closure != null) {
final List<Type> consArgTypes = new LinkedList<Type>(Arrays.asList(constructorMethod.getArgumentTypes()));
final LinkedList<JvmMethodParameterSignature> consArgTypes = new LinkedList<JvmMethodParameterSignature>(constructorMethod.getKotlinParameterTypes());
int insert = 0;
if(closure.captureThis) {
if(!CodegenUtil.hasThis0(descriptor))
consArgTypes.add(insert, Type.getObjectType(context.getThisDescriptor().getName()));
consArgTypes.add(insert, new JvmMethodParameterSignature(Type.getObjectType(context.getThisDescriptor().getName()), "", JvmMethodParameterKind.THIS0));
insert++;
}
else {
@@ -412,24 +411,24 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
if(closure.captureReceiver != null)
consArgTypes.add(insert++, closure.captureReceiver);
consArgTypes.add(insert++, new JvmMethodParameterSignature(closure.captureReceiver, "", JvmMethodParameterKind.RECEIVER));
for (DeclarationDescriptor descriptor : closure.closure.keySet()) {
if(descriptor instanceof VariableDescriptor && !(descriptor instanceof PropertyDescriptor)) {
final Type sharedVarType = typeMapper.getSharedVarType(descriptor);
final Type type = sharedVarType != null ? sharedVarType : state.getTypeMapper().mapType(((VariableDescriptor) descriptor).getOutType());
consArgTypes.add(insert++, type);
consArgTypes.add(insert++, new JvmMethodParameterSignature(type, "", JvmMethodParameterKind.SHARED_VAR));
}
else if(descriptor instanceof FunctionDescriptor) {
assert closure.captureReceiver != null;
}
}
constructorMethod = new Method("<init>", Type.VOID_TYPE, consArgTypes.toArray(new Type[consArgTypes.size()]));
constructorMethod = JvmMethodSignature.simple("<init>", Type.VOID_TYPE, consArgTypes);
}
int flags = Opcodes.ACC_PUBLIC; // TODO
final MethodVisitor mv = v.newMethod(myClass, flags, constructorMethod.getName(), constructorMethod.getDescriptor(), null, null);
final MethodVisitor mv = v.newMethod(myClass, flags, constructorMethod.getName(), constructorMethod.getAsmMethod().getDescriptor(), constructorMethod.getGenericsSignature(), null);
if (!v.generateCode()) return;
AnnotationVisitor jetConstructorVisitor = mv.visitAnnotation(JvmStdlibNames.JET_CONSTRUCTOR.getDescriptor(), true);
@@ -613,7 +612,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
mv.visitInsn(Opcodes.RETURN);
FunctionCodegen.endVisit(mv, "constructor", myClass);
FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod, constructorDescriptor, OwnerKind.IMPLEMENTATION);
FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod.getAsmMethod(), constructorDescriptor, OwnerKind.IMPLEMENTATION);
}
private void generateTraitMethods(ExpressionCodegen codegen) {
@@ -650,8 +650,9 @@ public class JetTypeMapper {
List<ValueParameterDescriptor> parameters = descriptor.getOriginal().getValueParameters();
ClassDescriptor classDescriptor = descriptor.getContainingDeclaration();
writeFormalTypeParameters(descriptor.getTypeParameters(), signatureWriter);
// constructor type parmeters are fake
writeFormalTypeParameters(Collections.<TypeParameterDescriptor>emptyList(), signatureWriter);
signatureWriter.writeParametersStart();
@@ -12,4 +12,5 @@ public enum JvmMethodParameterKind {
THIS0,
RECEIVER,
TYPE_INFO,
SHARED_VAR,
}
@@ -46,6 +46,19 @@ public class JvmMethodSignature {
this.kotlinReturnType = "";
this.genericsAvailable = false;
}
public static JvmMethodSignature simple(@NotNull String methodName, @NotNull Type returnType, @NotNull List<JvmMethodParameterSignature> parameterSignatures) {
return new JvmMethodSignature(new Method(methodName, returnType, getTypes(parameterSignatures).toArray(new Type[0])), parameterSignatures);
}
@NotNull
private static List<Type> getTypes(@NotNull List<JvmMethodParameterSignature> signatures) {
List<Type> r = new ArrayList<Type>(signatures.size());
for (JvmMethodParameterSignature signature : signatures) {
r.add(signature.getAsmType());
}
return r;
}
private void checkGenericsAvailable() {
if (!genericsAvailable) {
@@ -0,0 +1,3 @@
package test
class ClassWithConstructorAndTypeParameter<P, Q>(q: Int)
@@ -0,0 +1,3 @@
package test
class ClassWithConstructorAndTypeParameter<P, Q>(q: Q)
@@ -0,0 +1,6 @@
class Constructor0()
// method: Constructor0::<init>
// jvm signature: ()V
// generic signature: null
// kotlin signature: null
@@ -0,0 +1,6 @@
class ConstructorWithTypeParameter<P>()
// method: ConstructorWithTypeParameter::<init>
// jvm signature: (Ljet/TypeInfo;)V
// generic signature: null
// kotlin signature: null
@@ -0,0 +1,6 @@
class ConstructorWithTypeParameter<P>(p: P)
// method: ConstructorWithTypeParameter::<init>
// jvm signature: (Ljet/TypeInfo;Ljava/lang/Object;)V
// generic signature: (Ljet/TypeInfo;TP;)V
// kotlin signature: null
@@ -182,17 +182,33 @@ public class WriteSignatureTest extends TestCaseWithTmpdir {
public AnnotationVisitor visitAnnotationDefault() {
return new EmptyVisitor();
}
@Nullable
private String makeKotlinSignature() {
boolean allNulls = true;
StringBuilder sb = new StringBuilder();
sb.append(typeParameters);
if (typeParameters != null && typeParameters.length() > 0) {
allNulls = false;
}
sb.append("(");
for (String parameterType : parameterTypes) {
sb.append(parameterType);
if (parameterType != null) {
allNulls = false;
}
}
sb.append(")");
sb.append(returnType);
return sb.toString();
if (returnType != null) {
allNulls = false;
}
if (allNulls) {
return null;
} else {
return sb.toString();
}
}
@Override