return 42
This commit is contained in:
@@ -4,6 +4,7 @@ import gnu.trove.TObjectIntHashMap;
|
|||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
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) {
|
private Type getType(JetProperty var) {
|
||||||
return InstructionAdapter.OBJECT_TYPE; // TODO:
|
return InstructionAdapter.OBJECT_TYPE; // TODO:
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,14 +25,33 @@ public class FunctionCodegen {
|
|||||||
for (int i = 0; i < parameters.size(); i++) {
|
for (int i = 0; i < parameters.size(); i++) {
|
||||||
parameterTypes[i] = mapTypeReference(parameters.get(i).getTypeReference());
|
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,
|
final MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
|
||||||
method.getName(), method.getDescriptor(), null, null);
|
method.getName(), method.getDescriptor(), null, null);
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
|
final JetExpression bodyExpression = f.getBodyExpression();
|
||||||
|
bodyExpression.accept(new ExpressionCodegen(mv));
|
||||||
|
if (needReturn(bodyExpression)) {
|
||||||
mv.visitInsn(Opcodes.RETURN);
|
mv.visitInsn(Opcodes.RETURN);
|
||||||
|
}
|
||||||
|
mv.visitMaxs(0, 0);
|
||||||
mv.visitEnd();
|
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) {
|
private Type mapTypeReference(JetTypeReference typeRef) {
|
||||||
if (typeRef == null) {
|
if (typeRef == null) {
|
||||||
throw new UnsupportedOperationException("Cannot evaluate type for parameter with no type ref");
|
throw new UnsupportedOperationException("Cannot evaluate type for parameter with no type ref");
|
||||||
@@ -53,6 +72,9 @@ public class FunctionCodegen {
|
|||||||
if ("String".equals(referencedName)) {
|
if ("String".equals(referencedName)) {
|
||||||
return Type.getType(String.class);
|
return Type.getType(String.class);
|
||||||
}
|
}
|
||||||
|
if ("Int".equals(referencedName)) {
|
||||||
|
return Type.getType(Integer.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new UnsupportedOperationException("Unknown type " + typeRef);
|
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);
|
System.out.println(text);
|
||||||
|
|
||||||
final Class aClass = generateToClass(namespace, codegen);
|
final Class aClass = generateToClass(namespace, codegen);
|
||||||
final Method[] methods = aClass.getMethods();
|
final Method main = firstMethod(aClass);
|
||||||
final Method main = methods[0];
|
|
||||||
Object[] args = new Object[] { new String[0] };
|
Object[] args = new Object[] { new String[0] };
|
||||||
main.invoke(null, args);
|
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) {
|
private static String generateToText(JetNamespace namespace, NamespaceCodegen codegen) {
|
||||||
StringWriter writer = new StringWriter();
|
StringWriter writer = new StringWriter();
|
||||||
codegen.generate(namespace, new TraceClassVisitor(new PrintWriter(writer)));
|
codegen.generate(namespace, new TraceClassVisitor(new PrintWriter(writer)));
|
||||||
@@ -46,6 +59,10 @@ public class NamespaceGenTest extends LightCodeInsightFixtureTestCase {
|
|||||||
return aClass;
|
return aClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Method firstMethod(Class aClass) {
|
||||||
|
return aClass.getMethods()[0];
|
||||||
|
}
|
||||||
|
|
||||||
private static class MyClassLoader extends ClassLoader {
|
private static class MyClassLoader extends ClassLoader {
|
||||||
public MyClassLoader(ClassLoader parent) {
|
public MyClassLoader(ClassLoader parent) {
|
||||||
super(parent);
|
super(parent);
|
||||||
|
|||||||
Reference in New Issue
Block a user