diff --git a/idea/META-INF/plugin.xml b/idea/META-INF/plugin.xml new file mode 100644 index 00000000000..09db9b20e72 --- /dev/null +++ b/idea/META-INF/plugin.xml @@ -0,0 +1,23 @@ + + Plugin name here + short description of the plugin + 1.0 + YourCompany + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/idea/idea.iml b/idea/idea.iml index d01e54ca4d0..4c1ad0fba3d 100644 --- a/idea/idea.iml +++ b/idea/idea.iml @@ -1,16 +1,32 @@ + + + + + + + - + - + + + + + + + + + + diff --git a/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 7c453ba3d0d..072be3d077a 100644 --- a/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -1,5 +1,6 @@ package org.jetbrains.jet.codegen; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; @@ -7,6 +8,7 @@ import org.jetbrains.jet.lang.psi.JetDeclarationWithBody; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetNamedFunction; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.types.JetTypeImpl; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; @@ -15,6 +17,7 @@ import org.objectweb.asm.commons.InstructionAdapter; import org.objectweb.asm.commons.Method; import java.util.List; +import java.util.Set; /** * @author max @@ -41,15 +44,41 @@ public class FunctionCodegen { ClassContext funContext = owner.intoFunction(functionDescriptor); final JetExpression bodyExpression = f.getBodyExpression(); - generatedMethod(bodyExpression, jvmMethod, funContext, functionDescriptor.getValueParameters(), functionDescriptor.getTypeParameters()); + generatedMethod(bodyExpression, jvmMethod, funContext, functionDescriptor); + } + + private void generateBridgeMethod(Method function, Method overriden) + { + int flags = Opcodes.ACC_PUBLIC; // TODO. + + final MethodVisitor mv = v.visitMethod(flags, function.getName(), overriden.getDescriptor(), null, null); + mv.visitCode(); + + Type[] argTypes = function.getArgumentTypes(); + InstructionAdapterEx iv = new InstructionAdapterEx(mv); + iv.load(0, JetTypeMapper.TYPE_OBJECT); + for (int i = 0, reg = 1; i < argTypes.length; i++) { + Type argType = argTypes[i]; + iv.load(reg, argType); + reg += argType.getSize(); + } + + iv.invokevirtual(state.getTypeMapper().jvmName((ClassDescriptor) owner.getContextDescriptor(), OwnerKind.IMPLEMENTATION), function.getName(), function.getDescriptor()); + if(JetTypeMapper.isPrimitive(function.getReturnType()) && !JetTypeMapper.isPrimitive(overriden.getReturnType())) + iv.valueOf(function.getReturnType()); + iv.areturn(overriden.getReturnType()); + mv.visitMaxs(0, 0); + mv.visitEnd(); } private void generatedMethod(JetExpression bodyExpressions, Method jvmSignature, ClassContext context, - List paramDescrs, - List typeParameters) + FunctionDescriptor functionDescriptor) { + List paramDescrs = functionDescriptor.getValueParameters(); + List typeParameters = functionDescriptor.getTypeParameters(); + int flags = Opcodes.ACC_PUBLIC; // TODO. OwnerKind kind = context.getContextKind(); @@ -99,6 +128,16 @@ public class FunctionCodegen { } mv.visitMaxs(0, 0); mv.visitEnd(); + + Set overriddenFunctions = functionDescriptor.getOverriddenFunctions(); + if(overriddenFunctions.size() > 0) { + for (FunctionDescriptor overriddenFunction : overriddenFunctions) { + // TODO should we check params here as well? + if(!JetTypeImpl.equalTypes(overriddenFunction.getReturnType(), functionDescriptor.getReturnType(), JetTypeImpl.EMPTY_AXIOMS)) { + generateBridgeMethod(jvmSignature, state.getTypeMapper().mapSignature(overriddenFunction.getName(), overriddenFunction)); + } + } + } } } diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeImpl.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeImpl.java index 202f16c9628..ac57307b37f 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeImpl.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeImpl.java @@ -17,7 +17,7 @@ import java.util.List; */ public final class JetTypeImpl extends AnnotatedImpl implements JetType { - private static final HashBiMap EMPTY_AXIOMS = HashBiMap.create(); + public static final HashBiMap EMPTY_AXIOMS = HashBiMap.create(); private final TypeConstructor constructor; private final List arguments; diff --git a/idea/testData/codegen/bridge.jet b/idea/testData/codegen/bridge.jet new file mode 100644 index 00000000000..22f30c592e1 --- /dev/null +++ b/idea/testData/codegen/bridge.jet @@ -0,0 +1,15 @@ +import java.lang.Integer + +class C { + fun f(): Any = "C f" +} + +class D() : C { + fun f(): String = "D f" +} + +fun box(): String{ + val d : C = D() + if(d.f() != "D f") return "fail f" + return "OK" +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/codegen/BridgeMethodGenTest.java b/idea/tests/org/jetbrains/jet/codegen/BridgeMethodGenTest.java new file mode 100644 index 00000000000..2f89c65b0e7 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/codegen/BridgeMethodGenTest.java @@ -0,0 +1,9 @@ +package org.jetbrains.jet.codegen; + +import java.util.List; + +public class BridgeMethodGenTest extends CodegenTestCase { + public void testBridgeMethod () throws Exception { + blackBoxFile("bridge.jet"); + } +}