added some e2e tests for CodeGenFiles with reflections

This commit is contained in:
JonathanFleischmann 2024-06-27 19:10:43 +02:00
parent a9bebece45
commit 78a34b915e
79 changed files with 4439 additions and 14 deletions

BIN
output/Operators.class Normal file

Binary file not shown.

View File

@ -75,6 +75,12 @@
<version>RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<!-- JUnit 5 end -->
<dependency>
<groupId>commons-cli</groupId>

View File

@ -223,4 +223,23 @@ public class TypedClass implements TypedNode {
return cw.toByteArray();
}
public ClassWriter codeGenClassWriter() {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
ClassContext ctx = new ClassContext(className, cw);
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, className, null, "java/lang/Object", null);
for (TypedDeclaration declaration : typedDeclarations) {
declaration.codeGen(cw);
}
for (TypedConstructor constructor : typedConstructors) {
constructor.codeGen(ctx);
}
for (TypedMethod m : typedMethods) {
m.codeGen(ctx);
}
return cw;
}
}

View File

@ -1,5 +1,12 @@
import e2e.BytecodeTestUtil;
import de.maishai.Compiler;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import testResources.CodeGen.BytecodeTestUtil;
import testResources.CodeGen.Features.*;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ -12,14 +19,32 @@ public class CodegeneratorTests {
// assertEquals(AbstractSyntax_PublicClass.get(), resultBytecode);
// }
@Test
public void testMethodCall() {
assertDoesNotThrow(() -> {
BytecodeTestUtil testUtility = new BytecodeTestUtil("src/test/testFiles/JavaTestfilesFeatures/MethodCall.java", "MethodCall");
// @Test
// public void testMethodCall() {
// assertDoesNotThrow(() -> {
// BytecodeTestUtil testUtility = new BytecodeTestUtil("src/test/testFiles/ASTandTypedASTFeatures/MethodCall.java", "MethodCall");
//
// assertEquals(0, testUtility.invokeMethod("method", null));
// assertEquals(1, testUtility.invokeMethod("method1", new Class<?>[]{int.class}, 1));
// assertEquals(3, testUtility.invokeMethod("method2", new Class<?>[]{int.class, int.class}, 1, 2));
// });
// }
assertEquals(0, testUtility.invokeMethod("method", null));
assertEquals(1, testUtility.invokeMethod("method1", new Class<?>[]{int.class}, 1));
assertEquals(3, testUtility.invokeMethod("method2", new Class<?>[]{int.class, int.class}, 1, 2));
});
}
// @Test
// public void testBreak() {
// ByteCode_Break ByteCode_Break = new ByteCode_Break();
// Assertions.assertTrue(ByteCode_Break.allTestsSuccessful());
// }
// @Test
// public void testClass() {
// ByteCode_Class ByteCode_Class = new ByteCode_Class();
// Assertions.assertTrue(ByteCode_Class.allTestsSuccessful());
// }
// @Test
// public void testClassObjects() {
// ByteCode_ClassObjects ByteCode_ClassObjects = new ByteCode_ClassObjects();
// Assertions.assertTrue(ByteCode_ClassObjects.allTestsSuccessful());
// }
}

View File

@ -217,7 +217,4 @@ public class ScannerParserTests {
Program resultAst = Compiler.generateASTFromFiles(List.of("src/test/testFiles/JavaTestfilesFeatures/While.java"));
assertEquals(AST_While.get(), resultAst);
}
//TODO: Anschauen: Warum sind die FieldVarAccess von Methodenaufrufen manchmal fields und manchmal ned (z.B. bei ComplexCalls)
// Warum geht MultipleClasses nicht?
}

View File

