From 4d58a4b1f295ae56f4c1f4109adcec85639dc418 Mon Sep 17 00:00:00 2001 From: JonathanFleischmann Date: Thu, 9 May 2024 00:10:23 +0200 Subject: [PATCH 1/3] wrote tests for ScannerAndParser and more --- pom.xml | 21 +++ src/main/java/de/maishai/Compiler.java | 15 +- .../AbstractSyntax_ClassWithConstructor.java | 2 +- ...lassWithConstructorWithCodeInComments.java | 128 ++++++++++++++++++ ...ax_ClassWithConstructorWithParameters.java | 4 +- .../AbstractSyntax_ClassWithField.java | 2 +- .../AbstractSyntax_OnlyClass.java | 18 --- ...lassWithConstructorWithCodeInComments.java | 14 ++ .../resources/JavaTestfiles/OnlyClass.java | 2 - ...lassWithConstructorWithCodeInComments.java | 128 ++++++++++++++++++ .../TypedAbstractSyntax_OnlyClass.java | 19 --- src/test/java/E2ETests.java | 2 - src/test/java/ScannerParserTests.java | 56 ++++++++ 13 files changed, 363 insertions(+), 48 deletions(-) create mode 100644 src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithConstructorWithCodeInComments.java delete mode 100644 src/main/resources/AbstractSyntax/AbstractSyntax_OnlyClass.java create mode 100644 src/main/resources/JavaTestfiles/ClassWithConstructorWithCodeInComments.java delete mode 100644 src/main/resources/JavaTestfiles/OnlyClass.java create mode 100644 src/main/resources/TypedAbstractSyntax/TypedAbstractSyntax_ClassWithConstructorWithCodeInComments.java delete mode 100644 src/main/resources/TypedAbstractSyntax/TypedAbstractSyntax_OnlyClass.java create mode 100644 src/test/java/ScannerParserTests.java diff --git a/pom.xml b/pom.xml index bd6a321..c26011c 100644 --- a/pom.xml +++ b/pom.xml @@ -55,6 +55,27 @@ 4.13.1 + + + + org.junit.jupiter + junit-jupiter-api + 5.10.2 + test + + + org.junit.jupiter + junit-jupiter-engine + 5.10.2 + test + + + org.junit.jupiter + junit-jupiter + RELEASE + test + + diff --git a/src/main/java/de/maishai/Compiler.java b/src/main/java/de/maishai/Compiler.java index e9dd64d..b1895aa 100644 --- a/src/main/java/de/maishai/Compiler.java +++ b/src/main/java/de/maishai/Compiler.java @@ -7,7 +7,6 @@ import de.maishai.typedast.CodeGenUtils; import de.maishai.typedast.typedclass.TypedClass; import org.antlr.v4.runtime.*; -import java.io.FileOutputStream; import java.io.IOException; /** @@ -41,8 +40,18 @@ public class Compiler { CommonTokenStream tokens = new CommonTokenStream(lexer); DecafParser parser = new DecafParser(tokens); DecafParser.ClassContext tree = parser.class_(); //Parsen - Class ast = ASTGenerator.generateAST(tree); - return ast; + return ASTGenerator.generateAST(tree); + } + + public static Class generateASTFromFile(String sourcePath) { + ANTLRInputStream antlrInputStream; + try { + antlrInputStream = new ANTLRFileStream(sourcePath); + } catch (IOException e) { + System.out.println("Ungültiger Dateipfad D:"); + throw new RuntimeException("Ungültiger Dateipfad D:"); + } + return generateAST(antlrInputStream.toString()); } public static TypedClass generateTypedASTFromAst(Class ast) { diff --git a/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithConstructor.java b/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithConstructor.java index a717132..bc1b95f 100644 --- a/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithConstructor.java +++ b/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithConstructor.java @@ -111,7 +111,7 @@ public class AbstractSyntax_ClassWithConstructor { "j"), Operator.LT, new FieldVarAccess( - false, + true, null, "x") ), diff --git a/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithConstructorWithCodeInComments.java b/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithConstructorWithCodeInComments.java new file mode 100644 index 0000000..3253a61 --- /dev/null +++ b/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithConstructorWithCodeInComments.java @@ -0,0 +1,128 @@ +//public class ClassWithConstructorWithCodeInComments { +// int x; +// public ClassWithConstructorWithCodeInComments() { +// this.x = 10; +// int i; +// for (i = 0; i < 6; i = i + 1) { +// this.x = this.x * this.x; +//// int j; +//// for (j = 0; j < this.x; j += 1) { +//// this.x = this.x * this.x; +//// } +// } +// } +//} + +import de.maishai.ast.Operator; +import de.maishai.ast.records.Class; +import de.maishai.ast.records.*; +import de.maishai.typedast.Type; + +import java.util.List; + +public class AbstractSyntax_ClassWithConstructorWithCodeInComments { + public static Class get() { + List declarations = List.of( + new Declaration( + "x", + Type.INT + ) + ); + List methods = List.of(); + List constructors = getConstructors(); + return new Class( + "ClassWithConstructorWithCodeInComments", + declarations, + methods, + constructors + ); + } + + private static List getConstructors() { + return List.of(getConstructor1()); + } + + private static Constructor getConstructor1() { + List parameters = List.of(); + + List localVariables = List.of( + new Declaration( + "i", + Type.INT + ) + ); + List statementList = List.of( + new Assignment( + new FieldVarAccess( + true, + null, + "x"), + new IntLiteral(10) + ), + new For( + new Assignment( + new FieldVarAccess( + false, + null, + "i"), + new IntLiteral(0) + ), + new Binary( + new FieldVarAccess( + false, + null, + "i"), + Operator.LT, + new IntLiteral(6) + ), + new Assignment( + new FieldVarAccess( + false, + null, + "i"), + new Binary( + new FieldVarAccess( + false, + null, + "i"), + Operator.ADD, + new IntLiteral(1) + ) + ), + new Block( + List.of(), + List.of( + new Assignment( + new FieldVarAccess( + true, + null, + "x"), + new Binary( + new FieldVarAccess( + true, + null, + "x"), + Operator.MUL, + new FieldVarAccess( + true, + null, + "x") + ) + ) + ) + ) + ) + + ); + Block block = new Block( + localVariables, + statementList + ); + + return new Constructor( + "ClassWithConstructorWithCodeInComments", + parameters, + block + ); + } +} \ No newline at end of file diff --git a/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithConstructorWithParameters.java b/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithConstructorWithParameters.java index 155a6bd..6cce69c 100644 --- a/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithConstructorWithParameters.java +++ b/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithConstructorWithParameters.java @@ -1,6 +1,6 @@ //public class ClassWithConstructorWithParameters { // int x; -// public classWithConstructorWithParameters(int startValue, int repetitions) { +// public ClassWithConstructorWithParameters(int startValue, int repetitions) { // this.x = startValue; // while (repetitions > 0) { // int innerRepetitions; @@ -158,7 +158,7 @@ public class AbstractSyntax_ClassWithConstructorWithParameters { ) ); return new Constructor( - "classWithConstructorWithParameters", + "ClassWithConstructorWithParameters", parameters, block ); diff --git a/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithField.java b/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithField.java index c166836..9d00045 100644 --- a/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithField.java +++ b/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithField.java @@ -21,7 +21,7 @@ public class AbstractSyntax_ClassWithField { List methods = List.of(); List constructors = List.of(); return new Class( - "ClassWithAssignment", + "ClassWithField", declarations, methods, constructors diff --git a/src/main/resources/AbstractSyntax/AbstractSyntax_OnlyClass.java b/src/main/resources/AbstractSyntax/AbstractSyntax_OnlyClass.java deleted file mode 100644 index 88dc316..0000000 --- a/src/main/resources/AbstractSyntax/AbstractSyntax_OnlyClass.java +++ /dev/null @@ -1,18 +0,0 @@ -//class OnlyClass { -//} - -import de.maishai.ast.records.*; -import de.maishai.ast.records.Class; - -import java.util.List; - -public class AbstractSyntax_OnlyClass { - public static Class get() { - return new Class( - "OnlyClass", - List.of(), - List.of(), - List.of() - ); - } -} \ No newline at end of file diff --git a/src/main/resources/JavaTestfiles/ClassWithConstructorWithCodeInComments.java b/src/main/resources/JavaTestfiles/ClassWithConstructorWithCodeInComments.java new file mode 100644 index 0000000..7f81001 --- /dev/null +++ b/src/main/resources/JavaTestfiles/ClassWithConstructorWithCodeInComments.java @@ -0,0 +1,14 @@ +public class ClassWithConstructorWithCodeInComments { + int x; + public ClassWithConstructorWithCodeInComments() { + this.x = 10; + int i; + for (i = 0; i < 6; i = i + 1) { + this.x = this.x * this.x; +// int j; +// for (j = 0; j < this.x; j += 1) { +// this.x = this.x * this.x; +// } + } + } +} \ No newline at end of file diff --git a/src/main/resources/JavaTestfiles/OnlyClass.java b/src/main/resources/JavaTestfiles/OnlyClass.java deleted file mode 100644 index bc5ca5c..0000000 --- a/src/main/resources/JavaTestfiles/OnlyClass.java +++ /dev/null @@ -1,2 +0,0 @@ -class OnlyClass { -} \ No newline at end of file diff --git a/src/main/resources/TypedAbstractSyntax/TypedAbstractSyntax_ClassWithConstructorWithCodeInComments.java b/src/main/resources/TypedAbstractSyntax/TypedAbstractSyntax_ClassWithConstructorWithCodeInComments.java new file mode 100644 index 0000000..9cb6e25 --- /dev/null +++ b/src/main/resources/TypedAbstractSyntax/TypedAbstractSyntax_ClassWithConstructorWithCodeInComments.java @@ -0,0 +1,128 @@ +//public class ClassWithConstructorWithCodeInComments { +// int x; +// public ClassWithConstructorWithCodeInComments() { +// this.x = 10; +// int i; +// for (i = 0; i < 6; i = i + 1) { +// this.x = this.x * this.x; +//// int j; +//// for (j = 0; j < this.x; j += 1) { +//// this.x = this.x * this.x; +//// } +// } +// } +//} + +import de.maishai.ast.Operator; +import de.maishai.ast.records.Class; +import de.maishai.ast.records.*; +import de.maishai.typedast.Type; + +import java.util.List; + +public class TypedAbstractSyntax_ClassWithConstructorWithCodeInComments { +// public static Class get() { +// List declarations = List.of( +// new Declaration( +// "x", +// Type.INT +// ) +// ); +// List methods = List.of(); +// List constructors = getConstructors(); +// return new Class( +// "ClassWithConstructorWithCodeInComments", +// declarations, +// methods, +// constructors +// ); +// } +// +// private static List getConstructors() { +// return List.of(getConstructor1()); +// } +// +// private static Constructor getConstructor1() { +// List parameters = List.of(); +// +// List localVariables = List.of( +// new Declaration( +// "i", +// Type.INT +// ) +// ); +// List statementList = List.of( +// new Assignment( +// new FieldVarAccess( +// true, +// null, +// "x"), +// new IntLiteral(10) +// ), +// new For( +// new Assignment( +// new FieldVarAccess( +// false, +// null, +// "i"), +// new IntLiteral(0) +// ), +// new Binary( +// new FieldVarAccess( +// false, +// null, +// "i"), +// Operator.LT, +// new IntLiteral(6) +// ), +// new Assignment( +// new FieldVarAccess( +// false, +// null, +// "i"), +// new Binary( +// new FieldVarAccess( +// false, +// null, +// "i"), +// Operator.ADD, +// new IntLiteral(1) +// ) +// ), +// new Block( +// List.of(), +// List.of( +// new Assignment( +// new FieldVarAccess( +// true, +// null, +// "x"), +// new Binary( +// new FieldVarAccess( +// true, +// null, +// "x"), +// Operator.MUL, +// new FieldVarAccess( +// true, +// null, +// "x") +// ) +// ) +// ) +// ) +// ) +// +// ); +// Block block = new Block( +// localVariables, +// statementList +// ); +// +// return new Constructor( +// "ClassWithConstructorWithCodeInComments", +// parameters, +// block +// ); +// } +} \ No newline at end of file diff --git a/src/main/resources/TypedAbstractSyntax/TypedAbstractSyntax_OnlyClass.java b/src/main/resources/TypedAbstractSyntax/TypedAbstractSyntax_OnlyClass.java deleted file mode 100644 index 0a61694..0000000 --- a/src/main/resources/TypedAbstractSyntax/TypedAbstractSyntax_OnlyClass.java +++ /dev/null @@ -1,19 +0,0 @@ -//class OnlyClass { -//} - -import de.maishai.typedast.typedclass.*; - -import java.util.List; - -public class TypedAbstractSyntax_OnlyClass { -// public static TypedClass get() { -// TypedClass typedClass = new TypedClass(); -// typedClass.setIsPublic(false); -// typedClass.setTypedId(new TypedId("OnlyClass")); -// typedClass.setTypedFields(List.of()); -// typedClass.setTypedMethods(List.of()); -// typedClass.setTypedMainMethod(null); -// typedClass.setTypedConstructors(List.of()); -// return typedClass; -// } -} \ No newline at end of file diff --git a/src/test/java/E2ETests.java b/src/test/java/E2ETests.java index db3a256..57f34f2 100644 --- a/src/test/java/E2ETests.java +++ b/src/test/java/E2ETests.java @@ -1,5 +1,3 @@ public class E2ETests { - public static void main(String[] args) { - } } diff --git a/src/test/java/ScannerParserTests.java b/src/test/java/ScannerParserTests.java new file mode 100644 index 0000000..26e52a2 --- /dev/null +++ b/src/test/java/ScannerParserTests.java @@ -0,0 +1,56 @@ +import de.maishai.Compiler; +import de.maishai.ast.records.Class; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ScannerParserTests { + + @Test + public void testPublicClass() { + Class resultAst = Compiler.generateASTFromFile("src/main/resources/JavaTestfiles/PublicClass.java"); + assertEquals(AbstractSyntax_PublicClass.get(), resultAst); + } + + @Test + public void testClassWithField() { + Class resultAst = Compiler.generateASTFromFile("src/main/resources/JavaTestfiles/ClassWithField.java"); + assertEquals(AbstractSyntax_ClassWithField.get(), resultAst); + } + + @Test + public void testClassWithConstructor() { + Class resultAst = Compiler.generateASTFromFile("src/main/resources/JavaTestfiles/ClassWithConstructor.java"); + assertEquals(AbstractSyntax_ClassWithConstructor.get(), resultAst); + } + + @Test + public void testClassWithMethod() { + Class resultAst = Compiler.generateASTFromFile("src/main/resources/JavaTestfiles/ClassWithMethod.java"); + assertEquals(AbstractSyntax_ClassWithMethod.get(), resultAst); + } + + @Test + public void testClassWithConstructorWithCodeInComments() { + Class resultAst = Compiler.generateASTFromFile("src/main/resources/JavaTestfiles/ClassWithConstructorWithCodeInComments.java"); + assertEquals(AbstractSyntax_ClassWithConstructorWithCodeInComments.get(), resultAst); + } + + @Test + public void testClassWithConstructorWithParameters() { + Class resultAst = Compiler.generateASTFromFile("src/main/resources/JavaTestfiles/ClassWithConstructorWithParameters.java"); + assertEquals(AbstractSyntax_ClassWithConstructorWithParameters.get(), resultAst); + } + + @Test + public void testClassWithMethodAndField() { + Class resultAst = Compiler.generateASTFromFile("src/main/resources/JavaTestfiles/ClassWithMethodAndField.java"); + assertEquals(AbstractSyntax_ClassWithMethodAndField.get(), resultAst); + } + +// @Test +// public void testClassWithConstructorAndMethodCall() { +// Class resultAst = Compiler.generateASTFromFile("src/main/resources/JavaTestfiles/ClassWithConstructorAndMethodCall.java"); +// assertEquals(AbstractSyntax_ClassWithConstructorAndMethodCall.get(), resultAst); +// } +} From ac23df965d33ddbb92248fc1937785609da0d632 Mon Sep 17 00:00:00 2001 From: Ahmad Date: Tue, 14 May 2024 06:55:18 +0200 Subject: [PATCH 2/3] Capture all return cases --- .../typedast/typedclass/TypedMethod.java | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedMethod.java b/src/main/java/de/maishai/typedast/typedclass/TypedMethod.java index 219d41e..cd701eb 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedMethod.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedMethod.java @@ -1,5 +1,6 @@ package de.maishai.typedast.typedclass; +import de.maishai.ast.records.IfElse; import de.maishai.ast.records.Method; import de.maishai.ast.records.Node; import de.maishai.ast.records.Parameter; @@ -63,13 +64,39 @@ public class TypedMethod implements TypedNode { return localVariables.stream().filter(localVariable -> localVariable.getName().equals(localVarName)).findFirst().get().getType(); } + private boolean hasEvenReturnsInIfElseBlocks() { + List typedIfElses = new ArrayList<>(); + for (var stmt : typedBlock.getStmts()) { + if (stmt instanceof TypedIfElse ifElse) { + for (var stmt2 : ifElse.getIfTypedBlock().getStmts()) { + if (stmt2 instanceof TypedReturn) { + typedIfElses.add(ifElse); + } + } + for (var stmt2 : ifElse.getElseTypedBlock().getStmts()) { + if (stmt2 instanceof TypedReturn) { + typedIfElses.add(ifElse); + } + } + } + } + if (typedIfElses.size() % 2 == 0) { + return true; + } else { + return false; + } + } @Override public Type typeCheck(TypedClass clas) { - if(returnType != Type.VOID){ - if(typedBlock.typeCheck(clas).getKind() != returnType.getKind()){ - throw new RuntimeException("Method " + name + " must return " + returnType); - } + if (returnType != Type.VOID && !hasEvenReturnsInIfElseBlocks()) { + if (typedBlock.typeCheck(clas).getKind() != returnType.getKind()) { + if (hasEvenReturnsInIfElseBlocks()) { + throw new RuntimeException("Method " + name + " must have even returns in if else blocks"); + } else { + throw new RuntimeException("Method " + name + " must return " + returnType.getKind()); + } + } } return returnType; } From 71560cf163b6b1b13789f70483bc02406f42f282 Mon Sep 17 00:00:00 2001 From: JonathanFleischmann Date: Tue, 14 May 2024 09:50:08 +0200 Subject: [PATCH 3/3] fixed missing empty constructor in Testfiles --- .../AbstractSyntax_ClassWithField.java | 16 ++++++++++++---- .../AbstractSyntax_ClassWithMethod.java | 11 ++++++++++- .../AbstractSyntax_PublicClass.java | 14 +++++++++++++- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithField.java b/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithField.java index 9d00045..48368a6 100644 --- a/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithField.java +++ b/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithField.java @@ -2,10 +2,8 @@ // int x; //} +import de.maishai.ast.records.*; import de.maishai.ast.records.Class; -import de.maishai.ast.records.Constructor; -import de.maishai.ast.records.Declaration; -import de.maishai.ast.records.Method; import de.maishai.typedast.Type; import java.util.List; @@ -19,7 +17,17 @@ public class AbstractSyntax_ClassWithField { ) ); List methods = List.of(); - List constructors = List.of(); + List constructors = + List.of( + new Constructor( + "ClassWithField", + List.of(), + new Block( + List.of(), + List.of() + ) + ) + ); return new Class( "ClassWithField", declarations, diff --git a/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithMethod.java b/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithMethod.java index e61e742..9a1dd4c 100644 --- a/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithMethod.java +++ b/src/main/resources/AbstractSyntax/AbstractSyntax_ClassWithMethod.java @@ -17,7 +17,16 @@ public class AbstractSyntax_ClassWithMethod { "ClassWithMethod", List.of(), methods, - List.of() + List.of( + new Constructor( + "ClassWithMethod", + List.of(), + new Block( + List.of(), + List.of() + ) + ) + ) ); } diff --git a/src/main/resources/AbstractSyntax/AbstractSyntax_PublicClass.java b/src/main/resources/AbstractSyntax/AbstractSyntax_PublicClass.java index d12d24e..8c0c341 100644 --- a/src/main/resources/AbstractSyntax/AbstractSyntax_PublicClass.java +++ b/src/main/resources/AbstractSyntax/AbstractSyntax_PublicClass.java @@ -1,7 +1,9 @@ //public class PublicClass { //} +import de.maishai.ast.records.Block; import de.maishai.ast.records.Class; +import de.maishai.ast.records.Constructor; import java.util.List; @@ -11,7 +13,17 @@ public class AbstractSyntax_PublicClass { "PublicClass", List.of(), List.of(), - List.of() + List.of( + new Constructor( + "PublicClass", + List.of(), + new Block( + List.of(), + List.of() + ) + ) + ) ); } + } \ No newline at end of file