summaryrefslogtreecommitdiff
path: root/modules/gdscript/gdscript.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript/gdscript.cpp')
-rw-r--r--modules/gdscript/gdscript.cpp113
1 files changed, 67 insertions, 46 deletions
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index 4425b59d62..d7814e85b0 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -45,6 +45,10 @@
#include "gdscript_parser.h"
#include "gdscript_warning.h"
+#ifdef TESTS_ENABLED
+#include "tests/gdscript_test_runner.h"
+#endif
+
///////////////////////////
GDScriptNativeClass::GDScriptNativeClass(const StringName &p_name) {
@@ -219,7 +223,7 @@ StringName GDScript::get_instance_base_type() const {
}
struct _GDScriptMemberSort {
- int index;
+ int index = 0;
StringName name;
_FORCE_INLINE_ bool operator<(const _GDScriptMemberSort &p_member) const { return index < p_member.index; }
};
@@ -276,7 +280,7 @@ void GDScript::_get_script_property_list(List<PropertyInfo> *r_list, bool p_incl
}
msort.sort();
- msort.invert();
+ msort.reverse();
for (int i = 0; i < msort.size(); i++) {
props.push_front(sptr->member_info[msort[i].name]);
}
@@ -425,7 +429,7 @@ void GDScript::_update_doc() {
_clear_doc();
doc.script_path = "\"" + get_path().get_slice("://", 1) + "\"";
- if (!name.empty()) {
+ if (!name.is_empty()) {
doc.name = name;
} else {
doc.name = doc.script_path;
@@ -477,7 +481,7 @@ void GDScript::_update_doc() {
methods[i].return_val.class_name = _get_gdscript_reference_class_name(Object::cast_to<GDScript>(return_type.script_type));
}
- // Change class name if argumetn is script reference.
+ // Change class name if argument is script reference.
for (int j = 0; j < fn->get_argument_count(); j++) {
GDScriptDataType arg_type = fn->get_argument_type(j);
if (arg_type.kind == GDScriptDataType::GDSCRIPT) {
@@ -793,10 +797,10 @@ Error GDScript::reload(bool p_keep_state) {
{
String source_path = path;
- if (source_path.empty()) {
+ if (source_path.is_empty()) {
source_path = get_path();
}
- if (!source_path.empty()) {
+ if (!source_path.is_empty()) {
MutexLock lock(GDScriptCache::singleton->lock);
if (!GDScriptCache::singleton->shallow_gdscript_cache.has(source_path)) {
GDScriptCache::singleton->shallow_gdscript_cache[source_path] = this;
@@ -812,7 +816,7 @@ Error GDScript::reload(bool p_keep_state) {
GDScriptLanguage::get_singleton()->debug_break_parse(get_path(), parser.get_errors().front()->get().line, "Parser Error: " + parser.get_errors().front()->get().message);
}
// TODO: Show all error messages.
- _err_print_error("GDScript::reload", path.empty() ? "built-in" : (const char *)path.utf8().get_data(), parser.get_errors().front()->get().line, ("Parse Error: " + parser.get_errors().front()->get().message).utf8().get_data(), ERR_HANDLER_SCRIPT);
+ _err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), parser.get_errors().front()->get().line, ("Parse Error: " + parser.get_errors().front()->get().message).utf8().get_data(), ERR_HANDLER_SCRIPT);
ERR_FAIL_V(ERR_PARSE_ERROR);
}
@@ -826,7 +830,7 @@ Error GDScript::reload(bool p_keep_state) {
const List<GDScriptParser::ParserError>::Element *e = parser.get_errors().front();
while (e != nullptr) {
- _err_print_error("GDScript::reload", path.empty() ? "built-in" : (const char *)path.utf8().get_data(), e->get().line, ("Parse Error: " + e->get().message).utf8().get_data(), ERR_HANDLER_SCRIPT);
+ _err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), e->get().line, ("Parse Error: " + e->get().message).utf8().get_data(), ERR_HANDLER_SCRIPT);
e = e->next();
}
ERR_FAIL_V(ERR_PARSE_ERROR);
@@ -846,7 +850,7 @@ Error GDScript::reload(bool p_keep_state) {
if (EngineDebugger::is_active()) {
GDScriptLanguage::get_singleton()->debug_break_parse(get_path(), compiler.get_error_line(), "Parser Error: " + compiler.get_error());
}
- _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);
+ _err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), compiler.get_error_line(), ("Compile Error: " + compiler.get_error()).utf8().get_data(), ERR_HANDLER_SCRIPT);
ERR_FAIL_V(ERR_COMPILATION_FAILED);
} else {
return err;
@@ -1041,10 +1045,10 @@ Error GDScript::load_source_code(const String &p_path) {
ERR_FAIL_COND_V(err, err);
}
- int len = f->get_len();
+ uint64_t len = f->get_length();
sourcef.resize(len + 1);
uint8_t *w = sourcef.ptrw();
- int r = f->get_buffer(w, len);
+ uint64_t r = f->get_buffer(w, len);
f->close();
memdelete(f);
ERR_FAIL_COND_V(r != len, ERR_CANT_OPEN);
@@ -1162,17 +1166,6 @@ String GDScript::_get_gdscript_reference_class_name(const GDScript *p_gdscript)
GDScript::GDScript() :
script_list(this) {
- valid = false;
- subclass_count = 0;
- initializer = nullptr;
- _base = nullptr;
- _owner = nullptr;
- tool = false;
-#ifdef TOOLS_ENABLED
- source_changed_cache = false;
- placeholder_fallback_enabled = false;
-#endif
-
#ifdef DEBUG_ENABLED
{
MutexLock lock(GDScriptLanguage::get_singleton()->lock);
@@ -1321,21 +1314,29 @@ bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) {
return true; //function exists, call was successful
}
} else {
- if (!member->data_type.is_type(p_value)) {
- // Try conversion
- Callable::CallError ce;
- const Variant *value = &p_value;
- Variant converted;
- Variant::construct(member->data_type.builtin_type, converted, &value, 1, ce);
- if (ce.error == Callable::CallError::CALL_OK) {
- members.write[member->index] = converted;
- return true;
- } else {
- return false;
+ if (member->data_type.has_type) {
+ if (member->data_type.builtin_type == Variant::ARRAY && member->data_type.has_container_element_type()) {
+ // Typed array.
+ if (p_value.get_type() == Variant::ARRAY) {
+ return VariantInternal::get_array(&members.write[member->index])->typed_assign(p_value);
+ } else {
+ return false;
+ }
+ } else if (!member->data_type.is_type(p_value)) {
+ // Try conversion
+ Callable::CallError ce;
+ const Variant *value = &p_value;
+ Variant converted;
+ Variant::construct(member->data_type.builtin_type, converted, &value, 1, ce);
+ if (ce.error == Callable::CallError::CALL_OK) {
+ members.write[member->index] = converted;
+ return true;
+ } else {
+ return false;
+ }
}
- } else {
- members.write[member->index] = p_value;
}
+ members.write[member->index] = p_value;
}
return true;
}
@@ -1505,7 +1506,7 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const
}
msort.sort();
- msort.invert();
+ msort.reverse();
for (int i = 0; i < msort.size(); i++) {
props.push_front(sptr->member_info[msort[i].name]);
}
@@ -1769,6 +1770,10 @@ void GDScriptLanguage::init() {
for (List<Engine::Singleton>::Element *E = singletons.front(); E; E = E->next()) {
_add_global(E->get().name, E->get().ptr);
}
+
+#ifdef TESTS_ENABLED
+ GDScriptTests::GDScriptTestRunner::handle_cmdline();
+#endif
}
String GDScriptLanguage::get_type() const {
@@ -2122,11 +2127,27 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const {
w++;
}
- for (int i = 0; i < GDScriptFunctions::FUNC_MAX; i++) {
- p_words->push_back(GDScriptFunctions::get_func_name(GDScriptFunctions::Function(i)));
+ List<StringName> functions;
+ GDScriptUtilityFunctions::get_function_list(&functions);
+
+ for (const List<StringName>::Element *E = functions.front(); E; E = E->next()) {
+ p_words->push_back(String(E->get()));
}
}
+bool GDScriptLanguage::is_control_flow_keyword(String p_keyword) const {
+ return p_keyword == "break" ||
+ p_keyword == "continue" ||
+ p_keyword == "elif" ||
+ p_keyword == "else" ||
+ p_keyword == "if" ||
+ p_keyword == "for" ||
+ p_keyword == "match" ||
+ p_keyword == "pass" ||
+ p_keyword == "return" ||
+ p_keyword == "while";
+}
+
bool GDScriptLanguage::handles_global_class_type(const String &p_type) const {
return p_type == "GDScript";
}
@@ -2148,7 +2169,7 @@ String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_b
if (err == OK) {
const GDScriptParser::ClassNode *c = parser.get_tree();
if (r_icon_path) {
- if (c->icon_path.empty() || c->icon_path.is_abs_path()) {
+ if (c->icon_path.is_empty() || c->icon_path.is_abs_path()) {
*r_icon_path = c->icon_path;
} else if (c->icon_path.is_rel_path()) {
*r_icon_path = p_path.get_base_dir().plus_file(c->icon_path).simplify_path();
@@ -2160,7 +2181,7 @@ String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_b
GDScriptParser subparser;
while (subclass) {
if (subclass->extends_used) {
- if (!subclass->extends_path.empty()) {
+ if (!subclass->extends_path.is_empty()) {
if (subclass->extends.size() == 0) {
get_global_class_name(subclass->extends_path, r_base_type);
subclass = nullptr;
@@ -2174,7 +2195,7 @@ String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_b
}
String subsource = subfile->get_as_utf8_string();
- if (subsource.empty()) {
+ if (subsource.is_empty()) {
break;
}
String subpath = subclass->extends_path;
@@ -2301,7 +2322,7 @@ GDScriptLanguage::~GDScriptLanguage() {
script->unreference();
}
- singleton = NULL;
+ singleton = nullptr;
}
void GDScriptLanguage::add_orphan_subclass(const String &p_qualified_name, const ObjectID &p_subclass) {
@@ -2324,7 +2345,7 @@ Ref<GDScript> GDScriptLanguage::get_orphan_subclass(const String &p_qualified_na
/*************** RESOURCE ***************/
-RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
if (r_error) {
*r_error = ERR_FILE_CANT_OPEN;
}
@@ -2371,7 +2392,7 @@ void ResourceFormatLoaderGDScript::get_dependencies(const String &p_path, List<S
ERR_FAIL_COND_MSG(!file, "Cannot open file '" + p_path + "'.");
String source = file->get_as_utf8_string();
- if (source.empty()) {
+ if (source.is_empty()) {
return;
}