bool GDScriptLanguage::validate(const String& p_script, int &r_line_error,int &r_col_error,String& r_test_error, const String& p_path,List<String> *r_functions) const { GDParser parser; Error err = parser.parse(p_script,p_path.get_base_dir(),true); if (err) { r_line_error=parser.get_error_line(); r_col_error=parser.get_error_column(); r_test_error=parser.get_error(); return false; } else { const GDParser::Node *root = parser.get_parse_tree(); ERR_FAIL_COND_V(root->type!=GDParser::Node::TYPE_CLASS,false); const GDParser::ClassNode *cl = static_cast<const GDParser::ClassNode*>(root); Map<int,String> funcs; for(int i=0;i<cl->functions.size();i++) { funcs[cl->functions[i]->line]=cl->functions[i]->name; } for(int i=0;i<cl->static_functions.size();i++) { funcs[cl->static_functions[i]->line]=cl->static_functions[i]->name; } for (Map<int,String>::Element *E=funcs.front();E;E=E->next()) { r_functions->push_back(E->get()+":"+itos(E->key())); } } return true; }
MainLoop* test(TestType p_test) { List<String> cmdlargs = OS::get_singleton()->get_cmdline_args(); if (cmdlargs.empty()) { //try editor! return NULL; } String test = cmdlargs.back()->get(); FileAccess *fa = FileAccess::open(test,FileAccess::READ); if (!fa) { ERR_EXPLAIN("Could not open file: "+test); ERR_FAIL_V(NULL); } Vector<uint8_t> buf; int flen = fa->get_len(); buf.resize(fa->get_len()+1); fa->get_buffer(&buf[0],flen); buf[flen]=0; String code; code.parse_utf8((const char*)&buf[0]); Vector<String> lines; int last=0; for(int i=0;i<=code.length();i++) { if (code[i]=='\n' || code[i]==0) { lines.push_back(code.substr(last,i-last)); last=i+1; } } if (p_test==TEST_TOKENIZER) { GDTokenizerText tk; tk.set_code(code); int line=-1; while(tk.get_token()!=GDTokenizer::TK_EOF) { String text; if (tk.get_token()==GDTokenizer::TK_IDENTIFIER) text="'"+tk.get_token_identifier()+"' (identifier)"; else if (tk.get_token()==GDTokenizer::TK_CONSTANT) { Variant c= tk.get_token_constant(); if (c.get_type()==Variant::STRING) text="\""+String(c)+"\""; else text=c; text=text+" ("+Variant::get_type_name(c.get_type())+" constant)"; } else if (tk.get_token()==GDTokenizer::TK_ERROR) text="ERROR: "+tk.get_token_error(); else if (tk.get_token()==GDTokenizer::TK_NEWLINE) text="newline ("+itos(tk.get_token_line())+") + indent: "+itos(tk.get_token_line_indent()); else if (tk.get_token()==GDTokenizer::TK_BUILT_IN_FUNC) text="'"+String(GDFunctions::get_func_name(tk.get_token_built_in_func()))+"' (built-in function)"; else text=tk.get_token_name(tk.get_token()); if (tk.get_token_line()!=line) { int from=line+1; line = tk.get_token_line();; for(int i=from;i<=line;i++) { int l=i-1; if (l>=0 && l<lines.size()) { print_line("\n"+itos(i)+": "+lines[l]+"\n"); } } } print_line("\t("+itos(tk.get_token_column())+"): "+text); tk.advance(); } } if (p_test==TEST_PARSER) { GDParser parser; Error err = parser.parse(code); if (err) { print_line("Parse Error:\n"+itos(parser.get_error_line())+":"+itos(parser.get_error_column())+":"+parser.get_error()); memdelete(fa); return NULL; } const GDParser::Node* root = parser.get_parse_tree(); ERR_FAIL_COND_V(root->type!=GDParser::Node::TYPE_CLASS,NULL); const GDParser::ClassNode *cnode=static_cast<const GDParser::ClassNode*>(root); _parser_show_class(cnode,0,lines); } if (p_test==TEST_COMPILER) { GDParser parser; Error err = parser.parse(code); if (err) { print_line("Parse Error:\n"+itos(parser.get_error_line())+":"+itos(parser.get_error_column())+":"+parser.get_error()); memdelete(fa); return NULL; } GDScript *script = memnew( GDScript ); GDCompiler gdc; err = gdc.compile(&parser,script); if (err) { print_line("Compile Error:\n"+itos(gdc.get_error_line())+":"+itos(gdc.get_error_column())+":"+gdc.get_error()); memdelete(script); return NULL; } Ref<GDScript> gds =Ref<GDScript>( script ); Ref<GDScript> current=gds; while(current.is_valid()) { print_line("** CLASS **"); _disassemble_class(current,lines); current=current->get_base(); } } else if (p_test==TEST_BYTECODE) { Vector<uint8_t> buf = GDTokenizerBuffer::parse_code_string(code); String dst = test.basename()+".gdc"; FileAccess *fw = FileAccess::open(dst,FileAccess::WRITE); fw->store_buffer(buf.ptr(),buf.size()); memdelete(fw); } #if 0 Parser parser; Error err = parser.parse(code); if (err) { print_line("error:"+itos(parser.get_error_line())+":"+itos(parser.get_error_column())+":"+parser.get_error()); } else { print_line("Parse O-K!"); } #endif memdelete(fa); return NULL; }