package me.tomassetti.turin.compiler; import me.tomassetti.turin.classloading.ClassFileDefinition; import me.tomassetti.turin.classloading.TurinClassLoader; import me.tomassetti.turin.parser.Parser; import me.tomassetti.turin.parser.ast.TurinFile; import org.junit.Test; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.Map; import static org.junit.Assert.assertEquals; public class ConstructorsAndExtensionCompilationTest extends AbstractCompilerTest { @Test public void theGeneratedConstructorOfTheDerivedTypeTakesTheExpectedParameters() throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException, IOException { TurinFile turinFile = new Parser().parse(this.getClass().getResourceAsStream("/scenarios/constructor_extends1/points.to")); // generate bytecode Compiler instance = new Compiler(getResolverFor(turinFile), new Compiler.Options()); List<ClassFileDefinition> classFileDefinitions = instance.compile(turinFile, new MyErrorCollector()); assertEquals(6, classFileDefinitions.size()); TurinClassLoader turinClassLoader = new TurinClassLoader(); Class pointClass = turinClassLoader.addClass(classFileDefinitions.get(0)); saveClassFile(classFileDefinitions.get(0), "const"); Class labelledPointClass = turinClassLoader.addClass(classFileDefinitions.get(1)); saveClassFile(classFileDefinitions.get(1), "const"); assertEquals(1, labelledPointClass.getConstructors().length); Constructor constructor = labelledPointClass.getConstructors()[0]; assertEquals(4, constructor.getParameterCount()); assertEquals(int.class, constructor.getParameterTypes()[0]); assertEquals(int.class, constructor.getParameterTypes()[1]); assertEquals(String.class, constructor.getParameterTypes()[2]); assertEquals(Map.class, constructor.getParameterTypes()[3]); } @Test public void theGeneratedConstructorOfTheDerivedTypeWorksAsExpected() throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException, IOException { TurinFile turinFile = new Parser().parse(this.getClass().getResourceAsStream("/scenarios/constructor_extends1/points.to")); // generate bytecode Compiler instance = new Compiler(getResolverFor(turinFile), new Compiler.Options()); List<ClassFileDefinition> classFileDefinitions = instance.compile(turinFile, new MyErrorCollector()); assertEquals(6, classFileDefinitions.size()); TurinClassLoader turinClassLoader = new TurinClassLoader(); Class pointClass = turinClassLoader.addClass(classFileDefinitions.get(0)); Class labelledPointClass = turinClassLoader.addClass(classFileDefinitions.get(1)); Class foo1Class = turinClassLoader.addClass(classFileDefinitions.get(2)); Class foo2Class = turinClassLoader.addClass(classFileDefinitions.get(3)); Class foo3Class = turinClassLoader.addClass(classFileDefinitions.get(4)); Class foo4Class = turinClassLoader.addClass(classFileDefinitions.get(5)); Object res1 = foo1Class.getMethod("invoke", new Class[]{}).invoke(null); assertEquals(1, res1.getClass().getMethod("getX").invoke(res1)); assertEquals(2, res1.getClass().getMethod("getY").invoke(res1)); assertEquals(0, res1.getClass().getMethod("getZ").invoke(res1)); assertEquals("hi", res1.getClass().getMethod("getLabel").invoke(res1)); Object res2 = foo2Class.getMethod("invoke", new Class[]{}).invoke(null); assertEquals(1, res2.getClass().getMethod("getX").invoke(res2)); assertEquals(2, res2.getClass().getMethod("getY").invoke(res2)); assertEquals(3, res2.getClass().getMethod("getZ").invoke(res2)); assertEquals("hi", res2.getClass().getMethod("getLabel").invoke(res2)); Object res3 = foo3Class.getMethod("invoke", new Class[]{}).invoke(null); assertEquals(1, res3.getClass().getMethod("getX").invoke(res3)); assertEquals(2, res3.getClass().getMethod("getY").invoke(res3)); assertEquals(3, res3.getClass().getMethod("getZ").invoke(res3)); assertEquals("hi", res3.getClass().getMethod("getLabel").invoke(res3)); Object res4 = foo4Class.getMethod("invoke", new Class[]{}).invoke(null); assertEquals(1, res4.getClass().getMethod("getX").invoke(res4)); assertEquals(2, res4.getClass().getMethod("getY").invoke(res4)); assertEquals(0, res4.getClass().getMethod("getZ").invoke(res4)); assertEquals("hi", res4.getClass().getMethod("getLabel").invoke(res4)); } }