package nl.uva.softwcons.ql.validation.identifier; import java.util.HashSet; import java.util.List; import java.util.Set; import nl.uva.softwcons.ql.ast.expression.identifier.Identifier; import nl.uva.softwcons.ql.ast.form.Form; import nl.uva.softwcons.ql.ast.form.FormVisitor; import nl.uva.softwcons.ql.ast.statement.ComputedQuestion; import nl.uva.softwcons.ql.ast.statement.Conditional; import nl.uva.softwcons.ql.ast.statement.Question; import nl.uva.softwcons.ql.ast.statement.StatementVisitor; import nl.uva.softwcons.ql.validation.Checker; import nl.uva.softwcons.ql.validation.Error; import nl.uva.softwcons.ql.validation.identifier.error.DuplicateQuestionIdentifier; public final class QuestionIdentifierChecker extends Checker implements FormVisitor<List<Error>>, StatementVisitor<Void> { private final Set<Identifier> identifiers; public static List<Error> check(final Form form) { return form.accept(new QuestionIdentifierChecker()); } private QuestionIdentifierChecker() { this.identifiers = new HashSet<>(); } @Override public List<Error> visit(final Form form) { form.getStatements().forEach(st -> st.accept(this)); return this.getErrors(); } @Override public Void visit(final ComputedQuestion question) { validateQuestionIdentifier(question); return null; } @Override public Void visit(final Question question) { validateQuestionIdentifier(question); return null; } @Override public Void visit(final Conditional conditional) { conditional.getQuestions().forEach(q -> q.accept(this)); return null; } /** * Registers the given question's identifier for the current environment or * adds a {@link DuplicateQuestionIdentifier} error to the current errors * list in case the variable has already been defined. * * @param question * The question whose identifier should be defined in the current * environment */ private void validateQuestionIdentifier(final Question question) { final Identifier questionIdentifier = question.getId(); if (this.identifiers.contains(questionIdentifier)) { this.addError(new DuplicateQuestionIdentifier(question.getLineInfo())); } else { this.identifiers.add(questionIdentifier); } } }