diff --git a/src/main/java/abstractSyntaxTree/Datatype/BoolDatatype.java b/src/main/java/abstractSyntaxTree/Datatype/BoolDatatype.java index 6b8ccf0..f09e9dc 100644 --- a/src/main/java/abstractSyntaxTree/Datatype/BoolDatatype.java +++ b/src/main/java/abstractSyntaxTree/Datatype/BoolDatatype.java @@ -2,11 +2,21 @@ package abstractSyntaxTree.Datatype; import TypeCheck.AbstractType; import TypeCheck.TypeCheckResult; +import abstractSyntaxTree.Class.RefType; import org.objectweb.asm.*; +import java.util.Objects; + public class BoolDatatype extends AbstractType implements IDatatype{ boolean value; @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BoolDatatype boolDatatype = (BoolDatatype) o; + return (Objects.equals(value, boolDatatype.value)); + } + @Override public TypeCheckResult typeCheck() throws Exception { TypeCheckResult result = new TypeCheckResult(); @@ -24,4 +34,6 @@ public class BoolDatatype extends AbstractType implements IDatatype{ mv.visitInsn(Opcodes.ICONST_0); // 0 for false } } + + } diff --git a/src/main/java/abstractSyntaxTree/Datatype/CharDatatype.java b/src/main/java/abstractSyntaxTree/Datatype/CharDatatype.java index 1346f0d..025abc4 100644 --- a/src/main/java/abstractSyntaxTree/Datatype/CharDatatype.java +++ b/src/main/java/abstractSyntaxTree/Datatype/CharDatatype.java @@ -4,8 +4,11 @@ import TypeCheck.AbstractType; import TypeCheck.TypeCheckResult; import org.objectweb.asm.MethodVisitor; +import java.util.Objects; + public class CharDatatype extends AbstractType implements IDatatype{ char value; + @Override public TypeCheckResult typeCheck() throws Exception { TypeCheckResult result = new TypeCheckResult(); @@ -24,4 +27,11 @@ public class CharDatatype extends AbstractType implements IDatatype{ mv.visitLdcInsn((int)value); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CharDatatype charDatatype = (CharDatatype) o; + return (Objects.equals(value, charDatatype.value)); + } } diff --git a/src/main/java/abstractSyntaxTree/Datatype/IntDatatype.java b/src/main/java/abstractSyntaxTree/Datatype/IntDatatype.java index 4733931..16e9256 100644 --- a/src/main/java/abstractSyntaxTree/Datatype/IntDatatype.java +++ b/src/main/java/abstractSyntaxTree/Datatype/IntDatatype.java @@ -5,6 +5,8 @@ import TypeCheck.TypeCheckResult; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; +import java.util.Objects; + public class IntDatatype extends AbstractType implements IDatatype{ int value; @Override @@ -31,4 +33,12 @@ public class IntDatatype extends AbstractType implements IDatatype{ else mv.visitLdcInsn(value); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + IntDatatype intDatatype = (IntDatatype) o; + return (Objects.equals(value, intDatatype.value)); + } } diff --git a/src/main/java/abstractSyntaxTree/Expression/BinaryExpression.java b/src/main/java/abstractSyntaxTree/Expression/BinaryExpression.java index c4b92a7..6352c80 100644 --- a/src/main/java/abstractSyntaxTree/Expression/BinaryExpression.java +++ b/src/main/java/abstractSyntaxTree/Expression/BinaryExpression.java @@ -3,6 +3,7 @@ package abstractSyntaxTree.Expression; import TypeCheck.TypeCheckResult; import TypeCheck.TypeCheckHelper; import TypeCheck.AbstractType; +import abstractSyntaxTree.Datatype.IntDatatype; import abstractSyntaxTree.Parameter.ParameterList; import org.objectweb.asm.*; @@ -175,4 +176,15 @@ public class BinaryExpression extends AbstractType implements IExpression{ mv.visitLabel(expressionEnd); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BinaryExpression binaryExpression = (BinaryExpression) o; + return (Objects.equals(operator, binaryExpression.operator) + && Objects.equals(left, binaryExpression.left) + && Objects.equals(right, binaryExpression.right) + ); + } } \ No newline at end of file diff --git a/src/main/java/abstractSyntaxTree/Expression/InstVarExpression.java b/src/main/java/abstractSyntaxTree/Expression/InstVarExpression.java index 25e8fe2..b95d99e 100644 --- a/src/main/java/abstractSyntaxTree/Expression/InstVarExpression.java +++ b/src/main/java/abstractSyntaxTree/Expression/InstVarExpression.java @@ -9,6 +9,7 @@ import org.objectweb.asm.Opcodes; import java.util.HashMap; import java.util.LinkedHashMap; +import java.util.Objects; public class InstVarExpression implements IExpression{ @@ -63,4 +64,14 @@ public class InstVarExpression implements IExpression{ // Load the variable onto the stack mv.visitFieldInsn(Opcodes.GETFIELD, classRef.name, fieldName, fieldDescriptor); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + InstVarExpression instVarExpression = (InstVarExpression) o; + return (Objects.equals(classRef, instVarExpression.classRef) + && Objects.equals(fieldName, instVarExpression.fieldName) + ); + } } diff --git a/src/main/java/abstractSyntaxTree/Expression/IntConstantExpression.java b/src/main/java/abstractSyntaxTree/Expression/IntConstantExpression.java index 08f04bc..b1a1d88 100644 --- a/src/main/java/abstractSyntaxTree/Expression/IntConstantExpression.java +++ b/src/main/java/abstractSyntaxTree/Expression/IntConstantExpression.java @@ -8,6 +8,8 @@ import org.objectweb.asm.MethodVisitor; import java.util.HashMap; import java.util.LinkedHashMap; +import java.util.Objects; + public class IntConstantExpression extends AbstractType implements IExpression{ public int value; @@ -24,4 +26,13 @@ public class IntConstantExpression extends AbstractType implements IExpression{ public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception { } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + IntConstantExpression intConstantExpression = (IntConstantExpression) o; + return (Objects.equals(value, intConstantExpression.value) + ); + } } diff --git a/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java b/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java index 573e917..2e3ceb9 100644 --- a/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java +++ b/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java @@ -10,6 +10,7 @@ import abstractSyntaxTree.Parameter.ParameterList; import org.objectweb.asm.MethodVisitor; import java.util.HashMap; +import java.util.Objects; public class LocalVarIdentifier implements IExpression{ @@ -71,4 +72,13 @@ public class LocalVarIdentifier implements IExpression{ break; } } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + LocalVarIdentifier localVarIdentifier = (LocalVarIdentifier) o; + return (Objects.equals(identifier, localVarIdentifier.identifier) + ); + } } diff --git a/src/main/java/abstractSyntaxTree/Expression/UnaryExpression.java b/src/main/java/abstractSyntaxTree/Expression/UnaryExpression.java index 0b8d5da..6ff3aee 100644 --- a/src/main/java/abstractSyntaxTree/Expression/UnaryExpression.java +++ b/src/main/java/abstractSyntaxTree/Expression/UnaryExpression.java @@ -70,4 +70,14 @@ public class UnaryExpression extends AbstractType implements IExpression{ } } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + UnaryExpression unaryExpression = (UnaryExpression) o; + return (Objects.equals(operator, unaryExpression.operator) + && Objects.equals(operand, unaryExpression.operand) + ); + } } diff --git a/src/main/java/abstractSyntaxTree/Parameter/Parameter.java b/src/main/java/abstractSyntaxTree/Parameter/Parameter.java index 9981905..3976957 100644 --- a/src/main/java/abstractSyntaxTree/Parameter/Parameter.java +++ b/src/main/java/abstractSyntaxTree/Parameter/Parameter.java @@ -1,7 +1,10 @@ package abstractSyntaxTree.Parameter; +import abstractSyntaxTree.Expression.UnaryExpression; import abstractSyntaxTree.Node; +import java.util.Objects; + public class Parameter implements Node { public String type; public String identifier; @@ -10,4 +13,14 @@ public class Parameter implements Node { this.type = type; this.identifier = identifier; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Parameter parameter = (Parameter) o; + return (Objects.equals(type, parameter.type) + && Objects.equals(identifier, parameter.identifier) + ); + } } diff --git a/src/main/java/abstractSyntaxTree/Parameter/ParameterList.java b/src/main/java/abstractSyntaxTree/Parameter/ParameterList.java index b3b634d..e8dee8b 100644 --- a/src/main/java/abstractSyntaxTree/Parameter/ParameterList.java +++ b/src/main/java/abstractSyntaxTree/Parameter/ParameterList.java @@ -3,6 +3,7 @@ package abstractSyntaxTree.Parameter; import abstractSyntaxTree.Node; import java.util.List; +import java.util.Objects; public class ParameterList implements Node { public List parameterList; @@ -10,4 +11,13 @@ public class ParameterList implements Node { public ParameterList(List parameterList) { this.parameterList = parameterList; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ParameterList parameterListObj = (ParameterList) o; + return (Objects.equals(parameterList, parameterListObj.parameterList) + ); + } } diff --git a/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java b/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java index 276f32e..b573fbc 100644 --- a/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java @@ -3,12 +3,14 @@ package abstractSyntaxTree.Statement; import TypeCheck.TypeCheckResult; import TypeCheck.AbstractType; import abstractSyntaxTree.Class.FieldDecl; +import abstractSyntaxTree.Parameter.Parameter; import abstractSyntaxTree.Parameter.ParameterList; import org.objectweb.asm.*; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; +import java.util.Objects; public class BlockStatement extends AbstractType implements IStatement { @@ -86,4 +88,15 @@ public class BlockStatement extends AbstractType implements IStatement { statement.codeGen(mv, blockLocalVars, typeContext); } } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BlockStatement blockStatement = (BlockStatement) o; + return (Objects.equals(localVars, blockStatement.localVars) + && Objects.equals(returnType, blockStatement.returnType) + && Objects.equals(statements, blockStatement.statements) + ); + } } \ No newline at end of file diff --git a/src/main/java/abstractSyntaxTree/Statement/EmptyStatement.java b/src/main/java/abstractSyntaxTree/Statement/EmptyStatement.java index 481c27c..b5f1790 100644 --- a/src/main/java/abstractSyntaxTree/Statement/EmptyStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/EmptyStatement.java @@ -8,6 +8,7 @@ import org.objectweb.asm.MethodVisitor; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; +import java.util.Objects; public class EmptyStatement extends AbstractType implements IStatement{ @@ -22,4 +23,9 @@ public class EmptyStatement extends AbstractType implements IStatement{ public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception { //An empty statement does not generate any code } + + @Override + public boolean equals(Object o) { + return true; + } } diff --git a/src/main/java/abstractSyntaxTree/Statement/IfElseStatement.java b/src/main/java/abstractSyntaxTree/Statement/IfElseStatement.java index 8d4d726..2f66e96 100644 --- a/src/main/java/abstractSyntaxTree/Statement/IfElseStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/IfElseStatement.java @@ -70,4 +70,15 @@ public class IfElseStatement extends AbstractType implements IStatement{ mv.visitLabel(statementEnd); //End of the if-else statement } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + IfElseStatement ifElseStatement = (IfElseStatement) o; + return (Objects.equals(condition, ifElseStatement.condition) + && Objects.equals(ifStatement, ifElseStatement.ifStatement) + && Objects.equals(elseStatement, ifElseStatement.elseStatement) + ); + } } diff --git a/src/main/java/abstractSyntaxTree/Statement/IfStatement.java b/src/main/java/abstractSyntaxTree/Statement/IfStatement.java index 5a9c4b1..2e233a7 100644 --- a/src/main/java/abstractSyntaxTree/Statement/IfStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/IfStatement.java @@ -9,6 +9,7 @@ import org.objectweb.asm.*; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; +import java.util.Objects; public class IfStatement extends AbstractType implements IStatement{ IExpression condition; @@ -50,6 +51,16 @@ public class IfStatement extends AbstractType implements IStatement{ mv.visitLabel(conditionFalse); // If the condition is false, the Statements in the ifBlock will not be executed } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + IfStatement ifStatementObj = (IfStatement) o; + return (Objects.equals(condition, ifStatementObj.condition) + && Objects.equals(ifStatement, ifStatementObj.ifStatement) + ); + } } diff --git a/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java b/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java index 71df469..325e04a 100644 --- a/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java +++ b/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java @@ -49,4 +49,14 @@ public class LocalVarDecl implements IStatement{ mv.visitVarInsn(Opcodes.ASTORE, index); } } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + LocalVarDecl localVarDecl = (LocalVarDecl) o; + return (Objects.equals(type, localVarDecl.type) + && Objects.equals(identifier, localVarDecl.identifier) + ); + } } diff --git a/src/main/java/abstractSyntaxTree/Statement/ReturnStatement.java b/src/main/java/abstractSyntaxTree/Statement/ReturnStatement.java index d0b44ee..9845fde 100644 --- a/src/main/java/abstractSyntaxTree/Statement/ReturnStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/ReturnStatement.java @@ -9,6 +9,7 @@ import org.objectweb.asm.*; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; +import java.util.Objects; public class ReturnStatement extends AbstractType implements IStatement{ IExpression expression; @@ -53,4 +54,13 @@ public class ReturnStatement extends AbstractType implements IStatement{ mv.visitInsn(Opcodes.RETURN); } } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ReturnStatement returnStatement = (ReturnStatement) o; + return (Objects.equals(expression, returnStatement.expression) + ); + } } diff --git a/src/main/java/abstractSyntaxTree/Statement/WhileStatement.java b/src/main/java/abstractSyntaxTree/Statement/WhileStatement.java index 3246648..a753df6 100644 --- a/src/main/java/abstractSyntaxTree/Statement/WhileStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/WhileStatement.java @@ -9,6 +9,7 @@ import org.objectweb.asm.*; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; +import java.util.Objects; public class WhileStatement extends AbstractType implements IStatement { IExpression condition; @@ -59,4 +60,14 @@ public class WhileStatement extends AbstractType implements IStatement { mv.visitLabel(conditionFalse); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + WhileStatement whileStatement = (WhileStatement) o; + return (Objects.equals(condition, whileStatement.condition) + && Objects.equals(statement, whileStatement.statement) + ); + } } \ No newline at end of file diff --git a/src/main/java/abstractSyntaxTree/StatementExpression/AssignStatementExpression.java b/src/main/java/abstractSyntaxTree/StatementExpression/AssignStatementExpression.java index 1259900..df815fd 100644 --- a/src/main/java/abstractSyntaxTree/StatementExpression/AssignStatementExpression.java +++ b/src/main/java/abstractSyntaxTree/StatementExpression/AssignStatementExpression.java @@ -8,6 +8,7 @@ import abstractSyntaxTree.Expression.InstVarExpression; import abstractSyntaxTree.Expression.LocalVarIdentifier; import abstractSyntaxTree.Parameter.ParameterList; import abstractSyntaxTree.Statement.IStatement; +import abstractSyntaxTree.Statement.WhileStatement; import org.objectweb.asm.*; import java.util.HashMap; @@ -112,4 +113,15 @@ public class AssignStatementExpression extends AbstractType implements IExpressi } */ } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + AssignStatementExpression assignStatementExpression = (AssignStatementExpression) o; + return (Objects.equals(operator, assignStatementExpression.operator) + && Objects.equals(left, assignStatementExpression.left) + && Objects.equals(right, assignStatementExpression.right) + ); + } } \ No newline at end of file diff --git a/src/main/java/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java b/src/main/java/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java index cf526f9..36c9bc3 100644 --- a/src/main/java/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java +++ b/src/main/java/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java @@ -14,6 +14,7 @@ import org.objectweb.asm.Opcodes; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; +import java.util.Objects; public class MethodCallStatementExpression extends AbstractType implements IExpression, IStatement { String methodName; @@ -56,8 +57,9 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr @Override public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception { //Generate Bytecode for the receiver - if(classThatHasTheMethodIfNotThis != null){ + if (classThatHasTheMethodIfNotThis != null) { //TODO: classThatHasTheMethodIfNotThis must be an object --> instance of the class not the class itself + // Need to call codeGen so it pushes the instance onto the stack, which will be popped of //classThatHasTheMethodIfNotThis.codeGen(); String descriptor; @@ -65,29 +67,39 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr for (MethodDecl methodDecl : methodDecls) { if (methodDecl.name.equals(methodName)) { //Get the method descriptor - //descriptor = methodDecl.getMethodDescriptor(methodContext); + descriptor = methodDecl.getMethodDescriptor(methodContext); } } - //mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classThatHasTheMethodIfNotThis.name, methodName, descriptor, false); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classThatHasTheMethodIfNotThis.name, methodName, descriptor, false); } else { // Load this onto the stack mv.visitVarInsn(Opcodes.ALOAD, 0); - } - for (IExpression argument : arguments) { - argument.codeGen(mv, localVars, typeContext); - } - - // Get the method descriptor - String descriptor; - List methodDecls = thisClass.methodDecls; - for (MethodDecl methodDecl : methodDecls) { - if (methodDecl.name.equals(methodName)) { - //Get the method descriptor - //descriptor = methodDecl.getMethodDescriptor(methodContext); + for (IExpression argument : arguments) { + argument.codeGen(mv, localVars, typeContext); } + + // Get the method descriptor + String descriptor; + List methodDecls = thisClass.methodDecls; + for (MethodDecl methodDecl : methodDecls) { + if (methodDecl.name.equals(methodName)) { + //Get the method descriptor + descriptor = methodDecl.getMethodDescriptor(methodContext); + } + } + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, thisClass.name, methodName, descriptor, false); } - //mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, thisClass.name, methodName, descriptor, false); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MethodCallStatementExpression methodCallStatementExpression = (MethodCallStatementExpression) o; + return (Objects.equals(methodName, methodCallStatementExpression.methodName) + && Objects.equals(arguments, methodCallStatementExpression.arguments) + ); } } diff --git a/src/main/java/abstractSyntaxTree/StatementExpression/NewStatementExpression.java b/src/main/java/abstractSyntaxTree/StatementExpression/NewStatementExpression.java index 7937135..6342503 100644 --- a/src/main/java/abstractSyntaxTree/StatementExpression/NewStatementExpression.java +++ b/src/main/java/abstractSyntaxTree/StatementExpression/NewStatementExpression.java @@ -6,6 +6,7 @@ import abstractSyntaxTree.Expression.IExpression; import abstractSyntaxTree.Parameter.ParameterList; import abstractSyntaxTree.Statement.IStatement; import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; import java.util.HashMap; import java.util.LinkedHashMap; @@ -13,6 +14,11 @@ import java.util.List; public class NewStatementExpression extends AbstractType implements IExpression, IStatement { + private String className; + + public NewStatementExpression(String className) { + this.className = className; + } @Override public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { @@ -21,8 +27,12 @@ public class NewStatementExpression extends AbstractType implements IExpression, @Override public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception { + //Create new instance of the class + mv.visitTypeInsn(Opcodes.NEW, className); + //Duplicate the reference, so I can use it after the INVOKE consumes one + mv.visitInsn(Opcodes.DUP); + //Call the constructor + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, className, "", "()V", false); } - - } diff --git a/src/test/java/ByteCode/ByteCodeLoader.java b/src/test/java/ByteCode/ByteCodeLoader.java deleted file mode 100644 index 0f16356..0000000 --- a/src/test/java/ByteCode/ByteCodeLoader.java +++ /dev/null @@ -1,16 +0,0 @@ -package ByteCode; - -import java.security.SecureClassLoader; -public class ByteCodeLoader extends SecureClassLoader { - private final byte[] bytecode; - - public ByteCodeLoader(byte[] bytecode) { - this.bytecode = bytecode; - } - - @Override - protected Class findClass(String name) throws ClassNotFoundException { - return defineClass(name, bytecode, 0, bytecode.length); - } -} - diff --git a/src/test/java/ByteCode/CompareByteCodeBehaviour.java b/src/test/java/ByteCode/CompareByteCodeBehaviour.java new file mode 100644 index 0000000..05fe0e3 --- /dev/null +++ b/src/test/java/ByteCode/CompareByteCodeBehaviour.java @@ -0,0 +1,110 @@ +package ByteCode; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +import static ByteCode.CompareByteCodeSyntax.compareMethod; + +public class CompareByteCodeBehaviour { + ArrayList methodArray1; + ArrayList methodArray2; + + public CompareByteCodeBehaviour(){ + methodArray1 = new ArrayList(); + methodArray2 = new ArrayList(); + } + + private void clearMethods(){ + methodArray1.clear(); + methodArray2.clear(); + } + + public boolean functionAlreadyAdded(Method method1, Method method2){ + int lengthOfArray = methodArray1.size(); + for (int i = 0; i < lengthOfArray; i++) { + if (method1.getName().equals(this.methodArray1.get(i).getName()) || + method2.getName().equals(this.methodArray1.get(i).getName())) { + return true; + } + } + return false; + } + + private void sortMethods(Class class1, Class class2) { + this.clearMethods(); + Method[] methods1 = class1.getDeclaredMethods(); + Method[] methods2 = class2.getDeclaredMethods(); + + for (Method method1 : methods1) { + for (Method method2 : methods2) { + if (compareMethod(method1, method2)) { + if (!functionAlreadyAdded(method1, method2)) { + this.methodArray1.add(method1); + this.methodArray2.add(method2); + } + break; + } + } + } + } + + public void compareMethodBehaviour(Class class1, Class class2){ + try { + this.sortMethods(class1, class2); + // Create instances + Constructor constructor1 = class1.getDeclaredConstructor(); + Constructor constructor2 = class2.getDeclaredConstructor(); + Object obj1 = constructor1.newInstance(); + Object obj2 = constructor2.newInstance(); + + // Get methods + Method[] methods1 = new Method[this.methodArray1.size()]; + methods1 = this.methodArray1.toArray(methods1); + Method[] methods2 = new Method[this.methodArray2.size()]; + methods2 = this.methodArray2.toArray(methods2); + + + // Compare methods + for (int i = 0; i < methods1.length; i++) { + Method method1 = methods1[i]; + Method method2 = methods2[i]; + + + // Test with some sample inputs + Object[] testInputs = getTestInputs(method1.getParameterTypes()); + + Object result1 = method1.invoke(obj1, testInputs); + Object result2 = method2.invoke(obj2, testInputs); + + /* + if (!result1.equals(result2)) { + System.out.println("Methods " + method1.getName() + " do not produce the same result"); + } else { + System.out.println("Methods " + method1.getName() + " produce the same result"); + } + */ + } + + } catch (InstantiationException | IllegalAccessException | + NoSuchMethodException | InvocationTargetException e) { + e.printStackTrace(); + } + } + + private static Object[] getTestInputs(Class[] parameterTypes) { + // Create test inputs based on parameter types + Object[] inputs = new Object[parameterTypes.length]; + for (int i = 0; i < parameterTypes.length; i++) { + if (parameterTypes[i] == int.class) { + inputs[i] = 1; // example value + } else if (parameterTypes[i] == String.class) { + inputs[i] = "test"; // example value + } + // Add more cases as needed for different parameter types + } + return inputs; + } + +} diff --git a/src/test/java/ByteCode/CompareByteCodeSyntax.java b/src/test/java/ByteCode/CompareByteCodeSyntax.java new file mode 100644 index 0000000..ebe6a9c --- /dev/null +++ b/src/test/java/ByteCode/CompareByteCodeSyntax.java @@ -0,0 +1,122 @@ +package ByteCode; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.Arrays; +public class CompareByteCodeSyntax { + + public static boolean haveSameBehavior(Class class1, Class class2) { + if (!compareClassSignatures(class1, class2)) { + return false; + } + if (!compareMethods(class1, class2)) { + return false; + } + if (!compareFields(class1, class2)) { + return false; + } + if (!compareAnnotations(class1.getAnnotations(), class2.getAnnotations())) { + return false; + } + return true; + } + + public static boolean compareClassSignatures(Class class1, Class class2) { + if (!Arrays.equals(class1.getInterfaces(), class2.getInterfaces())) { + return false; + } + if (class1.getSuperclass() != class2.getSuperclass()) { + return false; + } + return true; + } + + public static boolean compareMethods(Class class1, Class class2) { + Method[] methods1 = class1.getDeclaredMethods(); + Method[] methods2 = class2.getDeclaredMethods(); + if (methods1.length != methods2.length) { + return false; + } + for (Method method1 : methods1) { + boolean found = false; + for (Method method2 : methods2) { + if (compareMethod(method1, method2)) { + found = true; + break; + } + } + if (!found) { + return false; + } + } + return true; + } + + public static boolean compareMethod(Method method1, Method method2) { + if (!method1.getReturnType().equals(method2.getReturnType())) { + return false; + } + if (!Arrays.equals(method1.getParameterTypes(), method2.getParameterTypes())) { + return false; + } + if (!Arrays.equals(method1.getExceptionTypes(), method2.getExceptionTypes())) { + return false; + } + if (!compareAnnotations(method1.getAnnotations(), method2.getAnnotations())) { + return false; + } + return true; + } + + public static boolean compareFields(Class class1, Class class2) { + Field[] fields1 = class1.getDeclaredFields(); + Field[] fields2 = class2.getDeclaredFields(); + if (fields1.length != fields2.length) { + return false; + } + for (Field field1 : fields1) { + boolean found = false; + for (Field field2 : fields2) { + if (compareField(field1, field2)) { + found = true; + break; + } + } + if (!found) { + return false; + } + } + return true; + } + + public static boolean compareField(Field field1, Field field2) { + if (!field1.getType().equals(field2.getType())) { + return false; + } + if (!compareAnnotations(field1.getAnnotations(), field2.getAnnotations())) { + return false; + } + return true; + } + + public static boolean compareAnnotations(Annotation[] annotations1, Annotation[] annotations2) { + if (annotations1.length != annotations2.length) { + return false; + } + for (Annotation annotation1 : annotations1) { + boolean found = false; + for (Annotation annotation2 : annotations2) { + if (annotation1.annotationType().equals(annotation2.annotationType())) { + found = true; + break; + } + } + if (!found) { + return false; + } + } + return true; + } +} + diff --git a/src/test/java/ByteCode/TestAll.java b/src/test/java/ByteCode/TestAll.java new file mode 100644 index 0000000..677f4f7 --- /dev/null +++ b/src/test/java/ByteCode/TestAll.java @@ -0,0 +1,4 @@ +package ByteCode; + +public class TestAll { +} diff --git a/src/test/java/Typecheck/TestAll.java b/src/test/java/Typecheck/TestAll.java new file mode 100644 index 0000000..9521ca9 --- /dev/null +++ b/src/test/java/Typecheck/TestAll.java @@ -0,0 +1,5 @@ +package Typecheck; + +public class TestAll { + +} diff --git a/src/test/java/Typecheck/TypeChecker.java b/src/test/java/Typecheck/TypeChecker.java new file mode 100644 index 0000000..b4619b9 --- /dev/null +++ b/src/test/java/Typecheck/TypeChecker.java @@ -0,0 +1,30 @@ +package Typecheck; + +import TypeCheck.TypeCheckResult; +import abstractSyntaxTree.Program; +import gen.DecafLexer; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.Token; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class TypeChecker { + // Method to test if the TypeCheck returns the expected Result + public void assertTypeCheckResult(Program programmToBeTested, boolean expectedResult) throws Exception { + boolean actualResult; + try { + TypeCheckResult typeCheckResult = programmToBeTested.typeCheck(); + actualResult = true; + } catch (Exception e) { + actualResult = false; + } + + assertEquals(expectedResult, actualResult); + } +}