package org.uva.qls.typechecker;
import java.util.List;
import org.uva.qls.ast.literal.BoolLiteral;
import org.uva.qls.ast.literal.ColorLiteral;
import org.uva.qls.ast.literal.IdentifierLiteral;
import org.uva.qls.ast.literal.IntLiteral;
import org.uva.qls.ast.literal.StrLiteral;
import org.uva.qls.ast.sheet.Page;
import org.uva.qls.ast.sheet.Question;
import org.uva.qls.ast.sheet.Section;
import org.uva.qls.ast.sheet.Sheet;
import org.uva.qls.ast.sheet.Style;
import org.uva.qls.ast.style.BackgroundColor;
import org.uva.qls.ast.style.Font;
import org.uva.qls.ast.style.Fontsize;
import org.uva.qls.ast.style.Height;
import org.uva.qls.ast.style.StyleProperty;
import org.uva.qls.ast.style.Width;
import org.uva.qls.ast.style.widget.CheckboxModel;
import org.uva.qls.ast.style.widget.RadioModel;
import org.uva.qls.ast.style.widget.SliderModel;
import org.uva.qls.ast.style.widget.SpinboxModel;
import org.uva.qls.ast.style.widget.TextboxModel;
import org.uva.qls.visitor.LiteralVisitor;
import org.uva.qls.visitor.SheetVisitor;
import org.uva.qls.visitor.StyleVisitor;
import org.uva.util.message.MessageManager;
import org.uva.util.message.Warning;
import org.uva.util.message.Warning.Type;
public class TypeChecker implements LiteralVisitor<Boolean>, StyleVisitor<Boolean>, SheetVisitor<Boolean> {
private MessageManager manager;
public TypeChecker() {
manager = new MessageManager();
}
@Override
public Boolean visit(Height height) {
if (height.isValid()) {
return true;
}
manager.addWarning(new Warning(Type.INVALID_INPUT, height.getPosition().getStartLine(), height.toString()));
return false;
}
@Override
public Boolean visit(Width width) {
if (width.isValid()) {
return true;
}
manager.addWarning(new Warning(Type.BELOW_ZERO, width.getPosition().getStartLine(), width.toString()));
return false;
}
@Override
public Boolean visit(Fontsize fontsize) {
if (fontsize.isValid()) {
return true;
}
manager.addWarning(new Warning(Type.BELOW_ZERO, fontsize.getPosition().getStartLine(), fontsize.toString()));
return false;
}
@Override
public Boolean visit(Font font) {
if (font.isValid()) {
return true;
}
manager.addWarning(new Warning(Type.INVALID_INPUT, font.getPosition().getStartLine(), font.toString()));
return false;
}
@Override
public Boolean visit(BackgroundColor color) {
if (color.isValid()) {
return true;
}
manager.addWarning(new Warning(Type.INVALID_INPUT, color.getPosition().getStartLine(), color.toString()));
return false;
}
@Override
public Boolean visit(TextboxModel textboxModel) {
if (textboxModel.isValid()) {
return true;
}
manager.addWarning(new Warning(Type.INVALID_INPUT, textboxModel.getPosition().getStartLine(), textboxModel
.toString()));
return false;
}
@Override
public Boolean visit(SpinboxModel spinboxModel) {
List<IntLiteral> duplicatedValues = spinboxModel.isValid();
if (duplicatedValues.isEmpty()) {
return true;
}
for (IntLiteral intLiteral : duplicatedValues) {
manager.addWarning(new Warning(Type.DUPLICATED_VALUES, spinboxModel.getPosition().getStartLine(),
intLiteral.toString()));
}
return false;
}
@Override
public Boolean visit(SliderModel sliderModel) {
if (sliderModel.getMin().accept(this) && sliderModel.getMax().accept(this)) {
if (sliderModel.isValid()) {
return true;
} else {
manager.addWarning(new Warning(Type.INVALID_INPUT, sliderModel.getPosition().getStartLine(),
sliderModel.toString()));
}
}
return false;
}
@Override
public Boolean visit(RadioModel radioModel) {
if (radioModel.getFirst().accept(this) && radioModel.getSecond().accept(this)) {
if (radioModel.isValid()) {
return true;
} else {
manager.addWarning(new Warning(Type.INVALID_INPUT, radioModel.getPosition().getStartLine(), radioModel
.toString()));
}
}
return false;
}
@Override
public Boolean visit(CheckboxModel checkboxModel) {
return checkboxModel.isValid();
}
@Override
public Boolean visit(BoolLiteral node) {
if (node.getValue().isDefined()) {
return true;
}
manager.addWarning(new Warning(Type.UNDEFINED, node.getPosition().getStartLine(), node.toString()));
return false;
}
@Override
public Boolean visit(IntLiteral node) {
if (node.getValue().isDefined()) {
return true;
}
manager.addWarning(new Warning(Type.UNDEFINED, node.getPosition().getStartLine(), node.toString()));
return false;
}
@Override
public Boolean visit(StrLiteral node) {
if (node.getValue().isDefined()) {
return true;
}
manager.addWarning(new Warning(Type.UNDEFINED, node.getPosition().getStartLine(), node.toString()));
return false;
}
@Override
public Boolean visit(ColorLiteral node) {
if (node.getValue().isDefined()) {
return true;
}
manager.addWarning(new Warning(Type.UNDEFINED, node.getPosition().getStartLine(), node.toString()));
return false;
}
@Override
public Boolean visit(IdentifierLiteral node) {
if (node.getValue().isDefined()) {
return true;
}
manager.addWarning(new Warning(Type.UNDEFINED, node.getPosition().getStartLine(), node.toString()));
return false;
}
@Override
public Boolean visit(Page page) {
for (Section section : page.getSectionList()) {
if (!section.accept(this)) {
return false;
}
}
for (Style style : page.getStyleList()) {
if (!style.accept(this)) {
return false;
}
}
return true;
}
@Override
public Boolean visit(Question question) {
if (!question.getIdentifier().accept(this)) {
return false;
}
return true;
}
@Override
public Boolean visit(Section section) {
for (Question question : section.getQuestionList()) {
if (!question.accept(this)) {
return false;
}
}
for (Style style : section.getStyleList()) {
if (!style.accept(this)) {
return false;
}
}
if (!section.getSectionTitle().accept(this)) {
return false;
}
return true;
}
@Override
public Boolean visit(Sheet sheet) {
for (Page page : sheet.getPageList()) {
if (!page.accept(this)) {
return false;
}
}
if (!sheet.getIdentifier().accept(this)) {
return false;
}
return true;
}
@Override
public Boolean visit(Style style) {
for (StyleProperty prop : style.getStyleProperties()) {
if (!prop.accept(this)) {
return false;
}
}
return true;
}
public void print() {
manager.printErrors();
manager.printWarnings();
}
}