package uva.qls.interpreter.typecheck; import org.antlr.v4.runtime.tree.ParseTree; import uva.ql.interpreter.typecheck.TypeCheckVisitor; import uva.qls.ast.CodeLines; import uva.qls.ast.Prog; import uva.ql.main.Main; import uva.qls.interpreter.typecheck.table.ErrorTable; import uva.qls.interpreter.typecheck.table.SymbolTable; import uva.ql.ast.ASTNode; import uva.qls.ast.literal.*; import uva.qls.ast.statements.DefaultValue; import uva.qls.ast.statements.Question; import uva.qls.interpreter.typecheck.TypeCheckVisitorQLS; import uva.ql.supporting.*; public class TypeCheckQLS { private SymbolTable table; private TypeCheckVisitor typeCheckQL; private ErrorTable errorTable; private TypeCheckVisitorQLS visitor; public TypeCheckQLS(uva.qls.ast.ASTNode _ast){ this.errorTable = new ErrorTable(); this.table = new SymbolTable(); this.initTypeCheckQL(); this.startTypeVisitor(_ast); this.allQuestionsDefined(); } public TypeCheckVisitor getTypeCheckQL(){ return this.typeCheckQL; } public SymbolTable getSymbolTable(){ return this.table; } public ErrorTable getErrorTable(){ return this.errorTable; } private void initTypeCheckQL(){ try{ ParseTree tree = Main.getParseTree("SupportingFiles/Test.ql"); ASTNode ast = Main.getAST(tree); this.typeCheckQL = Main.getTypeCheck(ast); } catch (Exception ex){ System.out.println("save to the error table: " + ex.getMessage()); } } private void startTypeVisitor(uva.qls.ast.ASTNode _ast){ this.visitor = new TypeCheckVisitorQLS(this, this.table); visitor.visitProg((Prog) _ast); } public boolean hasErrors(){ return this.errorTable.getTable().values().size() != 0; } public boolean isMultiple (Identifier _identifier){ return this.table.keyExists(_identifier) ? this.setValuesToErrorTable("Multiple references to same question" , _identifier.getLOC()) : false; } public boolean correctWidget(String _type, String _evaltype, CodeLines _lines){ return ((_type).equals(_evaltype)) ? false : this.setValuesToErrorTable("Wrong widget selection" , _lines); } public boolean isUndefined (Identifier _identifier) { return this.typeCheckQL.getSymbolTable().keyExists(_identifier.evaluatedValue()) ? false : this.setValuesToErrorTable("Question is not defined in both QL & QLS", _identifier.getLOC()); } public boolean allQuestionsDefined(){ for (String key : this.typeCheckQL.getSymbolTable().getTable().keySet()){ if (!this.table.keyExists(new Identifier(key, null))){ try{ this.typeCheckQL.getSymbolTable().retrieveValue(key).getPrimitiveType(); Tuple<Integer, Integer> locs = this.typeCheckQL.getSymbolTable().retrieveValue(key).getSourceCodeLines().getLOCTuple(); this.setValuesToErrorTable("Question of QL not defined: " + key, new CodeLines(locs.x, locs.y)); } catch (Exception ex){ System.out.println("Primitive type for: " + key + " could not be found"); } } } return true; } public boolean isCompatibleDefaultValue(DefaultValue value, String type, String componentName){ return isCompatible(type, componentName) ? true : this.setValuesToErrorTable("Default value not compatible type: " + value.toString(), value.getLOC()); } public boolean isCompatibleQuestionType(Question question, String type, String componentName){ return isCompatible(type, componentName) ? true : this.setValuesToErrorTable("Question not compatible with type: " + question.getIdentifier().evaluatedValue(), question.getLOC()); } private boolean isCompatible(String type, String componentName){ for (CheckWidget w : CheckWidget.detectTypes(type)){ if (w.getName().equals(componentName)){ return true; } } return false; } public boolean setValuesToErrorTable(String value, CodeLines codeLines){ this.errorTable.putValue(value, codeLines); return true; } }