package nl.uva.softwcons.ql.validation.dependency;
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.VariableExctractor;
import nl.uva.softwcons.ql.validation.dependency.error.CyclicQuestionsDependency;
public final class CyclicDependencyChecker extends Checker implements FormVisitor<List<Error>>, StatementVisitor<Void> {
public static List<Error> check(final Form form) {
return form.accept(new CyclicDependencyChecker());
}
private CyclicDependencyChecker() {
}
@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) {
final Identifier questionIdentifier = question.getId();
final Set<Identifier> expressionVariables = VariableExctractor.extractFrom(question.getExpression());
if (expressionVariables.contains(questionIdentifier)) {
this.addError(new CyclicQuestionsDependency(question.getLineInfo()));
}
return null;
}
@Override
public Void visit(final Question question) {
return null;
}
@Override
public Void visit(final Conditional conditional) {
conditional.getQuestions().forEach(q -> q.accept(this));
return null;
}
}