BothSignatureWriter should write JVM signatures too

(this simplifies body of JetTypeMapper)
This commit is contained in:
Stepan Koltsov
2012-01-13 03:55:10 +04:00
parent 82880c82e3
commit aa2f2742d5
9 changed files with 377 additions and 175 deletions
@@ -3,11 +3,12 @@ package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.JetSignatureUtils; import org.jetbrains.jet.lang.resolve.java.JetSignatureUtils;
import org.jetbrains.jet.lang.types.Variance;
import org.jetbrains.jet.rt.signature.JetSignatureAdapter; import org.jetbrains.jet.rt.signature.JetSignatureAdapter;
import org.jetbrains.jet.rt.signature.JetSignatureReader; import org.jetbrains.jet.rt.signature.JetSignatureReader;
import org.jetbrains.jet.rt.signature.JetSignatureWriter; import org.jetbrains.jet.rt.signature.JetSignatureWriter;
import org.jetbrains.jet.lang.types.Variance;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import org.objectweb.asm.commons.Method;
import org.objectweb.asm.signature.SignatureVisitor; import org.objectweb.asm.signature.SignatureVisitor;
import org.objectweb.asm.signature.SignatureWriter; import org.objectweb.asm.signature.SignatureWriter;
import org.objectweb.asm.util.CheckSignatureAdapter; import org.objectweb.asm.util.CheckSignatureAdapter;
@@ -40,6 +41,7 @@ public class BothSignatureWriter {
TYPE_PARAMETERS, TYPE_PARAMETERS,
PARAMETERS, PARAMETERS,
PARAMETER,
RETURN_TYPE, RETURN_TYPE,
METHOD_END, METHOD_END,
@@ -55,16 +57,26 @@ public class BothSignatureWriter {
private String kotlinClassParameters; private String kotlinClassParameters;
private String kotlinClassSignature; private String kotlinClassSignature;
private List<String> kotlinParameterTypes = new ArrayList<String>(); private List<JvmMethodParameterSignature> kotlinParameterTypes = new ArrayList<JvmMethodParameterSignature>();
private String kotlinReturnType; private String kotlinReturnType;
private int jvmCurrentTypeArrayLevel;
private Type jvmCurrentType;
private Type jvmReturnType;
private JvmMethodParameterKind currentParameterKind;
private final Mode mode; private final Mode mode;
private final boolean needGenerics;
private State state = State.START; private State state = State.START;
private boolean generic = false; private boolean generic = false;
public BothSignatureWriter(Mode mode) { public BothSignatureWriter(Mode mode, boolean needGenerics) {
this.mode = mode; this.mode = mode;
this.needGenerics = needGenerics;
if (DEBUG_SIGNATURE_WRITER) { if (DEBUG_SIGNATURE_WRITER) {
signatureVisitor = new CheckSignatureAdapter(mode.asmType, signatureWriter); signatureVisitor = new CheckSignatureAdapter(mode.asmType, signatureWriter);
} else { } else {
@@ -152,11 +164,27 @@ public class BothSignatureWriter {
} }
signatureVisitor().visitBaseType(c); signatureVisitor().visitBaseType(c);
jetSignatureWriter.visitBaseType(c, nullable); jetSignatureWriter.visitBaseType(c, nullable);
writeAsmType0(Type.getType(String.valueOf(c)));
}
private String makeArrayPrefix() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < jvmCurrentTypeArrayLevel; ++i) {
sb.append('[');
}
return sb.toString();
}
private void writeAsmType0(Type type) {
if (jvmCurrentType == null) {
jvmCurrentType = Type.getType(makeArrayPrefix() + type.getDescriptor());
}
} }
public void writeClassBegin(String internalName, boolean nullable) { public void writeClassBegin(String internalName, boolean nullable) {
signatureVisitor().visitClassType(internalName); signatureVisitor().visitClassType(internalName);
jetSignatureWriter.visitClassType(internalName, nullable); jetSignatureWriter.visitClassType(internalName, nullable);
writeAsmType0(Type.getObjectType(internalName));
} }
public void writeClassEnd() { public void writeClassEnd() {
@@ -167,6 +195,9 @@ public class BothSignatureWriter {
public void writeArrayType(boolean nullable) { public void writeArrayType(boolean nullable) {
push(signatureVisitor().visitArrayType()); push(signatureVisitor().visitArrayType());
jetSignatureWriter.visitArrayType(nullable); jetSignatureWriter.visitArrayType(nullable);
if (jvmCurrentType == null) {
++jvmCurrentTypeArrayLevel;
}
} }
public void writeArrayEnd() { public void writeArrayEnd() {
@@ -183,10 +214,11 @@ public class BothSignatureWriter {
pop(); pop();
} }
public void writeTypeVariable(final String name, boolean nullable) { public void writeTypeVariable(final String name, boolean nullable, Type asmType) {
signatureVisitor().visitTypeVariable(name); signatureVisitor().visitTypeVariable(name);
jetSignatureWriter.visitTypeVariable(name, nullable); jetSignatureWriter.visitTypeVariable(name, nullable);
generic = true; generic = true;
writeAsmType0(asmType);
} }
public void writeFormalTypeParameter(final String name, Variance variance) { public void writeFormalTypeParameter(final String name, Variance variance) {
@@ -202,7 +234,7 @@ public class BothSignatureWriter {
jetSignatureWriter.visitFormalTypeParameterEnd(); jetSignatureWriter.visitFormalTypeParameterEnd();
} }
public void writerFormalTypeParametersStart() { public void writeFormalTypeParametersStart() {
checkTopLevel(); checkTopLevel();
transitionState(State.START, State.TYPE_PARAMETERS); transitionState(State.START, State.TYPE_PARAMETERS);
jetSignatureWriter = new JetSignatureWriter(); jetSignatureWriter = new JetSignatureWriter();
@@ -242,28 +274,59 @@ public class BothSignatureWriter {
public void writeParametersStart() { public void writeParametersStart() {
transitionState(State.TYPE_PARAMETERS, State.PARAMETERS); transitionState(State.TYPE_PARAMETERS, State.PARAMETERS);
// hacks
jvmCurrentType = null;
jvmCurrentTypeArrayLevel = 0;
} }
public void writeParametersEnd() { public void writeParametersEnd() {
checkState(State.PARAMETERS); checkState(State.PARAMETERS);
} }
public void writeParameterType() { public void writeParameterType(JvmMethodParameterKind parameterKind) {
transitionState(State.PARAMETERS, State.PARAMETER);
push(signatureVisitor().visitParameterType()); push(signatureVisitor().visitParameterType());
jetSignatureWriter = new JetSignatureWriter(); jetSignatureWriter = new JetSignatureWriter();
if (jvmCurrentType != null || jvmCurrentTypeArrayLevel != 0) {
throw new IllegalStateException();
}
if (currentParameterKind != null) {
throw new IllegalStateException();
}
this.currentParameterKind = parameterKind;
//jetSignatureWriter.visitParameterType(); //jetSignatureWriter.visitParameterType();
} }
public void writeParameterTypeEnd() { public void writeParameterTypeEnd() {
pop(); pop();
if (jvmCurrentType == null) {
throw new IllegalStateException();
}
String signature = jetSignatureWriter.toString(); String signature = jetSignatureWriter.toString();
kotlinParameterTypes.add(signature); kotlinParameterTypes.add(new JvmMethodParameterSignature(jvmCurrentType, signature, currentParameterKind));
if (DEBUG_SIGNATURE_WRITER) { if (DEBUG_SIGNATURE_WRITER) {
new JetSignatureReader(signature).acceptTypeOnly(new JetSignatureAdapter()); new JetSignatureReader(signature).acceptTypeOnly(new JetSignatureAdapter());
} }
currentParameterKind = null;
jvmCurrentType = null;
jvmCurrentTypeArrayLevel = 0;
jetSignatureWriter = null; jetSignatureWriter = null;
transitionState(State.PARAMETER, State.PARAMETERS);
}
public void writeTypeInfoParameter() {
writeParameterType(JvmMethodParameterKind.TYPE_INFO);
writeAsmType(JetTypeMapper.TYPE_TYPEINFO, false);
writeParameterTypeEnd();
} }
public void writeReturnType() { public void writeReturnType() {
@@ -271,6 +334,10 @@ public class BothSignatureWriter {
jetSignatureWriter = new JetSignatureWriter(); jetSignatureWriter = new JetSignatureWriter();
if (jvmCurrentType != null) {
throw new IllegalStateException();
}
push(signatureVisitor().visitReturnType()); push(signatureVisitor().visitReturnType());
//jetSignatureWriter.visitReturnType(); //jetSignatureWriter.visitReturnType();
} }
@@ -280,6 +347,14 @@ public class BothSignatureWriter {
kotlinReturnType = jetSignatureWriter.toString(); kotlinReturnType = jetSignatureWriter.toString();
if (jvmCurrentType == null) {
throw new IllegalStateException();
}
jvmReturnType = jvmCurrentType;
jvmCurrentType = null;
jvmCurrentTypeArrayLevel = 0;
if (DEBUG_SIGNATURE_WRITER) { if (DEBUG_SIGNATURE_WRITER) {
new JetSignatureReader(kotlinReturnType).acceptTypeOnly(new JetSignatureAdapter()); new JetSignatureReader(kotlinReturnType).acceptTypeOnly(new JetSignatureAdapter());
} }
@@ -288,6 +363,12 @@ public class BothSignatureWriter {
transitionState(State.RETURN_TYPE, State.METHOD_END); transitionState(State.RETURN_TYPE, State.METHOD_END);
} }
public void writeVoidReturn() {
writeReturnType();
writeAsmType(Type.VOID_TYPE, false);
writeReturnTypeEnd();
}
public void writeSupersStart() { public void writeSupersStart() {
transitionState(State.TYPE_PARAMETERS, State.SUPERS); transitionState(State.TYPE_PARAMETERS, State.SUPERS);
jetSignatureWriter = new JetSignatureWriter(); jetSignatureWriter = new JetSignatureWriter();
@@ -333,6 +414,14 @@ public class BothSignatureWriter {
@NotNull
public Method makeAsmMethod(String name) {
List<Type> jvmParameterTypes = new ArrayList<Type>(kotlinParameterTypes.size());
for (JvmMethodParameterSignature p : kotlinParameterTypes) {
jvmParameterTypes.add(p.getAsmType());
}
return new Method(name, jvmReturnType, jvmParameterTypes.toArray(new Type[0]));
}
@Nullable @Nullable
public String makeJavaString() { public String makeJavaString() {
@@ -344,7 +433,7 @@ public class BothSignatureWriter {
} }
@NotNull @NotNull
public List<String> makeKotlinParameterTypes() { public List<JvmMethodParameterSignature> makeKotlinParameterTypes() {
checkState(State.METHOD_END); checkState(State.METHOD_END);
// TODO: return nulls if equal to #makeJavaString // TODO: return nulls if equal to #makeJavaString
return kotlinParameterTypes; return kotlinParameterTypes;
@@ -373,4 +462,19 @@ public class BothSignatureWriter {
return kotlinClassParameters + kotlinClassSignature; return kotlinClassParameters + kotlinClassSignature;
} }
@NotNull
public JvmMethodSignature makeJvmMethodSignature(String name) {
if (needGenerics) {
return new JvmMethodSignature(
makeAsmMethod(name),
makeJavaString(),
makeKotlinMethodTypeParameters(),
makeKotlinParameterTypes(),
makeKotlinReturnTypeSignature()
);
} else {
return new JvmMethodSignature(makeAsmMethod(name), makeKotlinParameterTypes());
}
}
} }
@@ -19,17 +19,15 @@ public class CallableMethod implements Callable {
private String owner; private String owner;
private final JvmMethodSignature signature; private final JvmMethodSignature signature;
private int invokeOpcode; private int invokeOpcode;
private final List<Type> valueParameterTypes;
private ClassDescriptor thisClass = null; private ClassDescriptor thisClass = null;
private CallableDescriptor receiverFunction = null; private CallableDescriptor receiverFunction = null;
private Type generateCalleeType = null; private Type generateCalleeType = null;
public CallableMethod(String owner, JvmMethodSignature signature, int invokeOpcode, List<Type> valueParameterTypes) { public CallableMethod(String owner, JvmMethodSignature signature, int invokeOpcode) {
this.owner = owner; this.owner = owner;
this.signature = signature; this.signature = signature;
this.invokeOpcode = invokeOpcode; this.invokeOpcode = invokeOpcode;
this.valueParameterTypes = valueParameterTypes;
} }
public String getOwner() { public String getOwner() {
@@ -45,7 +43,7 @@ public class CallableMethod implements Callable {
} }
public List<Type> getValueParameterTypes() { public List<Type> getValueParameterTypes() {
return valueParameterTypes; return signature.getValueParameterTypes();
} }
public void setNeedsReceiver(@Nullable CallableDescriptor receiverClass) { public void setNeedsReceiver(@Nullable CallableDescriptor receiverClass) {
@@ -39,23 +39,40 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
bindingContext = state.getBindingContext(); bindingContext = state.getBindingContext();
} }
public static Method erasedInvokeSignature(FunctionDescriptor fd) { public static JvmMethodSignature erasedInvokeSignature(FunctionDescriptor fd) {
BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, false);
signatureWriter.writeFormalTypeParametersStart();
signatureWriter.writeFormalTypeParametersEnd();
boolean isExtensionFunction = fd.getReceiverParameter().exists(); boolean isExtensionFunction = fd.getReceiverParameter().exists();
int paramCount = fd.getValueParameters().size(); int paramCount = fd.getValueParameters().size();
if (isExtensionFunction) { if (isExtensionFunction) {
paramCount++; paramCount++;
} }
Type[] args = new Type[paramCount]; signatureWriter.writeParametersStart();
Arrays.fill(args, JetTypeMapper.TYPE_OBJECT);
return new Method("invoke", JetTypeMapper.TYPE_OBJECT, args); for (int i = 0; i < paramCount; ++i) {
signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
signatureWriter.writeAsmType(JetTypeMapper.TYPE_OBJECT, true);
signatureWriter.writeParameterTypeEnd();
}
signatureWriter.writeParametersEnd();
signatureWriter.writeReturnType();
signatureWriter.writeAsmType(JetTypeMapper.TYPE_OBJECT, true);
signatureWriter.writeReturnTypeEnd();
return signatureWriter.makeJvmMethodSignature("invoke");
} }
public static CallableMethod asCallableMethod(FunctionDescriptor fd) { public static CallableMethod asCallableMethod(FunctionDescriptor fd) {
Method descriptor = erasedInvokeSignature(fd); JvmMethodSignature descriptor = erasedInvokeSignature(fd);
String owner = getInternalClassName(fd); String owner = getInternalClassName(fd);
JvmMethodSignature jvmMethodSignature = new JvmMethodSignature(descriptor, null, null, null, ""); final CallableMethod result = new CallableMethod(owner, descriptor, INVOKEVIRTUAL);
final CallableMethod result = new CallableMethod(owner, jvmMethodSignature, INVOKEVIRTUAL, Arrays.asList(descriptor.getArgumentTypes()));
if (fd.getReceiverParameter().exists()) { if (fd.getReceiverParameter().exists()) {
result.setNeedsReceiver(fd); result.setNeedsReceiver(fd);
} }
@@ -63,8 +80,8 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
return result; return result;
} }
public Method invokeSignature(FunctionDescriptor fd) { public JvmMethodSignature invokeSignature(FunctionDescriptor fd) {
return state.getTypeMapper().mapSignature("invoke", fd).getAsmMethod(); return state.getTypeMapper().mapSignature("invoke", fd);
} }
public GeneratedAnonymousClassDescriptor gen(JetFunctionLiteralExpression fun) { public GeneratedAnonymousClassDescriptor gen(JetFunctionLiteralExpression fun) {
@@ -166,19 +183,19 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
final CodegenContext.ClosureContext closureContext = context.intoClosure(funDescriptor, function, name, this, state.getTypeMapper()); final CodegenContext.ClosureContext closureContext = context.intoClosure(funDescriptor, function, name, this, state.getTypeMapper());
FunctionCodegen fc = new FunctionCodegen(closureContext, cv, state); FunctionCodegen fc = new FunctionCodegen(closureContext, cv, state);
JvmMethodSignature jvmMethodSignature = new JvmMethodSignature(invokeSignature(funDescriptor), null, null, null, ""); JvmMethodSignature jvmMethodSignature = invokeSignature(funDescriptor);
fc.generateMethod(body, jvmMethodSignature, null, funDescriptor); fc.generateMethod(body, jvmMethodSignature, null, funDescriptor);
return closureContext.outerWasUsed; return closureContext.outerWasUsed;
} }
private void generateBridge(String className, FunctionDescriptor funDescriptor, JetExpression fun, ClassBuilder cv) { private void generateBridge(String className, FunctionDescriptor funDescriptor, JetExpression fun, ClassBuilder cv) {
final Method bridge = erasedInvokeSignature(funDescriptor); final JvmMethodSignature bridge = erasedInvokeSignature(funDescriptor);
final Method delegate = invokeSignature(funDescriptor); final Method delegate = invokeSignature(funDescriptor).getAsmMethod();
if(bridge.getDescriptor().equals(delegate.getDescriptor())) if(bridge.getAsmMethod().getDescriptor().equals(delegate.getDescriptor()))
return; return;
final MethodVisitor mv = cv.newMethod(fun, ACC_PUBLIC, "invoke", bridge.getDescriptor(), null, new String[0]); final MethodVisitor mv = cv.newMethod(fun, ACC_PUBLIC, "invoke", bridge.getAsmMethod().getDescriptor(), null, new String[0]);
if (cv.generateCode()) { if (cv.generateCode()) {
mv.visitCode(); mv.visitCode();
@@ -1,6 +1,7 @@
package org.jetbrains.jet.codegen; package org.jetbrains.jet.codegen;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
@@ -144,7 +145,7 @@ public class FunctionCodegen {
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true); av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true);
} }
if (jvmSignature.getKotlinParameterTypes() != null && jvmSignature.getKotlinParameterTypes().get(i) != null) { if (jvmSignature.getKotlinParameterTypes() != null && jvmSignature.getKotlinParameterTypes().get(i) != null) {
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_TYPE_FIELD, jvmSignature.getKotlinParameterTypes().get(i + start)); av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_TYPE_FIELD, jvmSignature.getKotlinParameterTypes().get(i + start).getKotlinSignature());
} }
av.visitEnd(); av.visitEnd();
} }
@@ -115,7 +115,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
LinkedHashSet<String> superInterfacesLinkedHashSet = new LinkedHashSet<String>(); LinkedHashSet<String> superInterfacesLinkedHashSet = new LinkedHashSet<String>();
BothSignatureWriter signatureVisitor = new BothSignatureWriter(BothSignatureWriter.Mode.CLASS); // TODO: generics signature is not always needed
BothSignatureWriter signatureVisitor = new BothSignatureWriter(BothSignatureWriter.Mode.CLASS, true);
{ // type parameters { // type parameters
@@ -351,17 +352,31 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
Method constructorMethod; Method constructorMethod;
CallableMethod callableMethod; CallableMethod callableMethod;
if (constructorDescriptor == null) { if (constructorDescriptor == null) {
List<Type> parameterTypes = new ArrayList<Type>();
BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, false);
signatureWriter.writeFormalTypeParametersStart();
signatureWriter.writeFormalTypeParametersEnd();
signatureWriter.writeParametersStart();
if (CodegenUtil.hasThis0(descriptor)) { if (CodegenUtil.hasThis0(descriptor)) {
parameterTypes.add(typeMapper.mapType(CodegenUtil.getOuterClassDescriptor(descriptor).getDefaultType(), OwnerKind.IMPLEMENTATION)); signatureWriter.writeParameterType(JvmMethodParameterKind.THIS0);
typeMapper.mapType(CodegenUtil.getOuterClassDescriptor(descriptor).getDefaultType(), OwnerKind.IMPLEMENTATION, signatureWriter, false);
signatureWriter.writeParameterTypeEnd();
} }
if (CodegenUtil.requireTypeInfoConstructorArg(descriptor.getDefaultType())) { if (CodegenUtil.requireTypeInfoConstructorArg(descriptor.getDefaultType())) {
parameterTypes.add(JetTypeMapper.TYPE_TYPEINFO); signatureWriter.writeTypeInfoParameter();
} }
constructorMethod = new Method("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()])); signatureWriter.writeParametersEnd();
callableMethod = new CallableMethod("", new JvmMethodSignature(constructorMethod, null, null, null, "") /* TODO */, Opcodes.INVOKESPECIAL, Collections.<Type>emptyList());
signatureWriter.writeVoidReturn();
JvmMethodSignature jvmMethodSignature = signatureWriter.makeJvmMethodSignature("<init>");
constructorMethod = jvmMethodSignature.getAsmMethod();
callableMethod = new CallableMethod("", jvmMethodSignature, Opcodes.INVOKESPECIAL);
} }
else { else {
callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, kind); callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, kind);
@@ -306,12 +306,13 @@ public class JetTypeMapper {
} }
if (descriptor instanceof TypeParameterDescriptor) { if (descriptor instanceof TypeParameterDescriptor) {
Type type = mapType(((TypeParameterDescriptor) descriptor).getUpperBoundsAsType(), kind);
if (signatureVisitor != null) { if (signatureVisitor != null) {
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) jetType.getConstructor().getDeclarationDescriptor(); TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) jetType.getConstructor().getDeclarationDescriptor();
signatureVisitor.writeTypeVariable(typeParameterDescriptor.getName(), jetType.isNullable()); signatureVisitor.writeTypeVariable(typeParameterDescriptor.getName(), jetType.isNullable(), type);
} }
return type;
return mapType(((TypeParameterDescriptor) descriptor).getUpperBoundsAsType(), kind);
} }
throw new UnsupportedOperationException("Unknown type " + jetType); throw new UnsupportedOperationException("Unknown type " + jetType);
@@ -355,8 +356,7 @@ public class JetTypeMapper {
return null; return null;
final DeclarationDescriptor functionParent = functionDescriptor.getContainingDeclaration(); final DeclarationDescriptor functionParent = functionDescriptor.getContainingDeclaration();
final List<Type> valueParameterTypes = new ArrayList<Type>(); JvmMethodSignature descriptor = mapSignature(functionDescriptor.getOriginal(), true, kind);
JvmMethodSignature descriptor = mapSignature(functionDescriptor.getOriginal(), true, valueParameterTypes, kind);
String owner; String owner;
int invokeOpcode; int invokeOpcode;
ClassDescriptor thisClass; ClassDescriptor thisClass;
@@ -383,7 +383,7 @@ public class JetTypeMapper {
? (superCall ? Opcodes.INVOKESTATIC : Opcodes.INVOKEINTERFACE) ? (superCall ? Opcodes.INVOKESTATIC : Opcodes.INVOKEINTERFACE)
: (superCall ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL); : (superCall ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL);
if(isInterface && superCall) { if(isInterface && superCall) {
descriptor = mapSignature(functionDescriptor.getOriginal(), false, valueParameterTypes, OwnerKind.TRAIT_IMPL); descriptor = mapSignature(functionDescriptor.getOriginal(), false, OwnerKind.TRAIT_IMPL);
} }
thisClass = (ClassDescriptor) functionParent; thisClass = (ClassDescriptor) functionParent;
} }
@@ -391,7 +391,7 @@ public class JetTypeMapper {
throw new UnsupportedOperationException("unknown function parent"); throw new UnsupportedOperationException("unknown function parent");
} }
final CallableMethod result = new CallableMethod(owner, descriptor, invokeOpcode, valueParameterTypes); final CallableMethod result = new CallableMethod(owner, descriptor, invokeOpcode);
result.setNeedsThis(thisClass); result.setNeedsThis(thisClass);
if(functionDescriptor.getReceiverParameter().exists()) { if(functionDescriptor.getReceiverParameter().exists()) {
result.setNeedsReceiver(functionDescriptor); result.setNeedsReceiver(functionDescriptor);
@@ -400,7 +400,7 @@ public class JetTypeMapper {
return result; return result;
} }
private JvmMethodSignature mapSignature(FunctionDescriptor f, boolean needGenericSignature, List<Type> valueParameterTypes, OwnerKind kind) { private JvmMethodSignature mapSignature(FunctionDescriptor f, boolean needGenericSignature, OwnerKind kind) {
for (ValueParameterDescriptor valueParameterDescriptor : f.getValueParameters()) { for (ValueParameterDescriptor valueParameterDescriptor : f.getValueParameters()) {
if (valueParameterDescriptor.hasDefaultValue()) { if (valueParameterDescriptor.hasDefaultValue()) {
@@ -413,94 +413,57 @@ public class JetTypeMapper {
needGenericSignature = false; needGenericSignature = false;
} }
BothSignatureWriter signatureVisitor = null; BothSignatureWriter signatureVisitor = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, needGenericSignature);
if (needGenericSignature) {
signatureVisitor = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD);
}
writeFormalTypeParameters(f.getTypeParameters(), signatureVisitor); writeFormalTypeParameters(f.getTypeParameters(), signatureVisitor);
final ReceiverDescriptor receiverTypeRef = f.getReceiverParameter(); final ReceiverDescriptor receiverTypeRef = f.getReceiverParameter();
final JetType receiverType = !receiverTypeRef.exists() ? null : receiverTypeRef.getType(); final JetType receiverType = !receiverTypeRef.exists() ? null : receiverTypeRef.getType();
final List<ValueParameterDescriptor> parameters = f.getValueParameters(); final List<ValueParameterDescriptor> parameters = f.getValueParameters();
List<Type> parameterTypes = new ArrayList<Type>();
signatureVisitor.writeParametersStart();
if(kind == OwnerKind.TRAIT_IMPL) { if(kind == OwnerKind.TRAIT_IMPL) {
ClassDescriptor containingDeclaration = (ClassDescriptor) f.getContainingDeclaration(); ClassDescriptor containingDeclaration = (ClassDescriptor) f.getContainingDeclaration();
JetType jetType = TraitImplBodyCodegen.getSuperClass(containingDeclaration, bindingContext); JetType jetType = TraitImplBodyCodegen.getSuperClass(containingDeclaration, bindingContext);
Type type = mapType(jetType, signatureVisitor); Type type = mapType(jetType);
if(type.getInternalName().equals("java/lang/Object")) { if(type.getInternalName().equals("java/lang/Object")) {
jetType = containingDeclaration.getDefaultType(); jetType = containingDeclaration.getDefaultType();
type = mapType(jetType, signatureVisitor); type = mapType(jetType);
} }
valueParameterTypes.add(type);
parameterTypes.add(type); signatureVisitor.writeParameterType(JvmMethodParameterKind.THIS);
signatureVisitor.writeAsmType(type, jetType.isNullable());
signatureVisitor.writeParameterTypeEnd();
} }
if (receiverType != null) { if (receiverType != null) {
if (signatureVisitor != null) { signatureVisitor.writeParameterType(JvmMethodParameterKind.RECEIVER);
signatureVisitor.writeParameterType(); mapType(receiverType, signatureVisitor);
} signatureVisitor.writeParameterTypeEnd();
parameterTypes.add(mapType(receiverType, signatureVisitor));
if (signatureVisitor != null) {
signatureVisitor.writeParameterTypeEnd();
}
}
if (signatureVisitor != null) {
signatureVisitor.writeParametersStart();
} }
for (TypeParameterDescriptor parameterDescriptor : f.getTypeParameters()) { for (TypeParameterDescriptor parameterDescriptor : f.getTypeParameters()) {
if(parameterDescriptor.isReified()) { if(parameterDescriptor.isReified()) {
parameterTypes.add(TYPE_TYPEINFO); signatureVisitor.writeTypeInfoParameter();
if (signatureVisitor != null) {
signatureVisitor.writeParameterType();
visitAsmType(signatureVisitor, TYPE_TYPEINFO, false);
signatureVisitor.writeParameterTypeEnd();
}
} }
} }
for (ValueParameterDescriptor parameter : parameters) { for (ValueParameterDescriptor parameter : parameters) {
if (signatureVisitor != null) { signatureVisitor.writeParameterType(JvmMethodParameterKind.VALUE);
signatureVisitor.writeParameterType(); mapType(parameter.getOutType(), signatureVisitor);
} signatureVisitor.writeParameterTypeEnd();
Type type = mapType(parameter.getOutType(), signatureVisitor);
if (signatureVisitor != null) {
signatureVisitor.writeParameterTypeEnd();
}
valueParameterTypes.add(type);
parameterTypes.add(type);
} }
if (signatureVisitor != null) { signatureVisitor.writeParametersEnd();
signatureVisitor.writeParametersEnd();
}
Type returnType;
if (f instanceof ConstructorDescriptor) { if (f instanceof ConstructorDescriptor) {
returnType = Type.VOID_TYPE; signatureVisitor.writeVoidReturn();
if (signatureVisitor != null) {
signatureVisitor.writeReturnType();
visitAsmType(signatureVisitor, Type.VOID_TYPE, false);
signatureVisitor.writeReturnTypeEnd();
}
} else { } else {
if (signatureVisitor != null) { signatureVisitor.writeReturnType();
signatureVisitor.writeReturnType(); mapReturnType(f.getReturnType(), signatureVisitor);
returnType = mapReturnType(f.getReturnType(), signatureVisitor); signatureVisitor.writeReturnTypeEnd();
signatureVisitor.writeReturnTypeEnd();
}
else {
returnType = mapReturnType(f.getReturnType(), null);
}
}
Method method = new Method(f.getName(), returnType, parameterTypes.toArray(new Type[parameterTypes.size()]));
if (signatureVisitor == null) {
return new JvmMethodSignature(method, null, null, null, "");
} else {
return new JvmMethodSignature(method, signatureVisitor.makeJavaString(),
signatureVisitor.makeKotlinMethodTypeParameters(),
signatureVisitor.makeKotlinParameterTypes(),
signatureVisitor.makeKotlinReturnTypeSignature());
} }
return signatureVisitor.makeJvmMethodSignature(f.getName());
} }
@@ -509,7 +472,7 @@ public class JetTypeMapper {
return; return;
} }
signatureVisitor.writerFormalTypeParametersStart(); signatureVisitor.writeFormalTypeParametersStart();
for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) { for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
writeFormalTypeParameter(typeParameterDescriptor, signatureVisitor); writeFormalTypeParameter(typeParameterDescriptor, signatureVisitor);
} }
@@ -560,27 +523,43 @@ public class JetTypeMapper {
public JvmMethodSignature mapSignature(String name, FunctionDescriptor f) { public JvmMethodSignature mapSignature(String name, FunctionDescriptor f) {
final ReceiverDescriptor receiver = f.getReceiverParameter(); final ReceiverDescriptor receiver = f.getReceiverParameter();
BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, false);
signatureWriter.writeFormalTypeParametersStart();
signatureWriter.writeFormalTypeParametersEnd();
signatureWriter.writeParametersStart();
final List<ValueParameterDescriptor> parameters = f.getValueParameters(); final List<ValueParameterDescriptor> parameters = f.getValueParameters();
List<Type> parameterTypes = new ArrayList<Type>();
if (receiver.exists()) { if (receiver.exists()) {
parameterTypes.add(mapType(receiver.getType())); signatureWriter.writeParameterType(JvmMethodParameterKind.RECEIVER);
mapType(receiver.getType(), signatureWriter);
signatureWriter.writeParameterTypeEnd();
} }
for (ValueParameterDescriptor parameter : parameters) { for (ValueParameterDescriptor parameter : parameters) {
parameterTypes.add(mapType(parameter.getOutType())); signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
mapType(parameter.getOutType(), signatureWriter);
signatureWriter.writeParameterTypeEnd();
} }
Type returnType = mapReturnType(f.getReturnType());
// TODO: proper generic signature signatureWriter.writeParametersEnd();
return new JvmMethodSignature(new Method(name, returnType, parameterTypes.toArray(new Type[parameterTypes.size()])), null, null, null, "");
signatureWriter.writeReturnType();
mapReturnType(f.getReturnType(), signatureWriter);
signatureWriter.writeReturnTypeEnd();
return signatureWriter.makeJvmMethodSignature(name);
} }
public JvmPropertyAccessorSignature mapGetterSignature(PropertyDescriptor descriptor, OwnerKind kind) { public JvmPropertyAccessorSignature mapGetterSignature(PropertyDescriptor descriptor, OwnerKind kind) {
String name = PropertyCodegen.getterName(descriptor.getName()); String name = PropertyCodegen.getterName(descriptor.getName());
ArrayList<Type> params = new ArrayList<Type>();
BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD); // TODO: do not generate generics if not needed
BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, true);
signatureWriter.writerFormalTypeParametersStart(); signatureWriter.writeFormalTypeParametersStart();
signatureWriter.writeFormalTypeParametersEnd(); signatureWriter.writeFormalTypeParametersEnd();
signatureWriter.writeParametersStart(); signatureWriter.writeParametersStart();
@@ -588,41 +567,30 @@ public class JetTypeMapper {
if(kind == OwnerKind.TRAIT_IMPL) { if(kind == OwnerKind.TRAIT_IMPL) {
ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration(); ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration();
assert containingDeclaration != null; assert containingDeclaration != null;
signatureWriter.writeParameterType(); signatureWriter.writeParameterType(JvmMethodParameterKind.THIS);
params.add(mapType(containingDeclaration.getDefaultType(), signatureWriter)); mapType(containingDeclaration.getDefaultType(), signatureWriter);
signatureWriter.writeParameterTypeEnd(); signatureWriter.writeParameterTypeEnd();
} }
if(descriptor.getReceiverParameter().exists()) { if(descriptor.getReceiverParameter().exists()) {
signatureWriter.writeParameterType(); signatureWriter.writeParameterType(JvmMethodParameterKind.RECEIVER);
params.add(mapType(descriptor.getReceiverParameter().getType(), signatureWriter)); mapType(descriptor.getReceiverParameter().getType(), signatureWriter);
signatureWriter.writeParameterTypeEnd(); signatureWriter.writeParameterTypeEnd();
} }
for (TypeParameterDescriptor typeParameterDescriptor : descriptor.getTypeParameters()) { for (TypeParameterDescriptor typeParameterDescriptor : descriptor.getTypeParameters()) {
if(typeParameterDescriptor.isReified()) { if(typeParameterDescriptor.isReified()) {
signatureWriter.writeParameterType(); signatureWriter.writeTypeInfoParameter();
params.add(TYPE_TYPEINFO);
visitAsmType(signatureWriter, TYPE_TYPEINFO, false);
signatureWriter.writeParameterTypeEnd();
} }
} }
signatureWriter.writeParametersEnd(); signatureWriter.writeParametersEnd();
signatureWriter.writeReturnType(); signatureWriter.writeReturnType();
Type returnType = mapType(descriptor.getOutType(), signatureWriter); mapType(descriptor.getOutType(), signatureWriter);
signatureWriter.writeReturnTypeEnd(); signatureWriter.writeReturnTypeEnd();
// TODO: proper generic signature JvmMethodSignature jvmMethodSignature = signatureWriter.makeJvmMethodSignature(name);
Method asmMethod = new Method(name, returnType, params.toArray(new Type[params.size()]));
JvmMethodSignature jvmMethodSignature = new JvmMethodSignature(
asmMethod,
signatureWriter.makeJavaString(),
signatureWriter.makeKotlinMethodTypeParameters(),
signatureWriter.makeKotlinParameterTypes(),
signatureWriter.makeKotlinReturnTypeSignature()
);
return new JvmPropertyAccessorSignature(jvmMethodSignature, jvmMethodSignature.getKotlinReturnType()); return new JvmPropertyAccessorSignature(jvmMethodSignature, jvmMethodSignature.getKotlinReturnType());
} }
@@ -633,9 +601,10 @@ public class JetTypeMapper {
return null; return null;
} }
BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD); // TODO: generics signature is not always needed
BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, true);
signatureWriter.writerFormalTypeParametersStart(); signatureWriter.writeFormalTypeParametersStart();
signatureWriter.writeFormalTypeParametersEnd(); signatureWriter.writeFormalTypeParametersEnd();
JetType outType = descriptor.getOutType(); JetType outType = descriptor.getOutType();
@@ -643,79 +612,77 @@ public class JetTypeMapper {
signatureWriter.writeParametersStart(); signatureWriter.writeParametersStart();
String name = PropertyCodegen.setterName(descriptor.getName()); String name = PropertyCodegen.setterName(descriptor.getName());
ArrayList<Type> params = new ArrayList<Type>();
if(kind == OwnerKind.TRAIT_IMPL) { if(kind == OwnerKind.TRAIT_IMPL) {
ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration(); ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration();
assert containingDeclaration != null; assert containingDeclaration != null;
signatureWriter.writeParameterType(); signatureWriter.writeParameterType(JvmMethodParameterKind.THIS);
params.add(mapType(containingDeclaration.getDefaultType(), signatureWriter)); mapType(containingDeclaration.getDefaultType(), signatureWriter);
signatureWriter.writeParameterTypeEnd(); signatureWriter.writeParameterTypeEnd();
} }
if(descriptor.getReceiverParameter().exists()) { if(descriptor.getReceiverParameter().exists()) {
signatureWriter.writeParameterType(); signatureWriter.writeParameterType(JvmMethodParameterKind.RECEIVER);
params.add(mapType(descriptor.getReceiverParameter().getType(), signatureWriter)); mapType(descriptor.getReceiverParameter().getType(), signatureWriter);
signatureWriter.writeParameterTypeEnd(); signatureWriter.writeParameterTypeEnd();
} }
for (TypeParameterDescriptor typeParameterDescriptor : descriptor.getTypeParameters()) { for (TypeParameterDescriptor typeParameterDescriptor : descriptor.getTypeParameters()) {
if(typeParameterDescriptor.isReified()) { if(typeParameterDescriptor.isReified()) {
signatureWriter.writeParameterType(); signatureWriter.writeTypeInfoParameter();
params.add(TYPE_TYPEINFO);
signatureWriter.writeParameterType();
visitAsmType(signatureWriter, TYPE_TYPEINFO, false);
signatureWriter.writeParameterTypeEnd();
} }
} }
signatureWriter.writeParameterType(); signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
params.add(mapType(outType, signatureWriter)); mapType(outType, signatureWriter);
signatureWriter.writeParameterTypeEnd(); signatureWriter.writeParameterTypeEnd();
signatureWriter.writeParametersEnd(); signatureWriter.writeParametersEnd();
signatureWriter.writeReturnType(); signatureWriter.writeVoidReturn();
visitAsmType(signatureWriter, Type.VOID_TYPE, false);
signatureWriter.writeReturnTypeEnd();
Method asmMethod = new Method(name, Type.VOID_TYPE, params.toArray(new Type[params.size()])); JvmMethodSignature jvmMethodSignature = signatureWriter.makeJvmMethodSignature(name);
JvmMethodSignature jvmMethodSignature = new JvmMethodSignature(
asmMethod,
signatureWriter.makeJavaString(),
signatureWriter.makeKotlinMethodTypeParameters(),
signatureWriter.makeKotlinParameterTypes(),
signatureWriter.makeKotlinReturnTypeSignature()
);
return new JvmPropertyAccessorSignature(jvmMethodSignature, jvmMethodSignature.getKotlinParameterType(jvmMethodSignature.getParameterCount() - 1)); return new JvmPropertyAccessorSignature(jvmMethodSignature, jvmMethodSignature.getKotlinParameterType(jvmMethodSignature.getParameterCount() - 1));
} }
private JvmMethodSignature mapConstructorSignature(ConstructorDescriptor descriptor, List<Type> valueParameterTypes) { private JvmMethodSignature mapConstructorSignature(ConstructorDescriptor descriptor) {
BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, true);
List<ValueParameterDescriptor> parameters = descriptor.getOriginal().getValueParameters(); List<ValueParameterDescriptor> parameters = descriptor.getOriginal().getValueParameters();
List<Type> parameterTypes = new ArrayList<Type>();
ClassDescriptor classDescriptor = descriptor.getContainingDeclaration(); ClassDescriptor classDescriptor = descriptor.getContainingDeclaration();
signatureWriter.writeFormalTypeParametersStart();
signatureWriter.writeFormalTypeParametersEnd();
signatureWriter.writeParametersStart();
if (CodegenUtil.hasThis0(classDescriptor)) { if (CodegenUtil.hasThis0(classDescriptor)) {
parameterTypes.add(mapType(CodegenUtil.getOuterClassDescriptor(classDescriptor).getDefaultType(), OwnerKind.IMPLEMENTATION)); signatureWriter.writeParameterType(JvmMethodParameterKind.THIS0);
mapType(CodegenUtil.getOuterClassDescriptor(classDescriptor).getDefaultType(), OwnerKind.IMPLEMENTATION, signatureWriter);
signatureWriter.writeParameterTypeEnd();
} }
if (CodegenUtil.requireTypeInfoConstructorArg(classDescriptor.getDefaultType())) { if (CodegenUtil.requireTypeInfoConstructorArg(classDescriptor.getDefaultType())) {
parameterTypes.add(TYPE_TYPEINFO); signatureWriter.writeTypeInfoParameter();
} }
for (ValueParameterDescriptor parameter : parameters) { for (ValueParameterDescriptor parameter : parameters) {
final Type type = mapType(parameter.getOutType()); signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
parameterTypes.add(type); mapType(parameter.getOutType(), signatureWriter);
valueParameterTypes.add(type); signatureWriter.writeParameterTypeEnd();
} }
Method method = new Method("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()])); signatureWriter.writeParametersEnd();
return new JvmMethodSignature(method, null, null, null, ""); // TODO: generics signature
signatureWriter.writeVoidReturn();
return signatureWriter.makeJvmMethodSignature("<init>");
} }
public CallableMethod mapToCallableMethod(ConstructorDescriptor descriptor, OwnerKind kind) { public CallableMethod mapToCallableMethod(ConstructorDescriptor descriptor, OwnerKind kind) {
List<Type> valueParameterTypes = new ArrayList<Type>(); final JvmMethodSignature method = mapConstructorSignature(descriptor);
final JvmMethodSignature method = mapConstructorSignature(descriptor, valueParameterTypes);
String owner = mapType(descriptor.getContainingDeclaration().getDefaultType(), kind).getInternalName(); String owner = mapType(descriptor.getContainingDeclaration().getDefaultType(), kind).getInternalName();
return new CallableMethod(owner, method, INVOKESPECIAL, valueParameterTypes); return new CallableMethod(owner, method, INVOKESPECIAL);
} }
static int getAccessModifiers(JetDeclaration p, int defaultFlags) { static int getAccessModifiers(JetDeclaration p, int defaultFlags) {
@@ -0,0 +1,15 @@
package org.jetbrains.jet.codegen;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
/**
* @author Stepan Koltsov
*/
public enum JvmMethodParameterKind {
VALUE,
THIS,
/** @see CodegenUtil#hasThis0(ClassDescriptor) */
THIS0,
RECEIVER,
TYPE_INFO,
}
@@ -0,0 +1,38 @@
package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull;
import org.objectweb.asm.Type;
/**
* @author Stepan Koltsov
*/
public class JvmMethodParameterSignature {
@NotNull
private final Type asmType;
@NotNull
private final String kotlinSignature;
@NotNull
private final JvmMethodParameterKind kind;
public JvmMethodParameterSignature(
@NotNull Type asmType, @NotNull String kotlinSignature, @NotNull JvmMethodParameterKind kind) {
this.asmType = asmType;
this.kotlinSignature = kotlinSignature;
this.kind = kind;
}
@NotNull
public Type getAsmType() {
return asmType;
}
@NotNull
public String getKotlinSignature() {
return kotlinSignature;
}
@NotNull
public JvmMethodParameterKind getKind() {
return kind;
}
}
@@ -2,8 +2,10 @@ package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.Method; import org.objectweb.asm.commons.Method;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@@ -11,37 +13,65 @@ import java.util.List;
*/ */
public class JvmMethodSignature { public class JvmMethodSignature {
@NotNull
private final Method asmMethod; private final Method asmMethod;
/** Null when we don't care about type parameters */ /** Null when we don't care about type parameters */
private final String genericsSignature; private final String genericsSignature;
private final String kotlinTypeParameter; private final String kotlinTypeParameter;
private final List<String> kotlinParameterTypes; @NotNull
private final List<JvmMethodParameterSignature> kotlinParameterTypes;
@NotNull @NotNull
private final String kotlinReturnType; private final String kotlinReturnType;
/**
* Generics info is generated. However it can be trivial (e.g. fields are null).
*/
private final boolean genericsAvailable;
public JvmMethodSignature(@NotNull Method asmMethod, @Nullable String genericsSignature, public JvmMethodSignature(@NotNull Method asmMethod, @Nullable String genericsSignature,
@Nullable String kotlinTypeParameters, @Nullable List<String> kotlinParameterTypes, @NotNull String kotlinReturnType) { @Nullable String kotlinTypeParameters, @NotNull List<JvmMethodParameterSignature> kotlinParameterTypes, @NotNull String kotlinReturnType) {
this.asmMethod = asmMethod; this.asmMethod = asmMethod;
this.genericsSignature = genericsSignature; this.genericsSignature = genericsSignature;
this.kotlinTypeParameter = kotlinTypeParameters; this.kotlinTypeParameter = kotlinTypeParameters;
this.kotlinParameterTypes = kotlinParameterTypes; this.kotlinParameterTypes = kotlinParameterTypes;
this.kotlinReturnType = kotlinReturnType; this.kotlinReturnType = kotlinReturnType;
this.genericsAvailable = true;
} }
public JvmMethodSignature(@NotNull Method asmMethod, @NotNull List<JvmMethodParameterSignature> kotlinParameterTypes) {
this.asmMethod = asmMethod;
this.genericsSignature = null;
this.kotlinTypeParameter = null;
this.kotlinParameterTypes = kotlinParameterTypes;
this.kotlinReturnType = "";
this.genericsAvailable = false;
}
private void checkGenericsAvailable() {
if (!genericsAvailable) {
// TODO: uncomment following line and fix all broken tests
//throw new IllegalStateException("incorrect call sequence");
}
}
@NotNull
public Method getAsmMethod() { public Method getAsmMethod() {
return asmMethod; return asmMethod;
} }
public String getGenericsSignature() { public String getGenericsSignature() {
checkGenericsAvailable();
return genericsSignature; return genericsSignature;
} }
public String getKotlinTypeParameter() { public String getKotlinTypeParameter() {
checkGenericsAvailable();
return kotlinTypeParameter; return kotlinTypeParameter;
} }
@Nullable @Nullable
public List<String> getKotlinParameterTypes() { public List<JvmMethodParameterSignature> getKotlinParameterTypes() {
checkGenericsAvailable();
return kotlinParameterTypes; return kotlinParameterTypes;
} }
@@ -52,15 +82,32 @@ public class JvmMethodSignature {
@NotNull @NotNull
public String getKotlinParameterType(int i) { public String getKotlinParameterType(int i) {
checkGenericsAvailable();
if (kotlinParameterTypes == null) { if (kotlinParameterTypes == null) {
return ""; return "";
} else { } else {
return kotlinParameterTypes.get(i); return kotlinParameterTypes.get(i).getKotlinSignature();
} }
} }
@NotNull @NotNull
public String getKotlinReturnType() { public String getKotlinReturnType() {
checkGenericsAvailable();
return kotlinReturnType; return kotlinReturnType;
} }
public List<Type> getValueParameterTypes() {
List<Type> r = new ArrayList<Type>(kotlinParameterTypes.size());
for (JvmMethodParameterSignature p : kotlinParameterTypes) {
if (p.getKind() == JvmMethodParameterKind.VALUE) {
r.add(p.getAsmType());
}
}
return r;
}
@NotNull
public String getName() {
return asmMethod.getName();
}
} }