return 42
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user