Trying to change to new AST
Some checks are pending
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run

This commit is contained in:
Bruder John 2024-06-20 11:43:58 +02:00
parent 978b5a2b4a
commit fd8c3b066a
17 changed files with 171 additions and 495 deletions

View File

@ -1,6 +1,5 @@
import oldAst.ASTNode;
import ast.*;
import org.antlr.v4.runtime.*;
import oldAst.ProgramNode;
import bytecode.ByteCodeGenerator;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;

View File

@ -9,16 +9,15 @@ import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
import visitor.Visitable;
import java.util.ArrayList;
import java.util.List;
public class MethodNode implements MemberNode {
public class MethodNode implements MemberNode, Visitable {
AccessModifierNode accesModifier;
TypeNode type;
Boolean voidType;
String identifier;
List<ParameterNode> parameters;
BlockNode block;
public BlockNode block;
public MethodNode() {}
@ -55,6 +54,8 @@ public class MethodNode implements MemberNode {
return isSame;
}
*/
@Override
public TypeCheckResult accept(SemanticVisitor visitor) {
return visitor.analyze(this);
@ -64,6 +65,6 @@ public class MethodNode implements MemberNode {
public void accept(MethodVisitor methodVisitor) {
methodVisitor.visit(this);
}
*/
}

View File

@ -2,10 +2,6 @@ package ast.statement;
import ast.ASTNode;
import ast.expression.ExpressionNode;
import ast.type.TypeNode;
import java.util.ArrayList;
import java.util.List;
public class ReturnStatementNode implements ASTNode {
public ExpressionNode expression;

View File

@ -4,11 +4,10 @@ import ast.ClassNode;
import ast.member.FieldNode;
import ast.member.MemberNode;
import ast.member.MethodNode;
import ast.type.BaseTypeNode;
import ast.type.TypeNode;
import bytecode.visitor.ClassVisitor;
import java.io.File;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import java.io.FileOutputStream;
import java.io.IOException;
@ -25,8 +24,8 @@ public class ClassCodeGen implements ClassVisitor {
@Override
public void visit(ClassNode classNode) {
classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
classWriter.visit(Opcodes.V1_5, mapper.mapAccessTypeToOpcode(classNode.accessType), classNode.identifier, null,
"java/lang/Object", null);
// classWriter.visit(Opcodes.V1_5, mapper.mapAccessTypeToOpcode(classNode.accessType), classNode.identifier, null,
// "java/lang/Object", null);
for (MemberNode memberNode : classNode.members) {
if (memberNode instanceof FieldNode) {
@ -45,8 +44,8 @@ public class ClassCodeGen implements ClassVisitor {
@Override
public void visit(FieldNode fieldNode) {
if(fieldNode.type instanceof BaseTypeNode baseTypeNode){
classWriter.visitField(mapper.mapAccessTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier, mapper.getTypeChar(baseTypeNode.enumType), null, null );
if(fieldNode.type instanceof TypeNode baseTypeNode){
// classWriter.visitField(mapper.mapAccessTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier, mapper.getTypeChar(baseTypeNode.enumType), null, null );
}
classWriter.visitEnd();
}

View File

@ -1,44 +1,41 @@
package bytecode;
import ast.parameter.ParameterNode;
import ast.type.*;
import org.objectweb.asm.Opcodes;
import ast.type.BaseTypeNode;
public class Mapper {
public int mapAccessTypeToOpcode(AccessTypeNode type) {
switch (type.enumAccessTypeNode) {
case EnumAccessTypeNode.PUBLIC:
return Opcodes.ACC_PUBLIC;
case EnumAccessTypeNode.PRIVATE:
return Opcodes.ACC_PRIVATE;
}
return 0;
}
// public int mapAccessTypeToOpcode(AccessModifierNode type) {
// switch (type.enumAccessTypeNode) {
// case EnumAccessTypeNode.PUBLIC:
// return Opcodes.ACC_PUBLIC;
// case EnumAccessTypeNode.PRIVATE:
// return Opcodes.ACC_PRIVATE;
// }
// return 0;
// }
public String generateMethodDescriptor(BaseTypeNode baseTypeNode, ParameterListNode parameterListNode) {
String descriptor = "(";
for(ParameterNode parameterNode : parameterListNode.parameters) {
descriptor += getTypeChar(EnumTypeNode.INT);
}
descriptor += ")";
descriptor += getTypeChar(baseTypeNode.enumType);
return descriptor;
}
// public String generateMethodDescriptor(BaseTypeNode baseTypeNode, ParameterListNode parameterListNode) {
// String descriptor = "(";
// for(ParameterNode parameterNode : parameterListNode.parameters) {
// descriptor += getTypeChar(EnumTypeNode.INT);
// }
// descriptor += ")";
// descriptor += getTypeChar(baseTypeNode.enumType);
// return descriptor;
// }
public String getTypeChar(EnumTypeNode enumTypeNode) {
String typeChar = "";
switch (enumTypeNode) {
case EnumTypeNode.INT:
typeChar = "I";
break;
case EnumTypeNode.CHAR:
typeChar = "C";
break;
case EnumTypeNode.BOOLEAN:
typeChar = "Z";
break;
}
return typeChar;
}
// public String getTypeChar(TypeEnum enumTypeNode) {
// String typeChar = "";
// switch (enumTypeNode) {
// case TypeEnum.INT:
// typeChar = "I";
// break;
// case TypeEnum.CHAR:
// typeChar = "C";
// break;
// case TypeEnum.BOOLEAN:
// typeChar = "Z";
// break;
// }
// return typeChar;
// }
}

View File

@ -2,12 +2,8 @@ package bytecode;
import ast.member.ConstructorNode;
import ast.member.MethodNode;
import ast.parameter.ParameterNode;
import ast.type.BaseTypeNode;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.ArrayList;
import java.util.List;
@ -31,12 +27,12 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
@Override
public void visit(ConstructorNode constructorNode) {
methodVisitor =
classWriter.visitMethod(mapper.mapAccessTypeToOpcode(constructorNode.visibility),
"<init>",
"()V",
null,
null);
// methodVisitor =
// classWriter.visitMethod(mapper.mapAccessTypeToOpcode(constructorNode.visibility),
// "<init>",
// "()V",
// null,
// null);
methodVisitor.visitCode();
methodVisitor.visitVarInsn(ALOAD, 0);
methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
@ -47,52 +43,52 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
@Override
public void visit(MethodNode methodNode) {
if (methodNode.type instanceof BaseTypeNode baseTypeNode) {
methodVisitor = classWriter.visitMethod(mapper.mapAccessTypeToOpcode(methodNode.visibility),
methodNode.identifier,
mapper.generateMethodDescriptor(baseTypeNode, methodNode.parameters),
null,
null);
// if (methodNode.type instanceof BaseTypeNode baseTypeNode) {
// methodVisitor = classWriter.visitMethod(mapper.mapAccessTypeToOpcode(methodNode.visibility),
// methodNode.identifier,
// mapper.generateMethodDescriptor(baseTypeNode, methodNode.parameters),
// null,
// null);
methodVisitor.visitCode();
localVaribales.add("this");
for (ParameterNode parameterNode : methodNode.parameters.parameters) {
localVaribales.add(parameterNode.identifier);
}
// for (ParameterNode parameterNode : methodNode.parameters.parameters) {
// localVaribales.add(parameterNode.identifier);
// }
//test();
methodVisitor.visitMaxs(1, localVaribales.size());
methodVisitor.visitEnd();
}
// }
}
public void test() {
Label start = new Label();
Label loop = new Label();
Label end = new Label();
methodVisitor.visitLabel(start);
//methodVisitor.visitVarInsn(Opcodes.ICONST_M1, 99);
// public void test() {
// Label start = new Label();
// Label loop = new Label();
// Label end = new Label();
// methodVisitor.visitLabel(start);
// //methodVisitor.visitVarInsn(Opcodes.ICONST_M1, 99);
// //methodVisitor.visitInsn(Opcodes.ICONST_5);
// methodVisitor.visitLdcInsn(99);
// // methodVisitor.visitInsn(Opcodes.ICONST_0);
// //methodVisitor.visitVarInsn(Opcodes.ILOAD, 2);
// methodVisitor.visitVarInsn(Opcodes.ISTORE, 1);
// methodVisitor.visitLabel(loop);
// methodVisitor.visitVarInsn(Opcodes.ILOAD, 1);
// methodVisitor.visitInsn(Opcodes.ICONST_5);
methodVisitor.visitLdcInsn(99);
// methodVisitor.visitInsn(Opcodes.ICONST_0);
//methodVisitor.visitVarInsn(Opcodes.ILOAD, 2);
methodVisitor.visitVarInsn(Opcodes.ISTORE, 1);
methodVisitor.visitLabel(loop);
methodVisitor.visitVarInsn(Opcodes.ILOAD, 1);
methodVisitor.visitInsn(Opcodes.ICONST_5);
methodVisitor.visitJumpInsn(Opcodes.IF_ICMPGE, end);
methodVisitor.visitFieldInsn(Opcodes.GETSTATIC,
"java/lang/System", "out",
"Ljava/io/PrintStream;");
methodVisitor.visitLdcInsn("Bytecode");
methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
"java/io/PrintStream", "println",
"(Ljava/lang/String;)V", false);
methodVisitor.visitIincInsn(1, 1);
methodVisitor.visitJumpInsn(Opcodes.GOTO, loop);
methodVisitor.visitLabel(end);
methodVisitor.visitVarInsn(Opcodes.ILOAD, 1);
methodVisitor.visitInsn(Opcodes.IRETURN);
methodVisitor.visitEnd();
}
// methodVisitor.visitJumpInsn(Opcodes.IF_ICMPGE, end);
// methodVisitor.visitFieldInsn(Opcodes.GETSTATIC,
// "java/lang/System", "out",
// "Ljava/io/PrintStream;");
// methodVisitor.visitLdcInsn("Bytecode");
// methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
// "java/io/PrintStream", "println",
// "(Ljava/lang/String;)V", false);
// methodVisitor.visitIincInsn(1, 1);
// methodVisitor.visitJumpInsn(Opcodes.GOTO, loop);
// methodVisitor.visitLabel(end);
// methodVisitor.visitVarInsn(Opcodes.ILOAD, 1);
// methodVisitor.visitInsn(Opcodes.IRETURN);
// methodVisitor.visitEnd();
// }
}

View File

@ -1,6 +1,6 @@
package semantic;
import oldAst.type.TypeNode;
import ast.type.TypeNode;
import java.util.HashMap;
import java.util.Stack;

View File

@ -1,25 +1,16 @@
package semantic;
import oldAst.*;
import oldAst.expression.*;
import oldAst.member.FieldNode;
import oldAst.member.MemberNode;
import oldAst.member.MethodNode;
import oldAst.parameter.ParameterListNode;
import oldAst.parameter.ParameterNode;
import oldAst.statement.*;
import oldAst.type.ReferenceTypeNode;
import oldAst.expression.This;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import oldAst.type.BaseTypeNode;
import oldAst.type.TypeNode;
import ast.*;
import ast.member.*;
import ast.statement.*;
import ast.statement.ifstatement.IfStatementNode;
import ast.type.*;
import semantic.context.Context;
import semantic.exeptions.AlreadyDeclearedException;
import semantic.exeptions.NotDeclearedException;
@ -90,10 +81,7 @@ public class SemanticAnalyzer implements SemanticVisitor {
for(MethodNode methode : currentClass.getMethods()){
if(methode.equals(methodNode))
break;
if(methode.isSame(methodNode)){
errors.add(new AlreadyDeclearedException("This method has already been declared"));
valid = false;
}
}
var result = methodNode.accept(this);
valid = valid && result.isValid();
@ -110,32 +98,6 @@ public class SemanticAnalyzer implements SemanticVisitor {
currentScope.pushScope();
//Parameter
ParameterListNode parameterListNode = methodNode.parameters;
if (parameterListNode != null) {
List<ParameterNode> parameters = parameterListNode.parameters;
for (ParameterNode parameter : parameters) {
if (currentScope.contains(parameter.identifier)) {
errors.add(new AlreadyDeclearedException("Duplicated Parameter " + parameter.identifier));
return new TypeCheckResult(false, null);
} else {
currentScope.addLocalVar(parameter.identifier, parameter.type);
}
}
}
//Statements
List<StatementNode> statements = methodNode.statements;
for (StatementNode statement : statements) {
if (statement instanceof AssignmentStatementNode assignmentStatementNode) {
var result = assignmentStatementNode.accept(this);
valid = valid && result.isValid();
} else if (statement instanceof VariableDeclarationStatementNode variableDeclarationStatementNode) {
var result = variableDeclarationStatementNode.accept(this);
valid = valid && result.isValid();
}
}
currentScope.popScope();
return new TypeCheckResult(valid, null);
}
@ -151,80 +113,6 @@ public class SemanticAnalyzer implements SemanticVisitor {
return new TypeCheckResult(true, null);
}
@Override
public TypeCheckResult analyze(AssignmentStatementNode assignmentStatementNode) {
boolean valid = true;
ExpressionNode expressionNodeLeft = assignmentStatementNode.expressionLeft;
var resultLeft = expressionNodeLeft.accept(this);
valid = valid && resultLeft.isValid();
ExpressionNode expressionNodeRight = assignmentStatementNode.expressionRight;
var resultRight = expressionNodeRight.accept(this);
valid = valid && resultRight.isValid();
if(Objects.equals(resultLeft.getType(), resultRight.getType())){
System.out.println("SAME TYPE");
} else {
errors.add(new TypeMismatchException("Type mismatch"));
valid = false;
}
return new TypeCheckResult(valid, null);
}
@Override
public TypeCheckResult analyze(BinaryExpressionNode toCheck) {
boolean valid = true;
ExpressionNode left = toCheck.left;
var resultLeft = left.accept(this);
ExpressionNode right = toCheck.right;
var resultRight = right.accept(this);
switch (toCheck.operator) {
case ASSIGNMENT:
if(Objects.equals(resultRight.getType(), resultLeft.getType())){
System.out.println("Correct Type");
} else {
valid = false;
errors.add(new TypeMismatchException("Type Mismatch " + resultLeft.getType() + " and " + resultRight.getType()));
}
break;
case DOT:
return new TypeCheckResult(true, resultRight.getType());
default:
throw new RuntimeException("Unexpected operator: " + toCheck.operator);
}
return new TypeCheckResult(valid, null);
}
@Override
public TypeCheckResult analyze(IdentifierExpressionNode toCheck) {
if(toCheck.name == "this"){
return new TypeCheckResult(true, null);
} else if (currentFields.get(toCheck.name) == null) {
errors.add(new AlreadyDeclearedException("Not declared " + toCheck.name + " in this scope"));
return new TypeCheckResult(false, null);
} else {
return new TypeCheckResult(false, currentFields.get(toCheck.name));
}
}
@Override
public TypeCheckResult analyze(UnaryExpressionNode toCheck) {
return null;
}
@Override
public TypeCheckResult analyze(VariableDeclarationStatementNode toCheck) {
if (currentScope.contains(toCheck.identifier)) {
errors.add(new AlreadyDeclearedException("Already declared " + toCheck.identifier + " in this scope"));
return new TypeCheckResult(false, null);
} else {
currentScope.addLocalVar(toCheck.identifier, toCheck.type);
}
return new TypeCheckResult(true, null);
}
@Override
public TypeCheckResult analyze(IfStatementNode toCheck) {
return null;
@ -240,40 +128,4 @@ public class SemanticAnalyzer implements SemanticVisitor {
return null;
}
@Override
public TypeCheckResult analyze(LiteralNode toCheck) {
return new TypeCheckResult(true, toCheck.getType());
}
@Override
public TypeCheckResult analyze(InstVar toCheck) {
boolean valid = true;
var result = toCheck.expression.accept(this);
if(result.getType() instanceof BaseTypeNode){
throw new RuntimeException("BaseType has no Methods or Fields");
} else {
//Get typ of Field
var type = (ReferenceTypeNode)result.getType();
var classContext = context.getClass(type.getIdentifier());
if(classContext == null){
errors.add(new NotDeclearedException("Not declared " + type.getIdentifier() + " in this scope"));
return new TypeCheckResult(false, null);
} else {
var field = classContext.getField(toCheck.identifier);
return new TypeCheckResult(valid, field.getType());
}
}
}
@Override
public TypeCheckResult analyze(This toCheck) {
return new TypeCheckResult(true, toCheck.getType());
}
}

View File

@ -1,18 +1,10 @@
package semantic;
import ast.ClassNode;
import ast.expression.LiteralNode;
import ast.ProgramNode;
import ast.expression.BinaryExpressionNode;
import ast.expression.IdentifierExpressionNode;
import ast.expression.InstVar;
import ast.expression.unaryexpression.UnaryExpressionNode;
import ast.member.FieldNode;
import ast.member.MethodNode;
import ast.*;
import ast.member.*;
import ast.statement.*;
import ast.expression.This;
import ast.statement.ifstatement.IfStatementNode;
import ast.statement.ifstatement.*;
import typechecker.TypeCheckResult;
public interface SemanticVisitor {
@ -25,25 +17,10 @@ public interface SemanticVisitor {
TypeCheckResult analyze(FieldNode toCheck);
TypeCheckResult analyze(AssignmentStatementNode toCheck);
TypeCheckResult analyze(BinaryExpressionNode toCheck);
TypeCheckResult analyze(IdentifierExpressionNode toCheck);
TypeCheckResult analyze(UnaryExpressionNode toCheck);
TypeCheckResult analyze(VariableDeclarationStatementNode toCheck);
TypeCheckResult analyze(IfStatementNode toCheck);
TypeCheckResult analyze(ReturnStatementNode toCheck);
TypeCheckResult analyze(WhileStatementNode toCheck);
TypeCheckResult analyze(LiteralNode toCheck);
TypeCheckResult analyze(InstVar toCheck);
TypeCheckResult analyze(This toCheck);
}

View File

@ -1,7 +1,7 @@
package semantic.context;
import oldAst.ClassNode;
import oldAst.member.FieldNode;
import ast.ClassNode;
import ast.member.FieldNode;
import java.util.HashMap;
public class ClassContext {

View File

@ -1,6 +1,6 @@
package semantic.context;
import oldAst.ProgramNode;
import ast.ProgramNode;
import java.util.HashMap;
public class Context {

View File

@ -1,12 +1,11 @@
package semantic.context;
import oldAst.member.FieldNode;
import oldAst.type.AccessTypeNode;
import oldAst.type.TypeNode;
import ast.member.FieldNode;
import ast.type.*;
public class FieldContext {
private AccessTypeNode accessModifier;
private AccessModifierNode accessModifier;
private TypeNode type;
public FieldContext(FieldNode field) {

View File

@ -1,7 +1,7 @@
package typechecker;
import oldAst.type.TypeNode;
import ast.type.TypeNode;
public class TypeCheckResult {

View File

@ -1,76 +1,36 @@
package semantic;
import oldAst.ClassNode;
import oldAst.expression.LiteralNode;
import oldAst.ProgramNode;
import oldAst.expression.*;
import oldAst.member.FieldNode;
import oldAst.member.MemberNode;
import oldAst.member.MethodNode;
import oldAst.parameter.ParameterListNode;
import oldAst.parameter.ParameterNode;
import oldAst.statement.AssignmentStatementNode;
import oldAst.statement.StatementNode;
import oldAst.type.*;
import ast.*;
import ast.block.BlockNode;
import ast.member.MethodNode;
import java.util.ArrayList;
import java.util.List;
import static parser.generated.SimpleJavaParser.Identifier;
public class Mocker {
public static ProgramNode mockCorrectProgrammNode(){
public static ProgramNode mockCorrectClass(){
ProgramNode p = new ProgramNode();
ProgramNode programNode = new ProgramNode();
List<ClassNode> classList = new ArrayList<ClassNode>();
AccessTypeNode accessTypeNode = new AccessTypeNode(EnumAccessTypeNode.PUBLIC);
ClassNode classNode = new ClassNode(accessTypeNode, "testClass");
ClassNode c = new ClassNode();
c.identifier = "testClass";
MemberNode memberNode1 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar1");
classNode.members.add(memberNode1);
MethodNode m = new MethodNode();
MemberNode memberNode2 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "objectVar");
classNode.members.add(memberNode2);
BlockNode b = new BlockNode();
List<ParameterNode> parameterNodeList = new ArrayList<ParameterNode>();
ParameterNode parameterNode1 = new ParameterNode(new BaseTypeNode(EnumTypeNode.INT), "param1");
parameterNodeList.add(parameterNode1);
ParameterListNode parameterListNode = new ParameterListNode(parameterNodeList);
List<StatementNode> statementNodeList = new ArrayList<StatementNode>();
ExpressionNode expressionNodeLeft = new InstVar(new This("testClass"), "objectVar");
// b.statements.add();
LiteralNode expressionNodeRight = new LiteralNode();
expressionNodeRight.setType(new BaseTypeNode(EnumTypeNode.INT));
m.block = b;
StatementNode statementNode1 = new AssignmentStatementNode(expressionNodeLeft, expressionNodeRight);
statementNodeList.add(statementNode1);
MemberNode memberNode3 = new MethodNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar2",parameterListNode, statementNodeList );
classNode.members.add(memberNode3);
classList.add(classNode);
programNode.classes = classList;
return programNode;
c.members.add(m);
p.classes.add(c);
return p;
}
public static ProgramNode mockFieldNodeAlreadyDeclaredProgrammNode(){
ProgramNode programNode = new ProgramNode();
List<ClassNode> classList = new ArrayList<ClassNode>();
AccessTypeNode accessTypeNode = new AccessTypeNode(EnumAccessTypeNode.PUBLIC);
ClassNode classNode = new ClassNode(accessTypeNode, "testClass");
MemberNode memberNode1 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar");
classNode.members.add(memberNode1);
MemberNode memberNode2 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar");
classNode.members.add(memberNode2);
classList.add(classNode);
programNode.classes = classList;
return programNode;
}
}

View File

@ -1,161 +1,13 @@
package semantic;
import oldAst.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import semantic.exeptions.AlreadyDeclearedException;
import semantic.exeptions.TypeMismatchException;
import java.io.File;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class SemanticTest {
@BeforeEach
public void init() {
SemanticAnalyzer.clearAnalyzier();
}
@Test
public void alreadyDeclaredLocalFieldVar() {
public void correctClass(){
//Arrange
ProgramNode programNode = Mocker.mockFieldNodeAlreadyDeclaredProgrammNode();
//Act
ASTNode typedAst = SemanticAnalyzer.generateTast(programNode);
//Assert
assertEquals(1, SemanticAnalyzer.errors.size());
assertEquals(true, SemanticAnalyzer.errors.get(0) instanceof AlreadyDeclearedException);
assertEquals(null, typedAst);
}
@Test
public void alreadyDecleared() {
//Arrange
ProgramNode programNode = Mocker.mockFieldNodeAlreadyDeclaredProgrammNode();
//Act
ASTNode typedAst = SemanticAnalyzer.generateTast(programNode);
//Assert
assertEquals(1, SemanticAnalyzer.errors.size());
assertInstanceOf(AlreadyDeclearedException.class, SemanticAnalyzer.errors.getFirst());
assertNull(typedAst);
}
@Test
public void shouldWorkWithNoError() {
//Arrange
ProgramNode programNode = Mocker.mockCorrectProgrammNode();
//Act
ASTNode typedAst = SemanticAnalyzer.generateTast(programNode);
//Assert
assertEquals(0, SemanticAnalyzer.errors.size());
assertEquals(programNode, typedAst);
}
@Test
public void refTypeCorrect() {
//Arrange
ObjectMapper objectMapper = new ObjectMapper();
ProgramNode programNode = null;
try{
programNode = objectMapper.readValue(new File("src/test/resources/semantic/correctRefType.json"), ProgramNode.class);
} catch (Exception e) {
e.printStackTrace();
}
//Act
ASTNode typedAst = SemanticAnalyzer.generateTast(programNode);
//Assert
assertEquals(0, SemanticAnalyzer.errors.size());
assertEquals(programNode, typedAst);
}
@Test
public void jsonWriteTest() {
ObjectMapper objectMapper = new ObjectMapper();
//Arrange
ProgramNode programNode = Mocker.mockCorrectProgrammNode();
try{
objectMapper.writeValue(new File("src/test/resources/semantic/test.json"), programNode);
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void jsonReadTest() {
ObjectMapper objectMapper = new ObjectMapper();
ProgramNode programNode1 = null;
try{
programNode1 = objectMapper.readValue(new File("src/test/resources/semantic/test.json"), ProgramNode.class);
} catch (Exception e) {
e.printStackTrace();
}
ProgramNode programNode2 = Mocker.mockCorrectProgrammNode();
}
@Test
public void typeMismatch() {
//Arrange
ObjectMapper objectMapper = new ObjectMapper();
ProgramNode programNode = null;
try{
programNode = objectMapper.readValue(new File("src/test/resources/semantic/refTypeMismatch.json"), ProgramNode.class);
} catch (Exception e) {
e.printStackTrace();
}
//Act
ASTNode typedAst = SemanticAnalyzer.generateTast(programNode);
//Assert
assertEquals(1, SemanticAnalyzer.errors.size());
assertInstanceOf(TypeMismatchException.class, SemanticAnalyzer.errors.getFirst());
assertNull(typedAst);
}

View File

@ -0,0 +1,41 @@
package semantic.endToTAST;
import ast.ProgramNode;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.junit.jupiter.api.Test;
import parser.astBuilder.ASTBuilder;
import parser.generated.SimpleJavaLexer;
import parser.generated.SimpleJavaParser;
import java.io.IOException;
import java.nio.file.Paths;
public class CorrectTest {
@Test
public void first(){
CharStream codeCharStream = null;
try {
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/semantic/endToTAST/Test.java"));
} catch (IOException e) {
throw new RuntimeException(e);
}
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
ParseTree parseTree = parser.program(); // parse the input
/* ------------------------- AST builder -> AST ------------------------- */
ASTBuilder astBuilder = new ASTBuilder();
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
System.out.println("Test");
}
}

View File

@ -0,0 +1,7 @@
public class Test {
public void test(){
}
}