1 /*************************************************************************/
2 /*  gdscript_editor.cpp                                                  */
3 /*************************************************************************/
4 /*                       This file is part of:                           */
5 /*                           GODOT ENGINE                                */
6 /*                      https://godotengine.org                          */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
9 /* Copyright (c) 2014-2020 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 
31 #include "gdscript.h"
32 
33 #include "core/engine.h"
34 #include "core/global_constants.h"
35 #include "core/os/file_access.h"
36 #include "gdscript_compiler.h"
37 
38 #ifdef TOOLS_ENABLED
39 #include "editor/editor_file_system.h"
40 #include "editor/editor_settings.h"
41 #endif
42 
get_comment_delimiters(List<String> * p_delimiters) const43 void GDScriptLanguage::get_comment_delimiters(List<String> *p_delimiters) const {
44 
45 	p_delimiters->push_back("#");
46 }
47 
get_string_delimiters(List<String> * p_delimiters) const48 void GDScriptLanguage::get_string_delimiters(List<String> *p_delimiters) const {
49 
50 	p_delimiters->push_back("\" \"");
51 	p_delimiters->push_back("' '");
52 	p_delimiters->push_back("\"\"\" \"\"\"");
53 }
54 
_get_processed_template(const String & p_template,const String & p_base_class_name) const55 String GDScriptLanguage::_get_processed_template(const String &p_template, const String &p_base_class_name) const {
56 
57 	String processed_template = p_template;
58 
59 #ifdef TOOLS_ENABLED
60 	if (EDITOR_DEF("text_editor/completion/add_type_hints", false)) {
61 		processed_template = processed_template.replace("%INT_TYPE%", ": int");
62 		processed_template = processed_template.replace("%STRING_TYPE%", ": String");
63 		processed_template = processed_template.replace("%FLOAT_TYPE%", ": float");
64 		processed_template = processed_template.replace("%VOID_RETURN%", " -> void");
65 	} else {
66 		processed_template = processed_template.replace("%INT_TYPE%", "");
67 		processed_template = processed_template.replace("%STRING_TYPE%", "");
68 		processed_template = processed_template.replace("%FLOAT_TYPE%", "");
69 		processed_template = processed_template.replace("%VOID_RETURN%", "");
70 	}
71 #else
72 	processed_template = processed_template.replace("%INT_TYPE%", "");
73 	processed_template = processed_template.replace("%STRING_TYPE%", "");
74 	processed_template = processed_template.replace("%FLOAT_TYPE%", "");
75 	processed_template = processed_template.replace("%VOID_RETURN%", "");
76 #endif
77 
78 	processed_template = processed_template.replace("%BASE%", p_base_class_name);
79 	processed_template = processed_template.replace("%TS%", _get_indentation());
80 
81 	return processed_template;
82 }
83 
get_template(const String & p_class_name,const String & p_base_class_name) const84 Ref<Script> GDScriptLanguage::get_template(const String &p_class_name, const String &p_base_class_name) const {
85 	String _template = "extends %BASE%\n"
86 					   "\n"
87 					   "\n"
88 					   "# Declare member variables here. Examples:\n"
89 					   "# var a%INT_TYPE% = 2\n"
90 					   "# var b%STRING_TYPE% = \"text\"\n"
91 					   "\n"
92 					   "\n"
93 					   "# Called when the node enters the scene tree for the first time.\n"
94 					   "func _ready()%VOID_RETURN%:\n"
95 					   "%TS%pass # Replace with function body.\n"
96 					   "\n"
97 					   "\n"
98 					   "# Called every frame. 'delta' is the elapsed time since the previous frame.\n"
99 					   "#func _process(delta%FLOAT_TYPE%)%VOID_RETURN%:\n"
100 					   "#%TS%pass\n";
101 
102 	_template = _get_processed_template(_template, p_base_class_name);
103 
104 	Ref<GDScript> script;
105 	script.instance();
106 	script->set_source_code(_template);
107 
108 	return script;
109 }
110 
is_using_templates()111 bool GDScriptLanguage::is_using_templates() {
112 
113 	return true;
114 }
115 
make_template(const String & p_class_name,const String & p_base_class_name,Ref<Script> & p_script)116 void GDScriptLanguage::make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {
117 
118 	String _template = _get_processed_template(p_script->get_source_code(), p_base_class_name);
119 	p_script->set_source_code(_template);
120 }
121 
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,List<ScriptLanguage::Warning> * r_warnings,Set<int> * r_safe_lines) const122 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, List<ScriptLanguage::Warning> *r_warnings, Set<int> *r_safe_lines) const {
123 
124 	GDScriptParser parser;
125 
126 	Error err = parser.parse(p_script, p_path.get_base_dir(), true, p_path, false, r_safe_lines);
127 #ifdef DEBUG_ENABLED
128 	if (r_warnings) {
129 		for (const List<GDScriptWarning>::Element *E = parser.get_warnings().front(); E; E = E->next()) {
130 			const GDScriptWarning &warn = E->get();
131 			ScriptLanguage::Warning w;
132 			w.line = warn.line;
133 			w.code = (int)warn.code;
134 			w.string_code = GDScriptWarning::get_name_from_code(warn.code);
135 			w.message = warn.get_message();
136 			r_warnings->push_back(w);
137 		}
138 	}
139 #endif
140 	if (err) {
141 		r_line_error = parser.get_error_line();
142 		r_col_error = parser.get_error_column();
143 		r_test_error = parser.get_error();
144 		return false;
145 	} else {
146 
147 		const GDScriptParser::Node *root = parser.get_parse_tree();
148 		ERR_FAIL_COND_V(root->type != GDScriptParser::Node::TYPE_CLASS, false);
149 
150 		const GDScriptParser::ClassNode *cl = static_cast<const GDScriptParser::ClassNode *>(root);
151 		Map<int, String> funcs;
152 		for (int i = 0; i < cl->functions.size(); i++) {
153 
154 			funcs[cl->functions[i]->line] = cl->functions[i]->name;
155 		}
156 
157 		for (int i = 0; i < cl->static_functions.size(); i++) {
158 
159 			funcs[cl->static_functions[i]->line] = cl->static_functions[i]->name;
160 		}
161 
162 		for (int i = 0; i < cl->subclasses.size(); i++) {
163 			for (int j = 0; j < cl->subclasses[i]->functions.size(); j++) {
164 
165 				funcs[cl->subclasses[i]->functions[j]->line] = String(cl->subclasses[i]->name) + "." + cl->subclasses[i]->functions[j]->name;
166 			}
167 			for (int j = 0; j < cl->subclasses[i]->static_functions.size(); j++) {
168 
169 				funcs[cl->subclasses[i]->static_functions[j]->line] = String(cl->subclasses[i]->name) + "." + cl->subclasses[i]->static_functions[j]->name;
170 			}
171 		}
172 
173 		for (Map<int, String>::Element *E = funcs.front(); E; E = E->next()) {
174 
175 			r_functions->push_back(E->get() + ":" + itos(E->key()));
176 		}
177 	}
178 
179 	return true;
180 }
181 
has_named_classes() const182 bool GDScriptLanguage::has_named_classes() const {
183 
184 	return false;
185 }
186 
supports_builtin_mode() const187 bool GDScriptLanguage::supports_builtin_mode() const {
188 
189 	return true;
190 }
191 
find_function(const String & p_function,const String & p_code) const192 int GDScriptLanguage::find_function(const String &p_function, const String &p_code) const {
193 
194 	GDScriptTokenizerText tokenizer;
195 	tokenizer.set_code(p_code);
196 	int indent = 0;
197 	while (tokenizer.get_token() != GDScriptTokenizer::TK_EOF && tokenizer.get_token() != GDScriptTokenizer::TK_ERROR) {
198 
199 		if (tokenizer.get_token() == GDScriptTokenizer::TK_NEWLINE) {
200 			indent = tokenizer.get_token_line_indent();
201 		}
202 		if (indent == 0 && tokenizer.get_token() == GDScriptTokenizer::TK_PR_FUNCTION && tokenizer.get_token(1) == GDScriptTokenizer::TK_IDENTIFIER) {
203 
204 			String identifier = tokenizer.get_token_identifier(1);
205 			if (identifier == p_function) {
206 				return tokenizer.get_token_line();
207 			}
208 		}
209 		tokenizer.advance();
210 	}
211 	return -1;
212 }
213 
create_script() const214 Script *GDScriptLanguage::create_script() const {
215 
216 	return memnew(GDScript);
217 }
218 
219 /* DEBUGGER FUNCTIONS */
220 
debug_break_parse(const String & p_file,int p_line,const String & p_error)221 bool GDScriptLanguage::debug_break_parse(const String &p_file, int p_line, const String &p_error) {
222 	//break because of parse error
223 
224 	if (ScriptDebugger::get_singleton() && Thread::get_caller_id() == Thread::get_main_id()) {
225 
226 		_debug_parse_err_line = p_line;
227 		_debug_parse_err_file = p_file;
228 		_debug_error = p_error;
229 		ScriptDebugger::get_singleton()->debug(this, false, true);
230 		return true;
231 	} else {
232 		return false;
233 	}
234 }
235 
debug_break(const String & p_error,bool p_allow_continue)236 bool GDScriptLanguage::debug_break(const String &p_error, bool p_allow_continue) {
237 
238 	if (ScriptDebugger::get_singleton() && Thread::get_caller_id() == Thread::get_main_id()) {
239 
240 		_debug_parse_err_line = -1;
241 		_debug_parse_err_file = "";
242 		_debug_error = p_error;
243 		bool is_error_breakpoint = p_error != "Breakpoint";
244 		ScriptDebugger::get_singleton()->debug(this, p_allow_continue, is_error_breakpoint);
245 		return true;
246 	} else {
247 		return false;
248 	}
249 }
250 
debug_get_error() const251 String GDScriptLanguage::debug_get_error() const {
252 
253 	return _debug_error;
254 }
255 
debug_get_stack_level_count() const256 int GDScriptLanguage::debug_get_stack_level_count() const {
257 
258 	if (_debug_parse_err_line >= 0)
259 		return 1;
260 
261 	return _debug_call_stack_pos;
262 }
debug_get_stack_level_line(int p_level) const263 int GDScriptLanguage::debug_get_stack_level_line(int p_level) const {
264 
265 	if (_debug_parse_err_line >= 0)
266 		return _debug_parse_err_line;
267 
268 	ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, -1);
269 
270 	int l = _debug_call_stack_pos - p_level - 1;
271 
272 	return *(_call_stack[l].line);
273 }
debug_get_stack_level_function(int p_level) const274 String GDScriptLanguage::debug_get_stack_level_function(int p_level) const {
275 
276 	if (_debug_parse_err_line >= 0)
277 		return "";
278 
279 	ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, "");
280 	int l = _debug_call_stack_pos - p_level - 1;
281 	return _call_stack[l].function->get_name();
282 }
debug_get_stack_level_source(int p_level) const283 String GDScriptLanguage::debug_get_stack_level_source(int p_level) const {
284 
285 	if (_debug_parse_err_line >= 0)
286 		return _debug_parse_err_file;
287 
288 	ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, "");
289 	int l = _debug_call_stack_pos - p_level - 1;
290 	return _call_stack[l].function->get_source();
291 }
debug_get_stack_level_locals(int p_level,List<String> * p_locals,List<Variant> * p_values,int p_max_subitems,int p_max_depth)292 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) {
293 
294 	if (_debug_parse_err_line >= 0)
295 		return;
296 
297 	ERR_FAIL_INDEX(p_level, _debug_call_stack_pos);
298 	int l = _debug_call_stack_pos - p_level - 1;
299 
300 	GDScriptFunction *f = _call_stack[l].function;
301 
302 	List<Pair<StringName, int> > locals;
303 
304 	f->debug_get_stack_member_state(*_call_stack[l].line, &locals);
305 	for (List<Pair<StringName, int> >::Element *E = locals.front(); E; E = E->next()) {
306 
307 		p_locals->push_back(E->get().first);
308 		p_values->push_back(_call_stack[l].stack[E->get().second]);
309 	}
310 }
debug_get_stack_level_members(int p_level,List<String> * p_members,List<Variant> * p_values,int p_max_subitems,int p_max_depth)311 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) {
312 
313 	if (_debug_parse_err_line >= 0)
314 		return;
315 
316 	ERR_FAIL_INDEX(p_level, _debug_call_stack_pos);
317 	int l = _debug_call_stack_pos - p_level - 1;
318 
319 	GDScriptInstance *instance = _call_stack[l].instance;
320 
321 	if (!instance)
322 		return;
323 
324 	Ref<GDScript> script = instance->get_script();
325 	ERR_FAIL_COND(script.is_null());
326 
327 	const Map<StringName, GDScript::MemberInfo> &mi = script->debug_get_member_indices();
328 
329 	for (const Map<StringName, GDScript::MemberInfo>::Element *E = mi.front(); E; E = E->next()) {
330 
331 		p_members->push_back(E->key());
332 		p_values->push_back(instance->debug_get_member_by_index(E->get().index));
333 	}
334 }
335 
debug_get_stack_level_instance(int p_level)336 ScriptInstance *GDScriptLanguage::debug_get_stack_level_instance(int p_level) {
337 
338 	if (_debug_parse_err_line >= 0)
339 		return NULL;
340 
341 	ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, NULL);
342 
343 	int l = _debug_call_stack_pos - p_level - 1;
344 	ScriptInstance *instance = _call_stack[l].instance;
345 
346 	return instance;
347 }
348 
debug_get_globals(List<String> * p_globals,List<Variant> * p_values,int p_max_subitems,int p_max_depth)349 void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
350 
351 	const Map<StringName, int> &name_idx = GDScriptLanguage::get_singleton()->get_global_map();
352 	const Variant *globals = GDScriptLanguage::get_singleton()->get_global_array();
353 
354 	List<Pair<String, Variant> > cinfo;
355 	get_public_constants(&cinfo);
356 
357 	for (const Map<StringName, int>::Element *E = name_idx.front(); E; E = E->next()) {
358 
359 		if (ClassDB::class_exists(E->key()) || Engine::get_singleton()->has_singleton(E->key()))
360 			continue;
361 
362 		bool is_script_constant = false;
363 		for (List<Pair<String, Variant> >::Element *CE = cinfo.front(); CE; CE = CE->next()) {
364 			if (CE->get().first == E->key()) {
365 				is_script_constant = true;
366 				break;
367 			}
368 		}
369 		if (is_script_constant)
370 			continue;
371 
372 		const Variant &var = globals[E->value()];
373 		if (Object *obj = var) {
374 			if (Object::cast_to<GDScriptNativeClass>(obj))
375 				continue;
376 		}
377 
378 		bool skip = false;
379 		for (int i = 0; i < GlobalConstants::get_global_constant_count(); i++) {
380 			if (E->key() == GlobalConstants::get_global_constant_name(i)) {
381 				skip = true;
382 				break;
383 			}
384 		}
385 		if (skip)
386 			continue;
387 
388 		p_globals->push_back(E->key());
389 		p_values->push_back(var);
390 	}
391 }
392 
debug_parse_stack_level_expression(int p_level,const String & p_expression,int p_max_subitems,int p_max_depth)393 String GDScriptLanguage::debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) {
394 
395 	return "";
396 }
397 
get_recognized_extensions(List<String> * p_extensions) const398 void GDScriptLanguage::get_recognized_extensions(List<String> *p_extensions) const {
399 
400 	p_extensions->push_back("gd");
401 }
402 
get_public_functions(List<MethodInfo> * p_functions) const403 void GDScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const {
404 
405 	for (int i = 0; i < GDScriptFunctions::FUNC_MAX; i++) {
406 
407 		p_functions->push_back(GDScriptFunctions::get_info(GDScriptFunctions::Function(i)));
408 	}
409 
410 	//not really "functions", but..
411 	{
412 		MethodInfo mi;
413 		mi.name = "preload";
414 		mi.arguments.push_back(PropertyInfo(Variant::STRING, "path"));
415 		mi.return_val = PropertyInfo(Variant::OBJECT, "", PROPERTY_HINT_RESOURCE_TYPE, "Resource");
416 		p_functions->push_back(mi);
417 	}
418 	{
419 		MethodInfo mi;
420 		mi.name = "yield";
421 		mi.arguments.push_back(PropertyInfo(Variant::OBJECT, "object"));
422 		mi.arguments.push_back(PropertyInfo(Variant::STRING, "signal"));
423 		mi.default_arguments.push_back(Variant());
424 		mi.default_arguments.push_back(String());
425 		mi.return_val = PropertyInfo(Variant::OBJECT, "", PROPERTY_HINT_RESOURCE_TYPE, "GDScriptFunctionState");
426 		p_functions->push_back(mi);
427 	}
428 	{
429 		MethodInfo mi;
430 		mi.name = "assert";
431 		mi.return_val.type = Variant::NIL;
432 		mi.arguments.push_back(PropertyInfo(Variant::BOOL, "condition"));
433 		mi.arguments.push_back(PropertyInfo(Variant::STRING, "message"));
434 		mi.default_arguments.push_back(String());
435 		p_functions->push_back(mi);
436 	}
437 }
438 
get_public_constants(List<Pair<String,Variant>> * p_constants) const439 void GDScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_constants) const {
440 
441 	Pair<String, Variant> pi;
442 	pi.first = "PI";
443 	pi.second = Math_PI;
444 	p_constants->push_back(pi);
445 
446 	Pair<String, Variant> tau;
447 	tau.first = "TAU";
448 	tau.second = Math_TAU;
449 	p_constants->push_back(tau);
450 
451 	Pair<String, Variant> infinity;
452 	infinity.first = "INF";
453 	infinity.second = Math_INF;
454 	p_constants->push_back(infinity);
455 
456 	Pair<String, Variant> nan;
457 	nan.first = "NAN";
458 	nan.second = Math_NAN;
459 	p_constants->push_back(nan);
460 }
461 
make_function(const String & p_class,const String & p_name,const PoolStringArray & p_args) const462 String GDScriptLanguage::make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const {
463 
464 #ifdef TOOLS_ENABLED
465 	bool th = EditorSettings::get_singleton()->get_setting("text_editor/completion/add_type_hints");
466 #else
467 	bool th = false;
468 #endif
469 
470 	String s = "func " + p_name + "(";
471 	if (p_args.size()) {
472 		for (int i = 0; i < p_args.size(); i++) {
473 			if (i > 0)
474 				s += ", ";
475 			s += p_args[i].get_slice(":", 0);
476 			if (th) {
477 				String type = p_args[i].get_slice(":", 1);
478 				if (!type.empty() && type != "var") {
479 					s += ": " + type;
480 				}
481 			}
482 		}
483 	}
484 	s += String(")") + (th ? " -> void" : "") + ":\n" + _get_indentation() + "pass # Replace with function body.\n";
485 
486 	return s;
487 }
488 
489 //////// COMPLETION //////////
490 
491 #if defined(DEBUG_METHODS_ENABLED) && defined(TOOLS_ENABLED)
492 
493 struct GDScriptCompletionContext {
494 
495 	const GDScriptParser::ClassNode *_class;
496 	const GDScriptParser::FunctionNode *function;
497 	const GDScriptParser::BlockNode *block;
498 	Object *base;
499 	String base_path;
500 	int line;
501 	uint32_t depth;
502 
GDScriptCompletionContextGDScriptCompletionContext503 	GDScriptCompletionContext() :
504 			_class(NULL),
505 			function(NULL),
506 			block(NULL),
507 			base(NULL),
508 			line(0),
509 			depth(0) {}
510 };
511 
512 struct GDScriptCompletionIdentifier {
513 	GDScriptParser::DataType type;
514 	String enumeration;
515 	Variant value;
516 	const GDScriptParser::Node *assigned_expression;
517 
GDScriptCompletionIdentifierGDScriptCompletionIdentifier518 	GDScriptCompletionIdentifier() :
519 			assigned_expression(NULL) {}
520 };
521 
_get_directory_contents(EditorFileSystemDirectory * p_dir,Map<String,ScriptCodeCompletionOption> & r_list,String p_ends_with="")522 static void _get_directory_contents(EditorFileSystemDirectory *p_dir, Map<String, ScriptCodeCompletionOption> &r_list, String p_ends_with = "") {
523 
524 	const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\"";
525 
526 	for (int i = 0; i < p_dir->get_file_count(); i++) {
527 		ScriptCodeCompletionOption option(p_dir->get_file_path(i), ScriptCodeCompletionOption::KIND_FILE_PATH);
528 		option.insert_text = quote_style + option.display + quote_style;
529 		if (!p_ends_with.empty()) {
530 			if (option.display.ends_with(p_ends_with)) {
531 				r_list.insert(option.display, option);
532 			}
533 		} else {
534 			r_list.insert(option.display, option);
535 		}
536 	}
537 
538 	for (int i = 0; i < p_dir->get_subdir_count(); i++) {
539 		_get_directory_contents(p_dir->get_subdir(i), r_list, p_ends_with);
540 	}
541 }
542 
_get_visual_datatype(const PropertyInfo & p_info,bool p_isarg=true)543 static String _get_visual_datatype(const PropertyInfo &p_info, bool p_isarg = true) {
544 
545 	if (p_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
546 		String enum_name = p_info.class_name;
547 		if (enum_name.find(".") == -1) {
548 			return enum_name;
549 		}
550 		return enum_name.get_slice(".", 1);
551 	}
552 
553 	String n = p_info.name;
554 	int idx = n.find(":");
555 	if (idx != -1) {
556 		return n.substr(idx + 1, n.length());
557 	}
558 
559 	if (p_info.type == Variant::OBJECT) {
560 		if (p_info.hint == PROPERTY_HINT_RESOURCE_TYPE) {
561 			return p_info.hint_string;
562 		} else {
563 			return p_info.class_name.operator String();
564 		}
565 	}
566 	if (p_info.type == Variant::NIL) {
567 		if (p_isarg || (p_info.usage & PROPERTY_USAGE_NIL_IS_VARIANT)) {
568 			return "Variant";
569 		} else {
570 			return "void";
571 		}
572 	}
573 
574 	return Variant::get_type_name(p_info.type);
575 }
576 
_type_from_variant(const Variant & p_value)577 static GDScriptCompletionIdentifier _type_from_variant(const Variant &p_value) {
578 	GDScriptCompletionIdentifier ci;
579 	ci.value = p_value;
580 	ci.type.is_constant = true;
581 	ci.type.has_type = true;
582 	ci.type.kind = GDScriptParser::DataType::BUILTIN;
583 	ci.type.builtin_type = p_value.get_type();
584 
585 	if (ci.type.builtin_type == Variant::OBJECT) {
586 		Object *obj = p_value.operator Object *();
587 		if (!obj) {
588 			return ci;
589 		}
590 		ci.type.native_type = obj->get_class_name();
591 		Ref<Script> scr = p_value;
592 		if (scr.is_valid()) {
593 			ci.type.is_meta_type = true;
594 		} else {
595 			ci.type.is_meta_type = false;
596 			scr = obj->get_script();
597 		}
598 		if (scr.is_valid()) {
599 			ci.type.script_type = scr;
600 			Ref<GDScript> gds = scr;
601 			if (gds.is_valid()) {
602 				ci.type.kind = GDScriptParser::DataType::GDSCRIPT;
603 			} else {
604 				ci.type.kind = GDScriptParser::DataType::SCRIPT;
605 			}
606 			ci.type.native_type = scr->get_instance_base_type();
607 		} else {
608 			ci.type.kind = GDScriptParser::DataType::NATIVE;
609 		}
610 	}
611 
612 	return ci;
613 }
614 
_type_from_property(const PropertyInfo & p_property)615 static GDScriptCompletionIdentifier _type_from_property(const PropertyInfo &p_property) {
616 	GDScriptCompletionIdentifier ci;
617 
618 	if (p_property.type == Variant::NIL) {
619 		// Variant
620 		return ci;
621 	}
622 
623 	if (p_property.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
624 		ci.enumeration = p_property.class_name;
625 	}
626 
627 	ci.type.has_type = true;
628 	ci.type.builtin_type = p_property.type;
629 	if (p_property.type == Variant::OBJECT) {
630 		ci.type.kind = GDScriptParser::DataType::NATIVE;
631 		ci.type.native_type = p_property.class_name == StringName() ? "Object" : p_property.class_name;
632 	} else {
633 		ci.type.kind = GDScriptParser::DataType::BUILTIN;
634 	}
635 	return ci;
636 }
637 
_type_from_gdtype(const GDScriptDataType & p_gdtype)638 static GDScriptCompletionIdentifier _type_from_gdtype(const GDScriptDataType &p_gdtype) {
639 	GDScriptCompletionIdentifier ci;
640 	if (!p_gdtype.has_type) {
641 		return ci;
642 	}
643 
644 	ci.type.has_type = true;
645 	ci.type.builtin_type = p_gdtype.builtin_type;
646 	ci.type.native_type = p_gdtype.native_type;
647 	ci.type.script_type = p_gdtype.script_type;
648 
649 	switch (p_gdtype.kind) {
650 		case GDScriptDataType::UNINITIALIZED: {
651 			ERR_PRINT("Uninitialized completion. Please report a bug.");
652 		} break;
653 		case GDScriptDataType::BUILTIN: {
654 			ci.type.kind = GDScriptParser::DataType::BUILTIN;
655 		} break;
656 		case GDScriptDataType::NATIVE: {
657 			ci.type.kind = GDScriptParser::DataType::NATIVE;
658 		} break;
659 		case GDScriptDataType::GDSCRIPT: {
660 			ci.type.kind = GDScriptParser::DataType::GDSCRIPT;
661 		} break;
662 		case GDScriptDataType::SCRIPT: {
663 			ci.type.kind = GDScriptParser::DataType::SCRIPT;
664 		} break;
665 	}
666 	return ci;
667 }
668 
669 static bool _guess_identifier_type(GDScriptCompletionContext &p_context, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type);
670 static bool _guess_identifier_type_from_base(GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type);
671 static bool _guess_method_return_type_from_base(GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_method, GDScriptCompletionIdentifier &r_type);
672 
_guess_expression_type(GDScriptCompletionContext & p_context,const GDScriptParser::Node * p_expression,GDScriptCompletionIdentifier & r_type)673 static bool _guess_expression_type(GDScriptCompletionContext &p_context, const GDScriptParser::Node *p_expression, GDScriptCompletionIdentifier &r_type) {
674 	bool found = false;
675 
676 	if (++p_context.depth > 100) {
677 		print_error("Maximum _guess_expression_type depth limit reached. Please file a bugreport.");
678 		return false;
679 	}
680 
681 	switch (p_expression->type) {
682 		case GDScriptParser::Node::TYPE_CONSTANT: {
683 			const GDScriptParser::ConstantNode *cn = static_cast<const GDScriptParser::ConstantNode *>(p_expression);
684 			r_type = _type_from_variant(cn->value);
685 			found = true;
686 		} break;
687 		case GDScriptParser::Node::TYPE_SELF: {
688 			if (p_context._class) {
689 				r_type.type.has_type = true;
690 				r_type.type.kind = GDScriptParser::DataType::CLASS;
691 				r_type.type.class_type = const_cast<GDScriptParser::ClassNode *>(p_context._class);
692 				r_type.type.is_constant = true;
693 				r_type.value = p_context.base;
694 				found = true;
695 			}
696 		} break;
697 		case GDScriptParser::Node::TYPE_IDENTIFIER: {
698 			const GDScriptParser::IdentifierNode *id = static_cast<const GDScriptParser::IdentifierNode *>(p_expression);
699 			found = _guess_identifier_type(p_context, id->name, r_type);
700 		} break;
701 		case GDScriptParser::Node::TYPE_DICTIONARY: {
702 			// Try to recreate the dictionary
703 			const GDScriptParser::DictionaryNode *dn = static_cast<const GDScriptParser::DictionaryNode *>(p_expression);
704 			Dictionary d;
705 			bool full = true;
706 			for (int i = 0; i < dn->elements.size(); i++) {
707 				GDScriptCompletionIdentifier key;
708 				if (_guess_expression_type(p_context, dn->elements[i].key, key)) {
709 					GDScriptCompletionIdentifier value;
710 					if (_guess_expression_type(p_context, dn->elements[i].value, value)) {
711 						if (!value.type.is_constant) {
712 							full = false;
713 							break;
714 						}
715 						d[key.value] = value.value;
716 					} else {
717 						full = false;
718 						break;
719 					}
720 				} else {
721 					full = false;
722 					break;
723 				}
724 			}
725 			if (full) {
726 				// If not fully constant, setting this value is detrimental to the inference
727 				r_type.value = d;
728 				r_type.type.is_constant = true;
729 			}
730 			r_type.type.has_type = true;
731 			r_type.type.kind = GDScriptParser::DataType::BUILTIN;
732 			r_type.type.builtin_type = Variant::DICTIONARY;
733 		} break;
734 		case GDScriptParser::Node::TYPE_ARRAY: {
735 			// Try to recreate the array
736 			const GDScriptParser::ArrayNode *an = static_cast<const GDScriptParser::ArrayNode *>(p_expression);
737 			Array a;
738 			bool full = true;
739 			a.resize(an->elements.size());
740 			for (int i = 0; i < an->elements.size(); i++) {
741 				GDScriptCompletionIdentifier value;
742 				if (_guess_expression_type(p_context, an->elements[i], value)) {
743 					a[i] = value.value;
744 				} else {
745 					full = false;
746 					break;
747 				}
748 			}
749 			if (full) {
750 				// If not fully constant, setting this value is detrimental to the inference
751 				r_type.value = a;
752 			}
753 			r_type.type.has_type = true;
754 			r_type.type.kind = GDScriptParser::DataType::BUILTIN;
755 			r_type.type.builtin_type = Variant::ARRAY;
756 		} break;
757 		case GDScriptParser::Node::TYPE_CAST: {
758 			const GDScriptParser::CastNode *cn = static_cast<const GDScriptParser::CastNode *>(p_expression);
759 			GDScriptCompletionIdentifier value;
760 			if (_guess_expression_type(p_context, cn->source_node, r_type)) {
761 				r_type.type = cn->get_datatype();
762 				found = true;
763 			}
764 		} break;
765 		case GDScriptParser::Node::TYPE_OPERATOR: {
766 			const GDScriptParser::OperatorNode *op = static_cast<const GDScriptParser::OperatorNode *>(p_expression);
767 			switch (op->op) {
768 				case GDScriptParser::OperatorNode::OP_CALL: {
769 					if (op->arguments[0]->type == GDScriptParser::Node::TYPE_TYPE) {
770 						const GDScriptParser::TypeNode *tn = static_cast<const GDScriptParser::TypeNode *>(op->arguments[0]);
771 						r_type.type.has_type = true;
772 						r_type.type.kind = GDScriptParser::DataType::BUILTIN;
773 						r_type.type.builtin_type = tn->vtype;
774 						found = true;
775 						break;
776 					} else if (op->arguments[0]->type == GDScriptParser::Node::TYPE_BUILT_IN_FUNCTION) {
777 						const GDScriptParser::BuiltInFunctionNode *bin = static_cast<const GDScriptParser::BuiltInFunctionNode *>(op->arguments[0]);
778 						MethodInfo mi = GDScriptFunctions::get_info(bin->function);
779 						r_type = _type_from_property(mi.return_val);
780 						found = true;
781 						break;
782 					} else if (op->arguments.size() >= 2 && op->arguments[1]->type == GDScriptParser::Node::TYPE_IDENTIFIER) {
783 						StringName id = static_cast<const GDScriptParser::IdentifierNode *>(op->arguments[1])->name;
784 
785 						GDScriptCompletionContext c = p_context;
786 						c.line = op->line;
787 
788 						GDScriptCompletionIdentifier base;
789 						if (!_guess_expression_type(c, op->arguments[0], base)) {
790 							found = false;
791 							break;
792 						}
793 
794 						// Try call if constant methods with constant arguments
795 						if (base.type.is_constant && base.value.get_type() == Variant::OBJECT) {
796 							GDScriptParser::DataType native_type = base.type;
797 
798 							while (native_type.kind == GDScriptParser::DataType::CLASS) {
799 								native_type = native_type.class_type->base_type;
800 							}
801 
802 							while (native_type.kind == GDScriptParser::DataType::GDSCRIPT || native_type.kind == GDScriptParser::DataType::SCRIPT) {
803 								if (native_type.script_type.is_valid()) {
804 									Ref<Script> parent = native_type.script_type->get_base_script();
805 									if (parent.is_valid()) {
806 										native_type.script_type = parent;
807 									} else {
808 										native_type.kind = GDScriptParser::DataType::NATIVE;
809 										native_type.native_type = native_type.script_type->get_instance_base_type();
810 										if (!ClassDB::class_exists(native_type.native_type)) {
811 											native_type.native_type = String("_") + native_type.native_type;
812 											if (!ClassDB::class_exists(native_type.native_type)) {
813 												native_type.has_type = false;
814 											}
815 										}
816 									}
817 								}
818 							}
819 
820 							if (native_type.has_type && native_type.kind == GDScriptParser::DataType::NATIVE) {
821 								MethodBind *mb = ClassDB::get_method(native_type.native_type, id);
822 								if (mb && mb->is_const()) {
823 									bool all_is_const = true;
824 									Vector<Variant> args;
825 									GDScriptCompletionContext c2 = p_context;
826 									c2.line = op->line;
827 									for (int i = 2; all_is_const && i < op->arguments.size(); i++) {
828 										GDScriptCompletionIdentifier arg;
829 
830 										if (_guess_expression_type(c2, op->arguments[i], arg)) {
831 											if (arg.type.has_type && arg.type.is_constant && arg.value.get_type() != Variant::OBJECT) {
832 												args.push_back(arg.value);
833 											} else {
834 												all_is_const = false;
835 											}
836 										} else {
837 											all_is_const = false;
838 										}
839 									}
840 
841 									Object *baseptr = base.value;
842 
843 									if (all_is_const && String(id) == "get_node" && ClassDB::is_parent_class(native_type.native_type, "Node") && args.size()) {
844 
845 										String arg1 = args[0];
846 										if (arg1.begins_with("/root/")) {
847 											String which = arg1.get_slice("/", 2);
848 											if (which != "") {
849 												// Try singletons first
850 												if (GDScriptLanguage::get_singleton()->get_named_globals_map().has(which)) {
851 													r_type = _type_from_variant(GDScriptLanguage::get_singleton()->get_named_globals_map()[which]);
852 													found = true;
853 												} else {
854 													List<PropertyInfo> props;
855 													ProjectSettings::get_singleton()->get_property_list(&props);
856 
857 													for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
858 
859 														String s = E->get().name;
860 														if (!s.begins_with("autoload/")) {
861 															continue;
862 														}
863 														String name = s.get_slice("/", 1);
864 														if (name == which) {
865 															String script = ProjectSettings::get_singleton()->get(s);
866 
867 															if (script.begins_with("*")) {
868 																script = script.right(1);
869 															}
870 
871 															if (!script.begins_with("res://")) {
872 																script = "res://" + script;
873 															}
874 
875 															if (!script.ends_with(".gd")) {
876 																//not a script, try find the script anyway,
877 																//may have some success
878 																script = script.get_basename() + ".gd";
879 															}
880 
881 															if (FileAccess::exists(script)) {
882 																Ref<Script> scr;
883 																if (ScriptCodeCompletionCache::get_singleton()) {
884 																	scr = ScriptCodeCompletionCache::get_singleton()->get_cached_resource(script);
885 																} else {
886 																	scr = ResourceLoader::load(script);
887 																}
888 																if (scr.is_valid()) {
889 																	r_type.type.has_type = true;
890 																	r_type.type.script_type = scr;
891 																	r_type.type.is_constant = false;
892 																	Ref<GDScript> gds = scr;
893 																	if (gds.is_valid()) {
894 																		r_type.type.kind = GDScriptParser::DataType::GDSCRIPT;
895 																	} else {
896 																		r_type.type.kind = GDScriptParser::DataType::SCRIPT;
897 																	}
898 																	r_type.value = Variant();
899 																	found = true;
900 																}
901 															}
902 															break;
903 														}
904 													}
905 												}
906 											}
907 										}
908 									}
909 
910 									if (!found && all_is_const && baseptr) {
911 										Vector<const Variant *> argptr;
912 										for (int i = 0; i < args.size(); i++) {
913 											argptr.push_back(&args[i]);
914 										}
915 
916 										Variant::CallError ce;
917 										Variant ret = mb->call(baseptr, (const Variant **)argptr.ptr(), argptr.size(), ce);
918 
919 										if (ce.error == Variant::CallError::CALL_OK && ret.get_type() != Variant::NIL) {
920 											if (ret.get_type() != Variant::OBJECT || ret.operator Object *() != NULL) {
921 												r_type = _type_from_variant(ret);
922 												found = true;
923 											}
924 										}
925 									}
926 								}
927 							}
928 						}
929 
930 						if (!found) {
931 							found = _guess_method_return_type_from_base(c, base, id, r_type);
932 						}
933 					}
934 				} break;
935 				case GDScriptParser::OperatorNode::OP_PARENT_CALL: {
936 					if (!p_context._class || !op->arguments.size() || op->arguments[0]->type != GDScriptParser::Node::TYPE_IDENTIFIER) {
937 						break;
938 					}
939 
940 					StringName id = static_cast<const GDScriptParser::IdentifierNode *>(op->arguments[0])->name;
941 
942 					GDScriptCompletionIdentifier base;
943 					base.value = p_context.base;
944 					base.type = p_context._class->base_type;
945 
946 					GDScriptCompletionContext c = p_context;
947 					c.line = op->line;
948 
949 					found = _guess_method_return_type_from_base(c, base, id, r_type);
950 				} break;
951 				case GDScriptParser::OperatorNode::OP_INDEX_NAMED: {
952 					if (op->arguments.size() < 2 || op->arguments[1]->type != GDScriptParser::Node::TYPE_IDENTIFIER) {
953 						found = false;
954 						break;
955 					}
956 					const GDScriptParser::IdentifierNode *id = static_cast<const GDScriptParser::IdentifierNode *>(op->arguments[1]);
957 
958 					GDScriptCompletionContext c = p_context;
959 					c.line = op->line;
960 
961 					GDScriptCompletionIdentifier base;
962 					if (!_guess_expression_type(c, op->arguments[0], base)) {
963 						found = false;
964 						break;
965 					}
966 
967 					if (base.value.get_type() == Variant::DICTIONARY && base.value.operator Dictionary().has(String(id->name))) {
968 						Variant value = base.value.operator Dictionary()[String(id->name)];
969 						r_type = _type_from_variant(value);
970 						found = true;
971 						break;
972 					}
973 
974 					const GDScriptParser::DictionaryNode *dn = NULL;
975 					if (op->arguments[0]->type == GDScriptParser::Node::TYPE_DICTIONARY) {
976 						dn = static_cast<const GDScriptParser::DictionaryNode *>(op->arguments[0]);
977 					} else if (base.assigned_expression && base.assigned_expression->type == GDScriptParser::Node::TYPE_DICTIONARY) {
978 						dn = static_cast<const GDScriptParser::DictionaryNode *>(base.assigned_expression);
979 					}
980 
981 					if (dn) {
982 						for (int i = 0; i < dn->elements.size(); i++) {
983 							GDScriptCompletionIdentifier key;
984 							if (!_guess_expression_type(c, dn->elements[i].key, key)) {
985 								continue;
986 							}
987 							if (key.value == String(id->name)) {
988 								r_type.assigned_expression = dn->elements[i].value;
989 								found = _guess_expression_type(c, dn->elements[i].value, r_type);
990 								break;
991 							}
992 						}
993 					}
994 
995 					if (!found) {
996 						found = _guess_identifier_type_from_base(c, base, id->name, r_type);
997 					}
998 				} break;
999 				case GDScriptParser::OperatorNode::OP_INDEX: {
1000 					if (op->arguments.size() < 2) {
1001 						found = false;
1002 						break;
1003 					}
1004 
1005 					GDScriptCompletionContext c = p_context;
1006 					c.line = op->line;
1007 
1008 					GDScriptCompletionIdentifier base;
1009 					if (!_guess_expression_type(c, op->arguments[0], base)) {
1010 						found = false;
1011 						break;
1012 					}
1013 
1014 					GDScriptCompletionIdentifier index;
1015 					if (!_guess_expression_type(c, op->arguments[1], index)) {
1016 						found = false;
1017 						break;
1018 					}
1019 
1020 					if (base.value.in(index.value)) {
1021 						Variant value = base.value.get(index.value);
1022 						r_type = _type_from_variant(value);
1023 						found = true;
1024 						break;
1025 					}
1026 
1027 					// Look if it is a dictionary node
1028 					const GDScriptParser::DictionaryNode *dn = NULL;
1029 					if (op->arguments[0]->type == GDScriptParser::Node::TYPE_DICTIONARY) {
1030 						dn = static_cast<const GDScriptParser::DictionaryNode *>(op->arguments[0]);
1031 					} else if (base.assigned_expression && base.assigned_expression->type == GDScriptParser::Node::TYPE_DICTIONARY) {
1032 						dn = static_cast<const GDScriptParser::DictionaryNode *>(base.assigned_expression);
1033 					}
1034 
1035 					if (dn) {
1036 						for (int i = 0; i < dn->elements.size(); i++) {
1037 							GDScriptCompletionIdentifier key;
1038 							if (!_guess_expression_type(c, dn->elements[i].key, key)) {
1039 								continue;
1040 							}
1041 							if (key.value == index.value) {
1042 								r_type.assigned_expression = dn->elements[i].value;
1043 								found = _guess_expression_type(p_context, dn->elements[i].value, r_type);
1044 								break;
1045 							}
1046 						}
1047 					}
1048 
1049 					// Look if it is an array node
1050 					if (!found && index.value.is_num()) {
1051 						int idx = index.value;
1052 						const GDScriptParser::ArrayNode *an = NULL;
1053 						if (op->arguments[0]->type == GDScriptParser::Node::TYPE_ARRAY) {
1054 							an = static_cast<const GDScriptParser::ArrayNode *>(op->arguments[0]);
1055 						} else if (base.assigned_expression && base.assigned_expression->type == GDScriptParser::Node::TYPE_ARRAY) {
1056 							an = static_cast<const GDScriptParser::ArrayNode *>(base.assigned_expression);
1057 						}
1058 
1059 						if (an && idx >= 0 && an->elements.size() > idx) {
1060 							r_type.assigned_expression = an->elements[idx];
1061 							found = _guess_expression_type(c, an->elements[idx], r_type);
1062 							break;
1063 						}
1064 					}
1065 
1066 					// Look for valid indexing in other types
1067 					if (!found && (index.value.get_type() == Variant::STRING || index.value.get_type() == Variant::NODE_PATH)) {
1068 						StringName id = index.value;
1069 						found = _guess_identifier_type_from_base(c, base, id, r_type);
1070 					} else if (!found && index.type.kind == GDScriptParser::DataType::BUILTIN) {
1071 						Variant::CallError err;
1072 						Variant base_val = Variant::construct(base.type.builtin_type, NULL, 0, err);
1073 						bool valid = false;
1074 						Variant res = base_val.get(index.value, &valid);
1075 						if (valid) {
1076 							r_type = _type_from_variant(res);
1077 							r_type.value = Variant();
1078 							r_type.type.is_constant = false;
1079 							found = true;
1080 						}
1081 					}
1082 				} break;
1083 				default: {
1084 					if (op->arguments.size() < 2) {
1085 						found = false;
1086 						break;
1087 					}
1088 
1089 					Variant::Operator vop = Variant::OP_MAX;
1090 					switch (op->op) {
1091 						case GDScriptParser::OperatorNode::OP_ADD: vop = Variant::OP_ADD; break;
1092 						case GDScriptParser::OperatorNode::OP_SUB: vop = Variant::OP_SUBTRACT; break;
1093 						case GDScriptParser::OperatorNode::OP_MUL: vop = Variant::OP_MULTIPLY; break;
1094 						case GDScriptParser::OperatorNode::OP_DIV: vop = Variant::OP_DIVIDE; break;
1095 						case GDScriptParser::OperatorNode::OP_MOD: vop = Variant::OP_MODULE; break;
1096 						case GDScriptParser::OperatorNode::OP_SHIFT_LEFT: vop = Variant::OP_SHIFT_LEFT; break;
1097 						case GDScriptParser::OperatorNode::OP_SHIFT_RIGHT: vop = Variant::OP_SHIFT_RIGHT; break;
1098 						case GDScriptParser::OperatorNode::OP_BIT_AND: vop = Variant::OP_BIT_AND; break;
1099 						case GDScriptParser::OperatorNode::OP_BIT_OR: vop = Variant::OP_BIT_OR; break;
1100 						case GDScriptParser::OperatorNode::OP_BIT_XOR: vop = Variant::OP_BIT_XOR; break;
1101 						default: {
1102 						}
1103 					}
1104 
1105 					if (vop == Variant::OP_MAX) {
1106 						break;
1107 					}
1108 
1109 					GDScriptCompletionContext context = p_context;
1110 					context.line = op->line;
1111 
1112 					GDScriptCompletionIdentifier p1;
1113 					GDScriptCompletionIdentifier p2;
1114 
1115 					if (!_guess_expression_type(context, op->arguments[0], p1)) {
1116 						found = false;
1117 						break;
1118 					}
1119 
1120 					if (!_guess_expression_type(context, op->arguments[1], p2)) {
1121 						found = false;
1122 						break;
1123 					}
1124 
1125 					Variant::CallError ce;
1126 					bool v1_use_value = p1.value.get_type() != Variant::NIL && p1.value.get_type() != Variant::OBJECT;
1127 					Variant v1 = (v1_use_value) ? p1.value : Variant::construct(p1.type.builtin_type, NULL, 0, ce);
1128 					bool v2_use_value = p2.value.get_type() != Variant::NIL && p2.value.get_type() != Variant::OBJECT;
1129 					Variant v2 = (v2_use_value) ? p2.value : Variant::construct(p2.type.builtin_type, NULL, 0, ce);
1130 					// avoid potential invalid ops
1131 					if ((vop == Variant::OP_DIVIDE || vop == Variant::OP_MODULE) && v2.get_type() == Variant::INT) {
1132 						v2 = 1;
1133 						v2_use_value = false;
1134 					}
1135 					if (vop == Variant::OP_DIVIDE && v2.get_type() == Variant::REAL) {
1136 						v2 = 1.0;
1137 						v2_use_value = false;
1138 					}
1139 
1140 					Variant res;
1141 					bool valid;
1142 					Variant::evaluate(vop, v1, v2, res, valid);
1143 					if (!valid) {
1144 						found = false;
1145 						break;
1146 					}
1147 					r_type = _type_from_variant(res);
1148 					if (!v1_use_value || !v2_use_value) {
1149 						r_type.value = Variant();
1150 						r_type.type.is_constant = false;
1151 					}
1152 
1153 					found = true;
1154 				} break;
1155 			}
1156 		} break;
1157 		default: {
1158 		}
1159 	}
1160 
1161 	// It may have found a null, but that's never useful
1162 	if (found && r_type.type.has_type && r_type.type.kind == GDScriptParser::DataType::BUILTIN && r_type.type.builtin_type == Variant::NIL) {
1163 		found = false;
1164 	}
1165 
1166 	// Check type hint last. For collections we want chance to get the actual value first
1167 	// This way we can detect types from the content of dictionaries and arrays
1168 	if (!found && p_expression->get_datatype().has_type) {
1169 		r_type.type = p_expression->get_datatype();
1170 		if (!r_type.assigned_expression) {
1171 			r_type.assigned_expression = p_expression;
1172 		}
1173 		found = true;
1174 	}
1175 
1176 	return found;
1177 }
1178 
_guess_identifier_type(GDScriptCompletionContext & p_context,const StringName & p_identifier,GDScriptCompletionIdentifier & r_type)1179 static bool _guess_identifier_type(GDScriptCompletionContext &p_context, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type) {
1180 
1181 	// Look in blocks first
1182 	const GDScriptParser::BlockNode *blk = p_context.block;
1183 	int last_assign_line = -1;
1184 	const GDScriptParser::Node *last_assigned_expression = NULL;
1185 	GDScriptParser::DataType var_type;
1186 	while (blk) {
1187 		if (blk->variables.has(p_identifier)) {
1188 			if (blk->variables[p_identifier]->line > p_context.line) {
1189 				return false;
1190 			}
1191 
1192 			var_type = blk->variables[p_identifier]->datatype;
1193 
1194 			if (!last_assigned_expression && blk->variables[p_identifier]->assign && blk->variables[p_identifier]->assign->type == GDScriptParser::Node::TYPE_OPERATOR) {
1195 				const GDScriptParser::OperatorNode *op = static_cast<const GDScriptParser::OperatorNode *>(blk->variables[p_identifier]->assign);
1196 				if (op->op == GDScriptParser::OperatorNode::OP_ASSIGN && op->arguments.size() >= 2) {
1197 					last_assign_line = op->line;
1198 					last_assigned_expression = op->arguments[1];
1199 				}
1200 			}
1201 		}
1202 
1203 		for (const List<GDScriptParser::Node *>::Element *E = blk->statements.front(); E; E = E->next()) {
1204 			const GDScriptParser::Node *expr = E->get();
1205 			if (expr->line > p_context.line || expr->type != GDScriptParser::Node::TYPE_OPERATOR) {
1206 				continue;
1207 			}
1208 
1209 			const GDScriptParser::OperatorNode *op = static_cast<const GDScriptParser::OperatorNode *>(expr);
1210 			if (op->op != GDScriptParser::OperatorNode::OP_ASSIGN || op->line < last_assign_line) {
1211 				continue;
1212 			}
1213 
1214 			if (op->arguments.size() >= 2 && op->arguments[0]->type == GDScriptParser::Node::TYPE_IDENTIFIER) {
1215 				const GDScriptParser::IdentifierNode *id = static_cast<const GDScriptParser::IdentifierNode *>(op->arguments[0]);
1216 				if (id->name == p_identifier) {
1217 					last_assign_line = op->line;
1218 					last_assigned_expression = op->arguments[1];
1219 				}
1220 			}
1221 		}
1222 
1223 		if (blk->if_condition && blk->if_condition->type == GDScriptParser::Node::TYPE_OPERATOR && static_cast<const GDScriptParser::OperatorNode *>(blk->if_condition)->op == GDScriptParser::OperatorNode::OP_IS) {
1224 			//is used, check if identifier is in there! this helps resolve in blocks that are (if (identifier is value)): which are very common..
1225 			//super dirty hack, but very useful
1226 			//credit: Zylann
1227 			//TODO: this could be hacked to detect ANDed conditions too..
1228 			const GDScriptParser::OperatorNode *op = static_cast<const GDScriptParser::OperatorNode *>(blk->if_condition);
1229 			if (op->arguments[0]->type == GDScriptParser::Node::TYPE_IDENTIFIER && static_cast<const GDScriptParser::IdentifierNode *>(op->arguments[0])->name == p_identifier) {
1230 				//bingo
1231 				GDScriptCompletionContext c = p_context;
1232 				c.line = op->line;
1233 				c.block = blk;
1234 				if (_guess_expression_type(p_context, op->arguments[1], r_type)) {
1235 					r_type.type.is_meta_type = false; // Right-hand of `is` will be a meta type, but the left-hand value is not
1236 					// Not an assignment, it shouldn't carry any value
1237 					r_type.value = Variant();
1238 					r_type.assigned_expression = NULL;
1239 
1240 					return true;
1241 				}
1242 			}
1243 		}
1244 
1245 		blk = blk->parent_block;
1246 	}
1247 
1248 	if (last_assigned_expression && last_assign_line != p_context.line) {
1249 		GDScriptCompletionContext c = p_context;
1250 		c.line = last_assign_line;
1251 		r_type.assigned_expression = last_assigned_expression;
1252 		if (_guess_expression_type(c, last_assigned_expression, r_type)) {
1253 			if (var_type.has_type) {
1254 				r_type.type = var_type;
1255 			}
1256 			return true;
1257 		}
1258 	}
1259 
1260 	if (var_type.has_type) {
1261 		r_type.type = var_type;
1262 		return true;
1263 	}
1264 
1265 	if (p_context.function) {
1266 		for (int i = 0; i < p_context.function->arguments.size(); i++) {
1267 			if (p_context.function->arguments[i] == p_identifier) {
1268 				if (p_context.function->argument_types[i].has_type) {
1269 					r_type.type = p_context.function->argument_types[i];
1270 					return true;
1271 				}
1272 
1273 				int def_from = p_context.function->arguments.size() - p_context.function->default_values.size();
1274 				if (i >= def_from) {
1275 					int def_idx = i - def_from;
1276 					if (p_context.function->default_values[def_idx]->type == GDScriptParser::Node::TYPE_OPERATOR) {
1277 						const GDScriptParser::OperatorNode *op = static_cast<const GDScriptParser::OperatorNode *>(p_context.function->default_values[def_idx]);
1278 						if (op->arguments.size() < 2) {
1279 							return false;
1280 						}
1281 						GDScriptCompletionContext c = p_context;
1282 						c.function = NULL;
1283 						c.block = NULL;
1284 						return _guess_expression_type(c, op->arguments[1], r_type);
1285 					}
1286 				}
1287 				break;
1288 			}
1289 		}
1290 
1291 		GDScriptParser::DataType base_type = p_context._class->base_type;
1292 		while (base_type.has_type) {
1293 			switch (base_type.kind) {
1294 				case GDScriptParser::DataType::GDSCRIPT: {
1295 					Ref<GDScript> gds = base_type.script_type;
1296 					if (gds.is_valid() && gds->has_method(p_context.function->name)) {
1297 						GDScriptFunction *func = gds->get_member_functions()[p_context.function->name];
1298 						if (func) {
1299 							for (int i = 0; i < func->get_argument_count(); i++) {
1300 								if (func->get_argument_name(i) == p_identifier) {
1301 									r_type = _type_from_gdtype(func->get_argument_type(i));
1302 									return true;
1303 								}
1304 							}
1305 						}
1306 						Ref<GDScript> base_gds = gds->get_base_script();
1307 						if (base_gds.is_valid()) {
1308 							base_type.kind = GDScriptParser::DataType::GDSCRIPT;
1309 							base_type.script_type = base_gds;
1310 						} else {
1311 							base_type.kind = GDScriptParser::DataType::NATIVE;
1312 							base_type.native_type = gds->get_instance_base_type();
1313 						}
1314 					} else {
1315 						base_type.kind = GDScriptParser::DataType::NATIVE;
1316 						base_type.native_type = gds->get_instance_base_type();
1317 					}
1318 				} break;
1319 				case GDScriptParser::DataType::NATIVE: {
1320 					List<MethodInfo> methods;
1321 					ClassDB::get_method_list(base_type.native_type, &methods);
1322 					ClassDB::get_virtual_methods(base_type.native_type, &methods);
1323 
1324 					for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
1325 						if (E->get().name == p_context.function->name) {
1326 							MethodInfo &mi = E->get();
1327 							for (List<PropertyInfo>::Element *F = mi.arguments.front(); F; F = F->next()) {
1328 								if (F->get().name == p_identifier) {
1329 									r_type = _type_from_property(F->get());
1330 									return true;
1331 								}
1332 							}
1333 						}
1334 					}
1335 					base_type.has_type = false;
1336 				} break;
1337 				default: {
1338 					base_type.has_type = false;
1339 				} break;
1340 			}
1341 		}
1342 	}
1343 
1344 	// Check current class (including inheritance)
1345 	if (p_context._class) {
1346 		GDScriptCompletionIdentifier context_base;
1347 		context_base.value = p_context.base;
1348 		context_base.type.has_type = true;
1349 		context_base.type.kind = GDScriptParser::DataType::CLASS;
1350 		context_base.type.class_type = const_cast<GDScriptParser::ClassNode *>(p_context._class);
1351 		context_base.type.is_meta_type = p_context.function && p_context.function->_static;
1352 
1353 		if (_guess_identifier_type_from_base(p_context, context_base, p_identifier, r_type)) {
1354 			return true;
1355 		}
1356 	}
1357 
1358 	// Check named scripts
1359 	if (ScriptServer::is_global_class(p_identifier)) {
1360 		Ref<Script> scr = ResourceLoader::load(ScriptServer::get_global_class_path(p_identifier));
1361 		if (scr.is_valid()) {
1362 			r_type = _type_from_variant(scr);
1363 			r_type.type.is_meta_type = true;
1364 			return true;
1365 		}
1366 		return false;
1367 	}
1368 
1369 	for (int i = 0; i < 2; i++) {
1370 		StringName target_id;
1371 		switch (i) {
1372 			case 0:
1373 				// Check ClassDB
1374 				target_id = p_identifier;
1375 				break;
1376 			case 1:
1377 				// ClassDB again for underscore-prefixed classes
1378 				target_id = String("_") + p_identifier;
1379 				break;
1380 		}
1381 
1382 		if (ClassDB::class_exists(target_id)) {
1383 			r_type.type.has_type = true;
1384 			r_type.type.kind = GDScriptParser::DataType::NATIVE;
1385 			r_type.type.native_type = target_id;
1386 			if (Engine::get_singleton()->has_singleton(target_id)) {
1387 				r_type.type.is_meta_type = false;
1388 				r_type.value = Engine::get_singleton()->get_singleton_object(target_id);
1389 			} else {
1390 				r_type.type.is_meta_type = true;
1391 				const Map<StringName, int>::Element *target_elem = GDScriptLanguage::get_singleton()->get_global_map().find(target_id);
1392 				// Check because classes like EditorNode are in ClassDB by now, but unknown to GDScript
1393 				if (!target_elem) {
1394 					return false;
1395 				}
1396 				int idx = target_elem->get();
1397 				r_type.value = GDScriptLanguage::get_singleton()->get_global_array()[idx];
1398 			}
1399 			return true;
1400 		}
1401 	}
1402 
1403 	// Check autoload singletons
1404 	if (GDScriptLanguage::get_singleton()->get_named_globals_map().has(p_identifier)) {
1405 		r_type = _type_from_variant(GDScriptLanguage::get_singleton()->get_named_globals_map()[p_identifier]);
1406 		return true;
1407 	}
1408 
1409 	return false;
1410 }
1411 
_guess_identifier_type_from_base(GDScriptCompletionContext & p_context,const GDScriptCompletionIdentifier & p_base,const StringName & p_identifier,GDScriptCompletionIdentifier & r_type)1412 static bool _guess_identifier_type_from_base(GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type) {
1413 	GDScriptParser::DataType base_type = p_base.type;
1414 	bool _static = base_type.is_meta_type;
1415 	while (base_type.has_type) {
1416 		switch (base_type.kind) {
1417 			case GDScriptParser::DataType::CLASS: {
1418 				if (base_type.class_type->constant_expressions.has(p_identifier)) {
1419 					GDScriptParser::ClassNode::Constant c = base_type.class_type->constant_expressions[p_identifier];
1420 					r_type.type = c.type;
1421 					if (c.expression->type == GDScriptParser::Node::TYPE_CONSTANT) {
1422 						r_type.value = static_cast<const GDScriptParser::ConstantNode *>(c.expression)->value;
1423 					}
1424 					return true;
1425 				}
1426 
1427 				if (!_static) {
1428 					for (int i = 0; i < base_type.class_type->variables.size(); i++) {
1429 						GDScriptParser::ClassNode::Member m = base_type.class_type->variables[i];
1430 						if (m.identifier == p_identifier) {
1431 							if (m.expression) {
1432 								if (p_context.line == m.expression->line) {
1433 									// Variable used in the same expression
1434 									return false;
1435 								}
1436 								if (_guess_expression_type(p_context, m.expression, r_type)) {
1437 									return true;
1438 								}
1439 								if (m.expression->get_datatype().has_type) {
1440 									r_type.type = m.expression->get_datatype();
1441 									return true;
1442 								}
1443 							}
1444 							if (m.data_type.has_type) {
1445 								r_type.type = m.data_type;
1446 								return true;
1447 							}
1448 							return false;
1449 						}
1450 					}
1451 				}
1452 				base_type = base_type.class_type->base_type;
1453 			} break;
1454 			case GDScriptParser::DataType::GDSCRIPT: {
1455 				Ref<GDScript> gds = base_type.script_type;
1456 				if (gds.is_valid()) {
1457 					if (gds->get_constants().has(p_identifier)) {
1458 						r_type = _type_from_variant(gds->get_constants()[p_identifier]);
1459 						return true;
1460 					}
1461 					if (!_static) {
1462 						const Set<StringName>::Element *m = gds->get_members().find(p_identifier);
1463 						if (m) {
1464 							r_type = _type_from_gdtype(gds->get_member_type(p_identifier));
1465 							return true;
1466 						}
1467 					}
1468 					Ref<GDScript> parent = gds->get_base_script();
1469 					if (parent.is_valid()) {
1470 						base_type.script_type = parent;
1471 					} else {
1472 						base_type.kind = GDScriptParser::DataType::NATIVE;
1473 						base_type.native_type = gds->get_instance_base_type();
1474 					}
1475 				} else {
1476 					return false;
1477 				}
1478 			} break;
1479 			case GDScriptParser::DataType::SCRIPT: {
1480 				Ref<Script> scr = base_type.script_type;
1481 				if (scr.is_valid()) {
1482 					Map<StringName, Variant> constants;
1483 					scr->get_constants(&constants);
1484 					if (constants.has(p_identifier)) {
1485 						r_type = _type_from_variant(constants[p_identifier]);
1486 						return true;
1487 					}
1488 
1489 					if (!_static) {
1490 						List<PropertyInfo> members;
1491 						scr->get_script_property_list(&members);
1492 						for (const List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) {
1493 							const PropertyInfo &prop = E->get();
1494 							if (prop.name == p_identifier) {
1495 								r_type = _type_from_property(prop);
1496 								return true;
1497 							}
1498 						}
1499 					}
1500 					Ref<Script> parent = scr->get_base_script();
1501 					if (parent.is_valid()) {
1502 						base_type.script_type = parent;
1503 					} else {
1504 						base_type.kind = GDScriptParser::DataType::NATIVE;
1505 						base_type.native_type = scr->get_instance_base_type();
1506 					}
1507 				} else {
1508 					return false;
1509 				}
1510 			} break;
1511 			case GDScriptParser::DataType::NATIVE: {
1512 				StringName class_name = base_type.native_type;
1513 				if (!ClassDB::class_exists(class_name)) {
1514 					class_name = String("_") + class_name;
1515 					if (!ClassDB::class_exists(class_name)) {
1516 						return false;
1517 					}
1518 				}
1519 
1520 				// Skip constants since they're all integers. Type does not matter because int has no members
1521 
1522 				List<PropertyInfo> props;
1523 				ClassDB::get_property_list(class_name, &props);
1524 				for (const List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
1525 					const PropertyInfo &prop = E->get();
1526 					if (prop.name == p_identifier) {
1527 						StringName getter = ClassDB::get_property_getter(class_name, p_identifier);
1528 						if (getter != StringName()) {
1529 							MethodBind *g = ClassDB::get_method(class_name, getter);
1530 							if (g) {
1531 								r_type = _type_from_property(g->get_return_info());
1532 								return true;
1533 							}
1534 						} else {
1535 							r_type = _type_from_property(prop);
1536 							return true;
1537 						}
1538 						break;
1539 					}
1540 				}
1541 				return false;
1542 			} break;
1543 			case GDScriptParser::DataType::BUILTIN: {
1544 				Variant::CallError err;
1545 				Variant tmp = Variant::construct(base_type.builtin_type, NULL, 0, err);
1546 
1547 				if (err.error != Variant::CallError::CALL_OK) {
1548 					return false;
1549 				}
1550 				bool valid = false;
1551 				Variant res = tmp.get(p_identifier, &valid);
1552 				if (valid) {
1553 					r_type = _type_from_variant(res);
1554 					r_type.value = Variant();
1555 					r_type.type.is_constant = false;
1556 					return true;
1557 				}
1558 				return false;
1559 			} break;
1560 			default: {
1561 				return false;
1562 			} break;
1563 		}
1564 	}
1565 
1566 	return false;
1567 }
1568 
_find_last_return_in_block(const GDScriptCompletionContext & p_context,int & r_last_return_line,const GDScriptParser::Node ** r_last_returned_value)1569 static bool _find_last_return_in_block(const GDScriptCompletionContext &p_context, int &r_last_return_line, const GDScriptParser::Node **r_last_returned_value) {
1570 	if (!p_context.block) {
1571 		return false;
1572 	}
1573 
1574 	for (int i = 0; i < p_context.block->statements.size(); i++) {
1575 		if (p_context.block->statements[i]->line < r_last_return_line) {
1576 			continue;
1577 		}
1578 		if (p_context.block->statements[i]->type != GDScriptParser::Node::TYPE_CONTROL_FLOW) {
1579 			continue;
1580 		}
1581 
1582 		const GDScriptParser::ControlFlowNode *cf = static_cast<const GDScriptParser::ControlFlowNode *>(p_context.block->statements[i]);
1583 		if (cf->cf_type == GDScriptParser::ControlFlowNode::CF_RETURN && cf->arguments.size() > 0) {
1584 			if (cf->line > r_last_return_line) {
1585 				r_last_return_line = cf->line;
1586 				*r_last_returned_value = cf->arguments[0];
1587 			}
1588 		}
1589 	}
1590 
1591 	// Recurse into subblocks
1592 	for (int i = 0; i < p_context.block->sub_blocks.size(); i++) {
1593 		GDScriptCompletionContext c = p_context;
1594 		c.block = p_context.block->sub_blocks[i];
1595 		_find_last_return_in_block(c, r_last_return_line, r_last_returned_value);
1596 	}
1597 
1598 	return false;
1599 }
1600 
_guess_method_return_type_from_base(GDScriptCompletionContext & p_context,const GDScriptCompletionIdentifier & p_base,const StringName & p_method,GDScriptCompletionIdentifier & r_type)1601 static bool _guess_method_return_type_from_base(GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_method, GDScriptCompletionIdentifier &r_type) {
1602 	GDScriptParser::DataType base_type = p_base.type;
1603 	bool _static = base_type.is_meta_type;
1604 
1605 	if (_static && p_method == "new") {
1606 		r_type.type = base_type;
1607 		r_type.type.is_meta_type = false;
1608 		r_type.type.is_constant = false;
1609 		return true;
1610 	}
1611 
1612 	while (base_type.has_type) {
1613 		switch (base_type.kind) {
1614 			case GDScriptParser::DataType::CLASS: {
1615 				if (!base_type.class_type) {
1616 					base_type.has_type = false;
1617 					break;
1618 				}
1619 
1620 				for (int i = 0; i < base_type.class_type->static_functions.size(); i++) {
1621 					if (base_type.class_type->static_functions[i]->name == p_method) {
1622 						int last_return_line = -1;
1623 						const GDScriptParser::Node *last_returned_value = NULL;
1624 						GDScriptCompletionContext c = p_context;
1625 						c._class = base_type.class_type;
1626 						c.function = base_type.class_type->static_functions[i];
1627 						c.block = c.function->body;
1628 
1629 						_find_last_return_in_block(c, last_return_line, &last_returned_value);
1630 						if (last_returned_value) {
1631 							c.line = c.block->end_line;
1632 							return _guess_expression_type(c, last_returned_value, r_type);
1633 						}
1634 					}
1635 				}
1636 				if (!_static) {
1637 					for (int i = 0; i < base_type.class_type->functions.size(); i++) {
1638 						if (base_type.class_type->functions[i]->name == p_method) {
1639 							int last_return_line = -1;
1640 							const GDScriptParser::Node *last_returned_value = NULL;
1641 							GDScriptCompletionContext c = p_context;
1642 							c._class = base_type.class_type;
1643 							c.function = base_type.class_type->functions[i];
1644 							c.block = c.function->body;
1645 
1646 							_find_last_return_in_block(c, last_return_line, &last_returned_value);
1647 							if (last_returned_value) {
1648 								c.line = c.block->end_line;
1649 								return _guess_expression_type(c, last_returned_value, r_type);
1650 							}
1651 						}
1652 					}
1653 				}
1654 
1655 				base_type = base_type.class_type->base_type;
1656 			} break;
1657 			case GDScriptParser::DataType::GDSCRIPT: {
1658 				Ref<GDScript> gds = base_type.script_type;
1659 				if (gds.is_valid()) {
1660 					if (gds->get_member_functions().has(p_method)) {
1661 						r_type = _type_from_gdtype(gds->get_member_functions()[p_method]->get_return_type());
1662 						return true;
1663 					}
1664 					Ref<GDScript> base_script = gds->get_base_script();
1665 					if (base_script.is_valid()) {
1666 						base_type.script_type = base_script;
1667 					} else {
1668 						base_type.kind = GDScriptParser::DataType::NATIVE;
1669 						base_type.native_type = gds->get_instance_base_type();
1670 					}
1671 				} else {
1672 					return false;
1673 				}
1674 			} break;
1675 			case GDScriptParser::DataType::SCRIPT: {
1676 				Ref<Script> scr = base_type.script_type;
1677 				if (scr.is_valid()) {
1678 					List<MethodInfo> methods;
1679 					scr->get_script_method_list(&methods);
1680 					for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
1681 						MethodInfo &mi = E->get();
1682 						if (mi.name == p_method) {
1683 							r_type = _type_from_property(mi.return_val);
1684 							return true;
1685 						}
1686 					}
1687 					Ref<Script> base_script = scr->get_base_script();
1688 					if (base_script.is_valid()) {
1689 						base_type.script_type = base_script;
1690 					} else {
1691 						base_type.kind = GDScriptParser::DataType::NATIVE;
1692 						base_type.native_type = scr->get_instance_base_type();
1693 					}
1694 				} else {
1695 					return false;
1696 				}
1697 			} break;
1698 			case GDScriptParser::DataType::NATIVE: {
1699 				StringName native = base_type.native_type;
1700 				if (!ClassDB::class_exists(native)) {
1701 					native = String("_") + native;
1702 					if (!ClassDB::class_exists(native)) {
1703 						return false;
1704 					}
1705 				}
1706 				MethodBind *mb = ClassDB::get_method(native, p_method);
1707 				if (mb) {
1708 					r_type = _type_from_property(mb->get_return_info());
1709 					return true;
1710 				}
1711 				return false;
1712 			} break;
1713 			case GDScriptParser::DataType::BUILTIN: {
1714 				Variant::CallError err;
1715 				Variant tmp = Variant::construct(base_type.builtin_type, NULL, 0, err);
1716 				if (err.error != Variant::CallError::CALL_OK) {
1717 					return false;
1718 				}
1719 
1720 				List<MethodInfo> methods;
1721 				tmp.get_method_list(&methods);
1722 
1723 				for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
1724 					MethodInfo &mi = E->get();
1725 					if (mi.name == p_method) {
1726 						r_type = _type_from_property(mi.return_val);
1727 						return true;
1728 					}
1729 				}
1730 				return false;
1731 			} break;
1732 			default: {
1733 				return false;
1734 			}
1735 		}
1736 	}
1737 	return false;
1738 }
1739 
_make_arguments_hint(const MethodInfo & p_info,int p_arg_idx)1740 static String _make_arguments_hint(const MethodInfo &p_info, int p_arg_idx) {
1741 
1742 	String arghint = _get_visual_datatype(p_info.return_val, false) + " " + p_info.name + "(";
1743 
1744 	int def_args = p_info.arguments.size() - p_info.default_arguments.size();
1745 	int i = 0;
1746 	for (const List<PropertyInfo>::Element *E = p_info.arguments.front(); E; E = E->next()) {
1747 		if (i > 0) {
1748 			arghint += ", ";
1749 		}
1750 
1751 		if (i == p_arg_idx) {
1752 			arghint += String::chr(0xFFFF);
1753 		}
1754 		arghint += E->get().name + ": " + _get_visual_datatype(E->get(), true);
1755 
1756 		if (i - def_args >= 0) {
1757 			arghint += String(" = ") + p_info.default_arguments[i - def_args].get_construct_string();
1758 		}
1759 
1760 		if (i == p_arg_idx) {
1761 			arghint += String::chr(0xFFFF);
1762 		}
1763 
1764 		i++;
1765 	}
1766 
1767 	if (p_info.flags & METHOD_FLAG_VARARG) {
1768 		if (p_info.arguments.size() > 0) {
1769 			arghint += ", ";
1770 		}
1771 		if (p_arg_idx >= p_info.arguments.size()) {
1772 			arghint += String::chr(0xFFFF);
1773 		}
1774 		arghint += "...";
1775 		if (p_arg_idx >= p_info.arguments.size()) {
1776 			arghint += String::chr(0xFFFF);
1777 		}
1778 	}
1779 
1780 	arghint += ")";
1781 
1782 	return arghint;
1783 }
1784 
_make_arguments_hint(const GDScriptParser::FunctionNode * p_function,int p_arg_idx)1785 static String _make_arguments_hint(const GDScriptParser::FunctionNode *p_function, int p_arg_idx) {
1786 
1787 	String arghint = p_function->return_type.to_string() + " " + p_function->name.operator String() + "(";
1788 
1789 	int def_args = p_function->arguments.size() - p_function->default_values.size();
1790 	for (int i = 0; i < p_function->arguments.size(); i++) {
1791 		if (i > 0) {
1792 			arghint += ", ";
1793 		}
1794 
1795 		if (i == p_arg_idx) {
1796 			arghint += String::chr(0xFFFF);
1797 		}
1798 		arghint += p_function->arguments[i].operator String() + ": " + p_function->argument_types[i].to_string();
1799 
1800 		if (i - def_args >= 0) {
1801 			String def_val = "<unknown>";
1802 			if (p_function->default_values[i - def_args] && p_function->default_values[i - def_args]->type == GDScriptParser::Node::TYPE_OPERATOR) {
1803 				const GDScriptParser::OperatorNode *assign = static_cast<const GDScriptParser::OperatorNode *>(p_function->default_values[i - def_args]);
1804 
1805 				if (assign->arguments.size() >= 2) {
1806 					if (assign->arguments[1]->type == GDScriptParser::Node::TYPE_CONSTANT) {
1807 						const GDScriptParser::ConstantNode *cn = static_cast<const GDScriptParser::ConstantNode *>(assign->arguments[1]);
1808 						def_val = cn->value.get_construct_string();
1809 					} else if (assign->arguments[1]->type == GDScriptParser::Node::TYPE_IDENTIFIER) {
1810 						const GDScriptParser::IdentifierNode *id = static_cast<const GDScriptParser::IdentifierNode *>(assign->arguments[1]);
1811 						def_val = id->name.operator String();
1812 					}
1813 				}
1814 			}
1815 			arghint += " = " + def_val;
1816 		}
1817 		if (i == p_arg_idx) {
1818 			arghint += String::chr(0xFFFF);
1819 		}
1820 	}
1821 
1822 	arghint += ")";
1823 
1824 	return arghint;
1825 }
1826 
_find_enumeration_candidates(const String p_enum_hint,Map<String,ScriptCodeCompletionOption> & r_result)1827 static void _find_enumeration_candidates(const String p_enum_hint, Map<String, ScriptCodeCompletionOption> &r_result) {
1828 
1829 	if (p_enum_hint.find(".") == -1) {
1830 		// Global constant
1831 		StringName current_enum = p_enum_hint;
1832 		for (int i = 0; i < GlobalConstants::get_global_constant_count(); i++) {
1833 			if (GlobalConstants::get_global_constant_enum(i) == current_enum) {
1834 				ScriptCodeCompletionOption option(GlobalConstants::get_global_constant_name(i), ScriptCodeCompletionOption::KIND_ENUM);
1835 				r_result.insert(option.display, option);
1836 			}
1837 		}
1838 	} else {
1839 		String class_name = p_enum_hint.get_slice(".", 0);
1840 		String enum_name = p_enum_hint.get_slice(".", 1);
1841 
1842 		if (!ClassDB::class_exists(class_name)) {
1843 			return;
1844 		}
1845 
1846 		List<StringName> enum_constants;
1847 		ClassDB::get_enum_constants(class_name, enum_name, &enum_constants);
1848 		for (List<StringName>::Element *E = enum_constants.front(); E; E = E->next()) {
1849 			String candidate = class_name + "." + E->get();
1850 			ScriptCodeCompletionOption option(candidate, ScriptCodeCompletionOption::KIND_ENUM);
1851 			r_result.insert(option.display, option);
1852 		}
1853 	}
1854 }
1855 
_find_identifiers_in_block(const GDScriptCompletionContext & p_context,Map<String,ScriptCodeCompletionOption> & r_result)1856 static void _find_identifiers_in_block(const GDScriptCompletionContext &p_context, Map<String, ScriptCodeCompletionOption> &r_result) {
1857 	for (Map<StringName, GDScriptParser::LocalVarNode *>::Element *E = p_context.block->variables.front(); E; E = E->next()) {
1858 		if (E->get()->line < p_context.line) {
1859 			ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_VARIABLE);
1860 			r_result.insert(option.display, option);
1861 		}
1862 	}
1863 	if (p_context.block->parent_block) {
1864 		GDScriptCompletionContext c = p_context;
1865 		c.block = p_context.block->parent_block;
1866 		_find_identifiers_in_block(c, r_result);
1867 	}
1868 }
1869 
1870 static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, bool p_only_functions, Map<String, ScriptCodeCompletionOption> &r_result);
1871 
_find_identifiers_in_class(const GDScriptCompletionContext & p_context,bool p_static,bool p_only_functions,bool p_parent_only,Map<String,ScriptCodeCompletionOption> & r_result)1872 static void _find_identifiers_in_class(const GDScriptCompletionContext &p_context, bool p_static, bool p_only_functions, bool p_parent_only, Map<String, ScriptCodeCompletionOption> &r_result) {
1873 	if (!p_parent_only) {
1874 		if (!p_static && !p_only_functions) {
1875 			for (int i = 0; i < p_context._class->variables.size(); i++) {
1876 				ScriptCodeCompletionOption option(p_context._class->variables[i].identifier, ScriptCodeCompletionOption::KIND_MEMBER);
1877 				r_result.insert(option.display, option);
1878 			}
1879 		}
1880 
1881 		if (!p_only_functions) {
1882 			for (Map<StringName, GDScriptParser::ClassNode::Constant>::Element *E = p_context._class->constant_expressions.front(); E; E = E->next()) {
1883 				ScriptCodeCompletionOption option(E->key(), ScriptCodeCompletionOption::KIND_CONSTANT);
1884 				r_result.insert(option.display, option);
1885 			}
1886 			for (int i = 0; i < p_context._class->subclasses.size(); i++) {
1887 				ScriptCodeCompletionOption option(p_context._class->subclasses[i]->name, ScriptCodeCompletionOption::KIND_CLASS);
1888 				r_result.insert(option.display, option);
1889 			}
1890 		}
1891 
1892 		for (int i = 0; i < p_context._class->static_functions.size(); i++) {
1893 			ScriptCodeCompletionOption option(p_context._class->static_functions[i]->name.operator String(), ScriptCodeCompletionOption::KIND_FUNCTION);
1894 			if (p_context._class->static_functions[i]->arguments.size()) {
1895 				option.insert_text += "(";
1896 			} else {
1897 				option.insert_text += "()";
1898 			}
1899 			r_result.insert(option.display, option);
1900 		}
1901 
1902 		if (!p_static) {
1903 			for (int i = 0; i < p_context._class->functions.size(); i++) {
1904 				ScriptCodeCompletionOption option(p_context._class->functions[i]->name.operator String(), ScriptCodeCompletionOption::KIND_FUNCTION);
1905 				if (p_context._class->functions[i]->arguments.size()) {
1906 					option.insert_text += "(";
1907 				} else {
1908 					option.insert_text += "()";
1909 				}
1910 				r_result.insert(option.display, option);
1911 			}
1912 		}
1913 	}
1914 
1915 	// Parents
1916 	GDScriptCompletionIdentifier base_type;
1917 	base_type.type = p_context._class->base_type;
1918 	base_type.type.is_meta_type = p_static;
1919 	base_type.value = p_context.base;
1920 
1921 	GDScriptCompletionContext c = p_context;
1922 	c.block = NULL;
1923 	c.function = NULL;
1924 
1925 	_find_identifiers_in_base(c, base_type, p_only_functions, r_result);
1926 }
1927 
_find_identifiers_in_base(const GDScriptCompletionContext & p_context,const GDScriptCompletionIdentifier & p_base,bool p_only_functions,Map<String,ScriptCodeCompletionOption> & r_result)1928 static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, bool p_only_functions, Map<String, ScriptCodeCompletionOption> &r_result) {
1929 	GDScriptParser::DataType base_type = p_base.type;
1930 	bool _static = base_type.is_meta_type;
1931 
1932 	if (_static && base_type.kind != GDScriptParser::DataType::BUILTIN) {
1933 		ScriptCodeCompletionOption option("new", ScriptCodeCompletionOption::KIND_FUNCTION);
1934 		option.insert_text += "(";
1935 		r_result.insert(option.display, option);
1936 	}
1937 
1938 	while (base_type.has_type) {
1939 		switch (base_type.kind) {
1940 			case GDScriptParser::DataType::CLASS: {
1941 				GDScriptCompletionContext c = p_context;
1942 				c._class = base_type.class_type;
1943 				c.block = NULL;
1944 				c.function = NULL;
1945 				_find_identifiers_in_class(c, _static, p_only_functions, false, r_result);
1946 				base_type = base_type.class_type->base_type;
1947 			} break;
1948 			case GDScriptParser::DataType::GDSCRIPT: {
1949 				Ref<GDScript> script = base_type.script_type;
1950 				if (script.is_valid()) {
1951 					if (!_static && !p_only_functions) {
1952 						if (p_context.base && p_context.base->get_script_instance()) {
1953 							List<PropertyInfo> members;
1954 							p_context.base->get_script_instance()->get_property_list(&members);
1955 							for (List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) {
1956 								ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_MEMBER);
1957 								r_result.insert(option.display, option);
1958 							}
1959 						}
1960 						for (const Set<StringName>::Element *E = script->get_members().front(); E; E = E->next()) {
1961 							ScriptCodeCompletionOption option(E->get().operator String(), ScriptCodeCompletionOption::KIND_MEMBER);
1962 							r_result.insert(option.display, option);
1963 						}
1964 					}
1965 					if (!p_only_functions) {
1966 						for (const Map<StringName, Variant>::Element *E = script->get_constants().front(); E; E = E->next()) {
1967 							ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CONSTANT);
1968 							r_result.insert(option.display, option);
1969 						}
1970 					}
1971 					for (const Map<StringName, GDScriptFunction *>::Element *E = script->get_member_functions().front(); E; E = E->next()) {
1972 						if (!_static || E->get()->is_static()) {
1973 							ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_FUNCTION);
1974 							if (E->get()->get_argument_count()) {
1975 								option.insert_text += "(";
1976 							} else {
1977 								option.insert_text += "()";
1978 							}
1979 							r_result.insert(option.display, option);
1980 						}
1981 					}
1982 					if (!p_only_functions) {
1983 						for (const Map<StringName, Ref<GDScript> >::Element *E = script->get_subclasses().front(); E; E = E->next()) {
1984 							ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS);
1985 							r_result.insert(option.display, option);
1986 						}
1987 					}
1988 					base_type = GDScriptParser::DataType();
1989 					if (script->get_base().is_valid()) {
1990 						base_type.has_type = true;
1991 						base_type.kind = GDScriptParser::DataType::GDSCRIPT;
1992 						base_type.script_type = script->get_base();
1993 					} else {
1994 						base_type.has_type = script->get_instance_base_type() != StringName();
1995 						base_type.kind = GDScriptParser::DataType::NATIVE;
1996 						base_type.native_type = script->get_instance_base_type();
1997 					}
1998 				} else {
1999 					return;
2000 				}
2001 			} break;
2002 			case GDScriptParser::DataType::SCRIPT: {
2003 				Ref<Script> scr = base_type.script_type;
2004 				if (scr.is_valid()) {
2005 					if (!_static && !p_only_functions) {
2006 						List<PropertyInfo> members;
2007 						scr->get_script_property_list(&members);
2008 						for (List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) {
2009 							ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_MEMBER);
2010 							r_result.insert(option.display, option);
2011 						}
2012 					}
2013 					if (!p_only_functions) {
2014 						Map<StringName, Variant> constants;
2015 						scr->get_constants(&constants);
2016 						for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) {
2017 							ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CONSTANT);
2018 							r_result.insert(option.display, option);
2019 						}
2020 					}
2021 
2022 					List<MethodInfo> methods;
2023 					scr->get_script_method_list(&methods);
2024 					for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
2025 						ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_FUNCTION);
2026 						if (E->get().arguments.size()) {
2027 							option.insert_text += "(";
2028 						} else {
2029 							option.insert_text += "()";
2030 						}
2031 						r_result.insert(option.display, option);
2032 					}
2033 
2034 					Ref<Script> base_script = scr->get_base_script();
2035 					if (base_script.is_valid()) {
2036 						base_type.script_type = base_script;
2037 					} else {
2038 						base_type.kind = GDScriptParser::DataType::NATIVE;
2039 						base_type.native_type = scr->get_instance_base_type();
2040 					}
2041 				} else {
2042 					return;
2043 				}
2044 			} break;
2045 			case GDScriptParser::DataType::NATIVE: {
2046 				StringName type = base_type.native_type;
2047 				if (!ClassDB::class_exists(type)) {
2048 					type = String("_") + type;
2049 					if (!ClassDB::class_exists(type)) {
2050 						return;
2051 					}
2052 				}
2053 
2054 				if (!p_only_functions) {
2055 					List<String> constants;
2056 					ClassDB::get_integer_constant_list(type, &constants);
2057 					for (List<String>::Element *E = constants.front(); E; E = E->next()) {
2058 						ScriptCodeCompletionOption option(E->get(), ScriptCodeCompletionOption::KIND_CONSTANT);
2059 						r_result.insert(option.display, option);
2060 					}
2061 
2062 					if (!_static) {
2063 						List<PropertyInfo> pinfo;
2064 						ClassDB::get_property_list(type, &pinfo);
2065 						for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
2066 							if (E->get().usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY)) {
2067 								continue;
2068 							}
2069 							if (E->get().name.find("/") != -1) {
2070 								continue;
2071 							}
2072 							ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_MEMBER);
2073 							r_result.insert(option.display, option);
2074 						}
2075 					}
2076 				}
2077 
2078 				if (!_static) {
2079 					List<MethodInfo> methods;
2080 					bool is_autocompleting_getters = GLOBAL_GET("debug/gdscript/completion/autocomplete_setters_and_getters").booleanize();
2081 					ClassDB::get_method_list(type, &methods, false, !is_autocompleting_getters);
2082 					for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
2083 						if (E->get().name.begins_with("_")) {
2084 							continue;
2085 						}
2086 						ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_FUNCTION);
2087 						if (E->get().arguments.size()) {
2088 							option.insert_text += "(";
2089 						} else {
2090 							option.insert_text += "()";
2091 						}
2092 						r_result.insert(option.display, option);
2093 					}
2094 				}
2095 
2096 				return;
2097 			} break;
2098 			case GDScriptParser::DataType::BUILTIN: {
2099 				Variant::CallError err;
2100 				Variant tmp = Variant::construct(base_type.builtin_type, NULL, 0, err);
2101 				if (err.error != Variant::CallError::CALL_OK) {
2102 					return;
2103 				}
2104 
2105 				if (!p_only_functions) {
2106 					List<PropertyInfo> members;
2107 					if (p_base.value.get_type() != Variant::NIL) {
2108 						p_base.value.get_property_list(&members);
2109 					} else {
2110 						tmp.get_property_list(&members);
2111 					}
2112 
2113 					for (List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) {
2114 						if (String(E->get().name).find("/") == -1) {
2115 							ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_MEMBER);
2116 							r_result.insert(option.display, option);
2117 						}
2118 					}
2119 				}
2120 
2121 				List<MethodInfo> methods;
2122 				tmp.get_method_list(&methods);
2123 				for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
2124 					ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_FUNCTION);
2125 					if (E->get().arguments.size()) {
2126 						option.insert_text += "(";
2127 					} else {
2128 						option.insert_text += "()";
2129 					}
2130 					r_result.insert(option.display, option);
2131 				}
2132 
2133 				return;
2134 			} break;
2135 			default: {
2136 				return;
2137 			} break;
2138 		}
2139 	}
2140 }
2141 
_find_identifiers(const GDScriptCompletionContext & p_context,bool p_only_functions,Map<String,ScriptCodeCompletionOption> & r_result)2142 static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p_only_functions, Map<String, ScriptCodeCompletionOption> &r_result) {
2143 
2144 	const GDScriptParser::BlockNode *block = p_context.block;
2145 
2146 	if (p_context.function) {
2147 
2148 		const GDScriptParser::FunctionNode *f = p_context.function;
2149 
2150 		for (int i = 0; i < f->arguments.size(); i++) {
2151 			ScriptCodeCompletionOption option(f->arguments[i].operator String(), ScriptCodeCompletionOption::KIND_PLAIN_TEXT);
2152 			r_result.insert(option.display, option);
2153 		}
2154 	}
2155 
2156 	if (!p_only_functions && block) {
2157 		GDScriptCompletionContext c = p_context;
2158 		c.block = block;
2159 		_find_identifiers_in_block(c, r_result);
2160 	}
2161 
2162 	const GDScriptParser::ClassNode *clss = p_context._class;
2163 	bool _static = p_context.function && p_context.function->_static;
2164 
2165 	while (clss) {
2166 		GDScriptCompletionContext c = p_context;
2167 		c._class = clss;
2168 		c.block = NULL;
2169 		c.function = NULL;
2170 		_find_identifiers_in_class(c, _static, p_only_functions, false, r_result);
2171 		_static = true;
2172 		clss = clss->owner;
2173 	}
2174 
2175 	for (int i = 0; i < GDScriptFunctions::FUNC_MAX; i++) {
2176 		MethodInfo mi = GDScriptFunctions::get_info(GDScriptFunctions::Function(i));
2177 		ScriptCodeCompletionOption option(String(GDScriptFunctions::get_func_name(GDScriptFunctions::Function(i))), ScriptCodeCompletionOption::KIND_FUNCTION);
2178 		if (mi.arguments.size() || (mi.flags & METHOD_FLAG_VARARG)) {
2179 			option.insert_text += "(";
2180 		} else {
2181 			option.insert_text += "()";
2182 		}
2183 		r_result.insert(option.display, option);
2184 	}
2185 
2186 	static const char *_type_names[Variant::VARIANT_MAX] = {
2187 		"null", "bool", "int", "float", "String", "Vector2", "Rect2", "Vector3", "Transform2D", "Plane", "Quat", "AABB", "Basis", "Transform",
2188 		"Color", "NodePath", "RID", "Object", "Dictionary", "Array", "PoolByteArray", "PoolIntArray", "PoolRealArray", "PoolStringArray",
2189 		"PoolVector2Array", "PoolVector3Array", "PoolColorArray"
2190 	};
2191 
2192 	for (int i = 0; i < Variant::VARIANT_MAX; i++) {
2193 		ScriptCodeCompletionOption option(_type_names[i], ScriptCodeCompletionOption::KIND_CLASS);
2194 		r_result.insert(option.display, option);
2195 	}
2196 
2197 	static const char *_keywords[] = {
2198 		"and", "in", "not", "or", "false", "PI", "TAU", "INF", "NAN", "self", "true", "as", "assert",
2199 		"breakpoint", "class", "extends", "is", "func", "preload", "setget", "signal", "tool", "yield",
2200 		"const", "enum", "export", "onready", "static", "var", "break", "continue", "if", "elif",
2201 		"else", "for", "pass", "return", "match", "while", "remote", "sync", "master", "puppet", "slave",
2202 		"remotesync", "mastersync", "puppetsync",
2203 		0
2204 	};
2205 
2206 	const char **kw = _keywords;
2207 	while (*kw) {
2208 		ScriptCodeCompletionOption option(*kw, ScriptCodeCompletionOption::KIND_PLAIN_TEXT);
2209 		r_result.insert(option.display, option);
2210 		kw++;
2211 	}
2212 
2213 	// Autoload singletons
2214 	List<PropertyInfo> props;
2215 	ProjectSettings::get_singleton()->get_property_list(&props);
2216 	for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
2217 		String s = E->get().name;
2218 		if (!s.begins_with("autoload/")) {
2219 			continue;
2220 		}
2221 		String path = ProjectSettings::get_singleton()->get(s);
2222 		if (path.begins_with("*")) {
2223 			ScriptCodeCompletionOption option(s.get_slice("/", 1), ScriptCodeCompletionOption::KIND_CONSTANT);
2224 			r_result.insert(option.display, option);
2225 		}
2226 	}
2227 
2228 	// Named scripts
2229 	List<StringName> named_scripts;
2230 	ScriptServer::get_global_class_list(&named_scripts);
2231 	for (List<StringName>::Element *E = named_scripts.front(); E; E = E->next()) {
2232 		ScriptCodeCompletionOption option(E->get().operator String(), ScriptCodeCompletionOption::KIND_CLASS);
2233 		r_result.insert(option.display, option);
2234 	}
2235 
2236 	// Native classes
2237 	for (const Map<StringName, int>::Element *E = GDScriptLanguage::get_singleton()->get_global_map().front(); E; E = E->next()) {
2238 		ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS);
2239 		r_result.insert(option.display, option);
2240 	}
2241 }
2242 
_find_call_arguments(const GDScriptCompletionContext & p_context,const GDScriptCompletionIdentifier & p_base,const StringName & p_method,int p_argidx,bool p_static,Map<String,ScriptCodeCompletionOption> & r_result,String & r_arghint)2243 static void _find_call_arguments(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_method, int p_argidx, bool p_static, Map<String, ScriptCodeCompletionOption> &r_result, String &r_arghint) {
2244 	Variant base = p_base.value;
2245 	GDScriptParser::DataType base_type = p_base.type;
2246 
2247 	const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\"";
2248 
2249 #define IS_METHOD_SIGNAL(m_method) (m_method == "connect" || m_method == "disconnect" || m_method == "is_connected" || m_method == "emit_signal")
2250 
2251 	while (base_type.has_type) {
2252 		switch (base_type.kind) {
2253 			case GDScriptParser::DataType::CLASS: {
2254 				for (int i = 0; i < base_type.class_type->static_functions.size(); i++) {
2255 					if (base_type.class_type->static_functions[i]->name == p_method) {
2256 						r_arghint = _make_arguments_hint(base_type.class_type->static_functions[i], p_argidx);
2257 						return;
2258 					}
2259 				}
2260 				for (int i = 0; i < base_type.class_type->functions.size(); i++) {
2261 					if (base_type.class_type->functions[i]->name == p_method) {
2262 						r_arghint = _make_arguments_hint(base_type.class_type->functions[i], p_argidx);
2263 						return;
2264 					}
2265 				}
2266 
2267 				if (IS_METHOD_SIGNAL(p_method) && p_argidx == 0) {
2268 					for (int i = 0; i < base_type.class_type->_signals.size(); i++) {
2269 						ScriptCodeCompletionOption option(base_type.class_type->_signals[i].name.operator String(), ScriptCodeCompletionOption::KIND_SIGNAL);
2270 						option.insert_text = quote_style + option.display + quote_style;
2271 						r_result.insert(option.display, option);
2272 					}
2273 				}
2274 
2275 				base_type = base_type.class_type->base_type;
2276 			} break;
2277 			case GDScriptParser::DataType::GDSCRIPT: {
2278 				Ref<GDScript> gds = base_type.script_type;
2279 				if (gds.is_valid()) {
2280 					if (IS_METHOD_SIGNAL(p_method) && p_argidx == 0) {
2281 						List<MethodInfo> signals;
2282 						gds->get_script_signal_list(&signals);
2283 						for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) {
2284 							ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_SIGNAL);
2285 							option.insert_text = quote_style + option.display + quote_style;
2286 							r_result.insert(option.display, option);
2287 						}
2288 					}
2289 					Ref<GDScript> base_script = gds->get_base_script();
2290 					if (base_script.is_valid()) {
2291 						base_type.script_type = base_script;
2292 					} else {
2293 						base_type.kind = GDScriptParser::DataType::NATIVE;
2294 						base_type.native_type = gds->get_instance_base_type();
2295 					}
2296 				} else {
2297 					return;
2298 				}
2299 			} break;
2300 			case GDScriptParser::DataType::NATIVE: {
2301 				StringName class_name = base_type.native_type;
2302 				if (!ClassDB::class_exists(class_name)) {
2303 					class_name = String("_") + class_name;
2304 					if (!ClassDB::class_exists(class_name)) {
2305 						base_type.has_type = false;
2306 						break;
2307 					}
2308 				}
2309 
2310 				List<MethodInfo> methods;
2311 				ClassDB::get_method_list(class_name, &methods);
2312 				ClassDB::get_virtual_methods(class_name, &methods);
2313 				int method_args = 0;
2314 
2315 				for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
2316 					if (E->get().name == p_method) {
2317 						method_args = E->get().arguments.size();
2318 						if (base.get_type() == Variant::OBJECT) {
2319 							Object *obj = base.operator Object *();
2320 							if (obj) {
2321 								List<String> options;
2322 								obj->get_argument_options(p_method, p_argidx, &options);
2323 								for (List<String>::Element *F = options.front(); F; F = F->next()) {
2324 									ScriptCodeCompletionOption option(F->get(), ScriptCodeCompletionOption::KIND_FUNCTION);
2325 									r_result.insert(option.display, option);
2326 								}
2327 							}
2328 						}
2329 
2330 						if (p_argidx < method_args) {
2331 							PropertyInfo arg_info = E->get().arguments[p_argidx];
2332 							if (arg_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
2333 								_find_enumeration_candidates(arg_info.class_name, r_result);
2334 							}
2335 						}
2336 
2337 						r_arghint = _make_arguments_hint(E->get(), p_argidx);
2338 						break;
2339 					}
2340 				}
2341 
2342 				if (IS_METHOD_SIGNAL(p_method) && p_argidx == 0) {
2343 					List<MethodInfo> signals;
2344 					ClassDB::get_signal_list(class_name, &signals);
2345 					for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) {
2346 						ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_SIGNAL);
2347 						option.insert_text = quote_style + option.display + quote_style;
2348 						r_result.insert(option.display, option);
2349 					}
2350 				}
2351 #undef IS_METHOD_SIGNAL
2352 
2353 				if (ClassDB::is_parent_class(class_name, "Node") && (p_method == "get_node" || p_method == "has_node") && p_argidx == 0) {
2354 					// Get autoloads
2355 					List<PropertyInfo> props;
2356 					ProjectSettings::get_singleton()->get_property_list(&props);
2357 
2358 					for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
2359 						String s = E->get().name;
2360 						if (!s.begins_with("autoload/")) {
2361 							continue;
2362 						}
2363 						String name = s.get_slice("/", 1);
2364 						ScriptCodeCompletionOption option("/root/" + name, ScriptCodeCompletionOption::KIND_NODE_PATH);
2365 						option.insert_text = quote_style + option.display + quote_style;
2366 						r_result.insert(option.display, option);
2367 					}
2368 				}
2369 
2370 				if (p_argidx == 0 && method_args > 0 && ClassDB::is_parent_class(class_name, "InputEvent") && p_method.operator String().find("action") != -1) {
2371 					// Get input actions
2372 					List<PropertyInfo> props;
2373 					ProjectSettings::get_singleton()->get_property_list(&props);
2374 					for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
2375 						String s = E->get().name;
2376 						if (!s.begins_with("input/")) {
2377 							continue;
2378 						}
2379 						String name = s.get_slice("/", 1);
2380 						ScriptCodeCompletionOption option(name, ScriptCodeCompletionOption::KIND_CONSTANT);
2381 						option.insert_text = quote_style + option.display + quote_style;
2382 						r_result.insert(option.display, option);
2383 					}
2384 				}
2385 
2386 				base_type.has_type = false;
2387 			} break;
2388 			case GDScriptParser::DataType::BUILTIN: {
2389 				if (base.get_type() == Variant::NIL) {
2390 					Variant::CallError err;
2391 					base = Variant::construct(base_type.builtin_type, NULL, 0, err);
2392 					if (err.error != Variant::CallError::CALL_OK) {
2393 						return;
2394 					}
2395 				}
2396 
2397 				List<MethodInfo> methods;
2398 				base.get_method_list(&methods);
2399 				for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
2400 					if (E->get().name == p_method) {
2401 						r_arghint = _make_arguments_hint(E->get(), p_argidx);
2402 						return;
2403 					}
2404 				}
2405 
2406 				base_type.has_type = false;
2407 			} break;
2408 			default: {
2409 				base_type.has_type = false;
2410 			} break;
2411 		}
2412 	}
2413 }
2414 
_find_call_arguments(GDScriptCompletionContext & p_context,const GDScriptParser::Node * p_node,int p_argidx,Map<String,ScriptCodeCompletionOption> & r_result,bool & r_forced,String & r_arghint)2415 static void _find_call_arguments(GDScriptCompletionContext &p_context, const GDScriptParser::Node *p_node, int p_argidx, Map<String, ScriptCodeCompletionOption> &r_result, bool &r_forced, String &r_arghint) {
2416 
2417 	const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\"";
2418 
2419 	if (!p_node || p_node->type != GDScriptParser::Node::TYPE_OPERATOR) {
2420 		return;
2421 	}
2422 
2423 	Variant base;
2424 	GDScriptParser::DataType base_type;
2425 	StringName function;
2426 	bool _static = false;
2427 	const GDScriptParser::OperatorNode *op = static_cast<const GDScriptParser::OperatorNode *>(p_node);
2428 
2429 	GDScriptCompletionIdentifier connect_base;
2430 
2431 	if (op->op != GDScriptParser::OperatorNode::OP_CALL && op->op != GDScriptParser::OperatorNode::OP_PARENT_CALL) {
2432 		return;
2433 	}
2434 
2435 	if (!op->arguments.size()) {
2436 		return;
2437 	}
2438 
2439 	if (op->op == GDScriptParser::OperatorNode::OP_CALL) {
2440 		if (op->arguments[0]->type == GDScriptParser::Node::TYPE_BUILT_IN_FUNCTION) {
2441 			// Complete built-in function
2442 			const GDScriptParser::BuiltInFunctionNode *fn = static_cast<const GDScriptParser::BuiltInFunctionNode *>(op->arguments[0]);
2443 			MethodInfo mi = GDScriptFunctions::get_info(fn->function);
2444 
2445 			if ((mi.name == "load" || mi.name == "preload") && bool(EditorSettings::get_singleton()->get("text_editor/completion/complete_file_paths"))) {
2446 				_get_directory_contents(EditorFileSystem::get_singleton()->get_filesystem(), r_result);
2447 			}
2448 
2449 			r_arghint = _make_arguments_hint(mi, p_argidx);
2450 			return;
2451 
2452 		} else if (op->arguments[0]->type == GDScriptParser::Node::TYPE_TYPE) {
2453 			// Complete constructor
2454 			const GDScriptParser::TypeNode *tn = static_cast<const GDScriptParser::TypeNode *>(op->arguments[0]);
2455 
2456 			List<MethodInfo> constructors;
2457 			Variant::get_constructor_list(tn->vtype, &constructors);
2458 
2459 			int i = 0;
2460 			for (List<MethodInfo>::Element *E = constructors.front(); E; E = E->next()) {
2461 				if (p_argidx >= E->get().arguments.size()) {
2462 					continue;
2463 				}
2464 				if (i > 0) {
2465 					r_arghint += "\n";
2466 				}
2467 				r_arghint += _make_arguments_hint(E->get(), p_argidx);
2468 				i++;
2469 			}
2470 			return;
2471 		} else if (op->arguments[0]->type == GDScriptParser::Node::TYPE_SELF) {
2472 
2473 			if (op->arguments.size() < 2 || op->arguments[1]->type != GDScriptParser::Node::TYPE_IDENTIFIER) {
2474 				return;
2475 			}
2476 
2477 			base = p_context.base;
2478 
2479 			const GDScriptParser::IdentifierNode *id = static_cast<const GDScriptParser::IdentifierNode *>(op->arguments[1]);
2480 			function = id->name;
2481 			base_type.has_type = true;
2482 			base_type.kind = GDScriptParser::DataType::CLASS;
2483 			base_type.class_type = const_cast<GDScriptParser::ClassNode *>(p_context._class);
2484 			_static = p_context.function && p_context.function->_static;
2485 
2486 			if (function == "connect" && op->arguments.size() >= 4) {
2487 				_guess_expression_type(p_context, op->arguments[3], connect_base);
2488 			}
2489 
2490 		} else {
2491 			if (op->arguments.size() < 2 || op->arguments[1]->type != GDScriptParser::Node::TYPE_IDENTIFIER) {
2492 				return;
2493 			}
2494 			const GDScriptParser::IdentifierNode *id = static_cast<const GDScriptParser::IdentifierNode *>(op->arguments[1]);
2495 			function = id->name;
2496 
2497 			GDScriptCompletionIdentifier ci;
2498 			if (_guess_expression_type(p_context, op->arguments[0], ci)) {
2499 				base_type = ci.type;
2500 				base = ci.value;
2501 			} else {
2502 				return;
2503 			}
2504 			_static = ci.type.is_meta_type;
2505 
2506 			if (function == "connect" && op->arguments.size() >= 4) {
2507 				_guess_expression_type(p_context, op->arguments[3], connect_base);
2508 			}
2509 		}
2510 	} else {
2511 		if (!p_context._class || op->arguments.size() < 1 || op->arguments[0]->type != GDScriptParser::Node::TYPE_IDENTIFIER) {
2512 			return;
2513 		}
2514 		base_type.has_type = true;
2515 		base_type.kind = GDScriptParser::DataType::CLASS;
2516 		base_type.class_type = const_cast<GDScriptParser::ClassNode *>(p_context._class);
2517 		base_type.is_meta_type = p_context.function && p_context.function->_static;
2518 		base = p_context.base;
2519 
2520 		function = static_cast<const GDScriptParser::IdentifierNode *>(op->arguments[0])->name;
2521 
2522 		if (function == "connect" && op->arguments.size() >= 4) {
2523 			_guess_expression_type(p_context, op->arguments[3], connect_base);
2524 		}
2525 	}
2526 
2527 	GDScriptCompletionIdentifier ci;
2528 	ci.type = base_type;
2529 	ci.value = base;
2530 	_find_call_arguments(p_context, ci, function, p_argidx, _static, r_result, r_arghint);
2531 
2532 	if (function == "connect" && p_argidx == 2) {
2533 		Map<String, ScriptCodeCompletionOption> methods;
2534 		_find_identifiers_in_base(p_context, connect_base, true, methods);
2535 		for (Map<String, ScriptCodeCompletionOption>::Element *E = methods.front(); E; E = E->next()) {
2536 			ScriptCodeCompletionOption &option = E->value();
2537 			option.insert_text = quote_style + option.display + quote_style;
2538 			r_result.insert(option.display, option);
2539 		}
2540 	}
2541 
2542 	r_forced = r_result.size() > 0;
2543 }
2544 
complete_code(const String & p_code,const String & p_path,Object * p_owner,List<ScriptCodeCompletionOption> * r_options,bool & r_forced,String & r_call_hint)2545 Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_forced, String &r_call_hint) {
2546 
2547 	const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\"";
2548 
2549 	GDScriptParser parser;
2550 
2551 	parser.parse(p_code, p_path.get_base_dir(), false, p_path, true);
2552 	r_forced = false;
2553 	Map<String, ScriptCodeCompletionOption> options;
2554 	GDScriptCompletionContext context;
2555 	context._class = parser.get_completion_class();
2556 	context.block = parser.get_completion_block();
2557 	context.function = parser.get_completion_function();
2558 	context.line = parser.get_completion_line();
2559 
2560 	if (!context._class || context._class->owner == NULL) {
2561 		context.base = p_owner;
2562 		context.base_path = p_path.get_base_dir();
2563 	}
2564 
2565 	bool is_function = false;
2566 
2567 	switch (parser.get_completion_type()) {
2568 		case GDScriptParser::COMPLETION_NONE: {
2569 		} break;
2570 		case GDScriptParser::COMPLETION_BUILT_IN_TYPE_CONSTANT: {
2571 			List<StringName> constants;
2572 			Variant::get_constants_for_type(parser.get_completion_built_in_constant(), &constants);
2573 			for (List<StringName>::Element *E = constants.front(); E; E = E->next()) {
2574 				ScriptCodeCompletionOption option(E->get().operator String(), ScriptCodeCompletionOption::KIND_CONSTANT);
2575 				options.insert(option.display, option);
2576 			}
2577 		} break;
2578 		case GDScriptParser::COMPLETION_PARENT_FUNCTION: {
2579 			_find_identifiers_in_class(context, !context.function || context.function->_static, true, true, options);
2580 		} break;
2581 		case GDScriptParser::COMPLETION_FUNCTION: {
2582 			is_function = true;
2583 			FALLTHROUGH;
2584 		}
2585 		case GDScriptParser::COMPLETION_IDENTIFIER: {
2586 			_find_identifiers(context, is_function, options);
2587 		} break;
2588 		case GDScriptParser::COMPLETION_EXTENDS: {
2589 
2590 			// Native classes.
2591 			List<StringName> class_list;
2592 			ClassDB::get_class_list(&class_list);
2593 			for (int i = 0; i < class_list.size(); i++) {
2594 				ScriptCodeCompletionOption option(class_list[i], ScriptCodeCompletionOption::KIND_CLASS);
2595 				options.insert(option.display, option);
2596 			}
2597 
2598 			// GDScript classes.
2599 			if (EditorSettings::get_singleton()->get("text_editor/completion/complete_file_paths")) {
2600 				for (int i = 0; i < ScriptServer::get_language_count(); i++) {
2601 					if (ScriptServer::get_language(i)->get_name() == "GDScript") {
2602 						List<String> extensions;
2603 						ScriptServer::get_language(i)->get_recognized_extensions(&extensions);
2604 						for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
2605 							_get_directory_contents(EditorFileSystem::get_singleton()->get_filesystem(), options, String("." + E->get()));
2606 						}
2607 					}
2608 				}
2609 				r_forced = true;
2610 			}
2611 
2612 			// Named Scripts.
2613 			List<StringName> named_scripts;
2614 			ScriptServer::get_global_class_list(&named_scripts);
2615 			for (List<StringName>::Element *E = named_scripts.front(); E; E = E->next()) {
2616 				ScriptCodeCompletionOption option(E->get().operator String(), ScriptCodeCompletionOption::KIND_CLASS);
2617 				options.insert(option.display, option);
2618 			}
2619 		} break;
2620 		case GDScriptParser::COMPLETION_GET_NODE: {
2621 			if (p_owner) {
2622 				List<String> opts;
2623 				p_owner->get_argument_options("get_node", 0, &opts);
2624 
2625 				for (List<String>::Element *E = opts.front(); E; E = E->next()) {
2626 
2627 					String opt = E->get().strip_edges();
2628 					if (opt.is_quoted()) {
2629 						r_forced = true;
2630 						String idopt = opt.unquote();
2631 						if (idopt.replace("/", "_").is_valid_identifier()) {
2632 							ScriptCodeCompletionOption option(idopt, ScriptCodeCompletionOption::KIND_NODE_PATH);
2633 							options.insert(option.display, option);
2634 						} else {
2635 							ScriptCodeCompletionOption option(opt, ScriptCodeCompletionOption::KIND_NODE_PATH);
2636 							options.insert(option.display, option);
2637 						}
2638 					}
2639 				}
2640 
2641 				// Get autoloads
2642 				List<PropertyInfo> props;
2643 				ProjectSettings::get_singleton()->get_property_list(&props);
2644 
2645 				for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
2646 					String s = E->get().name;
2647 					if (!s.begins_with("autoload/")) {
2648 						continue;
2649 					}
2650 					String name = s.get_slice("/", 1);
2651 					ScriptCodeCompletionOption option(quote_style + "/root/" + name + quote_style, ScriptCodeCompletionOption::KIND_NODE_PATH);
2652 					options.insert(option.display, option);
2653 				}
2654 			}
2655 		} break;
2656 		case GDScriptParser::COMPLETION_METHOD: {
2657 			is_function = true;
2658 			FALLTHROUGH;
2659 		}
2660 		case GDScriptParser::COMPLETION_INDEX: {
2661 			const GDScriptParser::Node *node = parser.get_completion_node();
2662 			if (node->type != GDScriptParser::Node::TYPE_OPERATOR) {
2663 				break;
2664 			}
2665 			const GDScriptParser::OperatorNode *op = static_cast<const GDScriptParser::OperatorNode *>(node);
2666 			if (op->arguments.size() < 1) {
2667 				break;
2668 			}
2669 
2670 			GDScriptCompletionIdentifier base;
2671 			if (!_guess_expression_type(context, op->arguments[0], base)) {
2672 				break;
2673 			}
2674 
2675 			GDScriptCompletionContext c = context;
2676 			c.function = NULL;
2677 			c.block = NULL;
2678 			c.base = base.value.get_type() == Variant::OBJECT ? base.value.operator Object *() : NULL;
2679 			if (base.type.kind == GDScriptParser::DataType::CLASS) {
2680 				c._class = base.type.class_type;
2681 			} else {
2682 				c._class = NULL;
2683 			}
2684 
2685 			_find_identifiers_in_base(c, base, is_function, options);
2686 		} break;
2687 		case GDScriptParser::COMPLETION_CALL_ARGUMENTS: {
2688 			_find_call_arguments(context, parser.get_completion_node(), parser.get_completion_argument_index(), options, r_forced, r_call_hint);
2689 		} break;
2690 		case GDScriptParser::COMPLETION_VIRTUAL_FUNC: {
2691 			GDScriptParser::DataType native_type = context._class->base_type;
2692 			while (native_type.has_type && native_type.kind != GDScriptParser::DataType::NATIVE) {
2693 				switch (native_type.kind) {
2694 					case GDScriptParser::DataType::CLASS: {
2695 						native_type = native_type.class_type->base_type;
2696 					} break;
2697 					case GDScriptParser::DataType::GDSCRIPT: {
2698 						Ref<GDScript> gds = native_type.script_type;
2699 						if (gds.is_valid()) {
2700 							Ref<GDScript> base = gds->get_base_script();
2701 							if (base.is_valid()) {
2702 								native_type.script_type = base;
2703 							} else {
2704 								native_type.native_type = gds->get_instance_base_type();
2705 								native_type.kind = GDScriptParser::DataType::NATIVE;
2706 							}
2707 						} else {
2708 							native_type.has_type = false;
2709 						}
2710 					} break;
2711 					default: {
2712 						native_type.has_type = false;
2713 					} break;
2714 				}
2715 			}
2716 
2717 			if (!native_type.has_type) {
2718 				break;
2719 			}
2720 
2721 			StringName class_name = native_type.native_type;
2722 			if (!ClassDB::class_exists(class_name)) {
2723 				class_name = String("_") + class_name;
2724 				if (!ClassDB::class_exists(class_name)) {
2725 					break;
2726 				}
2727 			}
2728 
2729 			bool use_type_hint = EditorSettings::get_singleton()->get_setting("text_editor/completion/add_type_hints").operator bool();
2730 
2731 			List<MethodInfo> virtual_methods;
2732 			ClassDB::get_virtual_methods(class_name, &virtual_methods);
2733 			for (List<MethodInfo>::Element *E = virtual_methods.front(); E; E = E->next()) {
2734 
2735 				MethodInfo &mi = E->get();
2736 				String method_hint = mi.name;
2737 				if (method_hint.find(":") != -1) {
2738 					method_hint = method_hint.get_slice(":", 0);
2739 				}
2740 				method_hint += "(";
2741 
2742 				if (mi.arguments.size()) {
2743 					for (int i = 0; i < mi.arguments.size(); i++) {
2744 						if (i > 0) {
2745 							method_hint += ", ";
2746 						}
2747 						String arg = mi.arguments[i].name;
2748 						if (arg.find(":") != -1) {
2749 							arg = arg.substr(0, arg.find(":"));
2750 						}
2751 						method_hint += arg;
2752 						if (use_type_hint && mi.arguments[i].type != Variant::NIL) {
2753 							method_hint += ": ";
2754 							if (mi.arguments[i].type == Variant::OBJECT && mi.arguments[i].class_name != StringName()) {
2755 								method_hint += mi.arguments[i].class_name.operator String();
2756 							} else {
2757 								method_hint += Variant::get_type_name(mi.arguments[i].type);
2758 							}
2759 						}
2760 					}
2761 				}
2762 				method_hint += ")";
2763 				if (use_type_hint && (mi.return_val.type != Variant::NIL || !(mi.return_val.usage & PROPERTY_USAGE_NIL_IS_VARIANT))) {
2764 					method_hint += " -> ";
2765 					if (mi.return_val.type == Variant::NIL) {
2766 						method_hint += "void";
2767 					} else if (mi.return_val.type == Variant::OBJECT && mi.return_val.class_name != StringName()) {
2768 						method_hint += mi.return_val.class_name.operator String();
2769 					} else {
2770 						method_hint += Variant::get_type_name(mi.return_val.type);
2771 					}
2772 				}
2773 				method_hint += ":";
2774 
2775 				ScriptCodeCompletionOption option(method_hint, ScriptCodeCompletionOption::KIND_FUNCTION);
2776 				options.insert(option.display, option);
2777 			}
2778 		} break;
2779 		case GDScriptParser::COMPLETION_YIELD: {
2780 			const GDScriptParser::Node *node = parser.get_completion_node();
2781 
2782 			GDScriptCompletionContext c = context;
2783 			c.line = node->line;
2784 			GDScriptCompletionIdentifier type;
2785 			if (!_guess_expression_type(c, node, type)) {
2786 				break;
2787 			}
2788 
2789 			GDScriptParser::DataType base_type = type.type;
2790 			while (base_type.has_type) {
2791 				switch (base_type.kind) {
2792 					case GDScriptParser::DataType::CLASS: {
2793 						for (int i = 0; i < base_type.class_type->_signals.size(); i++) {
2794 							ScriptCodeCompletionOption option(base_type.class_type->_signals[i].name.operator String(), ScriptCodeCompletionOption::KIND_SIGNAL);
2795 							option.insert_text = quote_style + option.display + quote_style;
2796 							options.insert(option.display, option);
2797 						}
2798 						base_type = base_type.class_type->base_type;
2799 					} break;
2800 					case GDScriptParser::DataType::SCRIPT:
2801 					case GDScriptParser::DataType::GDSCRIPT: {
2802 						Ref<Script> scr = base_type.script_type;
2803 						if (scr.is_valid()) {
2804 							List<MethodInfo> signals;
2805 							scr->get_script_signal_list(&signals);
2806 							for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) {
2807 								ScriptCodeCompletionOption option(quote_style + E->get().name + quote_style, ScriptCodeCompletionOption::KIND_SIGNAL);
2808 								options.insert(option.display, option);
2809 							}
2810 							Ref<Script> base_script = scr->get_base_script();
2811 							if (base_script.is_valid()) {
2812 								base_type.script_type = base_script;
2813 							} else {
2814 								base_type.kind = GDScriptParser::DataType::NATIVE;
2815 								base_type.native_type = scr->get_instance_base_type();
2816 							}
2817 						} else {
2818 							base_type.has_type = false;
2819 						}
2820 					} break;
2821 					case GDScriptParser::DataType::NATIVE: {
2822 						base_type.has_type = false;
2823 
2824 						StringName class_name = base_type.native_type;
2825 						if (!ClassDB::class_exists(class_name)) {
2826 							class_name = String("_") + class_name;
2827 							if (!ClassDB::class_exists(class_name)) {
2828 								break;
2829 							}
2830 						}
2831 
2832 						List<MethodInfo> signals;
2833 						ClassDB::get_signal_list(class_name, &signals);
2834 						for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) {
2835 							ScriptCodeCompletionOption option(quote_style + E->get().name + quote_style, ScriptCodeCompletionOption::KIND_SIGNAL);
2836 							options.insert(option.display, option);
2837 						}
2838 					} break;
2839 					default: {
2840 						base_type.has_type = false;
2841 					}
2842 				}
2843 			}
2844 		} break;
2845 		case GDScriptParser::COMPLETION_RESOURCE_PATH: {
2846 			if (EditorSettings::get_singleton()->get("text_editor/completion/complete_file_paths")) {
2847 				_get_directory_contents(EditorFileSystem::get_singleton()->get_filesystem(), options);
2848 				r_forced = true;
2849 			}
2850 		} break;
2851 		case GDScriptParser::COMPLETION_ASSIGN: {
2852 			GDScriptCompletionIdentifier type;
2853 			if (!_guess_expression_type(context, parser.get_completion_node(), type)) {
2854 				break;
2855 			}
2856 
2857 			if (!type.enumeration.empty()) {
2858 				_find_enumeration_candidates(type.enumeration, options);
2859 				r_forced = options.size() > 0;
2860 			}
2861 		} break;
2862 		case GDScriptParser::COMPLETION_TYPE_HINT: {
2863 			const GDScriptParser::ClassNode *clss = context._class;
2864 			while (clss) {
2865 				for (Map<StringName, GDScriptParser::ClassNode::Constant>::Element *E = clss->constant_expressions.front(); E; E = E->next()) {
2866 					GDScriptCompletionIdentifier constant;
2867 					GDScriptCompletionContext c = context;
2868 					c.function = NULL;
2869 					c.block = NULL;
2870 					c.line = E->value().expression->line;
2871 					if (_guess_expression_type(c, E->value().expression, constant)) {
2872 						if (constant.type.has_type && constant.type.is_meta_type) {
2873 							ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS);
2874 							options.insert(option.display, option);
2875 						}
2876 					}
2877 				}
2878 				for (int i = 0; i < clss->subclasses.size(); i++) {
2879 					if (clss->subclasses[i]->name != StringName()) {
2880 						ScriptCodeCompletionOption option(clss->subclasses[i]->name.operator String(), ScriptCodeCompletionOption::KIND_CLASS);
2881 						options.insert(option.display, option);
2882 					}
2883 				}
2884 				clss = clss->owner;
2885 				for (int i = 0; i < Variant::VARIANT_MAX; i++) {
2886 					ScriptCodeCompletionOption option(Variant::get_type_name((Variant::Type)i), ScriptCodeCompletionOption::KIND_CLASS);
2887 					options.insert(option.display, option);
2888 				}
2889 				List<PropertyInfo> props;
2890 				ProjectSettings::get_singleton()->get_property_list(&props);
2891 				for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
2892 					String s = E->get().name;
2893 					if (!s.begins_with("autoload/")) {
2894 						continue;
2895 					}
2896 					ScriptCodeCompletionOption option(s.get_slice("/", 1), ScriptCodeCompletionOption::KIND_CLASS);
2897 					options.insert(option.display, option);
2898 				}
2899 			}
2900 
2901 			List<StringName> native_classes;
2902 			ClassDB::get_class_list(&native_classes);
2903 			for (List<StringName>::Element *E = native_classes.front(); E; E = E->next()) {
2904 				String class_name = E->get().operator String();
2905 				if (class_name.begins_with("_")) {
2906 					class_name = class_name.right(1);
2907 				}
2908 				if (Engine::get_singleton()->has_singleton(class_name)) {
2909 					continue;
2910 				}
2911 				ScriptCodeCompletionOption option(class_name, ScriptCodeCompletionOption::KIND_CLASS);
2912 				options.insert(option.display, option);
2913 			}
2914 
2915 			// Named scripts
2916 			List<StringName> named_scripts;
2917 			ScriptServer::get_global_class_list(&named_scripts);
2918 			for (List<StringName>::Element *E = named_scripts.front(); E; E = E->next()) {
2919 				ScriptCodeCompletionOption option(E->get().operator String(), ScriptCodeCompletionOption::KIND_CLASS);
2920 				options.insert(option.display, option);
2921 			}
2922 
2923 			if (parser.get_completion_identifier_is_function()) {
2924 				ScriptCodeCompletionOption option("void", ScriptCodeCompletionOption::KIND_PLAIN_TEXT);
2925 				options.insert(option.display, option);
2926 			}
2927 			r_forced = true;
2928 		} break;
2929 		case GDScriptParser::COMPLETION_TYPE_HINT_INDEX: {
2930 			GDScriptCompletionIdentifier base;
2931 			String index = parser.get_completion_cursor().operator String();
2932 			if (!_guess_identifier_type(context, index.get_slice(".", 0), base)) {
2933 				break;
2934 			}
2935 
2936 			GDScriptCompletionContext c = context;
2937 			c._class = NULL;
2938 			c.function = NULL;
2939 			c.block = NULL;
2940 			bool finding = true;
2941 			index = index.right(index.find(".") + 1);
2942 			while (index.find(".") != -1) {
2943 				String id = index.get_slice(".", 0);
2944 
2945 				GDScriptCompletionIdentifier sub_base;
2946 				if (!_guess_identifier_type_from_base(c, base, id, sub_base)) {
2947 					finding = false;
2948 					break;
2949 				}
2950 				index = index.right(index.find(".") + 1);
2951 				base = sub_base;
2952 			}
2953 
2954 			if (!finding) {
2955 				break;
2956 			}
2957 
2958 			GDScriptParser::DataType base_type = base.type;
2959 			while (base_type.has_type) {
2960 				switch (base_type.kind) {
2961 					case GDScriptParser::DataType::CLASS: {
2962 						if (base_type.class_type) {
2963 							for (Map<StringName, GDScriptParser::ClassNode::Constant>::Element *E = base_type.class_type->constant_expressions.front(); E; E = E->next()) {
2964 								GDScriptCompletionIdentifier constant;
2965 								GDScriptCompletionContext c2 = context;
2966 								c2._class = base_type.class_type;
2967 								c2.function = NULL;
2968 								c2.block = NULL;
2969 								c2.line = E->value().expression->line;
2970 								if (_guess_expression_type(c2, E->value().expression, constant)) {
2971 									if (constant.type.has_type && constant.type.is_meta_type) {
2972 										ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS);
2973 										options.insert(option.display, option);
2974 									}
2975 								}
2976 							}
2977 							for (int i = 0; i < base_type.class_type->subclasses.size(); i++) {
2978 								if (base_type.class_type->subclasses[i]->name != StringName()) {
2979 									ScriptCodeCompletionOption option(base_type.class_type->subclasses[i]->name.operator String(), ScriptCodeCompletionOption::KIND_CLASS);
2980 									options.insert(option.display, option);
2981 								}
2982 							}
2983 
2984 							base_type = base_type.class_type->base_type;
2985 						} else {
2986 							base_type.has_type = false;
2987 						}
2988 					} break;
2989 					case GDScriptParser::DataType::SCRIPT:
2990 					case GDScriptParser::DataType::GDSCRIPT: {
2991 						Ref<Script> scr = base_type.script_type;
2992 						if (scr.is_valid()) {
2993 							Map<StringName, Variant> constants;
2994 							scr->get_constants(&constants);
2995 							for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) {
2996 								Ref<Script> const_scr = E->value();
2997 								if (const_scr.is_valid()) {
2998 									ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS);
2999 									options.insert(option.display, option);
3000 								}
3001 							}
3002 							Ref<Script> base_script = scr->get_base_script();
3003 							if (base_script.is_valid()) {
3004 								base_type.script_type = base_script;
3005 							} else {
3006 								base_type.has_type = false;
3007 							}
3008 						} else {
3009 							base_type.has_type = false;
3010 						}
3011 					} break;
3012 					default: {
3013 						base_type.has_type = false;
3014 					} break;
3015 				}
3016 			}
3017 			r_forced = options.size() > 0;
3018 		} break;
3019 	}
3020 
3021 	for (Map<String, ScriptCodeCompletionOption>::Element *E = options.front(); E; E = E->next()) {
3022 		r_options->push_back(E->get());
3023 	}
3024 
3025 	return OK;
3026 }
3027 
3028 #else
3029 
complete_code(const String & p_code,const String & p_path,Object * p_owner,List<ScriptCodeCompletionOption> * r_options,bool & r_forced,String & r_call_hint)3030 Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_forced, String &r_call_hint) {
3031 	return OK;
3032 }
3033 
3034 #endif
3035 
3036 //////// END COMPLETION //////////
3037 
_get_indentation() const3038 String GDScriptLanguage::_get_indentation() const {
3039 #ifdef TOOLS_ENABLED
3040 	if (Engine::get_singleton()->is_editor_hint()) {
3041 		bool use_space_indentation = EDITOR_DEF("text_editor/indent/type", false);
3042 
3043 		if (use_space_indentation) {
3044 			int indent_size = EDITOR_DEF("text_editor/indent/size", 4);
3045 
3046 			String space_indent = "";
3047 			for (int i = 0; i < indent_size; i++) {
3048 				space_indent += " ";
3049 			}
3050 			return space_indent;
3051 		}
3052 	}
3053 #endif
3054 	return "\t";
3055 }
3056 
auto_indent_code(String & p_code,int p_from_line,int p_to_line) const3057 void GDScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_to_line) const {
3058 
3059 	String indent = _get_indentation();
3060 
3061 	Vector<String> lines = p_code.split("\n");
3062 	List<int> indent_stack;
3063 
3064 	for (int i = 0; i < lines.size(); i++) {
3065 
3066 		String l = lines[i];
3067 		int tc = 0;
3068 		for (int j = 0; j < l.length(); j++) {
3069 			if (l[j] == ' ' || l[j] == '\t') {
3070 
3071 				tc++;
3072 			} else {
3073 				break;
3074 			}
3075 		}
3076 
3077 		String st = l.substr(tc, l.length()).strip_edges();
3078 		if (st == "" || st.begins_with("#"))
3079 			continue; //ignore!
3080 
3081 		int ilevel = 0;
3082 		if (indent_stack.size()) {
3083 			ilevel = indent_stack.back()->get();
3084 		}
3085 
3086 		if (tc > ilevel) {
3087 			indent_stack.push_back(tc);
3088 		} else if (tc < ilevel) {
3089 			while (indent_stack.size() && indent_stack.back()->get() > tc) {
3090 				indent_stack.pop_back();
3091 			}
3092 
3093 			if (indent_stack.size() && indent_stack.back()->get() != tc)
3094 				indent_stack.push_back(tc); //this is not right but gets the job done
3095 		}
3096 
3097 		if (i >= p_from_line) {
3098 
3099 			l = "";
3100 			for (int j = 0; j < indent_stack.size(); j++) {
3101 				l += indent;
3102 			}
3103 			l += st;
3104 
3105 		} else if (i > p_to_line) {
3106 			break;
3107 		}
3108 
3109 		lines.write[i] = l;
3110 	}
3111 
3112 	p_code = "";
3113 	for (int i = 0; i < lines.size(); i++) {
3114 		if (i > 0)
3115 			p_code += "\n";
3116 		p_code += lines[i];
3117 	}
3118 }
3119 
3120 #ifdef TOOLS_ENABLED
3121 
_lookup_symbol_from_base(const GDScriptParser::DataType & p_base,const String & p_symbol,bool p_is_function,GDScriptLanguage::LookupResult & r_result)3122 static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, const String &p_symbol, bool p_is_function, GDScriptLanguage::LookupResult &r_result) {
3123 	GDScriptParser::DataType base_type = p_base;
3124 
3125 	while (base_type.has_type) {
3126 		switch (base_type.kind) {
3127 			case GDScriptParser::DataType::CLASS: {
3128 				if (base_type.class_type) {
3129 					if (p_is_function) {
3130 						for (int i = 0; i < base_type.class_type->functions.size(); i++) {
3131 							if (base_type.class_type->functions[i]->name == p_symbol) {
3132 								r_result.type = ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION;
3133 								r_result.location = base_type.class_type->functions[i]->line;
3134 								return OK;
3135 							}
3136 						}
3137 						for (int i = 0; i < base_type.class_type->static_functions.size(); i++) {
3138 							if (base_type.class_type->static_functions[i]->name == p_symbol) {
3139 								r_result.type = ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION;
3140 								r_result.location = base_type.class_type->static_functions[i]->line;
3141 								return OK;
3142 							}
3143 						}
3144 					} else {
3145 						if (base_type.class_type->constant_expressions.has(p_symbol)) {
3146 							r_result.type = ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION;
3147 							r_result.location = base_type.class_type->constant_expressions[p_symbol].expression->line;
3148 							return OK;
3149 						}
3150 
3151 						for (int i = 0; i < base_type.class_type->variables.size(); i++) {
3152 							if (base_type.class_type->variables[i].identifier == p_symbol) {
3153 								r_result.type = ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION;
3154 								r_result.location = base_type.class_type->variables[i].line;
3155 								return OK;
3156 							}
3157 						}
3158 
3159 						for (int i = 0; i < base_type.class_type->subclasses.size(); i++) {
3160 							if (base_type.class_type->subclasses[i]->name == p_symbol) {
3161 								r_result.type = ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION;
3162 								r_result.location = base_type.class_type->subclasses[i]->line;
3163 								return OK;
3164 							}
3165 						}
3166 					}
3167 					base_type = base_type.class_type->base_type;
3168 				}
3169 			} break;
3170 			case GDScriptParser::DataType::SCRIPT:
3171 			case GDScriptParser::DataType::GDSCRIPT: {
3172 				Ref<Script> scr = base_type.script_type;
3173 				if (scr.is_valid()) {
3174 					int line = scr->get_member_line(p_symbol);
3175 					if (line >= 0) {
3176 						r_result.type = ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION;
3177 						r_result.location = line;
3178 						r_result.script = scr;
3179 						return OK;
3180 					}
3181 					Ref<Script> base_script = scr->get_base_script();
3182 					if (base_script.is_valid()) {
3183 						base_type.script_type = base_script;
3184 					} else {
3185 						base_type.kind = GDScriptParser::DataType::NATIVE;
3186 						base_type.native_type = scr->get_instance_base_type();
3187 					}
3188 				} else {
3189 					base_type.has_type = false;
3190 				}
3191 			} break;
3192 			case GDScriptParser::DataType::NATIVE: {
3193 				StringName class_name = base_type.native_type;
3194 				if (!ClassDB::class_exists(class_name)) {
3195 					class_name = String("_") + class_name;
3196 					if (!ClassDB::class_exists(class_name)) {
3197 						base_type.has_type = false;
3198 						break;
3199 					}
3200 				}
3201 
3202 				if (ClassDB::has_method(class_name, p_symbol, true)) {
3203 					r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_METHOD;
3204 					r_result.class_name = base_type.native_type;
3205 					r_result.class_member = p_symbol;
3206 					return OK;
3207 				}
3208 
3209 				List<MethodInfo> virtual_methods;
3210 				ClassDB::get_virtual_methods(class_name, &virtual_methods, true);
3211 				for (List<MethodInfo>::Element *E = virtual_methods.front(); E; E = E->next()) {
3212 					if (E->get().name == p_symbol) {
3213 						r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_METHOD;
3214 						r_result.class_name = base_type.native_type;
3215 						r_result.class_member = p_symbol;
3216 						return OK;
3217 					}
3218 				}
3219 
3220 				StringName enum_name = ClassDB::get_integer_constant_enum(class_name, p_symbol, true);
3221 				if (enum_name != StringName()) {
3222 					r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_ENUM;
3223 					r_result.class_name = base_type.native_type;
3224 					r_result.class_member = enum_name;
3225 					return OK;
3226 				}
3227 
3228 				List<String> constants;
3229 				ClassDB::get_integer_constant_list(class_name, &constants, true);
3230 				for (List<String>::Element *E = constants.front(); E; E = E->next()) {
3231 					if (E->get() == p_symbol) {
3232 						r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_CONSTANT;
3233 						r_result.class_name = base_type.native_type;
3234 						r_result.class_member = p_symbol;
3235 						return OK;
3236 					}
3237 				}
3238 
3239 				List<PropertyInfo> properties;
3240 				ClassDB::get_property_list(class_name, &properties, true);
3241 				for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
3242 					if (E->get().name == p_symbol) {
3243 						r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_PROPERTY;
3244 						r_result.class_name = base_type.native_type;
3245 						r_result.class_member = p_symbol;
3246 						return OK;
3247 					}
3248 				}
3249 
3250 				StringName parent = ClassDB::get_parent_class(class_name);
3251 				if (parent != StringName()) {
3252 					if (String(parent).begins_with("_")) {
3253 						base_type.native_type = String(parent).right(1);
3254 					} else {
3255 						base_type.native_type = parent;
3256 					}
3257 				} else {
3258 					base_type.has_type = false;
3259 				}
3260 			} break;
3261 			case GDScriptParser::DataType::BUILTIN: {
3262 				base_type.has_type = false;
3263 
3264 				if (Variant::has_constant(base_type.builtin_type, p_symbol)) {
3265 					r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_CONSTANT;
3266 					r_result.class_name = Variant::get_type_name(base_type.builtin_type);
3267 					r_result.class_member = p_symbol;
3268 					return OK;
3269 				}
3270 
3271 				Variant v;
3272 				REF v_ref;
3273 				if (base_type.builtin_type == Variant::OBJECT) {
3274 					v_ref.instance();
3275 					v = v_ref;
3276 				} else {
3277 					Variant::CallError err;
3278 					v = Variant::construct(base_type.builtin_type, NULL, 0, err);
3279 					if (err.error != Variant::CallError::CALL_OK) {
3280 						break;
3281 					}
3282 				}
3283 
3284 				if (v.has_method(p_symbol)) {
3285 					r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_METHOD;
3286 					r_result.class_name = Variant::get_type_name(base_type.builtin_type);
3287 					r_result.class_member = p_symbol;
3288 					return OK;
3289 				}
3290 
3291 				bool valid = false;
3292 				v.get(p_symbol, &valid);
3293 				if (valid) {
3294 					r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_PROPERTY;
3295 					r_result.class_name = Variant::get_type_name(base_type.builtin_type);
3296 					r_result.class_member = p_symbol;
3297 					return OK;
3298 				}
3299 			} break;
3300 			default: {
3301 				base_type.has_type = false;
3302 			} break;
3303 		}
3304 	}
3305 
3306 	return ERR_CANT_RESOLVE;
3307 }
3308 
lookup_code(const String & p_code,const String & p_symbol,const String & p_path,Object * p_owner,LookupResult & r_result)3309 Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result) {
3310 
3311 	//before parsing, try the usual stuff
3312 	if (ClassDB::class_exists(p_symbol)) {
3313 		r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS;
3314 		r_result.class_name = p_symbol;
3315 		return OK;
3316 	} else {
3317 		String under_prefix = "_" + p_symbol;
3318 		if (ClassDB::class_exists(under_prefix)) {
3319 			r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS;
3320 			r_result.class_name = p_symbol;
3321 			return OK;
3322 		}
3323 	}
3324 
3325 	for (int i = 0; i < Variant::VARIANT_MAX; i++) {
3326 		Variant::Type t = Variant::Type(i);
3327 		if (Variant::get_type_name(t) == p_symbol) {
3328 			r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS;
3329 			r_result.class_name = Variant::get_type_name(t);
3330 			return OK;
3331 		}
3332 	}
3333 
3334 	for (int i = 0; i < GDScriptFunctions::FUNC_MAX; i++) {
3335 		if (GDScriptFunctions::get_func_name(GDScriptFunctions::Function(i)) == p_symbol) {
3336 			r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_METHOD;
3337 			r_result.class_name = "@GDScript";
3338 			r_result.class_member = p_symbol;
3339 			return OK;
3340 		}
3341 	}
3342 
3343 	if ("PI" == p_symbol || "TAU" == p_symbol || "INF" == p_symbol || "NAN" == p_symbol) {
3344 		r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_CONSTANT;
3345 		r_result.class_name = "@GDScript";
3346 		r_result.class_member = p_symbol;
3347 		return OK;
3348 	}
3349 
3350 	GDScriptParser parser;
3351 	parser.parse(p_code, p_path.get_base_dir(), false, p_path, true);
3352 
3353 	if (parser.get_completion_type() == GDScriptParser::COMPLETION_NONE) {
3354 		return ERR_CANT_RESOLVE;
3355 	}
3356 
3357 	GDScriptCompletionContext context;
3358 	context._class = parser.get_completion_class();
3359 	context.function = parser.get_completion_function();
3360 	context.block = parser.get_completion_block();
3361 	context.line = parser.get_completion_line();
3362 	context.base = p_owner;
3363 	context.base_path = p_path.get_base_dir();
3364 
3365 	if (context._class && context._class->extends_class.size() > 0) {
3366 		bool success = false;
3367 		ClassDB::get_integer_constant(context._class->extends_class[0], p_symbol, &success);
3368 		if (success) {
3369 			r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_CONSTANT;
3370 			r_result.class_name = context._class->extends_class[0];
3371 			r_result.class_member = p_symbol;
3372 			return OK;
3373 		}
3374 	}
3375 
3376 	bool is_function = false;
3377 
3378 	switch (parser.get_completion_type()) {
3379 		case GDScriptParser::COMPLETION_BUILT_IN_TYPE_CONSTANT: {
3380 			r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_CONSTANT;
3381 			r_result.class_name = Variant::get_type_name(parser.get_completion_built_in_constant());
3382 			r_result.class_member = p_symbol;
3383 			return OK;
3384 		} break;
3385 		case GDScriptParser::COMPLETION_PARENT_FUNCTION:
3386 		case GDScriptParser::COMPLETION_FUNCTION: {
3387 			is_function = true;
3388 			FALLTHROUGH;
3389 		}
3390 		case GDScriptParser::COMPLETION_IDENTIFIER: {
3391 
3392 			if (!is_function) {
3393 				is_function = parser.get_completion_identifier_is_function();
3394 			}
3395 
3396 			GDScriptParser::DataType base_type;
3397 			if (context._class) {
3398 				if (parser.get_completion_type() != GDScriptParser::COMPLETION_PARENT_FUNCTION) {
3399 					base_type.has_type = true;
3400 					base_type.kind = GDScriptParser::DataType::CLASS;
3401 					base_type.class_type = const_cast<GDScriptParser::ClassNode *>(context._class);
3402 				} else {
3403 					base_type = context._class->base_type;
3404 				}
3405 			} else {
3406 				break;
3407 			}
3408 
3409 			if (!is_function && context.block) {
3410 				// Lookup local variables
3411 				const GDScriptParser::BlockNode *block = context.block;
3412 				while (block) {
3413 					if (block->variables.has(p_symbol)) {
3414 						r_result.type = ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION;
3415 						r_result.location = block->variables[p_symbol]->line;
3416 						return OK;
3417 					}
3418 					block = block->parent_block;
3419 				}
3420 			}
3421 
3422 			if (context.function && context.function->name != StringName()) {
3423 				// Lookup function arguments
3424 				for (int i = 0; i < context.function->arguments.size(); i++) {
3425 					if (context.function->arguments[i] == p_symbol) {
3426 						r_result.type = ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION;
3427 						r_result.location = context.function->line;
3428 						return OK;
3429 					}
3430 				}
3431 			}
3432 
3433 			if (_lookup_symbol_from_base(base_type, p_symbol, is_function, r_result) == OK) {
3434 				return OK;
3435 			}
3436 
3437 			if (!is_function) {
3438 				// Guess in autoloads as singletons
3439 				List<PropertyInfo> props;
3440 				ProjectSettings::get_singleton()->get_property_list(&props);
3441 
3442 				for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
3443 
3444 					String s = E->get().name;
3445 					if (!s.begins_with("autoload/"))
3446 						continue;
3447 					String name = s.get_slice("/", 1);
3448 					if (name == String(p_symbol)) {
3449 
3450 						String path = ProjectSettings::get_singleton()->get(s);
3451 						if (path.begins_with("*")) {
3452 							String script = path.substr(1, path.length());
3453 
3454 							if (!script.ends_with(".gd")) {
3455 								// Not a script, try find the script anyway,
3456 								// may have some success
3457 								script = script.get_basename() + ".gd";
3458 							}
3459 
3460 							if (FileAccess::exists(script)) {
3461 
3462 								r_result.type = ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION;
3463 								r_result.location = 0;
3464 								r_result.script = ResourceLoader::load(script);
3465 								return OK;
3466 							}
3467 						}
3468 					}
3469 				}
3470 
3471 				// Global
3472 				Map<StringName, int> classes = GDScriptLanguage::get_singleton()->get_global_map();
3473 				if (classes.has(p_symbol)) {
3474 					Variant value = GDScriptLanguage::get_singleton()->get_global_array()[classes[p_symbol]];
3475 					if (value.get_type() == Variant::OBJECT) {
3476 						Object *obj = value;
3477 						if (obj) {
3478 							if (Object::cast_to<GDScriptNativeClass>(obj)) {
3479 								r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS;
3480 								r_result.class_name = Object::cast_to<GDScriptNativeClass>(obj)->get_name();
3481 							} else {
3482 								r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS;
3483 								r_result.class_name = obj->get_class();
3484 							}
3485 
3486 							// proxy class remove the underscore.
3487 							if (r_result.class_name.begins_with("_")) {
3488 								r_result.class_name = r_result.class_name.right(1);
3489 							}
3490 							return OK;
3491 						}
3492 					} else {
3493 						/*
3494 						// Because get_integer_constant_enum and get_integer_constant don't work on @GlobalScope
3495 						// We cannot determine the exact nature of the identifier here
3496 						// Otherwise these codes would work
3497 						StringName enumName = ClassDB::get_integer_constant_enum("@GlobalScope", p_symbol, true);
3498 						if (enumName != NULL) {
3499 							r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_ENUM;
3500 							r_result.class_name = "@GlobalScope";
3501 							r_result.class_member = enumName;
3502 							return OK;
3503 						}
3504 						else {
3505 							r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_CONSTANT;
3506 							r_result.class_name = "@GlobalScope";
3507 							r_result.class_member = p_symbol;
3508 							return OK;
3509 						}*/
3510 						r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_TBD_GLOBALSCOPE;
3511 						r_result.class_name = "@GlobalScope";
3512 						r_result.class_member = p_symbol;
3513 						return OK;
3514 					}
3515 				}
3516 			}
3517 		} break;
3518 		case GDScriptParser::COMPLETION_METHOD: {
3519 			is_function = true;
3520 			FALLTHROUGH;
3521 		}
3522 		case GDScriptParser::COMPLETION_INDEX: {
3523 			const GDScriptParser::Node *node = parser.get_completion_node();
3524 			if (node->type != GDScriptParser::Node::TYPE_OPERATOR) {
3525 				break;
3526 			}
3527 			GDScriptCompletionIdentifier base;
3528 			if (!_guess_expression_type(context, static_cast<const GDScriptParser::OperatorNode *>(node)->arguments[0], base)) {
3529 				break;
3530 			}
3531 
3532 			if (_lookup_symbol_from_base(base.type, p_symbol, is_function, r_result) == OK) {
3533 				return OK;
3534 			}
3535 		} break;
3536 		case GDScriptParser::COMPLETION_VIRTUAL_FUNC: {
3537 			GDScriptParser::DataType base_type = context._class->base_type;
3538 
3539 			if (_lookup_symbol_from_base(base_type, p_symbol, true, r_result) == OK) {
3540 				return OK;
3541 			}
3542 		} break;
3543 		case GDScriptParser::COMPLETION_TYPE_HINT: {
3544 
3545 			GDScriptParser::DataType base_type = context._class->base_type;
3546 			base_type.has_type = true;
3547 			base_type.kind = GDScriptParser::DataType::CLASS;
3548 			base_type.class_type = const_cast<GDScriptParser::ClassNode *>(context._class);
3549 
3550 			if (_lookup_symbol_from_base(base_type, p_symbol, false, r_result) == OK) {
3551 				return OK;
3552 			}
3553 		} break;
3554 		default: {
3555 		}
3556 	}
3557 
3558 	return ERR_CANT_RESOLVE;
3559 }
3560 
3561 #endif
3562