@ -0,0 +1,177 @@
package testResources.CodeGen;
import de.maishai.Compiler;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class BytecodeTestUtil {
private Class<?> clazz;
private Object instance;
public BytecodeTestUtil(List<String> sourceFilePaths, String className) throws Exception {
byte[] resultBytecode = Compiler.generateByteCodeArrayFromFiles(sourceFilePaths).get(0);
ClassLoader classLoader = new ClassLoader() {
@Override
protected Class<?> findClass(String name) {
return defineClass(name, resultBytecode, 0, resultBytecode.length);
}
};
clazz = classLoader.loadClass(className);
this.instance = clazz.getDeclaredConstructor().newInstance();
}
public int getConstructorCount() {
return clazz.getDeclaredConstructors().length;
}
public List<String> getConstructorNames() {
List<String> constructorNames = new ArrayList<>();
for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
constructorNames.add(constructor.getName());
}
return constructorNames;
}
public int getConstructorParameterCount(int index) {
return clazz.getDeclaredConstructors()[index].getParameterCount();
}
public List<String> getConstructorParameterTypes(int index) {
List<String> parameterTypes = new ArrayList<>();
for (Class<?> parameterType : clazz.getDeclaredConstructors()[index].getParameterTypes()) {
parameterTypes.add(parameterType.getSimpleName());
}
return parameterTypes;
}
public Object invokeConstructor(Class<?>[] parameterTypes, Object... args) throws Exception {
return clazz.getDeclaredConstructor(parameterTypes).newInstance(args);
}
public int getMethodCount() {
return clazz.getDeclaredMethods().length;
}
public List<String> getMethodNames() {
List<String> methodNames = new ArrayList<>();
for (Method method : clazz.getDeclaredMethods()) {
methodNames.add(method.getName());
}
return methodNames;
}
public String getMethodReturnType(String methodName, Class<?>... params) throws Exception {
return clazz.getMethod(methodName, params).getReturnType().getSimpleName();
}
public int getMethodParameterCount(String methodName, Class<?>... params) throws Exception {
return clazz.getMethod(methodName, params).getParameterCount();
}
public List<String> getMethodParameterTypes(String methodName, Class<?>... params) throws Exception {
List<String> parameterTypes = new ArrayList<>();
for (Class<?> parameterType : clazz.getMethod(methodName, params).getParameterTypes()) {
parameterTypes.add(parameterType.getSimpleName());
}
return parameterTypes;
}
public Object invokeMethod(String methodName, Class<?>[] parameterTypes, Object... args) throws Exception {
try {
Method method = clazz.getMethod(methodName, parameterTypes);
return method.invoke(instance, args);
} catch (InvocationTargetException e) {
e.getTargetException().printStackTrace();
throw new RuntimeException(e.getTargetException());
}
}
public int getFieldCount() {
return clazz.getDeclaredFields().length;
}
public List<String> getFieldNames() {
List<String> fieldNames = new ArrayList<>();
for (Field field : clazz.getDeclaredFields()) {
fieldNames.add(field.getName());
}
return fieldNames;
}
public List<String> getFieldTypes() {
List<String> fieldTypes = new ArrayList<>();
for (Field field : clazz.getDeclaredFields()) {
fieldTypes.add(field.getType().getSimpleName());
}
return fieldTypes;
}
public Object getFieldValue(String fieldName) throws Exception {
return clazz.getField(fieldName).get(instance);
}
public void setFieldValue(String fieldName, Object value) throws Exception {
clazz.getField(fieldName).set(instance, value);
}
public Object getFieldValueAfterMethodInvocation(String fieldName, String methodName, Class<?>[] parameterTypes, Object... args) throws Exception {
Object instance = clazz.getDeclaredConstructor().newInstance();
// Methode aufrufen
Method method = clazz.getMethod(methodName, parameterTypes);
method.invoke(instance, args);
// Wert des Feldes nach dem Methodenaufruf abrufen
return clazz.getField(fieldName).get(instance);
}
public Object getFieldValueOfObject(Object obj, String fieldName) {
try {
Field field = obj.getClass().getField(fieldName);
return field.get(obj);
} catch (NoSuchFieldException e) {
System.out.println("Das Feld " + fieldName + " existiert nicht.");
return null;
} catch (IllegalAccessException e) {
System.out.println("Zugriff auf das Feld " + fieldName + " ist nicht erlaubt.");
return null;
}
}
private Class<?>[] toClassArray(Object... args) {
return java.util.Arrays.stream(args)
.map(Object::getClass)
.toArray(Class<?>[]::new);
}
public Object getValueOfFieldInObject(Object instance, String fieldName) {
try {
Field field = instance.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(instance);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -0,0 +1,144 @@
package testResources.CodeGen.Features;
import de.maishai.typedast.Type;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import testResources.CodeGen.BytecodeTestUtil;
import java.util.List;
public class ByteCode_Break {
private BytecodeTestUtil util;
@BeforeEach
public void setUp() {
try {
util = new BytecodeTestUtil(List.of("src/test/testFiles/CodeGenFeatures/Break.java"), "Break");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
public void testConstructorCount() {
Assertions.assertEquals(1, util.getConstructorCount());
// default constructor
}
@Test
public void testDefaultConstructor() {
Assertions.assertEquals("Break", util.getConstructorNames().get(0));
Assertions.assertEquals(0, util.getConstructorParameterCount(0));
try {
Assertions.assertEquals("Break", util.invokeConstructor(new Class<?>[]{}, null).getClass().getName());
} catch (Exception e) {
Assertions.fail();
}
}
@Test
public void testMethodCount() {
Assertions.assertEquals(1, util.getMethodCount());
}
@Test
public void testMethodNames() {
Assertions.assertEquals("breakMethod", util.getMethodNames().get(0));
}
@Test
public void testMethodReturnType() {
try {
Assertions.assertEquals("void", util.getMethodReturnType("breakMethod", new Class<?>[]{boolean.class}));
} catch (Exception e) {
Assertions.fail();
}
}
@Test
public void testMethodParameters() {
try {
Assertions.assertEquals(1, util.getMethodParameterCount("breakMethod", new Class<?>[]{}));
Assertions.assertEquals("boolean", util.getMethodParameterTypes("breakMethod", new Class<?>[]{}).get(0));
} catch (Exception e) {
Assertions.fail();
}
}
@Test
public void testFieldCount() {
Assertions.assertEquals(2, util.getFieldCount());
}
@Test
public void testFieldNames() {
Assertions.assertEquals("whileRepetition", util.getFieldNames().get(0));
Assertions.assertEquals("forRepetition", util.getFieldNames().get(1));
}
@Test
public void testFieldTypes() {
Assertions.assertEquals("int", util.getFieldTypes().get(0));
Assertions.assertEquals("int", util.getFieldTypes().get(1));
}
@Test
public void testFieldValues() {
try {
Assertions.assertEquals(0, util.getFieldValue("whileRepetition"));
Assertions.assertEquals(0, util.getFieldValue("forRepetition"));
} catch (Exception e) {
Assertions.fail();
}
}
@Test
public void testInvokeDefaultConstructor() {
try {
Object instance = util.invokeConstructor(new Class<?>[]{}, null);
Assertions.assertEquals(instance.getClass().getName(), "Break");
Assertions.assertEquals(0, util.getFieldValueOfObject(instance, "whileRepetition"));
Assertions.assertEquals(0, util.getFieldValueOfObject(instance, "forRepetition"));
} catch (Exception e) {
Assertions.fail();
}
}
@Test
public void testInvokeBreakMethodWithFalse() {
try {
int fieldWhileRepetition = (int) util.getFieldValue("whileRepetition");
int fieldForRepetition = (int) util.getFieldValue("forRepetition");
util.invokeMethod("breakMethod", new Class<?>[]{boolean.class}, new Object[]{false});
Assertions.assertNotEquals(fieldWhileRepetition, util.getFieldValue("whileRepetition"));
Assertions.assertEquals(10, util.getFieldValue("whileRepetition"));
Assertions.assertNotEquals(fieldForRepetition, util.getFieldValue("forRepetition"));
Assertions.assertEquals(10, util.getFieldValue("forRepetition"));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
public void testInvokeBreakMethodWithTrue() {
try {
int fieldWhileRepetition = (int) util.getFieldValue("whileRepetition");
int fieldForRepetition = (int) util.getFieldValue("forRepetition");
util.invokeMethod("breakMethod", new Class<?>[]{boolean.class}, new Object[]{true});
Assertions.assertNotEquals(fieldWhileRepetition, util.getFieldValue("whileRepetition"));
Assertions.assertEquals(5, util.getFieldValue("whileRepetition"));
Assertions.assertNotEquals(fieldForRepetition, util.getFieldValue("forRepetition"));
Assertions.assertEquals(5, util.getFieldValue("forRepetition"));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,66 @@
package testResources.CodeGen.Features;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import testResources.CodeGen.BytecodeTestUtil;
import java.util.List;
public class ByteCode_Class {
private BytecodeTestUtil util;
@BeforeEach
public void setUp() {
try {
util = new BytecodeTestUtil(List.of("src/test/testFiles/CodeGenFeatures/Class.java"), "Class");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
public void testConstructorCount() {
Assertions.assertEquals(1, util.getConstructorCount());
// default constructor
}
@Test
public void testDefaultConstructor() {
Assertions.assertEquals("Class", util.getConstructorNames().get(0));
Assertions.assertEquals(0, util.getConstructorParameterCount(0));
try {
Assertions.assertEquals("Class", util.invokeConstructor(new Class<?>[]{}, null).getClass().getName());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
public void testMethodCount() {
Assertions.assertEquals(0, util.getMethodCount());
}
@Test
public void testFieldCount() {
Assertions.assertEquals(0, util.getFieldCount());
}
@Test
public void testInvokeDefaultConstructor() {
try {
Object instance = util.invokeConstructor(new Class<?>[]{}, null);
Assertions.assertEquals(instance.getClass().getName(), "Class");
} catch (Exception e) {
Assertions.fail();
}
}
}

View File

@ -0,0 +1,150 @@
package testResources.CodeGen.Features;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import testResources.CodeGen.BytecodeTestUtil;
import java.util.List;
public class ByteCode_ClassObjects {
private BytecodeTestUtil util;
@BeforeEach
public void setUp() {
try {
util = new BytecodeTestUtil(List.of("src/test/testFiles/CodeGenFeatures/ClassObjects.java"), "ClassObjects");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
public void testConstructorCount() {
Assertions.assertEquals(2, util.getConstructorCount());
}
@Test
public void testConstructor1() {
Assertions.assertEquals("ClassObjects", util.getConstructorNames().get(0));
Assertions.assertEquals(0, util.getConstructorParameterCount(0));
}
@Test
public void testConstructor2() {
Assertions.assertEquals("ClassObjects", util.getConstructorNames().get(1));
Assertions.assertEquals(1, util.getConstructorParameterCount(1));
}
@Test
public void testMethodCount() {
Assertions.assertEquals(1, util.getMethodCount());
}
@Test
public void testMethodNames() {
Assertions.assertEquals("objectsMethod", util.getMethodNames().get(0));
}
@Test
public void testMethodReturnType() {
try {
Assertions.assertEquals("void", util.getMethodReturnType("objectsMethod", new Class<?>[]{}));
} catch (Exception e) {
Assertions.fail();
}
}
@Test
public void testMethodParameters() {
try {
Assertions.assertEquals(0, util.getMethodParameterCount("objectsMethod", new Class<?>[]{}));
} catch (Exception e) {
Assertions.fail();
}
}
@Test
public void testFieldCount() {
Assertions.assertEquals(3, util.getFieldCount());
}
@Test
public void testFieldNames() {
Assertions.assertEquals("object", util.getFieldNames().get(0));
Assertions.assertEquals("objectWithValue", util.getFieldNames().get(1));
Assertions.assertEquals("integerValue", util.getFieldNames().get(2));
}
@Test
public void testFieldTypes() {
Assertions.assertEquals("ClassObjects", util.getFieldTypes().get(0));
Assertions.assertEquals("ClassObjects", util.getFieldTypes().get(1));
Assertions.assertEquals("int", util.getFieldTypes().get(2));
}
@Test
public void testFieldValues() {
try {
Assertions.assertNull(util.getFieldValue("object"));
Assertions.assertNull(util.getFieldValue("objectWithValue"));
Assertions.assertEquals(0, util.getFieldValue("integerValue"));
} catch (Exception e) {
Assertions.fail();
}
}
@Test
public void testInvokeConstructor1() {
try {
Object constructor1ReturnValue = util.invokeConstructor(new Class<?>[]{}, new Object[]{});
Assertions.assertEquals(constructor1ReturnValue.getClass().getName(), "ClassObjects");
Assertions.assertNull(util.getFieldValueOfObject(constructor1ReturnValue,"object"));
Assertions.assertNull(util.getFieldValueOfObject(constructor1ReturnValue, "objectWithValue"));
Assertions.assertEquals(0,
(int) util.getFieldValueOfObject(constructor1ReturnValue,"integerValue"));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
public void testInvokeConstructor2() {
try {
Object constructor2ReturnValue = util.invokeConstructor(new Class<?>[]{int.class}, new Object[]{2});
Assertions.assertEquals(constructor2ReturnValue.getClass().getName(), "ClassObjects");
Assertions.assertNull(util.getFieldValueOfObject(constructor2ReturnValue, "object"));
Assertions.assertNull(util.getFieldValueOfObject(constructor2ReturnValue, "objectWithValue"));
Assertions.assertEquals(2,
(int) util.getFieldValueOfObject(constructor2ReturnValue,"integerValue"));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
public void testInvokeMethod() {
try {
Object fieldObject = util.getFieldValue("object");
Object fieldObjectWithValue = util.getFieldValue("objectWithValue");
int fieldIntegerValue = (int) util.getFieldValue("integerValue");
util.invokeMethod("objectsMethod", new Class<?>[]{}, new Object[]{});
Assertions.assertNotSame(util.getFieldValue("object"), fieldObject);
Assertions.assertEquals(util.getFieldValue("object").getClass().getName(), "ClassObjects");
Assertions.assertNotSame(util.getFieldValue("objectWithValue"), fieldObjectWithValue);
Assertions.assertEquals(util.getFieldValue("objectWithValue").getClass().getName(), "ClassObjects");
Assertions.assertEquals((int) util.getFieldValue("integerValue"), fieldIntegerValue);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,71 @@
package testResources.CodeGen.Features;
import de.maishai.typedast.Type;
import de.maishai.typedast.typedclass.TypedBlock;
import de.maishai.typedast.typedclass.TypedClass;
import de.maishai.typedast.typedclass.TypedConstructor;
import de.maishai.typedast.typedclass.TypedProgram;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import testResources.CodeGen.BytecodeTestUtil;
import java.util.List;
public class ByteCode_Comment {
private BytecodeTestUtil util;
@BeforeEach
public void setUp() {
try {
util = new BytecodeTestUtil(List.of("src/test/testFiles/CodeGenFeatures/Comment.java"), "Comment");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
public void testConstructorCount() {
Assertions.assertEquals(1, util.getConstructorCount());
// default constructor
}
@Test
public void testDefaultConstructor() {
Assertions.assertEquals("Comment", util.getConstructorNames().get(0));
Assertions.assertEquals(0, util.getConstructorParameterCount(0));
try {
Assertions.assertEquals("Comment", util.invokeConstructor(new Class<?>[]{}, null).getClass().getName());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
public void testMethodCount() {
Assertions.assertEquals(0, util.getMethodCount());
}
@Test
public void testFieldCount() {
Assertions.assertEquals(0, util.getFieldCount());
}
@Test
public void testInvokeDefaultConstructor() {
try {
Object instance = util.invokeConstructor(new Class<?>[]{}, null);
Assertions.assertEquals(instance.getClass().getName(), "Comment");
} catch (Exception e) {
Assertions.fail();
}
}
}

View File

@ -0,0 +1,156 @@
package testResources.CodeGen.Features;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import testResources.CodeGen.BytecodeTestUtil;
import java.util.List;
public class ByteCode_CompAssign {
private BytecodeTestUtil util;
@BeforeEach
public void setUp() {
try {
util = new BytecodeTestUtil(List.of("src/test/testFiles/CodeGenFeatures/CompAssign.java"), "CompAssign");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
public void testConstructorCount() {
Assertions.assertEquals(1, util.getConstructorCount());
// default constructor
}
@Test
public void testDefaultConstructor() {
Assertions.assertEquals("CompAssign", util.getConstructorNames().get(0));
Assertions.assertEquals(0, util.getConstructorParameterCount(0));
try {
Assertions.assertEquals("CompAssign", util.invokeConstructor(new Class<?>[]{}, null).getClass().getName());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
public void testMethodCount() {
Assertions.assertEquals(5, util.getMethodCount());
}
@Test
public void testMethodNames() {
Assertions.assertTrue(util.getMethodNames().contains("increase"));
Assertions.assertTrue(util.getMethodNames().contains("decrease"));
Assertions.assertTrue(util.getMethodNames().contains("multiply"));
Assertions.assertTrue(util.getMethodNames().contains("divide"));
Assertions.assertTrue(util.getMethodNames().contains("modulus"));
}
@Test
public void testMethodReturnType() {
try {
Assertions.assertEquals("int", util.getMethodReturnType("increase", new Class<?>[]{int.class}));
Assertions.assertEquals("int", util.getMethodReturnType("decrease", new Class<?>[]{int.class}));
Assertions.assertEquals("int", util.getMethodReturnType("multiply", new Class<?>[]{int.class}));
Assertions.assertEquals("int", util.getMethodReturnType("divide", new Class<?>[]{int.class}));
Assertions.assertEquals("int", util.getMethodReturnType("modulus", new Class<?>[]{int.class}));
} catch (Exception e) {
Assertions.fail();
}
}
@Test
public void testMethodParameters() {
try {
Assertions.assertEquals(1, util.getMethodParameterCount("increase", new Class<?>[]{int.class}));
Assertions.assertEquals("int", util.getMethodParameterTypes("increase", new Class<?>[]{int.class}).get(0));
Assertions.assertEquals(1, util.getMethodParameterCount("decrease", new Class<?>[]{int.class}));
Assertions.assertEquals("int", util.getMethodParameterTypes("decrease", new Class<?>[]{int.class}).get(0));
Assertions.assertEquals(1, util.getMethodParameterCount("multiply", new Class<?>[]{int.class}));
Assertions.assertEquals("int", util.getMethodParameterTypes("multiply", new Class<?>[]{int.class}).get(0));
Assertions.assertEquals(1, util.getMethodParameterCount("divide", new Class<?>[]{int.class}));
Assertions.assertEquals("int", util.getMethodParameterTypes("divide", new Class<?>[]{int.class}).get(0));
Assertions.assertEquals(1, util.getMethodParameterCount("modulus", new Class<?>[]{int.class}));
Assertions.assertEquals("int", util.getMethodParameterTypes("modulus", new Class<?>[]{int.class}).get(0));
} catch (Exception e) {
Assertions.fail();
}
}
@Test
public void testFieldCount() {
Assertions.assertEquals(0, util.getFieldCount());
}
@Test
public void testInvokeDefaultConstructor() {
try {
Object instance = util.invokeConstructor(new Class<?>[]{}, null);
Assertions.assertEquals(instance.getClass().getName(), "CompAssign");
} catch (Exception e) {
Assertions.fail();
}
}
@Test
public void testInvokeIncrease() {
try {
Assertions.assertEquals(1, util.invokeMethod("increase", new Class<?>[]{int.class}, new Object[]{0}));
Assertions.assertEquals(6, util.invokeMethod("increase", new Class<?>[]{int.class}, new Object[]{5}));
} catch (Exception e) {
Assertions.fail();
}
}
@Test
public void testInvokeDecrease() {
try {
Assertions.assertEquals(0, util.invokeMethod("decrease", new Class<?>[]{int.class}, new Object[]{1}));
Assertions.assertEquals(4, util.invokeMethod("decrease", new Class<?>[]{int.class}, new Object[]{5}));
} catch (Exception e) {
Assertions.fail();
}
}
@Test
public void testInvokeMultiply() {
try {
Assertions.assertEquals(0, util.invokeMethod("multiply", new Class<?>[]{int.class}, new Object[]{0}));
Assertions.assertEquals(10, util.invokeMethod("multiply", new Class<?>[]{int.class}, new Object[]{5}));
} catch (Exception e) {
Assertions.fail();
}
}
@Test
public void testInvokeDivide() {
try {
Assertions.assertEquals(0, util.invokeMethod("divide", new Class<?>[]{int.class}, new Object[]{0}));
Assertions.assertEquals(2, util.invokeMethod("divide", new Class<?>[]{int.class}, new Object[]{5}));
} catch (Exception e) {
Assertions.fail();
}
}
@Test
public void testInvokeModulus() {
try {
Assertions.assertEquals(0, util.invokeMethod("modulus", new Class<?>[]{int.class}, new Object[]{0}));
Assertions.assertEquals(1, util.invokeMethod("modulus", new Class<?>[]{int.class}, new Object[]{5}));
} catch (Exception e) {
Assertions.fail();
}
}
}

View File

@ -0,0 +1,178 @@
package testResources.CodeGen.Features;
import de.maishai.typedast.Type;
import de.maishai.typedast.typedclass.*;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import testResources.CodeGen.BytecodeTestUtil;
import java.util.List;
public class ByteCode_ComplexCalls {
private BytecodeTestUtil util;
@BeforeEach
public void setUp() {
try {
util = new BytecodeTestUtil(List.of("src/test/testFiles/CodeGenFeatures/ComplexCalls.java"), "ComplexCalls");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
public void testConstructorCount() {
Assertions.assertEquals(1, util.getConstructorCount());
// default constructor
}
@Test
public void testDefaultConstructor() {
Assertions.assertEquals("ComplexCalls", util.getConstructorNames().get(0));
Assertions.assertEquals(0, util.getConstructorParameterCount(0));
try {
Assertions.assertEquals("ComplexCalls", util.invokeConstructor(new Class<?>[]{}, null).getClass().getName());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
public void testMethodCount() {
Assertions.assertEquals(3, util.getMethodCount());
}
@Test
public void testMethodNames() {
Assertions.assertTrue(util.getMethodNames().contains("makeComplexCalls"));
Assertions.assertTrue(util.getMethodNames().contains("getClassObject"));
Assertions.assertTrue(util.getMethodNames().contains("getA"));
}
@Test
public void testMethodReturnType() {
try {
Assertions.assertEquals("int", util.getMethodReturnType("makeComplexCalls", new Class<?>[]{}));
Assertions.assertEquals("ComplexCalls", util.getMethodReturnType("getClassObject", new Class<?>[]{}));
Assertions.assertEquals("int", util.getMethodReturnType("getA", new Class<?>[]{int.class}));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
public void testMethodParameters() {
try {
Assertions.assertEquals(0, util.getMethodParameterCount("makeComplexCalls", new Class<?>[]{}));
Assertions.assertEquals(0, util.getMethodParameterCount("getClassObject", new Class<?>[]{}));
Assertions.assertEquals(1, util.getMethodParameterCount("getA", new Class<?>[]{int.class}));
Assertions.assertEquals("int", util.getMethodParameterTypes("getA", new Class<?>[]{int.class}).get(0));
} catch (Exception e) {
Assertions.fail();
}
}
@Test
public void testFieldCount() {
Assertions.assertEquals(2, util.getFieldCount());
}
@Test
public void testFieldNames() {
Assertions.assertTrue(util.getFieldNames().contains("a"));
Assertions.assertTrue(util.getFieldNames().contains("classObject"));
}
@Test
public void testFieldTypes() {
Assertions.assertEquals("int", util.getFieldTypes().get(1));
Assertions.assertEquals("ComplexCalls", util.getFieldTypes().get(0));
}
@Test
public void testFieldValues() {
try {
Assertions.assertEquals(0, util.getFieldValue("a"));
Assertions.assertNull(util.getFieldValue("classObject"));
} catch (Exception e) {
Assertions.fail();
}
}
@Test
public void testInvokeDefaultConstructor() {
try {
Object instance = util.invokeConstructor(new Class<?>[]{}, null);
Assertions.assertEquals(instance.getClass().getName(), "ComplexCalls");
} catch (Exception e) {
Assertions.fail();
}
}
@Test
public void testInvokeMethodMakeComplexCalls() {
try {
Object fieldClassObject = util.getFieldValue("classObject");
Assertions.assertNull(fieldClassObject);
int fieldA = (int) util.getFieldValue("a");
Assertions.assertEquals(0, fieldA);
int returnValue = (int) util.invokeMethod("makeComplexCalls", new Class<?>[]{}, new Object[]{});
Assertions.assertEquals(3, returnValue);
Assertions.assertNotEquals(fieldClassObject, util.getFieldValue("classObject"));
Assertions.assertEquals("ComplexCalls", util.getFieldValue("classObject").getClass().getName());
Assertions.assertNotEquals(fieldA, util.getFieldValue("a"));
Assertions.assertEquals(1, util.getFieldValue("a"));
Object fieldClassObjectContent = util.getFieldValue("classObject");
Assertions.assertEquals(2, util.getFieldValueOfObject(fieldClassObjectContent, "a"));
Assertions.assertEquals("ComplexCalls", util.getFieldValueOfObject(
fieldClassObjectContent, "classObject").getClass().getName());
Assertions.assertEquals(3, util.getFieldValueOfObject(
util.getFieldValueOfObject(fieldClassObjectContent, "classObject"), "a"));
} catch (Exception e) {
Assertions.fail();
}
}
@Test
public void testInvokeMethodGetClassObject() {
try {
Object fieldClassObject = util.getFieldValue("classObject");
Assertions.assertNull(fieldClassObject);
int fieldA = (int) util.getFieldValue("a");
Assertions.assertEquals(0, fieldA);
Object returnValue = util.invokeMethod("getClassObject", new Class<?>[]{}, new Object[]{});
Assertions.assertEquals(util.getFieldValue("classObject"), returnValue);
Assertions.assertEquals(fieldClassObject, util.getFieldValue("classObject"));
Assertions.assertEquals(fieldA, util.getFieldValue("a"));
} catch (Exception e) {
Assertions.fail();
}
}
@Test
public void testInvokeMethodGetA() {
try {
Object fieldClassObject = util.getFieldValue("classObject");
Assertions.assertNull(fieldClassObject);
int fieldA = (int) util.getFieldValue("a");
Assertions.assertEquals(0, fieldA);
int returnValue = (int) util.invokeMethod("getA", new Class<?>[]{int.class}, new Object[]{5});
Assertions.assertEquals(5, returnValue);
Assertions.assertEquals(fieldClassObject, util.getFieldValue("classObject"));
Assertions.assertNotEquals(fieldA, util.getFieldValue("a"));
Assertions.assertEquals(5, util.getFieldValue("a"));
} catch (Exception e) {
Assertions.fail();
}
}
}

View File

@ -0,0 +1,159 @@
package testResources.CodeGen.Features;
import de.maishai.ast.Operator;
import de.maishai.typedast.Type;
import de.maishai.typedast.typedclass.*;
import java.util.List;
public class ByteCode_Constructor {
public static TypedProgram get() {
return new TypedProgram(
List.of(
new TypedClass(
"Constructor",
List.of(),
List.of(),
List.of(
new TypedConstructor(
"Constructor",
List.of(),
new TypedBlock(
List.of(
new TypedLocalVariable(
"i",
Type.INT
)
),
List.of(
new TypedAssignment(
new TypedIntLiteral(
1,
Type.INT),
new TypedFieldVarAccess(
false,
null,
"i",
Type.INT
),
Type.INT
)
),
Type.VOID
),
Type.VOID,
List.of()
),
new TypedConstructor(
"Constructor",
List.of(
new TypedParameter(
"x",
Type.INT
)
),
new TypedBlock(
List.of(
new TypedLocalVariable(
"i",
Type.INT
)
),
List.of(
new TypedAssignment(
new TypedFieldVarAccess(
false,
null,
"x",
Type.INT
),
new TypedFieldVarAccess(
false,
null,
"i",
Type.INT
),
Type.INT
)
),
Type.VOID
),
Type.VOID,
List.of(
new TypedLocalVariable(
"x",
Type.INT
)
)
),
new TypedConstructor(
"Constructor",
List.of(
new TypedParameter(
"x",
Type.INT
),
new TypedParameter(
"y",
Type.INT
)
),
new TypedBlock(
List.of(
new TypedLocalVariable(
"i",
Type.INT
)
),
List.of(
new TypedAssignment(
new TypedBinary(
new TypedFieldVarAccess(
false,
null,
"x",
Type.INT
),
Operator.ADD,
new TypedFieldVarAccess(
false,
null,
"y",
Type.INT
),
Type.INT
),
new TypedFieldVarAccess(
false,
null,
"i",
Type.INT
),
Type.INT
)
),
Type.VOID
),
Type.VOID,
List.of(
new TypedLocalVariable(
"x",
Type.INT
),
new TypedLocalVariable(
"y",
Type.INT
)
)
)
),
null,
null,
null,
Type.REFERENCE("Constructor")
)
),
null
);
}
}

View File

@ -0,0 +1,145 @@
package testResources.CodeGen.Features;
import de.maishai.ast.Operator;
import de.maishai.typedast.Type;
import de.maishai.typedast.typedclass.*;
import java.util.List;
public class ByteCode_Continue {
public static TypedProgram get() {
return new TypedProgram(
List.of(
new TypedClass(
"Continue",
List.of(),
List.of(
new TypedMethod(
"continueLoop",
Type.VOID,
List.of(),
List.of(),
new TypedBlock(
List.of(
new TypedLocalVariable(
"i",
Type.INT
)),
List.of(
new TypedFor(
new TypedAssignment(
new TypedIntLiteral(
0,
Type.INT
),
new TypedFieldVarAccess(
false,
null,
"i",
Type.INT
),
Type.INT
),
new TypedBinary(
new TypedFieldVarAccess(
false,
null,
"i",
Type.INT
),
Operator.LT,
new TypedIntLiteral(
5,
Type.INT
),
Type.BOOL
),
new TypedAssignment(
new TypedBinary(
new TypedFieldVarAccess(
false,
null,
"i",
Type.INT
),
Operator.ADD,
new TypedIntLiteral(
1,
Type.INT
),
Type.INT
),
new TypedFieldVarAccess(
false,
null,
"i",
Type.INT
),
Type.INT
),
new TypedBlock(
List.of(),
List.of(
new TypedIfElse(
new TypedBinary(
new TypedFieldVarAccess(
false,
null,
"i",
Type.INT
),