package nl.uva.softwcons.ql.validation.label; import java.util.HashSet; import java.util.List; import java.util.Set; 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.label.error.DuplicateLabel; public final class LabelChecker extends Checker implements FormVisitor<List<Error>>, StatementVisitor<Void> { private final Set<String> labels; public static List<Error> check(final Form form) { return form.accept(new LabelChecker()); } private LabelChecker() { this.labels = 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) { validateQuestionLabel(question); return null; } @Override public Void visit(final Question question) { validateQuestionLabel(question); return null; } @Override public Void visit(final Conditional conditional) { conditional.getQuestions().forEach(q -> q.accept(this)); return null; } /** * Registers the given question's label for the current environment or adds * a {@link DuplicateLabel} error to the current errors list in case the * variable has already been defined. * * @param question * The question whose label should be defined in the current * environment */ private void validateQuestionLabel(final Question question) { final String questionLabel = question.getLabel(); if (this.labels.contains(questionLabel)) { this.addError(new DuplicateLabel(question.getLineInfo())); } else { this.labels.add(questionLabel); } } }