Compare commits

...

2 Commits

Author SHA1 Message Date
Julian Murek
4b36453ff3 Merge branch 'master' of https://gitea.hb.dhbw-stuttgart.de/i22022/NichtHaskell 2024-07-04 13:36:16 +02:00
Julian Murek
78d6d402a2 Test update 2024-07-04 13:36:05 +02:00
18 changed files with 222 additions and 41 deletions

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +1,9 @@
package TypeCheck;
import abstractSyntaxTree.StatementExpression.ReceivingMethod;
import java.util.Objects;
public class TypeCheckResult {
public TypeCheckResult(){}
@ -8,4 +12,16 @@ public class TypeCheckResult {
}
public String type;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TypeCheckResult typeCheckResult = (TypeCheckResult) o;
boolean result = (Objects.equals(type, typeCheckResult.type)
);
System.out.println("In TypeCheckResult: " + result);
return result;
}
}

View File

@ -175,6 +175,7 @@ public class BinaryExpression extends AbstractType implements IExpression{
boolean result = (Objects.equals(operator, binaryExpression.operator)
&& Objects.equals(left, binaryExpression.left)
&& Objects.equals(right, binaryExpression.right)
&& Objects.equals(left.getTypeCheckResult(), binaryExpression.left.getTypeCheckResult())
);
System.out.println("In BinaryExpression: " + result);

View File

@ -246,8 +246,10 @@ public class InstVarExpression extends AbstractType implements IExpression {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
InstVarExpression instVarExpression = (InstVarExpression) o;
boolean result = (Objects.equals(thisClass, instVarExpression.thisClass)
boolean result = (Objects.equals(receivers, instVarExpression.receivers)
&& Objects.equals(fieldName, instVarExpression.fieldName)
&& Objects.equals(receivingMethods, instVarExpression.receivingMethods)
&& Objects.equals(thisClass, instVarExpression.thisClass)
);
System.out.println("In InstVarExpression: " + result);

View File

@ -69,6 +69,7 @@ public class ReturnStatement extends AbstractType implements IStatement{
if (o == null || getClass() != o.getClass()) return false;
ReturnStatement returnStatement = (ReturnStatement) o;
boolean result = (Objects.equals(expression, returnStatement.expression)
&& Objects.equals(expression.getTypeCheckResult(), returnStatement.expression.getTypeCheckResult())
);
System.out.println("In PrintStatement: " + result);

View File

@ -17,8 +17,8 @@ import java.util.*;
public class MethodCallStatementExpression extends AbstractType implements IExpression, IStatement {
String methodName;
List<IExpression> arguments;
Receiver receiver; // Braucht typecheckResult
List<IExpression> arguments; // Need typecheckresults
Receiver receiver; // InstVarExpression und NewStatementExpression Braucht typecheckResult
List<ReceivingMethod> receivingMethods;
public String thisClass;
@ -234,9 +234,80 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MethodCallStatementExpression methodCallStatementExpression = (MethodCallStatementExpression) o;
return (Objects.equals(methodName, methodCallStatementExpression.methodName)
boolean typeCheckResults = testTypeChecks(this, methodCallStatementExpression);
boolean result = (Objects.equals(methodName, methodCallStatementExpression.methodName)
&& Objects.equals(arguments, methodCallStatementExpression.arguments)
);
&& Objects.equals(thisClass, methodCallStatementExpression.thisClass));
return result && typeCheckResults;
}
public boolean testTypeChecks(MethodCallStatementExpression class1, MethodCallStatementExpression class2) {
boolean resultArguments = true;
for (int i = 0; i < class1.arguments.size(); i++){
resultArguments = resultArguments && Objects.equals(class1.arguments.get(i).getTypeCheckResult(), class2.arguments.get(i).getTypeCheckResult());
}
boolean exception1 = false;
boolean exception2 = false;
try {
class1.receiver.instVarExpression.getTypeCheckResult();
} catch (NullPointerException e) {
exception1 = true;
}
try {
class2.receiver.instVarExpression.getTypeCheckResult();
} catch (NullPointerException e) {
exception2 = true;
}
if(exception1 != exception2) {
System.out.println("Only one of the InstVarTypeChecks is null in MethodCallStatementExpression");
return false;
}
if(!exception1) {
boolean resultInstVar = Objects.equals(receiver.instVarExpression.getTypeCheckResult(), class2.receiver.instVarExpression.getTypeCheckResult());
if(!resultInstVar) {
System.out.println("TypeCheckResult of receiver.instVarExpression.getTypeCheckResult() in MethodCallStatementExpression do not match");
return false;
}
}
try {
class1.receiver.newStatementExpression.getTypeCheckResult();
} catch (NullPointerException e) {
exception1 = true;
}
try {
class2.receiver.newStatementExpression.getTypeCheckResult();
} catch (NullPointerException e) {
exception2 = true;
}
if(exception1 != exception2) {
System.out.println("Only one of the newStatementExpression Typechecks is null in MethodCallStatementExpression");
return false;
}
if(!exception1) {
boolean resultNewStatementExpression = Objects.equals(receiver.newStatementExpression.getTypeCheckResult().type, class2.receiver.newStatementExpression.getTypeCheckResult().type);
if(!resultNewStatementExpression) {
System.out.println("TypeCheckResult of receiver.newStatementExpression.getTypeCheckResult().type in MethodCallStatementExpression do not match");
}
}
return true;
}
@Override

View File

@ -9,13 +9,11 @@ import abstractSyntaxTree.Expression.InstVarExpression;
import abstractSyntaxTree.Parameter.Parameter;
import abstractSyntaxTree.Parameter.ParameterList;
import abstractSyntaxTree.Statement.IStatement;
import abstractSyntaxTree.Statement.WhileStatement;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.*;
public class NewStatementExpression extends AbstractType implements IExpression, IStatement {
@ -28,6 +26,24 @@ public class NewStatementExpression extends AbstractType implements IExpression,
this.arguments = arguments;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
NewStatementExpression newStatementExpression = (NewStatementExpression) o;
boolean resultTypeCheckArguments = true;
for (int i = 0; i < newStatementExpression.arguments.size(); i++){
resultTypeCheckArguments = resultTypeCheckArguments && Objects.equals(this.arguments.get(i).getTypeCheckResult(), newStatementExpression.arguments.get(i).getTypeCheckResult());
}
boolean result = (Objects.equals(className, newStatementExpression.className)
&& Objects.equals(arguments, newStatementExpression.arguments)
);
System.out.println("In newStatementExpression: " + result);
return result;
}
@Override
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws TypeCheckException {
if(!TypeCheckHelper.typeExists(className, new ArrayList<>(typeContext.keySet()))){

View File

@ -11,6 +11,7 @@ import org.objectweb.asm.MethodVisitor;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Objects;
public class Receiver implements Node {
boolean thisExpression;
@ -18,6 +19,22 @@ public class Receiver implements Node {
NewStatementExpression newStatementExpression;
String identifier;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Receiver receiver = (Receiver) o;
boolean result = (Objects.equals(thisExpression, receiver.thisExpression)
&& Objects.equals(instVarExpression, receiver.instVarExpression)
&& Objects.equals(newStatementExpression, receiver.newStatementExpression)
&& Objects.equals(identifier, receiver.identifier)
);
System.out.println("In receiver: " + result);
return result;
}
public Receiver(boolean thisExpression) {
this.thisExpression = thisExpression;
}

View File

@ -9,12 +9,26 @@ import abstractSyntaxTree.Statement.LocalVarDecl;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
public class ReceivingMethod implements Node {
public String methodName;
public List<IExpression> arguments;
public String thisClass;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ReceivingMethod receivingMethod = (ReceivingMethod) o;
boolean result = (Objects.equals(methodName, receivingMethod.methodName)
&& Objects.equals(arguments, receivingMethod.arguments)
);
System.out.println("In ReceivingMethod: " + result);
return result;
}
public ReceivingMethod(String methodName, List<IExpression> arguments) {
this.methodName = methodName;
this.arguments = arguments;

View File

@ -1,5 +1,6 @@
package ASTs;
import TypeCheck.TypeCheckResult;
import Typecheck.TypingHelper;
import abstractSyntaxTree.Class.FieldDecl;
import abstractSyntaxTree.Class.MethodDecl;
@ -24,6 +25,8 @@ public class CharArgumentASTTyped {
List<RefType> classes = new ArrayList<>();
classes.add(getRefType());
Program program = new Program(classes);
addTyping(program);
return program;
}
@ -44,14 +47,17 @@ public class CharArgumentASTTyped {
List<SubReceiver> subReceiverList0 = new ArrayList<>();
subReceiverList0.add(subReceiver0);
InstVarExpression instVarExpression0 = new InstVarExpression(subReceiverList0, new ArrayList<>(), "c");
instVarExpression0.thisClass = "CharArgument";
CharConstantExpression charConstantExpression0 = new CharConstantExpression('a');
List<IExpression> argumentList0 = new ArrayList<>();
charConstantExpression0.setTypeCheckResult(new TypeCheckResult("char"));
argumentList0.add(charConstantExpression0);
MethodCallStatementExpression methodCallStatementExpression0 = new MethodCallStatementExpression("foo", null, new ArrayList<>(), argumentList0);
methodCallStatementExpression0.thisClass = "CharArgument";
AssignStatementExpression assignStatementExpression0 = new AssignStatementExpression("=", instVarExpression0,methodCallStatementExpression0);
List<IStatement> iStatementList0 = new ArrayList<>();
iStatementList0.add(assignStatementExpression0);
BlockStatement blockStatement0 = new BlockStatement(iStatementList0, null);
BlockStatement blockStatement0 = new BlockStatement(iStatementList0, "void");
MethodDecl methodDecl0 =new MethodDecl("CharArgument", null,
"CharArgument", new ParameterList(new ArrayList<>()), blockStatement0);
@ -59,10 +65,12 @@ public class CharArgumentASTTyped {
}
public static MethodDecl method1(){
ReturnStatement returnStatement0 =new ReturnStatement(new LocalVarIdentifier("c"));
LocalVarIdentifier localVarIdentifierC = new LocalVarIdentifier("c");
localVarIdentifierC.setTypeCheckResult(new TypeCheckResult("char"));
ReturnStatement returnStatement0 =new ReturnStatement(localVarIdentifierC);
List<IStatement> iStatementList0 =new ArrayList<>();
iStatementList0.add(returnStatement0);
BlockStatement blockStatement0 = new BlockStatement(iStatementList0, null);
BlockStatement blockStatement0 = new BlockStatement(iStatementList0, "char");
Parameter parameter00 = new Parameter("char", "c");
List<Parameter> parameterList0 = new ArrayList<>();
parameterList0.add(parameter00);
@ -75,13 +83,18 @@ public class CharArgumentASTTyped {
public static void addTyping(Program program){
// TypeContext
TypingHelper.addTypeContext(program, "EmptyClassWithConstructor", new HashMap<>());
HashMap<String, String> charArgumentMap0 = new HashMap<>();
charArgumentMap0.put("c", "char");
TypingHelper.addTypeContext(program, "CharArgument", charArgumentMap0);
// MethodContext
HashMap<String, ParameterList> method0 = new HashMap<>();
//method0.put("void", new ParameterList(new ArrayList<>()));
List<Parameter> parameterList0 = new ArrayList<>();
parameterList0.add(new Parameter("char", "c"));
ParameterList parameterListObj0 = new ParameterList(parameterList0);
method0.put("char", parameterListObj0);
HashMap<String, HashMap<String, ParameterList>> methods = new HashMap<>();
//methods.put("main", method0);
TypingHelper.addMethodContext(program, "EmptyClassWithConstructor", methods);
methods.put("foo", method0);
TypingHelper.addMethodContext(program, "CharArgument", methods);
}
}

View File

@ -94,14 +94,18 @@ public class FakultaetASTTyped {
iStmtList0.add(localVarExpr1);
//While Statement
BinaryExpression whileCondition = new BinaryExpression("<=", new LocalVarIdentifier("i"), new LocalVarIdentifier("number"));
LocalVarIdentifier identifierI = new LocalVarIdentifier("i");
identifierI.setTypeCheckResult(new TypeCheckResult("int"));
BinaryExpression whileCondition = new BinaryExpression("<=", identifierI, new LocalVarIdentifier("number"));
whileCondition.setTypeCheckResult(new TypeCheckResult("void"));
BinaryExpression whileBinExpr = new BinaryExpression("*", new LocalVarIdentifier("factorial"), new LocalVarIdentifier("i"));
AssignStatementExpression assignStatementExpression0 = new AssignStatementExpression("=", new LocalVarIdentifier("factorial"), whileBinExpr);
LocalVarIdentifier localVarIdentifierFactorial = new LocalVarIdentifier("factorial");
localVarIdentifierFactorial.setTypeCheckResult(new TypeCheckResult("int"));
BinaryExpression whileBinExpr = new BinaryExpression("*", localVarIdentifierFactorial, identifierI);
AssignStatementExpression assignStatementExpression0 = new AssignStatementExpression("=", localVarIdentifierFactorial, whileBinExpr);
List<IStatement> whileBlockStmts = new ArrayList<>();
LocalVarIdentifier identifierI = new LocalVarIdentifier("i");
BinaryExpression rightAssign1 = new BinaryExpression("+", identifierI, new IntConstantExpression(1));
AssignStatementExpression assignStatementExpression1 = new AssignStatementExpression("=", identifierI, rightAssign1);

View File

@ -5,6 +5,7 @@ import java.util.ArrayList;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Parameter;
import java.util.Random;
import static ByteCode.CompareByteCodeSyntax.compareMethod;
@ -93,10 +94,8 @@ public class CompareByteCodeBehaviour {
}
*/
System.out.println("length: " + methods1.length);
// Compare methods
for (int i = 0; i < methods1.length; i++) {
System.out.println("i: " + i);
Method method1 = methods1[i];
Method method2 = methods2[i];
@ -109,6 +108,9 @@ public class CompareByteCodeBehaviour {
// Test with some sample inputs
Object[] testInputs = getTestInputs(method1.getParameterTypes());
for(int j = 0; j < testInputs.length; j++){
System.out.println("TestInput: " + testInputs[j]);
}
Object result1 = method1.invoke(obj1, testInputs);
Object result2 = method2.invoke(obj2, testInputs);
@ -139,15 +141,16 @@ public class CompareByteCodeBehaviour {
private static Object[] getTestInputs(Class<?>[] parameterTypes) {
// Create test inputs based on parameter types
Object[] inputs = new Object[parameterTypes.length];
Random random = new Random();
for (int i = 0; i < parameterTypes.length; i++) {
if (parameterTypes[i] == int.class) {
inputs[i] = 1; // example value
inputs[i] = random.nextInt(10); // example value
} else if (parameterTypes[i] == String.class) {
inputs[i] = "test"; // example value
inputs[i] = "baguette"; // example value
} else if (parameterTypes[i] == char.class) {
inputs[i] = 'a';
} else if (parameterTypes[i] == boolean.class) {
inputs[i] = false;
inputs[i] = random.nextBoolean();
}
// Add more cases as needed for different parameter types
}
@ -156,13 +159,14 @@ public class CompareByteCodeBehaviour {
private Object[] getDefaultArguments(Parameter[] parameters) {
Object[] defaultArgs = new Object[parameters.length];
Random random = new Random();
for (int i = 0; i < parameters.length; i++) {
Class<?> paramType = parameters[i].getType();
if (paramType.isPrimitive()) {
if (paramType == boolean.class) {
defaultArgs[i] = false;
defaultArgs[i] = random.nextBoolean();
} else if (paramType == int.class) {
defaultArgs[i] = 1;
defaultArgs[i] = random.nextInt(10);
} else if (paramType == char.class) {
defaultArgs[i] = '\u0000';
} else if (paramType == String.class) {

View File

@ -8,19 +8,15 @@ import java.util.Arrays;
public class CompareByteCodeSyntax {
public static boolean haveSameBehavior(Class<?> class1, Class<?> class2) {
System.out.println("Comparing class signatures of " + class1.getName() + " and " + class2.getName());
if (!compareClassSignatures(class1, class2)) {
return false;
}
System.out.println("Comparing methods of " + class1.getName() + " and " + class2.getName());
if (!compareMethods(class1, class2)) {
return false;
}
System.out.println("Comparing fields of " + class1.getName() + " and " + class2.getName());
if (!compareFields(class1, class2)) {
return false;
}
System.out.println("Comparing annotations of " + class1.getName() + " and " + class2.getName());
if (!compareAnnotations(class1.getAnnotations(), class2.getAnnotations())) {
return false;
}
@ -81,6 +77,11 @@ public class CompareByteCodeSyntax {
System.out.println("Annotations do not match for methods " + method1.getName() + " and " + method2.getName());
return false;
}
if (method1.getModifiers() != method2.getModifiers()) {
System.out.println("Modifiers do not match for methods " + method1.getName() + " and " + method2.getName());
return false;
}
return true;
}

View File

@ -35,10 +35,10 @@ public class TestAll {
@Test
public void testFakultaet() {
String classPath = "src/test/resources/basicClasses/Fakultaet.class";
Program ast = FakultaetAST.getProgram();
Program ast = FakultaetASTTyped.getProgram();
String className = "Fakultaet";
String javacode = "src/test/resources/basicClasses/Fakultaet.java";
byteCodeTester.testByteCodeFromAst(classPath, ast ,className);
byteCodeTester.testByteCodeFromTypedAst(classPath, ast ,className);
//byteCodeTester.testClassFileFromScratch(classPath, javacode, className);
}
@ -55,10 +55,10 @@ public class TestAll {
@Test
public void testCharArgument() {
String classPath = "src/test/resources/SimpleTests/CharArgument.class";
Program ast = CharArgumentAST.getProgram();
Program ast = CharArgumentASTTyped.getProgram();
String className = "CharArgument";
String javacode = "src/test/resources/SimpleTests/CharArgument.java";
byteCodeTester.testByteCodeFromAst(classPath, ast ,className);
byteCodeTester.testByteCodeFromTypedAst(classPath, ast ,className);
byteCodeTester.testClassFileFromScratch(classPath, javacode, className);
}
@ -166,8 +166,6 @@ public class TestAll {
}
@Test
public void testTwoClasses() {
String jarPath = "src/test/resources/basicClasses/TwoClasses.jar";
@ -187,6 +185,7 @@ public class TestAll {
byteCodeTester.compareJarFilesFromScratch(javacode, jarPath, classNames);
}
/*
@Test
public void testDijkstra() {
String jarPath = "src/test/resources/Integration/Dijkstra.jar";
@ -195,6 +194,7 @@ public class TestAll {
String javacode = "src/test/resources/Integration/Dijkstra.java";
byteCodeTester.compareJarFilesFromScratch(javacode, jarPath, classNames);
}
*/

View File

@ -109,7 +109,22 @@ public class TestAll {
testTypeCheck(fakultaet, correctAST, expectedResult);
}
@Test
public void testCharArgument(){
Program fakultaet = CharArgumentAST.getProgram();
Program correctAST = CharArgumentASTTyped.getProgram();
boolean expectedResult = true;
testTypeCheckWOM(fakultaet, correctAST, expectedResult);
}
public void testTypeCheckWOM(Program abstractSyntaxTree, Program correctAST, boolean expectedResult) {
try {
TypeChecker.assertTypeCheckResultNoMain(abstractSyntaxTree , correctAST,expectedResult);
} catch (Exception e) {
fail();
}
}
public void testTypeCheckWM(Program abstractSyntaxTree, Program correctAST, boolean expectedResult){
abstractSyntaxTree.classes.add(ClassWithMainASTTyped.getRefType());
correctAST.classes.add(ClassWithMainASTTyped.getRefType());

View File

@ -8,7 +8,7 @@ import static org.junit.Assert.assertEquals;
public class TypeChecker {
// Method to test if the TypeCheck returns the expected Result
static public void assertTypeCheckResultNoMain(boolean testForMain, Program programmToBeTested, Program correctAST, boolean expectedResult) {
static public void assertTypeCheckResultNoMain(Program programmToBeTested, Program correctAST, boolean expectedResult) {
assertTypeCheckResult(false, programmToBeTested, correctAST, expectedResult);
}
@ -28,9 +28,9 @@ public class TypeChecker {
} catch (Exception e) {
actualResult = false;
}
assertEquals(expectedResult, actualResult);
assertEquals(programmToBeTested.typeContext, correctAST.typeContext);
assertEquals(programmToBeTested.methodContext, correctAST.methodContext);
assertEquals(expectedResult, actualResult);
if(expectedResult){
assertEquals(programmToBeTested, correctAST);
}

View File

@ -28,12 +28,12 @@ Semicolon: ";"
Int: "int"
Identifier: "i"
Assign: "="
IntValue: "0"
IntValue: "1"
Semicolon: ";"
While: "while"
OpenRoundBracket: "("
Identifier: "i"
ComparisonOperator: "<"
ComparisonOperator: "<="
Identifier: "number"
ClosedRoundBracket: ")"
OpenCurlyBracket: "{"
@ -43,6 +43,12 @@ Identifier: "factorial"
DotOperator: "*"
Identifier: "i"
Semicolon: ";"
Identifier: "i"
Assign: "="
Identifier: "i"
LineOperator: "+"
IntValue: "1"
Semicolon: ";"
ClosedCurlyBracket: "}"
Return: "return"
Identifier: "factorial"