Added Basic RefTypes to InstVar and SematicCheck
Some checks are pending
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run
Some checks are pending
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run
This commit is contained in:
parent
56d316a6d0
commit
e552bd5ada
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
@ -0,0 +1,5 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</state>
|
||||
</component>
|
13
pom.xml
13
pom.xml
@ -27,13 +27,22 @@
|
||||
<artifactId>antlr4-runtime</artifactId>
|
||||
<version>4.13.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
<version>9.7</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.16.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>3.26.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -20,6 +20,8 @@ public class ClassNode implements ASTNode, Visitable {
|
||||
public List<MemberNode> members = new ArrayList<>();
|
||||
public boolean hasConstructor = false;
|
||||
|
||||
public ClassNode() {}
|
||||
|
||||
public ClassNode(AccessTypeNode accessType, String identifier){
|
||||
this.accessType = accessType;
|
||||
this.identifier = identifier;
|
||||
|
@ -1,8 +1,25 @@
|
||||
package ast.expression;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.statement.AssignmentStatementNode;
|
||||
import ast.statement.IfStatementNode;
|
||||
import ast.statement.VariableDeclarationStatementNode;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import visitor.Visitable;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY)
|
||||
@JsonSubTypes({
|
||||
@JsonSubTypes.Type(value = BinaryExpressionNode.class, name = "Binary"),
|
||||
@JsonSubTypes.Type(value = This.class, name = "This"),
|
||||
@JsonSubTypes.Type(value = InstVar.class, name = "InstVar"),
|
||||
@JsonSubTypes.Type(value = IdentifierExpressionNode.class, name = "Identifier"),
|
||||
@JsonSubTypes.Type(value = LiteralNode.class, name = "Literal"),
|
||||
@JsonSubTypes.Type(value = UnaryExpressionNode.class, name = "Unary")}
|
||||
)
|
||||
|
||||
public interface ExpressionNode extends ASTNode, Visitable {
|
||||
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ public class InstVar implements ExpressionNode, Visitable {
|
||||
public ExpressionNode expression;
|
||||
public TypeNode type;
|
||||
|
||||
public InstVar(){}
|
||||
|
||||
public InstVar(ExpressionNode expression, String identifier) {
|
||||
this.identifier = identifier;
|
||||
|
@ -1,23 +1,25 @@
|
||||
package ast;
|
||||
package ast.expression;
|
||||
|
||||
import ast.expression.ExpressionNode;
|
||||
import ast.type.TypeNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class LiteralNode implements ExpressionNode {
|
||||
|
||||
int value;
|
||||
private String type;
|
||||
private TypeNode type;
|
||||
|
||||
public LiteralNode(){}
|
||||
|
||||
public LiteralNode(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
public TypeNode getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
public void setType(TypeNode type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
26
src/main/java/ast/expression/This.java
Normal file
26
src/main/java/ast/expression/This.java
Normal file
@ -0,0 +1,26 @@
|
||||
package ast.expression;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.type.ReferenceTypeNode;
|
||||
import ast.type.TypeNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class This implements ASTNode, ExpressionNode {
|
||||
private TypeNode type;
|
||||
|
||||
public This(){}
|
||||
|
||||
public This(String className) {
|
||||
type = new ReferenceTypeNode(className);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return visitor.analyze(this);
|
||||
}
|
||||
|
||||
public TypeNode getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
@ -12,6 +12,8 @@ public class FieldNode implements MemberNode, Visitable {
|
||||
public TypeNode type;
|
||||
public String identifier;
|
||||
|
||||
public FieldNode(){}
|
||||
|
||||
public FieldNode(AccessTypeNode accessTypeNode, TypeNode type, String name){
|
||||
this.accessTypeNode = accessTypeNode;
|
||||
this.type = type;
|
||||
|
@ -1,6 +1,18 @@
|
||||
package ast.member;
|
||||
|
||||
import ast.ASTNode;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY)
|
||||
@JsonSubTypes({
|
||||
@JsonSubTypes.Type(value = MethodNode.class, name = "Method"),
|
||||
|
||||
@JsonSubTypes.Type(value = FieldNode.class, name = "Field") }
|
||||
)
|
||||
|
||||
public interface MemberNode extends ASTNode {
|
||||
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ public class MethodNode implements MemberNode, Visitable {
|
||||
|
||||
public List<StatementNode> statements = new ArrayList<>();
|
||||
|
||||
public MethodNode(){}
|
||||
|
||||
public MethodNode(AccessTypeNode visibility, TypeNode type, String identifier, ParameterListNode parameters,
|
||||
List<StatementNode> statements){
|
||||
this.visibility = visibility;
|
||||
|
@ -8,6 +8,8 @@ import java.util.List;
|
||||
public class ParameterListNode implements ASTNode {
|
||||
public List<ParameterNode> parameters = new ArrayList<>();
|
||||
|
||||
public ParameterListNode() {}
|
||||
|
||||
public ParameterListNode(List<ParameterNode> parameters){
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ public class ParameterNode implements ASTNode {
|
||||
public TypeNode type;
|
||||
public String identifier;
|
||||
|
||||
public ParameterNode(){}
|
||||
|
||||
public ParameterNode(TypeNode type, String identifier) {
|
||||
this.type = type;
|
||||
this.identifier = identifier;
|
||||
|
@ -10,7 +10,9 @@ import visitor.Visitable;
|
||||
public class AssignmentStatementNode extends StatementNode implements Visitable {
|
||||
public ExpressionNode expressionLeft;
|
||||
public ExpressionNode expressionRight;
|
||||
public TypeNode type;
|
||||
// public TypeNode type;
|
||||
|
||||
public AssignmentStatementNode(){}
|
||||
|
||||
public AssignmentStatementNode(ExpressionNode expressionLeft, ExpressionNode expressionRight) {
|
||||
this.expressionLeft = expressionLeft;
|
||||
|
@ -1,8 +1,22 @@
|
||||
package ast.statement;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.type.BaseTypeNode;
|
||||
import ast.type.ReferenceTypeNode;
|
||||
import visitor.Visitable;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY)
|
||||
@JsonSubTypes({
|
||||
@JsonSubTypes.Type(value = IfStatementNode.class, name = "IF"),
|
||||
@JsonSubTypes.Type(value = AssignmentStatementNode.class, name = "Assignment"),
|
||||
@JsonSubTypes.Type(value = VariableDeclarationStatementNode.class, name = "VariableDeclaration") }
|
||||
)
|
||||
|
||||
public abstract class StatementNode implements ASTNode, Visitable {
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,9 @@ public class VariableDeclarationStatementNode extends StatementNode {
|
||||
public TypeNode type;
|
||||
public String identifier;
|
||||
public ExpressionNode expression;
|
||||
|
||||
public VariableDeclarationStatementNode(){}
|
||||
|
||||
public VariableDeclarationStatementNode(TypeNode type, String identifier, ExpressionNode expression) {
|
||||
this.type = type;
|
||||
this.identifier = identifier;
|
||||
|
@ -5,6 +5,8 @@ import ast.ASTNode;
|
||||
public class AccessTypeNode implements ASTNode {
|
||||
public EnumAccessTypeNode enumAccessTypeNode;
|
||||
|
||||
public AccessTypeNode(){}
|
||||
|
||||
public AccessTypeNode(EnumAccessTypeNode enumAccessTypeNode) {
|
||||
this.enumAccessTypeNode = enumAccessTypeNode;
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ public class BaseTypeNode implements ASTNode, TypeNode {
|
||||
|
||||
public EnumTypeNode enumType;
|
||||
|
||||
public BaseTypeNode(){}
|
||||
|
||||
public BaseTypeNode(EnumTypeNode enumType) {
|
||||
this.enumType = enumType;
|
||||
}
|
||||
|
@ -3,4 +3,34 @@ package ast.type;
|
||||
import ast.ASTNode;
|
||||
|
||||
public class ReferenceTypeNode implements ASTNode, TypeNode {
|
||||
|
||||
private String identifier;
|
||||
|
||||
public ReferenceTypeNode() {}
|
||||
|
||||
public ReferenceTypeNode(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
ReferenceTypeNode other = (ReferenceTypeNode) obj;
|
||||
if (identifier == null) {
|
||||
if (other.identifier != null)
|
||||
return false;
|
||||
} else if (!identifier.equals(other.identifier))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
package ast.type;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.expression.ExpressionNode;
|
||||
import semantic.SemanticVisitor;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class This implements ASTNode, ExpressionNode {
|
||||
@Override
|
||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -2,5 +2,17 @@ package ast.type;
|
||||
|
||||
import ast.ASTNode;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY)
|
||||
@JsonSubTypes({
|
||||
@JsonSubTypes.Type(value = BaseTypeNode.class, name = "Base"),
|
||||
|
||||
@JsonSubTypes.Type(value = ReferenceTypeNode.class, name = "Reference") }
|
||||
)
|
||||
|
||||
public interface TypeNode extends ASTNode {
|
||||
}
|
@ -1,11 +1,7 @@
|
||||
package parser;
|
||||
|
||||
import ast.*;
|
||||
import ast.expression.BinaryExpressionNode;
|
||||
import ast.expression.ExpressionNode;
|
||||
import ast.expression.ExpresssionOperator;
|
||||
import ast.expression.IdentifierExpressionNode;
|
||||
import ast.expression.UnaryExpressionNode;
|
||||
import ast.expression.*;
|
||||
import ast.member.FieldNode;
|
||||
import ast.member.MemberNode;
|
||||
import ast.member.MethodNode;
|
||||
@ -210,7 +206,7 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
||||
int intValue = Integer.parseInt(literalContext.getText());
|
||||
LiteralNode literalNode = new LiteralNode(intValue);
|
||||
|
||||
literalNode.setType("int");
|
||||
literalNode.setType(new BaseTypeNode(EnumTypeNode.INT));
|
||||
return literalNode;
|
||||
} catch (NumberFormatException ignored) {}
|
||||
|
||||
|
@ -10,6 +10,9 @@ import ast.member.MethodNode;
|
||||
import ast.parameter.ParameterListNode;
|
||||
import ast.parameter.ParameterNode;
|
||||
import ast.statement.*;
|
||||
import ast.type.ReferenceTypeNode;
|
||||
import ast.expression.This;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -17,8 +20,8 @@ import java.util.Objects;
|
||||
|
||||
import ast.type.BaseTypeNode;
|
||||
import ast.type.EnumTypeNode;
|
||||
import ast.type.This;
|
||||
import ast.type.TypeNode;
|
||||
import semantic.context.Context;
|
||||
import semantic.exeptions.AlreadyDeclearedException;
|
||||
import semantic.exeptions.NotDeclearedException;
|
||||
import semantic.exeptions.TypeMismatchException;
|
||||
@ -30,6 +33,7 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
|
||||
public static ArrayList<Exception> errors = new ArrayList<>();
|
||||
|
||||
private Context context;
|
||||
private static Scope currentScope;
|
||||
private static ClassNode currentClass;
|
||||
|
||||
@ -60,6 +64,7 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
var valid = true;
|
||||
|
||||
currentScope = new Scope();
|
||||
context = new Context(node);
|
||||
|
||||
List<ClassNode> classes = node.classes;
|
||||
for (ClassNode classNode : classes) {
|
||||
@ -74,7 +79,7 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
var valid = true;
|
||||
|
||||
currentClass = classNode;
|
||||
|
||||
currentFields.clear();
|
||||
List<MemberNode> members = classNode.members;
|
||||
for (MemberNode memberNode : members) {
|
||||
if (memberNode instanceof FieldNode fieldNode) {
|
||||
@ -238,23 +243,38 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(LiteralNode toCheck) {
|
||||
return new TypeCheckResult(true, new BaseTypeNode(EnumTypeNode.INT));
|
||||
return new TypeCheckResult(true, toCheck.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(InstVar toCheck) {
|
||||
boolean valid = true;
|
||||
|
||||
if(toCheck.expression instanceof This){
|
||||
if(currentFields.get(toCheck.identifier) == null){
|
||||
errors.add(new NotDeclearedException("Not declared " + toCheck.identifier + " in this scope"));
|
||||
valid = false;
|
||||
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 {
|
||||
TypeNode typeNode = currentFields.get(toCheck.identifier);
|
||||
return new TypeCheckResult(valid, typeNode);
|
||||
var field = classContext.getField(toCheck.identifier);
|
||||
|
||||
return new TypeCheckResult(valid, field.getType());
|
||||
}
|
||||
}
|
||||
return new TypeCheckResult(valid, null);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeCheckResult analyze(This toCheck) {
|
||||
return new TypeCheckResult(true, toCheck.getType());
|
||||
}
|
||||
|
||||
}
|
@ -2,7 +2,7 @@ package semantic;
|
||||
|
||||
|
||||
import ast.ClassNode;
|
||||
import ast.LiteralNode;
|
||||
import ast.expression.LiteralNode;
|
||||
import ast.ProgramNode;
|
||||
import ast.expression.BinaryExpressionNode;
|
||||
import ast.expression.IdentifierExpressionNode;
|
||||
@ -11,6 +11,7 @@ import ast.expression.UnaryExpressionNode;
|
||||
import ast.member.FieldNode;
|
||||
import ast.member.MethodNode;
|
||||
import ast.statement.*;
|
||||
import ast.expression.This;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public interface SemanticVisitor {
|
||||
@ -42,4 +43,6 @@ public interface SemanticVisitor {
|
||||
TypeCheckResult analyze(LiteralNode toCheck);
|
||||
|
||||
TypeCheckResult analyze(InstVar toCheck);
|
||||
|
||||
TypeCheckResult analyze(This toCheck);
|
||||
}
|
27
src/main/java/semantic/context/ClassContext.java
Normal file
27
src/main/java/semantic/context/ClassContext.java
Normal file
@ -0,0 +1,27 @@
|
||||
package semantic.context;
|
||||
|
||||
import ast.ClassNode;
|
||||
import ast.member.FieldNode;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class ClassContext {
|
||||
|
||||
private HashMap<String, FieldContext> fields;
|
||||
|
||||
public ClassContext(ClassNode classNode) {
|
||||
|
||||
fields = new HashMap<>();
|
||||
|
||||
classNode.members.forEach(member -> {
|
||||
if(member instanceof FieldNode fieldNode) {
|
||||
fields.put(fieldNode.identifier, new FieldContext(fieldNode));
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public FieldContext getField(String name) {
|
||||
return fields.get(name);
|
||||
}
|
||||
|
||||
}
|
25
src/main/java/semantic/context/Context.java
Normal file
25
src/main/java/semantic/context/Context.java
Normal file
@ -0,0 +1,25 @@
|
||||
package semantic.context;
|
||||
|
||||
import ast.ClassNode;
|
||||
import ast.ProgramNode;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class Context {
|
||||
|
||||
private HashMap<String, ClassContext> classes;
|
||||
|
||||
public Context(ProgramNode programNode) {
|
||||
classes = new HashMap<>();
|
||||
|
||||
programNode.classes.forEach(classNode -> {
|
||||
ClassContext classContext = new ClassContext(classNode);
|
||||
classes.put(classNode.identifier, classContext);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public ClassContext getClass(String identifier) {
|
||||
return classes.get(identifier);
|
||||
}
|
||||
|
||||
}
|
22
src/main/java/semantic/context/FieldContext.java
Normal file
22
src/main/java/semantic/context/FieldContext.java
Normal file
@ -0,0 +1,22 @@
|
||||
package semantic.context;
|
||||
|
||||
import ast.member.FieldNode;
|
||||
import ast.type.AccessTypeNode;
|
||||
import ast.type.EnumAccessTypeNode;
|
||||
import ast.type.TypeNode;
|
||||
|
||||
public class FieldContext {
|
||||
|
||||
private AccessTypeNode accessModifier;
|
||||
private TypeNode type;
|
||||
|
||||
public FieldContext(FieldNode field) {
|
||||
accessModifier = field.accessTypeNode;
|
||||
type = field.type;
|
||||
}
|
||||
|
||||
public TypeNode getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package semantic;
|
||||
|
||||
import ast.ClassNode;
|
||||
import ast.LiteralNode;
|
||||
import ast.expression.LiteralNode;
|
||||
import ast.ProgramNode;
|
||||
import ast.expression.*;
|
||||
import ast.member.FieldNode;
|
||||
@ -39,16 +39,14 @@ public class Mocker {
|
||||
|
||||
List<StatementNode> statementNodeList = new ArrayList<StatementNode>();
|
||||
|
||||
ExpressionNode expressionNodeLeft = new InstVar(new This(), "objectVar");
|
||||
ExpressionNode expressionNodeLeft = new InstVar(new This("testClass"), "objectVar");
|
||||
|
||||
ExpressionNode expressionNodeRight = new LiteralNode(1);
|
||||
LiteralNode expressionNodeRight = new LiteralNode();
|
||||
expressionNodeRight.setType(new BaseTypeNode(EnumTypeNode.INT));
|
||||
|
||||
StatementNode statementNode1 = new AssignmentStatementNode(expressionNodeLeft, expressionNodeRight);
|
||||
statementNodeList.add(statementNode1);
|
||||
|
||||
StatementNode statementNode2 = new VariableDeclarationStatementNode(new BaseTypeNode(EnumTypeNode.CHAR), "objectVar", new LiteralNode(1));
|
||||
statementNodeList.add(statementNode2);
|
||||
|
||||
MemberNode memberNode3 = new MethodNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar2",parameterListNode, statementNodeList );
|
||||
classNode.members.add(memberNode3);
|
||||
|
||||
@ -76,5 +74,4 @@ public class Mocker {
|
||||
|
||||
return programNode;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,20 +2,19 @@ package semantic;
|
||||
|
||||
|
||||
import ast.*;
|
||||
import ast.member.FieldNode;
|
||||
import ast.member.MemberNode;
|
||||
import ast.type.AccessTypeNode;
|
||||
import ast.type.BaseTypeNode;
|
||||
import ast.type.EnumAccessTypeNode;
|
||||
import ast.type.EnumTypeNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.assertj.core.api.MatcherAssert;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import semantic.exeptions.AlreadyDeclearedException;
|
||||
import semantic.exeptions.TypeMismatchException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
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 {
|
||||
|
||||
@ -25,7 +24,7 @@ public class SemanticTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void alreadyDeclaredLocalFieldVar(){
|
||||
public void alreadyDeclaredLocalFieldVar() {
|
||||
|
||||
//Arrange
|
||||
|
||||
@ -44,7 +43,7 @@ public class SemanticTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeMismatch(){
|
||||
public void alreadyDecleared() {
|
||||
|
||||
//Arrange
|
||||
|
||||
@ -57,13 +56,13 @@ public class SemanticTest {
|
||||
//Assert
|
||||
|
||||
assertEquals(1, SemanticAnalyzer.errors.size());
|
||||
assertEquals(true, SemanticAnalyzer.errors.get(0) instanceof AlreadyDeclearedException);
|
||||
assertEquals(null, typedAst);
|
||||
assertInstanceOf(AlreadyDeclearedException.class, SemanticAnalyzer.errors.getFirst());
|
||||
assertNull(typedAst);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldWorkWithNoError(){
|
||||
public void shouldWorkWithNoError() {
|
||||
|
||||
//Arrange
|
||||
|
||||
@ -80,4 +79,85 @@ public class SemanticTest {
|
||||
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
70
src/test/resources/semantic/correctRefType.json
Normal file
70
src/test/resources/semantic/correctRefType.json
Normal file
@ -0,0 +1,70 @@
|
||||
{
|
||||
"classes": [
|
||||
{
|
||||
"identifier": "testClass1",
|
||||
"accessType": {
|
||||
"enumAccessTypeNode": "PUBLIC"
|
||||
},
|
||||
"members": [
|
||||
{
|
||||
"@type": "Field",
|
||||
"accessTypeNode": {
|
||||
"enumAccessTypeNode": "PUBLIC"
|
||||
},
|
||||
"type": {
|
||||
"@type": "Base",
|
||||
"enumType": "INT"
|
||||
},
|
||||
"identifier": "testVar1"
|
||||
},
|
||||
{
|
||||
"@type": "Method",
|
||||
"visibility": {
|
||||
"enumAccessTypeNode": "PUBLIC"
|
||||
},
|
||||
"type": {
|
||||
"@type": "Base",
|
||||
"enumType": "INT"
|
||||
},
|
||||
"identifier": "testMethod",
|
||||
"parameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"type": {
|
||||
"@type": "Base",
|
||||
"enumType": "INT"
|
||||
},
|
||||
"identifier": "param1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"statements": [
|
||||
{
|
||||
"@type": "Assignment",
|
||||
"expressionLeft": {
|
||||
"@type": "InstVar",
|
||||
"identifier": "testVar1",
|
||||
"expression": {
|
||||
"@type": "This",
|
||||
"type": {
|
||||
"@type": "Reference",
|
||||
"identifier": "testClass1"
|
||||
}
|
||||
},
|
||||
"type": null
|
||||
},
|
||||
"expressionRight": {
|
||||
"@type": "Literal",
|
||||
"type": {
|
||||
"@type": "Base",
|
||||
"enumType": "INT"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"hasConstructor": false
|
||||
}
|
||||
]
|
||||
}
|
133
src/test/resources/semantic/refTypeMismatch.json
Normal file
133
src/test/resources/semantic/refTypeMismatch.json
Normal file
@ -0,0 +1,133 @@
|
||||
{
|
||||
"classes": [
|
||||
{
|
||||
"identifier": "testClass1",
|
||||
"accessType": {
|
||||
"enumAccessTypeNode": "PUBLIC"
|
||||
},
|
||||
"members": [
|
||||
{
|
||||
"@type": "Field",
|
||||
"accessTypeNode": {
|
||||
"enumAccessTypeNode": "PUBLIC"
|
||||
},
|
||||
"type": {
|
||||
"@type": "Base",
|
||||
"enumType": "INT"
|
||||
},
|
||||
"identifier": "testVar1"
|
||||
},
|
||||
{
|
||||
"@type": "Method",
|
||||
"visibility": {
|
||||
"enumAccessTypeNode": "PUBLIC"
|
||||
},
|
||||
"type": {
|
||||
"@type": "Base",
|
||||
"enumType": "INT"
|
||||
},
|
||||
"identifier": "testMethod",
|
||||
"parameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"type": {
|
||||
"@type": "Base",
|
||||
"enumType": "INT"
|
||||
},
|
||||
"identifier": "param1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"statements": [
|
||||
{
|
||||
"@type": "Assignment",
|
||||
"expressionLeft": {
|
||||
"@type": "InstVar",
|
||||
"identifier": "testVar1",
|
||||
"expression": {
|
||||
"@type": "This",
|
||||
"type": {
|
||||
"@type": "Reference",
|
||||
"identifier": "testClass1"
|
||||
}
|
||||
},
|
||||
"type": null
|
||||
},
|
||||
"expressionRight": {
|
||||
"@type": "Literal",
|
||||
"type": {
|
||||
"@type": "Base",
|
||||
"enumType": "BOOLEAN"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"hasConstructor": false,
|
||||
"methods": [
|
||||
{
|
||||
"@type": "Method",
|
||||
"visibility": {
|
||||
"enumAccessTypeNode": "PUBLIC"
|
||||
},
|
||||
"type": {
|
||||
"@type": "Base",
|
||||
"enumType": "INT"
|
||||
},
|
||||
"identifier": "testMethod",
|
||||
"parameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"type": {
|
||||
"@type": "Base",
|
||||
"enumType": "INT"
|
||||
},
|
||||
"identifier": "param1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"statements": [
|
||||
{
|
||||
"@type": "Assignment",
|
||||
"expressionLeft": {
|
||||
"@type": "InstVar",
|
||||
"identifier": "testVar",
|
||||
"expression": {
|
||||
"@type": "InstVar",
|
||||
"identifier": "testVar",
|
||||
"expression": {
|
||||
"@type": "This",
|
||||
"type": {
|
||||
"@type": "Reference",
|
||||
"identifier": "testClass2"
|
||||
}
|
||||
},
|
||||
"type": null
|
||||
},
|
||||
"type": null
|
||||
},
|
||||
"expressionRight": {
|
||||
"@type": "Literal",
|
||||
"type": null
|
||||
},
|
||||
"type": null
|
||||
},
|
||||
{
|
||||
"@type": "VariableDeclaration",
|
||||
"type": {
|
||||
"@type": "Base",
|
||||
"enumType": "CHAR"
|
||||
},
|
||||
"identifier": "objectVar",
|
||||
"expression": {
|
||||
"@type": "Literal",
|
||||
"type": null
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
1
src/test/resources/semantic/test.json
Normal file
1
src/test/resources/semantic/test.json
Normal file
@ -0,0 +1 @@
|
||||
{"classes":[{"identifier":"testClass","accessType":{"enumAccessTypeNode":"PUBLIC"},"members":[{"@type":"Field","accessTypeNode":{"enumAccessTypeNode":"PUBLIC"},"type":{"@type":"Base","enumType":"INT"},"identifier":"testVar1"},{"@type":"Field","accessTypeNode":{"enumAccessTypeNode":"PUBLIC"},"type":{"@type":"Base","enumType":"INT"},"identifier":"objectVar"},{"@type":"Method","visibility":{"enumAccessTypeNode":"PUBLIC"},"type":{"@type":"Base","enumType":"INT"},"identifier":"testVar2","parameters":{"parameters":[{"type":{"@type":"Base","enumType":"INT"},"identifier":"param1"}]},"statements":[{"@type":"Assignment","expressionLeft":{"@type":"InstVar","identifier":"objectVar","expression":{"@type":"This","type":{"@type":"Reference","identifier":"testClass"}},"type":null},"expressionRight":{"@type":"Literal","type":{"@type":"Base","enumType":"INT"}}}]}],"hasConstructor":false,"methods":[{"@type":"Method","visibility":{"enumAccessTypeNode":"PUBLIC"},"type":{"@type":"Base","enumType":"INT"},"identifier":"testVar2","parameters":{"parameters":[{"type":{"@type":"Base","enumType":"INT"},"identifier":"param1"}]},"statements":[{"@type":"Assignment","expressionLeft":{"@type":"InstVar","identifier":"objectVar","expression":{"@type":"This","type":{"@type":"Reference","identifier":"testClass"}},"type":null},"expressionRight":{"@type":"Literal","type":{"@type":"Base","enumType":"INT"}}}]}]}]}
|
Loading…
Reference in New Issue
Block a user