diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index febc4231f5e..4ed3ca65957 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -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(""); - constructorMethod = jvmMethodSignature.getAsmMethod(); - callableMethod = new CallableMethod("", jvmMethodSignature, Opcodes.INVOKESPECIAL); + constructorMethod = signatureWriter.makeJvmMethodSignature(""); + 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 consArgTypes = new LinkedList(Arrays.asList(constructorMethod.getArgumentTypes())); + final LinkedList consArgTypes = new LinkedList(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("", Type.VOID_TYPE, consArgTypes.toArray(new Type[consArgTypes.size()])); + constructorMethod = JvmMethodSignature.simple("", 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) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index d997b8f7c4c..35b9d27f0a6 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -650,8 +650,9 @@ public class JetTypeMapper { List parameters = descriptor.getOriginal().getValueParameters(); ClassDescriptor classDescriptor = descriptor.getContainingDeclaration(); - - writeFormalTypeParameters(descriptor.getTypeParameters(), signatureWriter); + + // constructor type parmeters are fake + writeFormalTypeParameters(Collections.emptyList(), signatureWriter); signatureWriter.writeParametersStart(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JvmMethodParameterKind.java b/compiler/backend/src/org/jetbrains/jet/codegen/JvmMethodParameterKind.java index 66cc3ef7376..b22769e1e0a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JvmMethodParameterKind.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JvmMethodParameterKind.java @@ -12,4 +12,5 @@ public enum JvmMethodParameterKind { THIS0, RECEIVER, TYPE_INFO, + SHARED_VAR, } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JvmMethodSignature.java b/compiler/backend/src/org/jetbrains/jet/codegen/JvmMethodSignature.java index a3487e8a50d..9f6a59f5540 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JvmMethodSignature.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JvmMethodSignature.java @@ -46,6 +46,19 @@ public class JvmMethodSignature { this.kotlinReturnType = ""; this.genericsAvailable = false; } + + public static JvmMethodSignature simple(@NotNull String methodName, @NotNull Type returnType, @NotNull List parameterSignatures) { + return new JvmMethodSignature(new Method(methodName, returnType, getTypes(parameterSignatures).toArray(new Type[0])), parameterSignatures); + } + + @NotNull + private static List getTypes(@NotNull List signatures) { + List r = new ArrayList(signatures.size()); + for (JvmMethodParameterSignature signature : signatures) { + r.add(signature.getAsmType()); + } + return r; + } private void checkGenericsAvailable() { if (!genericsAvailable) { diff --git a/compiler/testData/readKotlinBinaryClass/constructor/ConstructorWithTwoTypeParametersAndOneIntValueParameter.kt b/compiler/testData/readKotlinBinaryClass/constructor/ConstructorWithTwoTypeParametersAndOneIntValueParameter.kt new file mode 100644 index 00000000000..6761a4ea6b6 --- /dev/null +++ b/compiler/testData/readKotlinBinaryClass/constructor/ConstructorWithTwoTypeParametersAndOneIntValueParameter.kt @@ -0,0 +1,3 @@ +package test + +class ClassWithConstructorAndTypeParameter(q: Int) diff --git a/compiler/testData/readKotlinBinaryClass/constructor/ConstructorWithTwoTypeParametersAndOnePValueParameter.kt b/compiler/testData/readKotlinBinaryClass/constructor/ConstructorWithTwoTypeParametersAndOnePValueParameter.kt new file mode 100644 index 00000000000..2bbc9f68741 --- /dev/null +++ b/compiler/testData/readKotlinBinaryClass/constructor/ConstructorWithTwoTypeParametersAndOnePValueParameter.kt @@ -0,0 +1,3 @@ +package test + +class ClassWithConstructorAndTypeParameter(q: Q) diff --git a/compiler/testData/writeSignature/constructor/Constructor0.kt b/compiler/testData/writeSignature/constructor/Constructor0.kt new file mode 100644 index 00000000000..13eaaa75106 --- /dev/null +++ b/compiler/testData/writeSignature/constructor/Constructor0.kt @@ -0,0 +1,6 @@ +class Constructor0() + +// method: Constructor0:: +// jvm signature: ()V +// generic signature: null +// kotlin signature: null diff --git a/compiler/testData/writeSignature/constructor/ConstructorWithTypeParameter.kt b/compiler/testData/writeSignature/constructor/ConstructorWithTypeParameter.kt new file mode 100644 index 00000000000..27af4628294 --- /dev/null +++ b/compiler/testData/writeSignature/constructor/ConstructorWithTypeParameter.kt @@ -0,0 +1,6 @@ +class ConstructorWithTypeParameter

() + +// method: ConstructorWithTypeParameter:: +// jvm signature: (Ljet/TypeInfo;)V +// generic signature: null +// kotlin signature: null diff --git a/compiler/testData/writeSignature/constructor/ConstructorWithTypeParameterAndValueParameterP.kt b/compiler/testData/writeSignature/constructor/ConstructorWithTypeParameterAndValueParameterP.kt new file mode 100644 index 00000000000..e0b43627efe --- /dev/null +++ b/compiler/testData/writeSignature/constructor/ConstructorWithTypeParameterAndValueParameterP.kt @@ -0,0 +1,6 @@ +class ConstructorWithTypeParameter

(p: P) + +// method: ConstructorWithTypeParameter:: +// jvm signature: (Ljet/TypeInfo;Ljava/lang/Object;)V +// generic signature: (Ljet/TypeInfo;TP;)V +// kotlin signature: null diff --git a/compiler/tests/org/jetbrains/jet/compiler/WriteSignatureTest.java b/compiler/tests/org/jetbrains/jet/compiler/WriteSignatureTest.java index 0d3f8c608fe..b3f569983b4 100644 --- a/compiler/tests/org/jetbrains/jet/compiler/WriteSignatureTest.java +++ b/compiler/tests/org/jetbrains/jet/compiler/WriteSignatureTest.java @@ -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