return 42

This commit is contained in:
Dmitry Jemerov
2011-02-25 19:14:11 +03:00
parent 8f1f89cca8
commit 8e6c2995d0
4 changed files with 57 additions and 4 deletions
@@ -4,6 +4,7 @@ import gnu.trove.TObjectIntHashMap;
import org.jetbrains.jet.lang.psi.*;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
@@ -230,6 +231,18 @@ public class ExpressionCodegen extends JetVisitor {
}
@Override
public void visitReturnExpression(JetReturnExpression expression) {
final JetExpression returnedExpression = expression.getReturnedExpression();
if (returnedExpression != null) {
returnedExpression.accept(this);
v.visitInsn(Opcodes.ARETURN);
}
else {
v.visitInsn(Opcodes.RETURN);
}
}
private Type getType(JetProperty var) {
return InstructionAdapter.OBJECT_TYPE; // TODO:
}
@@ -25,14 +25,33 @@ public class FunctionCodegen {
for (int i = 0; i < parameters.size(); i++) {
parameterTypes[i] = mapTypeReference(parameters.get(i).getTypeReference());
}
Method method = new Method(f.getName(), Type.VOID_TYPE, parameterTypes);
final JetTypeReference returnTypeRef = f.getReturnTypeRef();
Type returnType = returnTypeRef == null ? Type.VOID_TYPE : mapTypeReference(returnTypeRef);
Method method = new Method(f.getName(), returnType, parameterTypes);
final MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
method.getName(), method.getDescriptor(), null, null);
mv.visitCode();
mv.visitInsn(Opcodes.RETURN);
final JetExpression bodyExpression = f.getBodyExpression();
bodyExpression.accept(new ExpressionCodegen(mv));
if (needReturn(bodyExpression)) {
mv.visitInsn(Opcodes.RETURN);
}
mv.visitMaxs(0, 0);
mv.visitEnd();
}
private boolean needReturn(JetExpression bodyExpression) {
if (bodyExpression instanceof JetBlockExpression) {
final List<JetElement> statements = ((JetBlockExpression) bodyExpression).getStatements();
if (statements.size() == 0) {
return true;
}
final JetElement jetElement = statements.get(statements.size() - 1);
return !(jetElement instanceof JetReturnExpression);
}
return false;
}
private Type mapTypeReference(JetTypeReference typeRef) {
if (typeRef == null) {
throw new UnsupportedOperationException("Cannot evaluate type for parameter with no type ref");
@@ -53,6 +72,9 @@ public class FunctionCodegen {
if ("String".equals(referencedName)) {
return Type.getType(String.class);
}
if ("Int".equals(referencedName)) {
return Type.getType(Integer.class);
}
}
throw new UnsupportedOperationException("Unknown type " + typeRef);
+1
View File
@@ -0,0 +1 @@
fun f() : Int { return 42; }
@@ -25,12 +25,25 @@ public class NamespaceGenTest extends LightCodeInsightFixtureTestCase {
System.out.println(text);
final Class aClass = generateToClass(namespace, codegen);
final Method[] methods = aClass.getMethods();
final Method main = methods[0];
final Method main = firstMethod(aClass);
Object[] args = new Object[] { new String[0] };
main.invoke(null, args);
}
public void testReturnOne() throws Exception {
myFixture.configureByFile(JetParsingTest.getTestDataDir() + "/codegen/returnOne.jet");
JetFile jetFile = (JetFile) myFixture.getFile();
JetNamespace namespace = jetFile.getRootNamespace();
NamespaceCodegen codegen = new NamespaceCodegen();
final String text = generateToText(namespace, codegen);
System.out.println(text);
final Class aClass = generateToClass(namespace, codegen);
final Method main = firstMethod(aClass);
final Object returnValue = main.invoke(null, new Object[0]);
assertEquals(new Integer(42), returnValue);
}
private static String generateToText(JetNamespace namespace, NamespaceCodegen codegen) {
StringWriter writer = new StringWriter();
codegen.generate(namespace, new TraceClassVisitor(new PrintWriter(writer)));
@@ -46,6 +59,10 @@ public class NamespaceGenTest extends LightCodeInsightFixtureTestCase {
return aClass;
}
private static Method firstMethod(Class aClass) {
return aClass.getMethods()[0];
}
private static class MyClassLoader extends ClassLoader {
public MyClassLoader(ClassLoader parent) {
super(parent);