diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
index 712ab9d..35e8b50 100644
--- a/.idea/jarRepositories.xml
+++ b/.idea/jarRepositories.xml
@@ -6,6 +6,11 @@
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index 99e9904..e32826e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -44,6 +44,12 @@
3.26.0
test
+
+ org.mockito
+ mockito-core
+ 5.11.0
+ test
+
@@ -78,4 +84,11 @@
+
+
+ maven_central
+ Maven Central
+ https://repo.maven.apache.org/maven2/
+
+
\ No newline at end of file
diff --git a/src/main/java/main/Main.java b/src/main/java/main/Main.java
index 7568d24..632154e 100644
--- a/src/main/java/main/Main.java
+++ b/src/main/java/main/Main.java
@@ -91,15 +91,15 @@ public class Main {
/*------------------------- Semantic Analyzer -> typed AST -------------------------*/
// Use the SemanticAnalyzer to generate a typed AST
- ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
+ //ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
// Log the typed AST
- RaupenLogger.logSemanticAnalyzer(typedAst);
+ RaupenLogger.logSemanticAnalyzer(abstractSyntaxTree);
/*------------------------- Bytecode Generator -> Bytecode -------------------------*/
// Use the ByteCodeGenerator to generate bytecode from the typed AST and output it to the specified directory
- ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(outputDirectoryPath);
- assert typedAst != null;
- byteCodeGenerator.visit((ProgramNode) typedAst);
+ ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(outputDirectoryPath, true, true);
+ assert abstractSyntaxTree != null;
+ byteCodeGenerator.visit((ProgramNode) abstractSyntaxTree);
// Log the bytecode generation
RaupenLogger.logBytecodeGenerator();
}
diff --git a/src/main/resources/input/CompilerInput.java b/src/main/resources/input/CompilerInput.java
index 825490d..b27068a 100644
--- a/src/main/resources/input/CompilerInput.java
+++ b/src/main/resources/input/CompilerInput.java
@@ -2,13 +2,15 @@ public class Compiler {
public int add(int i, int j) {
return i+j;
}
+ public static void main(String[] args) {
+ int a = 1;
+ }
}
public class Node {
public void main() {
Compiler compiler = new Compiler();
int i = compiler.add(5, 8);
- return i;
}
}
diff --git a/src/main/resources/output/output.jar b/src/main/resources/output/output.jar
new file mode 100644
index 0000000..5749e1b
Binary files /dev/null and b/src/main/resources/output/output.jar differ
diff --git a/src/test/Makefile b/src/test/Makefile
index 883b79c..1464161 100644
--- a/src/test/Makefile
+++ b/src/test/Makefile
@@ -10,7 +10,7 @@ compile-javac:
compile-raupenpiler:
cd ../.. ; mvn -DskipTests install
cd ../.. ; mvn exec:java -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/raupenpiler
test: compile-javac compile-raupenpiler test-javac test-raupenpiler
@@ -31,6 +31,7 @@ test-raupenpiler:
clean:
# clean output folders
rm -f ../main/resources/output/*.class
+ rm -f ../main/resources/output/*.jar
rm -f ./resources/output/javac/*.class
rm -f ./resources/output/raupenpiler/*.class
# clean logs
diff --git a/src/test/java/main/E2EReflectionsTest.java b/src/test/java/main/E2EReflectionsTest.java
new file mode 100644
index 0000000..bb7f2ed
--- /dev/null
+++ b/src/test/java/main/E2EReflectionsTest.java
@@ -0,0 +1,177 @@
+package main;
+
+import ast.ASTNode;
+import ast.ProgramNode;
+import bytecode.ByteCodeGenerator;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.antlr.v4.runtime.CharStream;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.tree.ParseTree;
+import parser.astBuilder.ASTBuilder;
+import parser.generated.SimpleJavaLexer;
+import parser.generated.SimpleJavaParser;
+import semantic.SemanticAnalyzer;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+
+public class E2EReflectionsTest {
+
+
+ private CharStream mockInputCharStream;
+ private String outputDirectoryPath;
+ private SimpleJavaLexer mockLexer;
+ private CommonTokenStream mockTokenStream;
+ private SimpleJavaParser mockParser;
+ private ParseTree mockParseTree;
+ private ASTBuilder mockASTBuilder;
+ private ASTNode mockASTNode;
+ private SemanticAnalyzer mockSemanticAnalyzer;
+ private ASTNode mockTypedAST;
+ private ByteCodeGenerator mockByteCodeGenerator;
+
+ @BeforeEach
+ public void setUp() {
+ mockInputCharStream = mock(CharStream.class);
+ outputDirectoryPath = "path/to/output";
+ mockLexer = mock(SimpleJavaLexer.class);
+ mockTokenStream = mock(CommonTokenStream.class);
+ mockParser = mock(SimpleJavaParser.class);
+ mockParseTree = mock(ParseTree.class);
+ mockASTBuilder = mock(ASTBuilder.class);
+ mockASTNode = mock(ASTNode.class);
+ mockSemanticAnalyzer = mock(SemanticAnalyzer.class);
+ mockTypedAST = mock(ASTNode.class);
+ mockByteCodeGenerator = mock(ByteCodeGenerator.class);
+ }
+
+ @Test
+ public void testCompileFile() throws Exception {
+ // Mock the dependencies
+ SimpleJavaLexer mockLexer = mock(SimpleJavaLexer.class);
+ CommonTokenStream mockTokenStream = mock(CommonTokenStream.class);
+ SimpleJavaParser mockParser = mock(SimpleJavaParser.class);
+ ParseTree mockParseTree = mock(ParseTree.class);
+ ASTBuilder mockASTBuilder = mock(ASTBuilder.class);
+ ASTNode mockASTNode = mock(ASTNode.class);
+ SemanticAnalyzer mockSemanticAnalyzer = mock(SemanticAnalyzer.class);
+ ASTNode mockTypedAST = mock(ASTNode.class);
+ ByteCodeGenerator mockByteCodeGenerator = mock(ByteCodeGenerator.class);
+
+ // Mock the behavior
+ when(mockLexer.nextToken()).thenReturn(null);
+ when(mockTokenStream.getTokens()).thenReturn(new ArrayList<>());
+ when(mockParser.program()).thenReturn((SimpleJavaParser.ProgramContext) mockParseTree);
+ when(mockASTBuilder.visit(mockParseTree)).thenReturn(mockASTNode);
+ when(SemanticAnalyzer.generateTast(mockASTNode)).thenReturn(mockTypedAST);
+
+ // Use reflection to invoke the compileFile method
+ Method compileFileMethod = main.Main.class.getDeclaredMethod("compileFile", CharStream.class, String.class);
+ compileFileMethod.setAccessible(true);
+
+ compileFileMethod.invoke(null, mockInputCharStream, outputDirectoryPath);
+
+ // Verify each step
+ verify(mockLexer, times(1)).nextToken();
+ verify(mockTokenStream, times(1)).getTokens();
+ verify(mockParser, times(1)).program();
+ verify(mockASTBuilder, times(1)).visit(mockParseTree);
+ verify(mockSemanticAnalyzer, times(1)).generateTast(mockASTNode);
+ verify(mockByteCodeGenerator, times(1)).visit((ProgramNode) mockTypedAST);
+ }
+
+ @Test
+ public void testCompileFile2() throws Exception {
+ // Mock the behavior
+ when(mockLexer.nextToken()).thenReturn(null);
+ when(mockTokenStream.getTokens()).thenReturn(new ArrayList<>());
+ when(mockParser.program()).thenReturn((SimpleJavaParser.ProgramContext) mockParseTree);
+ when(mockASTBuilder.visit(mockParseTree)).thenReturn(mockASTNode);
+ when(SemanticAnalyzer.generateTast(mockASTNode)).thenReturn(mockTypedAST);
+
+ // Use reflection to invoke the compileFile method
+ Method compileFileMethod = main.Main.class.getDeclaredMethod("compileFile", CharStream.class, String.class);
+ compileFileMethod.setAccessible(true);
+
+ compileFileMethod.invoke(null, mockInputCharStream, outputDirectoryPath);
+
+ // Verify each step
+ verify(mockLexer, times(1)).nextToken();
+ verify(mockTokenStream, times(1)).getTokens();
+ verify(mockParser, times(1)).program();
+ verify(mockASTBuilder, times(1)).visit(mockParseTree);
+ verify(mockSemanticAnalyzer, times(1)).generateTast(mockASTNode);
+ verify(mockByteCodeGenerator, times(1)).visit((ProgramNode) mockTypedAST);
+ }
+
+
+
+
+
+
+ @Test
+ public void testLexer() {
+ // Mock the behavior
+ when(mockLexer.nextToken()).thenReturn(null);
+
+ // Test the lexer
+ SimpleJavaLexer lexer = new SimpleJavaLexer(mockInputCharStream);
+ CommonTokenStream tokenStream = new CommonTokenStream(lexer);
+ tokenStream.fill();
+
+ assertNotNull(tokenStream.getTokens());
+ verify(mockLexer, atLeastOnce()).nextToken();
+ }
+
+ @Test
+ public void testParser() {
+ // Mock the behavior
+ when(mockParser.program()).thenReturn((SimpleJavaParser.ProgramContext) mockParseTree);
+
+ // Test the parser
+ SimpleJavaParser parser = new SimpleJavaParser(mockTokenStream);
+ ParseTree parseTree = parser.program();
+
+ assertNotNull(parseTree);
+ verify(mockParser, times(1)).program();
+ }
+
+ @Test
+ public void testASTBuilder() {
+ // Mock the behavior
+ when(mockASTBuilder.visit(mockParseTree)).thenReturn(mockASTNode);
+
+ // Test the AST builder
+ ASTBuilder astBuilder = new ASTBuilder();
+ ASTNode abstractSyntaxTree = astBuilder.visit(mockParseTree);
+
+ assertNotNull(abstractSyntaxTree);
+ verify(mockASTBuilder, times(1)).visit(mockParseTree);
+ }
+
+ @Test
+ public void testSemanticAnalyzer() {
+ // Mock the behavior
+ when(SemanticAnalyzer.generateTast(mockASTNode)).thenReturn(mockTypedAST);
+
+ // Test the semantic analyzer
+ ASTNode typedAst = SemanticAnalyzer.generateTast(mockASTNode);
+
+ assertNotNull(typedAst);
+ verify(mockSemanticAnalyzer, times(1)).generateTast(mockASTNode);
+ }
+
+ @Test
+ public void testByteCodeGenerator() {
+ // Test the bytecode generator
+ ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(outputDirectoryPath, true, true);
+ byteCodeGenerator.visit((ProgramNode) mockTypedAST);
+
+ verify(mockByteCodeGenerator, times(1)).visit((ProgramNode) mockTypedAST);
+ }
+}
+
diff --git a/src/test/resources/input/AllFeaturesClassExample.java b/src/test/resources/input/AllFeaturesClassExample.java
index 1a8493d..73121ee 100644
--- a/src/test/resources/input/AllFeaturesClassExample.java
+++ b/src/test/resources/input/AllFeaturesClassExample.java
@@ -9,42 +9,25 @@ public class AllFeaturesClassExample {
this.b = b;
this.c = c;
}
- private class InnerClass {
- void innerMethod() {
- System.out.println("Inner class method");
- }
- }
// Methode zur Demonstration von Kontrollstrukturen
void controlStructures() {
// if-else Anweisung
if (a > 10) {
- System.out.println("a ist größer als 10");
+ // System.out.println("a ist größer als 10");
} else {
- System.out.println("a ist nicht größer als 10");
+ // System.out.println("a ist nicht größer als 10");
}
// while Schleife
while (a > 0) {
- System.out.println("a ist " + a);
+ // System.out.println("a ist " + a);
a--;
}
// for Schleife
for (int i = 0; i < 5; i++) {
- System.out.println("for Schleife Iteration: " + i);
- }
-
- // switch Anweisung
- switch (c) {
- case 'a':
- System.out.println("c ist ein 'a'");
- break;
- case 'b':
- System.out.println("c ist ein 'b'");
- break;
- default:
- System.out.println("c ist nicht 'a' oder 'b'");
+ // System.out.println("for Schleife Iteration: " + i);
}
}
@@ -52,15 +35,28 @@ public class AllFeaturesClassExample {
void logicalOperations() {
// Logische UND-Operation
if (b && a > 5) {
- System.out.println("a ist größer als 5 und b ist wahr");
+ // System.out.println("a ist größer als 5 und b ist wahr");
}
// Logische ODER-Operation
if (b || a < 5) {
- System.out.println("b ist wahr oder a ist kleiner als 5");
+ // System.out.println("b ist wahr oder a ist kleiner als 5");
}
}
+ void mathOperations() {
+ // Addition
+ int sum = a + 5;
+ // Subtraktion
+ int difference = a - 5;
+ // Multiplikation
+ int product = a * 5;
+ // Division
+ int quotient = a / 5;
+ // Modulo
+ int remainder = a % 5;
+ }
+
public static void main(String[] args) {
AllFeaturesClassExample obj = new AllFeaturesClassExample(12, true, 'a');
obj.controlStructures();
diff --git a/src/test/resources/trees/correctRefType.json b/src/test/resources/trees/correctRefType.json
deleted file mode 100644
index 7e67bbc..0000000
--- a/src/test/resources/trees/correctRefType.json
+++ /dev/null
@@ -1,70 +0,0 @@
-{
- "classes": [
- {
- "identifier": "testClass1",
- "accessType": {
- "enumAccessTypeNode": "PUBLIC"
- },
- "members": [
- {
- "@type": "Field",
- "accessTypeNode": {
- "enumAccessTypeNode": "PUBLIC"
- },
- "type": {
- "@type": "Base",
- "enumType": "INT"
- },
- "identifier": "testVar1"
- },
- {
- "@type": "Method",
- "visibility": {
- "enumAccessTypeNode": "PUBLIC"
- },
- "type": {
- "@type": "Base",
- "enumType": "INT"
- },
- "identifier": "testMethod",
- "parameters": {
- "parameters": [
- {
- "type": {
- "@type": "Base",
- "enumType": "INT"
- },
- "identifier": "param1"
- }
- ]
- },
- "statements": [
- {
- "@type": "Assignment",
- "expressionLeft": {
- "@type": "InstVar",
- "identifier": "testVar1",
- "expression": {
- "@type": "This",
- "type": {
- "@type": "Reference",
- "identifier": "testClass1"
- }
- },
- "type": null
- },
- "expressionRight": {
- "@type": "Literal",
- "type": {
- "@type": "Base",
- "enumType": "INT"
- }
- }
- }
- ]
- }
- ],
- "hasConstructor": false
- }
- ]
-}
\ No newline at end of file
diff --git a/src/test/resources/trees/refTypeMismatch.json b/src/test/resources/trees/refTypeMismatch.json
deleted file mode 100644
index e5ebcd3..0000000
--- a/src/test/resources/trees/refTypeMismatch.json
+++ /dev/null
@@ -1,133 +0,0 @@
-{
- "classes": [
- {
- "identifier": "testClass1",
- "accessType": {
- "enumAccessTypeNode": "PUBLIC"
- },
- "members": [
- {
- "@type": "Field",
- "accessTypeNode": {
- "enumAccessTypeNode": "PUBLIC"
- },
- "type": {
- "@type": "Base",
- "enumType": "INT"
- },
- "identifier": "testVar1"
- },
- {
- "@type": "Method",
- "visibility": {
- "enumAccessTypeNode": "PUBLIC"
- },
- "type": {
- "@type": "Base",
- "enumType": "INT"
- },
- "identifier": "testMethod",
- "parameters": {
- "parameters": [
- {
- "type": {
- "@type": "Base",
- "enumType": "INT"
- },
- "identifier": "param1"
- }
- ]
- },
- "statements": [
- {
- "@type": "Assignment",
- "expressionLeft": {
- "@type": "InstVar",
- "identifier": "testVar1",
- "expression": {
- "@type": "This",
- "type": {
- "@type": "Reference",
- "identifier": "testClass1"
- }
- },
- "type": null
- },
- "expressionRight": {
- "@type": "Literal",
- "type": {
- "@type": "Base",
- "enumType": "BOOLEAN"
- }
- }
- }
- ]
- }
- ],
- "hasConstructor": false,
- "methods": [
- {
- "@type": "Method",
- "visibility": {
- "enumAccessTypeNode": "PUBLIC"
- },
- "type": {
- "@type": "Base",
- "enumType": "INT"
- },
- "identifier": "testMethod",
- "parameters": {
- "parameters": [
- {
- "type": {
- "@type": "Base",
- "enumType": "INT"
- },
- "identifier": "param1"
- }
- ]
- },
- "statements": [
- {
- "@type": "Assignment",
- "expressionLeft": {
- "@type": "InstVar",
- "identifier": "testVar",
- "expression": {
- "@type": "InstVar",
- "identifier": "testVar",
- "expression": {
- "@type": "This",
- "type": {
- "@type": "Reference",
- "identifier": "testClass2"
- }
- },
- "type": null
- },
- "type": null
- },
- "expressionRight": {
- "@type": "Literal",
- "type": null
- },
- "type": null
- },
- {
- "@type": "VariableDeclaration",
- "type": {
- "@type": "Base",
- "enumType": "CHAR"
- },
- "identifier": "objectVar",
- "expression": {
- "@type": "Literal",
- "type": null
- }
- }
- ]
- }
- ]
- }
- ]
-}
\ No newline at end of file
diff --git a/src/test/resources/trees/test.json b/src/test/resources/trees/test.json
deleted file mode 100644
index 7acc30f..0000000
--- a/src/test/resources/trees/test.json
+++ /dev/null
@@ -1 +0,0 @@
-{"classes":[{"identifier":"testClass","accessType":{"enumAccessTypeNode":"PUBLIC"},"members":[{"@type":"Field","accessTypeNode":{"enumAccessTypeNode":"PUBLIC"},"type":{"@type":"Base","enumType":"INT"},"identifier":"testVar1"},{"@type":"Field","accessTypeNode":{"enumAccessTypeNode":"PUBLIC"},"type":{"@type":"Base","enumType":"INT"},"identifier":"objectVar"},{"@type":"Method","visibility":{"enumAccessTypeNode":"PUBLIC"},"type":{"@type":"Base","enumType":"INT"},"identifier":"testVar2","parameters":{"parameters":[{"type":{"@type":"Base","enumType":"INT"},"identifier":"param1"}]},"statements":[{"@type":"Assignment","expressionLeft":{"@type":"InstVar","identifier":"objectVar","expression":{"@type":"This","type":{"@type":"Reference","identifier":"testClass"}},"type":null},"expressionRight":{"@type":"Literal","type":{"@type":"Base","enumType":"INT"}}}]}],"hasConstructor":false,"methods":[{"@type":"Method","visibility":{"enumAccessTypeNode":"PUBLIC"},"type":{"@type":"Base","enumType":"INT"},"identifier":"testVar2","parameters":{"parameters":[{"type":{"@type":"Base","enumType":"INT"},"identifier":"param1"}]},"statements":[{"@type":"Assignment","expressionLeft":{"@type":"InstVar","identifier":"objectVar","expression":{"@type":"This","type":{"@type":"Reference","identifier":"testClass"}},"type":null},"expressionRight":{"@type":"Literal","type":{"@type":"Base","enumType":"INT"}}}]}]}]}
\ No newline at end of file