package qlProject.typeChecking.typeCheckVisitors; import java.util.*; import qlProject.ast.Questionnaire; import qlProject.ast.expression.IExpression; import qlProject.ast.statement.IStatement; import qlProject.ast.statement.IStatementsVisitor; import qlProject.ast.statement.IfStatement; import qlProject.ast.statement.assignment.ComputedAssignment; import qlProject.ast.statement.assignment.DirectAssignment; import qlProject.ast.type.BooleanType; import qlProject.ast.type.NullType; import qlProject.ast.type.Type; import qlProject.typeChecking.complaints.Complaint; import qlProject.typeChecking.complaints.expression_level_complaint.ConditionTypeError; import qlProject.typeChecking.complaints.expression_level_complaint.ExpressionTypeError; import qlProject.util.QuestionDetails; public class StatementsTypeCheckVisitor implements IStatementsVisitor { private final HashSet<Complaint> complaints; private final Map<String, QuestionDetails> questionsDetails; private final Map<String, Set<String>> deps; private final ExpressionsTypeCheckVisitor expressionVisitor; public StatementsTypeCheckVisitor(Map<String, QuestionDetails> questionsDetails, HashSet<Complaint> complaints, Map<String, Set<String>> deps) { this.complaints = complaints; this.questionsDetails = questionsDetails; this.deps = deps; this.expressionVisitor = new ExpressionsTypeCheckVisitor(questionsDetails); } @Override public void visit(Questionnaire q) { for (IStatement s : q.getStatements()){ s.accept(this); } } public void visit (IfStatement ifStatements){ checkConditionCyclicReference(ifStatements); for (IStatement s : ifStatements.getIfTrueStatements()){ s.accept(this); } for (IStatement s : ifStatements.getIfFalseStatements()){ s.accept(this); } checkCondition(ifStatements.getCondition()); } public void visit (ComputedAssignment q){ Type t = (Type)q.getExpression().accept(expressionVisitor); if (!t.equals(q.getType())){ complaints.add(new ExpressionTypeError(questionsDetails, q, q.getExpression(), t)); } } public void visit (DirectAssignment q){ } public void checkCondition(IExpression e){ Type t = (Type)e.accept(expressionVisitor); complaints.addAll(expressionVisitor.getComplaints()); if (!(t.isOfType(new NullType()))){ if (!(t.isOfType(new BooleanType()))){ complaints.add(new ConditionTypeError(e, t)); } } } public void showComplaints(){ for (Complaint complaint : complaints){ complaint.presentComplaint(); } } public void checkConditionCyclicReference(IfStatement conditionalQs){ Set<String> vars = conditionalQs.getExpressionVariables(); for (String observer : vars){ if (deps.containsKey(observer) || deps.containsValue(observer)){ complaints.add(new ConditionCyclicReference(conditionalQs.getCondition(), observer)); } } } }