1 /*************************************************************************/
2 /* gd_editor.cpp */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* https://godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
9 /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
10 /* */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the */
13 /* "Software"), to deal in the Software without restriction, including */
14 /* without limitation the rights to use, copy, modify, merge, publish, */
15 /* distribute, sublicense, and/or sell copies of the Software, and to */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions: */
18 /* */
19 /* The above copyright notice and this permission notice shall be */
20 /* included in all copies or substantial portions of the Software. */
21 /* */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 /*************************************************************************/
30 #include "gd_compiler.h"
31 #include "gd_script.h"
32 #include "global_constants.h"
33 #include "globals.h"
34 #include "os/file_access.h"
35
get_comment_delimiters(List<String> * p_delimiters) const36 void GDScriptLanguage::get_comment_delimiters(List<String> *p_delimiters) const {
37
38 p_delimiters->push_back("#");
39 p_delimiters->push_back("\"\"\" \"\"\"");
40 }
get_string_delimiters(List<String> * p_delimiters) const41 void GDScriptLanguage::get_string_delimiters(List<String> *p_delimiters) const {
42
43 p_delimiters->push_back("\" \"");
44 p_delimiters->push_back("' '");
45 }
get_template(const String & p_class_name,const String & p_base_class_name) const46 String GDScriptLanguage::get_template(const String &p_class_name, const String &p_base_class_name) const {
47
48 String _template =
49 String() +
50 "extends %BASE%\n\n" +
51 "# class member variables go here, for example:\n" +
52 "# var a = 2\n" +
53 "# var b = \"textvar\"\n\n" +
54 "func _ready():\n" +
55 "\t# Called every time the node is added to the scene.\n" +
56 "\t# Initialization here\n" +
57 "\tpass\n";
58
59 return _template.replace("%BASE%", p_base_class_name);
60 }
61
get_empty_template(const String & p_class_name,const String & p_base_class_name) const62 String GDScriptLanguage::get_empty_template(const String &p_class_name, const String &p_base_class_name) const {
63
64 String _template = String() + "extends %BASE%\n\n";
65
66 return _template.replace("%BASE%", p_base_class_name);
67 }
68
get_nocomment_template(const String & p_class_name,const String & p_base_class_name) const69 String GDScriptLanguage::get_nocomment_template(const String &p_class_name, const String &p_base_class_name) const {
70
71 String _template =
72 String() +
73 "extends %BASE%\n\n" +
74 "func _ready():\n" +
75 "\tpass\n";
76
77 return _template.replace("%BASE%", p_base_class_name);
78 }
79
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) const80 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 {
81
82 GDParser parser;
83
84 Error err = parser.parse(p_script, p_path.get_base_dir(), true, p_path);
85 if (err) {
86 r_line_error = parser.get_error_line();
87 r_col_error = parser.get_error_column();
88 r_test_error = parser.get_error();
89 return false;
90 } else {
91
92 const GDParser::Node *root = parser.get_parse_tree();
93 ERR_FAIL_COND_V(root->type != GDParser::Node::TYPE_CLASS, false);
94
95 const GDParser::ClassNode *cl = static_cast<const GDParser::ClassNode *>(root);
96 Map<int, String> funcs;
97 for (int i = 0; i < cl->functions.size(); i++) {
98
99 funcs[cl->functions[i]->line] = cl->functions[i]->name;
100 }
101
102 for (int i = 0; i < cl->static_functions.size(); i++) {
103
104 funcs[cl->static_functions[i]->line] = cl->static_functions[i]->name;
105 }
106
107 for (Map<int, String>::Element *E = funcs.front(); E; E = E->next()) {
108
109 r_functions->push_back(E->get() + ":" + itos(E->key()));
110 }
111 }
112
113 return true;
114 }
115
has_named_classes() const116 bool GDScriptLanguage::has_named_classes() const {
117
118 return false;
119 }
120
find_function(const String & p_function,const String & p_code) const121 int GDScriptLanguage::find_function(const String &p_function, const String &p_code) const {
122
123 GDTokenizerText tokenizer;
124 tokenizer.set_code(p_code);
125 int indent = 0;
126 while (tokenizer.get_token() != GDTokenizer::TK_EOF && tokenizer.get_token() != GDTokenizer::TK_ERROR) {
127
128 if (tokenizer.get_token() == GDTokenizer::TK_NEWLINE) {
129 indent = tokenizer.get_token_line_indent();
130 }
131 //print_line("TOKEN: "+String(GDTokenizer::get_token_name(tokenizer.get_token())));
132 if (indent == 0 && tokenizer.get_token() == GDTokenizer::TK_PR_FUNCTION && tokenizer.get_token(1) == GDTokenizer::TK_IDENTIFIER) {
133
134 String identifier = tokenizer.get_token_identifier(1);
135 if (identifier == p_function) {
136 return tokenizer.get_token_line();
137 }
138 }
139 tokenizer.advance();
140 //print_line("NEXT: "+String(GDTokenizer::get_token_name(tokenizer.get_token())));
141 }
142 return -1;
143 }
144
create_script() const145 Script *GDScriptLanguage::create_script() const {
146
147 return memnew(GDScript);
148 }
149
150 /* DEBUGGER FUNCTIONS */
151
debug_break_parse(const String & p_file,int p_line,const String & p_error)152 bool GDScriptLanguage::debug_break_parse(const String &p_file, int p_line, const String &p_error) {
153 //break because of parse error
154
155 if (ScriptDebugger::get_singleton() && Thread::get_caller_ID() == Thread::get_main_ID()) {
156
157 _debug_parse_err_line = p_line;
158 _debug_parse_err_file = p_file;
159 _debug_error = p_error;
160 ScriptDebugger::get_singleton()->debug(this, false);
161 return true;
162 } else {
163 return false;
164 }
165 }
166
debug_break(const String & p_error,bool p_allow_continue)167 bool GDScriptLanguage::debug_break(const String &p_error, bool p_allow_continue) {
168
169 if (ScriptDebugger::get_singleton() && Thread::get_caller_ID() == Thread::get_main_ID()) {
170
171 _debug_parse_err_line = -1;
172 _debug_parse_err_file = "";
173 _debug_error = p_error;
174 ScriptDebugger::get_singleton()->debug(this, p_allow_continue);
175 return true;
176 } else {
177 return false;
178 }
179 }
180
debug_get_error() const181 String GDScriptLanguage::debug_get_error() const {
182
183 return _debug_error;
184 }
185
debug_get_stack_level_count() const186 int GDScriptLanguage::debug_get_stack_level_count() const {
187
188 if (_debug_parse_err_line >= 0)
189 return 1;
190
191 return _debug_call_stack_pos;
192 }
debug_get_stack_level_line(int p_level) const193 int GDScriptLanguage::debug_get_stack_level_line(int p_level) const {
194
195 if (_debug_parse_err_line >= 0)
196 return _debug_parse_err_line;
197
198 ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, -1);
199
200 int l = _debug_call_stack_pos - p_level - 1;
201
202 return *(_call_stack[l].line);
203 }
debug_get_stack_level_function(int p_level) const204 String GDScriptLanguage::debug_get_stack_level_function(int p_level) const {
205
206 if (_debug_parse_err_line >= 0)
207 return "";
208
209 ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, "");
210 int l = _debug_call_stack_pos - p_level - 1;
211 return _call_stack[l].function->get_name();
212 }
debug_get_stack_level_source(int p_level) const213 String GDScriptLanguage::debug_get_stack_level_source(int p_level) const {
214
215 if (_debug_parse_err_line >= 0)
216 return _debug_parse_err_file;
217
218 ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, "");
219 int l = _debug_call_stack_pos - p_level - 1;
220 return _call_stack[l].function->get_source();
221 }
debug_get_stack_level_locals(int p_level,List<String> * p_locals,List<Variant> * p_values,int p_max_subitems,int p_max_depth)222 void GDScriptLanguage::debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
223
224 if (_debug_parse_err_line >= 0)
225 return;
226
227 ERR_FAIL_INDEX(p_level, _debug_call_stack_pos);
228 int l = _debug_call_stack_pos - p_level - 1;
229
230 GDFunction *f = _call_stack[l].function;
231
232 List<Pair<StringName, int> > locals;
233
234 f->debug_get_stack_member_state(*_call_stack[l].line, &locals);
235 for (List<Pair<StringName, int> >::Element *E = locals.front(); E; E = E->next()) {
236
237 p_locals->push_back(E->get().first);
238 p_values->push_back(_call_stack[l].stack[E->get().second]);
239 }
240 }
debug_get_stack_level_members(int p_level,List<String> * p_members,List<Variant> * p_values,int p_max_subitems,int p_max_depth)241 void GDScriptLanguage::debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
242
243 if (_debug_parse_err_line >= 0)
244 return;
245
246 ERR_FAIL_INDEX(p_level, _debug_call_stack_pos);
247 int l = _debug_call_stack_pos - p_level - 1;
248
249 GDInstance *instance = _call_stack[l].instance;
250
251 if (!instance)
252 return;
253
254 Ref<GDScript> script = instance->get_script();
255 ERR_FAIL_COND(script.is_null());
256
257 const Map<StringName, GDScript::MemberInfo> &mi = script->debug_get_member_indices();
258
259 for (const Map<StringName, GDScript::MemberInfo>::Element *E = mi.front(); E; E = E->next()) {
260
261 p_members->push_back(E->key());
262 p_values->push_back(instance->debug_get_member_by_index(E->get().index));
263 }
264 }
265
debug_get_stack_level_instance(int p_level)266 ScriptInstance *GDScriptLanguage::debug_get_stack_level_instance(int p_level) {
267
268 ERR_FAIL_COND_V(_debug_parse_err_line >= 0, NULL);
269 ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, NULL);
270
271 int l = _debug_call_stack_pos - p_level - 1;
272 GDInstance *instance = _call_stack[l].instance;
273
274 return instance;
275 }
276
debug_get_globals(List<String> * p_globals,List<Variant> * p_values,int p_max_subitems,int p_max_depth)277 void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
278
279 const Map<StringName, int> &name_idx = GDScriptLanguage::get_singleton()->get_global_map();
280 const Variant *globals = GDScriptLanguage::get_singleton()->get_global_array();
281
282 for (const Map<StringName, int>::Element *E = name_idx.front(); E; E = E->next()) {
283
284 if (ObjectTypeDB::type_exists(E->key()) || Globals::get_singleton()->has_singleton(E->key()) || E->key() == "PI")
285 continue;
286
287 const Variant &var = globals[E->value()];
288 if (Object *obj = var) {
289 if (obj->cast_to<GDNativeClass>())
290 continue;
291 }
292
293 bool skip = false;
294 for (int i = 0; i < GlobalConstants::get_global_constant_count(); i++) {
295 if (E->key() == GlobalConstants::get_global_constant_name(i)) {
296 skip = true;
297 break;
298 }
299 }
300 if (skip)
301 continue;
302
303 p_globals->push_back(E->key());
304 p_values->push_back(var);
305 }
306 }
debug_parse_stack_level_expression(int p_level,const String & p_expression,int p_max_subitems,int p_max_depth)307 String GDScriptLanguage::debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) {
308
309 if (_debug_parse_err_line >= 0)
310 return "";
311 return "";
312 }
313
get_recognized_extensions(List<String> * p_extensions) const314 void GDScriptLanguage::get_recognized_extensions(List<String> *p_extensions) const {
315
316 p_extensions->push_back("gd");
317 }
318
get_public_functions(List<MethodInfo> * p_functions) const319 void GDScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const {
320
321 for (int i = 0; i < GDFunctions::FUNC_MAX; i++) {
322
323 p_functions->push_back(GDFunctions::get_info(GDFunctions::Function(i)));
324 }
325
326 //not really "functions", but..
327 {
328 MethodInfo mi;
329 mi.name = "preload:Resource";
330 mi.arguments.push_back(PropertyInfo(Variant::STRING, "path"));
331 mi.return_val = PropertyInfo(Variant::OBJECT, "", PROPERTY_HINT_RESOURCE_TYPE, "Resource");
332 p_functions->push_back(mi);
333 }
334 {
335 MethodInfo mi;
336 mi.name = "yield:GDFunctionState";
337 mi.arguments.push_back(PropertyInfo(Variant::OBJECT, "object"));
338 mi.arguments.push_back(PropertyInfo(Variant::STRING, "signal"));
339 mi.default_arguments.push_back(Variant::NIL);
340 mi.default_arguments.push_back(Variant::STRING);
341 p_functions->push_back(mi);
342 }
343 {
344 MethodInfo mi;
345 mi.name = "assert";
346 mi.arguments.push_back(PropertyInfo(Variant::BOOL, "condition"));
347 p_functions->push_back(mi);
348 }
349 }
350
get_public_constants(List<Pair<String,Variant>> * p_constants) const351 void GDScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_constants) const {
352
353 Pair<String, Variant> pi;
354 pi.first = "PI";
355 pi.second = Math_PI;
356 p_constants->push_back(pi);
357 }
358
make_function(const String & p_class,const String & p_name,const StringArray & p_args) const359 String GDScriptLanguage::make_function(const String &p_class, const String &p_name, const StringArray &p_args) const {
360
361 String s = "func " + p_name + "(";
362 if (p_args.size()) {
363 s += " ";
364 for (int i = 0; i < p_args.size(); i++) {
365 if (i > 0)
366 s += ", ";
367 s += p_args[i];
368 }
369 s += " ";
370 }
371 s += "):\n\tpass # replace with function body\n";
372
373 return s;
374 }
375
376 #if defined(DEBUG_METHODS_ENABLED) && defined(TOOLS_ENABLED)
377
378 struct GDCompletionIdentifier {
379
380 StringName obj_type;
381 Ref<GDScript> script;
382 Variant::Type type;
383 Variant value; //im case there is a value, also return it
384 };
385
_get_type_from_variant(const Variant & p_variant)386 static GDCompletionIdentifier _get_type_from_variant(const Variant &p_variant) {
387
388 GDCompletionIdentifier t;
389 t.type = p_variant.get_type();
390 t.value = p_variant;
391 if (p_variant.get_type() == Variant::OBJECT) {
392 Object *obj = p_variant;
393 if (obj) {
394 //if (obj->cast_to<GDNativeClass>()) {
395 // t.obj_type=obj->cast_to<GDNativeClass>()->get_name();
396 // t.value=Variant();
397 //} else {
398 t.obj_type = obj->get_type();
399 //}
400 }
401 }
402 return t;
403 }
404
_get_type_from_pinfo(const PropertyInfo & p_info)405 static GDCompletionIdentifier _get_type_from_pinfo(const PropertyInfo &p_info) {
406
407 GDCompletionIdentifier t;
408 t.type = p_info.type;
409 if (p_info.hint == PROPERTY_HINT_RESOURCE_TYPE) {
410 t.obj_type = p_info.hint_string;
411 }
412 return t;
413 }
414
415 struct GDCompletionContext {
416
417 const GDParser::ClassNode *_class;
418 const GDParser::FunctionNode *function;
419 const GDParser::BlockNode *block;
420 Object *base;
421 String base_path;
422 };
423
_get_parent_class(GDCompletionContext & context)424 static Ref<Reference> _get_parent_class(GDCompletionContext &context) {
425
426 if (context._class->extends_used) {
427 //do inheritance
428 String path = context._class->extends_file;
429
430 Ref<GDScript> script;
431 Ref<GDNativeClass> native;
432
433 if (path != "") {
434 //path (and optionally subclasses)
435
436 if (path.is_rel_path()) {
437
438 path = context.base_path.plus_file(path);
439 }
440
441 if (ScriptCodeCompletionCache::get_sigleton())
442 script = ScriptCodeCompletionCache::get_sigleton()->get_cached_resource(path);
443 else
444 script = ResourceLoader::load(path);
445
446 if (script.is_null()) {
447 return REF();
448 }
449 if (!script->is_valid()) {
450
451 return REF();
452 }
453 //print_line("EXTENDS PATH: "+path+" script is "+itos(script.is_valid())+" indices is "+itos(script->member_indices.size())+" valid? "+itos(script->valid));
454
455 if (context._class->extends_class.size()) {
456
457 for (int i = 0; i < context._class->extends_class.size(); i++) {
458
459 String sub = context._class->extends_class[i];
460 if (script->get_subclasses().has(sub)) {
461
462 script = script->get_subclasses()[sub];
463 } else {
464
465 return REF();
466 }
467 }
468 }
469
470 if (script.is_valid())
471 return script;
472
473 } else {
474
475 if (context._class->extends_class.size() == 0) {
476 ERR_PRINT("BUG");
477 return REF();
478 }
479
480 String base = context._class->extends_class[0];
481
482 if (context._class->extends_class.size() > 1) {
483
484 return REF();
485 }
486 //if not found, try engine classes
487 if (!GDScriptLanguage::get_singleton()->get_global_map().has(base)) {
488
489 return REF();
490 }
491
492 int base_idx = GDScriptLanguage::get_singleton()->get_global_map()[base];
493 native = GDScriptLanguage::get_singleton()->get_global_array()[base_idx];
494 return native;
495 }
496 }
497
498 return Ref<Reference>();
499 }
500
_get_native_class(GDCompletionContext & context)501 static GDCompletionIdentifier _get_native_class(GDCompletionContext &context) {
502
503 //eeh...
504 GDCompletionIdentifier id;
505 id.type = Variant::NIL;
506
507 REF pc = _get_parent_class(context);
508 if (!pc.is_valid()) {
509 return id;
510 }
511 Ref<GDNativeClass> nc = pc;
512 Ref<GDScript> s = pc;
513
514 if (s.is_null() && nc.is_null()) {
515 return id;
516 }
517 while (!s.is_null()) {
518 nc = s->get_native();
519 s = s->get_base();
520 }
521 if (nc.is_null()) {
522 return id;
523 }
524
525 id.type = Variant::OBJECT;
526 if (context.base)
527 id.value = context.base;
528 id.obj_type = nc->get_name();
529 return id;
530 }
531
532 static bool _guess_identifier_type(GDCompletionContext &context, int p_line, const StringName &p_identifier, GDCompletionIdentifier &r_type);
533
_guess_expression_type(GDCompletionContext & context,const GDParser::Node * p_node,int p_line,GDCompletionIdentifier & r_type)534 static bool _guess_expression_type(GDCompletionContext &context, const GDParser::Node *p_node, int p_line, GDCompletionIdentifier &r_type) {
535
536 if (p_node->type == GDParser::Node::TYPE_CONSTANT) {
537
538 const GDParser::ConstantNode *cn = static_cast<const GDParser::ConstantNode *>(p_node);
539
540 r_type = _get_type_from_variant(cn->value);
541
542 return true;
543 } else if (p_node->type == GDParser::Node::TYPE_DICTIONARY) {
544
545 r_type.type = Variant::DICTIONARY;
546
547 //what the heck, fill it anyway
548 const GDParser::DictionaryNode *an = static_cast<const GDParser::DictionaryNode *>(p_node);
549 Dictionary d;
550 for (int i = 0; i < an->elements.size(); i++) {
551 GDCompletionIdentifier k;
552 if (_guess_expression_type(context, an->elements[i].key, p_line, k) && k.value.get_type() != Variant::NIL) {
553 GDCompletionIdentifier v;
554 if (_guess_expression_type(context, an->elements[i].value, p_line, v)) {
555 d[k.value] = v.value;
556 }
557 }
558 }
559 r_type.value = d;
560 return true;
561 } else if (p_node->type == GDParser::Node::TYPE_ARRAY) {
562
563 r_type.type = Variant::ARRAY;
564 //what the heck, fill it anyway
565 const GDParser::ArrayNode *an = static_cast<const GDParser::ArrayNode *>(p_node);
566 Array arr;
567 arr.resize(an->elements.size());
568 for (int i = 0; i < an->elements.size(); i++) {
569 GDCompletionIdentifier ci;
570 if (_guess_expression_type(context, an->elements[i], p_line, ci)) {
571 arr[i] = ci.value;
572 }
573 }
574 r_type.value = arr;
575 return true;
576
577 } else if (p_node->type == GDParser::Node::TYPE_BUILT_IN_FUNCTION) {
578
579 MethodInfo mi = GDFunctions::get_info(static_cast<const GDParser::BuiltInFunctionNode *>(p_node)->function);
580 r_type = _get_type_from_pinfo(mi.return_val);
581
582 return true;
583 } else if (p_node->type == GDParser::Node::TYPE_IDENTIFIER) {
584
585 return _guess_identifier_type(context, p_line - 1, static_cast<const GDParser::IdentifierNode *>(p_node)->name, r_type);
586 } else if (p_node->type == GDParser::Node::TYPE_SELF) {
587 //eeh...
588
589 r_type = _get_native_class(context);
590 return r_type.type != Variant::NIL;
591
592 } else if (p_node->type == GDParser::Node::TYPE_OPERATOR) {
593
594 const GDParser::OperatorNode *op = static_cast<const GDParser::OperatorNode *>(p_node);
595 if (op->op == GDParser::OperatorNode::OP_CALL) {
596 if (op->arguments[0]->type == GDParser::Node::TYPE_TYPE) {
597
598 const GDParser::TypeNode *tn = static_cast<const GDParser::TypeNode *>(op->arguments[0]);
599 r_type.type = tn->vtype;
600 return true;
601 } else if (op->arguments[0]->type == GDParser::Node::TYPE_BUILT_IN_FUNCTION) {
602
603 const GDParser::BuiltInFunctionNode *bin = static_cast<const GDParser::BuiltInFunctionNode *>(op->arguments[0]);
604 return _guess_expression_type(context, bin, p_line, r_type);
605
606 } else if (op->arguments.size() > 1 && op->arguments[1]->type == GDParser::Node::TYPE_IDENTIFIER) {
607
608 GDCompletionIdentifier base;
609 if (!_guess_expression_type(context, op->arguments[0], p_line, base))
610 return false;
611
612 StringName id = static_cast<const GDParser::IdentifierNode *>(op->arguments[1])->name;
613
614 if (base.type == Variant::OBJECT) {
615
616 if (id.operator String() == "new" && base.value.get_type() == Variant::OBJECT) {
617 Object *obj = base.value;
618 if (obj && obj->cast_to<GDNativeClass>()) {
619 GDNativeClass *gdnc = obj->cast_to<GDNativeClass>();
620 r_type.type = Variant::OBJECT;
621 r_type.value = Variant();
622 r_type.obj_type = gdnc->get_name();
623 return true;
624 }
625 }
626
627 if (ObjectTypeDB::has_method(base.obj_type, id)) {
628
629 #ifdef TOOLS_ENABLED
630 MethodBind *mb = ObjectTypeDB::get_method(base.obj_type, id);
631 PropertyInfo pi = mb->get_argument_info(-1);
632
633 //try calling the function if constant and all args are constant, should not crash..
634 Object *baseptr = base.value;
635
636 if (mb->is_const() && pi.type == Variant::OBJECT) {
637
638 bool all_valid = true;
639 Vector<Variant> args;
640 for (int i = 2; i < op->arguments.size(); i++) {
641 GDCompletionIdentifier arg;
642
643 if (_guess_expression_type(context, op->arguments[i], p_line, arg)) {
644 if (arg.value.get_type() != Variant::NIL && arg.value.get_type() != Variant::OBJECT) { // calling with object seems dangerous, i don' t know
645 args.push_back(arg.value);
646 } else {
647 all_valid = false;
648 break;
649 }
650 } else {
651 all_valid = false;
652 }
653 }
654
655 if (all_valid && String(id) == "get_node" && ObjectTypeDB::is_type(base.obj_type, "Node") && args.size()) {
656
657 String arg1 = args[0];
658 if (arg1.begins_with("/root/")) {
659 String which = arg1.get_slice("/", 2);
660 if (which != "") {
661 List<PropertyInfo> props;
662 Globals::get_singleton()->get_property_list(&props);
663 //print_line("find singleton");
664
665 for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
666
667 String s = E->get().name;
668 if (!s.begins_with("autoload/"))
669 continue;
670 //print_line("found "+s);
671 String name = s.get_slice("/", 1);
672 //print_line("name: "+name+", which: "+which);
673 if (name == which) {
674 String script = Globals::get_singleton()->get(s);
675
676 if (!script.begins_with("res://")) {
677 script = "res://" + script;
678 }
679
680 if (!script.ends_with(".gd")) {
681 //not a script, try find the script anyway,
682 //may have some success
683 script = script.basename() + ".gd";
684 }
685
686 if (FileAccess::exists(script)) {
687
688 //print_line("is a script");
689
690 Ref<Script> scr;
691 if (ScriptCodeCompletionCache::get_sigleton())
692 scr = ScriptCodeCompletionCache::get_sigleton()->get_cached_resource(script);
693 else
694 scr = ResourceLoader::load(script);
695
696 r_type.obj_type = "Node";
697 r_type.type = Variant::OBJECT;
698 r_type.script = scr;
699 r_type.value = Variant();
700
701 return true;
702 }
703 }
704 }
705 }
706 }
707 }
708
709 if (baseptr) {
710
711 if (all_valid) {
712 Vector<const Variant *> argptr;
713 for (int i = 0; i < args.size(); i++) {
714 argptr.push_back(&args[i]);
715 }
716
717 Variant::CallError ce;
718 Variant ret = mb->call(baseptr, argptr.ptr(), argptr.size(), ce);
719
720 if (ce.error == Variant::CallError::CALL_OK && ret.get_type() != Variant::NIL) {
721
722 if (ret.get_type() != Variant::OBJECT || ret.operator Object *() != NULL) {
723
724 r_type = _get_type_from_variant(ret);
725 return true;
726 }
727 }
728 }
729 }
730 }
731
732 r_type.type = pi.type;
733 if (pi.hint == PROPERTY_HINT_RESOURCE_TYPE) {
734 r_type.obj_type = pi.hint_string;
735 }
736
737 return true;
738 #else
739 return false;
740 #endif
741 } else {
742 return false;
743 }
744 } else {
745 //method for some variant..
746 Variant::CallError ce;
747 Variant v = Variant::construct(base.type, NULL, 0, ce);
748 List<MethodInfo> mi;
749 v.get_method_list(&mi);
750 for (List<MethodInfo>::Element *E = mi.front(); E; E = E->next()) {
751
752 if (!E->get().name.begins_with("_") && E->get().name == id.operator String()) {
753
754 MethodInfo mi = E->get();
755 r_type.type = mi.return_val.type;
756 if (mi.return_val.hint == PROPERTY_HINT_RESOURCE_TYPE) {
757 r_type.obj_type = mi.return_val.hint_string;
758 }
759 return true;
760 }
761 }
762 }
763 }
764 } else if (op->op == GDParser::OperatorNode::OP_INDEX || op->op == GDParser::OperatorNode::OP_INDEX_NAMED) {
765
766 GDCompletionIdentifier p1;
767 GDCompletionIdentifier p2;
768
769 if (op->op == GDParser::OperatorNode::OP_INDEX_NAMED) {
770
771 if (op->arguments[1]->type == GDParser::Node::TYPE_IDENTIFIER) {
772 String id = static_cast<const GDParser::IdentifierNode *>(op->arguments[1])->name;
773 p2.type = Variant::STRING;
774 p2.value = id;
775 }
776
777 } else {
778 if (op->arguments[1]) {
779 if (!_guess_expression_type(context, op->arguments[1], p_line, p2)) {
780
781 return false;
782 }
783 }
784 }
785
786 if (op->arguments[0]->type == GDParser::Node::TYPE_ARRAY) {
787
788 const GDParser::ArrayNode *an = static_cast<const GDParser::ArrayNode *>(op->arguments[0]);
789 if (p2.value.is_num()) {
790 int index = p2.value;
791 if (index < 0 || index >= an->elements.size())
792 return false;
793 return _guess_expression_type(context, an->elements[index], p_line, r_type);
794 }
795
796 } else if (op->arguments[0]->type == GDParser::Node::TYPE_DICTIONARY) {
797
798 const GDParser::DictionaryNode *dn = static_cast<const GDParser::DictionaryNode *>(op->arguments[0]);
799
800 if (p2.value.get_type() == Variant::NIL)
801 return false;
802
803 for (int i = 0; i < dn->elements.size(); i++) {
804
805 GDCompletionIdentifier k;
806
807 if (!_guess_expression_type(context, dn->elements[i].key, p_line, k)) {
808
809 return false;
810 }
811
812 if (k.value.get_type() == Variant::NIL)
813 return false;
814
815 if (k.value == p2.value) {
816
817 return _guess_expression_type(context, dn->elements[i].value, p_line, r_type);
818 }
819 }
820
821 } else {
822
823 if (op->arguments[0]) {
824 if (!_guess_expression_type(context, op->arguments[0], p_line, p1)) {
825
826 return false;
827 }
828 }
829
830 if (p1.value.get_type() == Variant::OBJECT) {
831 //??
832 } else if (p1.value.get_type() != Variant::NIL) {
833
834 bool valid;
835 Variant ret = p1.value.get(p2.value, &valid);
836 if (valid) {
837 r_type = _get_type_from_variant(ret);
838 return true;
839 }
840
841 } else {
842 if (p1.type != Variant::NIL) {
843 Variant::CallError ce;
844 Variant base = Variant::construct(p1.type, NULL, 0, ce);
845 bool valid;
846 Variant ret = base.get(p2.value, &valid);
847 if (valid) {
848 r_type = _get_type_from_variant(ret);
849 return true;
850 }
851 }
852 }
853 }
854
855 } else {
856
857 Variant::Operator vop = Variant::OP_MAX;
858 switch (op->op) {
859 case GDParser::OperatorNode::OP_ADD: vop = Variant::OP_ADD; break;
860 case GDParser::OperatorNode::OP_SUB: vop = Variant::OP_SUBSTRACT; break;
861 case GDParser::OperatorNode::OP_MUL: vop = Variant::OP_MULTIPLY; break;
862 case GDParser::OperatorNode::OP_DIV: vop = Variant::OP_DIVIDE; break;
863 case GDParser::OperatorNode::OP_MOD: vop = Variant::OP_MODULE; break;
864 case GDParser::OperatorNode::OP_SHIFT_LEFT: vop = Variant::OP_SHIFT_LEFT; break;
865 case GDParser::OperatorNode::OP_SHIFT_RIGHT: vop = Variant::OP_SHIFT_RIGHT; break;
866 case GDParser::OperatorNode::OP_BIT_AND: vop = Variant::OP_BIT_AND; break;
867 case GDParser::OperatorNode::OP_BIT_OR: vop = Variant::OP_BIT_OR; break;
868 case GDParser::OperatorNode::OP_BIT_XOR: vop = Variant::OP_BIT_XOR; break;
869 default: {}
870 }
871
872 if (vop == Variant::OP_MAX)
873 return false;
874
875 GDCompletionIdentifier p1;
876 GDCompletionIdentifier p2;
877
878 if (op->arguments[0]) {
879 if (!_guess_expression_type(context, op->arguments[0], p_line, p1)) {
880
881 return false;
882 }
883 }
884
885 if (op->arguments.size() > 1) {
886 if (!_guess_expression_type(context, op->arguments[1], p_line, p2)) {
887
888 return false;
889 }
890 }
891
892 Variant::CallError ce;
893 bool v1_use_value = p1.value.get_type() != Variant::NIL && p1.value.get_type() != Variant::OBJECT;
894 Variant v1 = (v1_use_value) ? p1.value : Variant::construct(p1.type, NULL, 0, ce);
895 bool v2_use_value = p2.value.get_type() != Variant::NIL && p2.value.get_type() != Variant::OBJECT;
896 Variant v2 = (v2_use_value) ? p2.value : Variant::construct(p2.type, NULL, 0, ce);
897 // avoid potential invalid ops
898 if ((vop == Variant::OP_DIVIDE || vop == Variant::OP_MODULE) && v2.get_type() == Variant::INT) {
899 v2 = 1;
900 v2_use_value = false;
901 }
902 if (vop == Variant::OP_DIVIDE && v2.get_type() == Variant::REAL) {
903 v2 = 1.0;
904 v2_use_value = false;
905 }
906
907 Variant r;
908 bool valid;
909 Variant::evaluate(vop, v1, v2, r, valid);
910 if (!valid)
911 return false;
912 r_type.type = r.get_type();
913 if (v1_use_value && v2_use_value)
914 r_type.value = r;
915
916 return true;
917 }
918 }
919
920 return false;
921 }
922
_guess_identifier_type_in_block(GDCompletionContext & context,int p_line,const StringName & p_identifier,GDCompletionIdentifier & r_type)923 static bool _guess_identifier_type_in_block(GDCompletionContext &context, int p_line, const StringName &p_identifier, GDCompletionIdentifier &r_type) {
924
925 const GDParser::Node *last_assign = NULL;
926 int last_assign_line = -1;
927
928 for (int i = 0; i < context.block->statements.size(); i++) {
929
930 if (context.block->statements[i]->line > p_line)
931 continue;
932
933 if (context.block->statements[i]->type == GDParser::BlockNode::TYPE_LOCAL_VAR) {
934
935 const GDParser::LocalVarNode *lv = static_cast<const GDParser::LocalVarNode *>(context.block->statements[i]);
936
937 if (lv->assign && lv->name == p_identifier) {
938
939 last_assign = lv->assign;
940 last_assign_line = context.block->statements[i]->line;
941 }
942 }
943
944 if (context.block->statements[i]->type == GDParser::BlockNode::TYPE_OPERATOR) {
945 const GDParser::OperatorNode *op = static_cast<const GDParser::OperatorNode *>(context.block->statements[i]);
946 if (op->op == GDParser::OperatorNode::OP_ASSIGN) {
947
948 if (op->arguments.size() && op->arguments[0]->type == GDParser::Node::TYPE_IDENTIFIER) {
949
950 const GDParser::IdentifierNode *id = static_cast<const GDParser::IdentifierNode *>(op->arguments[0]);
951
952 if (id->name == p_identifier) {
953
954 last_assign = op->arguments[1];
955 last_assign_line = context.block->statements[i]->line;
956 }
957 }
958 }
959 }
960 }
961
962 //use the last assignment, (then backwards?)
963 if (last_assign) {
964
965 return _guess_expression_type(context, last_assign, last_assign_line, r_type);
966 }
967
968 return false;
969 }
970
_guess_identifier_from_assignment_in_function(GDCompletionContext & context,int p_src_line,const StringName & p_identifier,const StringName & p_function,GDCompletionIdentifier & r_type)971 static bool _guess_identifier_from_assignment_in_function(GDCompletionContext &context, int p_src_line, const StringName &p_identifier, const StringName &p_function, GDCompletionIdentifier &r_type) {
972
973 const GDParser::FunctionNode *func = NULL;
974 for (int i = 0; i < context._class->functions.size(); i++) {
975 if (context._class->functions[i]->name == p_function) {
976 func = context._class->functions[i];
977 break;
978 }
979 }
980
981 if (!func)
982 return false;
983
984 for (int i = 0; i < func->body->statements.size(); i++) {
985
986 if (func->body->statements[i]->line == p_src_line) {
987 break;
988 }
989
990 if (func->body->statements[i]->type == GDParser::BlockNode::TYPE_OPERATOR) {
991 const GDParser::OperatorNode *op = static_cast<const GDParser::OperatorNode *>(func->body->statements[i]);
992 if (op->op == GDParser::OperatorNode::OP_ASSIGN) {
993
994 if (op->arguments.size() && op->arguments[0]->type == GDParser::Node::TYPE_IDENTIFIER) {
995
996 const GDParser::IdentifierNode *id = static_cast<const GDParser::IdentifierNode *>(op->arguments[0]);
997
998 if (id->name == p_identifier) {
999
1000 return _guess_expression_type(context, op->arguments[1], func->body->statements[i]->line, r_type);
1001 }
1002 }
1003 }
1004 }
1005 }
1006
1007 return false;
1008 }
1009
_guess_identifier_type(GDCompletionContext & context,int p_line,const StringName & p_identifier,GDCompletionIdentifier & r_type)1010 static bool _guess_identifier_type(GDCompletionContext &context, int p_line, const StringName &p_identifier, GDCompletionIdentifier &r_type) {
1011
1012 //go to block first
1013
1014 const GDParser::BlockNode *block = context.block;
1015
1016 while (block) {
1017
1018 GDCompletionContext c = context;
1019 c.block = block;
1020
1021 if (_guess_identifier_type_in_block(c, p_line, p_identifier, r_type)) {
1022 return true;
1023 }
1024
1025 block = block->parent_block;
1026 }
1027
1028 //guess from argument if virtual
1029 if (context.function && context.function->name != StringName()) {
1030
1031 int argindex = -1;
1032
1033 for (int i = 0; i < context.function->arguments.size(); i++) {
1034
1035 if (context.function->arguments[i] == p_identifier) {
1036 argindex = i;
1037 break;
1038 }
1039 }
1040
1041 if (argindex != -1) {
1042 GDCompletionIdentifier id = _get_native_class(context);
1043 if (id.type == Variant::OBJECT && id.obj_type != StringName()) {
1044 //this kinda sucks but meh
1045
1046 List<MethodInfo> vmethods;
1047 ObjectTypeDB::get_virtual_methods(id.obj_type, &vmethods);
1048 for (List<MethodInfo>::Element *E = vmethods.front(); E; E = E->next()) {
1049
1050 if (E->get().name == context.function->name && argindex < E->get().arguments.size()) {
1051
1052 PropertyInfo arg = E->get().arguments[argindex];
1053
1054 int scp = arg.name.find(":");
1055 if (scp != -1) {
1056
1057 r_type.type = Variant::OBJECT;
1058 r_type.obj_type = arg.name.substr(scp + 1, arg.name.length());
1059 return true;
1060
1061 } else {
1062
1063 r_type.type = arg.type;
1064 if (arg.hint == PROPERTY_HINT_RESOURCE_TYPE)
1065 r_type.obj_type = arg.hint_string;
1066 return true;
1067 }
1068 }
1069 }
1070 }
1071 }
1072 }
1073
1074 //guess type in constant
1075
1076 for (int i = 0; i < context._class->constant_expressions.size(); i++) {
1077
1078 if (context._class->constant_expressions[i].identifier == p_identifier) {
1079
1080 ERR_FAIL_COND_V(context._class->constant_expressions[i].expression->type != GDParser::Node::TYPE_CONSTANT, false);
1081 r_type = _get_type_from_variant(static_cast<const GDParser::ConstantNode *>(context._class->constant_expressions[i].expression)->value);
1082 return true;
1083 }
1084 }
1085
1086 if (!(context.function && context.function->_static)) {
1087
1088 for (int i = 0; i < context._class->variables.size(); i++) {
1089
1090 if (context._class->variables[i].identifier == p_identifier) {
1091
1092 if (context._class->variables[i]._export.type != Variant::NIL) {
1093
1094 r_type = _get_type_from_pinfo(context._class->variables[i]._export);
1095 return true;
1096 } else if (context._class->variables[i].expression) {
1097
1098 bool rtype = _guess_expression_type(context, context._class->variables[i].expression, context._class->variables[i].line, r_type);
1099 if (rtype && r_type.type != Variant::NIL)
1100 return true;
1101 //return _guess_expression_type(context,context._class->variables[i].expression,context._class->variables[i].line,r_type);
1102 }
1103
1104 //try to guess from assignment in construtor or _ready
1105 if (_guess_identifier_from_assignment_in_function(context, p_line + 1, p_identifier, "_ready", r_type))
1106 return true;
1107 if (_guess_identifier_from_assignment_in_function(context, p_line + 1, p_identifier, "_enter_tree", r_type))
1108 return true;
1109 if (_guess_identifier_from_assignment_in_function(context, p_line + 1, p_identifier, "_init", r_type))
1110 return true;
1111
1112 return false;
1113 }
1114 }
1115 }
1116
1117 //autoloads as singletons
1118 List<PropertyInfo> props;
1119 Globals::get_singleton()->get_property_list(&props);
1120
1121 for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
1122
1123 String s = E->get().name;
1124 if (!s.begins_with("autoload/"))
1125 continue;
1126 String name = s.get_slice("/", 1);
1127 if (name == String(p_identifier)) {
1128
1129 String path = Globals::get_singleton()->get(s);
1130 if (path.begins_with("*")) {
1131 String script = path.substr(1, path.length());
1132
1133 if (!script.ends_with(".gd")) {
1134 //not a script, try find the script anyway,
1135 //may have some success
1136 script = script.basename() + ".gd";
1137 }
1138
1139 if (FileAccess::exists(script)) {
1140
1141 //print_line("is a script");
1142
1143 Ref<Script> scr;
1144 if (ScriptCodeCompletionCache::get_sigleton())
1145 scr = ScriptCodeCompletionCache::get_sigleton()->get_cached_resource(script);
1146 else
1147 scr = ResourceLoader::load(script);
1148
1149 r_type.obj_type = "Node";
1150 r_type.type = Variant::OBJECT;
1151 r_type.script = scr;
1152 r_type.value = Variant();
1153
1154 return true;
1155 }
1156 }
1157 }
1158 }
1159
1160 //global
1161 for (Map<StringName, int>::Element *E = GDScriptLanguage::get_singleton()->get_global_map().front(); E; E = E->next()) {
1162 if (E->key() == p_identifier) {
1163
1164 r_type = _get_type_from_variant(GDScriptLanguage::get_singleton()->get_global_array()[E->get()]);
1165 return true;
1166 }
1167 }
1168 return false;
1169 }
1170
_find_identifiers_in_block(GDCompletionContext & context,int p_line,bool p_only_functions,Set<String> & result)1171 static void _find_identifiers_in_block(GDCompletionContext &context, int p_line, bool p_only_functions, Set<String> &result) {
1172
1173 if (p_only_functions)
1174 return;
1175
1176 for (int i = 0; i < context.block->statements.size(); i++) {
1177
1178 if (context.block->statements[i]->line > p_line)
1179 continue;
1180
1181 if (context.block->statements[i]->type == GDParser::BlockNode::TYPE_LOCAL_VAR) {
1182
1183 const GDParser::LocalVarNode *lv = static_cast<const GDParser::LocalVarNode *>(context.block->statements[i]);
1184 result.insert(lv->name.operator String());
1185 }
1186 }
1187 }
1188
_find_identifiers_in_class(GDCompletionContext & context,bool p_static,bool p_only_functions,Set<String> & result)1189 static void _find_identifiers_in_class(GDCompletionContext &context, bool p_static, bool p_only_functions, Set<String> &result) {
1190
1191 if (!p_static && !p_only_functions) {
1192
1193 for (int i = 0; i < context._class->variables.size(); i++) {
1194 result.insert(context._class->variables[i].identifier);
1195 }
1196 }
1197 if (!p_only_functions) {
1198
1199 for (int i = 0; i < context._class->constant_expressions.size(); i++) {
1200 result.insert(context._class->constant_expressions[i].identifier);
1201 }
1202
1203 for (int i = 0; i < context._class->subclasses.size(); i++) {
1204 result.insert(context._class->subclasses[i]->name);
1205 }
1206 }
1207
1208 for (int i = 0; i < context._class->static_functions.size(); i++) {
1209 if (context._class->static_functions[i]->arguments.size())
1210 result.insert(context._class->static_functions[i]->name.operator String() + "(");
1211 else
1212 result.insert(context._class->static_functions[i]->name.operator String() + "()");
1213 }
1214
1215 if (!p_static) {
1216
1217 for (int i = 0; i < context._class->functions.size(); i++) {
1218 if (context._class->functions[i]->arguments.size())
1219 result.insert(context._class->functions[i]->name.operator String() + "(");
1220 else
1221 result.insert(context._class->functions[i]->name.operator String() + "()");
1222 }
1223 }
1224
1225 //globals
1226
1227 Ref<Reference> base = _get_parent_class(context);
1228
1229 while (true) {
1230
1231 Ref<GDScript> script = base;
1232 Ref<GDNativeClass> nc = base;
1233 if (script.is_valid()) {
1234
1235 if (!p_static && !p_only_functions) {
1236 for (const Set<StringName>::Element *E = script->get_members().front(); E; E = E->next()) {
1237 result.insert(E->get().operator String());
1238 }
1239 }
1240
1241 if (!p_only_functions) {
1242 for (const Map<StringName, Variant>::Element *E = script->get_constants().front(); E; E = E->next()) {
1243 result.insert(E->key().operator String());
1244 }
1245 }
1246
1247 for (const Map<StringName, GDFunction *>::Element *E = script->get_member_functions().front(); E; E = E->next()) {
1248 if (!p_static || E->get()->is_static()) {
1249 if (E->get()->get_argument_count())
1250 result.insert(E->key().operator String() + "(");
1251 else
1252 result.insert(E->key().operator String() + "()");
1253 }
1254 }
1255
1256 if (!p_only_functions) {
1257 for (const Map<StringName, Ref<GDScript> >::Element *E = script->get_subclasses().front(); E; E = E->next()) {
1258 result.insert(E->key().operator String());
1259 }
1260 }
1261
1262 base = script->get_base();
1263 if (base.is_null())
1264 base = script->get_native();
1265 } else if (nc.is_valid()) {
1266
1267 if (!p_only_functions) {
1268
1269 StringName type = nc->get_name();
1270 List<String> constants;
1271 ObjectTypeDB::get_integer_constant_list(type, &constants);
1272 for (List<String>::Element *E = constants.front(); E; E = E->next()) {
1273 result.insert(E->get());
1274 }
1275
1276 List<MethodInfo> methods;
1277 ObjectTypeDB::get_method_list(type, &methods);
1278 for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
1279 if (E->get().name.begins_with("_"))
1280 continue;
1281 if (E->get().arguments.size())
1282 result.insert(E->get().name + "(");
1283 else
1284 result.insert(E->get().name + "()");
1285 }
1286 }
1287 break;
1288 } else
1289 break;
1290 }
1291 }
1292
_find_identifiers(GDCompletionContext & context,int p_line,bool p_only_functions,Set<String> & result)1293 static void _find_identifiers(GDCompletionContext &context, int p_line, bool p_only_functions, Set<String> &result) {
1294
1295 const GDParser::BlockNode *block = context.block;
1296
1297 if (context.function) {
1298
1299 const GDParser::FunctionNode *f = context.function;
1300
1301 for (int i = 0; i < f->arguments.size(); i++) {
1302 result.insert(f->arguments[i].operator String());
1303 }
1304 }
1305
1306 while (block) {
1307
1308 GDCompletionContext c = context;
1309 c.block = block;
1310
1311 _find_identifiers_in_block(c, p_line, p_only_functions, result);
1312 block = block->parent_block;
1313 }
1314
1315 const GDParser::ClassNode *clss = context._class;
1316
1317 bool _static = context.function && context.function->_static;
1318
1319 while (clss) {
1320 GDCompletionContext c = context;
1321 c._class = clss;
1322 c.block = NULL;
1323 c.function = NULL;
1324 _find_identifiers_in_class(c, _static, p_only_functions, result);
1325 clss = clss->owner;
1326 }
1327
1328 for (int i = 0; i < GDFunctions::FUNC_MAX; i++) {
1329
1330 result.insert(GDFunctions::get_func_name(GDFunctions::Function(i)));
1331 }
1332
1333 static const char *_type_names[Variant::VARIANT_MAX] = {
1334 "null", "bool", "int", "float", "String", "Vector2", "Rect2", "Vector3", "Matrix32", "Plane", "Quat", "AABB", "Matrix3", "Transform",
1335 "Color", "Image", "NodePath", "RID", "Object", "InputEvent", "Dictionary", "Array", "RawArray", "IntArray", "FloatArray", "StringArray",
1336 "Vector2Array", "Vector3Array", "ColorArray"
1337 };
1338
1339 for (int i = 0; i < Variant::VARIANT_MAX; i++) {
1340 result.insert(_type_names[i]);
1341 }
1342
1343 //autoload singletons
1344 List<PropertyInfo> props;
1345 Globals::get_singleton()->get_property_list(&props);
1346
1347 for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
1348
1349 String s = E->get().name;
1350 if (!s.begins_with("autoload/"))
1351 continue;
1352 String name = s.get_slice("/", 1);
1353 String path = Globals::get_singleton()->get(s);
1354 if (path.begins_with("*")) {
1355 result.insert(name);
1356 }
1357 }
1358
1359 for (const Map<StringName, int>::Element *E = GDScriptLanguage::get_singleton()->get_global_map().front(); E; E = E->next()) {
1360 result.insert(E->key().operator String());
1361 }
1362 }
1363
_get_visual_datatype(const PropertyInfo & p_info,bool p_isarg=true)1364 static String _get_visual_datatype(const PropertyInfo &p_info, bool p_isarg = true) {
1365
1366 String n = p_info.name;
1367 int idx = n.find(":");
1368 if (idx != -1) {
1369 return n.substr(idx + 1, n.length());
1370 }
1371
1372 if (p_info.type == Variant::OBJECT && p_info.hint == PROPERTY_HINT_RESOURCE_TYPE)
1373 return p_info.hint_string;
1374 if (p_info.type == Variant::NIL) {
1375 if (p_isarg)
1376 return "var";
1377 else
1378 return "void";
1379 }
1380
1381 return Variant::get_type_name(p_info.type);
1382 }
1383
_make_function_hint(const GDParser::FunctionNode * p_func,int p_argidx,String & arghint)1384 static void _make_function_hint(const GDParser::FunctionNode *p_func, int p_argidx, String &arghint) {
1385
1386 arghint = "func " + p_func->name + "(";
1387 for (int i = 0; i < p_func->arguments.size(); i++) {
1388 if (i > 0)
1389 arghint += ", ";
1390 else
1391 arghint += " ";
1392
1393 if (i == p_argidx) {
1394 arghint += String::chr(0xFFFF);
1395 }
1396 arghint += p_func->arguments[i].operator String();
1397 int deffrom = p_func->arguments.size() - p_func->default_values.size();
1398
1399 if (i >= deffrom) {
1400 int defidx = deffrom - i;
1401
1402 if (defidx >= 0 && defidx < p_func->default_values.size()) {
1403
1404 if (p_func->default_values[defidx]->type == GDParser::Node::TYPE_OPERATOR) {
1405
1406 const GDParser::OperatorNode *op = static_cast<const GDParser::OperatorNode *>(p_func->default_values[defidx]);
1407 if (op->op == GDParser::OperatorNode::OP_ASSIGN) {
1408 const GDParser::ConstantNode *cn = static_cast<const GDParser::ConstantNode *>(op->arguments[1]);
1409 arghint += "=" + cn->value.get_construct_string();
1410 }
1411 } else {
1412 }
1413 }
1414 }
1415
1416 if (i == p_argidx) {
1417 arghint += String::chr(0xFFFF);
1418 }
1419 }
1420 if (p_func->arguments.size() > 0)
1421 arghint += " ";
1422 arghint += ")";
1423 }
1424
_find_type_arguments(const GDParser::Node * p_node,int p_line,const StringName & p_method,const GDCompletionIdentifier & id,int p_argidx,Set<String> & result,String & arghint)1425 static void _find_type_arguments(const GDParser::Node *p_node, int p_line, const StringName &p_method, const GDCompletionIdentifier &id, int p_argidx, Set<String> &result, String &arghint) {
1426
1427 //print_line("find type arguments?");
1428 if (id.type == Variant::INPUT_EVENT && String(p_method) == "is_action" && p_argidx == 0) {
1429
1430 List<PropertyInfo> pinfo;
1431 Globals::get_singleton()->get_property_list(&pinfo);
1432
1433 for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
1434 const PropertyInfo &pi = E->get();
1435
1436 if (!pi.name.begins_with("input/"))
1437 continue;
1438
1439 String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
1440 result.insert("\"" + name + "\"");
1441 }
1442
1443 } else if (id.type == Variant::OBJECT && id.obj_type != StringName()) {
1444
1445 MethodBind *m = ObjectTypeDB::get_method(id.obj_type, p_method);
1446 if (!m) {
1447 //not in static method, see script
1448
1449 //print_line("not in static: "+String(p_method));
1450 Ref<GDScript> on_script;
1451
1452 if (id.value.get_type()) {
1453 Object *obj = id.value;
1454
1455 if (obj) {
1456
1457 GDScript *scr = obj->cast_to<GDScript>();
1458 if (scr) {
1459 while (scr) {
1460
1461 for (const Map<StringName, GDFunction *>::Element *E = scr->get_member_functions().front(); E; E = E->next()) {
1462 if (E->get()->is_static() && p_method == E->get()->get_name()) {
1463 arghint = "static func " + String(p_method) + "(";
1464 for (int i = 0; i < E->get()->get_argument_count(); i++) {
1465 if (i > 0)
1466 arghint += ", ";
1467 else
1468 arghint += " ";
1469 if (i == p_argidx) {
1470 arghint += String::chr(0xFFFF);
1471 }
1472 arghint += "var " + E->get()->get_argument_name(i);
1473 int deffrom = E->get()->get_argument_count() - E->get()->get_default_argument_count();
1474 if (i >= deffrom) {
1475 int defidx = deffrom - i;
1476 if (defidx >= 0 && defidx < E->get()->get_default_argument_count()) {
1477 arghint += "=" + E->get()->get_default_argument(defidx).get_construct_string();
1478 }
1479 }
1480 if (i == p_argidx) {
1481 arghint += String::chr(0xFFFF);
1482 }
1483 }
1484 arghint += ")";
1485 return; //found
1486 }
1487 }
1488
1489 if (scr->get_base().is_valid())
1490 scr = scr->get_base().ptr();
1491 else
1492 scr = NULL;
1493 }
1494 } else {
1495 on_script = obj->get_script();
1496 }
1497 }
1498 }
1499
1500 //print_line("but it has a script?");
1501 if (!on_script.is_valid() && id.script.is_valid()) {
1502 //print_line("yes");
1503 on_script = id.script;
1504 }
1505
1506 if (on_script.is_valid()) {
1507
1508 GDScript *scr = on_script.ptr();
1509 if (scr) {
1510 while (scr) {
1511
1512 String code = scr->get_source_code();
1513 //print_line("has source code!");
1514
1515 if (code != "") {
1516 //if there is code, parse it. This way is slower but updates in real-time
1517 GDParser p;
1518 //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);
1519
1520 Error err = p.parse(scr->get_source_code(), scr->get_path().get_base_dir(), true, "", false);
1521
1522 if (err == OK) {
1523 //print_line("checking the functions...");
1524 //only if ok, otherwise use what is cached on the script
1525 //GDParser::ClassNode *base = p.
1526 const GDParser::Node *root = p.get_parse_tree();
1527 ERR_FAIL_COND(root->type != GDParser::Node::TYPE_CLASS);
1528
1529 const GDParser::ClassNode *cl = static_cast<const GDParser::ClassNode *>(root);
1530
1531 const GDParser::FunctionNode *func = NULL;
1532 bool st = false;
1533
1534 for (int i = 0; i < cl->functions.size(); i++) {
1535 //print_line(String(cl->functions[i]->name)+" vs "+String(p_method));
1536 if (cl->functions[i]->name == p_method) {
1537 func = cl->functions[i];
1538 }
1539 }
1540
1541 for (int i = 0; i < cl->static_functions.size(); i++) {
1542
1543 //print_line(String(cl->static_functions[i]->name)+" vs "+String(p_method));
1544 if (cl->static_functions[i]->name == p_method) {
1545 func = cl->static_functions[i];
1546 st = true;
1547 }
1548 }
1549
1550 if (func) {
1551
1552 arghint = "func " + String(p_method) + "(";
1553 if (st)
1554 arghint = "static " + arghint;
1555 for (int i = 0; i < func->arguments.size(); i++) {
1556 if (i > 0)
1557 arghint += ", ";
1558 else
1559 arghint += " ";
1560 if (i == p_argidx) {
1561 arghint += String::chr(0xFFFF);
1562 }
1563 arghint += "var " + String(func->arguments[i]);
1564 int deffrom = func->arguments.size() - func->default_values.size();
1565 if (i >= deffrom) {
1566
1567 int defidx = deffrom - i;
1568
1569 if (defidx >= 0 && defidx < func->default_values.size() && func->default_values[defidx]->type == GDParser::Node::TYPE_OPERATOR) {
1570 const GDParser::OperatorNode *op = static_cast<const GDParser::OperatorNode *>(func->default_values[defidx]);
1571 if (op->op == GDParser::OperatorNode::OP_ASSIGN) {
1572 const GDParser::ConstantNode *cn = static_cast<const GDParser::ConstantNode *>(op->arguments[1]);
1573 arghint += "=" + cn->value.get_construct_string();
1574 }
1575 }
1576 }
1577 if (i == p_argidx) {
1578 arghint += String::chr(0xFFFF);
1579 }
1580 }
1581
1582 arghint += " )";
1583 return;
1584 }
1585 } else {
1586 //print_line("failed parsing?");
1587 code = "";
1588 }
1589 }
1590
1591 if (code == "") {
1592
1593 for (const Map<StringName, GDFunction *>::Element *E = scr->get_member_functions().front(); E; E = E->next()) {
1594 if (p_method == E->get()->get_name()) {
1595 arghint = "func " + String(p_method) + "(";
1596 for (int i = 0; i < E->get()->get_argument_count(); i++) {
1597 if (i > 0)
1598 arghint += ", ";
1599 else
1600 arghint += " ";
1601 if (i == p_argidx) {
1602 arghint += String::chr(0xFFFF);
1603 }
1604 arghint += "var " + E->get()->get_argument_name(i);
1605 int deffrom = E->get()->get_argument_count() - E->get()->get_default_argument_count();
1606 if (i >= deffrom) {
1607 int defidx = deffrom - i;
1608 if (defidx >= 0 && defidx < E->get()->get_default_argument_count()) {
1609 arghint += "=" + E->get()->get_default_argument(defidx).get_construct_string();
1610 }
1611 }
1612 if (i == p_argidx) {
1613 arghint += String::chr(0xFFFF);
1614 }
1615 }
1616 arghint += ")";
1617 return; //found
1618 }
1619 }
1620 #if 0
1621 //use class directly, no code was found
1622 if (!isfunction) {
1623 for (const Map<StringName,Variant>::Element *E=scr->get_constants().front();E;E=E->next()) {
1624 options.insert(E->key());
1625 }
1626 }
1627 for (const Map<StringName,GDFunction>::Element *E=scr->get_member_functions().front();E;E=E->next()) {
1628 options.insert(String(E->key())+"(");
1629 }
1630
1631 for (const Set<StringName>::Element *E=scr->get_members().front();E;E=E->next()) {
1632 options.insert(E->get());
1633 }
1634 #endif
1635 }
1636
1637 if (scr->get_base().is_valid())
1638 scr = scr->get_base().ptr();
1639 else
1640 scr = NULL;
1641 }
1642 }
1643 }
1644
1645 } else {
1646 //regular method
1647
1648 if (p_method.operator String() == "connect" || (p_method.operator String() == "emit_signal" && p_argidx == 0)) {
1649
1650 if (p_argidx == 0) {
1651 List<MethodInfo> sigs;
1652 ObjectTypeDB::get_signal_list(id.obj_type, &sigs);
1653 for (List<MethodInfo>::Element *E = sigs.front(); E; E = E->next()) {
1654 result.insert("\"" + E->get().name + "\"");
1655 }
1656 }
1657 /*if (p_argidx==2) {
1658
1659 ERR_FAIL_COND(p_node->type!=GDParser::Node::TYPE_OPERATOR);
1660 const GDParser::OperatorNode *op=static_cast<const GDParser::OperatorNode *>(p_node);
1661 if (op->arguments.size()>)
1662
1663 }*/
1664 } else {
1665
1666 if (p_argidx == 0 && (String(p_method) == "get_node" || String(p_method) == "has_node") && ObjectTypeDB::is_type(id.obj_type, "Node")) {
1667
1668 List<PropertyInfo> props;
1669 Globals::get_singleton()->get_property_list(&props);
1670
1671 for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
1672
1673 String s = E->get().name;
1674 if (!s.begins_with("autoload/"))
1675 continue;
1676 // print_line("found "+s);
1677 String name = s.get_slice("/", 1);
1678 result.insert("\"/root/" + name + "\"");
1679 }
1680 }
1681
1682 Object *obj = id.value;
1683 if (obj) {
1684 List<String> options;
1685 obj->get_argument_options(p_method, p_argidx, &options);
1686
1687 for (List<String>::Element *E = options.front(); E; E = E->next()) {
1688
1689 result.insert(E->get());
1690 }
1691 }
1692 }
1693
1694 arghint = _get_visual_datatype(m->get_argument_info(-1), false) + " " + p_method.operator String() + String("(");
1695
1696 for (int i = 0; i < m->get_argument_count(); i++) {
1697 if (i > 0)
1698 arghint += ", ";
1699 else
1700 arghint += " ";
1701
1702 if (i == p_argidx) {
1703 arghint += String::chr(0xFFFF);
1704 }
1705 String n = m->get_argument_info(i).name;
1706 int dp = n.find(":");
1707 if (dp != -1)
1708 n = n.substr(0, dp);
1709 arghint += _get_visual_datatype(m->get_argument_info(i)) + " " + n;
1710 int deffrom = m->get_argument_count() - m->get_default_argument_count();
1711
1712 if (i >= deffrom) {
1713 int defidx = i - deffrom;
1714
1715 if (defidx >= 0 && defidx < m->get_default_argument_count()) {
1716 Variant v = m->get_default_argument(i);
1717 arghint += "=" + v.get_construct_string();
1718 }
1719 }
1720
1721 if (i == p_argidx) {
1722 arghint += String::chr(0xFFFF);
1723 }
1724 }
1725 if (m->get_argument_count() > 0)
1726 arghint += " ";
1727
1728 arghint += ")";
1729 }
1730 }
1731 }
1732
_find_call_arguments(GDCompletionContext & context,const GDParser::Node * p_node,int p_line,int p_argidx,Set<String> & result,String & arghint)1733 static void _find_call_arguments(GDCompletionContext &context, const GDParser::Node *p_node, int p_line, int p_argidx, Set<String> &result, String &arghint) {
1734
1735 if (!p_node || p_node->type != GDParser::Node::TYPE_OPERATOR) {
1736
1737 return;
1738 }
1739
1740 const GDParser::OperatorNode *op = static_cast<const GDParser::OperatorNode *>(p_node);
1741
1742 if (op->op != GDParser::OperatorNode::OP_CALL) {
1743
1744 return;
1745 }
1746
1747 if (op->arguments[0]->type == GDParser::Node::TYPE_BUILT_IN_FUNCTION) {
1748 //complete built-in function
1749 const GDParser::BuiltInFunctionNode *fn = static_cast<const GDParser::BuiltInFunctionNode *>(op->arguments[0]);
1750 MethodInfo mi = GDFunctions::get_info(fn->function);
1751
1752 arghint = _get_visual_datatype(mi.return_val, false) + " " + GDFunctions::get_func_name(fn->function) + String("(");
1753 for (int i = 0; i < mi.arguments.size(); i++) {
1754 if (i > 0)
1755 arghint += ", ";
1756 else
1757 arghint += " ";
1758 if (i == p_argidx) {
1759 arghint += String::chr(0xFFFF);
1760 }
1761 arghint += _get_visual_datatype(mi.arguments[i]) + " " + mi.arguments[i].name;
1762 if (i == p_argidx) {
1763 arghint += String::chr(0xFFFF);
1764 }
1765 }
1766 if (mi.arguments.size() > 0)
1767 arghint += " ";
1768 arghint += ")";
1769
1770 } else if (op->arguments[0]->type == GDParser::Node::TYPE_TYPE) {
1771 //complete constructor
1772 const GDParser::TypeNode *tn = static_cast<const GDParser::TypeNode *>(op->arguments[0]);
1773
1774 List<MethodInfo> mil;
1775 Variant::get_constructor_list(tn->vtype, &mil);
1776
1777 for (List<MethodInfo>::Element *E = mil.front(); E; E = E->next()) {
1778
1779 MethodInfo mi = E->get();
1780 if (mi.arguments.size() == 0)
1781 continue;
1782 if (E->prev())
1783 arghint += "\n";
1784 arghint += Variant::get_type_name(tn->vtype) + " " + Variant::get_type_name(tn->vtype) + String("(");
1785 for (int i = 0; i < mi.arguments.size(); i++) {
1786 if (i > 0)
1787 arghint += ", ";
1788 else
1789 arghint += " ";
1790 if (i == p_argidx) {
1791 arghint += String::chr(0xFFFF);
1792 }
1793 arghint += _get_visual_datatype(mi.arguments[i]) + " " + mi.arguments[i].name;
1794 if (i == p_argidx) {
1795 arghint += String::chr(0xFFFF);
1796 }
1797 }
1798 if (mi.arguments.size() > 0)
1799 arghint += " ";
1800 arghint += ")";
1801 }
1802
1803 } else if (op->arguments.size() >= 2 && op->arguments[1]->type == GDParser::Node::TYPE_IDENTIFIER) {
1804 //make sure identifier exists...
1805
1806 const GDParser::IdentifierNode *id = static_cast<const GDParser::IdentifierNode *>(op->arguments[1]);
1807
1808 if (op->arguments[0]->type == GDParser::Node::TYPE_SELF) {
1809 //self, look up
1810
1811 for (int i = 0; i < context._class->static_functions.size(); i++) {
1812 if (context._class->static_functions[i]->name == id->name) {
1813 _make_function_hint(context._class->static_functions[i], p_argidx, arghint);
1814 return;
1815 }
1816 }
1817
1818 if (context.function && !context.function->_static) {
1819
1820 for (int i = 0; i < context._class->functions.size(); i++) {
1821 if (context._class->functions[i]->name == id->name) {
1822 _make_function_hint(context._class->functions[i], p_argidx, arghint);
1823 return;
1824 }
1825 }
1826 }
1827
1828 Ref<Reference> base = _get_parent_class(context);
1829
1830 while (true) {
1831
1832 Ref<GDScript> script = base;
1833 Ref<GDNativeClass> nc = base;
1834 if (script.is_valid()) {
1835
1836 for (const Map<StringName, GDFunction *>::Element *E = script->get_member_functions().front(); E; E = E->next()) {
1837
1838 if (E->key() == id->name) {
1839
1840 if (context.function && context.function->_static && !E->get()->is_static())
1841 continue;
1842
1843 arghint = "func " + id->name.operator String() + String("(");
1844 for (int i = 0; i < E->get()->get_argument_count(); i++) {
1845 if (i > 0)
1846 arghint += ", ";
1847 else
1848 arghint += " ";
1849 if (i == p_argidx) {
1850 arghint += String::chr(0xFFFF);
1851 }
1852 arghint += E->get()->get_argument_name(i);
1853 int deffrom = E->get()->get_argument_count() - E->get()->get_default_argument_count();
1854 if (i >= deffrom) {
1855 int defidx = deffrom - i;
1856 if (defidx >= 0 && defidx < E->get()->get_default_argument_count()) {
1857 arghint += "=" + E->get()->get_default_argument(defidx).get_construct_string();
1858 }
1859 }
1860 if (i == p_argidx) {
1861 arghint += String::chr(0xFFFF);
1862 }
1863 }
1864 if (E->get()->get_argument_count() > 0)
1865 arghint += " ";
1866 arghint += ")";
1867 return;
1868 }
1869 }
1870
1871 base = script->get_base();
1872 if (base.is_null())
1873 base = script->get_native();
1874 } else if (nc.is_valid()) {
1875
1876 if (context.function && !context.function->_static) {
1877
1878 GDCompletionIdentifier ci;
1879 ci.type = Variant::OBJECT;
1880 ci.obj_type = nc->get_name();
1881 if (!context._class->owner)
1882 ci.value = context.base;
1883
1884 _find_type_arguments(p_node, p_line, id->name, ci, p_argidx, result, arghint);
1885 //guess type..
1886 /*
1887 List<MethodInfo> methods;
1888 ObjectTypeDB::get_method_list(type,&methods);
1889 for(List<MethodInfo>::Element *E=methods.front();E;E=E->next()) {
1890 //if (E->get().arguments.size())
1891 // result.insert(E->get().name+"(");
1892 //else
1893 // result.insert(E->get().name+"()");
1894 }*/
1895 }
1896 break;
1897 } else
1898 break;
1899 }
1900 } else {
1901 //indexed lookup
1902
1903 GDCompletionIdentifier ci;
1904 if (_guess_expression_type(context, op->arguments[0], p_line, ci)) {
1905
1906 _find_type_arguments(p_node, p_line, id->name, ci, p_argidx, result, arghint);
1907 return;
1908 }
1909 }
1910 }
1911 #if 0
1912 bool _static=context.function->_static;
1913
1914
1915
1916
1917 for(int i=0;i<context._class->static_functions.size();i++) {
1918 if (context._class->static_functions[i]->arguments.size())
1919 result.insert(context._class->static_functions[i]->name.operator String()+"(");
1920 else
1921 result.insert(context._class->static_functions[i]->name.operator String()+"()");
1922 }
1923
1924 if (!p_static) {
1925
1926 for(int i=0;i<context._class->functions.size();i++) {
1927 if (context._class->functions[i]->arguments.size())
1928 result.insert(context._class->functions[i]->name.operator String()+"(");
1929 else
1930 result.insert(context._class->functions[i]->name.operator String()+"()");
1931 }
1932 }
1933
1934 Ref<Reference> base = _get_parent_class(context);
1935
1936 while(true) {
1937
1938 Ref<GDScript> script = base;
1939 Ref<GDNativeClass> nc = base;
1940 if (script.is_valid()) {
1941
1942 if (!p_static && !p_only_functions) {
1943 for (const Set<StringName>::Element *E=script->get_members().front();E;E=E->next()) {
1944 result.insert(E->get().operator String());
1945 }
1946 }
1947
1948 if (!p_only_functions) {
1949 for (const Map<StringName,Variant>::Element *E=script->get_constants().front();E;E=E->next()) {
1950 result.insert(E->key().operator String());
1951 }
1952 }
1953
1954 for (const Map<StringName,GDFunction>::Element *E=script->get_member_functions().front();E;E=E->next()) {
1955 if (!p_static || E->get().is_static()) {
1956 if (E->get().get_argument_count())
1957 result.insert(E->key().operator String()+"(");
1958 else
1959 result.insert(E->key().operator String()+"()");
1960 }
1961 }
1962
1963 if (!p_only_functions) {
1964 for (const Map<StringName,Ref<GDScript> >::Element *E=script->get_subclasses().front();E;E=E->next()) {
1965 result.insert(E->key().operator String());
1966 }
1967 }
1968
1969 base=script->get_base();
1970 if (base.is_null())
1971 base=script->get_native();
1972 } else if (nc.is_valid()) {
1973
1974 if (!p_only_functions) {
1975
1976 StringName type = nc->get_name();
1977 List<String> constants;
1978 ObjectTypeDB::get_integer_constant_list(type,&constants);
1979 for(List<String>::Element *E=constants.front();E;E=E->next()) {
1980 result.insert(E->get());
1981 }
1982
1983 List<MethodInfo> methods;
1984 ObjectTypeDB::get_method_list(type,&methods);
1985 for(List<MethodInfo>::Element *E=methods.front();E;E=E->next()) {
1986 if (E->get().arguments.size())
1987 result.insert(E->get().name+"(");
1988 else
1989 result.insert(E->get().name+"()");
1990 }
1991 }
1992 break;
1993 } else
1994 break;
1995
1996 }
1997
1998 for(int i=0;i<GDFunctions::FUNC_MAX;i++) {
1999
2000 result.insert(GDFunctions::get_func_name(GDFunctions::Function(i)));
2001 }
2002
2003 #endif
2004 }
2005
complete_code(const String & p_code,const String & p_base_path,Object * p_owner,List<String> * r_options,String & r_call_hint)2006 Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, String &r_call_hint) {
2007
2008 GDParser p;
2009
2010 Error err = p.parse(p_code, p_base_path, false, "", true);
2011 bool isfunction = false;
2012 Set<String> options;
2013
2014 GDCompletionContext context;
2015 context._class = p.get_completion_class();
2016 context.block = p.get_completion_block();
2017 context.function = p.get_completion_function();
2018 context.base = p_owner;
2019 context.base_path = p_base_path;
2020
2021 switch (p.get_completion_type()) {
2022
2023 case GDParser::COMPLETION_NONE: {
2024 } break;
2025 case GDParser::COMPLETION_BUILT_IN_TYPE_CONSTANT: {
2026 List<StringName> constants;
2027 Variant::get_numeric_constants_for_type(p.get_completion_built_in_constant(), &constants);
2028 for (List<StringName>::Element *E = constants.front(); E; E = E->next()) {
2029 options.insert(E->get().operator String());
2030 }
2031
2032 } break;
2033 case GDParser::COMPLETION_FUNCTION:
2034 isfunction = true;
2035 case GDParser::COMPLETION_IDENTIFIER: {
2036
2037 _find_identifiers(context, p.get_completion_line(), isfunction, options);
2038 } break;
2039 case GDParser::COMPLETION_PARENT_FUNCTION: {
2040
2041 } break;
2042 case GDParser::COMPLETION_METHOD:
2043 isfunction = true;
2044 case GDParser::COMPLETION_INDEX: {
2045
2046 const GDParser::Node *node = p.get_completion_node();
2047 if (node->type != GDParser::Node::TYPE_OPERATOR)
2048 break;
2049
2050 GDCompletionIdentifier t;
2051 if (_guess_expression_type(context, static_cast<const GDParser::OperatorNode *>(node)->arguments[0], p.get_completion_line(), t)) {
2052
2053 if (t.type == Variant::OBJECT && t.obj_type == "GDNativeClass") {
2054 //native enum
2055 Ref<GDNativeClass> gdn = t.value;
2056 if (gdn.is_valid()) {
2057 StringName cn = gdn->get_name();
2058 List<String> cnames;
2059 ObjectTypeDB::get_integer_constant_list(cn, &cnames);
2060 for (List<String>::Element *E = cnames.front(); E; E = E->next()) {
2061 options.insert(E->get());
2062 }
2063 }
2064 } else if (t.type == Variant::OBJECT && t.obj_type != StringName()) {
2065
2066 Ref<GDScript> on_script;
2067
2068 if (t.value.get_type()) {
2069 Object *obj = t.value;
2070
2071 if (obj) {
2072
2073 GDScript *scr = obj->cast_to<GDScript>();
2074 if (scr) {
2075 while (scr) {
2076
2077 if (!isfunction) {
2078 for (const Map<StringName, Variant>::Element *E = scr->get_constants().front(); E; E = E->next()) {
2079 options.insert(E->key());
2080 }
2081 }
2082 for (const Map<StringName, GDFunction *>::Element *E = scr->get_member_functions().front(); E; E = E->next()) {
2083 if (E->get()->is_static())
2084 options.insert(E->key());
2085 }
2086
2087 if (scr->get_base().is_valid())
2088 scr = scr->get_base().ptr();
2089 else
2090 scr = NULL;
2091 }
2092 } else {
2093 on_script = obj->get_script();
2094 }
2095 }
2096 }
2097
2098 if (!on_script.is_valid() && t.script.is_valid()) {
2099 on_script = t.script;
2100 }
2101
2102 if (on_script.is_valid()) {
2103
2104 GDScript *scr = on_script.ptr();
2105 if (scr) {
2106 while (scr) {
2107
2108 String code = scr->get_source_code();
2109
2110 if (code != "") {
2111 //if there is code, parse it. This way is slower but updates in real-time
2112 GDParser p;
2113
2114 Error err = p.parse(scr->get_source_code(), scr->get_path().get_base_dir(), true, "", false);
2115
2116 if (err == OK) {
2117 //only if ok, otherwise use what is cached on the script
2118 //GDParser::ClassNode *base = p.
2119 const GDParser::Node *root = p.get_parse_tree();
2120 ERR_FAIL_COND_V(root->type != GDParser::Node::TYPE_CLASS, ERR_PARSE_ERROR);
2121
2122 const GDParser::ClassNode *cl = static_cast<const GDParser::ClassNode *>(root);
2123
2124 for (int i = 0; i < cl->functions.size(); i++) {
2125
2126 if (cl->functions[i]->arguments.size())
2127 options.insert(String(cl->functions[i]->name) + "(");
2128 else
2129 options.insert(String(cl->functions[i]->name) + "()");
2130 }
2131
2132 for (int i = 0; i < cl->static_functions.size(); i++) {
2133
2134 if (cl->static_functions[i]->arguments.size())
2135 options.insert(String(cl->static_functions[i]->name) + "(");
2136 else
2137 options.insert(String(cl->static_functions[i]->name) + "()");
2138 }
2139
2140 if (!isfunction) {
2141 for (int i = 0; i < cl->variables.size(); i++) {
2142
2143 options.insert(String(cl->variables[i].identifier));
2144 }
2145
2146 for (int i = 0; i < cl->constant_expressions.size(); i++) {
2147
2148 options.insert(String(cl->constant_expressions[i].identifier));
2149 }
2150 }
2151
2152 } else {
2153 code = ""; //well, then no code
2154 }
2155 }
2156
2157 if (code == "") {
2158 //use class directly, no code was found
2159 if (!isfunction) {
2160 for (const Map<StringName, Variant>::Element *E = scr->get_constants().front(); E; E = E->next()) {
2161 options.insert(E->key());
2162 }
2163 }
2164 for (const Map<StringName, GDFunction *>::Element *E = scr->get_member_functions().front(); E; E = E->next()) {
2165 if (E->get()->get_argument_count())
2166 options.insert(String(E->key()) + "()");
2167 else
2168 options.insert(String(E->key()) + "(");
2169 }
2170
2171 for (const Set<StringName>::Element *E = scr->get_members().front(); E; E = E->next()) {
2172 options.insert(E->get());
2173 }
2174 }
2175
2176 if (scr->get_base().is_valid())
2177 scr = scr->get_base().ptr();
2178 else
2179 scr = NULL;
2180 }
2181 }
2182 }
2183
2184 if (!isfunction) {
2185 ObjectTypeDB::get_integer_constant_list(t.obj_type, r_options);
2186 }
2187 List<MethodInfo> mi;
2188 ObjectTypeDB::get_method_list(t.obj_type, &mi);
2189 for (List<MethodInfo>::Element *E = mi.front(); E; E = E->next()) {
2190
2191 if (E->get().name.begins_with("_"))
2192 continue;
2193
2194 if (E->get().arguments.size())
2195 options.insert(E->get().name + "(");
2196 else
2197 options.insert(E->get().name + "()");
2198 }
2199 } else {
2200
2201 if (t.type == Variant::INPUT_EVENT) {
2202
2203 //this is hardcoded otherwise it's not obvious
2204 Set<String> exclude;
2205
2206 for (int i = 0; i < InputEvent::TYPE_MAX; i++) {
2207
2208 InputEvent ie;
2209 ie.type = InputEvent::Type(i);
2210 static const char *evnames[] = {
2211 "# Common",
2212 "# Key",
2213 "# MouseMotion",
2214 "# MouseButton",
2215 "# JoystickMotion",
2216 "# JoystickButton",
2217 "# ScreenTouch",
2218 "# ScreenDrag",
2219 "# Action"
2220 };
2221
2222 r_options->push_back(evnames[i]);
2223
2224 Variant v = ie;
2225
2226 if (i == 0) {
2227 List<MethodInfo> mi;
2228 v.get_method_list(&mi);
2229 for (List<MethodInfo>::Element *E = mi.front(); E; E = E->next()) {
2230 r_options->push_back(E->get().name + "(");
2231 }
2232 }
2233
2234 List<PropertyInfo> pi;
2235 v.get_property_list(&pi);
2236
2237 for (List<PropertyInfo>::Element *E = pi.front(); E; E = E->next()) {
2238
2239 if (i == 0)
2240 exclude.insert(E->get().name);
2241 else if (exclude.has(E->get().name))
2242 continue;
2243
2244 r_options->push_back(E->get().name);
2245 }
2246 }
2247 return OK;
2248 } else {
2249 if (t.value.get_type() == Variant::NIL) {
2250 Variant::CallError ce;
2251 t.value = Variant::construct(t.type, NULL, 0, ce);
2252 }
2253
2254 if (!isfunction) {
2255 List<PropertyInfo> pl;
2256 t.value.get_property_list(&pl);
2257 for (List<PropertyInfo>::Element *E = pl.front(); E; E = E->next()) {
2258
2259 if (E->get().name.find("/") == -1)
2260 options.insert(E->get().name);
2261 }
2262 }
2263
2264 List<MethodInfo> mi;
2265 t.value.get_method_list(&mi);
2266 for (List<MethodInfo>::Element *E = mi.front(); E; E = E->next()) {
2267 if (E->get().arguments.size())
2268 options.insert(E->get().name + "(");
2269 else
2270 options.insert(E->get().name + "()");
2271 }
2272 }
2273 }
2274 }
2275
2276 } break;
2277 case GDParser::COMPLETION_CALL_ARGUMENTS: {
2278
2279 _find_call_arguments(context, p.get_completion_node(), p.get_completion_line(), p.get_completion_argument_index(), options, r_call_hint);
2280 } break;
2281 case GDParser::COMPLETION_VIRTUAL_FUNC: {
2282
2283 GDCompletionIdentifier cid = _get_native_class(context);
2284
2285 if (cid.obj_type != StringName()) {
2286 List<MethodInfo> vm;
2287 ObjectTypeDB::get_virtual_methods(cid.obj_type, &vm);
2288 for (List<MethodInfo>::Element *E = vm.front(); E; E = E->next()) {
2289
2290 MethodInfo &mi = E->get();
2291 String m = mi.name;
2292 if (m.find(":") != -1)
2293 m = m.substr(0, m.find(":"));
2294 m += "(";
2295
2296 if (mi.arguments.size()) {
2297 for (int i = 0; i < mi.arguments.size(); i++) {
2298 if (i > 0)
2299 m += ", ";
2300 String n = mi.arguments[i].name;
2301 if (n.find(":") != -1)
2302 n = n.substr(0, n.find(":"));
2303 m += n;
2304 }
2305 }
2306 m += "):";
2307
2308 options.insert(m);
2309 }
2310 }
2311 } break;
2312 }
2313
2314 for (Set<String>::Element *E = options.front(); E; E = E->next()) {
2315 r_options->push_back(E->get());
2316 }
2317
2318 return OK;
2319 }
2320
2321 #else
2322
complete_code(const String & p_code,const String & p_base_path,Object * p_owner,List<String> * r_options,String & r_call_hint)2323 Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, String &r_call_hint) {
2324 return OK;
2325 }
2326
2327 #endif
2328
auto_indent_code(String & p_code,int p_from_line,int p_to_line) const2329 void GDScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_to_line) const {
2330
2331 Vector<String> lines = p_code.split("\n");
2332 List<int> indent_stack;
2333
2334 for (int i = 0; i < lines.size(); i++) {
2335
2336 String l = lines[i];
2337 int tc = 0;
2338 for (int j = 0; j < l.length(); j++) {
2339 if (l[j] == ' ' || l[j] == '\t') {
2340
2341 tc++;
2342 } else {
2343 break;
2344 }
2345 }
2346
2347 String st = l.substr(tc, l.length()).strip_edges();
2348 if (st == "" || st.begins_with("#"))
2349 continue; //ignore!
2350
2351 int ilevel = 0;
2352 if (indent_stack.size()) {
2353 ilevel = indent_stack.back()->get();
2354 }
2355
2356 if (tc > ilevel) {
2357 indent_stack.push_back(tc);
2358 } else if (tc < ilevel) {
2359 while (indent_stack.size() && indent_stack.back()->get() > tc) {
2360 indent_stack.pop_back();
2361 }
2362
2363 if (indent_stack.size() && indent_stack.back()->get() != tc)
2364 indent_stack.push_back(tc); //this is not right but gets the job done
2365 }
2366
2367 if (i >= p_from_line) {
2368
2369 l = "";
2370 for (int j = 0; j < indent_stack.size(); j++)
2371 l += "\t";
2372 l += st;
2373
2374 } else if (i > p_to_line) {
2375 break;
2376 }
2377
2378 //print_line(itos(indent_stack.size())+","+itos(tc)+": "+l);
2379 lines[i] = l;
2380 }
2381
2382 p_code = "";
2383 for (int i = 0; i < lines.size(); i++) {
2384 if (i > 0)
2385 p_code += "\n";
2386 p_code += lines[i];
2387 }
2388 }
2389