1 /*************************************************************************/
2 /*  gdscript.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/core_string_names.h"
34 #include "core/engine.h"
35 #include "core/global_constants.h"
36 #include "core/io/file_access_encrypted.h"
37 #include "core/os/file_access.h"
38 #include "core/os/os.h"
39 #include "core/project_settings.h"
40 #include "gdscript_compiler.h"
41 
42 ///////////////////////////
43 
GDScriptNativeClass(const StringName & p_name)44 GDScriptNativeClass::GDScriptNativeClass(const StringName &p_name) {
45 
46 	name = p_name;
47 }
48 
_get(const StringName & p_name,Variant & r_ret) const49 bool GDScriptNativeClass::_get(const StringName &p_name, Variant &r_ret) const {
50 
51 	bool ok;
52 	int v = ClassDB::get_integer_constant(name, p_name, &ok);
53 
54 	if (ok) {
55 		r_ret = v;
56 		return true;
57 	} else {
58 		return false;
59 	}
60 }
61 
_bind_methods()62 void GDScriptNativeClass::_bind_methods() {
63 
64 	ClassDB::bind_method(D_METHOD("new"), &GDScriptNativeClass::_new);
65 }
66 
_new()67 Variant GDScriptNativeClass::_new() {
68 
69 	Object *o = instance();
70 	ERR_FAIL_COND_V_MSG(!o, Variant(), "Class type: '" + String(name) + "' is not instantiable.");
71 
72 	Reference *ref = Object::cast_to<Reference>(o);
73 	if (ref) {
74 		return REF(ref);
75 	} else {
76 		return o;
77 	}
78 }
79 
instance()80 Object *GDScriptNativeClass::instance() {
81 
82 	return ClassDB::instance(name);
83 }
84 
_create_instance(const Variant ** p_args,int p_argcount,Object * p_owner,bool p_isref,Variant::CallError & r_error)85 GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error) {
86 
87 	/* STEP 1, CREATE */
88 
89 	GDScriptInstance *instance = memnew(GDScriptInstance);
90 	instance->base_ref = p_isref;
91 	instance->members.resize(member_indices.size());
92 	instance->script = Ref<GDScript>(this);
93 	instance->owner = p_owner;
94 #ifdef DEBUG_ENABLED
95 	//needed for hot reloading
96 	for (Map<StringName, MemberInfo>::Element *E = member_indices.front(); E; E = E->next()) {
97 		instance->member_indices_cache[E->key()] = E->get().index;
98 	}
99 #endif
100 	instance->owner->set_script_instance(instance);
101 
102 	/* STEP 2, INITIALIZE AND CONSTRUCT */
103 
104 #ifndef NO_THREADS
105 	GDScriptLanguage::singleton->lock->lock();
106 #endif
107 
108 	instances.insert(instance->owner);
109 
110 #ifndef NO_THREADS
111 	GDScriptLanguage::singleton->lock->unlock();
112 #endif
113 
114 	initializer->call(instance, p_args, p_argcount, r_error);
115 
116 	if (r_error.error != Variant::CallError::CALL_OK) {
117 		instance->script = Ref<GDScript>();
118 		instance->owner->set_script_instance(NULL);
119 #ifndef NO_THREADS
120 		GDScriptLanguage::singleton->lock->lock();
121 #endif
122 		instances.erase(p_owner);
123 #ifndef NO_THREADS
124 		GDScriptLanguage::singleton->lock->unlock();
125 #endif
126 
127 		ERR_FAIL_COND_V(r_error.error != Variant::CallError::CALL_OK, NULL); //error constructing
128 	}
129 
130 	//@TODO make thread safe
131 	return instance;
132 }
133 
_new(const Variant ** p_args,int p_argcount,Variant::CallError & r_error)134 Variant GDScript::_new(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
135 
136 	/* STEP 1, CREATE */
137 
138 	if (!valid) {
139 		r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
140 		return Variant();
141 	}
142 
143 	r_error.error = Variant::CallError::CALL_OK;
144 	REF ref;
145 	Object *owner = NULL;
146 
147 	GDScript *_baseptr = this;
148 	while (_baseptr->_base) {
149 		_baseptr = _baseptr->_base;
150 	}
151 
152 	ERR_FAIL_COND_V(_baseptr->native.is_null(), Variant());
153 	if (_baseptr->native.ptr()) {
154 		owner = _baseptr->native->instance();
155 	} else {
156 		owner = memnew(Reference); //by default, no base means use reference
157 	}
158 	ERR_FAIL_COND_V_MSG(!owner, Variant(), "Can't inherit from a virtual class.");
159 
160 	Reference *r = Object::cast_to<Reference>(owner);
161 	if (r) {
162 		ref = REF(r);
163 	}
164 
165 	GDScriptInstance *instance = _create_instance(p_args, p_argcount, owner, r != NULL, r_error);
166 	if (!instance) {
167 		if (ref.is_null()) {
168 			memdelete(owner); //no owner, sorry
169 		}
170 		return Variant();
171 	}
172 
173 	if (ref.is_valid()) {
174 		return ref;
175 	} else {
176 		return owner;
177 	}
178 }
179 
can_instance() const180 bool GDScript::can_instance() const {
181 
182 #ifdef TOOLS_ENABLED
183 	return valid && (tool || ScriptServer::is_scripting_enabled());
184 #else
185 	return valid;
186 #endif
187 }
188 
get_base_script() const189 Ref<Script> GDScript::get_base_script() const {
190 
191 	if (_base) {
192 		return Ref<GDScript>(_base);
193 	} else {
194 		return Ref<Script>();
195 	}
196 }
197 
get_instance_base_type() const198 StringName GDScript::get_instance_base_type() const {
199 
200 	if (native.is_valid())
201 		return native->get_name();
202 	if (base.is_valid() && base->is_valid())
203 		return base->get_instance_base_type();
204 	return StringName();
205 }
206 
207 struct _GDScriptMemberSort {
208 
209 	int index;
210 	StringName name;
operator <_GDScriptMemberSort211 	_FORCE_INLINE_ bool operator<(const _GDScriptMemberSort &p_member) const { return index < p_member.index; }
212 };
213 
214 #ifdef TOOLS_ENABLED
215 
_placeholder_erased(PlaceHolderScriptInstance * p_placeholder)216 void GDScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) {
217 
218 	placeholders.erase(p_placeholder);
219 }
220 #endif
221 
get_script_method_list(List<MethodInfo> * p_list) const222 void GDScript::get_script_method_list(List<MethodInfo> *p_list) const {
223 
224 	const GDScript *current = this;
225 	while (current) {
226 		for (const Map<StringName, GDScriptFunction *>::Element *E = current->member_functions.front(); E; E = E->next()) {
227 			GDScriptFunction *func = E->get();
228 			MethodInfo mi;
229 			mi.name = E->key();
230 			for (int i = 0; i < func->get_argument_count(); i++) {
231 				mi.arguments.push_back(func->get_argument_type(i));
232 			}
233 
234 			mi.return_val = func->get_return_type();
235 			p_list->push_back(mi);
236 		}
237 
238 		current = current->_base;
239 	}
240 }
241 
get_script_property_list(List<PropertyInfo> * p_list) const242 void GDScript::get_script_property_list(List<PropertyInfo> *p_list) const {
243 
244 	const GDScript *sptr = this;
245 	List<PropertyInfo> props;
246 
247 	while (sptr) {
248 
249 		Vector<_GDScriptMemberSort> msort;
250 		for (Map<StringName, PropertyInfo>::Element *E = sptr->member_info.front(); E; E = E->next()) {
251 
252 			_GDScriptMemberSort ms;
253 			ERR_CONTINUE(!sptr->member_indices.has(E->key()));
254 			ms.index = sptr->member_indices[E->key()].index;
255 			ms.name = E->key();
256 			msort.push_back(ms);
257 		}
258 
259 		msort.sort();
260 		msort.invert();
261 		for (int i = 0; i < msort.size(); i++) {
262 
263 			props.push_front(sptr->member_info[msort[i].name]);
264 		}
265 
266 		sptr = sptr->_base;
267 	}
268 
269 	for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
270 		p_list->push_back(E->get());
271 	}
272 }
273 
has_method(const StringName & p_method) const274 bool GDScript::has_method(const StringName &p_method) const {
275 
276 	return member_functions.has(p_method);
277 }
278 
get_method_info(const StringName & p_method) const279 MethodInfo GDScript::get_method_info(const StringName &p_method) const {
280 
281 	const Map<StringName, GDScriptFunction *>::Element *E = member_functions.find(p_method);
282 	if (!E)
283 		return MethodInfo();
284 
285 	GDScriptFunction *func = E->get();
286 	MethodInfo mi;
287 	mi.name = E->key();
288 	for (int i = 0; i < func->get_argument_count(); i++) {
289 		mi.arguments.push_back(func->get_argument_type(i));
290 	}
291 
292 	mi.return_val = func->get_return_type();
293 	return mi;
294 }
295 
get_property_default_value(const StringName & p_property,Variant & r_value) const296 bool GDScript::get_property_default_value(const StringName &p_property, Variant &r_value) const {
297 
298 #ifdef TOOLS_ENABLED
299 
300 	const Map<StringName, Variant>::Element *E = member_default_values_cache.find(p_property);
301 	if (E) {
302 		r_value = E->get();
303 		return true;
304 	}
305 
306 	if (base_cache.is_valid()) {
307 		return base_cache->get_property_default_value(p_property, r_value);
308 	}
309 #endif
310 	return false;
311 }
312 
instance_create(Object * p_this)313 ScriptInstance *GDScript::instance_create(Object *p_this) {
314 
315 	GDScript *top = this;
316 	while (top->_base)
317 		top = top->_base;
318 
319 	if (top->native.is_valid()) {
320 		if (!ClassDB::is_parent_class(p_this->get_class_name(), top->native->get_name())) {
321 
322 			if (ScriptDebugger::get_singleton()) {
323 				GDScriptLanguage::get_singleton()->debug_break_parse(get_path(), 1, "Script inherits from native type '" + String(top->native->get_name()) + "', so it can't be instanced in object of type: '" + p_this->get_class() + "'");
324 			}
325 			ERR_FAIL_V_MSG(NULL, "Script inherits from native type '" + String(top->native->get_name()) + "', so it can't be instanced in object of type '" + p_this->get_class() + "'" + ".");
326 		}
327 	}
328 
329 	Variant::CallError unchecked_error;
330 	return _create_instance(NULL, 0, p_this, Object::cast_to<Reference>(p_this) != NULL, unchecked_error);
331 }
332 
placeholder_instance_create(Object * p_this)333 PlaceHolderScriptInstance *GDScript::placeholder_instance_create(Object *p_this) {
334 #ifdef TOOLS_ENABLED
335 	PlaceHolderScriptInstance *si = memnew(PlaceHolderScriptInstance(GDScriptLanguage::get_singleton(), Ref<Script>(this), p_this));
336 	placeholders.insert(si);
337 	_update_exports();
338 	return si;
339 #else
340 	return NULL;
341 #endif
342 }
343 
instance_has(const Object * p_this) const344 bool GDScript::instance_has(const Object *p_this) const {
345 
346 #ifndef NO_THREADS
347 	GDScriptLanguage::singleton->lock->lock();
348 #endif
349 	bool hasit = instances.has((Object *)p_this);
350 
351 #ifndef NO_THREADS
352 	GDScriptLanguage::singleton->lock->unlock();
353 #endif
354 
355 	return hasit;
356 }
357 
has_source_code() const358 bool GDScript::has_source_code() const {
359 
360 	return source != "";
361 }
get_source_code() const362 String GDScript::get_source_code() const {
363 
364 	return source;
365 }
set_source_code(const String & p_code)366 void GDScript::set_source_code(const String &p_code) {
367 
368 	if (source == p_code)
369 		return;
370 	source = p_code;
371 #ifdef TOOLS_ENABLED
372 	source_changed_cache = true;
373 #endif
374 }
375 
376 #ifdef TOOLS_ENABLED
_update_exports_values(Map<StringName,Variant> & values,List<PropertyInfo> & propnames)377 void GDScript::_update_exports_values(Map<StringName, Variant> &values, List<PropertyInfo> &propnames) {
378 
379 	if (base_cache.is_valid()) {
380 		base_cache->_update_exports_values(values, propnames);
381 	}
382 
383 	for (Map<StringName, Variant>::Element *E = member_default_values_cache.front(); E; E = E->next()) {
384 		values[E->key()] = E->get();
385 	}
386 
387 	for (List<PropertyInfo>::Element *E = members_cache.front(); E; E = E->next()) {
388 		propnames.push_back(E->get());
389 	}
390 }
391 #endif
392 
_update_exports(bool * r_err,bool p_recursive_call)393 bool GDScript::_update_exports(bool *r_err, bool p_recursive_call) {
394 
395 #ifdef TOOLS_ENABLED
396 
397 	static Vector<GDScript *> base_caches;
398 	if (!p_recursive_call)
399 		base_caches.clear();
400 	base_caches.push_back(this);
401 
402 	bool changed = false;
403 
404 	if (source_changed_cache) {
405 		source_changed_cache = false;
406 		changed = true;
407 
408 		String basedir = path;
409 
410 		if (basedir == "")
411 			basedir = get_path();
412 
413 		if (basedir != "")
414 			basedir = basedir.get_base_dir();
415 
416 		GDScriptParser parser;
417 		Error err = parser.parse(source, basedir, true, path);
418 
419 		if (err == OK) {
420 
421 			const GDScriptParser::Node *root = parser.get_parse_tree();
422 			ERR_FAIL_COND_V(root->type != GDScriptParser::Node::TYPE_CLASS, false);
423 
424 			const GDScriptParser::ClassNode *c = static_cast<const GDScriptParser::ClassNode *>(root);
425 
426 			if (base_cache.is_valid()) {
427 				base_cache->inheriters_cache.erase(get_instance_id());
428 				base_cache = Ref<GDScript>();
429 			}
430 
431 			if (c->extends_used) {
432 				String path = "";
433 				if (String(c->extends_file) != "" && String(c->extends_file) != get_path()) {
434 					path = c->extends_file;
435 					if (path.is_rel_path()) {
436 
437 						String base = get_path();
438 						if (base == "" || base.is_rel_path()) {
439 
440 							ERR_PRINT(("Could not resolve relative path for parent class: " + path).utf8().get_data());
441 						} else {
442 							path = base.get_base_dir().plus_file(path);
443 						}
444 					}
445 				} else if (c->extends_class.size() != 0) {
446 					String base = c->extends_class[0];
447 
448 					if (ScriptServer::is_global_class(base))
449 						path = ScriptServer::get_global_class_path(base);
450 				}
451 
452 				if (path != "") {
453 					if (path != get_path()) {
454 
455 						Ref<GDScript> bf = ResourceLoader::load(path);
456 
457 						if (bf.is_valid()) {
458 
459 							base_cache = bf;
460 							bf->inheriters_cache.insert(get_instance_id());
461 						}
462 					} else {
463 						ERR_PRINT(("Path extending itself in  " + path).utf8().get_data());
464 					}
465 				}
466 			}
467 
468 			members_cache.clear();
469 			member_default_values_cache.clear();
470 
471 			for (int i = 0; i < c->variables.size(); i++) {
472 				if (c->variables[i]._export.type == Variant::NIL)
473 					continue;
474 
475 				members_cache.push_back(c->variables[i]._export);
476 				member_default_values_cache[c->variables[i].identifier] = c->variables[i].default_value;
477 			}
478 
479 			_signals.clear();
480 
481 			for (int i = 0; i < c->_signals.size(); i++) {
482 				_signals[c->_signals[i].name] = c->_signals[i].arguments;
483 			}
484 		} else {
485 			placeholder_fallback_enabled = true;
486 			return false;
487 		}
488 	} else if (placeholder_fallback_enabled) {
489 		return false;
490 	}
491 
492 	placeholder_fallback_enabled = false;
493 
494 	if (base_cache.is_valid() && base_cache->is_valid()) {
495 		for (int i = 0; i < base_caches.size(); i++) {
496 			if (base_caches[i] == base_cache.ptr()) {
497 				if (r_err)
498 					*r_err = true;
499 				valid = false; // to show error in the editor
500 				base_cache->valid = false;
501 				base_cache->inheriters_cache.clear(); // to prevent future stackoverflows
502 				base_cache.unref();
503 				base.unref();
504 				_base = nullptr;
505 				ERR_FAIL_V_MSG(false, "Cyclic inheritance in script class.");
506 			}
507 		}
508 		if (base_cache->_update_exports(r_err, true)) {
509 			if (r_err && *r_err)
510 				return false;
511 			changed = true;
512 		}
513 	}
514 
515 	if (placeholders.size()) { //hm :(
516 
517 		// update placeholders if any
518 		Map<StringName, Variant> values;
519 		List<PropertyInfo> propnames;
520 		_update_exports_values(values, propnames);
521 
522 		for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
523 			E->get()->update(propnames, values);
524 		}
525 	}
526 
527 	return changed;
528 
529 #else
530 	return false;
531 #endif
532 }
533 
update_exports()534 void GDScript::update_exports() {
535 
536 #ifdef TOOLS_ENABLED
537 
538 	bool cyclic_error = false;
539 	_update_exports(&cyclic_error);
540 	if (cyclic_error)
541 		return;
542 
543 	Set<ObjectID> copy = inheriters_cache; //might get modified
544 
545 	for (Set<ObjectID>::Element *E = copy.front(); E; E = E->next()) {
546 		Object *id = ObjectDB::get_instance(E->get());
547 		GDScript *s = Object::cast_to<GDScript>(id);
548 		if (!s)
549 			continue;
550 		s->update_exports();
551 	}
552 
553 #endif
554 }
555 
_set_subclass_path(Ref<GDScript> & p_sc,const String & p_path)556 void GDScript::_set_subclass_path(Ref<GDScript> &p_sc, const String &p_path) {
557 
558 	p_sc->path = p_path;
559 	for (Map<StringName, Ref<GDScript> >::Element *E = p_sc->subclasses.front(); E; E = E->next()) {
560 
561 		_set_subclass_path(E->get(), p_path);
562 	}
563 }
564 
reload(bool p_keep_state)565 Error GDScript::reload(bool p_keep_state) {
566 
567 #ifndef NO_THREADS
568 	GDScriptLanguage::singleton->lock->lock();
569 #endif
570 	bool has_instances = instances.size();
571 
572 #ifndef NO_THREADS
573 	GDScriptLanguage::singleton->lock->unlock();
574 #endif
575 
576 	ERR_FAIL_COND_V(!p_keep_state && has_instances, ERR_ALREADY_IN_USE);
577 
578 	String basedir = path;
579 
580 	if (basedir == "")
581 		basedir = get_path();
582 
583 	if (basedir != "")
584 		basedir = basedir.get_base_dir();
585 
586 	if (source.find("%BASE%") != -1) {
587 		//loading a template, don't parse
588 		return OK;
589 	}
590 
591 	valid = false;
592 	GDScriptParser parser;
593 	Error err = parser.parse(source, basedir, false, path);
594 	if (err) {
595 		if (ScriptDebugger::get_singleton()) {
596 			GDScriptLanguage::get_singleton()->debug_break_parse(get_path(), parser.get_error_line(), "Parser Error: " + parser.get_error());
597 		}
598 		_err_print_error("GDScript::reload", path.empty() ? "built-in" : (const char *)path.utf8().get_data(), parser.get_error_line(), ("Parse Error: " + parser.get_error()).utf8().get_data(), ERR_HANDLER_SCRIPT);
599 		ERR_FAIL_V(ERR_PARSE_ERROR);
600 	}
601 
602 	bool can_run = ScriptServer::is_scripting_enabled() || parser.is_tool_script();
603 
604 	GDScriptCompiler compiler;
605 	err = compiler.compile(&parser, this, p_keep_state);
606 
607 	if (err) {
608 
609 		if (can_run) {
610 			if (ScriptDebugger::get_singleton()) {
611 				GDScriptLanguage::get_singleton()->debug_break_parse(get_path(), compiler.get_error_line(), "Parser Error: " + compiler.get_error());
612 			}
613 			_err_print_error("GDScript::reload", path.empty() ? "built-in" : (const char *)path.utf8().get_data(), compiler.get_error_line(), ("Compile Error: " + compiler.get_error()).utf8().get_data(), ERR_HANDLER_SCRIPT);
614 			ERR_FAIL_V(ERR_COMPILATION_FAILED);
615 		} else {
616 			return err;
617 		}
618 	}
619 #ifdef DEBUG_ENABLED
620 	for (const List<GDScriptWarning>::Element *E = parser.get_warnings().front(); E; E = E->next()) {
621 		const GDScriptWarning &warning = E->get();
622 		if (ScriptDebugger::get_singleton()) {
623 			Vector<ScriptLanguage::StackInfo> si;
624 			ScriptDebugger::get_singleton()->send_error("", get_path(), warning.line, warning.get_name(), warning.get_message(), ERR_HANDLER_WARNING, si);
625 		}
626 	}
627 #endif
628 
629 	valid = true;
630 
631 	for (Map<StringName, Ref<GDScript> >::Element *E = subclasses.front(); E; E = E->next()) {
632 
633 		_set_subclass_path(E->get(), path);
634 	}
635 
636 	return OK;
637 }
638 
get_language() const639 ScriptLanguage *GDScript::get_language() const {
640 
641 	return GDScriptLanguage::get_singleton();
642 }
643 
get_constants(Map<StringName,Variant> * p_constants)644 void GDScript::get_constants(Map<StringName, Variant> *p_constants) {
645 
646 	if (p_constants) {
647 		for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) {
648 			(*p_constants)[E->key()] = E->value();
649 		}
650 	}
651 }
652 
get_members(Set<StringName> * p_members)653 void GDScript::get_members(Set<StringName> *p_members) {
654 	if (p_members) {
655 		for (Set<StringName>::Element *E = members.front(); E; E = E->next()) {
656 			p_members->insert(E->get());
657 		}
658 	}
659 }
660 
call(const StringName & p_method,const Variant ** p_args,int p_argcount,Variant::CallError & r_error)661 Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
662 
663 	GDScript *top = this;
664 	while (top) {
665 
666 		Map<StringName, GDScriptFunction *>::Element *E = top->member_functions.find(p_method);
667 		if (E) {
668 
669 			ERR_FAIL_COND_V_MSG(!E->get()->is_static(), Variant(), "Can't call non-static function '" + String(p_method) + "' in script.");
670 
671 			return E->get()->call(NULL, p_args, p_argcount, r_error);
672 		}
673 		top = top->_base;
674 	}
675 
676 	//none found, regular
677 
678 	return Script::call(p_method, p_args, p_argcount, r_error);
679 }
680 
_get(const StringName & p_name,Variant & r_ret) const681 bool GDScript::_get(const StringName &p_name, Variant &r_ret) const {
682 
683 	{
684 
685 		const GDScript *top = this;
686 		while (top) {
687 
688 			{
689 				const Map<StringName, Variant>::Element *E = top->constants.find(p_name);
690 				if (E) {
691 
692 					r_ret = E->get();
693 					return true;
694 				}
695 			}
696 
697 			{
698 				const Map<StringName, Ref<GDScript> >::Element *E = subclasses.find(p_name);
699 				if (E) {
700 
701 					r_ret = E->get();
702 					return true;
703 				}
704 			}
705 			top = top->_base;
706 		}
707 
708 		if (p_name == GDScriptLanguage::get_singleton()->strings._script_source) {
709 
710 			r_ret = get_source_code();
711 			return true;
712 		}
713 	}
714 
715 	return false;
716 }
_set(const StringName & p_name,const Variant & p_value)717 bool GDScript::_set(const StringName &p_name, const Variant &p_value) {
718 
719 	if (p_name == GDScriptLanguage::get_singleton()->strings._script_source) {
720 
721 		set_source_code(p_value);
722 		reload();
723 	} else
724 		return false;
725 
726 	return true;
727 }
728 
_get_property_list(List<PropertyInfo> * p_properties) const729 void GDScript::_get_property_list(List<PropertyInfo> *p_properties) const {
730 
731 	p_properties->push_back(PropertyInfo(Variant::STRING, "script/source", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
732 }
733 
_bind_methods()734 void GDScript::_bind_methods() {
735 
736 	ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &GDScript::_new, MethodInfo("new"));
737 
738 	ClassDB::bind_method(D_METHOD("get_as_byte_code"), &GDScript::get_as_byte_code);
739 }
740 
get_as_byte_code() const741 Vector<uint8_t> GDScript::get_as_byte_code() const {
742 
743 	GDScriptTokenizerBuffer tokenizer;
744 	return tokenizer.parse_code_string(source);
745 };
746 
load_byte_code(const String & p_path)747 Error GDScript::load_byte_code(const String &p_path) {
748 
749 	Vector<uint8_t> bytecode;
750 
751 	if (p_path.ends_with("gde")) {
752 
753 		FileAccess *fa = FileAccess::open(p_path, FileAccess::READ);
754 		ERR_FAIL_COND_V(!fa, ERR_CANT_OPEN);
755 
756 		FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
757 		ERR_FAIL_COND_V(!fae, ERR_CANT_OPEN);
758 
759 		Vector<uint8_t> key;
760 		key.resize(32);
761 		for (int i = 0; i < key.size(); i++) {
762 			key.write[i] = script_encryption_key[i];
763 		}
764 
765 		Error err = fae->open_and_parse(fa, key, FileAccessEncrypted::MODE_READ);
766 
767 		if (err) {
768 			fa->close();
769 			memdelete(fa);
770 			memdelete(fae);
771 
772 			ERR_FAIL_COND_V(err, err);
773 		}
774 
775 		bytecode.resize(fae->get_len());
776 		fae->get_buffer(bytecode.ptrw(), bytecode.size());
777 		fae->close();
778 		memdelete(fae);
779 
780 	} else {
781 
782 		bytecode = FileAccess::get_file_as_array(p_path);
783 	}
784 
785 	ERR_FAIL_COND_V(bytecode.size() == 0, ERR_PARSE_ERROR);
786 	path = p_path;
787 
788 	String basedir = path;
789 
790 	if (basedir == "")
791 		basedir = get_path();
792 
793 	if (basedir != "")
794 		basedir = basedir.get_base_dir();
795 
796 	valid = false;
797 	GDScriptParser parser;
798 	Error err = parser.parse_bytecode(bytecode, basedir, get_path());
799 	if (err) {
800 		_err_print_error("GDScript::load_byte_code", path.empty() ? "built-in" : (const char *)path.utf8().get_data(), parser.get_error_line(), ("Parse Error: " + parser.get_error()).utf8().get_data(), ERR_HANDLER_SCRIPT);
801 		ERR_FAIL_V(ERR_PARSE_ERROR);
802 	}
803 
804 	GDScriptCompiler compiler;
805 	err = compiler.compile(&parser, this);
806 
807 	if (err) {
808 		_err_print_error("GDScript::load_byte_code", path.empty() ? "built-in" : (const char *)path.utf8().get_data(), compiler.get_error_line(), ("Compile Error: " + compiler.get_error()).utf8().get_data(), ERR_HANDLER_SCRIPT);
809 		ERR_FAIL_V(ERR_COMPILATION_FAILED);
810 	}
811 
812 	valid = true;
813 
814 	for (Map<StringName, Ref<GDScript> >::Element *E = subclasses.front(); E; E = E->next()) {
815 
816 		_set_subclass_path(E->get(), path);
817 	}
818 
819 	return OK;
820 }
821 
load_source_code(const String & p_path)822 Error GDScript::load_source_code(const String &p_path) {
823 
824 	PoolVector<uint8_t> sourcef;
825 	Error err;
826 	FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
827 	if (err) {
828 
829 		ERR_FAIL_COND_V(err, err);
830 	}
831 
832 	int len = f->get_len();
833 	sourcef.resize(len + 1);
834 	PoolVector<uint8_t>::Write w = sourcef.write();
835 	int r = f->get_buffer(w.ptr(), len);
836 	f->close();
837 	memdelete(f);
838 	ERR_FAIL_COND_V(r != len, ERR_CANT_OPEN);
839 	w[len] = 0;
840 
841 	String s;
842 	if (s.parse_utf8((const char *)w.ptr())) {
843 
844 		ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode.");
845 	}
846 
847 	source = s;
848 #ifdef TOOLS_ENABLED
849 	source_changed_cache = true;
850 #endif
851 	path = p_path;
852 	return OK;
853 }
854 
debug_get_member_functions() const855 const Map<StringName, GDScriptFunction *> &GDScript::debug_get_member_functions() const {
856 
857 	return member_functions;
858 }
859 
debug_get_member_by_index(int p_idx) const860 StringName GDScript::debug_get_member_by_index(int p_idx) const {
861 
862 	for (const Map<StringName, MemberInfo>::Element *E = member_indices.front(); E; E = E->next()) {
863 
864 		if (E->get().index == p_idx)
865 			return E->key();
866 	}
867 
868 	return "<error>";
869 }
870 
get_base() const871 Ref<GDScript> GDScript::get_base() const {
872 
873 	return base;
874 }
875 
has_script_signal(const StringName & p_signal) const876 bool GDScript::has_script_signal(const StringName &p_signal) const {
877 	if (_signals.has(p_signal))
878 		return true;
879 	if (base.is_valid()) {
880 		return base->has_script_signal(p_signal);
881 	}
882 #ifdef TOOLS_ENABLED
883 	else if (base_cache.is_valid()) {
884 		return base_cache->has_script_signal(p_signal);
885 	}
886 #endif
887 	return false;
888 }
get_script_signal_list(List<MethodInfo> * r_signals) const889 void GDScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
890 
891 	for (const Map<StringName, Vector<StringName> >::Element *E = _signals.front(); E; E = E->next()) {
892 
893 		MethodInfo mi;
894 		mi.name = E->key();
895 		for (int i = 0; i < E->get().size(); i++) {
896 			PropertyInfo arg;
897 			arg.name = E->get()[i];
898 			mi.arguments.push_back(arg);
899 		}
900 		r_signals->push_back(mi);
901 	}
902 
903 	if (base.is_valid()) {
904 		base->get_script_signal_list(r_signals);
905 	}
906 #ifdef TOOLS_ENABLED
907 	else if (base_cache.is_valid()) {
908 		base_cache->get_script_signal_list(r_signals);
909 	}
910 
911 #endif
912 }
913 
GDScript()914 GDScript::GDScript() :
915 		script_list(this) {
916 
917 	_static_ref = this;
918 	valid = false;
919 	subclass_count = 0;
920 	initializer = NULL;
921 	_base = NULL;
922 	_owner = NULL;
923 	tool = false;
924 #ifdef TOOLS_ENABLED
925 	source_changed_cache = false;
926 	placeholder_fallback_enabled = false;
927 #endif
928 
929 #ifdef DEBUG_ENABLED
930 	if (GDScriptLanguage::get_singleton()->lock) {
931 		GDScriptLanguage::get_singleton()->lock->lock();
932 	}
933 	GDScriptLanguage::get_singleton()->script_list.add(&script_list);
934 
935 	if (GDScriptLanguage::get_singleton()->lock) {
936 		GDScriptLanguage::get_singleton()->lock->unlock();
937 	}
938 #endif
939 }
940 
_save_orphaned_subclasses()941 void GDScript::_save_orphaned_subclasses() {
942 	struct ClassRefWithName {
943 		ObjectID id;
944 		String fully_qualified_name;
945 	};
946 	Vector<ClassRefWithName> weak_subclasses;
947 	// collect subclasses ObjectID and name
948 	for (Map<StringName, Ref<GDScript> >::Element *E = subclasses.front(); E; E = E->next()) {
949 		E->get()->_owner = NULL; //bye, you are no longer owned cause I died
950 		ClassRefWithName subclass;
951 		subclass.id = E->get()->get_instance_id();
952 		subclass.fully_qualified_name = E->get()->fully_qualified_name;
953 		weak_subclasses.push_back(subclass);
954 	}
955 
956 	// clear subclasses to allow unused subclasses to be deleted
957 	subclasses.clear();
958 	// subclasses are also held by constants, clear those as well
959 	constants.clear();
960 
961 	// keep orphan subclass only for subclasses that are still in use
962 	for (int i = 0; i < weak_subclasses.size(); i++) {
963 		ClassRefWithName subclass = weak_subclasses[i];
964 		Object *obj = ObjectDB::get_instance(subclass.id);
965 		if (!obj)
966 			continue;
967 		// subclass is not released
968 		GDScriptLanguage::get_singleton()->add_orphan_subclass(subclass.fully_qualified_name, subclass.id);
969 	}
970 }
971 
~GDScript()972 GDScript::~GDScript() {
973 
974 	if (GDScriptLanguage::get_singleton()->lock) {
975 		GDScriptLanguage::get_singleton()->lock->lock();
976 	}
977 	while (SelfList<GDScriptFunctionState> *E = pending_func_states.first()) {
978 		E->self()->_clear_stack();
979 		pending_func_states.remove(E);
980 	}
981 	if (GDScriptLanguage::get_singleton()->lock) {
982 		GDScriptLanguage::get_singleton()->lock->unlock();
983 	}
984 
985 	for (Map<StringName, GDScriptFunction *>::Element *E = member_functions.front(); E; E = E->next()) {
986 		memdelete(E->get());
987 	}
988 
989 	_save_orphaned_subclasses();
990 
991 #ifdef DEBUG_ENABLED
992 	if (GDScriptLanguage::get_singleton()->lock) {
993 		GDScriptLanguage::get_singleton()->lock->lock();
994 	}
995 	GDScriptLanguage::get_singleton()->script_list.remove(&script_list);
996 
997 	if (GDScriptLanguage::get_singleton()->lock) {
998 		GDScriptLanguage::get_singleton()->lock->unlock();
999 	}
1000 #endif
1001 }
1002 
1003 //////////////////////////////
1004 //         INSTANCE         //
1005 //////////////////////////////
1006 
set(const StringName & p_name,const Variant & p_value)1007 bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) {
1008 
1009 	//member
1010 	{
1011 		const Map<StringName, GDScript::MemberInfo>::Element *E = script->member_indices.find(p_name);
1012 		if (E) {
1013 			const GDScript::MemberInfo *member = &E->get();
1014 			if (member->setter) {
1015 				const Variant *val = &p_value;
1016 				Variant::CallError err;
1017 				call(member->setter, &val, 1, err);
1018 				if (err.error == Variant::CallError::CALL_OK) {
1019 					return true; //function exists, call was successful
1020 				}
1021 			} else {
1022 				if (!member->data_type.is_type(p_value)) {
1023 					// Try conversion
1024 					Variant::CallError ce;
1025 					const Variant *value = &p_value;
1026 					Variant converted = Variant::construct(member->data_type.builtin_type, &value, 1, ce);
1027 					if (ce.error == Variant::CallError::CALL_OK) {
1028 						members.write[member->index] = converted;
1029 						return true;
1030 					} else {
1031 						return false;
1032 					}
1033 				} else {
1034 					members.write[member->index] = p_value;
1035 				}
1036 			}
1037 			return true;
1038 		}
1039 	}
1040 
1041 	GDScript *sptr = script.ptr();
1042 	while (sptr) {
1043 
1044 		Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._set);
1045 		if (E) {
1046 
1047 			Variant name = p_name;
1048 			const Variant *args[2] = { &name, &p_value };
1049 
1050 			Variant::CallError err;
1051 			Variant ret = E->get()->call(this, (const Variant **)args, 2, err);
1052 			if (err.error == Variant::CallError::CALL_OK && ret.get_type() == Variant::BOOL && ret.operator bool())
1053 				return true;
1054 		}
1055 		sptr = sptr->_base;
1056 	}
1057 
1058 	return false;
1059 }
1060 
get(const StringName & p_name,Variant & r_ret) const1061 bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
1062 
1063 	const GDScript *sptr = script.ptr();
1064 	while (sptr) {
1065 
1066 		{
1067 			const Map<StringName, GDScript::MemberInfo>::Element *E = script->member_indices.find(p_name);
1068 			if (E) {
1069 				if (E->get().getter) {
1070 					Variant::CallError err;
1071 					r_ret = const_cast<GDScriptInstance *>(this)->call(E->get().getter, NULL, 0, err);
1072 					if (err.error == Variant::CallError::CALL_OK) {
1073 						return true;
1074 					}
1075 				}
1076 				r_ret = members[E->get().index];
1077 				return true; //index found
1078 			}
1079 		}
1080 
1081 		{
1082 
1083 			const GDScript *sl = sptr;
1084 			while (sl) {
1085 				const Map<StringName, Variant>::Element *E = sl->constants.find(p_name);
1086 				if (E) {
1087 					r_ret = E->get();
1088 					return true; //index found
1089 				}
1090 				sl = sl->_base;
1091 			}
1092 		}
1093 
1094 		{
1095 			const Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._get);
1096 			if (E) {
1097 
1098 				Variant name = p_name;
1099 				const Variant *args[1] = { &name };
1100 
1101 				Variant::CallError err;
1102 				Variant ret = const_cast<GDScriptFunction *>(E->get())->call(const_cast<GDScriptInstance *>(this), (const Variant **)args, 1, err);
1103 				if (err.error == Variant::CallError::CALL_OK && ret.get_type() != Variant::NIL) {
1104 					r_ret = ret;
1105 					return true;
1106 				}
1107 			}
1108 		}
1109 		sptr = sptr->_base;
1110 	}
1111 
1112 	return false;
1113 }
1114 
get_property_type(const StringName & p_name,bool * r_is_valid) const1115 Variant::Type GDScriptInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const {
1116 
1117 	const GDScript *sptr = script.ptr();
1118 	while (sptr) {
1119 
1120 		if (sptr->member_info.has(p_name)) {
1121 			if (r_is_valid)
1122 				*r_is_valid = true;
1123 			return sptr->member_info[p_name].type;
1124 		}
1125 		sptr = sptr->_base;
1126 	}
1127 
1128 	if (r_is_valid)
1129 		*r_is_valid = false;
1130 	return Variant::NIL;
1131 }
1132 
get_property_list(List<PropertyInfo> * p_properties) const1133 void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const {
1134 	// exported members, not done yet!
1135 
1136 	const GDScript *sptr = script.ptr();
1137 	List<PropertyInfo> props;
1138 
1139 	while (sptr) {
1140 
1141 		const Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._get_property_list);
1142 		if (E) {
1143 
1144 			Variant::CallError err;
1145 			Variant ret = const_cast<GDScriptFunction *>(E->get())->call(const_cast<GDScriptInstance *>(this), NULL, 0, err);
1146 			if (err.error == Variant::CallError::CALL_OK) {
1147 
1148 				ERR_FAIL_COND_MSG(ret.get_type() != Variant::ARRAY, "Wrong type for _get_property_list, must be an array of dictionaries.");
1149 
1150 				Array arr = ret;
1151 				for (int i = 0; i < arr.size(); i++) {
1152 
1153 					Dictionary d = arr[i];
1154 					ERR_CONTINUE(!d.has("name"));
1155 					ERR_CONTINUE(!d.has("type"));
1156 					PropertyInfo pinfo;
1157 					pinfo.type = Variant::Type(d["type"].operator int());
1158 					ERR_CONTINUE(pinfo.type < 0 || pinfo.type >= Variant::VARIANT_MAX);
1159 					pinfo.name = d["name"];
1160 					ERR_CONTINUE(pinfo.name == "");
1161 					if (d.has("hint"))
1162 						pinfo.hint = PropertyHint(d["hint"].operator int());
1163 					if (d.has("hint_string"))
1164 						pinfo.hint_string = d["hint_string"];
1165 					if (d.has("usage"))
1166 						pinfo.usage = d["usage"];
1167 
1168 					props.push_back(pinfo);
1169 				}
1170 			}
1171 		}
1172 
1173 		//instance a fake script for editing the values
1174 
1175 		Vector<_GDScriptMemberSort> msort;
1176 		for (Map<StringName, PropertyInfo>::Element *F = sptr->member_info.front(); F; F = F->next()) {
1177 
1178 			_GDScriptMemberSort ms;
1179 			ERR_CONTINUE(!sptr->member_indices.has(F->key()));
1180 			ms.index = sptr->member_indices[F->key()].index;
1181 			ms.name = F->key();
1182 			msort.push_back(ms);
1183 		}
1184 
1185 		msort.sort();
1186 		msort.invert();
1187 		for (int i = 0; i < msort.size(); i++) {
1188 
1189 			props.push_front(sptr->member_info[msort[i].name]);
1190 		}
1191 
1192 		sptr = sptr->_base;
1193 	}
1194 
1195 	for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
1196 
1197 		p_properties->push_back(E->get());
1198 	}
1199 }
1200 
get_method_list(List<MethodInfo> * p_list) const1201 void GDScriptInstance::get_method_list(List<MethodInfo> *p_list) const {
1202 
1203 	const GDScript *sptr = script.ptr();
1204 	while (sptr) {
1205 
1206 		for (Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.front(); E; E = E->next()) {
1207 
1208 			MethodInfo mi;
1209 			mi.name = E->key();
1210 			mi.flags |= METHOD_FLAG_FROM_SCRIPT;
1211 			for (int i = 0; i < E->get()->get_argument_count(); i++)
1212 				mi.arguments.push_back(PropertyInfo(Variant::NIL, "arg" + itos(i)));
1213 			p_list->push_back(mi);
1214 		}
1215 		sptr = sptr->_base;
1216 	}
1217 }
1218 
has_method(const StringName & p_method) const1219 bool GDScriptInstance::has_method(const StringName &p_method) const {
1220 
1221 	const GDScript *sptr = script.ptr();
1222 	while (sptr) {
1223 		const Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(p_method);
1224 		if (E)
1225 			return true;
1226 		sptr = sptr->_base;
1227 	}
1228 
1229 	return false;
1230 }
call(const StringName & p_method,const Variant ** p_args,int p_argcount,Variant::CallError & r_error)1231 Variant GDScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
1232 
1233 	GDScript *sptr = script.ptr();
1234 	while (sptr) {
1235 		Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(p_method);
1236 		if (E) {
1237 			return E->get()->call(this, p_args, p_argcount, r_error);
1238 		}
1239 		sptr = sptr->_base;
1240 	}
1241 	r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
1242 	return Variant();
1243 }
1244 
call_multilevel(const StringName & p_method,const Variant ** p_args,int p_argcount)1245 void GDScriptInstance::call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount) {
1246 
1247 	GDScript *sptr = script.ptr();
1248 	Variant::CallError ce;
1249 
1250 	while (sptr) {
1251 		Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(p_method);
1252 		if (E) {
1253 			E->get()->call(this, p_args, p_argcount, ce);
1254 		}
1255 		sptr = sptr->_base;
1256 	}
1257 }
1258 
_ml_call_reversed(GDScript * sptr,const StringName & p_method,const Variant ** p_args,int p_argcount)1259 void GDScriptInstance::_ml_call_reversed(GDScript *sptr, const StringName &p_method, const Variant **p_args, int p_argcount) {
1260 
1261 	if (sptr->_base)
1262 		_ml_call_reversed(sptr->_base, p_method, p_args, p_argcount);
1263 
1264 	Variant::CallError ce;
1265 
1266 	Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(p_method);
1267 	if (E) {
1268 		E->get()->call(this, p_args, p_argcount, ce);
1269 	}
1270 }
1271 
call_multilevel_reversed(const StringName & p_method,const Variant ** p_args,int p_argcount)1272 void GDScriptInstance::call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount) {
1273 
1274 	if (script.ptr()) {
1275 		_ml_call_reversed(script.ptr(), p_method, p_args, p_argcount);
1276 	}
1277 }
1278 
notification(int p_notification)1279 void GDScriptInstance::notification(int p_notification) {
1280 
1281 	//notification is not virtual, it gets called at ALL levels just like in C.
1282 	Variant value = p_notification;
1283 	const Variant *args[1] = { &value };
1284 
1285 	GDScript *sptr = script.ptr();
1286 	while (sptr) {
1287 		Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._notification);
1288 		if (E) {
1289 			Variant::CallError err;
1290 			E->get()->call(this, args, 1, err);
1291 			if (err.error != Variant::CallError::CALL_OK) {
1292 				//print error about notification call
1293 			}
1294 		}
1295 		sptr = sptr->_base;
1296 	}
1297 }
1298 
to_string(bool * r_valid)1299 String GDScriptInstance::to_string(bool *r_valid) {
1300 	if (has_method(CoreStringNames::get_singleton()->_to_string)) {
1301 		Variant::CallError ce;
1302 		Variant ret = call(CoreStringNames::get_singleton()->_to_string, NULL, 0, ce);
1303 		if (ce.error == Variant::CallError::CALL_OK) {
1304 			if (ret.get_type() != Variant::STRING) {
1305 				if (r_valid)
1306 					*r_valid = false;
1307 				ERR_FAIL_V_MSG(String(), "Wrong type for " + CoreStringNames::get_singleton()->_to_string + ", must be a String.");
1308 			}
1309 			if (r_valid)
1310 				*r_valid = true;
1311 			return ret.operator String();
1312 		}
1313 	}
1314 	if (r_valid)
1315 		*r_valid = false;
1316 	return String();
1317 }
1318 
get_script() const1319 Ref<Script> GDScriptInstance::get_script() const {
1320 
1321 	return script;
1322 }
1323 
get_language()1324 ScriptLanguage *GDScriptInstance::get_language() {
1325 
1326 	return GDScriptLanguage::get_singleton();
1327 }
1328 
get_rpc_mode(const StringName & p_method) const1329 MultiplayerAPI::RPCMode GDScriptInstance::get_rpc_mode(const StringName &p_method) const {
1330 
1331 	const GDScript *cscript = script.ptr();
1332 
1333 	while (cscript) {
1334 		const Map<StringName, GDScriptFunction *>::Element *E = cscript->member_functions.find(p_method);
1335 		if (E) {
1336 
1337 			if (E->get()->get_rpc_mode() != MultiplayerAPI::RPC_MODE_DISABLED) {
1338 				return E->get()->get_rpc_mode();
1339 			}
1340 		}
1341 		cscript = cscript->_base;
1342 	}
1343 
1344 	return MultiplayerAPI::RPC_MODE_DISABLED;
1345 }
1346 
get_rset_mode(const StringName & p_variable) const1347 MultiplayerAPI::RPCMode GDScriptInstance::get_rset_mode(const StringName &p_variable) const {
1348 
1349 	const GDScript *cscript = script.ptr();
1350 
1351 	while (cscript) {
1352 		const Map<StringName, GDScript::MemberInfo>::Element *E = cscript->member_indices.find(p_variable);
1353 		if (E) {
1354 
1355 			if (E->get().rpc_mode) {
1356 				return E->get().rpc_mode;
1357 			}
1358 		}
1359 		cscript = cscript->_base;
1360 	}
1361 
1362 	return MultiplayerAPI::RPC_MODE_DISABLED;
1363 }
1364 
reload_members()1365 void GDScriptInstance::reload_members() {
1366 
1367 #ifdef DEBUG_ENABLED
1368 
1369 	members.resize(script->member_indices.size()); //resize
1370 
1371 	Vector<Variant> new_members;
1372 	new_members.resize(script->member_indices.size());
1373 
1374 	//pass the values to the new indices
1375 	for (Map<StringName, GDScript::MemberInfo>::Element *E = script->member_indices.front(); E; E = E->next()) {
1376 
1377 		if (member_indices_cache.has(E->key())) {
1378 			Variant value = members[member_indices_cache[E->key()]];
1379 			new_members.write[E->get().index] = value;
1380 		}
1381 	}
1382 
1383 	//apply
1384 	members = new_members;
1385 
1386 	//pass the values to the new indices
1387 	member_indices_cache.clear();
1388 	for (Map<StringName, GDScript::MemberInfo>::Element *E = script->member_indices.front(); E; E = E->next()) {
1389 
1390 		member_indices_cache[E->key()] = E->get().index;
1391 	}
1392 
1393 #endif
1394 }
1395 
GDScriptInstance()1396 GDScriptInstance::GDScriptInstance() {
1397 	owner = NULL;
1398 	base_ref = false;
1399 }
1400 
~GDScriptInstance()1401 GDScriptInstance::~GDScriptInstance() {
1402 #ifndef NO_THREADS
1403 	GDScriptLanguage::singleton->lock->lock();
1404 #endif
1405 
1406 	while (SelfList<GDScriptFunctionState> *E = pending_func_states.first()) {
1407 		E->self()->_clear_stack();
1408 		pending_func_states.remove(E);
1409 	}
1410 
1411 	if (script.is_valid() && owner) {
1412 		script->instances.erase(owner);
1413 	}
1414 
1415 #ifndef NO_THREADS
1416 	GDScriptLanguage::singleton->lock->unlock();
1417 #endif
1418 }
1419 
1420 /************* SCRIPT LANGUAGE **************/
1421 
1422 GDScriptLanguage *GDScriptLanguage::singleton = NULL;
1423 
get_name() const1424 String GDScriptLanguage::get_name() const {
1425 
1426 	return "GDScript";
1427 }
1428 
1429 /* LANGUAGE FUNCTIONS */
1430 
_add_global(const StringName & p_name,const Variant & p_value)1431 void GDScriptLanguage::_add_global(const StringName &p_name, const Variant &p_value) {
1432 
1433 	if (globals.has(p_name)) {
1434 		//overwrite existing
1435 		global_array.write[globals[p_name]] = p_value;
1436 		return;
1437 	}
1438 	globals[p_name] = global_array.size();
1439 	global_array.push_back(p_value);
1440 	_global_array = global_array.ptrw();
1441 }
1442 
add_global_constant(const StringName & p_variable,const Variant & p_value)1443 void GDScriptLanguage::add_global_constant(const StringName &p_variable, const Variant &p_value) {
1444 
1445 	_add_global(p_variable, p_value);
1446 }
1447 
add_named_global_constant(const StringName & p_name,const Variant & p_value)1448 void GDScriptLanguage::add_named_global_constant(const StringName &p_name, const Variant &p_value) {
1449 	named_globals[p_name] = p_value;
1450 }
1451 
remove_named_global_constant(const StringName & p_name)1452 void GDScriptLanguage::remove_named_global_constant(const StringName &p_name) {
1453 	ERR_FAIL_COND(!named_globals.has(p_name));
1454 	named_globals.erase(p_name);
1455 }
1456 
init()1457 void GDScriptLanguage::init() {
1458 
1459 	//populate global constants
1460 	int gcc = GlobalConstants::get_global_constant_count();
1461 	for (int i = 0; i < gcc; i++) {
1462 
1463 		_add_global(StaticCString::create(GlobalConstants::get_global_constant_name(i)), GlobalConstants::get_global_constant_value(i));
1464 	}
1465 
1466 	_add_global(StaticCString::create("PI"), Math_PI);
1467 	_add_global(StaticCString::create("TAU"), Math_TAU);
1468 	_add_global(StaticCString::create("INF"), Math_INF);
1469 	_add_global(StaticCString::create("NAN"), Math_NAN);
1470 
1471 	//populate native classes
1472 
1473 	List<StringName> class_list;
1474 	ClassDB::get_class_list(&class_list);
1475 	for (List<StringName>::Element *E = class_list.front(); E; E = E->next()) {
1476 
1477 		StringName n = E->get();
1478 		String s = String(n);
1479 		if (s.begins_with("_"))
1480 			n = s.substr(1, s.length());
1481 
1482 		if (globals.has(n))
1483 			continue;
1484 		Ref<GDScriptNativeClass> nc = memnew(GDScriptNativeClass(E->get()));
1485 		_add_global(n, nc);
1486 	}
1487 
1488 	//populate singletons
1489 
1490 	List<Engine::Singleton> singletons;
1491 	Engine::get_singleton()->get_singletons(&singletons);
1492 	for (List<Engine::Singleton>::Element *E = singletons.front(); E; E = E->next()) {
1493 
1494 		_add_global(E->get().name, E->get().ptr);
1495 	}
1496 }
1497 
get_type() const1498 String GDScriptLanguage::get_type() const {
1499 
1500 	return "GDScript";
1501 }
get_extension() const1502 String GDScriptLanguage::get_extension() const {
1503 
1504 	return "gd";
1505 }
execute_file(const String & p_path)1506 Error GDScriptLanguage::execute_file(const String &p_path) {
1507 
1508 	// ??
1509 	return OK;
1510 }
finish()1511 void GDScriptLanguage::finish() {
1512 }
1513 
profiling_start()1514 void GDScriptLanguage::profiling_start() {
1515 
1516 #ifdef DEBUG_ENABLED
1517 	if (lock) {
1518 		lock->lock();
1519 	}
1520 
1521 	SelfList<GDScriptFunction> *elem = function_list.first();
1522 	while (elem) {
1523 		elem->self()->profile.call_count = 0;
1524 		elem->self()->profile.self_time = 0;
1525 		elem->self()->profile.total_time = 0;
1526 		elem->self()->profile.frame_call_count = 0;
1527 		elem->self()->profile.frame_self_time = 0;
1528 		elem->self()->profile.frame_total_time = 0;
1529 		elem->self()->profile.last_frame_call_count = 0;
1530 		elem->self()->profile.last_frame_self_time = 0;
1531 		elem->self()->profile.last_frame_total_time = 0;
1532 		elem = elem->next();
1533 	}
1534 
1535 	profiling = true;
1536 	if (lock) {
1537 		lock->unlock();
1538 	}
1539 
1540 #endif
1541 }
1542 
profiling_stop()1543 void GDScriptLanguage::profiling_stop() {
1544 
1545 #ifdef DEBUG_ENABLED
1546 	if (lock) {
1547 		lock->lock();
1548 	}
1549 
1550 	profiling = false;
1551 	if (lock) {
1552 		lock->unlock();
1553 	}
1554 
1555 #endif
1556 }
1557 
profiling_get_accumulated_data(ProfilingInfo * p_info_arr,int p_info_max)1558 int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) {
1559 
1560 	int current = 0;
1561 #ifdef DEBUG_ENABLED
1562 	if (lock) {
1563 		lock->lock();
1564 	}
1565 
1566 	SelfList<GDScriptFunction> *elem = function_list.first();
1567 	while (elem) {
1568 		if (current >= p_info_max)
1569 			break;
1570 		p_info_arr[current].call_count = elem->self()->profile.call_count;
1571 		p_info_arr[current].self_time = elem->self()->profile.self_time;
1572 		p_info_arr[current].total_time = elem->self()->profile.total_time;
1573 		p_info_arr[current].signature = elem->self()->profile.signature;
1574 		elem = elem->next();
1575 		current++;
1576 	}
1577 
1578 	if (lock) {
1579 		lock->unlock();
1580 	}
1581 
1582 #endif
1583 
1584 	return current;
1585 }
1586 
profiling_get_frame_data(ProfilingInfo * p_info_arr,int p_info_max)1587 int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) {
1588 
1589 	int current = 0;
1590 
1591 #ifdef DEBUG_ENABLED
1592 	if (lock) {
1593 		lock->lock();
1594 	}
1595 
1596 	SelfList<GDScriptFunction> *elem = function_list.first();
1597 	while (elem) {
1598 		if (current >= p_info_max)
1599 			break;
1600 		if (elem->self()->profile.last_frame_call_count > 0) {
1601 			p_info_arr[current].call_count = elem->self()->profile.last_frame_call_count;
1602 			p_info_arr[current].self_time = elem->self()->profile.last_frame_self_time;
1603 			p_info_arr[current].total_time = elem->self()->profile.last_frame_total_time;
1604 			p_info_arr[current].signature = elem->self()->profile.signature;
1605 			current++;
1606 		}
1607 		elem = elem->next();
1608 	}
1609 
1610 	if (lock) {
1611 		lock->unlock();
1612 	}
1613 
1614 #endif
1615 
1616 	return current;
1617 }
1618 
1619 struct GDScriptDepSort {
1620 
1621 	//must support sorting so inheritance works properly (parent must be reloaded first)
operator ()GDScriptDepSort1622 	bool operator()(const Ref<GDScript> &A, const Ref<GDScript> &B) const {
1623 
1624 		if (A == B)
1625 			return false; //shouldn't happen but..
1626 		const GDScript *I = B->get_base().ptr();
1627 		while (I) {
1628 			if (I == A.ptr()) {
1629 				// A is a base of B
1630 				return true;
1631 			}
1632 
1633 			I = I->get_base().ptr();
1634 		}
1635 
1636 		return false; //not a base
1637 	}
1638 };
1639 
reload_all_scripts()1640 void GDScriptLanguage::reload_all_scripts() {
1641 
1642 #ifdef DEBUG_ENABLED
1643 	print_verbose("GDScript: Reloading all scripts");
1644 	if (lock) {
1645 		lock->lock();
1646 	}
1647 
1648 	List<Ref<GDScript> > scripts;
1649 
1650 	SelfList<GDScript> *elem = script_list.first();
1651 	while (elem) {
1652 		if (elem->self()->get_path().is_resource_file()) {
1653 			print_verbose("GDScript: Found: " + elem->self()->get_path());
1654 			scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident
1655 		}
1656 		elem = elem->next();
1657 	}
1658 
1659 	if (lock) {
1660 		lock->unlock();
1661 	}
1662 
1663 	//as scripts are going to be reloaded, must proceed without locking here
1664 
1665 	scripts.sort_custom<GDScriptDepSort>(); //update in inheritance dependency order
1666 
1667 	for (List<Ref<GDScript> >::Element *E = scripts.front(); E; E = E->next()) {
1668 
1669 		print_verbose("GDScript: Reloading: " + E->get()->get_path());
1670 		E->get()->load_source_code(E->get()->get_path());
1671 		E->get()->reload(true);
1672 	}
1673 #endif
1674 }
1675 
reload_tool_script(const Ref<Script> & p_script,bool p_soft_reload)1676 void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload) {
1677 
1678 #ifdef DEBUG_ENABLED
1679 
1680 	if (lock) {
1681 		lock->lock();
1682 	}
1683 
1684 	List<Ref<GDScript> > scripts;
1685 
1686 	SelfList<GDScript> *elem = script_list.first();
1687 	while (elem) {
1688 		if (elem->self()->get_path().is_resource_file()) {
1689 
1690 			scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident
1691 		}
1692 		elem = elem->next();
1693 	}
1694 
1695 	if (lock) {
1696 		lock->unlock();
1697 	}
1698 
1699 	//when someone asks you why dynamically typed languages are easier to write....
1700 
1701 	Map<Ref<GDScript>, Map<ObjectID, List<Pair<StringName, Variant> > > > to_reload;
1702 
1703 	//as scripts are going to be reloaded, must proceed without locking here
1704 
1705 	scripts.sort_custom<GDScriptDepSort>(); //update in inheritance dependency order
1706 
1707 	for (List<Ref<GDScript> >::Element *E = scripts.front(); E; E = E->next()) {
1708 
1709 		bool reload = E->get() == p_script || to_reload.has(E->get()->get_base());
1710 
1711 		if (!reload)
1712 			continue;
1713 
1714 		to_reload.insert(E->get(), Map<ObjectID, List<Pair<StringName, Variant> > >());
1715 
1716 		if (!p_soft_reload) {
1717 
1718 			//save state and remove script from instances
1719 			Map<ObjectID, List<Pair<StringName, Variant> > > &map = to_reload[E->get()];
1720 
1721 			while (E->get()->instances.front()) {
1722 				Object *obj = E->get()->instances.front()->get();
1723 				//save instance info
1724 				List<Pair<StringName, Variant> > state;
1725 				if (obj->get_script_instance()) {
1726 
1727 					obj->get_script_instance()->get_property_state(state);
1728 					map[obj->get_instance_id()] = state;
1729 					obj->set_script(RefPtr());
1730 				}
1731 			}
1732 
1733 //same thing for placeholders
1734 #ifdef TOOLS_ENABLED
1735 
1736 			while (E->get()->placeholders.size()) {
1737 				Object *obj = E->get()->placeholders.front()->get()->get_owner();
1738 
1739 				//save instance info
1740 				if (obj->get_script_instance()) {
1741 
1742 					map.insert(obj->get_instance_id(), List<Pair<StringName, Variant> >());
1743 					List<Pair<StringName, Variant> > &state = map[obj->get_instance_id()];
1744 					obj->get_script_instance()->get_property_state(state);
1745 					obj->set_script(RefPtr());
1746 				} else {
1747 					// no instance found. Let's remove it so we don't loop forever
1748 					E->get()->placeholders.erase(E->get()->placeholders.front()->get());
1749 				}
1750 			}
1751 
1752 #endif
1753 
1754 			for (Map<ObjectID, List<Pair<StringName, Variant> > >::Element *F = E->get()->pending_reload_state.front(); F; F = F->next()) {
1755 				map[F->key()] = F->get(); //pending to reload, use this one instead
1756 			}
1757 		}
1758 	}
1759 
1760 	for (Map<Ref<GDScript>, Map<ObjectID, List<Pair<StringName, Variant> > > >::Element *E = to_reload.front(); E; E = E->next()) {
1761 
1762 		Ref<GDScript> scr = E->key();
1763 		scr->reload(p_soft_reload);
1764 
1765 		//restore state if saved
1766 		for (Map<ObjectID, List<Pair<StringName, Variant> > >::Element *F = E->get().front(); F; F = F->next()) {
1767 
1768 			List<Pair<StringName, Variant> > &saved_state = F->get();
1769 
1770 			Object *obj = ObjectDB::get_instance(F->key());
1771 			if (!obj)
1772 				continue;
1773 
1774 			if (!p_soft_reload) {
1775 				//clear it just in case (may be a pending reload state)
1776 				obj->set_script(RefPtr());
1777 			}
1778 			obj->set_script(scr.get_ref_ptr());
1779 
1780 			ScriptInstance *script_instance = obj->get_script_instance();
1781 
1782 			if (!script_instance) {
1783 				//failed, save reload state for next time if not saved
1784 				if (!scr->pending_reload_state.has(obj->get_instance_id())) {
1785 					scr->pending_reload_state[obj->get_instance_id()] = saved_state;
1786 				}
1787 				continue;
1788 			}
1789 
1790 			if (script_instance->is_placeholder() && scr->is_placeholder_fallback_enabled()) {
1791 				PlaceHolderScriptInstance *placeholder = static_cast<PlaceHolderScriptInstance *>(script_instance);
1792 				for (List<Pair<StringName, Variant> >::Element *G = saved_state.front(); G; G = G->next()) {
1793 					placeholder->property_set_fallback(G->get().first, G->get().second);
1794 				}
1795 			} else {
1796 				for (List<Pair<StringName, Variant> >::Element *G = saved_state.front(); G; G = G->next()) {
1797 					script_instance->set(G->get().first, G->get().second);
1798 				}
1799 			}
1800 
1801 			scr->pending_reload_state.erase(obj->get_instance_id()); //as it reloaded, remove pending state
1802 		}
1803 
1804 		//if instance states were saved, set them!
1805 	}
1806 
1807 #endif
1808 }
1809 
frame()1810 void GDScriptLanguage::frame() {
1811 
1812 	calls = 0;
1813 
1814 #ifdef DEBUG_ENABLED
1815 	if (profiling) {
1816 		if (lock) {
1817 			lock->lock();
1818 		}
1819 
1820 		SelfList<GDScriptFunction> *elem = function_list.first();
1821 		while (elem) {
1822 			elem->self()->profile.last_frame_call_count = elem->self()->profile.frame_call_count;
1823 			elem->self()->profile.last_frame_self_time = elem->self()->profile.frame_self_time;
1824 			elem->self()->profile.last_frame_total_time = elem->self()->profile.frame_total_time;
1825 			elem->self()->profile.frame_call_count = 0;
1826 			elem->self()->profile.frame_self_time = 0;
1827 			elem->self()->profile.frame_total_time = 0;
1828 			elem = elem->next();
1829 		}
1830 
1831 		if (lock) {
1832 			lock->unlock();
1833 		}
1834 	}
1835 
1836 #endif
1837 }
1838 
1839 /* EDITOR FUNCTIONS */
get_reserved_words(List<String> * p_words) const1840 void GDScriptLanguage::get_reserved_words(List<String> *p_words) const {
1841 
1842 	static const char *_reserved_words[] = {
1843 		// operators
1844 		"and",
1845 		"in",
1846 		"not",
1847 		"or",
1848 		// types and values
1849 		"false",
1850 		"float",
1851 		"int",
1852 		"bool",
1853 		"null",
1854 		"PI",
1855 		"TAU",
1856 		"INF",
1857 		"NAN",
1858 		"self",
1859 		"true",
1860 		"void",
1861 		// functions
1862 		"as",
1863 		"assert",
1864 		"breakpoint",
1865 		"class",
1866 		"class_name",
1867 		"extends",
1868 		"is",
1869 		"func",
1870 		"preload",
1871 		"setget",
1872 		"signal",
1873 		"tool",
1874 		"yield",
1875 		// var
1876 		"const",
1877 		"enum",
1878 		"export",
1879 		"onready",
1880 		"static",
1881 		"var",
1882 		// control flow
1883 		"break",
1884 		"continue",
1885 		"if",
1886 		"elif",
1887 		"else",
1888 		"for",
1889 		"pass",
1890 		"return",
1891 		"match",
1892 		"while",
1893 		"remote",
1894 		"sync",
1895 		"master",
1896 		"puppet",
1897 		"slave",
1898 		"remotesync",
1899 		"mastersync",
1900 		"puppetsync",
1901 		0
1902 	};
1903 
1904 	const char **w = _reserved_words;
1905 
1906 	while (*w) {
1907 
1908 		p_words->push_back(*w);
1909 		w++;
1910 	}
1911 
1912 	for (int i = 0; i < GDScriptFunctions::FUNC_MAX; i++) {
1913 		p_words->push_back(GDScriptFunctions::get_func_name(GDScriptFunctions::Function(i)));
1914 	}
1915 }
1916 
handles_global_class_type(const String & p_type) const1917 bool GDScriptLanguage::handles_global_class_type(const String &p_type) const {
1918 
1919 	return p_type == "GDScript";
1920 }
1921 
get_global_class_name(const String & p_path,String * r_base_type,String * r_icon_path) const1922 String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_base_type, String *r_icon_path) const {
1923 
1924 	PoolVector<uint8_t> sourcef;
1925 	Error err;
1926 	FileAccessRef f = FileAccess::open(p_path, FileAccess::READ, &err);
1927 	if (err) {
1928 		return String();
1929 	}
1930 
1931 	String source = f->get_as_utf8_string();
1932 
1933 	GDScriptParser parser;
1934 	parser.parse(source, p_path.get_base_dir(), true, p_path, false, NULL, true);
1935 
1936 	if (parser.get_parse_tree() && parser.get_parse_tree()->type == GDScriptParser::Node::TYPE_CLASS) {
1937 
1938 		const GDScriptParser::ClassNode *c = static_cast<const GDScriptParser::ClassNode *>(parser.get_parse_tree());
1939 		if (r_icon_path) {
1940 			if (c->icon_path.empty() || c->icon_path.is_abs_path())
1941 				*r_icon_path = c->icon_path;
1942 			else if (c->icon_path.is_rel_path())
1943 				*r_icon_path = p_path.get_base_dir().plus_file(c->icon_path).simplify_path();
1944 		}
1945 		if (r_base_type) {
1946 
1947 			const GDScriptParser::ClassNode *subclass = c;
1948 			String path = p_path;
1949 			GDScriptParser subparser;
1950 			while (subclass) {
1951 				if (subclass->extends_used) {
1952 					if (subclass->extends_file) {
1953 						if (subclass->extends_class.size() == 0) {
1954 							get_global_class_name(subclass->extends_file, r_base_type);
1955 							subclass = NULL;
1956 							break;
1957 						} else {
1958 							Vector<StringName> extend_classes = subclass->extends_class;
1959 
1960 							FileAccessRef subfile = FileAccess::open(subclass->extends_file, FileAccess::READ);
1961 							if (!subfile) {
1962 								break;
1963 							}
1964 							String subsource = subfile->get_as_utf8_string();
1965 
1966 							if (subsource.empty()) {
1967 								break;
1968 							}
1969 							String subpath = subclass->extends_file;
1970 							if (subpath.is_rel_path()) {
1971 								subpath = path.get_base_dir().plus_file(subpath).simplify_path();
1972 							}
1973 
1974 							if (OK != subparser.parse(subsource, subpath.get_base_dir(), true, subpath, false, NULL, true)) {
1975 								break;
1976 							}
1977 							path = subpath;
1978 							if (!subparser.get_parse_tree() || subparser.get_parse_tree()->type != GDScriptParser::Node::TYPE_CLASS) {
1979 								break;
1980 							}
1981 							subclass = static_cast<const GDScriptParser::ClassNode *>(subparser.get_parse_tree());
1982 
1983 							while (extend_classes.size() > 0) {
1984 								bool found = false;
1985 								for (int i = 0; i < subclass->subclasses.size(); i++) {
1986 									const GDScriptParser::ClassNode *inner_class = subclass->subclasses[i];
1987 									if (inner_class->name == extend_classes[0]) {
1988 										extend_classes.remove(0);
1989 										found = true;
1990 										subclass = inner_class;
1991 										break;
1992 									}
1993 								}
1994 								if (!found) {
1995 									subclass = NULL;
1996 									break;
1997 								}
1998 							}
1999 						}
2000 					} else if (subclass->extends_class.size() == 1) {
2001 						*r_base_type = subclass->extends_class[0];
2002 						subclass = NULL;
2003 					} else {
2004 						break;
2005 					}
2006 				} else {
2007 					*r_base_type = "Reference";
2008 					subclass = NULL;
2009 				}
2010 			}
2011 		}
2012 		return c->name;
2013 	}
2014 
2015 	return String();
2016 }
2017 
2018 #ifdef DEBUG_ENABLED
get_message() const2019 String GDScriptWarning::get_message() const {
2020 
2021 #define CHECK_SYMBOLS(m_amount) ERR_FAIL_COND_V(symbols.size() < m_amount, String());
2022 
2023 	switch (code) {
2024 		case UNASSIGNED_VARIABLE_OP_ASSIGN: {
2025 			CHECK_SYMBOLS(1);
2026 			return "Using assignment with operation but the variable '" + symbols[0] + "' was not previously assigned a value.";
2027 		} break;
2028 		case UNASSIGNED_VARIABLE: {
2029 			CHECK_SYMBOLS(1);
2030 			return "The variable '" + symbols[0] + "' was used but never assigned a value.";
2031 		} break;
2032 		case UNUSED_VARIABLE: {
2033 			CHECK_SYMBOLS(1);
2034 			return "The local variable '" + symbols[0] + "' is declared but never used in the block. If this is intended, prefix it with an underscore: '_" + symbols[0] + "'";
2035 		} break;
2036 		case SHADOWED_VARIABLE: {
2037 			CHECK_SYMBOLS(2);
2038 			return "The local variable '" + symbols[0] + "' is shadowing an already-defined variable at line " + symbols[1] + ".";
2039 		} break;
2040 		case UNUSED_CLASS_VARIABLE: {
2041 			CHECK_SYMBOLS(1);
2042 			return "The class variable '" + symbols[0] + "' is declared but never used in the script.";
2043 		} break;
2044 		case UNUSED_ARGUMENT: {
2045 			CHECK_SYMBOLS(2);
2046 			return "The argument '" + symbols[1] + "' is never used in the function '" + symbols[0] + "'. If this is intended, prefix it with an underscore: '_" + symbols[1] + "'";
2047 		} break;
2048 		case UNREACHABLE_CODE: {
2049 			CHECK_SYMBOLS(1);
2050 			return "Unreachable code (statement after return) in function '" + symbols[0] + "()'.";
2051 		} break;
2052 		case STANDALONE_EXPRESSION: {
2053 			return "Standalone expression (the line has no effect).";
2054 		} break;
2055 		case VOID_ASSIGNMENT: {
2056 			CHECK_SYMBOLS(1);
2057 			return "Assignment operation, but the function '" + symbols[0] + "()' returns void.";
2058 		} break;
2059 		case NARROWING_CONVERSION: {
2060 			return "Narrowing conversion (float is converted to int and loses precision).";
2061 		} break;
2062 		case FUNCTION_MAY_YIELD: {
2063 			CHECK_SYMBOLS(1);
2064 			return "Assigned variable is typed but the function '" + symbols[0] + "()' may yield and return a GDScriptFunctionState instead.";
2065 		} break;
2066 		case VARIABLE_CONFLICTS_FUNCTION: {
2067 			CHECK_SYMBOLS(1);
2068 			return "Variable declaration of '" + symbols[0] + "' conflicts with a function of the same name.";
2069 		} break;
2070 		case FUNCTION_CONFLICTS_VARIABLE: {
2071 			CHECK_SYMBOLS(1);
2072 			return "Function declaration of '" + symbols[0] + "()' conflicts with a variable of the same name.";
2073 		} break;
2074 		case FUNCTION_CONFLICTS_CONSTANT: {
2075 			CHECK_SYMBOLS(1);
2076 			return "Function declaration of '" + symbols[0] + "()' conflicts with a constant of the same name.";
2077 		} break;
2078 		case INCOMPATIBLE_TERNARY: {
2079 			return "Values of the ternary conditional are not mutually compatible.";
2080 		} break;
2081 		case UNUSED_SIGNAL: {
2082 			CHECK_SYMBOLS(1);
2083 			return "The signal '" + symbols[0] + "' is declared but never emitted.";
2084 		} break;
2085 		case RETURN_VALUE_DISCARDED: {
2086 			CHECK_SYMBOLS(1);
2087 			return "The function '" + symbols[0] + "()' returns a value, but this value is never used.";
2088 		} break;
2089 		case PROPERTY_USED_AS_FUNCTION: {
2090 			CHECK_SYMBOLS(2);
2091 			return "The method '" + symbols[0] + "()' was not found in base '" + symbols[1] + "' but there's a property with the same name. Did you mean to access it?";
2092 		} break;
2093 		case CONSTANT_USED_AS_FUNCTION: {
2094 			CHECK_SYMBOLS(2);
2095 			return "The method '" + symbols[0] + "()' was not found in base '" + symbols[1] + "' but there's a constant with the same name. Did you mean to access it?";
2096 		} break;
2097 		case FUNCTION_USED_AS_PROPERTY: {
2098 			CHECK_SYMBOLS(2);
2099 			return "The property '" + symbols[0] + "' was not found in base '" + symbols[1] + "' but there's a method with the same name. Did you mean to call it?";
2100 		} break;
2101 		case INTEGER_DIVISION: {
2102 			return "Integer division, decimal part will be discarded.";
2103 		} break;
2104 		case UNSAFE_PROPERTY_ACCESS: {
2105 			CHECK_SYMBOLS(2);
2106 			return "The property '" + symbols[0] + "' is not present on the inferred type '" + symbols[1] + "' (but may be present on a subtype).";
2107 		} break;
2108 		case UNSAFE_METHOD_ACCESS: {
2109 			CHECK_SYMBOLS(2);
2110 			return "The method '" + symbols[0] + "' is not present on the inferred type '" + symbols[1] + "' (but may be present on a subtype).";
2111 		} break;
2112 		case UNSAFE_CAST: {
2113 			CHECK_SYMBOLS(1);
2114 			return "The value is cast to '" + symbols[0] + "' but has an unknown type.";
2115 		} break;
2116 		case UNSAFE_CALL_ARGUMENT: {
2117 			CHECK_SYMBOLS(4);
2118 			return "The argument '" + symbols[0] + "' of the function '" + symbols[1] + "' requires a the subtype '" + symbols[2] + "' but the supertype '" + symbols[3] + "' was provided";
2119 		} break;
2120 		case DEPRECATED_KEYWORD: {
2121 			CHECK_SYMBOLS(2);
2122 			return "The '" + symbols[0] + "' keyword is deprecated and will be removed in a future release, please replace its uses by '" + symbols[1] + "'.";
2123 		} break;
2124 		case STANDALONE_TERNARY: {
2125 			return "Standalone ternary conditional operator: the return value is being discarded.";
2126 		}
2127 		case WARNING_MAX:
2128 			break; // Can't happen, but silences warning
2129 	}
2130 	ERR_FAIL_V_MSG(String(), "Invalid GDScript warning code: " + get_name_from_code(code) + ".");
2131 
2132 #undef CHECK_SYMBOLS
2133 }
2134 
get_name() const2135 String GDScriptWarning::get_name() const {
2136 	return get_name_from_code(code);
2137 }
2138 
get_name_from_code(Code p_code)2139 String GDScriptWarning::get_name_from_code(Code p_code) {
2140 	ERR_FAIL_COND_V(p_code < 0 || p_code >= WARNING_MAX, String());
2141 
2142 	static const char *names[] = {
2143 		"UNASSIGNED_VARIABLE",
2144 		"UNASSIGNED_VARIABLE_OP_ASSIGN",
2145 		"UNUSED_VARIABLE",
2146 		"SHADOWED_VARIABLE",
2147 		"UNUSED_CLASS_VARIABLE",
2148 		"UNUSED_ARGUMENT",
2149 		"UNREACHABLE_CODE",
2150 		"STANDALONE_EXPRESSION",
2151 		"VOID_ASSIGNMENT",
2152 		"NARROWING_CONVERSION",
2153 		"FUNCTION_MAY_YIELD",
2154 		"VARIABLE_CONFLICTS_FUNCTION",
2155 		"FUNCTION_CONFLICTS_VARIABLE",
2156 		"FUNCTION_CONFLICTS_CONSTANT",
2157 		"INCOMPATIBLE_TERNARY",
2158 		"UNUSED_SIGNAL",
2159 		"RETURN_VALUE_DISCARDED",
2160 		"PROPERTY_USED_AS_FUNCTION",
2161 		"CONSTANT_USED_AS_FUNCTION",
2162 		"FUNCTION_USED_AS_PROPERTY",
2163 		"INTEGER_DIVISION",
2164 		"UNSAFE_PROPERTY_ACCESS",
2165 		"UNSAFE_METHOD_ACCESS",
2166 		"UNSAFE_CAST",
2167 		"UNSAFE_CALL_ARGUMENT",
2168 		"DEPRECATED_KEYWORD",
2169 		"STANDALONE_TERNARY",
2170 		NULL
2171 	};
2172 
2173 	return names[(int)p_code];
2174 }
2175 
get_code_from_name(const String & p_name)2176 GDScriptWarning::Code GDScriptWarning::get_code_from_name(const String &p_name) {
2177 	for (int i = 0; i < WARNING_MAX; i++) {
2178 		if (get_name_from_code((Code)i) == p_name) {
2179 			return (Code)i;
2180 		}
2181 	}
2182 
2183 	ERR_FAIL_V_MSG(WARNING_MAX, "Invalid GDScript warning name: " + p_name);
2184 }
2185 
2186 #endif // DEBUG_ENABLED
2187 
GDScriptLanguage()2188 GDScriptLanguage::GDScriptLanguage() {
2189 
2190 	calls = 0;
2191 	ERR_FAIL_COND(singleton);
2192 	singleton = this;
2193 	strings._init = StaticCString::create("_init");
2194 	strings._notification = StaticCString::create("_notification");
2195 	strings._set = StaticCString::create("_set");
2196 	strings._get = StaticCString::create("_get");
2197 	strings._get_property_list = StaticCString::create("_get_property_list");
2198 	strings._script_source = StaticCString::create("script/source");
2199 	_debug_parse_err_line = -1;
2200 	_debug_parse_err_file = "";
2201 
2202 #ifdef NO_THREADS
2203 	lock = NULL;
2204 #else
2205 	lock = Mutex::create();
2206 #endif
2207 	profiling = false;
2208 	script_frame_time = 0;
2209 
2210 	_debug_call_stack_pos = 0;
2211 	int dmcs = GLOBAL_DEF("debug/settings/gdscript/max_call_stack", 1024);
2212 	ProjectSettings::get_singleton()->set_custom_property_info("debug/settings/gdscript/max_call_stack", PropertyInfo(Variant::INT, "debug/settings/gdscript/max_call_stack", PROPERTY_HINT_RANGE, "1024,4096,1,or_greater")); //minimum is 1024
2213 
2214 	if (ScriptDebugger::get_singleton()) {
2215 		//debugging enabled!
2216 
2217 		_debug_max_call_stack = dmcs;
2218 		_call_stack = memnew_arr(CallLevel, _debug_max_call_stack + 1);
2219 
2220 	} else {
2221 		_debug_max_call_stack = 0;
2222 		_call_stack = NULL;
2223 	}
2224 
2225 #ifdef DEBUG_ENABLED
2226 	GLOBAL_DEF("debug/gdscript/warnings/enable", true);
2227 	GLOBAL_DEF("debug/gdscript/warnings/treat_warnings_as_errors", false);
2228 	GLOBAL_DEF("debug/gdscript/warnings/exclude_addons", true);
2229 	GLOBAL_DEF("debug/gdscript/completion/autocomplete_setters_and_getters", false);
2230 	for (int i = 0; i < (int)GDScriptWarning::WARNING_MAX; i++) {
2231 		String warning = GDScriptWarning::get_name_from_code((GDScriptWarning::Code)i).to_lower();
2232 		bool default_enabled = !warning.begins_with("unsafe_") && i != GDScriptWarning::UNUSED_CLASS_VARIABLE;
2233 		GLOBAL_DEF("debug/gdscript/warnings/" + warning, default_enabled);
2234 	}
2235 #endif // DEBUG_ENABLED
2236 }
2237 
~GDScriptLanguage()2238 GDScriptLanguage::~GDScriptLanguage() {
2239 
2240 	if (lock) {
2241 		memdelete(lock);
2242 		lock = NULL;
2243 	}
2244 	if (_call_stack) {
2245 		memdelete_arr(_call_stack);
2246 	}
2247 	singleton = NULL;
2248 }
2249 
add_orphan_subclass(const String & p_qualified_name,const ObjectID & p_subclass)2250 void GDScriptLanguage::add_orphan_subclass(const String &p_qualified_name, const ObjectID &p_subclass) {
2251 	orphan_subclasses[p_qualified_name] = p_subclass;
2252 }
2253 
get_orphan_subclass(const String & p_qualified_name)2254 Ref<GDScript> GDScriptLanguage::get_orphan_subclass(const String &p_qualified_name) {
2255 	Map<String, ObjectID>::Element *orphan_subclass_element = orphan_subclasses.find(p_qualified_name);
2256 	if (!orphan_subclass_element)
2257 		return Ref<GDScript>();
2258 	ObjectID orphan_subclass = orphan_subclass_element->get();
2259 	Object *obj = ObjectDB::get_instance(orphan_subclass);
2260 	orphan_subclasses.erase(orphan_subclass_element);
2261 	if (!obj)
2262 		return Ref<GDScript>();
2263 	return Ref<GDScript>(Object::cast_to<GDScript>(obj));
2264 }
2265 
2266 /*************** RESOURCE ***************/
2267 
load(const String & p_path,const String & p_original_path,Error * r_error)2268 RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error) {
2269 
2270 	if (r_error)
2271 		*r_error = ERR_FILE_CANT_OPEN;
2272 
2273 	GDScript *script = memnew(GDScript);
2274 
2275 	Ref<GDScript> scriptres(script);
2276 
2277 	if (p_path.ends_with(".gde") || p_path.ends_with(".gdc")) {
2278 
2279 		script->set_script_path(p_original_path); // script needs this.
2280 		script->set_path(p_original_path);
2281 		Error err = script->load_byte_code(p_path);
2282 		ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot load byte code from file '" + p_path + "'.");
2283 
2284 	} else {
2285 		Error err = script->load_source_code(p_path);
2286 		ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot load source code from file '" + p_path + "'.");
2287 
2288 		script->set_script_path(p_original_path); // script needs this.
2289 		script->set_path(p_original_path);
2290 
2291 		script->reload();
2292 	}
2293 	if (r_error)
2294 		*r_error = OK;
2295 
2296 	return scriptres;
2297 }
2298 
get_recognized_extensions(List<String> * p_extensions) const2299 void ResourceFormatLoaderGDScript::get_recognized_extensions(List<String> *p_extensions) const {
2300 
2301 	p_extensions->push_back("gd");
2302 	p_extensions->push_back("gdc");
2303 	p_extensions->push_back("gde");
2304 }
2305 
handles_type(const String & p_type) const2306 bool ResourceFormatLoaderGDScript::handles_type(const String &p_type) const {
2307 
2308 	return (p_type == "Script" || p_type == "GDScript");
2309 }
2310 
get_resource_type(const String & p_path) const2311 String ResourceFormatLoaderGDScript::get_resource_type(const String &p_path) const {
2312 
2313 	String el = p_path.get_extension().to_lower();
2314 	if (el == "gd" || el == "gdc" || el == "gde")
2315 		return "GDScript";
2316 	return "";
2317 }
2318 
get_dependencies(const String & p_path,List<String> * p_dependencies,bool p_add_types)2319 void ResourceFormatLoaderGDScript::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
2320 
2321 	FileAccessRef file = FileAccess::open(p_path, FileAccess::READ);
2322 	ERR_FAIL_COND_MSG(!file, "Cannot open file '" + p_path + "'.");
2323 
2324 	String source = file->get_as_utf8_string();
2325 	if (source.empty()) {
2326 		return;
2327 	}
2328 
2329 	GDScriptParser parser;
2330 	if (OK != parser.parse(source, p_path.get_base_dir(), true, p_path, false, NULL, true)) {
2331 		return;
2332 	}
2333 
2334 	for (const List<String>::Element *E = parser.get_dependencies().front(); E; E = E->next()) {
2335 		p_dependencies->push_back(E->get());
2336 	}
2337 }
2338 
save(const String & p_path,const RES & p_resource,uint32_t p_flags)2339 Error ResourceFormatSaverGDScript::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
2340 
2341 	Ref<GDScript> sqscr = p_resource;
2342 	ERR_FAIL_COND_V(sqscr.is_null(), ERR_INVALID_PARAMETER);
2343 
2344 	String source = sqscr->get_source_code();
2345 
2346 	Error err;
2347 	FileAccess *file = FileAccess::open(p_path, FileAccess::WRITE, &err);
2348 
2349 	ERR_FAIL_COND_V_MSG(err, err, "Cannot save GDScript file '" + p_path + "'.");
2350 
2351 	file->store_string(source);
2352 	if (file->get_error() != OK && file->get_error() != ERR_FILE_EOF) {
2353 		memdelete(file);
2354 		return ERR_CANT_CREATE;
2355 	}
2356 	file->close();
2357 	memdelete(file);
2358 
2359 	if (ScriptServer::is_reload_scripts_on_save_enabled()) {
2360 		GDScriptLanguage::get_singleton()->reload_tool_script(p_resource, false);
2361 	}
2362 
2363 	return OK;
2364 }
2365 
get_recognized_extensions(const RES & p_resource,List<String> * p_extensions) const2366 void ResourceFormatSaverGDScript::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
2367 
2368 	if (Object::cast_to<GDScript>(*p_resource)) {
2369 		p_extensions->push_back("gd");
2370 	}
2371 }
recognize(const RES & p_resource) const2372 bool ResourceFormatSaverGDScript::recognize(const RES &p_resource) const {
2373 
2374 	return Object::cast_to<GDScript>(*p_resource) != NULL;
2375 }
2376