default params of constructors (untested because frontend is not ready yet)
This commit is contained in:
@@ -81,9 +81,14 @@ public class CallableMethod implements Callable {
|
||||
public void invokeWithDefault(InstructionAdapter v, int mask) {
|
||||
v.iconst(mask);
|
||||
String desc = getSignature().getDescriptor().replace(")", "I)");
|
||||
if(getInvokeOpcode() != Opcodes.INVOKESTATIC)
|
||||
desc = desc.replace("(", "(L" + getOwner() + ";");
|
||||
v.visitMethodInsn(Opcodes.INVOKESTATIC, getInvokeOpcode() == Opcodes.INVOKEINTERFACE ? getOwner() + "$$TImpl" : getOwner(), getSignature().getName() + "$default", desc);
|
||||
if("<init>".equals(getSignature().getName())) {
|
||||
v.visitMethodInsn(Opcodes.INVOKESPECIAL, getOwner(), "<init>", desc);
|
||||
}
|
||||
else {
|
||||
if(getInvokeOpcode() != Opcodes.INVOKESTATIC)
|
||||
desc = desc.replace("(", "(L" + getOwner() + ";");
|
||||
v.visitMethodInsn(Opcodes.INVOKESTATIC, getInvokeOpcode() == Opcodes.INVOKEINTERFACE ? getOwner() + "$$TImpl" : getOwner(), getSignature().getName() + "$default", desc);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isNeedsThis() {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
@@ -226,7 +227,7 @@ public class FunctionCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
static void generateDefaultIfNeeded(CodegenContext.MethodContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, FunctionDescriptor functionDescriptor, OwnerKind kind) {
|
||||
static void generateDefaultIfNeeded(CodegenContext.MethodContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, @Nullable FunctionDescriptor functionDescriptor, OwnerKind kind) {
|
||||
DeclarationDescriptor contextClass = owner.getContextDescriptor().getContainingDeclaration();
|
||||
|
||||
if(kind != OwnerKind.TRAIT_IMPL) {
|
||||
@@ -242,15 +243,18 @@ public class FunctionCodegen {
|
||||
}
|
||||
|
||||
boolean needed = false;
|
||||
for (ValueParameterDescriptor parameterDescriptor : functionDescriptor.getValueParameters()) {
|
||||
if(parameterDescriptor.hasDefaultValue()) {
|
||||
needed = true;
|
||||
break;
|
||||
if(functionDescriptor != null) {
|
||||
for (ValueParameterDescriptor parameterDescriptor : functionDescriptor.getValueParameters()) {
|
||||
if(parameterDescriptor.hasDefaultValue()) {
|
||||
needed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(needed) {
|
||||
boolean hasReceiver = functionDescriptor.getReceiverParameter().exists();
|
||||
ReceiverDescriptor receiverParameter = functionDescriptor.getReceiverParameter();
|
||||
boolean hasReceiver = receiverParameter.exists();
|
||||
boolean isStatic = kind == OwnerKind.NAMESPACE;
|
||||
|
||||
if(kind == OwnerKind.TRAIT_IMPL) {
|
||||
@@ -265,9 +269,10 @@ public class FunctionCodegen {
|
||||
state.getTypeMapper().mapType(((ClassDescriptor) contextClass).getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
|
||||
|
||||
String descriptor = jvmSignature.getDescriptor().replace(")","I)");
|
||||
if(!isStatic)
|
||||
boolean isConstructor = "<init>".equals(jvmSignature.getName());
|
||||
if(!isStatic && !isConstructor)
|
||||
descriptor = descriptor.replace("(","(L" + ownerInternalName + ";");
|
||||
final MethodVisitor mv = v.newMethod(null, flags | ACC_STATIC, jvmSignature.getName() + "$default", descriptor, null, null);
|
||||
final MethodVisitor mv = v.newMethod(null, flags | (isConstructor ? 0 : ACC_STATIC), isConstructor ? "<init>" : jvmSignature.getName() + "$default", descriptor, null, null);
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
if (v.generateCode()) {
|
||||
mv.visitCode();
|
||||
@@ -278,33 +283,28 @@ public class FunctionCodegen {
|
||||
|
||||
int var = 0;
|
||||
if(!isStatic) {
|
||||
frameMap.enterTemp();
|
||||
var++;
|
||||
}
|
||||
|
||||
Type receiverType = receiverParameter.exists() ? state.getTypeMapper().mapType(receiverParameter.getType()) : Type.DOUBLE_TYPE;
|
||||
if(hasReceiver) {
|
||||
frameMap.enterTemp();
|
||||
var++;
|
||||
var += receiverType.getSize();
|
||||
}
|
||||
|
||||
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getTypeParameters();
|
||||
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
|
||||
int slot = frameMap.enterTemp();
|
||||
codegen.addTypeParameter(typeParameterDescriptor, StackValue.local(slot, JetTypeMapper.TYPE_TYPEINFO));
|
||||
var++;
|
||||
if(typeParameterDescriptor.isReified()) {
|
||||
codegen.addTypeParameter(typeParameterDescriptor, StackValue.local(var++, JetTypeMapper.TYPE_TYPEINFO));
|
||||
}
|
||||
}
|
||||
|
||||
Type[] argTypes = jvmSignature.getArgumentTypes();
|
||||
List<ValueParameterDescriptor> paramDescrs = functionDescriptor.getValueParameters();
|
||||
for (int i = 0; i < paramDescrs.size(); i++) {
|
||||
ValueParameterDescriptor parameter = paramDescrs.get(i);
|
||||
int size = argTypes[i + (hasReceiver ? 1 : 0)].getSize();
|
||||
var += size;
|
||||
frameMap.enter(parameter, size);
|
||||
}
|
||||
|
||||
frameMap.enterTemp();
|
||||
|
||||
int maskIndex = var;
|
||||
|
||||
var = 0;
|
||||
@@ -313,7 +313,8 @@ public class FunctionCodegen {
|
||||
}
|
||||
|
||||
if(hasReceiver) {
|
||||
mv.visitVarInsn(ALOAD, var++); // todo - Long etc.
|
||||
iv.load(var, receiverType);
|
||||
var += receiverType.getSize();
|
||||
}
|
||||
|
||||
int extra = hasReceiver ? 1 : 0;
|
||||
|
||||
@@ -269,7 +269,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
CodegenContext.ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor);
|
||||
|
||||
Method method;
|
||||
Method constructorMethod;
|
||||
CallableMethod callableMethod;
|
||||
if (constructorDescriptor == null) {
|
||||
List<Type> parameterTypes = new ArrayList<Type>();
|
||||
@@ -282,17 +282,17 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
parameterTypes.add(JetTypeMapper.TYPE_TYPEINFO);
|
||||
}
|
||||
|
||||
method = new Method("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
||||
callableMethod = new CallableMethod("", method, Opcodes.INVOKESPECIAL, Collections.<Type>emptyList());
|
||||
constructorMethod = new Method("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
||||
callableMethod = new CallableMethod("", constructorMethod, Opcodes.INVOKESPECIAL, Collections.<Type>emptyList());
|
||||
}
|
||||
else {
|
||||
callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, kind);
|
||||
method = callableMethod.getSignature();
|
||||
constructorMethod = callableMethod.getSignature();
|
||||
}
|
||||
|
||||
ObjectOrClosureCodegen closure = context.closure;
|
||||
if(closure != null) {
|
||||
final List<Type> consArgTypes = new LinkedList<Type>(Arrays.asList(method.getArgumentTypes()));
|
||||
final List<Type> consArgTypes = new LinkedList<Type>(Arrays.asList(constructorMethod.getArgumentTypes()));
|
||||
|
||||
int insert = 0;
|
||||
if(closure.captureThis) {
|
||||
@@ -319,11 +319,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
method = new Method("<init>", Type.VOID_TYPE, consArgTypes.toArray(new Type[consArgTypes.size()]));
|
||||
constructorMethod = new Method("<init>", Type.VOID_TYPE, consArgTypes.toArray(new Type[consArgTypes.size()]));
|
||||
}
|
||||
|
||||
int flags = Opcodes.ACC_PUBLIC; // TODO
|
||||
final MethodVisitor mv = v.newMethod(myClass, flags, "<init>", method.getDescriptor(), null, null);
|
||||
final MethodVisitor mv = v.newMethod(myClass, flags, "<init>", constructorMethod.getDescriptor(), null, null);
|
||||
if (!v.generateCode()) return;
|
||||
|
||||
mv.visitCode();
|
||||
@@ -470,6 +470,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
mv.visitInsn(Opcodes.RETURN);
|
||||
mv.visitMaxs(0, 0);
|
||||
mv.visitEnd();
|
||||
|
||||
FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod, constructorDescriptor, OwnerKind.IMPLEMENTATION );
|
||||
}
|
||||
|
||||
private void generateTraitMethods(ExpressionCodegen codegen) {
|
||||
|
||||
Reference in New Issue
Block a user