package me.tomassetti.turin.compiler; import com.google.common.collect.ImmutableList; import me.tomassetti.turin.classloading.TurinClassLoader; import me.tomassetti.turin.classloading.ClassFileDefinition; import me.tomassetti.turin.parser.Parser; import me.tomassetti.turin.resolvers.*; import me.tomassetti.turin.resolvers.jdk.JdkTypeResolver; import me.tomassetti.turin.parser.ast.TurinFile; import org.junit.Test; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.List; import static org.junit.Assert.assertEquals; public class FunctionsCompilationTest { private SymbolResolver getResolverFor(TurinFile turinFile) { return new ComposedSymbolResolver(ImmutableList.of(new InFileSymbolResolver(JdkTypeResolver.getInstance()), new SrcSymbolResolver(ImmutableList.of(turinFile)))); } @Test public void compileFunctionWithBlockBody() throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException, IOException { TurinFile turinFile = new Parser().parse(this.getClass().getResourceAsStream("/function_with_block_body.to")); // generate bytecode Compiler instance = new Compiler(getResolverFor(turinFile), new Compiler.Options()); List<ClassFileDefinition> classFileDefinitions = instance.compile(turinFile, new AbstractCompilerTest.MyErrorCollector()); assertEquals(1, classFileDefinitions.size()); TurinClassLoader turinClassLoader = new TurinClassLoader(); Class functionClass = turinClassLoader.addClass(classFileDefinitions.get(0).getName(), classFileDefinitions.get(0).getBytecode()); assertEquals(0, functionClass.getConstructors().length); Method invoke = functionClass.getMethod("invoke", int.class, int.class); assertEquals(10, invoke.invoke(null, 7, 3)); } @Test public void compileFunctionWithExpressionBody() throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException, IOException { TurinFile turinFile = new Parser().parse(this.getClass().getResourceAsStream("/function_with_expression_body.to")); // generate bytecode Compiler instance = new Compiler(getResolverFor(turinFile), new Compiler.Options()); List<ClassFileDefinition> classFileDefinitions = instance.compile(turinFile, new AbstractCompilerTest.MyErrorCollector()); assertEquals(1, classFileDefinitions.size()); TurinClassLoader turinClassLoader = new TurinClassLoader(); Class functionClass = turinClassLoader.addClass(classFileDefinitions.get(0).getName(), classFileDefinitions.get(0).getBytecode()); assertEquals(0, functionClass.getConstructors().length); Method invoke = functionClass.getMethod("invoke"); assertEquals("foo", invoke.invoke(null)); } @Test public void compileFunctionReturningVoid() throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException, IOException { TurinFile turinFile = new Parser().parse(this.getClass().getResourceAsStream("/call_void_function.to")); // generate bytecode Compiler instance = new Compiler(getResolverFor(turinFile), new Compiler.Options()); List<ClassFileDefinition> classFileDefinitions = instance.compile(turinFile, new AbstractCompilerTest.MyErrorCollector()); assertEquals(2, classFileDefinitions.size()); TurinClassLoader turinClassLoader = new TurinClassLoader(); Class functionClass = turinClassLoader.addClass(classFileDefinitions.get(0).getName(), classFileDefinitions.get(0).getBytecode()); Class programClass = turinClassLoader.addClass(classFileDefinitions.get(1).getName(), classFileDefinitions.get(1).getBytecode()); Method main = programClass.getMethod("main", String[].class); main.invoke(null, (Object)new String[]{}); } }