improved get_node(), connect(), etc code completion.
-properly completes text arguments -includes the "/root" autoloads
This commit is contained in:
@ -381,7 +381,12 @@ static Ref<Reference> _get_parent_class(GDCompletionContext& context) {
|
||||
|
||||
path=context.base_path.plus_file(path);
|
||||
}
|
||||
script = ResourceLoader::load(path);
|
||||
|
||||
if (ScriptCodeCompletionCache::get_sigleton())
|
||||
script = ScriptCodeCompletionCache::get_sigleton()->get_cached_resource(path);
|
||||
else
|
||||
script = ResourceLoader::load(path);
|
||||
|
||||
if (script.is_null()) {
|
||||
return REF();
|
||||
}
|
||||
@ -1322,6 +1327,21 @@ static void _find_type_arguments(const GDParser::Node*p_node,int p_line,const St
|
||||
if (obj) {
|
||||
List<String> options;
|
||||
obj->get_argument_options(p_method,p_argidx,&options);
|
||||
if (obj->is_type("Node") && p_argidx==0 && (String(p_method)=="get_node" || String(p_method)=="has_node")) {
|
||||
|
||||
List<PropertyInfo> props;
|
||||
Globals::get_singleton()->get_property_list(&props);
|
||||
|
||||
for(List<PropertyInfo>::Element *E=props.front();E;E=E->next()) {
|
||||
|
||||
String s = E->get().name;
|
||||
if (!s.begins_with("autoload/"))
|
||||
continue;
|
||||
// print_line("found "+s);
|
||||
String name = s.get_slice("/",1);
|
||||
options.push_back("\"/root/"+name+"\"");
|
||||
}
|
||||
}
|
||||
for(List<String>::Element *E=options.front();E;E=E->next()) {
|
||||
|
||||
result.insert(E->get());
|
||||
@ -1661,7 +1681,9 @@ Error GDScriptLanguage::complete_code(const String& p_code, const String& p_base
|
||||
//print_line( p_code.replace(String::chr(0xFFFF),"<cursor>"));
|
||||
|
||||
GDParser p;
|
||||
Error err = p.parse(p_code,p_base_path,true);
|
||||
//Error parse(const String& p_code, const String& p_base_path="", bool p_just_validate=false,const String& p_self_path="",bool p_for_completion=false);
|
||||
|
||||
Error err = p.parse(p_code,p_base_path,false,"",true);
|
||||
bool isfunction=false;
|
||||
Set<String> options;
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
#include "print_string.h"
|
||||
#include "io/resource_loader.h"
|
||||
#include "os/file_access.h"
|
||||
#include "script_language.h"
|
||||
|
||||
template<class T>
|
||||
T* GDParser::alloc_node() {
|
||||
@ -116,6 +117,14 @@ bool GDParser::_parse_arguments(Node* p_parent,Vector<Node*>& p_args,bool p_stat
|
||||
if (tokenizer->get_token()==GDTokenizer::TK_CURSOR) {
|
||||
_make_completable_call(argidx);
|
||||
completion_node=p_parent;
|
||||
} else if (tokenizer->get_token()==GDTokenizer::TK_CONSTANT && tokenizer->get_token_constant().get_type()==Variant::STRING && tokenizer->get_token(1)==GDTokenizer::TK_CURSOR) {
|
||||
//completing a string argument..
|
||||
completion_cursor=tokenizer->get_token_constant();
|
||||
|
||||
_make_completable_call(argidx);
|
||||
completion_node=p_parent;
|
||||
tokenizer->advance(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
Node*arg = _parse_expression(p_parent,p_static);
|
||||
@ -277,7 +286,11 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_
|
||||
if (!validating) {
|
||||
|
||||
//this can be too slow for just validating code
|
||||
res = ResourceLoader::load(path);
|
||||
if (for_completion && ScriptCodeCompletionCache::get_sigleton()) {
|
||||
res = ScriptCodeCompletionCache::get_sigleton()->get_cached_resource(path);
|
||||
} else {
|
||||
res = ResourceLoader::load(path);
|
||||
}
|
||||
if (!res.is_valid()) {
|
||||
_set_error("Can't preload resource at path: "+path);
|
||||
return NULL;
|
||||
@ -2814,6 +2827,8 @@ Error GDParser::_parse(const String& p_base_path) {
|
||||
|
||||
Error GDParser::parse_bytecode(const Vector<uint8_t> &p_bytecode,const String& p_base_path, const String &p_self_path) {
|
||||
|
||||
for_completion=false;
|
||||
validating=false;
|
||||
completion_type=COMPLETION_NONE;
|
||||
completion_node=NULL;
|
||||
completion_class=NULL;
|
||||
@ -2834,7 +2849,7 @@ Error GDParser::parse_bytecode(const Vector<uint8_t> &p_bytecode,const String& p
|
||||
}
|
||||
|
||||
|
||||
Error GDParser::parse(const String& p_code, const String& p_base_path, bool p_just_validate, const String &p_self_path) {
|
||||
Error GDParser::parse(const String& p_code, const String& p_base_path, bool p_just_validate, const String &p_self_path,bool p_for_completion) {
|
||||
|
||||
completion_type=COMPLETION_NONE;
|
||||
completion_node=NULL;
|
||||
@ -2851,6 +2866,7 @@ Error GDParser::parse(const String& p_code, const String& p_base_path, bool p_ju
|
||||
tt->set_code(p_code);
|
||||
|
||||
validating=p_just_validate;
|
||||
for_completion=p_for_completion;
|
||||
tokenizer=tt;
|
||||
Error ret = _parse(p_base_path);
|
||||
memdelete(tt);
|
||||
@ -2886,6 +2902,7 @@ void GDParser::clear() {
|
||||
current_function=NULL;
|
||||
|
||||
validating=false;
|
||||
for_completion=false;
|
||||
error_set=false;
|
||||
tab_level.clear();
|
||||
tab_level.push_back(0);
|
||||
|
||||
@ -387,6 +387,7 @@ private:
|
||||
T* alloc_node();
|
||||
|
||||
bool validating;
|
||||
bool for_completion;
|
||||
int parenthesis;
|
||||
bool error_set;
|
||||
String error;
|
||||
@ -443,7 +444,7 @@ public:
|
||||
String get_error() const;
|
||||
int get_error_line() const;
|
||||
int get_error_column() const;
|
||||
Error parse(const String& p_code, const String& p_base_path="", bool p_just_validate=false,const String& p_self_path="");
|
||||
Error parse(const String& p_code, const String& p_base_path="", bool p_just_validate=false,const String& p_self_path="",bool p_for_completion=false);
|
||||
Error parse_bytecode(const Vector<uint8_t> &p_bytecode,const String& p_base_path="",const String& p_self_path="");
|
||||
|
||||
const Node *get_parse_tree() const;
|
||||
|
||||
@ -568,7 +568,10 @@ void GDTokenizerText::_advance() {
|
||||
} else if( string_mode!=STRING_MULTILINE && CharType(GETCHAR(i))=='\n') {
|
||||
_make_error("Unexpected EOL at String.");
|
||||
return;
|
||||
|
||||
} else if( CharType(GETCHAR(i))==0xFFFF) {
|
||||
//string ends here, next will be TK
|
||||
i--;
|
||||
break;
|
||||
} else if (CharType(GETCHAR(i))=='\\') {
|
||||
//escaped characters...
|
||||
i++;
|
||||
@ -670,19 +673,19 @@ void GDTokenizerText::_advance() {
|
||||
while(true) {
|
||||
if (GETCHAR(i)=='.') {
|
||||
if (period_found || exponent_found) {
|
||||
_make_error("Invalid numeric constant at '.'");
|
||||
_make_error("Invalid numeric constant at '.'");
|
||||
return;
|
||||
}
|
||||
period_found=true;
|
||||
} else if (GETCHAR(i)=='x') {
|
||||
if (hexa_found || str.length()!=1 || !( (i==1 && str[0]=='0') || (i==2 && str[1]=='0' && str[0]=='-') ) ) {
|
||||
_make_error("Invalid numeric constant at 'x'");
|
||||
if (hexa_found || str.length()!=1 || !( (i==1 && str[0]=='0') || (i==2 && str[1]=='0' && str[0]=='-') ) ) {
|
||||
_make_error("Invalid numeric constant at 'x'");
|
||||
return;
|
||||
}
|
||||
hexa_found=true;
|
||||
} else if (!hexa_found && GETCHAR(i)=='e') {
|
||||
} else if (!hexa_found && GETCHAR(i)=='e') {
|
||||
if (hexa_found || exponent_found) {
|
||||
_make_error("Invalid numeric constant at 'e'");
|
||||
_make_error("Invalid numeric constant at 'e'");
|
||||
return;
|
||||
}
|
||||
exponent_found=true;
|
||||
@ -692,7 +695,7 @@ void GDTokenizerText::_advance() {
|
||||
|
||||
} else if ((GETCHAR(i)=='-' || GETCHAR(i)=='+') && exponent_found) {
|
||||
if (sign_found) {
|
||||
_make_error("Invalid numeric constant at '-'");
|
||||
_make_error("Invalid numeric constant at '-'");
|
||||
return;
|
||||
}
|
||||
sign_found=true;
|
||||
@ -703,20 +706,20 @@ void GDTokenizerText::_advance() {
|
||||
i++;
|
||||
}
|
||||
|
||||
if (!( _is_number(str[str.length()-1]) || (hexa_found && _is_hex(str[str.length()-1])))) {
|
||||
_make_error("Invalid numeric constant: "+str);
|
||||
if (!( _is_number(str[str.length()-1]) || (hexa_found && _is_hex(str[str.length()-1])))) {
|
||||
_make_error("Invalid numeric constant: "+str);
|
||||
return;
|
||||
}
|
||||
|
||||
INCPOS(str.length());
|
||||
if (hexa_found) {
|
||||
int val = str.hex_to_int();
|
||||
_make_constant(val);
|
||||
} else if (period_found) {
|
||||
if (hexa_found) {
|
||||
int val = str.hex_to_int();
|
||||
_make_constant(val);
|
||||
} else if (period_found) {
|
||||
real_t val = str.to_double();
|
||||
//print_line("*%*%*%*% to convert: "+str+" result: "+rtos(val));
|
||||
_make_constant(val);
|
||||
} else {
|
||||
} else {
|
||||
int val = str.to_int();
|
||||
_make_constant(val);
|
||||
|
||||
@ -825,7 +828,7 @@ void GDTokenizerText::_advance() {
|
||||
|
||||
_make_built_in_func(GDFunctions::Function(i));
|
||||
found=true;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user