diff --git a/.gitignore b/.gitignore index cb648af..5d19a24 100644 --- a/.gitignore +++ b/.gitignore @@ -77,10 +77,10 @@ fabric.properties .idea/caches/build_file_checksums.ser /target -src/main/resources/logs/RaupenLog.log +src/main/resources/logs/miniCompilerLog.log src/main/resources/output/CompilerInput.class src/test/resources/output/javac/CompilerInput$Test.class src/test/resources/output/javac/CompilerInput.class -src/test/resources/output/raupenpiler/CompilerInput.class -src/test/resources/output/raupenpiler/CompilerInput$Test.class +src/test/resources/output/miniCompiler/CompilerInput.class +src/test/resources/output/miniCompiler/CompilerInput$Test.class .idea/inspectionProfiles/Project_Default.xml diff --git a/pom.xml b/pom.xml index 4712163..84326da 100644 --- a/pom.xml +++ b/pom.xml @@ -23,6 +23,24 @@ 5.11.0-M2 test + + org.junit.platform + junit-platform-suite-engine + 1.11.0-M2 + test + + + org.junit.jupiter + junit-jupiter-api + 5.11.0-M2 + test + + + junit + junit + 4.13.1 + test + org.antlr antlr4-runtime @@ -44,18 +62,6 @@ 3.26.0 test - - org.junit.jupiter - junit-jupiter-api - 5.11.0-M2 - test - - - org.mockito - mockito-core - 5.11.0 - test - @@ -65,6 +71,11 @@ org.apache.maven.plugins maven-surefire-plugin 3.0.0-M5 + + + **/*Test.java + + maven-assembly-plugin diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..8d2f771 --- /dev/null +++ b/readme.md @@ -0,0 +1,100 @@ +# "Nicht Haskel 2.0" Java Compiler + +Realisation of a subset of the Java Standard Compiler in the course Compiler Construction of the 4th semester Computer Science at the Duale Hochschule Stuttgart (Horb). + +This project aims to provide a simplified version of the Java compiler, focusing on key language features and demonstrating the principles of compiler construction. + +## Realised Java syntax + +- **Data types**: `int`, `boolean`, `char` +- **Access modifier**: `public`, `protected`, `private` +- **Operators**: `=` `+` `-` `*` `%` `/` `>` `<` `>=` `<=` `==` `!=` `!` `&&` `||` `++` `--` +- **Keywords**: `class`, `this`, `while`, `do`, `if`, `else`, `for`, `return`, `new`, `switch`, `case`, `break`, `default`, `:` +- **Statements**: + - `if` ... `if else` ... `else`; + - `while` ... ; + - `do` ... `while`; + - `for`; + - `switch` ... `case` ... ; +- **Comments**: + - Single line: `// comment` + - Multi-line: `/* comment */` +- **Further functions**: + - All methods are overloadable + - High maintainability and expandability through implementation of the visitor pattern + - Logging Input and Outputs + - Error Handling in the Semantic Check + +## Project Structure + +```plain +src/ +└── main/ + ├── java/ + │ ├── ast/ -> Defining the structure of the AST + │ ├── bytecode/ -> Generate Java bytecode + │ ├── main/ -> Running the compiler + │ ├── parser/ + │ │ ├── astBuilder/ -> Builder creating the AST + │ │ ├── generated/ -> Antlr generated grammar + │ │ └── grammar/ -> Antlr grammar + │ ├── semantic/ -> Running the semantic check + │ └── visitor/ -> Visitor interface + └── resources/ +test/ +└── java/ +│ ├── main/ -> MainTest, E2ETests, UtilityTests +│ ├── parser/ -> Performs tests on the parser +│ └── semantic/ -> Performs tests on the semantic check +└── resources/ -> Ressources for running the Tests +``` + +## Class-Diagramm AST + +![AST Diagramm](ast.png) + +## Used Tools + +- [Maven 4.0](https://maven.apache.org/index.html) + - Used for automating the build process and managing dependencies. +- [ANTLR4 v.13.1](https://www.antlr.org/) + - Used to parse the input Java code into the Abstract Syntax Tree. + + +## How to run the compiler +### Possibilities +### 1. Start miniCompiler using make: +Make needs to be installed +```bash +cd .\src\test\ ; make clean compile-miniCompiler +``` + +### 2. Start miniCompiler using jar: +If you do not have the .jar, download it [here](https://gitea.hb.dhbw-stuttgart.de/i22005/NichtHaskell2.0/src/branch/Endabgabe/src) or compile it using mvn package or make first +``` +java.exe -DgenJar=bool -DgenClass=bool -jar path_to_jar\jarName.jar 'path_to_input_file.java' 'path_to_output_directory' +``` + +Example (jar needs to be in the target directory) +```bash + java.exe -DgenJar=true -DgenClass=true -jar .\target\JavaCompiler-1.0-jar-with-dependencies.jar 'src/main/resources/input/CompilerInput.java' 'src/main/resources/output' +``` + +- set DgenJar true, to generate the jar, false for no jar + +``` + DgenJar=true +``` + +- set DgenClass true, to generate class files, false for no class files + +``` + DgenClass=true + ``` + +## How to run tests + +```bash +mvn test +``` +Or start them manually in your IDE \ No newline at end of file diff --git a/src/main/java/main/Main.java b/src/main/java/main/Main.java index 5f1395b..a596fae 100644 --- a/src/main/java/main/Main.java +++ b/src/main/java/main/Main.java @@ -17,10 +17,10 @@ import java.util.Optional; /** - * Start Raupenpiler using make: + * Start miniCompiler using make: *

cd .\src\test\ - *

make clean compile-raupenpiler - *

Start Raupenpiler using jar: + *

make clean compile-miniCompiler + *

Start miniCompiler using jar: *

java.exe -DgenJar=true_OR_false -DgenClass=true_OR_false -jar path_to_jar\JavaCompiler-1.0-jar-with-dependencies.jar 'path_to_input_file.java' 'path_to_output_directory' *

Example (jar needs to be in the target directory, compile with make or mvn package first): * java.exe -DgenJar=true -DgenClass=true -jar .\target\JavaCompiler-1.0-jar-with-dependencies.jar 'src/main/resources/input/CompilerInput.java' 'src/main/resources/output' @@ -40,16 +40,6 @@ public class Main { System.err.println("Error reading the file: " + e.getMessage()); } } - /* !!! Else Branch (main ohne args starten) ist nicht zur Verwendung vorgesehen, immer mit args starten !!! - else { - try { - CharStream codeCharStream = CharStreams.fromPath(Paths.get("src/main/resources/input/CompilerInput.java")); - compileFile(codeCharStream); - } catch (IOException e) { - System.err.println("Error reading the file: " + e.getMessage()); - } - } - */ } /** @@ -66,7 +56,7 @@ public class Main { */ static void compileFile(CharStream inputCharStream, String outputDirectoryPath) { // Initialize the logger - new RaupenLogger(); + new MiniCompilerLogger(); /* ------------------------- Scanner -> tokens ------------------------- */ // Use the SimpleJavaLexer to tokenize the input CharStream @@ -74,27 +64,27 @@ public class Main { CommonTokenStream tokenStream = new CommonTokenStream(lexer); tokenStream.fill(); // Log the tokens - RaupenLogger.logScanner(tokenStream); + MiniCompilerLogger.logScanner(tokenStream); /*------------------------- Parser -> Parsetree -------------------------*/ // Use the SimpleJavaParser to parse the tokens and generate a ParseTree SimpleJavaParser parser = new SimpleJavaParser(tokenStream); ParseTree parseTree = parser.program(); // parse the input // Log the ParseTree - RaupenLogger.logParser(parseTree, parser); + MiniCompilerLogger.logParser(parseTree, parser); /*------------------------- AST builder -> AST -------------------------*/ // Use the ASTBuilder to visit the ParseTree and generate an Abstract Syntax Tree (AST) ASTBuilder astBuilder = new ASTBuilder(); ASTNode abstractSyntaxTree = astBuilder.visit(parseTree); // Log the AST - RaupenLogger.logAST(abstractSyntaxTree); + MiniCompilerLogger.logAST(abstractSyntaxTree); /*------------------------- Semantic Analyzer -> typed AST -------------------------*/ // Use the SemanticAnalyzer to generate a typed AST ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree); // Log the typed AST - RaupenLogger.logSemanticAnalyzer(typedAst); + MiniCompilerLogger.logSemanticAnalyzer(typedAst); if(SemanticAnalyzer.errors.isEmpty()){ /*------------------------- Bytecode Generator -> Bytecode -------------------------*/ @@ -107,7 +97,7 @@ public class Main { assert typedAst != null; byteCodeGenerator.visit((ProgramNode) typedAst); // Log the bytecode generation - RaupenLogger.logBytecodeGenerator(); + MiniCompilerLogger.logBytecodeGenerator(); } else { for(Exception exception : SemanticAnalyzer.errors){ exception.printStackTrace(); diff --git a/src/main/java/main/RaupenLogger.java b/src/main/java/main/MiniCompilerLogger.java similarity index 96% rename from src/main/java/main/RaupenLogger.java rename to src/main/java/main/MiniCompilerLogger.java index 90bc7e2..f2314a1 100644 --- a/src/main/java/main/RaupenLogger.java +++ b/src/main/java/main/MiniCompilerLogger.java @@ -29,11 +29,11 @@ import java.util.logging.*; * consoleHandler.setLevel(Level.OFF); * fileHandler.setLevel(Level.ALL); */ -public class RaupenLogger { +public class MiniCompilerLogger { - static Logger logger = Logger.getLogger("RaupenLogs"); + static Logger logger = Logger.getLogger("miniCompilerLogs"); - public RaupenLogger() { + public MiniCompilerLogger() { // ------------------------- Logging ------------------------- logger.setLevel(Level.ALL); logger.getParent().getHandlers()[0].setLevel(Level.ALL); @@ -66,7 +66,7 @@ public class RaupenLogger { logger.addHandler(consoleHandler); // Configure file handler - Handler fileHandler = new FileHandler("src/main/resources/logs/RaupenLog.log"); + Handler fileHandler = new FileHandler("src/main/resources/logs/miniCompiler.log"); // Toggle file logging on/off fileHandler.setLevel(Level.ALL); fileHandler.setFormatter(new CustomFormatter()); @@ -117,7 +117,7 @@ public class RaupenLogger { public static void logBytecodeGenerator() { // Printing the bytecode logger.info("-------------------- Bytecode Generator -> Bytecode --------------------"); - logger.info("Bytecode generated"); + logger.info("Bytecode generated without errors."); logger.info("\n"); } diff --git a/src/main/java/semantic/SemanticAnalyzer.java b/src/main/java/semantic/SemanticAnalyzer.java index 91ad3b7..8146052 100644 --- a/src/main/java/semantic/SemanticAnalyzer.java +++ b/src/main/java/semantic/SemanticAnalyzer.java @@ -25,15 +25,19 @@ import ast.statementexpressions.methodcallstatementnexpressions.ChainedMethodNod import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode; import ast.statementexpressions.methodcallstatementnexpressions.TargetNode; import ast.statements.*; +import ast.type.AccessModifierNode; import ast.type.EnumAccessModifierNode; import ast.type.ValueNode; import ast.type.type.*; +import com.sun.jdi.IntegerType; +import semantic.context.ClassContext; import semantic.context.Context; import semantic.exceptions.*; +import typechecker.TypeCheckResult; public class SemanticAnalyzer implements SemanticVisitor { - private static final HashMap currentFields = new HashMap<>(); + private static HashMap currentFields = new HashMap<>(); public static ArrayList errors = new ArrayList<>(); @@ -249,6 +253,7 @@ public class SemanticAnalyzer implements SemanticVisitor { if (toCheck.memberAccess != null) { var result = toCheck.memberAccess.accept(this); + toCheck.identifier = toCheck.memberAccess.identifiers.getLast(); toCheck.setTypeNode(result.getType()); return result; } else { @@ -312,9 +317,13 @@ public class SemanticAnalyzer implements SemanticVisitor { @Override public TypeCheckResult analyze(IfElseNode toCheck) { var resultIf = toCheck.ifStatement.accept(this); - var resultElse = toCheck.elseStatement.accept(this); + if(toCheck.elseStatement != null){ + var resultElse = toCheck.elseStatement.accept(this); + return new TypeCheckResult(resultIf.isValid() && resultElse.isValid(), new BaseType(TypeEnum.VOID)); + } - return new TypeCheckResult(resultIf.isValid() && resultElse.isValid(), new BaseType(TypeEnum.VOID)); + + return new TypeCheckResult(resultIf.isValid(), new BaseType(TypeEnum.VOID)); } @Override @@ -450,6 +459,7 @@ public class SemanticAnalyzer implements SemanticVisitor { case PLUS, MINUS: if (calcRes.getType() instanceof BaseType calcType && dotRes.getType() instanceof BaseType dotType && calcType.getTypeEnum().equals(TypeEnum.INT) && dotType.getTypeEnum().equals(TypeEnum.INT)) { + calcNode.setType(new BaseType(TypeEnum.INT)); return new TypeCheckResult(true, new BaseType(TypeEnum.INT)); } break; @@ -457,10 +467,12 @@ public class SemanticAnalyzer implements SemanticVisitor { } } else { + calcNode.setType(calcNode.getType()); return new TypeCheckResult(calcRes.isValid(), calcRes.getType()); } } else if (calcNode.dotExpression != null) { var dotRes = calcNode.dotExpression.accept(this); + calcNode.setType(dotRes.getType()); return new TypeCheckResult(dotRes.isValid(), dotRes.getType()); } return new TypeCheckResult(false, null); @@ -468,28 +480,46 @@ public class SemanticAnalyzer implements SemanticVisitor { @Override public TypeCheckResult analyze(DotNode toCheck) { - if (toCheck.dotSubtractionExpression != null) { - return toCheck.dotSubtractionExpression.accept(this); + if (toCheck.dotSubstractionExpression != null) { + var result = toCheck.dotSubstractionExpression.accept(this); + toCheck.setType(result.getType()); + return result; } return new TypeCheckResult(false, null); } @Override - public TypeCheckResult analyze(DotSubtractionNode toCheck) { + public TypeCheckResult analyze(DotSubstractionNode toCheck) { if (toCheck.value != null) { - return toCheck.value.accept(this); + var result = toCheck.value.accept(this); + toCheck.setType(result.getType()); + return result; } else if (toCheck.memberAccess != null) { - return toCheck.memberAccess.accept(this); + var result = toCheck.memberAccess.accept(this); + toCheck.setType(result.getType()); + return result; } else if (toCheck.methodCall != null) { - return toCheck.methodCall.accept(this); + var result = toCheck.methodCall.accept(this); + toCheck.setType(result.getType()); + return result; } else if (toCheck.identifier != null) { if (currentScope.contains(toCheck.identifier)) { - return new TypeCheckResult(true, currentScope.getLocalVar(toCheck.identifier)); + var type = currentScope.getLocalVar(toCheck.identifier); + toCheck.setType(type); + return new TypeCheckResult(true, type); } else if (currentFields.get(toCheck.identifier) != null) { - return new TypeCheckResult(true, currentFields.get(toCheck.identifier)); + var type = currentFields.get(toCheck.identifier); + toCheck.setType(type); + MemberAccessNode memberAccessNode = new MemberAccessNode(false); + memberAccessNode.identifiers.add(currentClass.identifier); + memberAccessNode.identifiers.add(toCheck.identifier); + toCheck.memberAccess = memberAccessNode; + return new TypeCheckResult(true, type); } } else if (toCheck.calculationExpression != null) { - return toCheck.calculationExpression.accept(this); + var result = toCheck.calculationExpression.accept(this); + toCheck.setType(result.getType()); + return result; } return null; } @@ -509,8 +539,8 @@ public class SemanticAnalyzer implements SemanticVisitor { } break; case OR, AND: - if (expResult.getType() instanceof BaseType expResultType && expResultType.getTypeEnum().equals(TypeEnum.INT) && - unaryResult.getType() instanceof BaseType unaryResultType && unaryResultType.getTypeEnum().equals(TypeEnum.INT)) { + if (expResult.getType() instanceof BaseType expResultType && expResultType.getTypeEnum().equals(TypeEnum.BOOL) && + unaryResult.getType() instanceof BaseType unaryResultType && unaryResultType.getTypeEnum().equals(TypeEnum.BOOL)) { return new TypeCheckResult(true, new BaseType(TypeEnum.BOOL)); } else { errors.add(new TypeMismatchException("Both types must be Boolean")); @@ -534,13 +564,17 @@ public class SemanticAnalyzer implements SemanticVisitor { if (unary.identifier != null) { if (currentScope.contains(unary.identifier)) { - return new TypeCheckResult(valid, currentScope.getLocalVar(unary.identifier)); + var type = currentScope.getLocalVar(unary.identifier); + unary.setType(type); + return new TypeCheckResult(valid, type); } else if (currentFields.get(unary.identifier) != null) { MemberAccessNode memberAccessNode = new MemberAccessNode(false); memberAccessNode.identifiers.add(currentClass.identifier); memberAccessNode.identifiers.add(unary.identifier); unary.memberAccess = memberAccessNode; - return new TypeCheckResult(valid, currentFields.get(unary.identifier)); + var type = currentFields.get(unary.identifier); + unary.setType(type); + return new TypeCheckResult(valid,type ); } else if (unary.statement != null) { var result = unary.statement.accept(this); unary.setType(result.getType()); @@ -550,15 +584,19 @@ public class SemanticAnalyzer implements SemanticVisitor { } } else if (unary.statement != null) { var result = unary.statement.accept(this); + unary.setType(result.getType()); return new TypeCheckResult(result.isValid(), result.getType()); } else if (unary.value != null) { var result = unary.value.accept(this); + unary.setType(result.getType()); return new TypeCheckResult(result.isValid(), result.getType()); } else if (unary.memberAccess != null) { var result = unary.memberAccess.accept(this); + unary.setType(result.getType()); return new TypeCheckResult(result.isValid(), result.getType()); } else if (unary.expression != null) { var result = unary.expression.accept(this); + unary.setType(result.getType()); return new TypeCheckResult(result.isValid(), result.getType()); } @@ -571,11 +609,15 @@ public class SemanticAnalyzer implements SemanticVisitor { ITypeNode currentType = null; int start = 0; if(!memberAccessNode.identifiers.isEmpty()){ - if(currentFields.get(memberAccessNode.identifiers.get(0)) != null){ - memberAccessNode.identifiers.add(0, currentClass.identifier); - start = 1; + if(currentFields.get(memberAccessNode.identifiers.getFirst()) != null){ + memberAccessNode.identifiers.addFirst(currentClass.identifier); + start++; } } + if(context.getClasses().get(memberAccessNode.identifiers.getFirst()) == null){ + memberAccessNode.identifiers.addFirst(currentClass.identifier); + start++; + } for (int i = start; i < memberAccessNode.identifiers.size(); i++) { String s = memberAccessNode.identifiers.get(i); @@ -593,7 +635,8 @@ public class SemanticAnalyzer implements SemanticVisitor { } else { if (currentType instanceof ReferenceType reference) { var currentTypeClass = context.getClass(reference.getIdentifier()); - + memberAccessNode.identifiers.add(i, reference.getIdentifier()); + i++; var currentField = currentTypeClass.getField(s); if (currentField.getAccessModifier().accessType == EnumAccessModifierNode.PUBLIC) { currentType = currentField.getType(); diff --git a/src/main/resources/input/CompilerInput.java b/src/main/resources/input/CompilerInput.java index 825490d..463fab7 100644 --- a/src/main/resources/input/CompilerInput.java +++ b/src/main/resources/input/CompilerInput.java @@ -8,7 +8,6 @@ public class Node { public void main() { Compiler compiler = new Compiler(); int i = compiler.add(5, 8); - return i; } } diff --git a/src/test/Makefile b/src/test/Makefile index a19508b..1fc9648 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -2,23 +2,17 @@ ### IntelliJs play buttons do not work. Run in "src/test" folder with "make" command to run all ### Or run only parts with "make compile-javac", "make clean" etc. -all: compile-javac compile-raupenpiler +all: compile-javac compile-miniCompiler compile-javac: javac -d .\resources\output\javac .\resources\input\CompilerInput.java -compile-raupenpiler: +compile-miniCompiler: cd ../.. ; mvn -DskipTests install cd ../.. ; mvn exec:java -DgenJar=true -DgenClass=true -Dexec.mainClass="main.Main" -Dexec.args="'src/main/resources/input/CompilerInput.java' 'src/main/resources/output'" - cp ../main/resources/output/CompilerInput.class .java/resources/output/raupenpiler + # cp ../main/resources/output/CompilerInput.class .java/resources/output/miniCompiler -test: compile-javac compile-raupenpiler test-javac test-raupenpiler - -test-javac: - # gleich wie bei raupenpiler, kann ich ohne funktionierenden Compiler nicht testen - - -test-raupenpiler: +test-miniCompiler: # move the compiled class to the test/main folder mv ../main/resources/output/CompilerInput.class .java/main/ # compile the test class @@ -29,17 +23,19 @@ test-raupenpiler: clean: - # clean output folders + # clean main output folders rm -f ../main/resources/output/*.class rm -f ../main/resources/output/*.jar + # clean resources output folders rm -f ./resources/output/javac/*.class - rm -f ./resources/output/raupenpiler/*.class + rm -f ./resources/output/miniCompiler/*.class + rm -f ./resources/output/miniCompiler/*.jar # clean logs - rm -f ../main/resources/logs/*.log + rm -f ../main/resources/logs/* # clean test/java/main folders from .class files for End-to-End tests rm -f ./java/main/*.class - # clean javac output from combinedFeatureTests - rm -f ./resources/input/combinedFeatureTests/*.class - rm -f ./resources/input/singleFeatureTests/*.class - rm -f ./resources/input/typedAstFeatureTests/*.class + # clean javac output from every folder + rm -f ./resources/input/*/*.class + # clean test results from maven surefire plugin + rm -f ../../target/surefire-reports/*.txt diff --git a/src/test/java/main/E2EReflectionsTest.java b/src/test/java/main/E2EReflectionsTest.java index f461417..28c95ed 100644 --- a/src/test/java/main/E2EReflectionsTest.java +++ b/src/test/java/main/E2EReflectionsTest.java @@ -1,9 +1,14 @@ package main; +import java.io.IOException; + import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.Arrays; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; import org.junit.jupiter.api.Test; @@ -14,77 +19,79 @@ import static org.junit.jupiter.api.Assertions.*; public class E2EReflectionsTest { @Test - public void AllFeaturesClassExampleTest(){ + public void CharTest() { + final String FILE_NAME = "Char"; try { - Main.main(new String[]{"src/test/resources/input/combinedFeatureTests/AllFeaturesClassExample.java", "src/test/resources/output/raupenpiler"}); + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); // Get the system Java compiler JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); // Assert that the compiler is available assertNotNull(javac, "Java Compiler is not available"); - javac.run(null, null, null, "src/test/resources/input/combinedFeatureTests/AllFeaturesClassExample.java"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); - Class clazz = Class.forName("src.resources.input.combinedFeatureTests.AllFeaturesClassExample"); - ClassLoader classLoader = getClass().getClassLoader(); - // Class clazz = classLoader.loadClass("main.AllFeaturesClassExample"); // Class Name - assertEquals("main.AllFeaturesClassExample", clazz.getName()); + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + // Constructors - Constructor[] actualConstructors = clazz.getDeclaredConstructors(); - assertTrue(actualConstructors.length > 0, "No constructors found"); + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); - Constructor expectedConstructor = clazz.getConstructor(int.class, boolean.class, char.class); + assertEquals(javacConstructors.length, miniCompilerConstructors.length); - boolean constructorFound = false; - for (Constructor constructor : actualConstructors) { - if (constructor.equals(expectedConstructor)) { - constructorFound = true; - break; + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } } } - assertTrue(constructorFound, "Expected constructor not found in actual constructors"); + // Methods - Method[] actualMethodNames = clazz.getDeclaredMethods(); - assertTrue(actualMethodNames.length > 0); - for (Method method : actualMethodNames) { - System.out.println("Method: " + method.getName()); + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); } - // Method Names - String[] expectedMethodNames = { - "controlStructures", - "logicalOperations", - "add", - "subtract", - "multiply", - "divide", - "modulo", - "main" - }; - - for (Method method : actualMethodNames) { - assertTrue(Arrays.asList(expectedMethodNames).contains(method.getName())); - } // Fields - Field[] actualFields = clazz.getDeclaredFields(); - assertTrue(actualFields.length > 0, "No fields found"); + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); - Field expectedField = clazz.getDeclaredField("c"); - assertEquals(expectedField.getType(), char.class); + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); - boolean fieldFound = false; - for (Field field : actualFields) { - if (field.equals(expectedField)) { - fieldFound = true; - break; + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } } } - assertTrue(fieldFound, "Expected field not found in actual fields"); - - } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { e.printStackTrace(); @@ -92,4 +99,1968 @@ public class E2EReflectionsTest { throw new RuntimeException(e); } } + + @Test + public void CommentsTest() { + final String FILE_NAME = "Comments"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void ConstructorMethodCallTest() { + final String FILE_NAME = "ConstructorMethodCall"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void ConstructorMethodCallParametersTest() { + final String FILE_NAME = "ConstructorMethodCallParameters"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void ConstructorParameterTest() { + final String FILE_NAME = "ConstructorParameter"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void ConstructorThisDotTest() { + final String FILE_NAME = "ConstructorThisDot"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void DoWhileTest() { + final String FILE_NAME = "DoWhile"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void EmptyClassTest() { + final String FILE_NAME = "EmptyClass"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void EmptyClassWithConstructorTest() { + final String FILE_NAME = "EmptyClassWithConstructor"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void FieldTest() { + final String FILE_NAME = "Field"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void FieldWithAccessModifierTest() { + final String FILE_NAME = "FieldWithAccessModifier"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void ForTest() { + final String FILE_NAME = "For"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + + @Test + public void IfTest() { + final String FILE_NAME = "If"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + @Test + public void IfElseTest() { + final String FILE_NAME = "IfElse"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + @Test + public void IfElseIfElseTest() { + final String FILE_NAME = "IfElseIfElse"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + @Test + public void IncrementTest() { + final String FILE_NAME = "Increment"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + @Test + public void MainMethodTest() { + final String FILE_NAME = "MainMethod"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + @Test + public void MultipleClassesTest() { + final String FILE_NAME = "MultipleClasses"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + @Test + public void NullTest() { + final String FILE_NAME = "Null"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + @Test + public void SelfReferenceTest() { + final String FILE_NAME = "SelfReference"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + @Test + public void ThisDotTest() { + final String FILE_NAME = "ThisDot"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + @Test + public void VariableCalculationTest() { + final String FILE_NAME = "VariableCalculation"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + @Test + public void VariableCompareTest() { + final String FILE_NAME = "VariableCompare"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + @Test + public void VoidMethodTest() { + final String FILE_NAME = "VoidMethod"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + @Test + public void WhileTest() { + final String FILE_NAME = "While"; + try { + // compile with miniCompiler + Main.main(new String[]{"src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java", "src/test/resources/output/miniCompiler"}); + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + // compile with javac + javac.run(null, null, null, "src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".java"); + moveFile("src/test/resources/input/singleFeatureTests/" + FILE_NAME + ".class", "src/test/resources/output/javac/" + FILE_NAME + ".class"); + + // Load the javac class + Path javacClassPath = Paths.get("src/test/resources/output/javac"); + ClassLoader javacClassLoader = new java.net.URLClassLoader(new java.net.URL[]{javacClassPath.toUri().toURL()}); + Class javacLoadedClass = javacClassLoader.loadClass(FILE_NAME); + + // Load the miniCompiler class + Path miniCompilerClassPath = Paths.get("src/test/resources/output/miniCompiler"); + ClassLoader miniCompilerClassLoader = new java.net.URLClassLoader(new java.net.URL[]{miniCompilerClassPath.toUri().toURL()}); + Class miniCompilerLoadedClass = miniCompilerClassLoader.loadClass(FILE_NAME); + + + // Class Name + assertEquals(FILE_NAME, javacLoadedClass.getName()); + assertEquals(FILE_NAME, miniCompilerLoadedClass.getName()); + + + // Constructors + Constructor[] javacConstructors = javacLoadedClass.getDeclaredConstructors(); + Constructor[] miniCompilerConstructors = miniCompilerLoadedClass.getDeclaredConstructors(); + + assertEquals(javacConstructors.length, miniCompilerConstructors.length); + + for(Constructor c : javacConstructors) { + for(Constructor miniCompilerConstructor : miniCompilerConstructors) { + assertEquals(c.getParameterCount(), miniCompilerConstructor.getParameterCount()); + if (c.getParameterCount() == miniCompilerConstructor.getParameterCount()) { + assertEquals(c.getName(), miniCompilerConstructor.getName()); + } + } + } + + + // Methods + Method[] javacMethods = javacLoadedClass.getDeclaredMethods(); + Method[] miniCompilerMethods = miniCompilerLoadedClass.getDeclaredMethods(); + + assertEquals(javacMethods.length, miniCompilerMethods.length); + + for (int i = 0; i < javacMethods.length; i++) { + assertEquals(javacMethods[i].getName(), miniCompilerMethods[i].getName()); + assertEquals(javacMethods[i].getReturnType(), miniCompilerMethods[i].getReturnType()); + assertEquals(javacMethods[i].getParameterCount(), miniCompilerMethods[i].getParameterCount()); + // assertEquals(javacMethods[i].getModifiers(), miniCompilerMethods[i].getModifiers()); + } + + + // Fields + Field[] javacLoadedClassDeclaredFields = javacLoadedClass.getDeclaredFields(); + Field[] miniCompilerLoadedClassDeclaredFields = miniCompilerLoadedClass.getDeclaredFields(); + + assertEquals(javacLoadedClassDeclaredFields.length, miniCompilerLoadedClassDeclaredFields.length); + + for (Field field : javacLoadedClassDeclaredFields) { + for (Field miniCompilerField : miniCompilerLoadedClassDeclaredFields) { + if (field.getName().equals(miniCompilerField.getName())) { + assertEquals(field.getType(), miniCompilerField.getType()); + // assertEquals(field.getModifiers(), miniCompilerField.getModifiers()); + } + } + } + + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + // Helpers + + public static void moveFile(String sourceFilePath, String destinationFilePath) throws IOException { + Path sourcePath = Paths.get(sourceFilePath); + Path destinationPath = Paths.get(destinationFilePath); + Files.move(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING); + } } \ No newline at end of file diff --git a/src/test/java/main/EndToEndTester.java b/src/test/java/main/EndToEndTester.java index 233a9c3..d7e40ef 100644 --- a/src/test/java/main/EndToEndTester.java +++ b/src/test/java/main/EndToEndTester.java @@ -11,8 +11,6 @@ package main; * Wenn unser Compiler funktioniert, sollten keine Errors kommen (sondern nur die Ausgaben, die wir in der CompilerInput.java Datei gemacht haben, * oder Methoden, die wir hier aufrufen).

* - *

PROBLEM: Hier kommen Errors, was eigentlich heißt, dass der Compiler nicht funktioniert, der Test sollte eigentlich passen. - *
DENN: Wenn ich statt unserem CompilerInput.class die CompilerInput.class von javac verwende (aus src/test/resources/output/javac ), dann funktioniert es.

*/ public class EndToEndTester { public static void main(String[] args) { diff --git a/src/test/java/main/InputFilesTest.java b/src/test/java/main/InputFilesTest.java index 4529c9d..3ba18f3 100644 --- a/src/test/java/main/InputFilesTest.java +++ b/src/test/java/main/InputFilesTest.java @@ -1,5 +1,6 @@ package main; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import javax.tools.JavaCompiler; @@ -26,13 +27,17 @@ public class InputFilesTest { // Assert that the compiler is available assertNotNull(javac, "Java Compiler is not available"); - File folder1 = new File("src/test/resources/input/combinedFeatureTests"); - File folder2 = new File("src/test/resources/input/singleFeatureTests"); - File folder3 = new File("src/test/resources/input/typedAstFeatureTests"); + File combinedFeatureTests = new File("src/test/resources/input/combinedFeatureTests"); + File endabgabeTests = new File("src/test/resources/input/endabgabeTests"); + File singleFeatureSemanticTests = new File("src/test/resources/input/singleFeatureSemanticTests"); + File singleFeatureTests = new File("src/test/resources/input/singleFeatureTests"); + File typedAstFeatureTests = new File("src/test/resources/input/typedAstFeatureTests"); - List files = getJavaFilesFromDirectory(folder1); - files.addAll(getJavaFilesFromDirectory(folder2)); - files.addAll(getJavaFilesFromDirectory(folder3)); + List files = getJavaFilesFromDirectory(combinedFeatureTests); + // files.addAll(getJavaFilesFromDirectory(endabgabeTests)); + // files.addAll(getJavaFilesFromDirectory(singleFeatureSemanticTests)); + files.addAll(getJavaFilesFromDirectory(singleFeatureTests)); + // files.addAll(getJavaFilesFromDirectory(typedAstFeatureTests)); if (!files.isEmpty()) { for (File file : files) { @@ -47,6 +52,133 @@ public class InputFilesTest { } } + @Test + public void areCombinedFeatureTestsValid() throws IOException { + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + + File combinedFeatureTests = new File("src/test/resources/input/combinedFeatureTests"); + + List files = getJavaFilesFromDirectory(combinedFeatureTests); + + if (!files.isEmpty()) { + for (File file : files) { + // Try to compile the file and get the result + int result = javac.run(null, null, null, file.getPath()); + + // Assert that the compilation succeeded (i.e., the result is zero) + assertEquals(0, result, "Expected compilation success for " + file.getName()); + } + } else { + System.out.println("No files found in the directories."); + } + } + + @Test + @Disabled + public void areEndabgabeTestsActuallyValid() throws IOException { + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + + File endabgabeTests = new File("src/test/resources/input/endabgabeTests"); + + List files = getJavaFilesFromDirectory(endabgabeTests); + + if (!files.isEmpty()) { + for (File file : files) { + // Try to compile the file and get the result + int result = javac.run(null, null, null, file.getPath()); + + // Assert that the compilation succeeded (i.e., the result is zero) + assertEquals(0, result, "Expected compilation success for " + file.getName()); + } + } else { + System.out.println("No files found in the directories."); + } + } + + @Test + @Disabled + public void areSingleFeatureSemanticTestsActuallyValid() throws IOException { + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + + File singleFeatureSemanticTests = new File("src/test/resources/input/singleFeatureSemanticTests"); + + List files = getJavaFilesFromDirectory(singleFeatureSemanticTests); + + if (!files.isEmpty()) { + for (File file : files) { + // Try to compile the file and get the result + int result = javac.run(null, null, null, file.getPath()); + + // Assert that the compilation succeeded (i.e., the result is zero) + assertEquals(0, result, "Expected compilation success for " + file.getName()); + } + } else { + System.out.println("No files found in the directories."); + } + } + + + @Test + public void areSingleFeatureTestsActuallyValid() throws IOException { + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + + File singleFeatureTests = new File("src/test/resources/input/singleFeatureTests"); + + List files = getJavaFilesFromDirectory(singleFeatureTests); + + if (!files.isEmpty()) { + for (File file : files) { + // Try to compile the file and get the result + int result = javac.run(null, null, null, file.getPath()); + + // Assert that the compilation succeeded (i.e., the result is zero) + assertEquals(0, result, "Expected compilation success for " + file.getName()); + } + } else { + System.out.println("No files found in the directories."); + } + } + + + @Test + @Disabled + public void areTypedAstFeatureTestsActuallyValid() throws IOException { + // Get the system Java compiler + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + // Assert that the compiler is available + assertNotNull(javac, "Java Compiler is not available"); + + File typedAstFeatureTests = new File("src/test/resources/input/typedAstFeatureTests"); + + List files = getJavaFilesFromDirectory(typedAstFeatureTests); + + if (!files.isEmpty()) { + for (File file : files) { + // Try to compile the file and get the result + int result = javac.run(null, null, null, file.getPath()); + + // Assert that the compilation succeeded (i.e., the result is zero) + assertEquals(0, result, "Expected compilation success for " + file.getName()); + } + } else { + System.out.println("No files found in the directories."); + } + } + + + /** * This test method checks if invalid Java files fail to compile as expected. diff --git a/src/test/java/main/MainTest.java b/src/test/java/main/MainTest.java index 24389bc..890f4cd 100644 --- a/src/test/java/main/MainTest.java +++ b/src/test/java/main/MainTest.java @@ -1,28 +1,25 @@ package main; -import org.junit.jupiter.api.Test; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CharStreams; - -import java.io.IOException; -import java.nio.file.Paths; - +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import parser.ParserTest; +import parser.ScannerTest; +import semantic.EndToTypedAstTest; +import semantic.SemanticTest; /** - * run every test: mvn test - * Nutzen dieser Klasse: Eigentlich nicht vorhanden, in der Main gibts nichts zu testen + * This class is a test suite that runs all the test classes in the project. + *

run: mvn test + *

check results in console or target/surefire-reports */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + InputFilesTest.class, + ScannerTest.class, + ParserTest.class, + SemanticTest.class, + EndToTypedAstTest.class +}) public class MainTest { - @Test - void test() { - CharStream codeCharStream = null; - try { - codeCharStream = CharStreams.fromPath(Paths.get("src/main/test/resources/CompilerInput.java")); - Main.compileFile(codeCharStream, "src/main/test/resources/output"); - } catch (IOException e) { - System.err.println("Error reading the file: " + e.getMessage()); - } - } + // This class remains empty, it is used only as a holder for the above annotations } - - diff --git a/src/test/java/main/ReflectionsTest.java b/src/test/java/main/ReflectionsTest.java deleted file mode 100644 index d47d95a..0000000 --- a/src/test/java/main/ReflectionsTest.java +++ /dev/null @@ -1,145 +0,0 @@ -package main; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.List; - -import org.antlr.v4.runtime.CharStream; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - - -public class ReflectionsTest { - - @Test - public void testSimpleJavaLexerClass() throws ClassNotFoundException, NoSuchMethodException { - Class clazz = Class.forName("parser.generated.SimpleJavaLexer"); - - // Class Name - assertEquals("parser.generated.SimpleJavaLexer", clazz.getName()); - - // Constructors - Constructor[] actualConstructors = clazz.getDeclaredConstructors(); - assertTrue(actualConstructors.length > 0, "No constructors found"); - - Constructor expectedConstructor = clazz.getConstructor(CharStream.class); - - boolean constructorFound = false; - for (Constructor constructor : actualConstructors) { - if (constructor.equals(expectedConstructor)) { - constructorFound = true; - break; - } - } - assertTrue(constructorFound, "Expected constructor not found in actual constructors"); - - - - // Methods - Method[] actualMethodNames = clazz.getDeclaredMethods(); - assertTrue(actualMethodNames.length > 0); - Arrays.stream(actualMethodNames).forEach(method -> System.out.println("Method: " + method.getName())); - - List expectedMethodNames = Arrays.asList( - "getTokenNames", - "getVocabulary", - "getGrammarFileName", - "getRuleNames", - "getSerializedATN", - "getChannelNames", - "getModeNames", - "getATN", - "makeRuleNames", - "makeLiteralNames", - "makeSymbolicNames" - ); - - for (Method method : actualMethodNames) { - assertTrue(expectedMethodNames.contains(method.getName())); - } - - for (String expectedMethodName : expectedMethodNames) { - boolean methodFound = false; - for (Method method : actualMethodNames) { - if (method.getName().equals(expectedMethodName)) { - methodFound = true; - break; - } - } - assertTrue(methodFound, "Expected method " + expectedMethodName + " not found in actual methods"); - } - - - // Fields - Field[] actualFieldNames = clazz.getDeclaredFields(); - assertTrue(actualFieldNames.length > 0); - Arrays.stream(actualFieldNames).forEach(field -> System.out.println("Field: " + field.getName())); - - List expectedFieldNames = Arrays.asList( - "_decisionToDFA", - "_sharedContextCache", - "channelNames", - "modeNames", - "ruleNames", - "_LITERAL_NAMES", - "_SYMBOLIC_NAMES", - "VOCABULARY", - "tokenNames", - "_serializedATN", - "_ATN" - ); - - for (Field field : actualFieldNames) { - assertTrue(expectedFieldNames.contains(field.getName())); - } - } - - @Test - public void testSimpleJavaParserClass() throws ClassNotFoundException { - Class clazz = Class.forName("parser.generated.SimpleJavaParser"); - - // Class Name - assertEquals("parser.generated.SimpleJavaParser", clazz.getName()); - - // Constructors - Constructor[] constructors = clazz.getDeclaredConstructors(); - assertTrue(constructors.length > 0); - - // Methods - Method[] methods = clazz.getDeclaredMethods(); - assertTrue(methods.length > 0); - Arrays.stream(methods).forEach(method -> System.out.println("Method: " + method.getName())); - - // Fields - Field[] fields = clazz.getDeclaredFields(); - assertTrue(fields.length > 0); - Arrays.stream(fields).forEach(field -> System.out.println("Field: " + field.getName())); - } - - @Test - public void testASTBuilderClass() throws ClassNotFoundException { - Class clazz = Class.forName("parser.astBuilder.ASTBuilder"); - - // Class Name - assertEquals("parser.astBuilder.ASTBuilder", clazz.getName()); - - // Constructors - Constructor[] constructors = clazz.getDeclaredConstructors(); - assertTrue(constructors.length > 0); - - // Methods - Method[] methods = clazz.getDeclaredMethods(); - assertTrue(methods.length > 0); - Arrays.stream(methods).forEach(method -> System.out.println("Method: " + method.getName())); - - // Fields - Field[] fields = clazz.getDeclaredFields(); - assertTrue(fields.length > 0); - Arrays.stream(fields).forEach(field -> System.out.println("Field: " + field.getName())); - } - - // Similarly, you can add tests for SemanticAnalyzer and ByteCodeGenerator -} diff --git a/src/test/java/semantic/EndToTypedAstTest.java b/src/test/java/semantic/EndToTypedAstTest.java index be95ab2..e319a91 100644 --- a/src/test/java/semantic/EndToTypedAstTest.java +++ b/src/test/java/semantic/EndToTypedAstTest.java @@ -281,6 +281,74 @@ public class EndToTypedAstTest { } + @Test + public void VariableCompare(){ + + ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/VariableCompare.java"); + + SemanticAnalyzer.generateTast(tast); + + assertTrue(SemanticAnalyzer.errors.isEmpty()); + + } + + @Test + public void IfExpressionInt(){ + + ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/IfExpressionInt.java"); + + SemanticAnalyzer.generateTast(tast); + + assertFalse(SemanticAnalyzer.errors.isEmpty()); + assertInstanceOf(TypeMismatchException.class, SemanticAnalyzer.errors.getFirst()); + + } + + @Test + public void SelectWrongMethodCauseParameter(){ + + ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/SelectWrongMethodCauseParameter.java"); + + SemanticAnalyzer.generateTast(tast); + + assertFalse(SemanticAnalyzer.errors.isEmpty()); + assertInstanceOf(TypeMismatchException.class, SemanticAnalyzer.errors.getFirst()); + + } + + @Test + public void SelectRightMethodCauseParameter(){ + + ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/SelectRightMethodCauseParameter.java"); + + SemanticAnalyzer.generateTast(tast); + + assertTrue(SemanticAnalyzer.errors.isEmpty()); + + } + + @Test + public void VariableCalculation(){ + + ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/VariableCalculation.java"); + + SemanticAnalyzer.generateTast(tast); + + assertTrue(SemanticAnalyzer.errors.isEmpty()); + + } + + @Test + public void Expression(){ + + ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/Expression.java"); + + SemanticAnalyzer.generateTast(tast); + + assertTrue(SemanticAnalyzer.errors.isEmpty()); + + } + // ------------------ Helpers ------------------ /** diff --git a/src/test/java/semantic/SemanticHelper.java b/src/test/java/semantic/SemanticHelper.java index 1293e1d..3f187ee 100644 --- a/src/test/java/semantic/SemanticHelper.java +++ b/src/test/java/semantic/SemanticHelper.java @@ -14,6 +14,9 @@ import java.io.IOException; public class SemanticHelper { public static ASTNode generateTypedASTFrom(String filePath) { + + SemanticAnalyzer.clearAnalyzer(); + CharStream testFile = null; try { testFile = CharStreams.fromFileName(filePath); diff --git a/src/test/java/semantic/SemanticTest.java b/src/test/java/semantic/SemanticTest.java new file mode 100644 index 0000000..ac7393f --- /dev/null +++ b/src/test/java/semantic/SemanticTest.java @@ -0,0 +1,441 @@ +package semantic; + +import ast.ASTNode; +import ast.ClassNode; +import ast.ProgramNode; +import ast.expressions.IExpressionNode; +import ast.expressions.unaryexpressions.MemberAccessNode; +import ast.expressions.unaryexpressions.UnaryNode; +import ast.members.ConstructorNode; +import ast.members.FieldNode; +import ast.members.MethodNode; +import ast.parameters.ParameterNode; +import ast.statementexpressions.AssignNode; +import ast.statementexpressions.AssignableNode; +import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode; +import ast.statements.BlockNode; +import ast.statements.ReturnNode; +import ast.type.AccessModifierNode; +import ast.type.EnumValueNode; +import ast.type.ValueNode; +import ast.type.type.BaseType; +import ast.type.type.TypeEnum; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import parser.Helper; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class SemanticTest { + + @BeforeEach + public void setUp() { + SemanticAnalyzer.clearAnalyzer(); + } + + @Test + @DisplayName("Empty Class Test") + public void emptyClassTest() { + ClassNode emptyClass = Helper.generateEmptyClass("EmptyClass"); + ProgramNode abstractSyntaxTree = new ProgramNode(); + abstractSyntaxTree.addClass(emptyClass); + + ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree); + for (Exception runtimeException : SemanticAnalyzer.errors) { + runtimeException.printStackTrace(); + } + assertTrue(SemanticAnalyzer.errors.isEmpty()); + assertNotNull(typedAst); + } + + + @Test + @DisplayName("Multiple Empty Classes Test") + public void multipleEmptyClassesTest() { + ClassNode class1 = Helper.generateEmptyClass("MultipleClasses"); + ClassNode class2 = Helper.generateEmptyClass("TestClass2"); + ProgramNode abstractSyntaxTree = new ProgramNode(); + abstractSyntaxTree.addClass(class1); + abstractSyntaxTree.addClass(class2); + + ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree); + for (Exception runtimeException : SemanticAnalyzer.errors) { + runtimeException.printStackTrace(); + } + assertTrue(SemanticAnalyzer.errors.isEmpty()); + assertNotNull(typedAst); + } + + + @Test + @DisplayName("Empty Class Test with Constructor") + public void emptyClassWithConstructorTest() { + ClassNode class1 = Helper.generateEmptyClass("EmptyClassWithConstructor"); + ProgramNode abstractSyntaxTree = new ProgramNode(); + abstractSyntaxTree.addClass(class1); + + ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree); + for (Exception runtimeException : SemanticAnalyzer.errors) { + runtimeException.printStackTrace(); + } + assertTrue(SemanticAnalyzer.errors.isEmpty()); + assertNotNull(typedAst); + } + + @Test + @DisplayName("Field Test") + public void fieldTest() { + ClassNode class1 = Helper.generateEmptyClass("Field"); + class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a")); + + ProgramNode abstractSyntaxTree = new ProgramNode(); + abstractSyntaxTree.addClass(class1); + + ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree); + for (Exception runtimeException : SemanticAnalyzer.errors) { + runtimeException.printStackTrace(); + } + assertTrue(SemanticAnalyzer.errors.isEmpty()); + assertNotNull(typedAst); + } + + @Test + @DisplayName("Field Test with Accessmodifier") + public void fieldTestWithModifier() { + ClassNode class1 = Helper.generateEmptyClass("FieldWithAccessModifier"); + class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a")); + + ProgramNode abstractSyntaxTree = new ProgramNode(); + abstractSyntaxTree.addClass(class1); + + ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree); + for (Exception runtimeException : SemanticAnalyzer.errors) { + runtimeException.printStackTrace(); + } + assertTrue(SemanticAnalyzer.errors.isEmpty()); + assertNotNull(typedAst); + } + + @Test + @DisplayName("Comments Ignore Test") + public void commentsIgnoreTest() { + ClassNode class1 = Helper.generateEmptyClass("Comments"); + class1.addMember(new FieldNode(new AccessModifierNode("private"), new BaseType(TypeEnum.INT), "a")); + + ProgramNode abstractSyntaxTree = new ProgramNode(); + abstractSyntaxTree.addClass(class1); + + ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree); + for (Exception runtimeException : SemanticAnalyzer.errors) { + runtimeException.printStackTrace(); + } + assertTrue(SemanticAnalyzer.errors.isEmpty()); + assertNotNull(typedAst); + } + + @Test + @DisplayName("Constructor Parameter Test") + public void constructorParameterTest() { + BlockNode block = new BlockNode(); + block.addStatement(new ReturnNode(null)); + ConstructorNode constructor = new ConstructorNode("public", "ConstructorParameter", block); + constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a")); + constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "b")); + + ClassNode class1 = new ClassNode("public", "ConstructorParameter"); + class1.addMember(constructor); + + ProgramNode abstractSyntaxTree = new ProgramNode(); + abstractSyntaxTree.addClass(class1); + + ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree); + for (Exception runtimeException : SemanticAnalyzer.errors) { + runtimeException.printStackTrace(); + } + assertTrue(SemanticAnalyzer.errors.isEmpty()); + assertNotNull(typedAst); + } + + @Test + @DisplayName("This Dot Test") + public void thisDotTest() { + BlockNode block = new BlockNode(); + MemberAccessNode memberAccess = new MemberAccessNode(true); + memberAccess.addIdentifier("a"); + + AssignableNode assignable = new AssignableNode(memberAccess); + + ValueNode value = new ValueNode(EnumValueNode.INT_VALUE, "1"); + IExpressionNode expression = new UnaryNode(value); + + block.addStatement(new AssignNode(assignable, expression)); + block.addStatement(new ReturnNode(null)); + ConstructorNode constructor = new ConstructorNode("public", "ThisDot", block); + + ClassNode class1 = new ClassNode("public", "ThisDot"); + class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a")); + class1.addMember(constructor); + + ProgramNode abstractSyntaxTree = new ProgramNode(); + abstractSyntaxTree.addClass(class1); + + ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree); + for (Exception runtimeException : SemanticAnalyzer.errors) { + runtimeException.printStackTrace(); + } + assertTrue(SemanticAnalyzer.errors.isEmpty()); + assertNotNull(typedAst); + } + + @Test + @DisplayName("Constructor This Dot Test") + public void constructorThisDotTest() { + BlockNode block = new BlockNode(); + MemberAccessNode memberAccess = new MemberAccessNode(true); + memberAccess.addIdentifier("a"); + + AssignableNode assignable = new AssignableNode(memberAccess); + + IExpressionNode expression = new UnaryNode("a"); + + block.addStatement(new AssignNode(assignable, expression)); + block.addStatement(new ReturnNode(null)); + ConstructorNode constructor = new ConstructorNode("public", "ConstructorThisDot", block); + constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a")); + + ClassNode class1 = new ClassNode("public", "ConstructorThisDot"); + class1.addMember(new FieldNode(new AccessModifierNode("private"), new BaseType(TypeEnum.INT), "a")); + class1.addMember(constructor); + + ProgramNode abstractSyntaxTree = new ProgramNode(); + abstractSyntaxTree.addClass(class1); + + ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree); + for (Exception runtimeException : SemanticAnalyzer.errors) { + runtimeException.printStackTrace(); + } + assertTrue(SemanticAnalyzer.errors.isEmpty()); + assertNotNull(typedAst); + } + + @Test + @DisplayName("Void Methoden Test") + public void voidMethodenTest() { + ClassNode class1 = Helper.generateEmptyClass("VoidMethod"); + BlockNode block = new BlockNode(); + block.addStatement(new ReturnNode(null)); + class1.addMember(new MethodNode("public", null, true, "test", block)); + + ProgramNode abstractSyntaxTree = new ProgramNode(); + abstractSyntaxTree.addClass(class1); + + ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree); + for (Exception runtimeException : SemanticAnalyzer.errors) { + runtimeException.printStackTrace(); + } + assertTrue(SemanticAnalyzer.errors.isEmpty()); + assertNotNull(typedAst); + } + + @Test + @DisplayName("Constructor Method call Test") + public void constructorMethodCallTest() { + BlockNode blockCon = new BlockNode(); + MemberAccessNode memberAccess = new MemberAccessNode(true); + memberAccess.addIdentifier("a"); + + AssignableNode assignable = new AssignableNode(memberAccess); + + IExpressionNode expression = new UnaryNode(new MethodCallNode(null, "testMethod")); + + blockCon.addStatement(new AssignNode(assignable, expression)); + blockCon.addStatement(new ReturnNode(null)); + ConstructorNode constructor = new ConstructorNode("public", "ConstructorMethodCall", blockCon); + + BlockNode blockMethod = new BlockNode(); + blockMethod.addStatement(new ReturnNode(new UnaryNode(new ValueNode(EnumValueNode.INT_VALUE, "1")))); + MethodNode method = new MethodNode("public", new BaseType(TypeEnum.INT), false, "testMethod", blockMethod); + + ClassNode class1 = new ClassNode("public", "ConstructorMethodCall"); + class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a")); + class1.addMember(constructor); + class1.addMember(method); + + ProgramNode abstractSyntaxTree = new ProgramNode(); + abstractSyntaxTree.addClass(class1); + + ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree); + for (Exception runtimeException : SemanticAnalyzer.errors) { + runtimeException.printStackTrace(); + } + assertTrue(SemanticAnalyzer.errors.isEmpty()); + assertNotNull(typedAst); + } + + @Test + @DisplayName("Constructor Method call Parameters Test") + public void constructorMethodCallParametersTest() { + BlockNode blockCon = new BlockNode(); + MemberAccessNode memberAccess = new MemberAccessNode(true); + memberAccess.addIdentifier("a"); + + AssignableNode assignable = new AssignableNode(memberAccess); + + MethodCallNode methodCall = new MethodCallNode(null, "testMethod"); + methodCall.addExpression(new UnaryNode("a")); + IExpressionNode expression = new UnaryNode(methodCall); + + blockCon.addStatement(new AssignNode(assignable, expression)); + blockCon.addStatement(new ReturnNode(null)); + ConstructorNode constructor = new ConstructorNode("public", "ConstructorMethodCallParameters", blockCon); + constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a")); + + BlockNode blockMethod = new BlockNode(); + blockMethod.addStatement(new ReturnNode(new UnaryNode("a"))); + MethodNode method = new MethodNode("public", new BaseType(TypeEnum.INT), false, "testMethod", blockMethod); + method.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a")); + + ClassNode class1 = new ClassNode("public", "ConstructorMethodCallParameters"); + class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a")); + class1.addMember(constructor); + class1.addMember(method); + + ProgramNode abstractSyntaxTree = new ProgramNode(); + abstractSyntaxTree.addClass(class1); + + ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree); + for (Exception runtimeException : SemanticAnalyzer.errors) { + runtimeException.printStackTrace(); + } + assertTrue(SemanticAnalyzer.errors.isEmpty()); + assertNotNull(typedAst); + } + + @Test + @DisplayName("Char Test") + public void charTest() { + BlockNode blockCon = new BlockNode(); + MemberAccessNode memberAccess = new MemberAccessNode(true); + memberAccess.addIdentifier("a"); + + AssignableNode assignable = new AssignableNode(memberAccess); + + MethodCallNode methodCall = new MethodCallNode(null, "testMethod"); + methodCall.addExpression(new UnaryNode("a")); + IExpressionNode expression = new UnaryNode(methodCall); + + blockCon.addStatement(new AssignNode(assignable, expression)); + blockCon.addStatement(new ReturnNode(null)); + ConstructorNode constructor = new ConstructorNode("public", "Char", blockCon); + constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.CHAR), "a")); + + BlockNode blockMethod = new BlockNode(); + blockMethod.addStatement(new ReturnNode(new UnaryNode("a"))); + MethodNode method = new MethodNode("public", new BaseType(TypeEnum.CHAR), false, "testMethod", blockMethod); + method.addParameter(new ParameterNode(new BaseType(TypeEnum.CHAR), "a")); + + ClassNode class1 = new ClassNode("public", "Char"); + class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.CHAR), "a")); + class1.addMember(constructor); + class1.addMember(method); + + ProgramNode abstractSyntaxTree = new ProgramNode(); + abstractSyntaxTree.addClass(class1); + + ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree); + for (Exception runtimeException : SemanticAnalyzer.errors) { + runtimeException.printStackTrace(); + } + assertTrue(SemanticAnalyzer.errors.isEmpty()); + assertNotNull(typedAst); + } + + @Test + @DisplayName("Null Test") + public void nullTest() { + BlockNode blockCon = new BlockNode(); + MemberAccessNode memberAccess = new MemberAccessNode(true); + memberAccess.addIdentifier("a"); + + AssignableNode assignable = new AssignableNode(memberAccess); + + blockCon.addStatement(new AssignNode(assignable, new UnaryNode(new ValueNode(EnumValueNode.NULL_VALUE, "null")))); + blockCon.addStatement(new ReturnNode(null)); + ConstructorNode constructor = new ConstructorNode("public", "Null", blockCon); + + ClassNode class1 = new ClassNode("public", "Null"); + class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a")); + class1.addMember(constructor); + + ProgramNode abstractSyntaxTree = new ProgramNode(); + abstractSyntaxTree.addClass(class1); + + ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree); + for (Exception runtimeException : SemanticAnalyzer.errors) { + runtimeException.printStackTrace(); + } + assertTrue(SemanticAnalyzer.errors.isEmpty()); + assertNotNull(typedAst); + } + + @Test + @DisplayName("Self Reference Test") + public void selfReferenceTest() { + + } + + @Test + @DisplayName("Variable Compare Test") + public void variableCompareTest() { + + } + + @Test + @DisplayName("Variable Calculation Test") + public void variableCalculationTest() { + + } + + @Test + @DisplayName("Main Method Test") + public void mainMethodTest() { + + } + + @Test + @DisplayName("While Test") + public void whileTest() { + + } + + @Test + @DisplayName("Do While Test") + public void doWhileTest() { + + } + + @Test + @DisplayName("For Test") + public void forTest() { + + } + + @Test + @DisplayName("Increment Test") + public void incrementTest() { + ClassNode classNode = Helper.generateEmptyClass("Increment"); + classNode.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a")); + + ProgramNode abstractSyntaxTree = new ProgramNode(); + abstractSyntaxTree.addClass(classNode); + + ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree); + for (Exception runtimeException : SemanticAnalyzer.errors) { + runtimeException.printStackTrace(); + } + assertTrue(SemanticAnalyzer.errors.isEmpty()); + assertNotNull(typedAst); + } +} \ No newline at end of file diff --git a/src/test/resources/input/singleFeatureSemanticTests/Expression.java b/src/test/resources/input/singleFeatureSemanticTests/Expression.java new file mode 100644 index 0000000..a18178b --- /dev/null +++ b/src/test/resources/input/singleFeatureSemanticTests/Expression.java @@ -0,0 +1,10 @@ +class VariableCompare{ + + void trueMethod(boolean a, int c) { + if(a && c == 10){ + + } + } + + +} \ No newline at end of file diff --git a/src/test/resources/input/typedAstExceptionsTests/IfExpressionInt.java b/src/test/resources/input/singleFeatureSemanticTests/IfExpressionInt.java similarity index 73% rename from src/test/resources/input/typedAstExceptionsTests/IfExpressionInt.java rename to src/test/resources/input/singleFeatureSemanticTests/IfExpressionInt.java index 2fbbbfc..43b5101 100644 --- a/src/test/resources/input/typedAstExceptionsTests/IfExpressionInt.java +++ b/src/test/resources/input/singleFeatureSemanticTests/IfExpressionInt.java @@ -1,4 +1,3 @@ -// @expected: TypeMismatchException public class Test{ public void test(int x){ diff --git a/src/test/resources/input/singleFeatureSemanticTests/SelectRightMethodCauseParameter.java b/src/test/resources/input/singleFeatureSemanticTests/SelectRightMethodCauseParameter.java new file mode 100644 index 0000000..e148c46 --- /dev/null +++ b/src/test/resources/input/singleFeatureSemanticTests/SelectRightMethodCauseParameter.java @@ -0,0 +1,22 @@ +// @expected: TypeMismatchException +public class Test{ + + public int i; + public boolean b; + + public int test(){ + + return test(b); + + } + + public void test(int a){ + + } + + public int test(boolean bool){ + int ret = 1; + return ret; + } + +} diff --git a/src/test/resources/input/typedAstExceptionsTests/SelectWrongMethodCauseParameter.java b/src/test/resources/input/singleFeatureSemanticTests/SelectWrongMethodCauseParameter.java similarity index 100% rename from src/test/resources/input/typedAstExceptionsTests/SelectWrongMethodCauseParameter.java rename to src/test/resources/input/singleFeatureSemanticTests/SelectWrongMethodCauseParameter.java diff --git a/src/test/resources/input/singleFeatureSemanticTests/VariableCalculation.java b/src/test/resources/input/singleFeatureSemanticTests/VariableCalculation.java new file mode 100644 index 0000000..847b1a6 --- /dev/null +++ b/src/test/resources/input/singleFeatureSemanticTests/VariableCalculation.java @@ -0,0 +1,34 @@ +class VariableCalculation{ + + int aPlusB(int a, int b){ + return a + b; + } + + int aMinusB(int a, int b){ + return a - b; + } + + int aTimeB(int a, int b){ + return a * b; + } + + int aDivB(int a, int b){ + return a / b; + } + + int complexCalc (int a, int b){ + return a * b / 1 * 3; + } + + boolean aSmallerB (int a, int b){ + return a < b; + } + + boolean aGreaterB (int a, int b){ + return a > b; + } + + boolean aEqualsB (int a, int b){ + return a == b; + } +} \ No newline at end of file diff --git a/src/test/resources/input/singleFeatureSemanticTests/VariableCompare.java b/src/test/resources/input/singleFeatureSemanticTests/VariableCompare.java new file mode 100644 index 0000000..70f2a39 --- /dev/null +++ b/src/test/resources/input/singleFeatureSemanticTests/VariableCompare.java @@ -0,0 +1,30 @@ +class VariableCompare{ + + boolean trueMethod() { + return true; + } + + boolean falseMethod(){ + return false; + } + + boolean trueAndTrueMethod(){ + return true && true; + } + + boolean trueAndFalseMethod(){ + return true && false; + } + + boolean falseAndFalseMethod(){ + return false && false; + } + + boolean trueOrTrueMethod(){ + return true || true; + } + + boolean falseOrFalseMethod(){ + return false || false; + } +} \ No newline at end of file diff --git a/src/test/resources/input/typedAstFeatureTests/CorrectTest.java b/src/test/resources/input/typedAstFeatureTests/CorrectTest.java index 53a8f3c..d5533fd 100644 --- a/src/test/resources/input/typedAstFeatureTests/CorrectTest.java +++ b/src/test/resources/input/typedAstFeatureTests/CorrectTest.java @@ -1,13 +1,16 @@ -public class Klasse1 { - public int test; - - public int test1() { - test = 5; - return 1; +public class Compiler { + Node node; + public int add(int i, int j) { + node = new Node(); + node.x = 1; + return i+j; } +} - public void test2() { - int testInt; - testInt = this.test1(); +public class Node { + public int x; + public void main() { + Compiler compiler = new Compiler(); + int i = compiler.add(5, 8); } } \ No newline at end of file