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