diff options
Diffstat (limited to 'modules/gdscript')
21 files changed, 712 insertions, 1374 deletions
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp index 0aca4dbc5e..d0f27b632b 100644 --- a/modules/gdscript/editor/gdscript_highlighter.cpp +++ b/modules/gdscript/editor/gdscript_highlighter.cpp @@ -34,17 +34,14 @@ #include "scene/gui/text_edit.h" inline bool _is_symbol(CharType c) { - return is_symbol(c); } static bool _is_text_char(CharType c) { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_'; } static bool _is_char(CharType c) { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'; } @@ -180,10 +177,10 @@ Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_ } if (in_region == -1 && !in_keyword && is_char && !prev_is_char) { - int to = j; - while (to < str.length() && _is_text_char(str[to])) + while (to < str.length() && _is_text_char(str[to])) { to++; + } String word = str.substr(j, to - j); Color col = Color(); @@ -208,7 +205,6 @@ Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_ } if (!in_function_name && in_word && !in_keyword) { - int k = j; while (k < str.length() && !_is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') { k++; @@ -238,7 +234,6 @@ Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_ } if (is_symbol) { - if (in_function_name) { in_function_args = true; } diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 8559fac57c..632407c61f 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -44,12 +44,10 @@ /////////////////////////// GDScriptNativeClass::GDScriptNativeClass(const StringName &p_name) { - name = p_name; } bool GDScriptNativeClass::_get(const StringName &p_name, Variant &r_ret) const { - bool ok; int v = ClassDB::get_integer_constant(name, p_name, &ok); @@ -62,12 +60,10 @@ bool GDScriptNativeClass::_get(const StringName &p_name, Variant &r_ret) const { } void GDScriptNativeClass::_bind_methods() { - ClassDB::bind_method(D_METHOD("new"), &GDScriptNativeClass::_new); } Variant GDScriptNativeClass::_new() { - Object *o = instance(); ERR_FAIL_COND_V_MSG(!o, Variant(), "Class type: '" + String(name) + "' is not instantiable."); @@ -80,12 +76,10 @@ Variant GDScriptNativeClass::_new() { } Object *GDScriptNativeClass::instance() { - return ClassDB::instance(name); } GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Callable::CallError &r_error) { - /* STEP 1, CREATE */ GDScriptInstance *instance = memnew(GDScriptInstance); @@ -125,7 +119,6 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco } Variant GDScript::_new(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { - /* STEP 1, CREATE */ if (!valid) { @@ -171,7 +164,6 @@ Variant GDScript::_new(const Variant **p_args, int p_argcount, Callable::CallErr } bool GDScript::can_instance() const { - #ifdef TOOLS_ENABLED return valid && (tool || ScriptServer::is_scripting_enabled()); #else @@ -180,7 +172,6 @@ bool GDScript::can_instance() const { } Ref<Script> GDScript::get_base_script() const { - if (_base) { return Ref<GDScript>(_base); } else { @@ -189,16 +180,16 @@ Ref<Script> GDScript::get_base_script() const { } StringName GDScript::get_instance_base_type() const { - - if (native.is_valid()) + if (native.is_valid()) { return native->get_name(); - if (base.is_valid() && base->is_valid()) + } + if (base.is_valid() && base->is_valid()) { return base->get_instance_base_type(); + } return StringName(); } struct _GDScriptMemberSort { - int index; StringName name; _FORCE_INLINE_ bool operator<(const _GDScriptMemberSort &p_member) const { return index < p_member.index; } @@ -207,13 +198,11 @@ struct _GDScriptMemberSort { #ifdef TOOLS_ENABLED void GDScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) { - placeholders.erase(p_placeholder); } #endif void GDScript::get_script_method_list(List<MethodInfo> *p_list) const { - const GDScript *current = this; while (current) { for (const Map<StringName, GDScriptFunction *>::Element *E = current->member_functions.front(); E; E = E->next()) { @@ -233,15 +222,12 @@ void GDScript::get_script_method_list(List<MethodInfo> *p_list) const { } void GDScript::get_script_property_list(List<PropertyInfo> *p_list) const { - const GDScript *sptr = this; List<PropertyInfo> props; while (sptr) { - Vector<_GDScriptMemberSort> msort; for (Map<StringName, PropertyInfo>::Element *E = sptr->member_info.front(); E; E = E->next()) { - _GDScriptMemberSort ms; ERR_CONTINUE(!sptr->member_indices.has(E->key())); ms.index = sptr->member_indices[E->key()].index; @@ -252,7 +238,6 @@ void GDScript::get_script_property_list(List<PropertyInfo> *p_list) const { msort.sort(); msort.invert(); for (int i = 0; i < msort.size(); i++) { - props.push_front(sptr->member_info[msort[i].name]); } @@ -265,15 +250,14 @@ void GDScript::get_script_property_list(List<PropertyInfo> *p_list) const { } bool GDScript::has_method(const StringName &p_method) const { - return member_functions.has(p_method); } MethodInfo GDScript::get_method_info(const StringName &p_method) const { - const Map<StringName, GDScriptFunction *>::Element *E = member_functions.find(p_method); - if (!E) + if (!E) { return MethodInfo(); + } GDScriptFunction *func = E->get(); MethodInfo mi; @@ -287,7 +271,6 @@ MethodInfo GDScript::get_method_info(const StringName &p_method) const { } bool GDScript::get_property_default_value(const StringName &p_property, Variant &r_value) const { - #ifdef TOOLS_ENABLED const Map<StringName, Variant>::Element *E = member_default_values_cache.find(p_property); @@ -304,14 +287,13 @@ bool GDScript::get_property_default_value(const StringName &p_property, Variant } ScriptInstance *GDScript::instance_create(Object *p_this) { - GDScript *top = this; - while (top->_base) + while (top->_base) { top = top->_base; + } if (top->native.is_valid()) { if (!ClassDB::is_parent_class(p_this->get_class_name(), top->native->get_name())) { - if (EngineDebugger::is_active()) { 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() + "'"); } @@ -335,24 +317,23 @@ PlaceHolderScriptInstance *GDScript::placeholder_instance_create(Object *p_this) } bool GDScript::instance_has(const Object *p_this) const { - MutexLock lock(GDScriptLanguage::singleton->lock); return instances.has((Object *)p_this); } bool GDScript::has_source_code() const { - return source != ""; } -String GDScript::get_source_code() const { +String GDScript::get_source_code() const { return source; } -void GDScript::set_source_code(const String &p_code) { - if (source == p_code) +void GDScript::set_source_code(const String &p_code) { + if (source == p_code) { return; + } source = p_code; #ifdef TOOLS_ENABLED source_changed_cache = true; @@ -361,7 +342,6 @@ void GDScript::set_source_code(const String &p_code) { #ifdef TOOLS_ENABLED void GDScript::_update_exports_values(Map<StringName, Variant> &values, List<PropertyInfo> &propnames) { - if (base_cache.is_valid()) { base_cache->_update_exports_values(values, propnames); } @@ -377,12 +357,12 @@ void GDScript::_update_exports_values(Map<StringName, Variant> &values, List<Pro #endif bool GDScript::_update_exports(bool *r_err, bool p_recursive_call) { - #ifdef TOOLS_ENABLED static Vector<GDScript *> base_caches; - if (!p_recursive_call) + if (!p_recursive_call) { base_caches.clear(); + } base_caches.append(this); bool changed = false; @@ -393,17 +373,18 @@ bool GDScript::_update_exports(bool *r_err, bool p_recursive_call) { String basedir = path; - if (basedir == "") + if (basedir == "") { basedir = get_path(); + } - if (basedir != "") + if (basedir != "") { basedir = basedir.get_base_dir(); + } GDScriptParser parser; Error err = parser.parse(source, basedir, true, path); if (err == OK) { - const GDScriptParser::Node *root = parser.get_parse_tree(); ERR_FAIL_COND_V(root->type != GDScriptParser::Node::TYPE_CLASS, false); @@ -419,10 +400,8 @@ bool GDScript::_update_exports(bool *r_err, bool p_recursive_call) { if (String(c->extends_file) != "" && String(c->extends_file) != get_path()) { path = c->extends_file; if (path.is_rel_path()) { - String base = get_path(); if (base == "" || base.is_rel_path()) { - ERR_PRINT(("Could not resolve relative path for parent class: " + path).utf8().get_data()); } else { path = base.get_base_dir().plus_file(path); @@ -431,17 +410,16 @@ bool GDScript::_update_exports(bool *r_err, bool p_recursive_call) { } else if (c->extends_class.size() != 0) { String base = c->extends_class[0]; - if (ScriptServer::is_global_class(base)) + if (ScriptServer::is_global_class(base)) { path = ScriptServer::get_global_class_path(base); + } } if (path != "") { if (path != get_path()) { - Ref<GDScript> bf = ResourceLoader::load(path); if (bf.is_valid()) { - base_cache = bf; bf->inheriters_cache.insert(get_instance_id()); } @@ -455,8 +433,9 @@ bool GDScript::_update_exports(bool *r_err, bool p_recursive_call) { member_default_values_cache.clear(); for (int i = 0; i < c->variables.size(); i++) { - if (c->variables[i]._export.type == Variant::NIL) + if (c->variables[i]._export.type == Variant::NIL) { continue; + } members_cache.push_back(c->variables[i]._export); member_default_values_cache[c->variables[i].identifier] = c->variables[i].default_value; @@ -480,8 +459,9 @@ bool GDScript::_update_exports(bool *r_err, bool p_recursive_call) { if (base_cache.is_valid() && base_cache->is_valid()) { for (int i = 0; i < base_caches.size(); i++) { if (base_caches[i] == base_cache.ptr()) { - if (r_err) + if (r_err) { *r_err = true; + } valid = false; // to show error in the editor base_cache->valid = false; base_cache->inheriters_cache.clear(); // to prevent future stackoverflows @@ -492,8 +472,9 @@ bool GDScript::_update_exports(bool *r_err, bool p_recursive_call) { } } if (base_cache->_update_exports(r_err, true)) { - if (r_err && *r_err) + if (r_err && *r_err) { return false; + } changed = true; } } @@ -518,21 +499,22 @@ bool GDScript::_update_exports(bool *r_err, bool p_recursive_call) { } void GDScript::update_exports() { - #ifdef TOOLS_ENABLED bool cyclic_error = false; _update_exports(&cyclic_error); - if (cyclic_error) + if (cyclic_error) { return; + } Set<ObjectID> copy = inheriters_cache; //might get modified for (Set<ObjectID>::Element *E = copy.front(); E; E = E->next()) { Object *id = ObjectDB::get_instance(E->get()); GDScript *s = Object::cast_to<GDScript>(id); - if (!s) + if (!s) { continue; + } s->update_exports(); } @@ -540,16 +522,13 @@ void GDScript::update_exports() { } void GDScript::_set_subclass_path(Ref<GDScript> &p_sc, const String &p_path) { - p_sc->path = p_path; for (Map<StringName, Ref<GDScript>>::Element *E = p_sc->subclasses.front(); E; E = E->next()) { - _set_subclass_path(E->get(), p_path); } } Error GDScript::reload(bool p_keep_state) { - bool has_instances; { MutexLock lock(GDScriptLanguage::singleton->lock); @@ -561,11 +540,13 @@ Error GDScript::reload(bool p_keep_state) { String basedir = path; - if (basedir == "") + if (basedir == "") { basedir = get_path(); + } - if (basedir != "") + if (basedir != "") { basedir = basedir.get_base_dir(); + } if (source.find("%BASE%") != -1) { //loading a template, don't parse @@ -589,7 +570,6 @@ Error GDScript::reload(bool p_keep_state) { err = compiler.compile(&parser, this, p_keep_state); if (err) { - if (can_run) { if (EngineDebugger::is_active()) { GDScriptLanguage::get_singleton()->debug_break_parse(get_path(), compiler.get_error_line(), "Parser Error: " + compiler.get_error()); @@ -613,7 +593,6 @@ Error GDScript::reload(bool p_keep_state) { valid = true; for (Map<StringName, Ref<GDScript>>::Element *E = subclasses.front(); E; E = E->next()) { - _set_subclass_path(E->get(), path); } @@ -623,12 +602,10 @@ Error GDScript::reload(bool p_keep_state) { } ScriptLanguage *GDScript::get_language() const { - return GDScriptLanguage::get_singleton(); } void GDScript::get_constants(Map<StringName, Variant> *p_constants) { - if (p_constants) { for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) { (*p_constants)[E->key()] = E->value(); @@ -658,14 +635,16 @@ uint16_t GDScript::get_rpc_method_id(const StringName &p_method) const { } StringName GDScript::get_rpc_method(const uint16_t p_rpc_method_id) const { - if (p_rpc_method_id >= rpc_functions.size()) + if (p_rpc_method_id >= rpc_functions.size()) { return StringName(); + } return rpc_functions[p_rpc_method_id].name; } MultiplayerAPI::RPCMode GDScript::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const { - if (p_rpc_method_id >= rpc_functions.size()) + if (p_rpc_method_id >= rpc_functions.size()) { return MultiplayerAPI::RPC_MODE_DISABLED; + } return rpc_functions[p_rpc_method_id].mode; } @@ -687,14 +666,16 @@ uint16_t GDScript::get_rset_property_id(const StringName &p_variable) const { } StringName GDScript::get_rset_property(const uint16_t p_rset_member_id) const { - if (p_rset_member_id >= rpc_variables.size()) + if (p_rset_member_id >= rpc_variables.size()) { return StringName(); + } return rpc_variables[p_rset_member_id].name; } MultiplayerAPI::RPCMode GDScript::get_rset_mode_by_id(const uint16_t p_rset_member_id) const { - if (p_rset_member_id >= rpc_variables.size()) + if (p_rset_member_id >= rpc_variables.size()) { return MultiplayerAPI::RPC_MODE_DISABLED; + } return rpc_variables[p_rset_member_id].mode; } @@ -703,13 +684,10 @@ MultiplayerAPI::RPCMode GDScript::get_rset_mode(const StringName &p_variable) co } Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { - GDScript *top = this; while (top) { - Map<StringName, GDScriptFunction *>::Element *E = top->member_functions.find(p_method); if (E) { - ERR_FAIL_COND_V_MSG(!E->get()->is_static(), Variant(), "Can't call non-static function '" + String(p_method) + "' in script."); return E->get()->call(nullptr, p_args, p_argcount, r_error); @@ -723,16 +701,12 @@ Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p } bool GDScript::_get(const StringName &p_name, Variant &r_ret) const { - { - const GDScript *top = this; while (top) { - { const Map<StringName, Variant>::Element *E = top->constants.find(p_name); if (E) { - r_ret = E->get(); return true; } @@ -741,7 +715,6 @@ bool GDScript::_get(const StringName &p_name, Variant &r_ret) const { { const Map<StringName, Ref<GDScript>>::Element *E = subclasses.find(p_name); if (E) { - r_ret = E->get(); return true; } @@ -750,7 +723,6 @@ bool GDScript::_get(const StringName &p_name, Variant &r_ret) const { } if (p_name == GDScriptLanguage::get_singleton()->strings._script_source) { - r_ret = get_source_code(); return true; } @@ -758,42 +730,37 @@ bool GDScript::_get(const StringName &p_name, Variant &r_ret) const { return false; } -bool GDScript::_set(const StringName &p_name, const Variant &p_value) { +bool GDScript::_set(const StringName &p_name, const Variant &p_value) { if (p_name == GDScriptLanguage::get_singleton()->strings._script_source) { - set_source_code(p_value); reload(); - } else + } else { return false; + } return true; } void GDScript::_get_property_list(List<PropertyInfo> *p_properties) const { - p_properties->push_back(PropertyInfo(Variant::STRING, "script/source", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); } void GDScript::_bind_methods() { - ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &GDScript::_new, MethodInfo("new")); ClassDB::bind_method(D_METHOD("get_as_byte_code"), &GDScript::get_as_byte_code); } Vector<uint8_t> GDScript::get_as_byte_code() const { - GDScriptTokenizerBuffer tokenizer; return tokenizer.parse_code_string(source); }; Error GDScript::load_byte_code(const String &p_path) { - Vector<uint8_t> bytecode; if (p_path.ends_with("gde")) { - FileAccess *fa = FileAccess::open(p_path, FileAccess::READ); ERR_FAIL_COND_V(!fa, ERR_CANT_OPEN); @@ -822,7 +789,6 @@ Error GDScript::load_byte_code(const String &p_path) { memdelete(fae); } else { - bytecode = FileAccess::get_file_as_array(p_path); } @@ -831,11 +797,13 @@ Error GDScript::load_byte_code(const String &p_path) { String basedir = path; - if (basedir == "") + if (basedir == "") { basedir = get_path(); + } - if (basedir != "") + if (basedir != "") { basedir = basedir.get_base_dir(); + } valid = false; GDScriptParser parser; @@ -856,7 +824,6 @@ Error GDScript::load_byte_code(const String &p_path) { valid = true; for (Map<StringName, Ref<GDScript>>::Element *E = subclasses.front(); E; E = E->next()) { - _set_subclass_path(E->get(), path); } @@ -866,12 +833,10 @@ Error GDScript::load_byte_code(const String &p_path) { } Error GDScript::load_source_code(const String &p_path) { - Vector<uint8_t> sourcef; Error err; FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); if (err) { - ERR_FAIL_COND_V(err, err); } @@ -886,7 +851,6 @@ Error GDScript::load_source_code(const String &p_path) { String s; if (s.parse_utf8((const char *)w)) { - 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."); } @@ -899,23 +863,20 @@ Error GDScript::load_source_code(const String &p_path) { } const Map<StringName, GDScriptFunction *> &GDScript::debug_get_member_functions() const { - return member_functions; } StringName GDScript::debug_get_member_by_index(int p_idx) const { - for (const Map<StringName, MemberInfo>::Element *E = member_indices.front(); E; E = E->next()) { - - if (E->get().index == p_idx) + if (E->get().index == p_idx) { return E->key(); + } } return "<error>"; } Ref<GDScript> GDScript::get_base() const { - return base; } @@ -938,8 +899,9 @@ bool GDScript::inherits_script(const Ref<Script> &p_script) const { } bool GDScript::has_script_signal(const StringName &p_signal) const { - if (_signals.has(p_signal)) + if (_signals.has(p_signal)) { return true; + } if (base.is_valid()) { return base->has_script_signal(p_signal); } @@ -950,10 +912,9 @@ bool GDScript::has_script_signal(const StringName &p_signal) const { #endif return false; } -void GDScript::get_script_signal_list(List<MethodInfo> *r_signals) const { +void GDScript::get_script_signal_list(List<MethodInfo> *r_signals) const { for (const Map<StringName, Vector<StringName>>::Element *E = _signals.front(); E; E = E->next()) { - MethodInfo mi; mi.name = E->key(); for (int i = 0; i < E->get().size(); i++) { @@ -977,7 +938,6 @@ void GDScript::get_script_signal_list(List<MethodInfo> *r_signals) const { GDScript::GDScript() : script_list(this) { - valid = false; subclass_count = 0; initializer = nullptr; @@ -1022,8 +982,9 @@ void GDScript::_save_orphaned_subclasses() { for (int i = 0; i < weak_subclasses.size(); i++) { ClassRefWithName subclass = weak_subclasses[i]; Object *obj = ObjectDB::get_instance(subclass.id); - if (!obj) + if (!obj) { continue; + } // subclass is not released GDScriptLanguage::get_singleton()->add_orphan_subclass(subclass.fully_qualified_name, subclass.id); } @@ -1064,13 +1025,15 @@ void GDScript::_init_rpc_methods_properties() { } } - if (cscript != this) + if (cscript != this) { sub_E = sub_E->next(); + } - if (sub_E) + if (sub_E) { cscript = sub_E->get().ptr(); - else + } else { cscript = nullptr; + } } // Sort so we are 100% that they are always the same. @@ -1079,7 +1042,6 @@ void GDScript::_init_rpc_methods_properties() { } GDScript::~GDScript() { - { MutexLock lock(GDScriptLanguage::get_singleton()->lock); @@ -1109,7 +1071,6 @@ GDScript::~GDScript() { ////////////////////////////// bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) { - //member { const Map<StringName, GDScript::MemberInfo>::Element *E = script->member_indices.find(p_name); @@ -1144,17 +1105,16 @@ bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) { GDScript *sptr = script.ptr(); while (sptr) { - Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._set); if (E) { - Variant name = p_name; const Variant *args[2] = { &name, &p_value }; Callable::CallError err; Variant ret = E->get()->call(this, (const Variant **)args, 2, err); - if (err.error == Callable::CallError::CALL_OK && ret.get_type() == Variant::BOOL && ret.operator bool()) + if (err.error == Callable::CallError::CALL_OK && ret.get_type() == Variant::BOOL && ret.operator bool()) { return true; + } } sptr = sptr->_base; } @@ -1163,10 +1123,8 @@ bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) { } bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const { - const GDScript *sptr = script.ptr(); while (sptr) { - { const Map<StringName, GDScript::MemberInfo>::Element *E = script->member_indices.find(p_name); if (E) { @@ -1183,7 +1141,6 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const { } { - const GDScript *sl = sptr; while (sl) { const Map<StringName, Variant>::Element *E = sl->constants.find(p_name); @@ -1198,7 +1155,6 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const { { const Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._get); if (E) { - Variant name = p_name; const Variant *args[1] = { &name }; @@ -1217,20 +1173,20 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const { } Variant::Type GDScriptInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const { - const GDScript *sptr = script.ptr(); while (sptr) { - if (sptr->member_info.has(p_name)) { - if (r_is_valid) + if (r_is_valid) { *r_is_valid = true; + } return sptr->member_info[p_name].type; } sptr = sptr->_base; } - if (r_is_valid) + if (r_is_valid) { *r_is_valid = false; + } return Variant::NIL; } @@ -1241,19 +1197,15 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const List<PropertyInfo> props; while (sptr) { - const Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._get_property_list); if (E) { - Callable::CallError err; Variant ret = const_cast<GDScriptFunction *>(E->get())->call(const_cast<GDScriptInstance *>(this), nullptr, 0, err); if (err.error == Callable::CallError::CALL_OK) { - ERR_FAIL_COND_MSG(ret.get_type() != Variant::ARRAY, "Wrong type for _get_property_list, must be an array of dictionaries."); Array arr = ret; for (int i = 0; i < arr.size(); i++) { - Dictionary d = arr[i]; ERR_CONTINUE(!d.has("name")); ERR_CONTINUE(!d.has("type")); @@ -1262,12 +1214,15 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const ERR_CONTINUE(pinfo.type < 0 || pinfo.type >= Variant::VARIANT_MAX); pinfo.name = d["name"]; ERR_CONTINUE(pinfo.name == ""); - if (d.has("hint")) + if (d.has("hint")) { pinfo.hint = PropertyHint(d["hint"].operator int()); - if (d.has("hint_string")) + } + if (d.has("hint_string")) { pinfo.hint_string = d["hint_string"]; - if (d.has("usage")) + } + if (d.has("usage")) { pinfo.usage = d["usage"]; + } props.push_back(pinfo); } @@ -1278,7 +1233,6 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const Vector<_GDScriptMemberSort> msort; for (Map<StringName, PropertyInfo>::Element *F = sptr->member_info.front(); F; F = F->next()) { - _GDScriptMemberSort ms; ERR_CONTINUE(!sptr->member_indices.has(F->key())); ms.index = sptr->member_indices[F->key()].index; @@ -1289,7 +1243,6 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const msort.sort(); msort.invert(); for (int i = 0; i < msort.size(); i++) { - props.push_front(sptr->member_info[msort[i].name]); } @@ -1297,23 +1250,20 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const } for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - p_properties->push_back(E->get()); } } void GDScriptInstance::get_method_list(List<MethodInfo> *p_list) const { - const GDScript *sptr = script.ptr(); while (sptr) { - for (Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.front(); E; E = E->next()) { - MethodInfo mi; mi.name = E->key(); mi.flags |= METHOD_FLAG_FROM_SCRIPT; - for (int i = 0; i < E->get()->get_argument_count(); i++) + for (int i = 0; i < E->get()->get_argument_count(); i++) { mi.arguments.push_back(PropertyInfo(Variant::NIL, "arg" + itos(i))); + } p_list->push_back(mi); } sptr = sptr->_base; @@ -1321,19 +1271,19 @@ void GDScriptInstance::get_method_list(List<MethodInfo> *p_list) const { } bool GDScriptInstance::has_method(const StringName &p_method) const { - const GDScript *sptr = script.ptr(); while (sptr) { const Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(p_method); - if (E) + if (E) { return true; + } sptr = sptr->_base; } return false; } -Variant GDScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { +Variant GDScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { GDScript *sptr = script.ptr(); while (sptr) { Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(p_method); @@ -1347,7 +1297,6 @@ Variant GDScriptInstance::call(const StringName &p_method, const Variant **p_arg } void GDScriptInstance::call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount) { - GDScript *sptr = script.ptr(); Callable::CallError ce; @@ -1361,9 +1310,9 @@ void GDScriptInstance::call_multilevel(const StringName &p_method, const Variant } void GDScriptInstance::_ml_call_reversed(GDScript *sptr, const StringName &p_method, const Variant **p_args, int p_argcount) { - - if (sptr->_base) + if (sptr->_base) { _ml_call_reversed(sptr->_base, p_method, p_args, p_argcount); + } Callable::CallError ce; @@ -1374,14 +1323,12 @@ void GDScriptInstance::_ml_call_reversed(GDScript *sptr, const StringName &p_met } void GDScriptInstance::call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount) { - if (script.ptr()) { _ml_call_reversed(script.ptr(), p_method, p_args, p_argcount); } } void GDScriptInstance::notification(int p_notification) { - //notification is not virtual, it gets called at ALL levels just like in C. Variant value = p_notification; const Variant *args[1] = { &value }; @@ -1406,27 +1353,28 @@ String GDScriptInstance::to_string(bool *r_valid) { Variant ret = call(CoreStringNames::get_singleton()->_to_string, nullptr, 0, ce); if (ce.error == Callable::CallError::CALL_OK) { if (ret.get_type() != Variant::STRING) { - if (r_valid) + if (r_valid) { *r_valid = false; + } ERR_FAIL_V_MSG(String(), "Wrong type for " + CoreStringNames::get_singleton()->_to_string + ", must be a String."); } - if (r_valid) + if (r_valid) { *r_valid = true; + } return ret.operator String(); } } - if (r_valid) + if (r_valid) { *r_valid = false; + } return String(); } Ref<Script> GDScriptInstance::get_script() const { - return script; } ScriptLanguage *GDScriptInstance::get_language() { - return GDScriptLanguage::get_singleton(); } @@ -1471,7 +1419,6 @@ MultiplayerAPI::RPCMode GDScriptInstance::get_rset_mode(const StringName &p_vari } void GDScriptInstance::reload_members() { - #ifdef DEBUG_ENABLED members.resize(script->member_indices.size()); //resize @@ -1481,7 +1428,6 @@ void GDScriptInstance::reload_members() { //pass the values to the new indices for (Map<StringName, GDScript::MemberInfo>::Element *E = script->member_indices.front(); E; E = E->next()) { - if (member_indices_cache.has(E->key())) { Variant value = members[member_indices_cache[E->key()]]; new_members.write[E->get().index] = value; @@ -1494,7 +1440,6 @@ void GDScriptInstance::reload_members() { //pass the values to the new indices member_indices_cache.clear(); for (Map<StringName, GDScript::MemberInfo>::Element *E = script->member_indices.front(); E; E = E->next()) { - member_indices_cache[E->key()] = E->get().index; } @@ -1507,7 +1452,6 @@ GDScriptInstance::GDScriptInstance() { } GDScriptInstance::~GDScriptInstance() { - MutexLock lock(GDScriptLanguage::get_singleton()->lock); while (SelfList<GDScriptFunctionState> *E = pending_func_states.first()) { @@ -1525,14 +1469,12 @@ GDScriptInstance::~GDScriptInstance() { GDScriptLanguage *GDScriptLanguage::singleton = nullptr; String GDScriptLanguage::get_name() const { - return "GDScript"; } /* LANGUAGE FUNCTIONS */ void GDScriptLanguage::_add_global(const StringName &p_name, const Variant &p_value) { - if (globals.has(p_name)) { //overwrite existing global_array.write[globals[p_name]] = p_value; @@ -1544,7 +1486,6 @@ void GDScriptLanguage::_add_global(const StringName &p_name, const Variant &p_va } void GDScriptLanguage::add_global_constant(const StringName &p_variable, const Variant &p_value) { - _add_global(p_variable, p_value); } @@ -1558,11 +1499,9 @@ void GDScriptLanguage::remove_named_global_constant(const StringName &p_name) { } void GDScriptLanguage::init() { - //populate global constants int gcc = GlobalConstants::get_global_constant_count(); for (int i = 0; i < gcc; i++) { - _add_global(StaticCString::create(GlobalConstants::get_global_constant_name(i)), GlobalConstants::get_global_constant_value(i)); } @@ -1576,14 +1515,15 @@ void GDScriptLanguage::init() { List<StringName> class_list; ClassDB::get_class_list(&class_list); for (List<StringName>::Element *E = class_list.front(); E; E = E->next()) { - StringName n = E->get(); String s = String(n); - if (s.begins_with("_")) + if (s.begins_with("_")) { n = s.substr(1, s.length()); + } - if (globals.has(n)) + if (globals.has(n)) { continue; + } Ref<GDScriptNativeClass> nc = memnew(GDScriptNativeClass(E->get())); _add_global(n, nc); } @@ -1593,29 +1533,27 @@ void GDScriptLanguage::init() { List<Engine::Singleton> singletons; Engine::get_singleton()->get_singletons(&singletons); for (List<Engine::Singleton>::Element *E = singletons.front(); E; E = E->next()) { - _add_global(E->get().name, E->get().ptr); } } String GDScriptLanguage::get_type() const { - return "GDScript"; } -String GDScriptLanguage::get_extension() const { +String GDScriptLanguage::get_extension() const { return "gd"; } -Error GDScriptLanguage::execute_file(const String &p_path) { +Error GDScriptLanguage::execute_file(const String &p_path) { // ?? return OK; } + void GDScriptLanguage::finish() { } void GDScriptLanguage::profiling_start() { - #ifdef DEBUG_ENABLED MutexLock lock(this->lock); @@ -1638,7 +1576,6 @@ void GDScriptLanguage::profiling_start() { } void GDScriptLanguage::profiling_stop() { - #ifdef DEBUG_ENABLED MutexLock lock(this->lock); @@ -1647,7 +1584,6 @@ void GDScriptLanguage::profiling_stop() { } int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) { - int current = 0; #ifdef DEBUG_ENABLED @@ -1655,8 +1591,9 @@ int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, SelfList<GDScriptFunction> *elem = function_list.first(); while (elem) { - if (current >= p_info_max) + if (current >= p_info_max) { break; + } p_info_arr[current].call_count = elem->self()->profile.call_count; p_info_arr[current].self_time = elem->self()->profile.self_time; p_info_arr[current].total_time = elem->self()->profile.total_time; @@ -1670,7 +1607,6 @@ int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, } int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) { - int current = 0; #ifdef DEBUG_ENABLED @@ -1678,8 +1614,9 @@ int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_ SelfList<GDScriptFunction> *elem = function_list.first(); while (elem) { - if (current >= p_info_max) + if (current >= p_info_max) { break; + } if (elem->self()->profile.last_frame_call_count > 0) { p_info_arr[current].call_count = elem->self()->profile.last_frame_call_count; p_info_arr[current].self_time = elem->self()->profile.last_frame_self_time; @@ -1695,12 +1632,11 @@ int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_ } struct GDScriptDepSort { - //must support sorting so inheritance works properly (parent must be reloaded first) bool operator()(const Ref<GDScript> &A, const Ref<GDScript> &B) const { - - if (A == B) + if (A == B) { return false; //shouldn't happen but.. + } const GDScript *I = B->get_base().ptr(); while (I) { if (I == A.ptr()) { @@ -1716,7 +1652,6 @@ struct GDScriptDepSort { }; void GDScriptLanguage::reload_all_scripts() { - #ifdef DEBUG_ENABLED print_verbose("GDScript: Reloading all scripts"); List<Ref<GDScript>> scripts; @@ -1738,7 +1673,6 @@ void GDScriptLanguage::reload_all_scripts() { scripts.sort_custom<GDScriptDepSort>(); //update in inheritance dependency order for (List<Ref<GDScript>>::Element *E = scripts.front(); E; E = E->next()) { - print_verbose("GDScript: Reloading: " + E->get()->get_path()); E->get()->load_source_code(E->get()->get_path()); E->get()->reload(true); @@ -1747,7 +1681,6 @@ void GDScriptLanguage::reload_all_scripts() { } void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload) { - #ifdef DEBUG_ENABLED List<Ref<GDScript>> scripts; @@ -1757,7 +1690,6 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so SelfList<GDScript> *elem = script_list.first(); while (elem) { if (elem->self()->get_path().is_resource_file()) { - scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident } elem = elem->next(); @@ -1773,16 +1705,15 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so scripts.sort_custom<GDScriptDepSort>(); //update in inheritance dependency order for (List<Ref<GDScript>>::Element *E = scripts.front(); E; E = E->next()) { - bool reload = E->get() == p_script || to_reload.has(E->get()->get_base()); - if (!reload) + if (!reload) { continue; + } to_reload.insert(E->get(), Map<ObjectID, List<Pair<StringName, Variant>>>()); if (!p_soft_reload) { - //save state and remove script from instances Map<ObjectID, List<Pair<StringName, Variant>>> &map = to_reload[E->get()]; @@ -1791,7 +1722,6 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so //save instance info List<Pair<StringName, Variant>> state; if (obj->get_script_instance()) { - obj->get_script_instance()->get_property_state(state); map[obj->get_instance_id()] = state; obj->set_script(Variant()); @@ -1806,7 +1736,6 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so //save instance info if (obj->get_script_instance()) { - map.insert(obj->get_instance_id(), List<Pair<StringName, Variant>>()); List<Pair<StringName, Variant>> &state = map[obj->get_instance_id()]; obj->get_script_instance()->get_property_state(state); @@ -1826,18 +1755,17 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so } for (Map<Ref<GDScript>, Map<ObjectID, List<Pair<StringName, Variant>>>>::Element *E = to_reload.front(); E; E = E->next()) { - Ref<GDScript> scr = E->key(); scr->reload(p_soft_reload); //restore state if saved for (Map<ObjectID, List<Pair<StringName, Variant>>>::Element *F = E->get().front(); F; F = F->next()) { - List<Pair<StringName, Variant>> &saved_state = F->get(); Object *obj = ObjectDB::get_instance(F->key()); - if (!obj) + if (!obj) { continue; + } if (!p_soft_reload) { //clear it just in case (may be a pending reload state) @@ -1876,7 +1804,6 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so } void GDScriptLanguage::frame() { - calls = 0; #ifdef DEBUG_ENABLED @@ -1900,7 +1827,6 @@ void GDScriptLanguage::frame() { /* EDITOR FUNCTIONS */ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const { - static const char *_reserved_words[] = { // operators "and", @@ -1964,7 +1890,6 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const { const char **w = _reserved_words; while (*w) { - p_words->push_back(*w); w++; } @@ -1975,12 +1900,10 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const { } bool GDScriptLanguage::handles_global_class_type(const String &p_type) const { - return p_type == "GDScript"; } String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_base_type, String *r_icon_path) const { - Vector<uint8_t> sourcef; Error err; FileAccessRef f = FileAccess::open(p_path, FileAccess::READ, &err); @@ -1994,16 +1917,15 @@ String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_b parser.parse(source, p_path.get_base_dir(), true, p_path, false, nullptr, true); if (parser.get_parse_tree() && parser.get_parse_tree()->type == GDScriptParser::Node::TYPE_CLASS) { - const GDScriptParser::ClassNode *c = static_cast<const GDScriptParser::ClassNode *>(parser.get_parse_tree()); if (r_icon_path) { - if (c->icon_path.empty() || c->icon_path.is_abs_path()) + if (c->icon_path.empty() || c->icon_path.is_abs_path()) { *r_icon_path = c->icon_path; - else if (c->icon_path.is_rel_path()) + } else if (c->icon_path.is_rel_path()) { *r_icon_path = p_path.get_base_dir().plus_file(c->icon_path).simplify_path(); + } } if (r_base_type) { - const GDScriptParser::ClassNode *subclass = c; String path = p_path; GDScriptParser subparser; @@ -2077,7 +1999,6 @@ String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_b #ifdef DEBUG_ENABLED String GDScriptWarning::get_message() const { - #define CHECK_SYMBOLS(m_amount) ERR_FAIL_COND_V(symbols.size() < m_amount, String()); switch (code) { @@ -2246,7 +2167,6 @@ GDScriptWarning::Code GDScriptWarning::get_code_from_name(const String &p_name) #endif // DEBUG_ENABLED GDScriptLanguage::GDScriptLanguage() { - calls = 0; ERR_FAIL_COND(singleton); singleton = this; @@ -2291,7 +2211,6 @@ GDScriptLanguage::GDScriptLanguage() { } GDScriptLanguage::~GDScriptLanguage() { - if (_call_stack) { memdelete_arr(_call_stack); } @@ -2304,29 +2223,30 @@ void GDScriptLanguage::add_orphan_subclass(const String &p_qualified_name, const Ref<GDScript> GDScriptLanguage::get_orphan_subclass(const String &p_qualified_name) { Map<String, ObjectID>::Element *orphan_subclass_element = orphan_subclasses.find(p_qualified_name); - if (!orphan_subclass_element) + if (!orphan_subclass_element) { return Ref<GDScript>(); + } ObjectID orphan_subclass = orphan_subclass_element->get(); Object *obj = ObjectDB::get_instance(orphan_subclass); orphan_subclasses.erase(orphan_subclass_element); - if (!obj) + if (!obj) { return Ref<GDScript>(); + } return Ref<GDScript>(Object::cast_to<GDScript>(obj)); } /*************** 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) { - - if (r_error) + if (r_error) { *r_error = ERR_FILE_CANT_OPEN; + } GDScript *script = memnew(GDScript); Ref<GDScript> scriptres(script); if (p_path.ends_with(".gde") || p_path.ends_with(".gdc")) { - script->set_script_path(p_original_path); // script needs this. script->set_path(p_original_path); Error err = script->load_byte_code(p_path); @@ -2341,34 +2261,32 @@ RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_ori script->reload(); } - if (r_error) + if (r_error) { *r_error = OK; + } return scriptres; } void ResourceFormatLoaderGDScript::get_recognized_extensions(List<String> *p_extensions) const { - p_extensions->push_back("gd"); p_extensions->push_back("gdc"); p_extensions->push_back("gde"); } bool ResourceFormatLoaderGDScript::handles_type(const String &p_type) const { - return (p_type == "Script" || p_type == "GDScript"); } String ResourceFormatLoaderGDScript::get_resource_type(const String &p_path) const { - String el = p_path.get_extension().to_lower(); - if (el == "gd" || el == "gdc" || el == "gde") + if (el == "gd" || el == "gdc" || el == "gde") { return "GDScript"; + } return ""; } void ResourceFormatLoaderGDScript::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) { - FileAccessRef file = FileAccess::open(p_path, FileAccess::READ); ERR_FAIL_COND_MSG(!file, "Cannot open file '" + p_path + "'."); @@ -2388,7 +2306,6 @@ void ResourceFormatLoaderGDScript::get_dependencies(const String &p_path, List<S } Error ResourceFormatSaverGDScript::save(const String &p_path, const RES &p_resource, uint32_t p_flags) { - Ref<GDScript> sqscr = p_resource; ERR_FAIL_COND_V(sqscr.is_null(), ERR_INVALID_PARAMETER); @@ -2415,12 +2332,11 @@ Error ResourceFormatSaverGDScript::save(const String &p_path, const RES &p_resou } void ResourceFormatSaverGDScript::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const { - if (Object::cast_to<GDScript>(*p_resource)) { p_extensions->push_back("gd"); } } -bool ResourceFormatSaverGDScript::recognize(const RES &p_resource) const { +bool ResourceFormatSaverGDScript::recognize(const RES &p_resource) const { return Object::cast_to<GDScript>(*p_resource) != nullptr; } diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 3cba621578..e770dc3abd 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -39,7 +39,6 @@ #include "gdscript_function.h" class GDScriptNativeClass : public Reference { - GDCLASS(GDScriptNativeClass, Reference); StringName name; @@ -56,7 +55,6 @@ public: }; class GDScript : public Script { - GDCLASS(GDScript, Script); bool tool; bool valid; @@ -211,11 +209,11 @@ public: virtual int get_member_line(const StringName &p_member) const { #ifdef TOOLS_ENABLED - if (member_lines.has(p_member)) + if (member_lines.has(p_member)) { return member_lines[p_member]; - else + } #endif - return -1; + return -1; } virtual void get_constants(Map<StringName, Variant> *p_constants); @@ -350,7 +348,6 @@ struct GDScriptWarning { #endif // DEBUG_ENABLED class GDScriptLanguage : public ScriptLanguage { - friend class GDScriptFunctionState; static GDScriptLanguage *singleton; @@ -361,7 +358,6 @@ class GDScriptLanguage : public ScriptLanguage { Map<StringName, Variant> named_globals; struct CallLevel { - Variant *stack; GDScriptFunction *function; GDScriptInstance *instance; @@ -400,12 +396,13 @@ public: bool debug_break_parse(const String &p_file, int p_line, const String &p_error); _FORCE_INLINE_ void enter_function(GDScriptInstance *p_instance, GDScriptFunction *p_function, Variant *p_stack, int *p_ip, int *p_line) { - - if (Thread::get_main_id() != Thread::get_caller_id()) + if (Thread::get_main_id() != Thread::get_caller_id()) { return; //no support for other threads than main for now + } - if (EngineDebugger::get_script_debugger()->get_lines_left() > 0 && EngineDebugger::get_script_debugger()->get_depth() >= 0) + if (EngineDebugger::get_script_debugger()->get_lines_left() > 0 && EngineDebugger::get_script_debugger()->get_depth() >= 0) { EngineDebugger::get_script_debugger()->set_depth(EngineDebugger::get_script_debugger()->get_depth() + 1); + } if (_debug_call_stack_pos >= _debug_max_call_stack) { //stack overflow @@ -423,15 +420,15 @@ public: } _FORCE_INLINE_ void exit_function() { - - if (Thread::get_main_id() != Thread::get_caller_id()) + if (Thread::get_main_id() != Thread::get_caller_id()) { return; //no support for other threads than main for now + } - if (EngineDebugger::get_script_debugger()->get_lines_left() > 0 && EngineDebugger::get_script_debugger()->get_depth() >= 0) + if (EngineDebugger::get_script_debugger()->get_lines_left() > 0 && EngineDebugger::get_script_debugger()->get_depth() >= 0) { EngineDebugger::get_script_debugger()->set_depth(EngineDebugger::get_script_debugger()->get_depth() - 1); + } if (_debug_call_stack_pos == 0) { - _debug_error = "Stack Underflow (Engine Bug)"; EngineDebugger::get_script_debugger()->debug(this); return; @@ -441,8 +438,9 @@ public: } virtual Vector<StackInfo> debug_get_current_stack_info() { - if (Thread::get_main_id() != Thread::get_caller_id()) + if (Thread::get_main_id() != Thread::get_caller_id()) { return Vector<StackInfo>(); + } Vector<StackInfo> csi; csi.resize(_debug_call_stack_pos); @@ -457,7 +455,6 @@ public: } struct { - StringName _init; StringName _notification; StringName _set; diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 473b6fab05..bc095ae1f9 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -33,24 +33,24 @@ #include "gdscript.h" bool GDScriptCompiler::_is_class_member_property(CodeGen &codegen, const StringName &p_name) { - - if (codegen.function_node && codegen.function_node->_static) + if (codegen.function_node && codegen.function_node->_static) { return false; + } - if (codegen.stack_identifiers.has(p_name)) + if (codegen.stack_identifiers.has(p_name)) { return false; //shadowed + } return _is_class_member_property(codegen.script, p_name); } bool GDScriptCompiler::_is_class_member_property(GDScript *owner, const StringName &p_name) { - GDScript *scr = owner; GDScriptNativeClass *nc = nullptr; while (scr) { - - if (scr->native.is_valid()) + if (scr->native.is_valid()) { nc = scr->native.ptr(); + } scr = scr->_base; } @@ -60,9 +60,9 @@ bool GDScriptCompiler::_is_class_member_property(GDScript *owner, const StringNa } void GDScriptCompiler::_set_error(const String &p_error, const GDScriptParser::Node *p_node) { - - if (error != "") + if (error != "") { return; + } error = p_error; if (p_node) { @@ -75,12 +75,12 @@ void GDScriptCompiler::_set_error(const String &p_error, const GDScriptParser::N } bool GDScriptCompiler::_create_unary_operator(CodeGen &codegen, const GDScriptParser::OperatorNode *on, Variant::Operator op, int p_stack_level) { - ERR_FAIL_COND_V(on->arguments.size() != 1, false); int src_address_a = _parse_expression(codegen, on->arguments[0], p_stack_level); - if (src_address_a < 0) + if (src_address_a < 0) { return false; + } codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR); // perform operator codegen.opcodes.push_back(op); //which operator @@ -91,18 +91,20 @@ bool GDScriptCompiler::_create_unary_operator(CodeGen &codegen, const GDScriptPa } bool GDScriptCompiler::_create_binary_operator(CodeGen &codegen, const GDScriptParser::OperatorNode *on, Variant::Operator op, int p_stack_level, bool p_initializer, int p_index_addr) { - ERR_FAIL_COND_V(on->arguments.size() != 2, false); int src_address_a = _parse_expression(codegen, on->arguments[0], p_stack_level, false, p_initializer, p_index_addr); - if (src_address_a < 0) + if (src_address_a < 0) { return false; - if (src_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) + } + if (src_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) { p_stack_level++; //uses stack for return, increase stack + } int src_address_b = _parse_expression(codegen, on->arguments[1], p_stack_level, false, p_initializer); - if (src_address_b < 0) + if (src_address_b < 0) { return false; + } codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR); // perform operator codegen.opcodes.push_back(op); //which operator @@ -172,11 +174,9 @@ GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::D } int GDScriptCompiler::_parse_assign_right_expression(CodeGen &codegen, const GDScriptParser::OperatorNode *p_expression, int p_stack_level, int p_index_addr) { - Variant::Operator var_op = Variant::OP_MAX; switch (p_expression->op) { - case GDScriptParser::OperatorNode::OP_ASSIGN_ADD: var_op = Variant::OP_ADD; break; @@ -209,11 +209,9 @@ int GDScriptCompiler::_parse_assign_right_expression(CodeGen &codegen, const GDS break; case GDScriptParser::OperatorNode::OP_INIT_ASSIGN: case GDScriptParser::OperatorNode::OP_ASSIGN: { - //none } break; default: { - ERR_FAIL_V(-1); } } @@ -221,12 +219,12 @@ int GDScriptCompiler::_parse_assign_right_expression(CodeGen &codegen, const GDS bool initializer = p_expression->op == GDScriptParser::OperatorNode::OP_INIT_ASSIGN; if (var_op == Variant::OP_MAX) { - return _parse_expression(codegen, p_expression->arguments[1], p_stack_level, false, initializer); } - if (!_create_binary_operator(codegen, p_expression, var_op, p_stack_level, initializer, p_index_addr)) + if (!_create_binary_operator(codegen, p_expression, var_op, p_stack_level, initializer, p_index_addr)) { return -1; + } int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode @@ -235,7 +233,6 @@ int GDScriptCompiler::_parse_assign_right_expression(CodeGen &codegen, const GDS } int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::Node *p_expression, int p_stack_level, bool p_root, bool p_initializer, int p_index_addr) { - switch (p_expression->type) { //should parse variable declaration and adjust stack accordingly... case GDScriptParser::Node::TYPE_IDENTIFIER: { @@ -251,7 +248,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: // TRY STACK! if (!p_initializer && codegen.stack_identifiers.has(identifier)) { - int pos = codegen.stack_identifiers[identifier]; return pos | (GDScriptFunction::ADDR_TYPE_STACK_VARIABLE << GDScriptFunction::ADDR_BITS); } @@ -269,11 +265,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: //TRY MEMBERS! if (!codegen.function_node || !codegen.function_node->_static) { - // TRY MEMBER VARIABLES! //static function if (codegen.script->member_indices.has(identifier)) { - int idx = codegen.script->member_indices[identifier].index; return idx | (GDScriptFunction::ADDR_TYPE_MEMBER << GDScriptFunction::ADDR_BITS); //argument (stack root) } @@ -283,26 +277,23 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: GDScript *owner = codegen.script; while (owner) { - GDScript *scr = owner; GDScriptNativeClass *nc = nullptr; while (scr) { - if (scr->constants.has(identifier)) { - //int idx=scr->constants[identifier]; int idx = codegen.get_name_map_pos(identifier); return idx | (GDScriptFunction::ADDR_TYPE_CLASS_CONSTANT << GDScriptFunction::ADDR_BITS); //argument (stack root) } - if (scr->native.is_valid()) + if (scr->native.is_valid()) { nc = scr->native.ptr(); + } scr = scr->_base; } // CLASS C++ Integer Constant if (nc) { - bool success = false; int constant = ClassDB::get_integer_constant(nc->get_name(), identifier, &success); if (success) { @@ -310,7 +301,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: int idx; if (!codegen.constant_map.has(key)) { - idx = codegen.constant_map.size(); codegen.constant_map[key] = idx; @@ -326,7 +316,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: } if (GDScriptLanguage::get_singleton()->get_global_map().has(identifier)) { - int idx = GDScriptLanguage::get_singleton()->get_global_map()[identifier]; return idx | (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS); //argument (stack root) } @@ -334,7 +323,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: /* TRY GLOBAL CLASSES */ if (ScriptServer::is_global_class(identifier)) { - const GDScriptParser::ClassNode *class_node = codegen.class_node; while (class_node->owner) { class_node = class_node->owner; @@ -355,7 +343,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: int idx; if (!codegen.constant_map.has(key)) { - idx = codegen.constant_map.size(); codegen.constant_map[key] = idx; @@ -368,7 +355,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: #ifdef TOOLS_ENABLED if (GDScriptLanguage::get_singleton()->get_named_globals_map().has(identifier)) { - int idx = codegen.named_globals.find(identifier); if (idx == -1) { idx = codegen.named_globals.size(); @@ -392,7 +378,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: int idx; if (!codegen.constant_map.has(cn->value)) { - idx = codegen.constant_map.size(); codegen.constant_map[cn->value] = idx; @@ -412,17 +397,16 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: return (GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS); } break; case GDScriptParser::Node::TYPE_ARRAY: { - const GDScriptParser::ArrayNode *an = static_cast<const GDScriptParser::ArrayNode *>(p_expression); Vector<int> values; int slevel = p_stack_level; for (int i = 0; i < an->elements.size(); i++) { - int ret = _parse_expression(codegen, an->elements[i], slevel); - if (ret < 0) + if (ret < 0) { return ret; + } if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) { slevel++; codegen.alloc_stack(slevel); @@ -433,8 +417,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: codegen.opcodes.push_back(GDScriptFunction::OPCODE_CONSTRUCT_ARRAY); codegen.opcodes.push_back(values.size()); - for (int i = 0; i < values.size(); i++) + for (int i = 0; i < values.size(); i++) { codegen.opcodes.push_back(values[i]); + } int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode @@ -443,17 +428,16 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: } break; case GDScriptParser::Node::TYPE_DICTIONARY: { - const GDScriptParser::DictionaryNode *dn = static_cast<const GDScriptParser::DictionaryNode *>(p_expression); Vector<int> values; int slevel = p_stack_level; for (int i = 0; i < dn->elements.size(); i++) { - int ret = _parse_expression(codegen, dn->elements[i].key, slevel); - if (ret < 0) + if (ret < 0) { return ret; + } if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) { slevel++; codegen.alloc_stack(slevel); @@ -462,8 +446,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: values.push_back(ret); ret = _parse_expression(codegen, dn->elements[i].value, slevel); - if (ret < 0) + if (ret < 0) { return ret; + } if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) { slevel++; codegen.alloc_stack(slevel); @@ -474,8 +459,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: codegen.opcodes.push_back(GDScriptFunction::OPCODE_CONSTRUCT_DICTIONARY); codegen.opcodes.push_back(dn->elements.size()); - for (int i = 0; i < values.size(); i++) + for (int i = 0; i < values.size(); i++) { codegen.opcodes.push_back(values[i]); + } int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode @@ -488,8 +474,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: int slevel = p_stack_level; int src_addr = _parse_expression(codegen, cn->source_node, slevel); - if (src_addr < 0) + if (src_addr < 0) { return src_addr; + } if (src_addr & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) { slevel++; codegen.alloc_stack(slevel); @@ -505,7 +492,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: case GDScriptDataType::NATIVE: { int class_idx; if (GDScriptLanguage::get_singleton()->get_global_map().has(cast_type.native_type)) { - class_idx = GDScriptLanguage::get_singleton()->get_global_map()[cast_type.native_type]; class_idx |= (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS); //argument (stack root) } else { @@ -517,7 +503,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: } break; case GDScriptDataType::SCRIPT: case GDScriptDataType::GDSCRIPT: { - Variant script = cast_type.script_type; int idx = codegen.get_constant_pos(script); idx |= GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS; //make it a local constant (faster access) @@ -543,10 +528,8 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: const GDScriptParser::OperatorNode *on = static_cast<const GDScriptParser::OperatorNode *>(p_expression); switch (on->op) { - //call/constructor operator case GDScriptParser::OperatorNode::OP_PARENT_CALL: { - ERR_FAIL_COND_V(on->arguments.size() < 1, -1); const GDScriptParser::IdentifierNode *in = (const GDScriptParser::IdentifierNode *)on->arguments[0]; @@ -554,10 +537,10 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: Vector<int> arguments; int slevel = p_stack_level; for (int i = 1; i < on->arguments.size(); i++) { - int ret = _parse_expression(codegen, on->arguments[i], slevel); - if (ret < 0) + if (ret < 0) { return ret; + } if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) { slevel++; codegen.alloc_stack(slevel); @@ -571,12 +554,12 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: codegen.opcodes.push_back(codegen.get_name_map_pos(in->name)); //instance codegen.opcodes.push_back(arguments.size()); //argument count codegen.alloc_call(arguments.size()); - for (int i = 0; i < arguments.size(); i++) + for (int i = 0; i < arguments.size(); i++) { codegen.opcodes.push_back(arguments[i]); //arguments + } } break; case GDScriptParser::OperatorNode::OP_CALL: { - if (on->arguments[0]->type == GDScriptParser::Node::TYPE_TYPE) { //construct a basic type ERR_FAIL_COND_V(on->arguments.size() < 1, -1); @@ -587,10 +570,10 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: Vector<int> arguments; int slevel = p_stack_level; for (int i = 1; i < on->arguments.size(); i++) { - int ret = _parse_expression(codegen, on->arguments[i], slevel); - if (ret < 0) + if (ret < 0) { return ret; + } if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) { slevel++; codegen.alloc_stack(slevel); @@ -603,8 +586,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: codegen.opcodes.push_back(vtype); //instance codegen.opcodes.push_back(arguments.size()); //argument count codegen.alloc_call(arguments.size()); - for (int i = 0; i < arguments.size(); i++) + for (int i = 0; i < arguments.size(); i++) { codegen.opcodes.push_back(arguments[i]); //arguments + } } else if (on->arguments[0]->type == GDScriptParser::Node::TYPE_BUILT_IN_FUNCTION) { //built in function @@ -614,10 +598,10 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: Vector<int> arguments; int slevel = p_stack_level; for (int i = 1; i < on->arguments.size(); i++) { - int ret = _parse_expression(codegen, on->arguments[i], slevel); - if (ret < 0) + if (ret < 0) { return ret; + } if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) { slevel++; @@ -631,8 +615,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: codegen.opcodes.push_back(static_cast<const GDScriptParser::BuiltInFunctionNode *>(on->arguments[0])->function); codegen.opcodes.push_back(on->arguments.size() - 1); codegen.alloc_call(on->arguments.size() - 1); - for (int i = 0; i < arguments.size(); i++) + for (int i = 0; i < arguments.size(); i++) { codegen.opcodes.push_back(arguments[i]); + } } else { //regular function @@ -648,14 +633,12 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: int slevel = p_stack_level; for (int i = 0; i < on->arguments.size(); i++) { - int ret; if (i == 0 && on->arguments[i]->type == GDScriptParser::Node::TYPE_SELF && codegen.function_node && codegen.function_node->_static) { //static call to self ret = (GDScriptFunction::ADDR_TYPE_CLASS << GDScriptFunction::ADDR_BITS); } else if (i == 1) { - if (on->arguments[i]->type != GDScriptParser::Node::TYPE_IDENTIFIER) { _set_error("Attempt to call a non-identifier.", on); return -1; @@ -664,10 +647,10 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: ret = codegen.get_name_map_pos(id->name); } else { - ret = _parse_expression(codegen, on->arguments[i], slevel); - if (ret < 0) + if (ret < 0) { return ret; + } if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) { slevel++; codegen.alloc_stack(slevel); @@ -679,21 +662,21 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: codegen.opcodes.push_back(p_root ? GDScriptFunction::OPCODE_CALL : GDScriptFunction::OPCODE_CALL_RETURN); // perform operator codegen.opcodes.push_back(on->arguments.size() - 2); codegen.alloc_call(on->arguments.size() - 2); - for (int i = 0; i < arguments.size(); i++) + for (int i = 0; i < arguments.size(); i++) { codegen.opcodes.push_back(arguments[i]); + } } } break; case GDScriptParser::OperatorNode::OP_YIELD: { - ERR_FAIL_COND_V(on->arguments.size() && on->arguments.size() != 2, -1); Vector<int> arguments; int slevel = p_stack_level; for (int i = 0; i < on->arguments.size(); i++) { - int ret = _parse_expression(codegen, on->arguments[i], slevel); - if (ret < 0) + if (ret < 0) { return ret; + } if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) { slevel++; codegen.alloc_stack(slevel); @@ -703,8 +686,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: //push call bytecode codegen.opcodes.push_back(arguments.size() == 0 ? GDScriptFunction::OPCODE_YIELD : GDScriptFunction::OPCODE_YIELD_SIGNAL); // basic type constructor - for (int i = 0; i < arguments.size(); i++) + for (int i = 0; i < arguments.size(); i++) { codegen.opcodes.push_back(arguments[i]); //arguments + } codegen.opcodes.push_back(GDScriptFunction::OPCODE_YIELD_RESUME); //next will be where to place the result :) @@ -713,22 +697,21 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: //indexing operator case GDScriptParser::OperatorNode::OP_INDEX: case GDScriptParser::OperatorNode::OP_INDEX_NAMED: { - ERR_FAIL_COND_V(on->arguments.size() != 2, -1); int slevel = p_stack_level; bool named = (on->op == GDScriptParser::OperatorNode::OP_INDEX_NAMED); int from = _parse_expression(codegen, on->arguments[0], slevel); - if (from < 0) + if (from < 0) { return from; + } int index; if (p_index_addr != 0) { index = p_index_addr; } else if (named) { if (on->arguments[0]->type == GDScriptParser::Node::TYPE_SELF && codegen.script && codegen.function_node && !codegen.function_node->_static) { - GDScriptParser::IdentifierNode *identifier = static_cast<GDScriptParser::IdentifierNode *>(on->arguments[1]); const Map<StringName, GDScript::MemberInfo>::Element *MI = codegen.script->member_indices.find(identifier->name); @@ -749,7 +732,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: index = codegen.get_name_map_pos(static_cast<GDScriptParser::IdentifierNode *>(on->arguments[1])->name); } else { - if (on->arguments[1]->type == GDScriptParser::Node::TYPE_CONSTANT && static_cast<const GDScriptParser::ConstantNode *>(on->arguments[1])->value.get_type() == Variant::STRING) { //also, somehow, named (speed up anyway) StringName name = static_cast<const GDScriptParser::ConstantNode *>(on->arguments[1])->value; @@ -764,8 +746,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: } index = _parse_expression(codegen, on->arguments[1], slevel); - if (index < 0) + if (index < 0) { return index; + } } } @@ -775,20 +758,21 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: } break; case GDScriptParser::OperatorNode::OP_AND: { - // AND operator with early out on failure int res = _parse_expression(codegen, on->arguments[0], p_stack_level); - if (res < 0) + if (res < 0) { return res; + } codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT); codegen.opcodes.push_back(res); int jump_fail_pos = codegen.opcodes.size(); codegen.opcodes.push_back(0); res = _parse_expression(codegen, on->arguments[1], p_stack_level); - if (res < 0) + if (res < 0) { return res; + } codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT); codegen.opcodes.push_back(res); @@ -808,20 +792,21 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: } break; case GDScriptParser::OperatorNode::OP_OR: { - // OR operator with early out on success int res = _parse_expression(codegen, on->arguments[0], p_stack_level); - if (res < 0) + if (res < 0) { return res; + } codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF); codegen.opcodes.push_back(res); int jump_success_pos = codegen.opcodes.size(); codegen.opcodes.push_back(0); res = _parse_expression(codegen, on->arguments[1], p_stack_level); - if (res < 0) + if (res < 0) { return res; + } codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF); codegen.opcodes.push_back(res); @@ -842,20 +827,21 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: } break; // ternary operators case GDScriptParser::OperatorNode::OP_TERNARY_IF: { - // x IF a ELSE y operator with early out on failure int res = _parse_expression(codegen, on->arguments[0], p_stack_level); - if (res < 0) + if (res < 0) { return res; + } codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT); codegen.opcodes.push_back(res); int jump_fail_pos = codegen.opcodes.size(); codegen.opcodes.push_back(0); res = _parse_expression(codegen, on->arguments[1], p_stack_level); - if (res < 0) + if (res < 0) { return res; + } codegen.alloc_stack(p_stack_level); //it will be used.. codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN); @@ -867,8 +853,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: codegen.opcodes.write[jump_fail_pos] = codegen.opcodes.size(); res = _parse_expression(codegen, on->arguments[2], p_stack_level); - if (res < 0) + if (res < 0) { return res; + } codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN); codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); @@ -881,92 +868,113 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: } break; //unary operators case GDScriptParser::OperatorNode::OP_NEG: { - if (!_create_unary_operator(codegen, on, Variant::OP_NEGATE, p_stack_level)) + if (!_create_unary_operator(codegen, on, Variant::OP_NEGATE, p_stack_level)) { return -1; + } } break; case GDScriptParser::OperatorNode::OP_POS: { - if (!_create_unary_operator(codegen, on, Variant::OP_POSITIVE, p_stack_level)) + if (!_create_unary_operator(codegen, on, Variant::OP_POSITIVE, p_stack_level)) { return -1; + } } break; case GDScriptParser::OperatorNode::OP_NOT: { - if (!_create_unary_operator(codegen, on, Variant::OP_NOT, p_stack_level)) + if (!_create_unary_operator(codegen, on, Variant::OP_NOT, p_stack_level)) { return -1; + } } break; case GDScriptParser::OperatorNode::OP_BIT_INVERT: { - if (!_create_unary_operator(codegen, on, Variant::OP_BIT_NEGATE, p_stack_level)) + if (!_create_unary_operator(codegen, on, Variant::OP_BIT_NEGATE, p_stack_level)) { return -1; + } } break; //binary operators (in precedence order) case GDScriptParser::OperatorNode::OP_IN: { - if (!_create_binary_operator(codegen, on, Variant::OP_IN, p_stack_level)) + if (!_create_binary_operator(codegen, on, Variant::OP_IN, p_stack_level)) { return -1; + } } break; case GDScriptParser::OperatorNode::OP_EQUAL: { - if (!_create_binary_operator(codegen, on, Variant::OP_EQUAL, p_stack_level)) + if (!_create_binary_operator(codegen, on, Variant::OP_EQUAL, p_stack_level)) { return -1; + } } break; case GDScriptParser::OperatorNode::OP_NOT_EQUAL: { - if (!_create_binary_operator(codegen, on, Variant::OP_NOT_EQUAL, p_stack_level)) + if (!_create_binary_operator(codegen, on, Variant::OP_NOT_EQUAL, p_stack_level)) { return -1; + } } break; case GDScriptParser::OperatorNode::OP_LESS: { - if (!_create_binary_operator(codegen, on, Variant::OP_LESS, p_stack_level)) + if (!_create_binary_operator(codegen, on, Variant::OP_LESS, p_stack_level)) { return -1; + } } break; case GDScriptParser::OperatorNode::OP_LESS_EQUAL: { - if (!_create_binary_operator(codegen, on, Variant::OP_LESS_EQUAL, p_stack_level)) + if (!_create_binary_operator(codegen, on, Variant::OP_LESS_EQUAL, p_stack_level)) { return -1; + } } break; case GDScriptParser::OperatorNode::OP_GREATER: { - if (!_create_binary_operator(codegen, on, Variant::OP_GREATER, p_stack_level)) + if (!_create_binary_operator(codegen, on, Variant::OP_GREATER, p_stack_level)) { return -1; + } } break; case GDScriptParser::OperatorNode::OP_GREATER_EQUAL: { - if (!_create_binary_operator(codegen, on, Variant::OP_GREATER_EQUAL, p_stack_level)) + if (!_create_binary_operator(codegen, on, Variant::OP_GREATER_EQUAL, p_stack_level)) { return -1; + } } break; case GDScriptParser::OperatorNode::OP_ADD: { - if (!_create_binary_operator(codegen, on, Variant::OP_ADD, p_stack_level)) + if (!_create_binary_operator(codegen, on, Variant::OP_ADD, p_stack_level)) { return -1; + } } break; case GDScriptParser::OperatorNode::OP_SUB: { - if (!_create_binary_operator(codegen, on, Variant::OP_SUBTRACT, p_stack_level)) + if (!_create_binary_operator(codegen, on, Variant::OP_SUBTRACT, p_stack_level)) { return -1; + } } break; case GDScriptParser::OperatorNode::OP_MUL: { - if (!_create_binary_operator(codegen, on, Variant::OP_MULTIPLY, p_stack_level)) + if (!_create_binary_operator(codegen, on, Variant::OP_MULTIPLY, p_stack_level)) { return -1; + } } break; case GDScriptParser::OperatorNode::OP_DIV: { - if (!_create_binary_operator(codegen, on, Variant::OP_DIVIDE, p_stack_level)) + if (!_create_binary_operator(codegen, on, Variant::OP_DIVIDE, p_stack_level)) { return -1; + } } break; case GDScriptParser::OperatorNode::OP_MOD: { - if (!_create_binary_operator(codegen, on, Variant::OP_MODULE, p_stack_level)) + if (!_create_binary_operator(codegen, on, Variant::OP_MODULE, p_stack_level)) { return -1; + } } break; //case GDScriptParser::OperatorNode::OP_SHIFT_LEFT: { if (!_create_binary_operator(codegen,on,Variant::OP_SHIFT_LEFT,p_stack_level)) return -1;} break; //case GDScriptParser::OperatorNode::OP_SHIFT_RIGHT: { if (!_create_binary_operator(codegen,on,Variant::OP_SHIFT_RIGHT,p_stack_level)) return -1;} break; case GDScriptParser::OperatorNode::OP_BIT_AND: { - if (!_create_binary_operator(codegen, on, Variant::OP_BIT_AND, p_stack_level)) + if (!_create_binary_operator(codegen, on, Variant::OP_BIT_AND, p_stack_level)) { return -1; + } } break; case GDScriptParser::OperatorNode::OP_BIT_OR: { - if (!_create_binary_operator(codegen, on, Variant::OP_BIT_OR, p_stack_level)) + if (!_create_binary_operator(codegen, on, Variant::OP_BIT_OR, p_stack_level)) { return -1; + } } break; case GDScriptParser::OperatorNode::OP_BIT_XOR: { - if (!_create_binary_operator(codegen, on, Variant::OP_BIT_XOR, p_stack_level)) + if (!_create_binary_operator(codegen, on, Variant::OP_BIT_XOR, p_stack_level)) { return -1; + } } break; //shift case GDScriptParser::OperatorNode::OP_SHIFT_LEFT: { - if (!_create_binary_operator(codegen, on, Variant::OP_SHIFT_LEFT, p_stack_level)) + if (!_create_binary_operator(codegen, on, Variant::OP_SHIFT_LEFT, p_stack_level)) { return -1; + } } break; case GDScriptParser::OperatorNode::OP_SHIFT_RIGHT: { - if (!_create_binary_operator(codegen, on, Variant::OP_SHIFT_RIGHT, p_stack_level)) + if (!_create_binary_operator(codegen, on, Variant::OP_SHIFT_RIGHT, p_stack_level)) { return -1; + } } break; //assignment operators case GDScriptParser::OperatorNode::OP_ASSIGN_ADD: @@ -981,18 +989,15 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: case GDScriptParser::OperatorNode::OP_ASSIGN_BIT_XOR: case GDScriptParser::OperatorNode::OP_INIT_ASSIGN: case GDScriptParser::OperatorNode::OP_ASSIGN: { - ERR_FAIL_COND_V(on->arguments.size() != 2, -1); if (on->arguments[0]->type == GDScriptParser::Node::TYPE_OPERATOR && (static_cast<GDScriptParser::OperatorNode *>(on->arguments[0])->op == GDScriptParser::OperatorNode::OP_INDEX || static_cast<GDScriptParser::OperatorNode *>(on->arguments[0])->op == GDScriptParser::OperatorNode::OP_INDEX_NAMED)) { - // SET (chained) MODE! #ifdef DEBUG_ENABLED if (static_cast<GDScriptParser::OperatorNode *>(on->arguments[0])->op == GDScriptParser::OperatorNode::OP_INDEX_NAMED) { const GDScriptParser::OperatorNode *inon = static_cast<GDScriptParser::OperatorNode *>(on->arguments[0]); if (inon->arguments[0]->type == GDScriptParser::Node::TYPE_SELF && codegen.script && codegen.function_node && !codegen.function_node->_static) { - const Map<StringName, GDScript::MemberInfo>::Element *MI = codegen.script->member_indices.find(static_cast<GDScriptParser::IdentifierNode *>(inon->arguments[1])->name); if (MI && MI->get().setter == codegen.function_node->name) { String n = static_cast<GDScriptParser::IdentifierNode *>(inon->arguments[1])->name; @@ -1017,13 +1022,10 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: //create get/set chain GDScriptParser::OperatorNode *n = op; while (true) { - chain.push_back(n); if (n->arguments[0]->type != GDScriptParser::Node::TYPE_OPERATOR) { - //check for a built-in property if (n->arguments[0]->type == GDScriptParser::Node::TYPE_IDENTIFIER) { - GDScriptParser::IdentifierNode *identifier = static_cast<GDScriptParser::IdentifierNode *>(n->arguments[0]); if (_is_class_member_property(codegen, identifier->name)) { assign_property = identifier->name; @@ -1032,8 +1034,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: break; } n = static_cast<GDScriptParser::OperatorNode *>(n->arguments[0]); - if (n->op != GDScriptParser::OperatorNode::OP_INDEX && n->op != GDScriptParser::OperatorNode::OP_INDEX_NAMED) + if (n->op != GDScriptParser::OperatorNode::OP_INDEX && n->op != GDScriptParser::OperatorNode::OP_INDEX_NAMED) { break; + } } } @@ -1041,8 +1044,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: //get at (potential) root stack pos, so it can be returned int prev_pos = _parse_expression(codegen, chain.back()->get()->arguments[0], slevel); - if (prev_pos < 0) + if (prev_pos < 0) { return prev_pos; + } int retval = prev_pos; if (retval & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) { @@ -1053,7 +1057,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: Vector<int> setchain; if (assign_property != StringName()) { - // recover and assign at the end, this allows stuff like // position.x+=2.0 // in Node2D @@ -1063,20 +1066,18 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: } for (List<GDScriptParser::OperatorNode *>::Element *E = chain.back(); E; E = E->prev()) { - - if (E == chain.front()) //ignore first + if (E == chain.front()) { //ignore first break; + } bool named = E->get()->op == GDScriptParser::OperatorNode::OP_INDEX_NAMED; int key_idx; if (named) { - key_idx = codegen.get_name_map_pos(static_cast<const GDScriptParser::IdentifierNode *>(E->get()->arguments[1])->name); //printf("named key %x\n",key_idx); } else { - if (prev_pos & (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS)) { slevel++; codegen.alloc_stack(slevel); @@ -1089,8 +1090,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: //stack was raised here if retval was stack but.. } - if (key_idx < 0) //error + if (key_idx < 0) { //error return key_idx; + } codegen.opcodes.push_back(named ? GDScriptFunction::OPCODE_GET_NAMED : GDScriptFunction::OPCODE_GET); codegen.opcodes.push_back(prev_pos); @@ -1117,17 +1119,16 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: bool named = false; if (op->op == GDScriptParser::OperatorNode::OP_INDEX_NAMED) { - set_index = codegen.get_name_map_pos(static_cast<const GDScriptParser::IdentifierNode *>(op->arguments[1])->name); named = true; } else { - set_index = _parse_expression(codegen, op->arguments[1], slevel + 1); named = false; } - if (set_index < 0) //error + if (set_index < 0) { //error return set_index; + } if (set_index & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) { slevel++; @@ -1135,8 +1136,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: } int set_value = _parse_assign_right_expression(codegen, on, slevel + 1, named ? 0 : set_index); - if (set_value < 0) //error + if (set_value < 0) { //error return set_value; + } codegen.opcodes.push_back(named ? GDScriptFunction::OPCODE_SET_NAMED : GDScriptFunction::OPCODE_SET); codegen.opcodes.push_back(prev_pos); @@ -1144,7 +1146,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: codegen.opcodes.push_back(set_value); for (int i = 0; i < setchain.size(); i++) { - codegen.opcodes.push_back(setchain[i]); } @@ -1156,8 +1157,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: int slevel = p_stack_level; int src_address = _parse_assign_right_expression(codegen, on, slevel); - if (src_address < 0) + if (src_address < 0) { return -1; + } StringName name = static_cast<GDScriptParser::IdentifierNode *>(on->arguments[0])->name; @@ -1167,14 +1169,14 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: return GDScriptFunction::ADDR_TYPE_NIL << GDScriptFunction::ADDR_BITS; } else { - //REGULAR ASSIGNMENT MODE!! int slevel = p_stack_level; int dst_address_a = _parse_expression(codegen, on->arguments[0], slevel, false, on->op == GDScriptParser::OperatorNode::OP_INIT_ASSIGN); - if (dst_address_a < 0) + if (dst_address_a < 0) { return -1; + } if (dst_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) { slevel++; @@ -1182,8 +1184,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: } int src_address_b = _parse_assign_right_expression(codegen, on, slevel); - if (src_address_b < 0) + if (src_address_b < 0) { return -1; + } GDScriptDataType assign_type = _gdtype_from_datatype(on->arguments[0]->get_datatype()); @@ -1199,7 +1202,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: case GDScriptDataType::NATIVE: { int class_idx; if (GDScriptLanguage::get_singleton()->get_global_map().has(assign_type.native_type)) { - class_idx = GDScriptLanguage::get_singleton()->get_global_map()[assign_type.native_type]; class_idx |= (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS); //argument (stack root) } else { @@ -1213,7 +1215,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: } break; case GDScriptDataType::SCRIPT: case GDScriptDataType::GDSCRIPT: { - Variant script = assign_type.script_type; int idx = codegen.get_constant_pos(script); idx |= GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS; //make it a local constant (faster access) @@ -1242,21 +1243,23 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: } } break; case GDScriptParser::OperatorNode::OP_IS: { - ERR_FAIL_COND_V(on->arguments.size() != 2, false); int slevel = p_stack_level; int src_address_a = _parse_expression(codegen, on->arguments[0], slevel); - if (src_address_a < 0) + if (src_address_a < 0) { return -1; + } - if (src_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) + if (src_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) { slevel++; //uses stack for return, increase stack + } int src_address_b = _parse_expression(codegen, on->arguments[1], slevel); - if (src_address_b < 0) + if (src_address_b < 0) { return -1; + } codegen.opcodes.push_back(GDScriptFunction::OPCODE_EXTENDS_TEST); // perform operator codegen.opcodes.push_back(src_address_a); // argument 1 @@ -1270,11 +1273,13 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: int slevel = p_stack_level; int src_address_a = _parse_expression(codegen, on->arguments[0], slevel); - if (src_address_a < 0) + if (src_address_a < 0) { return -1; + } - if (src_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) + if (src_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) { slevel++; //uses stack for return, increase stack + } const GDScriptParser::TypeNode *tn = static_cast<const GDScriptParser::TypeNode *>(on->arguments[1]); @@ -1283,7 +1288,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: codegen.opcodes.push_back((int)tn->vtype); // argument 2 (unary only takes one parameter) } break; default: { - ERR_FAIL_V_MSG(0, "Bug in bytecode compiler, unexpected operator #" + itos(on->op) + " in parse tree while parsing expression."); //unreachable code } break; @@ -1296,20 +1300,17 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: } break; //TYPE_TYPE, default: { - ERR_FAIL_V_MSG(-1, "Bug in bytecode compiler, unexpected node in parse tree while parsing expression."); //unreachable code } break; } } Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::BlockNode *p_block, int p_stack_level, int p_break_addr, int p_continue_addr) { - codegen.push_stack_identifiers(); int new_identifiers = 0; codegen.current_line = p_block->line; for (int i = 0; i < p_block->statements.size(); i++) { - const GDScriptParser::Node *s = p_block->statements[i]; switch (s->type) { @@ -1327,7 +1328,6 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo const GDScriptParser::ControlFlowNode *cf = static_cast<const GDScriptParser::ControlFlowNode *>(s); switch (cf->cf_type) { - case GDScriptParser::ControlFlowNode::CF_MATCH: { GDScriptParser::MatchNode *match = cf->match; @@ -1401,10 +1401,10 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo } break; case GDScriptParser::ControlFlowNode::CF_IF: { - int ret2 = _parse_expression(codegen, cf->arguments[0], p_stack_level, false); - if (ret2 < 0) + if (ret2 < 0) { return ERR_PARSE_ERROR; + } codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT); codegen.opcodes.push_back(ret2); @@ -1412,19 +1412,20 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo codegen.opcodes.push_back(0); //temporary Error err = _parse_block(codegen, cf->body, p_stack_level, p_break_addr, p_continue_addr); - if (err) + if (err) { return err; + } if (cf->body_else) { - codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); int end_addr = codegen.opcodes.size(); codegen.opcodes.push_back(0); codegen.opcodes.write[else_addr] = codegen.opcodes.size(); Error err2 = _parse_block(codegen, cf->body_else, p_stack_level, p_break_addr, p_continue_addr); - if (err2) + if (err2) { return err2; + } codegen.opcodes.write[end_addr] = codegen.opcodes.size(); } else { @@ -1434,7 +1435,6 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo } break; case GDScriptParser::ControlFlowNode::CF_FOR: { - int slevel = p_stack_level; int iter_stack_pos = slevel; int iterator_pos = (slevel++) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); @@ -1446,8 +1446,9 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo codegen.add_stack_identifier(static_cast<const GDScriptParser::IdentifierNode *>(cf->arguments[0])->name, iter_stack_pos); int ret2 = _parse_expression(codegen, cf->arguments[1], slevel, false); - if (ret2 < 0) + if (ret2 < 0) { return ERR_COMPILATION_FAILED; + } //assign container codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN); @@ -1475,8 +1476,9 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo codegen.opcodes.push_back(iterator_pos); Error err = _parse_block(codegen, cf->body, slevel, break_pos, continue_pos); - if (err) + if (err) { return err; + } codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); codegen.opcodes.push_back(continue_pos); @@ -1486,7 +1488,6 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo } break; case GDScriptParser::ControlFlowNode::CF_WHILE: { - codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); codegen.opcodes.push_back(codegen.opcodes.size() + 3); int break_addr = codegen.opcodes.size(); @@ -1495,14 +1496,16 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo int continue_addr = codegen.opcodes.size(); int ret2 = _parse_expression(codegen, cf->arguments[0], p_stack_level, false); - if (ret2 < 0) + if (ret2 < 0) { return ERR_PARSE_ERROR; + } codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT); codegen.opcodes.push_back(ret2); codegen.opcodes.push_back(break_addr); Error err = _parse_block(codegen, cf->body, p_stack_level, break_addr, continue_addr); - if (err) + if (err) { return err; + } codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); codegen.opcodes.push_back(continue_addr); @@ -1510,9 +1513,7 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo } break; case GDScriptParser::ControlFlowNode::CF_BREAK: { - if (p_break_addr < 0) { - _set_error("'break'' not within loop", cf); return ERR_COMPILATION_FAILED; } @@ -1521,9 +1522,7 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo } break; case GDScriptParser::ControlFlowNode::CF_CONTINUE: { - if (p_continue_addr < 0) { - _set_error("'continue' not within loop", cf); return ERR_COMPILATION_FAILED; } @@ -1533,17 +1532,15 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo } break; case GDScriptParser::ControlFlowNode::CF_RETURN: { - int ret2; if (cf->arguments.size()) { - ret2 = _parse_expression(codegen, cf->arguments[0], p_stack_level, false); - if (ret2 < 0) + if (ret2 < 0) { return ERR_PARSE_ERROR; + } } else { - ret2 = GDScriptFunction::ADDR_TYPE_NIL << GDScriptFunction::ADDR_BITS; } @@ -1560,14 +1557,16 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo const GDScriptParser::AssertNode *as = static_cast<const GDScriptParser::AssertNode *>(s); int ret2 = _parse_expression(codegen, as->condition, p_stack_level, false); - if (ret2 < 0) + if (ret2 < 0) { return ERR_PARSE_ERROR; + } int message_ret = 0; if (as->message) { message_ret = _parse_expression(codegen, as->message, p_stack_level + 1, false); - if (message_ret < 0) + if (message_ret < 0) { return ERR_PARSE_ERROR; + } } codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSERT); @@ -1582,7 +1581,6 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo #endif } break; case GDScriptParser::Node::TYPE_LOCAL_VAR: { - const GDScriptParser::LocalVarNode *lv = static_cast<const GDScriptParser::LocalVarNode *>(s); // since we are using properties now for most class access, allow shadowing of class members to make user's life easier. @@ -1600,8 +1598,9 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo default: { //expression int ret2 = _parse_expression(codegen, s, p_stack_level, true); - if (ret2 < 0) + if (ret2 < 0) { return ERR_PARSE_ERROR; + } } break; } } @@ -1610,7 +1609,6 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo } Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::FunctionNode *p_func, bool p_for_ready) { - Vector<int> bytecode; CodeGen codegen; @@ -1651,7 +1649,6 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser if (is_initializer || (p_func && String(p_func->name) == "_init")) { //parse initializer for class members if (!p_func && p_class->extends_used && p_script->native.is_null()) { - //call implicit parent constructor codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_SELF_BASE); codegen.opcodes.push_back(codegen.get_name_map_pos("_init")); @@ -1659,8 +1656,9 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser codegen.opcodes.push_back((GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) | 0); } Error err = _parse_block(codegen, p_class->initializer, stack_level); - if (err) + if (err) { return err; + } is_initializer = true; } @@ -1668,8 +1666,9 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser //parse initializer for class members if (p_class->ready->statements.size()) { Error err = _parse_block(codegen, p_class->ready, stack_level); - if (err) + if (err) { return err; + } } } @@ -1679,13 +1678,10 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser StringName func_name; if (p_func) { - if (p_func->default_values.size()) { - codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_TO_DEF_ARGUMENT); defarg_addr.push_back(codegen.opcodes.size()); for (int i = 0; i < p_func->default_values.size(); i++) { - _parse_expression(codegen, p_func->default_values[i], stack_level, true); defarg_addr.push_back(codegen.opcodes.size()); } @@ -1694,15 +1690,17 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser } Error err = _parse_block(codegen, p_func->body, stack_level); - if (err) + if (err) { return err; + } func_name = p_func->name; } else { - if (p_for_ready) + if (p_for_ready) { func_name = "_ready"; - else + } else { func_name = "_init"; + } } codegen.opcodes.push_back(GDScriptFunction::OPCODE_END); @@ -1747,17 +1745,14 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser gdfunc->constants.write[idx] = *K; } } else { - gdfunc->_constants_ptr = nullptr; gdfunc->_constant_count = 0; } //global names if (codegen.name_map.size()) { - gdfunc->global_names.resize(codegen.name_map.size()); gdfunc->_global_names_ptr = &gdfunc->global_names[0]; for (Map<StringName, int>::Element *E = codegen.name_map.front(); E; E = E->next()) { - gdfunc->global_names.write[E->get()] = E->key(); } gdfunc->_global_names_count = gdfunc->global_names.size(); @@ -1780,19 +1775,16 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser #endif if (codegen.opcodes.size()) { - gdfunc->code = codegen.opcodes; gdfunc->_code_ptr = &gdfunc->code[0]; gdfunc->_code_size = codegen.opcodes.size(); } else { - gdfunc->_code_ptr = nullptr; gdfunc->_code_size = 0; } if (defarg_addr.size()) { - gdfunc->default_arguments = defarg_addr; gdfunc->_default_arg_count = defarg_addr.size() - 1; gdfunc->_default_arg_ptr = &gdfunc->default_arguments[0]; @@ -1809,8 +1801,9 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser if (EngineDebugger::is_active()) { String signature; //path - if (p_script->get_path() != String()) + if (p_script->get_path() != String()) { signature += p_script->get_path(); + } //loc if (p_func) { signature += "::" + itos(p_func->body->line); @@ -1850,17 +1843,18 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser gdfunc->_initial_line = 0; } - if (codegen.debug_stack) + if (codegen.debug_stack) { gdfunc->stack_debug = codegen.stack_debug; + } - if (is_initializer) + if (is_initializer) { p_script->initializer = gdfunc; + } return OK; } Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) { - parsing_classes.insert(p_script); if (p_class->owner && p_class->owner->owner) { @@ -1931,7 +1925,6 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar } for (int i = 0; i < p_class->variables.size(); i++) { - StringName name = p_class->variables[i].identifier; GDScript::MemberInfo minfo; @@ -1946,7 +1939,6 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar PropertyInfo export_info = p_class->variables[i]._export; if (export_info.type != Variant::NIL) { - if (!minfo.data_type.has_type) { prop_info.type = export_info.type; prop_info.class_name = export_info.class_name; @@ -1973,7 +1965,6 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar } for (Map<StringName, GDScriptParser::ClassNode::Constant>::Element *E = p_class->constant_expressions.front(); E; E = E->next()) { - StringName name = E->key(); ERR_CONTINUE(E->get().expression->type != GDScriptParser::Node::TYPE_CONSTANT); @@ -1988,13 +1979,11 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar } for (int i = 0; i < p_class->_signals.size(); i++) { - StringName name = p_class->_signals[i].name; GDScript *c = p_script; while (c) { - if (c->_signals.has(name)) { _set_error("Signal '" + name + "' redefined (in current or parent class)", p_class); return ERR_ALREADY_EXISTS; @@ -2030,8 +2019,9 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar // Subclass might still be parsing, just skip it if (!parsed_classes.has(subclass_ptr) && !parsing_classes.has(subclass_ptr)) { Error err = _parse_class_level(subclass_ptr, p_class->subclasses[i], p_keep_state); - if (err) + if (err) { return err; + } } #ifdef TOOLS_ENABLED @@ -2052,37 +2042,41 @@ Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptPa bool has_ready = false; for (int i = 0; i < p_class->functions.size(); i++) { - - if (!has_initializer && p_class->functions[i]->name == "_init") + if (!has_initializer && p_class->functions[i]->name == "_init") { has_initializer = true; - if (!has_ready && p_class->functions[i]->name == "_ready") + } + if (!has_ready && p_class->functions[i]->name == "_ready") { has_ready = true; + } Error err = _parse_function(p_script, p_class, p_class->functions[i]); - if (err) + if (err) { return err; + } } //parse static methods for (int i = 0; i < p_class->static_functions.size(); i++) { - Error err = _parse_function(p_script, p_class, p_class->static_functions[i]); - if (err) + if (err) { return err; + } } if (!has_initializer) { //create a constructor Error err = _parse_function(p_script, p_class, nullptr); - if (err) + if (err) { return err; + } } if (!has_ready && p_class->ready->statements.size()) { //create a constructor Error err = _parse_function(p_script, p_class, nullptr, true); - if (err) + if (err) { return err; + } } #ifdef DEBUG_ENABLED @@ -2091,7 +2085,6 @@ Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptPa if (p_keep_state) { for (Set<Object *>::Element *E = p_script->instances.front(); E;) { - Set<Object *>::Element *N = E->next(); ScriptInstance *si = E->get()->get_script_instance(); @@ -2126,7 +2119,6 @@ Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptPa } #endif } else { - GDScriptInstance *gi = static_cast<GDScriptInstance *>(si); gi->reload_members(); } @@ -2151,7 +2143,6 @@ Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptPa } void GDScriptCompiler::_make_scripts(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) { - Map<StringName, Ref<GDScript>> old_subclasses; if (p_keep_state) { @@ -2186,7 +2177,6 @@ void GDScriptCompiler::_make_scripts(GDScript *p_script, const GDScriptParser::C } Error GDScriptCompiler::compile(const GDScriptParser *p_parser, GDScript *p_script, bool p_keep_state) { - err_line = -1; err_column = -1; error = ""; @@ -2206,27 +2196,28 @@ Error GDScriptCompiler::compile(const GDScriptParser *p_parser, GDScript *p_scri p_script->_owner = nullptr; Error err = _parse_class_level(p_script, static_cast<const GDScriptParser::ClassNode *>(root), p_keep_state); - if (err) + if (err) { return err; + } err = _parse_class_blocks(p_script, static_cast<const GDScriptParser::ClassNode *>(root), p_keep_state); - if (err) + if (err) { return err; + } return OK; } String GDScriptCompiler::get_error() const { - return error; } -int GDScriptCompiler::get_error_line() const { +int GDScriptCompiler::get_error_line() const { return err_line; } -int GDScriptCompiler::get_error_column() const { +int GDScriptCompiler::get_error_column() const { return err_column; } diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h index 08e1ec74af..315d4f1842 100644 --- a/modules/gdscript/gdscript_compiler.h +++ b/modules/gdscript/gdscript_compiler.h @@ -36,13 +36,11 @@ #include "gdscript_parser.h" class GDScriptCompiler { - const GDScriptParser *parser; Set<GDScript *> parsed_classes; Set<GDScript *> parsing_classes; GDScript *main_script; struct CodeGen { - GDScript *script; const GDScriptParser::ClassNode *class_node; const GDScriptParser::FunctionNode *function_node; @@ -71,7 +69,6 @@ class GDScriptCompiler { void push_stack_identifiers() { stack_id_stack.push_back(stack_identifiers); if (debug_stack) { - block_identifier_stack.push_back(block_identifiers); block_identifiers.clear(); } @@ -83,7 +80,6 @@ class GDScriptCompiler { if (debug_stack) { for (Map<StringName, int>::Element *E = block_identifiers.front(); E; E = E->next()) { - GDScriptFunction::StackDebug sd; sd.added = false; sd.identifier = E->key(); @@ -114,8 +110,9 @@ class GDScriptCompiler { } int get_constant_pos(const Variant &p_constant) { - if (constant_map.has(p_constant)) + if (constant_map.has(p_constant)) { return constant_map[p_constant]; + } int pos = constant_map.size(); constant_map[p_constant] = pos; return pos; @@ -123,12 +120,14 @@ class GDScriptCompiler { Vector<int> opcodes; void alloc_stack(int p_level) { - if (p_level >= stack_max) + if (p_level >= stack_max) { stack_max = p_level + 1; + } } void alloc_call(int p_params) { - if (p_params >= call_max) + if (p_params >= call_max) { call_max = p_params; + } } int current_line; diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 56381e8af7..7433c4a5bc 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -41,19 +41,16 @@ #endif void GDScriptLanguage::get_comment_delimiters(List<String> *p_delimiters) const { - p_delimiters->push_back("#"); } void GDScriptLanguage::get_string_delimiters(List<String> *p_delimiters) const { - p_delimiters->push_back("\" \""); p_delimiters->push_back("' '"); p_delimiters->push_back("\"\"\" \"\"\""); } String GDScriptLanguage::_get_processed_template(const String &p_template, const String &p_base_class_name) const { - String processed_template = p_template; #ifdef TOOLS_ENABLED @@ -109,18 +106,15 @@ Ref<Script> GDScriptLanguage::get_template(const String &p_class_name, const Str } bool GDScriptLanguage::is_using_templates() { - return true; } void GDScriptLanguage::make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) { - String _template = _get_processed_template(p_script->get_source_code(), p_base_class_name); p_script->set_source_code(_template); } 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 { - GDScriptParser parser; Error err = parser.parse(p_script, p_path.get_base_dir(), true, p_path, false, r_safe_lines); @@ -143,35 +137,29 @@ bool GDScriptLanguage::validate(const String &p_script, int &r_line_error, int & r_test_error = parser.get_error(); return false; } else { - const GDScriptParser::Node *root = parser.get_parse_tree(); ERR_FAIL_COND_V(root->type != GDScriptParser::Node::TYPE_CLASS, false); const GDScriptParser::ClassNode *cl = static_cast<const GDScriptParser::ClassNode *>(root); Map<int, String> funcs; for (int i = 0; i < cl->functions.size(); i++) { - funcs[cl->functions[i]->line] = cl->functions[i]->name; } for (int i = 0; i < cl->static_functions.size(); i++) { - funcs[cl->static_functions[i]->line] = cl->static_functions[i]->name; } for (int i = 0; i < cl->subclasses.size(); i++) { for (int j = 0; j < cl->subclasses[i]->functions.size(); j++) { - funcs[cl->subclasses[i]->functions[j]->line] = String(cl->subclasses[i]->name) + "." + cl->subclasses[i]->functions[j]->name; } for (int j = 0; j < cl->subclasses[i]->static_functions.size(); j++) { - funcs[cl->subclasses[i]->static_functions[j]->line] = String(cl->subclasses[i]->name) + "." + cl->subclasses[i]->static_functions[j]->name; } } for (Map<int, String>::Element *E = funcs.front(); E; E = E->next()) { - r_functions->push_back(E->get() + ":" + itos(E->key())); } } @@ -180,27 +168,22 @@ bool GDScriptLanguage::validate(const String &p_script, int &r_line_error, int & } bool GDScriptLanguage::has_named_classes() const { - return false; } bool GDScriptLanguage::supports_builtin_mode() const { - return true; } int GDScriptLanguage::find_function(const String &p_function, const String &p_code) const { - GDScriptTokenizerText tokenizer; tokenizer.set_code(p_code); int indent = 0; while (tokenizer.get_token() != GDScriptTokenizer::TK_EOF && tokenizer.get_token() != GDScriptTokenizer::TK_ERROR) { - if (tokenizer.get_token() == GDScriptTokenizer::TK_NEWLINE) { indent = tokenizer.get_token_line_indent(); } if (indent == 0 && tokenizer.get_token() == GDScriptTokenizer::TK_PR_FUNCTION && tokenizer.get_token(1) == GDScriptTokenizer::TK_IDENTIFIER) { - String identifier = tokenizer.get_token_identifier(1); if (identifier == p_function) { return tokenizer.get_token_line(); @@ -212,7 +195,6 @@ int GDScriptLanguage::find_function(const String &p_function, const String &p_co } Script *GDScriptLanguage::create_script() const { - return memnew(GDScript); } @@ -222,7 +204,6 @@ bool GDScriptLanguage::debug_break_parse(const String &p_file, int p_line, const //break because of parse error if (EngineDebugger::is_active() && Thread::get_caller_id() == Thread::get_main_id()) { - _debug_parse_err_line = p_line; _debug_parse_err_file = p_file; _debug_error = p_error; @@ -234,9 +215,7 @@ bool GDScriptLanguage::debug_break_parse(const String &p_file, int p_line, const } bool GDScriptLanguage::debug_break(const String &p_error, bool p_allow_continue) { - if (EngineDebugger::is_active() && Thread::get_caller_id() == Thread::get_main_id()) { - _debug_parse_err_line = -1; _debug_parse_err_file = ""; _debug_error = p_error; @@ -249,21 +228,21 @@ bool GDScriptLanguage::debug_break(const String &p_error, bool p_allow_continue) } String GDScriptLanguage::debug_get_error() const { - return _debug_error; } int GDScriptLanguage::debug_get_stack_level_count() const { - - if (_debug_parse_err_line >= 0) + if (_debug_parse_err_line >= 0) { return 1; + } return _debug_call_stack_pos; } -int GDScriptLanguage::debug_get_stack_level_line(int p_level) const { - if (_debug_parse_err_line >= 0) +int GDScriptLanguage::debug_get_stack_level_line(int p_level) const { + if (_debug_parse_err_line >= 0) { return _debug_parse_err_line; + } ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, -1); @@ -271,28 +250,31 @@ int GDScriptLanguage::debug_get_stack_level_line(int p_level) const { return *(_call_stack[l].line); } -String GDScriptLanguage::debug_get_stack_level_function(int p_level) const { - if (_debug_parse_err_line >= 0) +String GDScriptLanguage::debug_get_stack_level_function(int p_level) const { + if (_debug_parse_err_line >= 0) { return ""; + } ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, ""); int l = _debug_call_stack_pos - p_level - 1; return _call_stack[l].function->get_name(); } -String GDScriptLanguage::debug_get_stack_level_source(int p_level) const { - if (_debug_parse_err_line >= 0) +String GDScriptLanguage::debug_get_stack_level_source(int p_level) const { + if (_debug_parse_err_line >= 0) { return _debug_parse_err_file; + } ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, ""); int l = _debug_call_stack_pos - p_level - 1; return _call_stack[l].function->get_source(); } -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) { - if (_debug_parse_err_line >= 0) +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) { + if (_debug_parse_err_line >= 0) { return; + } ERR_FAIL_INDEX(p_level, _debug_call_stack_pos); int l = _debug_call_stack_pos - p_level - 1; @@ -303,23 +285,24 @@ void GDScriptLanguage::debug_get_stack_level_locals(int p_level, List<String> *p f->debug_get_stack_member_state(*_call_stack[l].line, &locals); for (List<Pair<StringName, int>>::Element *E = locals.front(); E; E = E->next()) { - p_locals->push_back(E->get().first); p_values->push_back(_call_stack[l].stack[E->get().second]); } } -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) { - if (_debug_parse_err_line >= 0) +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) { + if (_debug_parse_err_line >= 0) { return; + } ERR_FAIL_INDEX(p_level, _debug_call_stack_pos); int l = _debug_call_stack_pos - p_level - 1; GDScriptInstance *instance = _call_stack[l].instance; - if (!instance) + if (!instance) { return; + } Ref<GDScript> script = instance->get_script(); ERR_FAIL_COND(script.is_null()); @@ -327,16 +310,15 @@ void GDScriptLanguage::debug_get_stack_level_members(int p_level, List<String> * const Map<StringName, GDScript::MemberInfo> &mi = script->debug_get_member_indices(); for (const Map<StringName, GDScript::MemberInfo>::Element *E = mi.front(); E; E = E->next()) { - p_members->push_back(E->key()); p_values->push_back(instance->debug_get_member_by_index(E->get().index)); } } ScriptInstance *GDScriptLanguage::debug_get_stack_level_instance(int p_level) { - - if (_debug_parse_err_line >= 0) + if (_debug_parse_err_line >= 0) { return nullptr; + } ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, nullptr); @@ -347,7 +329,6 @@ ScriptInstance *GDScriptLanguage::debug_get_stack_level_instance(int p_level) { } void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) { - const Map<StringName, int> &name_idx = GDScriptLanguage::get_singleton()->get_global_map(); const Variant *globals = GDScriptLanguage::get_singleton()->get_global_array(); @@ -355,9 +336,9 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant> get_public_constants(&cinfo); for (const Map<StringName, int>::Element *E = name_idx.front(); E; E = E->next()) { - - if (ClassDB::class_exists(E->key()) || Engine::get_singleton()->has_singleton(E->key())) + if (ClassDB::class_exists(E->key()) || Engine::get_singleton()->has_singleton(E->key())) { continue; + } bool is_script_constant = false; for (List<Pair<String, Variant>>::Element *CE = cinfo.front(); CE; CE = CE->next()) { @@ -366,13 +347,15 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant> break; } } - if (is_script_constant) + if (is_script_constant) { continue; + } const Variant &var = globals[E->value()]; if (Object *obj = var) { - if (Object::cast_to<GDScriptNativeClass>(obj)) + if (Object::cast_to<GDScriptNativeClass>(obj)) { continue; + } } bool skip = false; @@ -382,8 +365,9 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant> break; } } - if (skip) + if (skip) { continue; + } p_globals->push_back(E->key()); p_values->push_back(var); @@ -391,19 +375,15 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant> } String GDScriptLanguage::debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) { - return ""; } void GDScriptLanguage::get_recognized_extensions(List<String> *p_extensions) const { - p_extensions->push_back("gd"); } void GDScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const { - for (int i = 0; i < GDScriptFunctions::FUNC_MAX; i++) { - p_functions->push_back(GDScriptFunctions::get_info(GDScriptFunctions::Function(i))); } @@ -437,7 +417,6 @@ void GDScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const } void GDScriptLanguage::get_public_constants(List<Pair<String, Variant>> *p_constants) const { - Pair<String, Variant> pi; pi.first = "PI"; pi.second = Math_PI; @@ -460,7 +439,6 @@ void GDScriptLanguage::get_public_constants(List<Pair<String, Variant>> *p_const } String GDScriptLanguage::make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const { - #ifdef TOOLS_ENABLED bool th = EditorSettings::get_singleton()->get_setting("text_editor/completion/add_type_hints"); #else @@ -470,8 +448,9 @@ String GDScriptLanguage::make_function(const String &p_class, const String &p_na String s = "func " + p_name + "("; if (p_args.size()) { for (int i = 0; i < p_args.size(); i++) { - if (i > 0) + if (i > 0) { s += ", "; + } s += p_args[i].get_slice(":", 0); if (th) { String type = p_args[i].get_slice(":", 1); @@ -491,7 +470,6 @@ String GDScriptLanguage::make_function(const String &p_class, const String &p_na #if defined(DEBUG_METHODS_ENABLED) && defined(TOOLS_ENABLED) struct GDScriptCompletionContext { - const GDScriptParser::ClassNode *_class = nullptr; const GDScriptParser::FunctionNode *function = nullptr; const GDScriptParser::BlockNode *block = nullptr; @@ -513,7 +491,6 @@ struct GDScriptCompletionIdentifier { }; static void _get_directory_contents(EditorFileSystemDirectory *p_dir, Map<String, ScriptCodeCompletionOption> &r_list) { - const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; for (int i = 0; i < p_dir->get_file_count(); i++) { @@ -528,7 +505,6 @@ static void _get_directory_contents(EditorFileSystemDirectory *p_dir, Map<String } static String _get_visual_datatype(const PropertyInfo &p_info, bool p_isarg = true) { - if (p_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { String enum_name = p_info.class_name; if (enum_name.find(".") == -1) { @@ -828,7 +804,6 @@ static bool _guess_expression_type(GDScriptCompletionContext &p_context, const G Object *baseptr = base.value; if (all_is_const && String(id) == "get_node" && ClassDB::is_parent_class(native_type.native_type, "Node") && args.size()) { - String arg1 = args[0]; if (arg1.begins_with("/root/")) { String which = arg1.get_slice("/", 2); @@ -842,7 +817,6 @@ static bool _guess_expression_type(GDScriptCompletionContext &p_context, const G ProjectSettings::get_singleton()->get_property_list(&props); for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - String s = E->get().name; if (!s.begins_with("autoload/")) { continue; @@ -1184,7 +1158,6 @@ static bool _guess_expression_type(GDScriptCompletionContext &p_context, const G } static bool _guess_identifier_type(GDScriptCompletionContext &p_context, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type) { - // Look in blocks first const GDScriptParser::BlockNode *blk = p_context.block; int last_assign_line = -1; @@ -1746,7 +1719,6 @@ static bool _guess_method_return_type_from_base(GDScriptCompletionContext &p_con } static String _make_arguments_hint(const MethodInfo &p_info, int p_arg_idx) { - String arghint = _get_visual_datatype(p_info.return_val, false) + " " + p_info.name + "("; int def_args = p_info.arguments.size() - p_info.default_arguments.size(); @@ -1791,7 +1763,6 @@ static String _make_arguments_hint(const MethodInfo &p_info, int p_arg_idx) { } static String _make_arguments_hint(const GDScriptParser::FunctionNode *p_function, int p_arg_idx) { - String arghint = p_function->return_type.to_string() + " " + p_function->name.operator String() + "("; int def_args = p_function->arguments.size() - p_function->default_values.size(); @@ -1833,7 +1804,6 @@ static String _make_arguments_hint(const GDScriptParser::FunctionNode *p_functio } static void _find_enumeration_candidates(const String p_enum_hint, Map<String, ScriptCodeCompletionOption> &r_result) { - if (p_enum_hint.find(".") == -1) { // Global constant StringName current_enum = p_enum_hint; @@ -2144,11 +2114,9 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context } static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p_only_functions, Map<String, ScriptCodeCompletionOption> &r_result) { - const GDScriptParser::BlockNode *block = p_context.block; if (p_context.function) { - const GDScriptParser::FunctionNode *f = p_context.function; for (int i = 0; i < f->arguments.size(); i++) { @@ -2417,7 +2385,6 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con } 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) { - const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; if (!p_node || p_node->type != GDScriptParser::Node::TYPE_OPERATOR) { @@ -2473,7 +2440,6 @@ static void _find_call_arguments(GDScriptCompletionContext &p_context, const GDS } return; } else if (op->arguments[0]->type == GDScriptParser::Node::TYPE_SELF) { - if (op->arguments.size() < 2 || op->arguments[1]->type != GDScriptParser::Node::TYPE_IDENTIFIER) { return; } @@ -2547,7 +2513,6 @@ static void _find_call_arguments(GDScriptCompletionContext &p_context, const GDS } 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) { - const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; GDScriptParser parser; @@ -2595,7 +2560,6 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path p_owner->get_argument_options("get_node", 0, &opts); for (List<String>::Element *E = opts.front(); E; E = E->next()) { - String opt = E->get().strip_edges(); if (opt.is_quoted()) { r_forced = true; @@ -2703,7 +2667,6 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path List<MethodInfo> virtual_methods; ClassDB::get_virtual_methods(class_name, &virtual_methods); for (List<MethodInfo>::Element *E = virtual_methods.front(); E; E = E->next()) { - MethodInfo &mi = E->get(); String method_hint = mi.name; if (method_hint.find(":") != -1) { @@ -3027,19 +2990,16 @@ String GDScriptLanguage::_get_indentation() const { } void GDScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_to_line) const { - String indent = _get_indentation(); Vector<String> lines = p_code.split("\n"); List<int> indent_stack; for (int i = 0; i < lines.size(); i++) { - String l = lines[i]; int tc = 0; for (int j = 0; j < l.length(); j++) { if (l[j] == ' ' || l[j] == '\t') { - tc++; } else { break; @@ -3047,8 +3007,9 @@ void GDScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_t } String st = l.substr(tc, l.length()).strip_edges(); - if (st == "" || st.begins_with("#")) + if (st == "" || st.begins_with("#")) { continue; //ignore! + } int ilevel = 0; if (indent_stack.size()) { @@ -3062,12 +3023,12 @@ void GDScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_t indent_stack.pop_back(); } - if (indent_stack.size() && indent_stack.back()->get() != tc) + if (indent_stack.size() && indent_stack.back()->get() != tc) { indent_stack.push_back(tc); //this is not right but gets the job done + } } if (i >= p_from_line) { - l = ""; for (int j = 0; j < indent_stack.size(); j++) { l += indent; @@ -3083,8 +3044,9 @@ void GDScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_t p_code = ""; for (int i = 0; i < lines.size(); i++) { - if (i > 0) + if (i > 0) { p_code += "\n"; + } p_code += lines[i]; } } @@ -3271,7 +3233,6 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co } Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result) { - //before parsing, try the usual stuff if (ClassDB::class_exists(p_symbol)) { r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS; @@ -3352,7 +3313,6 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol [[fallthrough]]; } case GDScriptParser::COMPLETION_IDENTIFIER: { - if (!is_function) { is_function = parser.get_completion_identifier_is_function(); } @@ -3404,13 +3364,12 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol ProjectSettings::get_singleton()->get_property_list(&props); for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - String s = E->get().name; - if (!s.begins_with("autoload/")) + if (!s.begins_with("autoload/")) { continue; + } String name = s.get_slice("/", 1); if (name == String(p_symbol)) { - String path = ProjectSettings::get_singleton()->get(s); if (path.begins_with("*")) { String script = path.substr(1, path.length()); @@ -3422,7 +3381,6 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol } if (FileAccess::exists(script)) { - r_result.type = ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION; r_result.location = 0; r_result.script = ResourceLoader::load(script); @@ -3505,7 +3463,6 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol } } break; case GDScriptParser::COMPLETION_TYPE_HINT: { - GDScriptParser::DataType base_type = context._class->base_type; base_type.has_type = true; base_type.kind = GDScriptParser::DataType::CLASS; diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index 4e31ffe2a4..92e07ab874 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -35,12 +35,10 @@ #include "gdscript_functions.h" Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant &static_ref, Variant *p_stack, String &r_error) const { - int address = p_address & ADDR_MASK; //sequential table (jump table generated by compiler) switch ((p_address & ADDR_TYPE_MASK) >> ADDR_BITS) { - case ADDR_TYPE_SELF: { #ifdef DEBUG_ENABLED if (unlikely(!p_instance)) { @@ -51,7 +49,6 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta return &self; } break; case ADDR_TYPE_CLASS: { - return &static_ref; } break; case ADDR_TYPE_MEMBER: { @@ -65,7 +62,6 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta return &p_instance->members.write[address]; } break; case ADDR_TYPE_CLASS_CONSTANT: { - //todo change to index! GDScript *s = p_script; #ifdef DEBUG_ENABLED @@ -76,7 +72,6 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta while (s) { GDScript *o = s; while (o) { - Map<StringName, Variant>::Element *E = o->constants.find(*sn); if (E) { return &E->get(); @@ -133,7 +128,6 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta #ifdef DEBUG_ENABLED static String _get_var_type(const Variant *p_var) { - String basestr; if (p_var->get_type() == Variant::OBJECT) { @@ -146,10 +140,11 @@ static String _get_var_type(const Variant *p_var) { basestr = "previously freed"; } } else { - if (bobj->get_script_instance()) + if (bobj->get_script_instance()) { basestr = bobj->get_class() + " (" + bobj->get_script_instance()->get_script()->get_path().get_file() + ")"; - else + } else { basestr = bobj->get_class(); + } } } else { @@ -161,7 +156,6 @@ static String _get_var_type(const Variant *p_var) { #endif // DEBUG_ENABLED String GDScriptFunction::_get_call_error(const Callable::CallError &p_err, const String &p_where, const Variant **argptrs) const { - String err_text; if (p_err.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) { @@ -259,11 +253,9 @@ String GDScriptFunction::_get_call_error(const Callable::CallError &p_err, const #endif Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_args, int p_argcount, Callable::CallError &r_err, CallState *p_state) { - OPCODES_TABLE; if (!_code_ptr) { - return Variant(); } @@ -300,22 +292,17 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a self = p_state->self; } else { - if (p_argcount != _argument_count) { - if (p_argcount > _argument_count) { - r_err.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; r_err.argument = _argument_count; return Variant(); } else if (p_argcount < _argument_count - _default_arg_count) { - r_err.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_err.argument = _argument_count - _default_arg_count; return Variant(); } else { - defarg = _argument_count - p_argcount; } } @@ -323,11 +310,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a alloca_size = sizeof(Variant *) * _call_size + sizeof(Variant) * _stack_size; if (alloca_size) { - uint8_t *aptr = (uint8_t *)alloca(alloca_size); if (_stack_size) { - stack = (Variant *)aptr; for (int i = 0; i < p_argcount; i++) { if (!argument_types[i].has_type) { @@ -356,10 +341,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } if (_call_size) { - call_args = (Variant **)&aptr[sizeof(Variant) * _stack_size]; } else { - call_args = nullptr; } @@ -370,7 +353,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a if (p_instance) { if (p_instance->base_ref && static_cast<Reference *>(p_instance->owner)->is_referenced()) { - self = REF(static_cast<Reference *>(p_instance->owner)); } else { self = p_instance->owner; @@ -385,8 +367,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #ifdef DEBUG_ENABLED - if (EngineDebugger::is_active()) + if (EngineDebugger::is_active()) { GDScriptLanguage::get_singleton()->enter_function(p_instance, this, stack, &ip, &line); + } #define GD_ERR_BREAK(m_cond) \ { \ @@ -437,9 +420,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #endif OPCODE_SWITCH(_code_ptr[ip]) { - OPCODE(OPCODE_OPERATOR) { - CHECK_SPACE(5); bool valid; @@ -459,7 +440,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #endif #ifdef DEBUG_ENABLED if (!valid) { - if (ret.get_type() == Variant::STRING) { //return a string when invalid with the error err_text = ret; @@ -476,7 +456,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_EXTENDS_TEST) { - CHECK_SPACE(4); GET_VARIANT_PTR(a, 1); @@ -485,7 +464,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #ifdef DEBUG_ENABLED if (b->get_type() != Variant::OBJECT || b->operator Object *() == nullptr) { - err_text = "Right operand of 'is' is not a class."; OPCODE_BREAK; } @@ -493,7 +471,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a bool extends_ok = false; if (a->get_type() == Variant::OBJECT && a->operator Object *() != nullptr) { - #ifdef DEBUG_ENABLED bool was_freed; Object *obj_A = a->get_validated_object_with_check(was_freed); @@ -522,11 +499,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a //in other situation, this shoul return false. if (obj_A->get_script_instance() && obj_A->get_script_instance()->get_language() == GDScriptLanguage::get_singleton()) { - GDScript *cmp = static_cast<GDScript *>(obj_A->get_script_instance()->get_script().ptr()); //bool found=false; while (cmp) { - if (cmp == scr_B) { //inherits from script, all ok extends_ok = true; @@ -538,12 +513,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } } else { - GDScriptNativeClass *nc = Object::cast_to<GDScriptNativeClass>(obj_B); #ifdef DEBUG_ENABLED if (!nc) { - err_text = "Right operand of 'is' is not a class (type: '" + obj_B->get_class() + "')."; OPCODE_BREAK; } @@ -558,7 +531,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_IS_BUILTIN) { - CHECK_SPACE(4); GET_VARIANT_PTR(value, 1); @@ -573,7 +545,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_SET) { - CHECK_SPACE(3); GET_VARIANT_PTR(dst, 1); @@ -600,7 +571,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_GET) { - CHECK_SPACE(3); GET_VARIANT_PTR(src, 1); @@ -633,7 +603,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_SET_NAMED) { - CHECK_SPACE(3); GET_VARIANT_PTR(dst, 1); @@ -659,7 +628,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_GET_NAMED) { - CHECK_SPACE(4); GET_VARIANT_PTR(src, 1); @@ -694,7 +662,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_SET_MEMBER) { - CHECK_SPACE(3); int indexname = _code_ptr[ip + 1]; GD_ERR_BREAK(indexname < 0 || indexname >= _global_names_count); @@ -719,7 +686,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_GET_MEMBER) { - CHECK_SPACE(3); int indexname = _code_ptr[ip + 1]; GD_ERR_BREAK(indexname < 0 || indexname >= _global_names_count); @@ -740,7 +706,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_ASSIGN) { - CHECK_SPACE(3); GET_VARIANT_PTR(dst, 1); GET_VARIANT_PTR(src, 2); @@ -752,7 +717,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_ASSIGN_TRUE) { - CHECK_SPACE(2); GET_VARIANT_PTR(dst, 1); @@ -763,7 +727,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_ASSIGN_FALSE) { - CHECK_SPACE(2); GET_VARIANT_PTR(dst, 1); @@ -774,7 +737,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_ASSIGN_TYPED_BUILTIN) { - CHECK_SPACE(4); GET_VARIANT_PTR(dst, 2); GET_VARIANT_PTR(src, 3); @@ -804,7 +766,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_ASSIGN_TYPED_NATIVE) { - CHECK_SPACE(4); GET_VARIANT_PTR(dst, 2); GET_VARIANT_PTR(src, 3); @@ -833,7 +794,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_ASSIGN_TYPED_SCRIPT) { - CHECK_SPACE(4); GET_VARIANT_PTR(dst, 2); GET_VARIANT_PTR(src, 3); @@ -850,7 +810,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } if (src->get_type() != Variant::NIL && src->operator Object *() != nullptr) { - ScriptInstance *scr_inst = src->operator Object *()->get_script_instance(); if (!scr_inst) { err_text = "Trying to assign value of type '" + src->operator Object *()->get_class_name() + @@ -884,7 +843,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_CAST_TO_BUILTIN) { - CHECK_SPACE(4); Variant::Type to_type = (Variant::Type)_code_ptr[ip + 1]; GET_VARIANT_PTR(src, 2); @@ -907,7 +865,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_CAST_TO_NATIVE) { - CHECK_SPACE(4); GET_VARIANT_PTR(to_type, 1); GET_VARIANT_PTR(src, 2); @@ -935,7 +892,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_CAST_TO_SCRIPT) { - CHECK_SPACE(4); GET_VARIANT_PTR(to_type, 1); GET_VARIANT_PTR(src, 2); @@ -955,11 +911,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a bool valid = false; if (src->get_type() != Variant::NIL && src->operator Object *() != nullptr) { - ScriptInstance *scr_inst = src->operator Object *()->get_script_instance(); if (scr_inst) { - Script *src_type = src->operator Object *()->get_script_instance()->get_script().ptr(); while (src_type) { @@ -983,7 +937,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_CONSTRUCT) { - CHECK_SPACE(2); Variant::Type t = Variant::Type(_code_ptr[ip + 1]); int argc = _code_ptr[ip + 2]; @@ -1000,7 +953,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #ifdef DEBUG_ENABLED if (err.error != Callable::CallError::CALL_OK) { - err_text = _get_call_error(err, "'" + Variant::get_type_name(t) + "' constructor", (const Variant **)argptrs); OPCODE_BREAK; } @@ -1012,7 +964,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_CONSTRUCT_ARRAY) { - CHECK_SPACE(1); int argc = _code_ptr[ip + 1]; Array array; //arrays are always shared @@ -1033,7 +984,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_CONSTRUCT_DICTIONARY) { - CHECK_SPACE(1); int argc = _code_ptr[ip + 1]; Dictionary dict; //arrays are always shared @@ -1041,7 +991,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a CHECK_SPACE(argc * 2 + 2); for (int i = 0; i < argc; i++) { - GET_VARIANT_PTR(k, 2 + i * 2 + 0); GET_VARIANT_PTR(v, 2 + i * 2 + 1); dict[*k] = *v; @@ -1057,7 +1006,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_CALL_RETURN) OPCODE(OPCODE_CALL) { - CHECK_SPACE(4); bool call_ret = _code_ptr[ip] == OPCODE_CALL_RETURN; @@ -1088,11 +1036,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #endif Callable::CallError err; if (call_ret) { - GET_VARIANT_PTR(ret, argc); base->call_ptr(*methodname, (const Variant **)argptrs, argc, ret, err); } else { - base->call_ptr(*methodname, (const Variant **)argptrs, argc, nullptr, err); } #ifdef DEBUG_ENABLED @@ -1101,7 +1047,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } if (err.error != Callable::CallError::CALL_OK) { - String methodstr = *methodname; String basestr = _get_var_type(base); @@ -1113,14 +1058,11 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } } } else if (methodstr == "free") { - if (err.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) { - if (base->is_ref()) { err_text = "Attempted to free a reference."; OPCODE_BREAK; } else if (base->get_type() == Variant::OBJECT) { - err_text = "Attempted to free a locked object (calling or emitting)."; OPCODE_BREAK; } @@ -1137,7 +1079,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_CALL_BUILT_IN) { - CHECK_SPACE(4); GDScriptFunctions::Function func = GDScriptFunctions::Function(_code_ptr[ip + 1]); @@ -1161,7 +1102,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #ifdef DEBUG_ENABLED if (err.error != Callable::CallError::CALL_OK) { - String methodstr = GDScriptFunctions::get_func_name(func); if (dst->get_type() == Variant::STRING) { //call provided error string @@ -1177,18 +1117,15 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_CALL_SELF) { - OPCODE_BREAK; } OPCODE(OPCODE_CALL_SELF_BASE) { - CHECK_SPACE(2); int self_fun = _code_ptr[ip + 1]; #ifdef DEBUG_ENABLED if (self_fun < 0 || self_fun >= _global_names_count) { - err_text = "compiler bug, function name not found"; OPCODE_BREAK; } @@ -1214,19 +1151,17 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a while (gds->base.ptr()) { gds = gds->base.ptr(); E = gds->member_functions.find(*methodname); - if (E) + if (E) { break; + } } Callable::CallError err; if (E) { - *dst = E->get()->call(p_instance, (const Variant **)argptrs, argc, err); } else if (gds->native.ptr()) { - if (*methodname != GDScriptLanguage::get_singleton()->strings._init) { - MethodBind *mb = ClassDB::get_method(gds->native->get_name(), *methodname); if (!mb) { err.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; @@ -1237,7 +1172,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a err.error = Callable::CallError::CALL_OK; } } else { - if (*methodname != GDScriptLanguage::get_singleton()->strings._init) { err.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; } else { @@ -1246,7 +1180,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } if (err.error != Callable::CallError::CALL_OK) { - String methodstr = *methodname; err_text = _get_call_error(err, "function '" + methodstr + "'", (const Variant **)argptrs); @@ -1259,7 +1192,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE(OPCODE_YIELD) OPCODE(OPCODE_YIELD_SIGNAL) { - int ipofs = 1; if (_code_ptr[ip] == OPCODE_YIELD_SIGNAL) { CHECK_SPACE(4); @@ -1332,7 +1264,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE_BREAK; } if (signal.length() == 0) { - err_text = "Second argument of yield() is an empty string (for signal name)."; OPCODE_BREAK; } @@ -1358,7 +1289,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } OPCODE(OPCODE_YIELD_RESUME) { - CHECK_SPACE(2); #ifdef DEBUG_ENABLED if (!p_state) { @@ -1373,7 +1303,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_JUMP) { - CHECK_SPACE(2); int to = _code_ptr[ip + 1]; @@ -1383,7 +1312,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_JUMP_IF) { - CHECK_SPACE(3); GET_VARIANT_PTR(test, 1); @@ -1401,7 +1329,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_JUMP_IF_NOT) { - CHECK_SPACE(3); GET_VARIANT_PTR(test, 1); @@ -1419,14 +1346,12 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_JUMP_TO_DEF_ARGUMENT) { - CHECK_SPACE(2); ip = _default_arg_ptr[defarg]; } DISPATCH_OPCODE; OPCODE(OPCODE_RETURN) { - CHECK_SPACE(2); GET_VARIANT_PTR(r, 1); retvalue = *r; @@ -1437,7 +1362,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } OPCODE(OPCODE_ITERATE_BEGIN) { - CHECK_SPACE(8); //space for this a regular iterate GET_VARIANT_PTR(counter, 1); @@ -1470,7 +1394,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a DISPATCH_OPCODE; OPCODE(OPCODE_ITERATE) { - CHECK_SPACE(4); GET_VARIANT_PTR(counter, 1); @@ -1546,15 +1469,17 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a bool do_break = false; if (EngineDebugger::get_script_debugger()->get_lines_left() > 0) { - - if (EngineDebugger::get_script_debugger()->get_depth() <= 0) + if (EngineDebugger::get_script_debugger()->get_depth() <= 0) { EngineDebugger::get_script_debugger()->set_lines_left(EngineDebugger::get_script_debugger()->get_lines_left() - 1); - if (EngineDebugger::get_script_debugger()->get_lines_left() <= 0) + } + if (EngineDebugger::get_script_debugger()->get_lines_left() <= 0) { do_break = true; + } } - if (EngineDebugger::get_script_debugger()->is_breakpoint(line, source)) + if (EngineDebugger::get_script_debugger()->is_breakpoint(line, source)) { do_break = true; + } if (do_break) { GDScriptLanguage::get_singleton()->debug_break("Breakpoint", true); @@ -1582,20 +1507,24 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODES_END #ifdef DEBUG_ENABLED - if (exit_ok) + if (exit_ok) { OPCODE_OUT; + } //error // function, file, line, error, explanation String err_file; - if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && p_instance->script->path != "") + if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && p_instance->script->path != "") { err_file = p_instance->script->path; - else if (script) + } else if (script) { err_file = script->path; - if (err_file == "") + } + if (err_file == "") { err_file = "<built-in>"; + } String err_func = name; - if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && p_instance->script->name != "") + if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && p_instance->script->name != "") { err_func = p_instance->script->name + "." + err_func; + } int err_line = line; if (err_text == "") { err_text = "Internal Script Error! - opcode #" + itos(last_opcode) + " (report please)."; @@ -1627,14 +1556,16 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a // When it's the last resume it will postpone the exit from stack, // so the debugger knows which function triggered the resume of the next function (if any) if (!p_state || yielded) { - if (EngineDebugger::is_active()) + if (EngineDebugger::is_active()) { GDScriptLanguage::get_singleton()->exit_function(); + } #endif if (_stack_size) { //free stack - for (int i = 0; i < _stack_size; i++) + for (int i = 0; i < _stack_size; i++) { stack[i].~Variant(); + } } #ifdef DEBUG_ENABLED @@ -1645,32 +1576,28 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } const int *GDScriptFunction::get_code() const { - return _code_ptr; } -int GDScriptFunction::get_code_size() const { +int GDScriptFunction::get_code_size() const { return _code_size; } Variant GDScriptFunction::get_constant(int p_idx) const { - ERR_FAIL_INDEX_V(p_idx, constants.size(), "<errconst>"); return constants[p_idx]; } StringName GDScriptFunction::get_global_name(int p_idx) const { - ERR_FAIL_INDEX_V(p_idx, global_names.size(), "<errgname>"); return global_names[p_idx]; } int GDScriptFunction::get_default_argument_count() const { - return _default_arg_count; } -int GDScriptFunction::get_default_argument_addr(int p_idx) const { +int GDScriptFunction::get_default_argument_addr(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, default_arguments.size(), -1); return default_arguments[p_idx]; } @@ -1685,45 +1612,38 @@ GDScriptDataType GDScriptFunction::get_argument_type(int p_idx) const { } StringName GDScriptFunction::get_name() const { - return name; } int GDScriptFunction::get_max_stack_size() const { - return _stack_size; } struct _GDFKC { - int order; List<int> pos; }; struct _GDFKCS { - int order; StringName id; int pos; bool operator<(const _GDFKCS &p_r) const { - return order < p_r.order; } }; void GDScriptFunction::debug_get_stack_member_state(int p_line, List<Pair<StringName, int>> *r_stackvars) const { - int oc = 0; Map<StringName, _GDFKC> sdmap; for (const List<StackDebug>::Element *E = stack_debug.front(); E; E = E->next()) { - const StackDebug &sd = E->get(); - if (sd.line > p_line) + if (sd.line > p_line) { break; + } if (sd.added) { - if (!sdmap.has(sd.identifier)) { _GDFKC d; d.order = oc++; @@ -1734,18 +1654,17 @@ void GDScriptFunction::debug_get_stack_member_state(int p_line, List<Pair<String sdmap[sd.identifier].pos.push_back(sd.pos); } } else { - ERR_CONTINUE(!sdmap.has(sd.identifier)); sdmap[sd.identifier].pos.pop_back(); - if (sdmap[sd.identifier].pos.empty()) + if (sdmap[sd.identifier].pos.empty()) { sdmap.erase(sd.identifier); + } } } List<_GDFKCS> stackpositions; for (Map<StringName, _GDFKC>::Element *E = sdmap.front(); E; E = E->next()) { - _GDFKCS spp; spp.id = E->key(); spp.order = E->get().order; @@ -1756,7 +1675,6 @@ void GDScriptFunction::debug_get_stack_member_state(int p_line, List<Pair<String stackpositions.sort(); for (List<_GDFKCS>::Element *E = stackpositions.front(); E; E = E->next()) { - Pair<StringName, int> p; p.first = E->get().id; p.second = E->get().pos; @@ -1766,7 +1684,6 @@ void GDScriptFunction::debug_get_stack_member_state(int p_line, List<Pair<String GDScriptFunction::GDScriptFunction() : function_list(this) { - _stack_size = 0; _call_size = 0; rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; @@ -1805,7 +1722,6 @@ GDScriptFunction::~GDScriptFunction() { ///////////////////// Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { - Variant arg; r_error.error = Callable::CallError::CALL_OK; @@ -1838,9 +1754,9 @@ Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_ar } bool GDScriptFunctionState::is_valid(bool p_extended_check) const { - - if (function == nullptr) + if (function == nullptr) { return false; + } if (p_extended_check) { MutexLock lock(GDScriptLanguage::get_singleton()->lock); @@ -1859,7 +1775,6 @@ bool GDScriptFunctionState::is_valid(bool p_extended_check) const { } Variant GDScriptFunctionState::resume(const Variant &p_arg) { - ERR_FAIL_COND_V(!function, Variant()); { MutexLock lock(GDScriptLanguage::singleton->lock); @@ -1912,8 +1827,9 @@ Variant GDScriptFunctionState::resume(const Variant &p_arg) { } #ifdef DEBUG_ENABLED - if (EngineDebugger::is_active()) + if (EngineDebugger::is_active()) { GDScriptLanguage::get_singleton()->exit_function(); + } #endif } @@ -1921,17 +1837,16 @@ Variant GDScriptFunctionState::resume(const Variant &p_arg) { } void GDScriptFunctionState::_clear_stack() { - if (state.stack_size) { Variant *stack = (Variant *)state.stack.ptr(); - for (int i = 0; i < state.stack_size; i++) + for (int i = 0; i < state.stack_size; i++) { stack[i].~Variant(); + } state.stack_size = 0; } } void GDScriptFunctionState::_bind_methods() { - ClassDB::bind_method(D_METHOD("resume", "arg"), &GDScriptFunctionState::resume, DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("is_valid", "extended_check"), &GDScriptFunctionState::is_valid, DEFVAL(false)); ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "_signal_callback", &GDScriptFunctionState::_signal_callback, MethodInfo("_signal_callback")); @@ -1942,12 +1857,10 @@ void GDScriptFunctionState::_bind_methods() { GDScriptFunctionState::GDScriptFunctionState() : scripts_list(this), instances_list(this) { - function = nullptr; } GDScriptFunctionState::~GDScriptFunctionState() { - _clear_stack(); { diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index 7043c9b69b..583eab744a 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -59,8 +59,9 @@ struct GDScriptDataType { Ref<Script> script_type; bool is_type(const Variant &p_variant, bool p_allow_implicit_conversion = false) const { - if (!has_type) + if (!has_type) { return true; // Can't type check + } switch (kind) { case UNINITIALIZED: @@ -215,7 +216,6 @@ public: }; struct StackDebug { - int line; int pos; bool added; @@ -293,7 +293,6 @@ private: public: struct CallState { - GDScript *script; GDScriptInstance *instance; #ifdef DEBUG_ENABLED @@ -351,7 +350,6 @@ public: }; class GDScriptFunctionState : public Reference { - GDCLASS(GDScriptFunctionState, Reference); friend class GDScriptFunction; GDScriptFunction *function; diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp index 85a5d86ca0..d4258c385e 100644 --- a/modules/gdscript/gdscript_functions.cpp +++ b/modules/gdscript/gdscript_functions.cpp @@ -41,7 +41,6 @@ #include "gdscript.h" const char *GDScriptFunctions::get_func_name(Function p_func) { - ERR_FAIL_INDEX_V(p_func, FUNC_MAX, ""); static const char *_names[FUNC_MAX] = { @@ -140,7 +139,6 @@ const char *GDScriptFunctions::get_func_name(Function p_func) { } void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_count, Variant &r_ret, Callable::CallError &r_error) { - r_error.error = Callable::CallError::CALL_OK; #ifdef DEBUG_ENABLED @@ -176,7 +174,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ //using a switch, so the compiler generates a jumptable switch (p_func) { - case MATH_SIN: { VALIDATE_ARG_COUNT(1); VALIDATE_ARG_NUM(0); @@ -269,15 +266,12 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ case MATH_ABS: { VALIDATE_ARG_COUNT(1); if (p_args[0]->get_type() == Variant::INT) { - int64_t i = *p_args[0]; r_ret = ABS(i); } else if (p_args[0]->get_type() == Variant::FLOAT) { - double r = *p_args[0]; r_ret = Math::abs(r); } else { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::FLOAT; @@ -287,15 +281,12 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ case MATH_SIGN: { VALIDATE_ARG_COUNT(1); if (p_args[0]->get_type() == Variant::INT) { - int64_t i = *p_args[0]; r_ret = i < 0 ? -1 : (i > 0 ? +1 : 0); } else if (p_args[0]->get_type() == Variant::FLOAT) { - real_t r = *p_args[0]; r_ret = r < 0.0 ? -1.0 : (r > 0.0 ? +1.0 : 0.0); } else { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::FLOAT; @@ -505,7 +496,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ case LOGIC_MAX: { VALIDATE_ARG_COUNT(2); if (p_args[0]->get_type() == Variant::INT && p_args[1]->get_type() == Variant::INT) { - int64_t a = *p_args[0]; int64_t b = *p_args[1]; r_ret = MAX(a, b); @@ -523,7 +513,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ case LOGIC_MIN: { VALIDATE_ARG_COUNT(2); if (p_args[0]->get_type() == Variant::INT && p_args[1]->get_type() == Variant::INT) { - int64_t a = *p_args[0]; int64_t b = *p_args[1]; r_ret = MIN(a, b); @@ -540,7 +529,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ case LOGIC_CLAMP: { VALIDATE_ARG_COUNT(3); if (p_args[0]->get_type() == Variant::INT && p_args[1]->get_type() == Variant::INT && p_args[2]->get_type() == Variant::INT) { - int64_t a = *p_args[0]; int64_t b = *p_args[1]; int64_t c = *p_args[2]; @@ -595,7 +583,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ case FUNC_FUNCREF: { VALIDATE_ARG_COUNT(2); if (p_args[0]->get_type() != Variant::OBJECT) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::OBJECT; @@ -603,7 +590,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ return; } if (p_args[1]->get_type() != Variant::STRING && p_args[1]->get_type() != Variant::NODE_PATH) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 1; r_error.expected = Variant::STRING; @@ -624,7 +610,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ VALIDATE_ARG_NUM(1); int type = *p_args[1]; if (type < 0 || type >= Variant::VARIANT_MAX) { - r_ret = RTR("Invalid type argument to convert(), use TYPE_* constants."); r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; @@ -632,18 +617,15 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ return; } else { - r_ret = Variant::construct(Variant::Type(type), p_args, 1, r_error); } } break; case TYPE_OF: { - VALIDATE_ARG_COUNT(1); r_ret = p_args[0]->get_type(); } break; case TYPE_EXISTS: { - VALIDATE_ARG_COUNT(1); r_ret = ClassDB::class_exists(*p_args[0]); @@ -655,11 +637,9 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ r_ret = String(result); } break; case TEXT_ORD: { - VALIDATE_ARG_COUNT(1); if (p_args[0]->get_type() != Variant::STRING) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING; @@ -670,7 +650,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ String str = p_args[0]->operator String(); if (str.length() != 1) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING; @@ -691,23 +670,21 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } String str; for (int i = 0; i < p_arg_count; i++) { - String os = p_args[i]->operator String(); - if (i == 0) + if (i == 0) { str = os; - else + } else { str += os; + } } r_ret = str; } break; case TEXT_PRINT: { - String str; for (int i = 0; i < p_arg_count; i++) { - str += p_args[i]->operator String(); } @@ -716,12 +693,11 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } break; case TEXT_PRINT_TABBED: { - String str; for (int i = 0; i < p_arg_count; i++) { - - if (i) + if (i) { str += "\t"; + } str += p_args[i]->operator String(); } @@ -730,12 +706,11 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } break; case TEXT_PRINT_SPACED: { - String str; for (int i = 0; i < p_arg_count; i++) { - - if (i) + if (i) { str += " "; + } str += p_args[i]->operator String(); } @@ -745,10 +720,8 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } break; case TEXT_PRINTERR: { - String str; for (int i = 0; i < p_arg_count; i++) { - str += p_args[i]->operator String(); } @@ -759,7 +732,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ case TEXT_PRINTRAW: { String str; for (int i = 0; i < p_arg_count; i++) { - str += p_args[i]->operator String(); } @@ -770,7 +742,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ case TEXT_PRINT_DEBUG: { String str; for (int i = 0; i < p_arg_count; i++) { - str += p_args[i]->operator String(); } @@ -922,18 +893,14 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } break; case GEN_RANGE: { - switch (p_arg_count) { - case 0: { - r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 1; r_ret = Variant(); } break; case 1: { - VALIDATE_ARG_NUM(0); int count = *p_args[0]; Array arr; @@ -955,7 +922,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ r_ret = arr; } break; case 2: { - VALIDATE_ARG_NUM(0); VALIDATE_ARG_NUM(1); @@ -973,12 +939,12 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ r_ret = Variant(); return; } - for (int i = from; i < to; i++) + for (int i = from; i < to; i++) { arr[i - from] = i; + } r_ret = arr; } break; case 3: { - VALIDATE_ARG_NUM(0); VALIDATE_ARG_NUM(1); VALIDATE_ARG_NUM(2); @@ -987,7 +953,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ int to = *p_args[1]; int incr = *p_args[2]; if (incr == 0) { - r_ret = RTR("Step argument is zero!"); r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; return; @@ -1006,10 +971,8 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ //calculate how many int count = 0; if (incr > 0) { - count = ((to - from - 1) / incr) + 1; } else { - count = ((from - to - 1) / -incr) + 1; } @@ -1027,7 +990,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ arr[idx++] = i; } } else { - int idx = 0; for (int i = from; i > to; i += incr) { arr[idx++] = i; @@ -1037,7 +999,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ r_ret = arr; } break; default: { - r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; r_error.argument = 3; r_ret = Variant(); @@ -1059,7 +1020,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } break; case INST2DICT: { - VALIDATE_ARG_COUNT(1); if (p_args[0]->get_type() == Variant::NIL) { @@ -1069,24 +1029,20 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ r_error.argument = 0; r_ret = Variant(); } else { - Object *obj = *p_args[0]; if (!obj) { r_ret = Variant(); } else if (!obj->get_script_instance() || obj->get_script_instance()->get_language() != GDScriptLanguage::get_singleton()) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::DICTIONARY; r_ret = RTR("Not a script with an instance"); return; } else { - GDScriptInstance *ins = static_cast<GDScriptInstance *>(obj->get_script_instance()); Ref<GDScript> base = ins->get_script(); if (base.is_null()) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::DICTIONARY; @@ -1098,7 +1054,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ Vector<StringName> sname; while (p->_owner) { - sname.push_back(p->name); p = p->_owner; } @@ -1132,11 +1087,9 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } break; case DICT2INST: { - VALIDATE_ARG_COUNT(1); if (p_args[0]->get_type() != Variant::DICTIONARY) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::DICTIONARY; @@ -1148,7 +1101,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ Dictionary d = *p_args[0]; if (!d.has("@path")) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::OBJECT; @@ -1159,7 +1111,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ Ref<Script> scr = ResourceLoader::load(d["@path"]); if (!scr.is_valid()) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::OBJECT; @@ -1170,7 +1121,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ Ref<GDScript> gdscr = scr; if (!gdscr.is_valid()) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::OBJECT; @@ -1185,10 +1135,8 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } for (int i = 0; i < sub.get_name_count(); i++) { - gdscr = gdscr->subclasses[sub.get_name(i)]; if (!gdscr.is_valid()) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::OBJECT; @@ -1215,7 +1163,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } break; case VALIDATE_JSON: { - VALIDATE_ARG_COUNT(1); if (p_args[0]->get_type() != Variant::STRING) { @@ -1239,7 +1186,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } break; case PARSE_JSON: { - VALIDATE_ARG_COUNT(1); if (p_args[0]->get_type() != Variant::STRING) { @@ -1267,13 +1213,11 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ r_ret = JSON::print(*p_args[0]); } break; case HASH: { - VALIDATE_ARG_COUNT(1); r_ret = p_args[0]->hash(); } break; case COLOR8: { - if (p_arg_count < 3) { r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 3; @@ -1304,7 +1248,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } break; case COLORN: { - if (p_arg_count < 1) { r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 1; @@ -1339,7 +1282,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ ScriptLanguage *script = GDScriptLanguage::get_singleton(); for (int i = 0; i < script->debug_get_stack_level_count(); i++) { - print_line("Frame " + itos(i) + " - " + script->debug_get_stack_level_source(i) + ":" + itos(script->debug_get_stack_level_line(i)) + " in function '" + script->debug_get_stack_level_function(i) + "'"); }; } break; @@ -1350,7 +1292,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ ScriptLanguage *script = GDScriptLanguage::get_singleton(); Array ret; for (int i = 0; i < script->debug_get_stack_level_count(); i++) { - Dictionary frame; frame["source"] = script->debug_get_stack_level_source(i); frame["function"] = script->debug_get_stack_level_function(i); @@ -1361,7 +1302,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } break; case INSTANCE_FROM_ID: { - VALIDATE_ARG_COUNT(1); if (p_args[0]->get_type() != Variant::INT && p_args[0]->get_type() != Variant::FLOAT) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; @@ -1376,66 +1316,53 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } break; case LEN: { - VALIDATE_ARG_COUNT(1); switch (p_args[0]->get_type()) { case Variant::STRING: { - String d = *p_args[0]; r_ret = d.length(); } break; case Variant::DICTIONARY: { - Dictionary d = *p_args[0]; r_ret = d.size(); } break; case Variant::ARRAY: { - Array d = *p_args[0]; r_ret = d.size(); } break; case Variant::PACKED_BYTE_ARRAY: { - Vector<uint8_t> d = *p_args[0]; r_ret = d.size(); } break; case Variant::PACKED_INT32_ARRAY: { - Vector<int32_t> d = *p_args[0]; r_ret = d.size(); } break; case Variant::PACKED_INT64_ARRAY: { - Vector<int64_t> d = *p_args[0]; r_ret = d.size(); } break; case Variant::PACKED_FLOAT32_ARRAY: { - Vector<float> d = *p_args[0]; r_ret = d.size(); } break; case Variant::PACKED_FLOAT64_ARRAY: { - Vector<double> d = *p_args[0]; r_ret = d.size(); } break; case Variant::PACKED_STRING_ARRAY: { - Vector<String> d = *p_args[0]; r_ret = d.size(); } break; case Variant::PACKED_VECTOR2_ARRAY: { - Vector<Vector2> d = *p_args[0]; r_ret = d.size(); } break; case Variant::PACKED_VECTOR3_ARRAY: { - Vector<Vector3> d = *p_args[0]; r_ret = d.size(); } break; case Variant::PACKED_COLOR_ARRAY: { - Vector<Color> d = *p_args[0]; r_ret = d.size(); } break; @@ -1450,7 +1377,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } break; case IS_INSTANCE_VALID: { - VALIDATE_ARG_COUNT(1); if (p_args[0]->get_type() != Variant::OBJECT) { r_ret = false; @@ -1461,19 +1387,16 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } break; case FUNC_MAX: { - ERR_FAIL(); } break; } } bool GDScriptFunctions::is_deterministic(Function p_func) { - //man i couldn't have chosen a worse function name, //way too controversial.. switch (p_func) { - case MATH_SIN: case MATH_COS: case MATH_TAN: @@ -1537,12 +1460,10 @@ bool GDScriptFunctions::is_deterministic(Function p_func) { } MethodInfo GDScriptFunctions::get_info(Function p_func) { - #ifdef DEBUG_ENABLED //using a switch, so the compiler generates a jumptable switch (p_func) { - case MATH_SIN: { MethodInfo mi("sin", PropertyInfo(Variant::FLOAT, "s")); mi.return_val.type = Variant::FLOAT; @@ -1817,7 +1738,6 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { return mi; } break; case OBJ_WEAKREF: { - MethodInfo mi("weakref", PropertyInfo(Variant::OBJECT, "obj")); mi.return_val.type = Variant::OBJECT; mi.return_val.class_name = "WeakRef"; @@ -1826,7 +1746,6 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { } break; case FUNC_FUNCREF: { - MethodInfo mi("funcref", PropertyInfo(Variant::OBJECT, "instance"), PropertyInfo(Variant::STRING, "funcname")); mi.return_val.type = Variant::OBJECT; mi.return_val.class_name = "FuncRef"; @@ -1834,42 +1753,36 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { } break; case TYPE_CONVERT: { - MethodInfo mi("convert", PropertyInfo(Variant::NIL, "what", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT), PropertyInfo(Variant::INT, "type")); mi.return_val.type = Variant::NIL; mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; return mi; } break; case TYPE_OF: { - MethodInfo mi("typeof", PropertyInfo(Variant::NIL, "what", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT)); mi.return_val.type = Variant::INT; return mi; } break; case TYPE_EXISTS: { - MethodInfo mi("type_exists", PropertyInfo(Variant::STRING, "type")); mi.return_val.type = Variant::BOOL; return mi; } break; case TEXT_CHAR: { - MethodInfo mi("char", PropertyInfo(Variant::INT, "code")); mi.return_val.type = Variant::STRING; return mi; } break; case TEXT_ORD: { - MethodInfo mi("ord", PropertyInfo(Variant::STRING, "char")); mi.return_val.type = Variant::INT; return mi; } break; case TEXT_STR: { - MethodInfo mi("str"); mi.return_val.type = Variant::STRING; mi.flags |= METHOD_FLAG_VARARG; @@ -1877,7 +1790,6 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { } break; case TEXT_PRINT: { - MethodInfo mi("print"); mi.return_val.type = Variant::NIL; mi.flags |= METHOD_FLAG_VARARG; @@ -1885,7 +1797,6 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { } break; case TEXT_PRINT_TABBED: { - MethodInfo mi("printt"); mi.return_val.type = Variant::NIL; mi.flags |= METHOD_FLAG_VARARG; @@ -1893,7 +1804,6 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { } break; case TEXT_PRINT_SPACED: { - MethodInfo mi("prints"); mi.return_val.type = Variant::NIL; mi.flags |= METHOD_FLAG_VARARG; @@ -1901,7 +1811,6 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { } break; case TEXT_PRINTERR: { - MethodInfo mi("printerr"); mi.return_val.type = Variant::NIL; mi.flags |= METHOD_FLAG_VARARG; @@ -1909,7 +1818,6 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { } break; case TEXT_PRINTRAW: { - MethodInfo mi("printraw"); mi.return_val.type = Variant::NIL; mi.flags |= METHOD_FLAG_VARARG; @@ -1917,7 +1825,6 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { } break; case TEXT_PRINT_DEBUG: { - MethodInfo mi("print_debug"); mi.return_val.type = Variant::NIL; mi.flags |= METHOD_FLAG_VARARG; @@ -1925,41 +1832,35 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { } break; case PUSH_ERROR: { - MethodInfo mi(Variant::NIL, "push_error", PropertyInfo(Variant::STRING, "message")); mi.return_val.type = Variant::NIL; return mi; } break; case PUSH_WARNING: { - MethodInfo mi(Variant::NIL, "push_warning", PropertyInfo(Variant::STRING, "message")); mi.return_val.type = Variant::NIL; return mi; } break; case VAR_TO_STR: { - MethodInfo mi("var2str", PropertyInfo(Variant::NIL, "var", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT)); mi.return_val.type = Variant::STRING; return mi; } break; case STR_TO_VAR: { - MethodInfo mi(Variant::NIL, "str2var", PropertyInfo(Variant::STRING, "string")); mi.return_val.type = Variant::NIL; mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; return mi; } break; case VAR_TO_BYTES: { - MethodInfo mi("var2bytes", PropertyInfo(Variant::NIL, "var", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT), PropertyInfo(Variant::BOOL, "full_objects")); mi.default_arguments.push_back(false); mi.return_val.type = Variant::PACKED_BYTE_ARRAY; return mi; } break; case BYTES_TO_VAR: { - MethodInfo mi(Variant::NIL, "bytes2var", PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytes"), PropertyInfo(Variant::BOOL, "allow_objects")); mi.default_arguments.push_back(false); mi.return_val.type = Variant::NIL; @@ -1967,65 +1868,55 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { return mi; } break; case GEN_RANGE: { - MethodInfo mi("range"); mi.return_val.type = Variant::ARRAY; mi.flags |= METHOD_FLAG_VARARG; return mi; } break; case RESOURCE_LOAD: { - MethodInfo mi("load", PropertyInfo(Variant::STRING, "path")); mi.return_val.type = Variant::OBJECT; mi.return_val.class_name = "Resource"; return mi; } break; case INST2DICT: { - MethodInfo mi("inst2dict", PropertyInfo(Variant::OBJECT, "inst")); mi.return_val.type = Variant::DICTIONARY; return mi; } break; case DICT2INST: { - MethodInfo mi("dict2inst", PropertyInfo(Variant::DICTIONARY, "dict")); mi.return_val.type = Variant::OBJECT; return mi; } break; case VALIDATE_JSON: { - MethodInfo mi("validate_json", PropertyInfo(Variant::STRING, "json")); mi.return_val.type = Variant::STRING; return mi; } break; case PARSE_JSON: { - MethodInfo mi(Variant::NIL, "parse_json", PropertyInfo(Variant::STRING, "json")); mi.return_val.type = Variant::NIL; mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; return mi; } break; case TO_JSON: { - MethodInfo mi("to_json", PropertyInfo(Variant::NIL, "var", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT)); mi.return_val.type = Variant::STRING; return mi; } break; case HASH: { - MethodInfo mi("hash", PropertyInfo(Variant::NIL, "var", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT)); mi.return_val.type = Variant::INT; return mi; } break; case COLOR8: { - MethodInfo mi("Color8", PropertyInfo(Variant::INT, "r8"), PropertyInfo(Variant::INT, "g8"), PropertyInfo(Variant::INT, "b8"), PropertyInfo(Variant::INT, "a8")); mi.default_arguments.push_back(255); mi.return_val.type = Variant::COLOR; return mi; } break; case COLORN: { - MethodInfo mi("ColorN", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::FLOAT, "alpha")); mi.default_arguments.push_back(1.0f); mi.return_val.type = Variant::COLOR; @@ -2059,7 +1950,6 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { return mi; } break; default: { - ERR_FAIL_V(MethodInfo()); } break; } diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index b900ba903f..57531ed13b 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -42,14 +42,14 @@ template <class T> T *GDScriptParser::alloc_node() { - T *t = memnew(T); t->next = list; list = t; - if (!head) + if (!head) { head = t; + } t->line = tokenizer->get_token_line(); t->column = tokenizer->get_token_column(); @@ -61,7 +61,6 @@ static String _find_function_name(const GDScriptParser::OperatorNode *p_call); #endif // DEBUG_ENABLED bool GDScriptParser::_end_statement() { - if (tokenizer->get_token() == GDScriptTokenizer::TK_SEMICOLON) { tokenizer->advance(); return true; //handle next @@ -83,7 +82,6 @@ void GDScriptParser::_set_end_statement_error(String p_name) { } bool GDScriptParser::_enter_indent_block(BlockNode *p_block) { - if (tokenizer->get_token() != GDScriptTokenizer::TK_COLON) { // report location at the previous token (on the previous line) int error_line = tokenizer->get_token_line(-1); @@ -108,12 +106,10 @@ bool GDScriptParser::_enter_indent_block(BlockNode *p_block) { while (true) { if (tokenizer->get_token() != GDScriptTokenizer::TK_NEWLINE) { - return false; //wtf } else if (tokenizer->get_token(1) == GDScriptTokenizer::TK_EOF) { return false; } else if (tokenizer->get_token(1) != GDScriptTokenizer::TK_NEWLINE) { - int indent = tokenizer->get_token_line_indent(); int tabs = tokenizer->get_token_line_tab_indent(); IndentLevel current_level = indent_level.back()->get(); @@ -132,7 +128,6 @@ bool GDScriptParser::_enter_indent_block(BlockNode *p_block) { return true; } else if (p_block) { - NewLineNode *nl = alloc_node<NewLineNode>(); nl->line = tokenizer->get_token_line(); p_block->statements.push_back(nl); @@ -143,16 +138,13 @@ bool GDScriptParser::_enter_indent_block(BlockNode *p_block) { } bool GDScriptParser::_parse_arguments(Node *p_parent, Vector<Node *> &p_args, bool p_static, bool p_can_codecomplete, bool p_parsing_constant) { - if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { tokenizer->advance(); } else { - parenthesis++; int argidx = 0; while (true) { - if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) { _make_completable_call(argidx); completion_node = p_parent; @@ -178,9 +170,7 @@ bool GDScriptParser::_parse_arguments(Node *p_parent, Vector<Node *> &p_args, bo break; } else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { - if (tokenizer->get_token(1) == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { - _set_error("Expression expected"); return false; } @@ -200,7 +190,6 @@ bool GDScriptParser::_parse_arguments(Node *p_parent, Vector<Node *> &p_args, bo } void GDScriptParser::_make_completable_call(int p_arg) { - completion_cursor = StringName(); completion_type = COMPLETION_CALL_ARGUMENTS; completion_class = current_class; @@ -213,14 +202,12 @@ void GDScriptParser::_make_completable_call(int p_arg) { } bool GDScriptParser::_get_completable_identifier(CompletionType p_type, StringName &identifier) { - identifier = StringName(); if (tokenizer->is_token_literal()) { identifier = tokenizer->get_token_literal(); tokenizer->advance(); } if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) { - completion_cursor = identifier; completion_type = p_type; completion_class = current_class; @@ -246,7 +233,6 @@ bool GDScriptParser::_get_completable_identifier(CompletionType p_type, StringNa } GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_static, bool p_allow_assign, bool p_parsing_constant) { - //Vector<Node*> expressions; //Vector<OperatorNode::Operator> operators; @@ -257,7 +243,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s int op_line = tokenizer->get_token_line(); // when operators are created at the bottom, the line might have been changed (\n found) while (true) { - /*****************/ /* Parse Operand */ /*****************/ @@ -285,11 +270,11 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s parenthesis++; Node *subexpr = _parse_expression(p_parent, p_static, p_allow_assign, p_parsing_constant); parenthesis--; - if (!subexpr) + if (!subexpr) { return nullptr; + } if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { - _set_error("Expected ')' in expression"); return nullptr; } @@ -306,7 +291,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s int line = tokenizer->get_token_line(); while (!done) { - switch (tokenizer->get_token()) { case GDScriptTokenizer::TK_CURSOR: { completion_type = COMPLETION_GET_NODE; @@ -320,7 +304,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s tokenizer->advance(); } break; case GDScriptTokenizer::TK_CONSTANT: { - if (!need_identifier) { done = true; break; @@ -337,7 +320,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s } break; case GDScriptTokenizer::TK_OP_DIV: { - if (need_identifier) { done = true; break; @@ -392,7 +374,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s continue; //no point in cursor in the middle of expression } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT) { - //constant defined by tokenizer ConstantNode *constant = alloc_node<ConstantNode>(); constant->value = tokenizer->get_token_constant(); @@ -400,7 +381,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s tokenizer->advance(); expr = constant; } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CONST_PI) { - //constant defined by tokenizer ConstantNode *constant = alloc_node<ConstantNode>(); constant->value = Math_PI; @@ -408,7 +388,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s tokenizer->advance(); expr = constant; } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CONST_TAU) { - //constant defined by tokenizer ConstantNode *constant = alloc_node<ConstantNode>(); constant->value = Math_TAU; @@ -416,7 +395,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s tokenizer->advance(); expr = constant; } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CONST_INF) { - //constant defined by tokenizer ConstantNode *constant = alloc_node<ConstantNode>(); constant->value = Math_INF; @@ -424,7 +402,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s tokenizer->advance(); expr = constant; } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CONST_NAN) { - //constant defined by tokenizer ConstantNode *constant = alloc_node<ConstantNode>(); constant->value = Math_NAN; @@ -432,7 +409,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s tokenizer->advance(); expr = constant; } else if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_PRELOAD) { - //constant defined by tokenizer tokenizer->advance(); if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) { @@ -489,11 +465,11 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s return nullptr; } - if (!path.is_abs_path() && base_path != "") + if (!path.is_abs_path() && base_path != "") { path = base_path.plus_file(path); + } path = path.replace("///", "//").simplify_path(); if (path == self_path) { - _set_error("Can't preload itself (use 'get_script()')."); return nullptr; } @@ -502,7 +478,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s dependencies.push_back(path); if (!dependencies_only) { if (!validating) { - //this can be too slow for just validating code if (for_completion && ScriptCodeCompletionCache::get_singleton() && FileAccess::exists(path)) { res = ScriptCodeCompletionCache::get_singleton()->get_cached_resource(path); @@ -510,7 +485,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s res = ResourceLoader::load(path); } } else { - if (!FileAccess::exists(path)) { _set_error("Can't preload resource at path: " + path); return nullptr; @@ -543,7 +517,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s expr = constant; } else if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_YIELD) { - if (!current_function) { _set_error("\"yield()\" can only be used inside function blocks."); return nullptr; @@ -570,12 +543,12 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s expr = yield; tokenizer->advance(); } else { - parenthesis++; Node *object = _parse_and_reduce_expression(p_parent, p_static); - if (!object) + if (!object) { return nullptr; + } yield->arguments.push_back(object); if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) { @@ -586,7 +559,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s tokenizer->advance(); if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) { - completion_cursor = StringName(); completion_node = object; completion_type = COMPLETION_YIELD; @@ -600,8 +572,9 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s } Node *signal = _parse_and_reduce_expression(p_parent, p_static); - if (!signal) + if (!signal) { return nullptr; + } yield->arguments.push_back(signal); if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { @@ -617,7 +590,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s } } else if (tokenizer->get_token() == GDScriptTokenizer::TK_SELF) { - if (p_static) { _set_error("\"self\" isn't allowed in a static function or constant expression."); return nullptr; @@ -627,28 +599,23 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s tokenizer->advance(); expr = self; } else if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_TYPE && tokenizer->get_token(1) == GDScriptTokenizer::TK_PERIOD) { - Variant::Type bi_type = tokenizer->get_token_type(); tokenizer->advance(2); StringName identifier; if (_get_completable_identifier(COMPLETION_BUILT_IN_TYPE_CONSTANT, identifier)) { - completion_built_in_constant = bi_type; } if (identifier == StringName()) { - _set_error("Built-in type constant or static function expected after \".\"."); return nullptr; } if (!Variant::has_constant(bi_type, identifier)) { - if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_OPEN && Variant::is_method_const(bi_type, identifier) && Variant::get_method_return_type(bi_type, identifier) == bi_type) { - tokenizer->advance(); OperatorNode *construct = alloc_node<OperatorNode>(); @@ -666,8 +633,9 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s id->name = identifier; op->arguments.push_back(id); - if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant)) + if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant)) { return nullptr; + } expr = op; } else { @@ -688,7 +656,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s } } } else { - ConstantNode *cn = alloc_node<ConstantNode>(); cn->value = Variant::get_constant_value(bi_type, identifier); cn->datatype = _type_from_variant(cn->value); @@ -733,13 +700,11 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s tokenizer->advance(2); } } else if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_FUNC) { - BuiltInFunctionNode *bn = alloc_node<BuiltInFunctionNode>(); bn->function = tokenizer->get_token_built_in_func(); op->arguments.push_back(bn); tokenizer->advance(2); } else { - SelfNode *self = alloc_node<SelfNode>(); op->arguments.push_back(self); @@ -765,8 +730,9 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s } } if (!replaced) { - if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant)) + if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant)) { return nullptr; + } expr = op; } } else if (tokenizer->is_token_literal(0, true)) { @@ -913,7 +879,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s } } else if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ADD || tokenizer->get_token() == GDScriptTokenizer::TK_OP_SUB || tokenizer->get_token() == GDScriptTokenizer::TK_OP_NOT || tokenizer->get_token() == GDScriptTokenizer::TK_OP_BIT_INVERT) { - //single prefix operators like !expr +expr -expr ++expr --expr alloc_node<OperatorNode>(); Expression e; @@ -979,9 +944,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s bool expecting_comma = false; while (true) { - if (tokenizer->get_token() == GDScriptTokenizer::TK_EOF) { - _set_error("Unterminated array"); return nullptr; @@ -989,7 +952,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s tokenizer->advance(); break; } else if (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) { - tokenizer->advance(); //ignore newline } else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { if (!expecting_comma) { @@ -1006,8 +968,9 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s return nullptr; } Node *n = _parse_expression(arr, p_static, p_allow_assign, p_parsing_constant); - if (!n) + if (!n) { return nullptr; + } arr->elements.push_back(n); expecting_comma = true; } @@ -1035,14 +998,11 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s DictExpect expecting = DICT_EXPECT_KEY; while (true) { - if (tokenizer->get_token() == GDScriptTokenizer::TK_EOF) { - _set_error("Unterminated dictionary"); return nullptr; } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CURLY_BRACKET_CLOSE) { - if (expecting == DICT_EXPECT_COLON) { _set_error("':' expected"); return nullptr; @@ -1054,10 +1014,8 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s tokenizer->advance(); break; } else if (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) { - tokenizer->advance(); //ignore newline } else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { - if (expecting == DICT_EXPECT_KEY) { _set_error("key or '}' expected"); return nullptr; @@ -1075,7 +1033,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s tokenizer->advance(); //ignore newline } else if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON) { - if (expecting == DICT_EXPECT_KEY) { _set_error("key or '}' expected"); return nullptr; @@ -1092,7 +1049,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s expecting = DICT_EXPECT_VALUE; tokenizer->advance(); //ignore newline } else { - if (expecting == DICT_EXPECT_COMMA) { _set_error("',' or '}' expected"); return nullptr; @@ -1103,7 +1059,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s } if (expecting == DICT_EXPECT_KEY) { - if (tokenizer->is_token_literal() && tokenizer->get_token(1) == GDScriptTokenizer::TK_OP_ASSIGN) { // We check with is_token_literal, as this allows us to use match/sync/etc. as a name //lua style identifier, easier to write @@ -1116,16 +1071,18 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s } else { //python/js style more flexible key = _parse_expression(dict, p_static, p_allow_assign, p_parsing_constant); - if (!key) + if (!key) { return nullptr; + } expecting = DICT_EXPECT_COLON; } } if (expecting == DICT_EXPECT_VALUE) { Node *value = _parse_expression(dict, p_static, p_allow_assign, p_parsing_constant); - if (!value) + if (!value) { return nullptr; + } expecting = DICT_EXPECT_COMMA; if (key->type == GDScriptParser::Node::TYPE_CONSTANT) { @@ -1191,7 +1148,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s expr = tn; tokenizer->advance(); } else { - //find list [ or find dictionary { _set_error("Error parsing expression, misplaced: " + String(tokenizer->get_token_name(tokenizer->get_token()))); return nullptr; //nothing @@ -1204,11 +1160,9 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s /******************/ while (true) { - //expressions can be indexed any number of times if (tokenizer->get_token() == GDScriptTokenizer::TK_PERIOD) { - //indexing using "." if (tokenizer->get_token(1) != GDScriptTokenizer::TK_CURSOR && !tokenizer->is_token_literal(1)) { @@ -1239,8 +1193,9 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s _make_completable_call(0); completion_node = op; } - if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant)) + if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant)) { return nullptr; + } expr = op; } else { @@ -1252,7 +1207,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s StringName identifier; if (_get_completable_identifier(COMPLETION_INDEX, identifier)) { - if (identifier == StringName()) { identifier = "@temp"; //so it parses alright } @@ -1292,8 +1246,9 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s tokenizer->advance(1); expr = op; - } else + } else { break; + } } /*****************/ @@ -1478,16 +1433,13 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s /* Reduce the set set of expressions and place them in an operator tree, respecting precedence */ while (expression.size() > 1) { - int next_op = -1; int min_priority = 0xFFFFF; bool is_unary = false; bool is_ternary = false; for (int i = 0; i < expression.size(); i++) { - if (!expression[i].is_op) { - continue; } @@ -1499,7 +1451,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s bool right_to_left = false; switch (expression[i].op) { - case OperatorNode::OP_IS: case OperatorNode::OP_IS_BUILTIN: priority = -1; @@ -1650,17 +1601,14 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s } if (next_op == -1) { - _set_error("Yet another parser bug...."); ERR_FAIL_V(nullptr); } // OK! create operator.. if (is_unary) { - int expr_pos = next_op; while (expression[expr_pos].is_op) { - expr_pos++; if (expr_pos == expression.size()) { //can happen.. @@ -1671,7 +1619,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s //consecutively do unary operators for (int i = expr_pos - 1; i >= next_op; i--) { - OperatorNode *op = alloc_node<OperatorNode>(); op->op = expression[i].op; op->arguments.push_back(expression[i + 1].node); @@ -1701,7 +1648,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s op->line = op_line; //line might have been changed from a \n if (expression[next_op - 1].is_op) { - _set_error("Parser bug..."); ERR_FAIL_V(nullptr); } @@ -1737,7 +1683,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s expression.remove(next_op); expression.remove(next_op); } else { - if (next_op < 1 || next_op >= (expression.size() - 1)) { _set_error("Parser bug..."); ERR_FAIL_V(nullptr); @@ -1748,7 +1693,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s op->line = op_line; //line might have been changed from a \n if (expression[next_op - 1].is_op) { - _set_error("Parser bug..."); ERR_FAIL_V(nullptr); } @@ -1777,23 +1721,20 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s } GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to_const) { - switch (p_node->type) { - case Node::TYPE_BUILT_IN_FUNCTION: { //many may probably be optimizable return p_node; } break; case Node::TYPE_ARRAY: { - ArrayNode *an = static_cast<ArrayNode *>(p_node); bool all_constants = true; for (int i = 0; i < an->elements.size(); i++) { - an->elements.write[i] = _reduce_expression(an->elements[i], p_to_const); - if (an->elements[i]->type != Node::TYPE_CONSTANT) + if (an->elements[i]->type != Node::TYPE_CONSTANT) { all_constants = false; + } } if (all_constants && p_to_const) { @@ -1815,18 +1756,18 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to } break; case Node::TYPE_DICTIONARY: { - DictionaryNode *dn = static_cast<DictionaryNode *>(p_node); bool all_constants = true; for (int i = 0; i < dn->elements.size(); i++) { - dn->elements.write[i].key = _reduce_expression(dn->elements[i].key, p_to_const); - if (dn->elements[i].key->type != Node::TYPE_CONSTANT) + if (dn->elements[i].key->type != Node::TYPE_CONSTANT) { all_constants = false; + } dn->elements.write[i].value = _reduce_expression(dn->elements[i].value, p_to_const); - if (dn->elements[i].value->type != Node::TYPE_CONSTANT) + if (dn->elements[i].value->type != Node::TYPE_CONSTANT) { all_constants = false; + } } if (all_constants && p_to_const) { @@ -1849,14 +1790,12 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to } break; case Node::TYPE_OPERATOR: { - OperatorNode *op = static_cast<OperatorNode *>(p_node); bool all_constants = true; int last_not_constant = -1; for (int i = 0; i < op->arguments.size(); i++) { - op->arguments.write[i] = _reduce_expression(op->arguments[i], p_to_const); if (op->arguments[i]->type != Node::TYPE_CONSTANT) { all_constants = false; @@ -1875,15 +1814,12 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to } else if (op->op == OperatorNode::OP_CALL) { //can reduce base type constructors if ((op->arguments[0]->type == Node::TYPE_TYPE || (op->arguments[0]->type == Node::TYPE_BUILT_IN_FUNCTION && GDScriptFunctions::is_deterministic(static_cast<BuiltInFunctionNode *>(op->arguments[0])->function))) && last_not_constant == 0) { - //native type constructor or intrinsic function const Variant **vptr = nullptr; Vector<Variant *> ptrs; if (op->arguments.size() > 1) { - ptrs.resize(op->arguments.size() - 1); for (int i = 0; i < ptrs.size(); i++) { - ConstantNode *cn = static_cast<ConstantNode *>(op->arguments[i + 1]); ptrs.write[i] = &cn->value; } @@ -1904,7 +1840,6 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to } if (ce.error != Callable::CallError::CALL_OK) { - String errwhere; if (op->arguments[0]->type == Node::TYPE_TYPE) { TypeNode *tn = static_cast<TypeNode *>(op->arguments[0]); @@ -1916,18 +1851,14 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to } switch (ce.error) { - case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: { - _set_error("Invalid argument (#" + itos(ce.argument + 1) + ") for " + errwhere + "."); } break; case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: { - _set_error("Too many arguments for " + errwhere + "."); } break; case Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: { - _set_error("Too few arguments for " + errwhere + "."); } break; default: { @@ -1956,7 +1887,6 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to //can reduce indices into constant arrays or dictionaries if (all_constants) { - ConstantNode *ca = static_cast<ConstantNode *>(op->arguments[0]); ConstantNode *cb = static_cast<ConstantNode *>(op->arguments[1]); @@ -1978,9 +1908,7 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to return op; } else if (op->op == OperatorNode::OP_INDEX_NAMED) { - if (op->arguments[0]->type == Node::TYPE_CONSTANT && op->arguments[1]->type == Node::TYPE_IDENTIFIER) { - ConstantNode *ca = static_cast<ConstantNode *>(op->arguments[0]); IdentifierNode *ib = static_cast<IdentifierNode *>(op->arguments[1]); @@ -2003,7 +1931,6 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to //validate assignment (don't assign to constant expression switch (op->op) { - case OperatorNode::OP_ASSIGN: case OperatorNode::OP_ASSIGN_ADD: case OperatorNode::OP_ASSIGN_SUB: @@ -2015,7 +1942,6 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to case OperatorNode::OP_ASSIGN_BIT_AND: case OperatorNode::OP_ASSIGN_BIT_OR: case OperatorNode::OP_ASSIGN_BIT_XOR: { - if (op->arguments[0]->type == Node::TYPE_CONSTANT) { _set_error("Can't assign to constant", tokenizer->get_token_line() - 1); error_line = op->line; @@ -2041,8 +1967,9 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to } } //now se if all are constants - if (!all_constants) + if (!all_constants) { return op; //nothing to reduce from here on + } #define _REDUCE_UNARY(m_vop) \ bool valid = false; \ Variant res; \ @@ -2072,7 +1999,6 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to return cn; switch (op->op) { - //unary operators case OperatorNode::OP_NEG: { _REDUCE_UNARY(Variant::OP_NEGATE); @@ -2164,23 +2090,24 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to } GDScriptParser::Node *GDScriptParser::_parse_and_reduce_expression(Node *p_parent, bool p_static, bool p_reduce_const, bool p_allow_assign) { - Node *expr = _parse_expression(p_parent, p_static, p_allow_assign, p_reduce_const); - if (!expr || error_set) + if (!expr || error_set) { return nullptr; + } expr = _reduce_expression(expr, p_reduce_const); - if (!expr || error_set) + if (!expr || error_set) { return nullptr; + } return expr; } bool GDScriptParser::_reduce_export_var_type(Variant &p_value, int p_line) { - if (p_value.get_type() == Variant::ARRAY) { Array arr = p_value; for (int i = 0; i < arr.size(); i++) { - if (!_reduce_export_var_type(arr[i], p_line)) + if (!_reduce_export_var_type(arr[i], p_line)) { return false; + } } return true; } @@ -2189,8 +2116,9 @@ bool GDScriptParser::_reduce_export_var_type(Variant &p_value, int p_line) { Dictionary dict = p_value; for (int i = 0; i < dict.size(); i++) { Variant value = dict.get_value_at_index(i); - if (!_reduce_export_var_type(value, p_line)) + if (!_reduce_export_var_type(value, p_line)) { return false; + } } return true; } @@ -2209,7 +2137,6 @@ bool GDScriptParser::_reduce_export_var_type(Variant &p_value, int p_line) { } bool GDScriptParser::_recover_from_completion() { - if (!completion_found) { return false; //can't recover if no completion } @@ -2227,12 +2154,12 @@ bool GDScriptParser::_recover_from_completion() { } GDScriptParser::PatternNode *GDScriptParser::_parse_pattern(bool p_static) { - PatternNode *pattern = alloc_node<PatternNode>(); GDScriptTokenizer::Token token = tokenizer->get_token(); - if (error_set) + if (error_set) { return nullptr; + } if (token == GDScriptTokenizer::TK_EOF) { return nullptr; @@ -2244,7 +2171,6 @@ GDScriptParser::PatternNode *GDScriptParser::_parse_pattern(bool p_static) { tokenizer->advance(); pattern->pt_type = GDScriptParser::PatternNode::PT_ARRAY; while (true) { - if (tokenizer->get_token() == GDScriptTokenizer::TK_BRACKET_CLOSE) { tokenizer->advance(); break; @@ -2316,7 +2242,6 @@ GDScriptParser::PatternNode *GDScriptParser::_parse_pattern(bool p_static) { tokenizer->advance(); pattern->pt_type = GDScriptParser::PatternNode::PT_DICTIONARY; while (true) { - if (tokenizer->get_token() == GDScriptTokenizer::TK_CURLY_BRACKET_CLOSE) { tokenizer->advance(); break; @@ -2429,13 +2354,14 @@ void GDScriptParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBran bool catch_all_appeared = false; while (true) { - - while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE && _parse_newline()) + while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE && _parse_newline()) { ; + } // GDScriptTokenizer::Token token = tokenizer->get_token(); - if (error_set) + if (error_set) { return; + } if (current_level.indent > indent_level.back()->get().indent) { break; // go back a level @@ -2507,12 +2433,10 @@ void GDScriptParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBran } void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_match, Node *&p_resulting_node, Map<StringName, Node *> &p_bindings) { - const DataType &to_match_type = p_node_to_match->get_datatype(); switch (p_pattern->pt_type) { case PatternNode::PT_CONSTANT: { - DataType pattern_type = _reduce_node_type(p_pattern->constant); if (error_set) { return; @@ -2576,7 +2500,6 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m p_resulting_node = true_value; } break; case PatternNode::PT_ARRAY: { - bool open_ended = false; if (p_pattern->array.size() > 0) { @@ -2673,7 +2596,6 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m } break; case PatternNode::PT_DICTIONARY: { - bool open_ended = false; if (p_pattern->array.size() > 0) { @@ -2742,7 +2664,6 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m } for (Map<ConstantNode *, PatternNode *>::Element *e = p_pattern->dictionary.front(); e; e = e->next()) { - Node *condition = nullptr; // check for has, then for pattern @@ -2757,7 +2678,6 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m has_call->arguments.push_back(e->key()); if (e->value()) { - OperatorNode *indexed_value = alloc_node<OperatorNode>(); indexed_value->op = OperatorNode::OP_INDEX; indexed_value->arguments.push_back(p_node_to_match); @@ -2795,7 +2715,6 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m p_resulting_node = true_value; } break; default: { - } break; } } @@ -2816,7 +2735,6 @@ void GDScriptParser::_transform_match_statment(MatchNode *p_match_statement) { } for (int i = 0; i < p_match_statement->branches.size(); i++) { - PatternBranchNode *branch = p_match_statement->branches[i]; MatchNode::CompiledPatternBranch compiled_branch; @@ -2899,7 +2817,6 @@ void GDScriptParser::_transform_match_statment(MatchNode *p_match_statement) { } void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { - IndentLevel current_level = indent_level.back()->get(); #ifdef DEBUG_ENABLED @@ -2926,8 +2843,9 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { is_first_line = false; GDScriptTokenizer::Token token = tokenizer->get_token(); - if (error_set) + if (error_set) { return; + } if (current_level.indent > indent_level.back()->get().indent) { p_block->end_line = tokenizer->get_token_line(); @@ -2935,7 +2853,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { } if (pending_newline != -1) { - NewLineNode *nl2 = alloc_node<NewLineNode>(); nl2->line = pending_newline; p_block->statements.push_back(nl2); @@ -2967,7 +2884,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { return; } break; case GDScriptTokenizer::TK_NEWLINE: { - int line = tokenizer->get_token_line(); if (!_parse_newline()) { @@ -2986,7 +2902,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { } break; case GDScriptTokenizer::TK_CF_PASS: { if (tokenizer->get_token(1) != GDScriptTokenizer::TK_SEMICOLON && tokenizer->get_token(1) != GDScriptTokenizer::TK_NEWLINE && tokenizer->get_token(1) != GDScriptTokenizer::TK_EOF) { - _set_error("Expected \";\" or a line break."); return; } @@ -3003,7 +2918,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { tokenizer->advance(); int var_line = tokenizer->get_token_line(); if (!tokenizer->is_token_literal(0, true)) { - _set_error("Expected an identifier for the local variable name."); return; } @@ -3048,7 +2962,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { } if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ASSIGN) { - tokenizer->advance(); Node *subexpr = _parse_and_reduce_expression(p_block, p_static); if (!subexpr) { @@ -3061,7 +2974,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { lv->assignments++; assigned = subexpr; } else { - assigned = _get_default_value_for_type(lv->datatype, var_line); } //must be added later, to avoid self-referencing. @@ -3088,7 +3000,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { } break; case GDScriptTokenizer::TK_CF_IF: { - tokenizer->advance(); Node *condition = _parse_and_reduce_expression(p_block, p_static); @@ -3120,17 +3031,18 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { _parse_block(cf_if->body, p_static); current_block = p_block; - if (error_set) + if (error_set) { return; + } p_block->statements.push_back(cf_if); bool all_have_return = cf_if->body->has_return; bool have_else = false; while (true) { - - while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE && _parse_newline()) + while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE && _parse_newline()) { ; + } if (indent_level.back()->get().indent < current_level.indent) { //not at current indent level p_block->end_line = tokenizer->get_token_line(); @@ -3138,9 +3050,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { } if (tokenizer->get_token() == GDScriptTokenizer::TK_CF_ELIF) { - if (indent_level.back()->get().indent > current_level.indent) { - _set_error("Invalid indentation."); return; } @@ -3180,13 +3090,13 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { current_block = cf_else->body; _parse_block(cf_else->body, p_static); current_block = p_block; - if (error_set) + if (error_set) { return; + } all_have_return = all_have_return && cf_else->body->has_return; } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CF_ELSE) { - if (indent_level.back()->get().indent > current_level.indent) { _set_error("Invalid indentation."); return; @@ -3205,16 +3115,18 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { current_block = cf_if->body_else; _parse_block(cf_if->body_else, p_static); current_block = p_block; - if (error_set) + if (error_set) { return; + } all_have_return = all_have_return && cf_if->body_else->has_return; have_else = true; break; //after else, exit - } else + } else { break; + } } cf_if->body->has_return = all_have_return; @@ -3223,7 +3135,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { } break; case GDScriptTokenizer::TK_CF_WHILE: { - tokenizer->advance(); Node *condition2 = _parse_and_reduce_expression(p_block, p_static); if (!condition2) { @@ -3251,17 +3162,16 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { current_block = cf_while->body; _parse_block(cf_while->body, p_static); current_block = p_block; - if (error_set) + if (error_set) { return; + } p_block->has_return = cf_while->body->has_return; p_block->statements.push_back(cf_while); } break; case GDScriptTokenizer::TK_CF_FOR: { - tokenizer->advance(); if (!tokenizer->is_token_literal(0, true)) { - _set_error("Identifier expected after \"for\"."); } @@ -3288,7 +3198,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { DataType iter_type; if (container->type == Node::TYPE_OPERATOR) { - OperatorNode *op = static_cast<OperatorNode *>(container); if (op->op == OperatorNode::OP_CALL && op->arguments[0]->type == Node::TYPE_BUILT_IN_FUNCTION && static_cast<BuiltInFunctionNode *>(op->arguments[0])->function == GDScriptFunctions::GEN_RANGE) { //iterating a range, so see if range() can be optimized without allocating memory, by replacing it by vectors (which can work as iterable too!) @@ -3313,9 +3222,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { } if (args.size() > 0 && args.size() < 4) { - if (constant) { - ConstantNode *cn = alloc_node<ConstantNode>(); switch (args.size()) { case 1: @@ -3394,13 +3301,13 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { _parse_block(cf_for->body, p_static); current_block = p_block; - if (error_set) + if (error_set) { return; + } p_block->has_return = cf_for->body->has_return; p_block->statements.push_back(cf_for); } break; case GDScriptTokenizer::TK_CF_CONTINUE: { - _mark_line_as_safe(tokenizer->get_token_line()); tokenizer->advance(); ControlFlowNode *cf_continue = alloc_node<ControlFlowNode>(); @@ -3412,7 +3319,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { } } break; case GDScriptTokenizer::TK_CF_BREAK: { - _mark_line_as_safe(tokenizer->get_token_line()); tokenizer->advance(); ControlFlowNode *cf_break = alloc_node<ControlFlowNode>(); @@ -3424,7 +3330,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { } } break; case GDScriptTokenizer::TK_CF_RETURN: { - tokenizer->advance(); ControlFlowNode *cf_return = alloc_node<ControlFlowNode>(); cf_return->cf_type = ControlFlowNode::CF_RETURN; @@ -3456,7 +3361,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { } break; case GDScriptTokenizer::TK_CF_MATCH: { - tokenizer->advance(); MatchNode *match_node = alloc_node<MatchNode>(); @@ -3485,8 +3389,9 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { _parse_pattern_block(compiled_branches, match_node->branches, p_static); - if (error_set) + if (error_set) { return; + } ControlFlowNode *match_cf_node = alloc_node<ControlFlowNode>(); match_cf_node->cf_type = ControlFlowNode::CF_MATCH; @@ -3499,7 +3404,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { _end_statement(); } break; case GDScriptTokenizer::TK_PR_ASSERT: { - tokenizer->advance(); if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) { @@ -3543,7 +3447,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { } } break; case GDScriptTokenizer::TK_PR_BREAKPOINT: { - tokenizer->advance(); BreakpointNode *bn = alloc_node<BreakpointNode>(); p_block->statements.push_back(bn); @@ -3554,7 +3457,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { } } break; default: { - Node *expression = _parse_and_reduce_expression(p_block, p_static, false, true); if (!expression) { if (_recover_from_completion()) { @@ -3579,9 +3481,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { } bool GDScriptParser::_parse_newline() { - if (tokenizer->get_token(1) != GDScriptTokenizer::TK_EOF && tokenizer->get_token(1) != GDScriptTokenizer::TK_NEWLINE) { - IndentLevel current_level = indent_level.back()->get(); int indent = tokenizer->get_token_line_indent(); int tabs = tokenizer->get_token_line_tab_indent(); @@ -3598,9 +3498,7 @@ bool GDScriptParser::_parse_newline() { } if (indent < current_level.indent) { - while (indent < current_level.indent) { - //exit block if (indent_level.size() == 1) { _set_error("Invalid indentation. Bug?"); @@ -3610,7 +3508,6 @@ bool GDScriptParser::_parse_newline() { indent_level.pop_back(); if (indent_level.back()->get().indent < indent) { - _set_error("Unindent does not match any outer indentation level."); return false; } @@ -3633,15 +3530,12 @@ bool GDScriptParser::_parse_newline() { } void GDScriptParser::_parse_extends(ClassNode *p_class) { - if (p_class->extends_used) { - _set_error("\"extends\" can only be present once per script."); return; } if (!p_class->constant_expressions.empty() || !p_class->subclasses.empty() || !p_class->functions.empty() || !p_class->variables.empty()) { - _set_error("\"extends\" must be used before anything else."); return; } @@ -3658,10 +3552,8 @@ void GDScriptParser::_parse_extends(ClassNode *p_class) { // see if inheritance happens from a file if (tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT) { - Variant constant = tokenizer->get_token_constant(); if (constant.get_type() != Variant::STRING) { - _set_error("\"extends\" constant must be a string."); return; } @@ -3678,16 +3570,14 @@ void GDScriptParser::_parse_extends(ClassNode *p_class) { if (tokenizer->get_token() != GDScriptTokenizer::TK_PERIOD) { return; - } else + } else { tokenizer->advance(); + } } while (true) { - switch (tokenizer->get_token()) { - case GDScriptTokenizer::TK_IDENTIFIER: { - StringName identifier = tokenizer->get_token_identifier(); p_class->extends_class.push_back(identifier); } break; @@ -3696,7 +3586,6 @@ void GDScriptParser::_parse_extends(ClassNode *p_class) { break; default: { - _set_error("Invalid \"extends\" syntax, expected string constant (path) and/or identifier (parent class)."); return; } @@ -3705,7 +3594,6 @@ void GDScriptParser::_parse_extends(ClassNode *p_class) { tokenizer->advance(1); switch (tokenizer->get_token()) { - case GDScriptTokenizer::TK_IDENTIFIER: case GDScriptTokenizer::TK_PERIOD: continue; @@ -3717,14 +3605,13 @@ void GDScriptParser::_parse_extends(ClassNode *p_class) { } void GDScriptParser::_parse_class(ClassNode *p_class) { - IndentLevel current_level = indent_level.back()->get(); while (true) { - GDScriptTokenizer::Token token = tokenizer->get_token(); - if (error_set) + if (error_set) { return; + } if (current_level.indent > indent_level.back()->get().indent) { p_class->end_line = tokenizer->get_token_line(); @@ -3732,7 +3619,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } switch (token) { - case GDScriptTokenizer::TK_CURSOR: { tokenizer->advance(); } break; @@ -3752,11 +3638,11 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } } break; case GDScriptTokenizer::TK_PR_EXTENDS: { - _mark_line_as_safe(tokenizer->get_token_line()); _parse_extends(p_class); - if (error_set) + if (error_set) { return; + } if (!_end_statement()) { _set_end_statement_error("extends"); return; @@ -3764,7 +3650,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } break; case GDScriptTokenizer::TK_PR_CLASS_NAME: { - _mark_line_as_safe(tokenizer->get_token_line()); if (p_class->owner) { _set_error("\"class_name\" is only valid for the main class namespace."); @@ -3775,7 +3660,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { return; } if (tokenizer->get_token(1) != GDScriptTokenizer::TK_IDENTIFIER) { - _set_error("\"class_name\" syntax: \"class_name <UniqueName>\""); return; } @@ -3841,9 +3725,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } break; case GDScriptTokenizer::TK_PR_TOOL: { - if (p_class->tool) { - _set_error("The \"tool\" keyword can only be present once per script."); return; } @@ -3858,7 +3740,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { StringName name; if (tokenizer->get_token(1) != GDScriptTokenizer::TK_IDENTIFIER) { - _set_error("\"class\" syntax: \"class <Name>:\" or \"class <Name> extends <BaseClass>:\""); return; } @@ -3907,14 +3788,13 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { p_class->subclasses.push_back(newclass); if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_EXTENDS) { - _parse_extends(newclass); - if (error_set) + if (error_set) { return; + } } if (!_enter_indent_block()) { - _set_error("Indented block expected."); return; } @@ -3932,7 +3812,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { case GDScriptTokenizer::TK_PR_STATIC: { tokenizer->advance(); if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) { - _set_error("Expected \"func\"."); return; } @@ -3940,12 +3819,10 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { [[fallthrough]]; } case GDScriptTokenizer::TK_PR_FUNCTION: { - bool _static = false; pending_newline = -1; if (tokenizer->get_token(-1) == GDScriptTokenizer::TK_PR_STATIC) { - _static = true; } @@ -3956,7 +3833,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } if (name == StringName()) { - _set_error("Expected an identifier after \"func\" (syntax: \"func <identifier>([arguments]):\")."); return; } @@ -3989,7 +3865,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { #endif // DEBUG_ENABLED if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) { - _set_error("Expected \"(\" after the identifier (syntax: \"func <identifier>([arguments]):\" )."); return; } @@ -4009,19 +3884,16 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { //has arguments bool defaulting = false; while (true) { - if (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) { tokenizer->advance(); continue; } if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_VAR) { - tokenizer->advance(); //var before the identifier is allowed } if (!tokenizer->is_token_literal(0, true)) { - _set_error("Expected an identifier for an argument."); return; } @@ -4053,7 +3925,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { argument_types.push_back(argtype); if (defaulting && tokenizer->get_token() != GDScriptTokenizer::TK_OP_ASSIGN) { - _set_error("Default parameter expected."); return; } @@ -4064,8 +3935,9 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { defaulting = true; tokenizer->advance(1); Node *defval = _parse_and_reduce_expression(p_class, _static); - if (!defval || error_set) + if (!defval || error_set) { return; + } OperatorNode *on = alloc_node<OperatorNode>(); on->op = OperatorNode::OP_ASSIGN; @@ -4094,7 +3966,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { tokenizer->advance(); continue; } else if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { - _set_error("Expected \",\" or \")\"."); return; } @@ -4122,14 +3993,12 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; if (name == "_init") { - if (_static) { _set_error("The constructor cannot be static."); return; } if (p_class->extends_used) { - OperatorNode *cparent = alloc_node<OperatorNode>(); cparent->op = OperatorNode::OP_PARENT_CALL; block->statements.push_back(cparent); @@ -4150,7 +4019,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { //has arguments parenthesis++; while (true) { - current_function = function; Node *arg = _parse_and_reduce_expression(p_class, _static); current_function = nullptr; @@ -4160,7 +4028,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { tokenizer->advance(); continue; } else if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { - _set_error("Expected \",\" or \")\"."); return; } @@ -4173,9 +4040,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { tokenizer->advance(); } } else { - if (tokenizer->get_token() == GDScriptTokenizer::TK_PERIOD) { - _set_error("Parent constructor call found for a class without inheritance."); return; } @@ -4184,7 +4049,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { DataType return_type; if (tokenizer->get_token() == GDScriptTokenizer::TK_FORWARD_ARROW) { - if (!_parse_type(return_type, true)) { _set_error("Expected a return type for the function."); return; @@ -4192,17 +4056,17 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } if (!_enter_indent_block(block)) { - _set_error(vformat("Indented block expected after declaration of \"%s\" function.", function->name)); return; } function->return_type = return_type; - if (_static) + if (_static) { p_class->static_functions.push_back(function); - else + } else { p_class->functions.push_back(function); + } current_function = function; function->body = block; @@ -4268,11 +4132,9 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } } break; case GDScriptTokenizer::TK_PR_EXPORT: { - tokenizer->advance(); if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_OPEN) { - #define _ADVANCE_AND_CONSUME_NEWLINES \ do { \ tokenizer->advance(); \ @@ -4297,7 +4159,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_TYPE) { - Variant::Type type = tokenizer->get_token_type(); if (type == Variant::NIL) { _set_error("Can't export null type."); @@ -4316,11 +4177,8 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { _ADVANCE_AND_CONSUME_NEWLINES; switch (type) { - case Variant::INT: { - if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "FLAGS") { - _ADVANCE_AND_CONSUME_NEWLINES; if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) { @@ -4333,7 +4191,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { bool first = true; while (true) { - if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) { current_export = PropertyInfo(); _set_error("Expected a string constant in the named bit flags hint."); @@ -4341,16 +4198,18 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } String c = tokenizer->get_token_constant(); - if (!first) + if (!first) { current_export.hint_string += ","; - else + } else { first = false; + } current_export.hint_string += c.xml_escape(); _ADVANCE_AND_CONSUME_NEWLINES; - if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { break; + } if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) { current_export = PropertyInfo(); @@ -4364,7 +4223,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_2D_RENDER") { - _ADVANCE_AND_CONSUME_NEWLINES; if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { _set_error("Expected \")\" in the layers 2D render hint."); @@ -4375,7 +4233,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_2D_PHYSICS") { - _ADVANCE_AND_CONSUME_NEWLINES; if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { _set_error("Expected \")\" in the layers 2D physics hint."); @@ -4386,7 +4243,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_3D_RENDER") { - _ADVANCE_AND_CONSUME_NEWLINES; if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { _set_error("Expected \")\" in the layers 3D render hint."); @@ -4397,7 +4253,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_3D_PHYSICS") { - _ADVANCE_AND_CONSUME_NEWLINES; if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { _set_error("Expected \")\" in the layers 3D physics hint."); @@ -4412,25 +4267,25 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { current_export.hint = PROPERTY_HINT_ENUM; bool first = true; while (true) { - if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) { - current_export = PropertyInfo(); _set_error("Expected a string constant in the enumeration hint."); return; } String c = tokenizer->get_token_constant(); - if (!first) + if (!first) { current_export.hint_string += ","; - else + } else { first = false; + } current_export.hint_string += c.xml_escape(); _ADVANCE_AND_CONSUME_NEWLINES; - if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { break; + } if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) { current_export = PropertyInfo(); @@ -4447,7 +4302,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { [[fallthrough]]; } case Variant::FLOAT: { - if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "EASE") { current_export.hint = PROPERTY_HINT_EXP_EASING; _ADVANCE_AND_CONSUME_NEWLINES; @@ -4460,19 +4314,19 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { // range if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "EXP") { - current_export.hint = PROPERTY_HINT_EXP_RANGE; _ADVANCE_AND_CONSUME_NEWLINES; - if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { break; - else if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) { + } else if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) { _set_error("Expected \")\" or \",\" in the exponential range hint."); return; } _ADVANCE_AND_CONSUME_NEWLINES; - } else + } else { current_export.hint = PROPERTY_HINT_RANGE; + } float sign = 1.0; @@ -4481,7 +4335,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { _ADVANCE_AND_CONSUME_NEWLINES; } if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) { - current_export = PropertyInfo(); _set_error("Expected a range in the numeric hint."); return; @@ -4496,7 +4349,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) { - current_export = PropertyInfo(); _set_error("Expected \",\" or \")\" in the numeric range hint."); return; @@ -4511,7 +4363,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) { - current_export = PropertyInfo(); _set_error("Expected a number as upper bound in the numeric range hint."); return; @@ -4520,11 +4371,11 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { current_export.hint_string += "," + rtos(sign * double(tokenizer->get_token_constant())); _ADVANCE_AND_CONSUME_NEWLINES; - if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { break; + } if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) { - current_export = PropertyInfo(); _set_error("Expected \",\" or \")\" in the numeric range hint."); return; @@ -4538,7 +4389,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) { - current_export = PropertyInfo(); _set_error("Expected a number as step in the numeric range hint."); return; @@ -4549,30 +4399,29 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } break; case Variant::STRING: { - if (tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT && tokenizer->get_token_constant().get_type() == Variant::STRING) { //enumeration current_export.hint = PROPERTY_HINT_ENUM; bool first = true; while (true) { - if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) { - current_export = PropertyInfo(); _set_error("Expected a string constant in the enumeration hint."); return; } String c = tokenizer->get_token_constant(); - if (!first) + if (!first) { current_export.hint_string += ","; - else + } else { first = false; + } current_export.hint_string += c.xml_escape(); _ADVANCE_AND_CONSUME_NEWLINES; - if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { break; + } if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) { current_export = PropertyInfo(); @@ -4586,13 +4435,11 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "DIR") { - _ADVANCE_AND_CONSUME_NEWLINES; - if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { current_export.hint = PROPERTY_HINT_DIR; - else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { - + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { _ADVANCE_AND_CONSUME_NEWLINES; if (tokenizer->get_token() != GDScriptTokenizer::TK_IDENTIFIER || !(tokenizer->get_token_identifier() == "GLOBAL")) { @@ -4618,16 +4465,13 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "FILE") { - current_export.hint = PROPERTY_HINT_FILE; _ADVANCE_AND_CONSUME_NEWLINES; if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { - _ADVANCE_AND_CONSUME_NEWLINES; if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "GLOBAL") { - if (!p_class->tool) { _set_error("Global filesystem hints may only be used in tool scripts."); return; @@ -4635,22 +4479,22 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { current_export.hint = PROPERTY_HINT_GLOBAL_FILE; _ADVANCE_AND_CONSUME_NEWLINES; - if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) + if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { break; - else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { _ADVANCE_AND_CONSUME_NEWLINES; - else { + } else { _set_error("Expected \")\" or \",\" in the hint."); return; } } if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) { - - if (current_export.hint == PROPERTY_HINT_GLOBAL_FILE) + if (current_export.hint == PROPERTY_HINT_GLOBAL_FILE) { _set_error("Expected string constant with filter."); - else + } else { _set_error("Expected \"GLOBAL\" or string constant with filter."); + } return; } current_export.hint_string = tokenizer->get_token_constant(); @@ -4665,7 +4509,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "MULTILINE") { - current_export.hint = PROPERTY_HINT_MULTILINE_TEXT; _ADVANCE_AND_CONSUME_NEWLINES; if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { @@ -4676,9 +4519,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } } break; case Variant::COLOR: { - if (tokenizer->get_token() != GDScriptTokenizer::TK_IDENTIFIER) { - current_export = PropertyInfo(); _set_error("Color type hint expects RGB or RGBA as hints."); return; @@ -4698,7 +4539,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } break; default: { - current_export = PropertyInfo(); _set_error("Type \"" + Variant::get_type_name(type) + "\" can't take hints."); return; @@ -4707,7 +4547,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } } else { - parenthesis++; Node *subexpr = _parse_and_reduce_expression(p_class, true, true); if (!subexpr) { @@ -4767,10 +4606,11 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { bool first = true; for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { if (enum_values[E->get()].get_type() == Variant::INT) { - if (!first) + if (!first) { current_export.hint_string += ","; - else + } else { first = false; + } current_export.hint_string += E->get().operator String().camelcase_to_underscore(true).capitalize().xml_escape(); if (!is_flags) { @@ -4787,7 +4627,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { - current_export = PropertyInfo(); _set_error("Expected \")\" or \",\" after the export hint."); return; @@ -4809,7 +4648,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_ONREADY && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTE && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTER && tokenizer->get_token() != GDScriptTokenizer::TK_PR_PUPPET && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTESYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTERSYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_PUPPETSYNC) { - current_export = PropertyInfo(); _set_error("Expected \"var\", \"onready\", \"remote\", \"master\", \"puppet\", \"remotesync\", \"mastersync\", \"puppetsync\"."); return; @@ -4818,7 +4656,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { continue; } break; case GDScriptTokenizer::TK_PR_ONREADY: { - //may be fallthrough from export, ignore if so tokenizer->advance(); if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR) { @@ -4829,7 +4666,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { continue; } break; case GDScriptTokenizer::TK_PR_REMOTE: { - //may be fallthrough from export, ignore if so tokenizer->advance(); if (current_export.type) { @@ -4849,7 +4685,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { continue; } break; case GDScriptTokenizer::TK_PR_MASTER: { - //may be fallthrough from export, ignore if so tokenizer->advance(); if (current_export.type) { @@ -4869,7 +4704,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { continue; } break; case GDScriptTokenizer::TK_PR_PUPPET: { - //may be fallthrough from export, ignore if so tokenizer->advance(); if (current_export.type) { @@ -4889,14 +4723,14 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { continue; } break; case GDScriptTokenizer::TK_PR_REMOTESYNC: { - //may be fallthrough from export, ignore if so tokenizer->advance(); if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) { - if (current_export.type) + if (current_export.type) { _set_error("Expected \"var\"."); - else + } else { _set_error("Expected \"var\" or \"func\"."); + } return; } @@ -4904,14 +4738,14 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { continue; } break; case GDScriptTokenizer::TK_PR_MASTERSYNC: { - //may be fallthrough from export, ignore if so tokenizer->advance(); if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) { - if (current_export.type) + if (current_export.type) { _set_error("Expected \"var\"."); - else + } else { _set_error("Expected \"var\" or \"func\"."); + } return; } @@ -4919,14 +4753,14 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { continue; } break; case GDScriptTokenizer::TK_PR_PUPPETSYNC: { - //may be fallthrough from export, ignore if so tokenizer->advance(); if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) { - if (current_export.type) + if (current_export.type) { _set_error("Expected \"var\"."); - else + } else { _set_error("Expected \"var\" or \"func\"."); + } return; } @@ -4948,7 +4782,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { tokenizer->advance(); if (!tokenizer->is_token_literal(0, true)) { - _set_error("Expected an identifier for the member variable name."); return; } @@ -5038,7 +4871,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { #endif if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ASSIGN) { - #ifdef DEBUG_ENABLED int line = tokenizer->get_token_line(); #endif @@ -5054,12 +4886,10 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { //discourage common error if (!onready && subexpr->type == Node::TYPE_OPERATOR) { - OperatorNode *op = static_cast<OperatorNode *>(subexpr); if (op->op == OperatorNode::OP_CALL && op->arguments[0]->type == Node::TYPE_SELF && op->arguments[1]->type == Node::TYPE_IDENTIFIER) { IdentifierNode *id = static_cast<IdentifierNode *>(op->arguments[1]); if (id->name == "get_node") { - _set_error("Use \"onready var " + String(member.identifier) + " = get_node(...)\" instead."); return; } @@ -5069,22 +4899,20 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { member.expression = subexpr; if (autoexport && !member.data_type.has_type) { - if (subexpr->type != Node::TYPE_CONSTANT) { - _set_error("Type-less export needs a constant expression assigned to infer type."); return; } ConstantNode *cn = static_cast<ConstantNode *>(subexpr); if (cn->value.get_type() == Variant::NIL) { - _set_error("Can't accept a null constant expression for inferring export type."); return; } - if (!_reduce_export_var_type(cn->value, member.line)) + if (!_reduce_export_var_type(cn->value, member.line)) { return; + } member._export.type = cn->value.get_type(); member._export.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE; @@ -5101,7 +4929,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } #ifdef TOOLS_ENABLED if (subexpr->type == Node::TYPE_CONSTANT && (member._export.type != Variant::NIL || member.data_type.has_type)) { - ConstantNode *cn = static_cast<ConstantNode *>(subexpr); if (cn->value.get_type() != Variant::NIL) { if (member._export.type != Variant::NIL && cn->value.get_type() != member._export.type) { @@ -5131,20 +4958,21 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { #ifdef DEBUG_ENABLED NewLineNode *nl2 = alloc_node<NewLineNode>(); nl2->line = line; - if (onready) + if (onready) { p_class->ready->statements.push_back(nl2); - else + } else { p_class->initializer->statements.push_back(nl2); + } #endif - if (onready) + if (onready) { p_class->ready->statements.push_back(op); - else + } else { p_class->initializer->statements.push_back(op); + } member.initial_assignment = op; } else { - if (autoexport && !member.data_type.has_type) { _set_error("Type-less export needs a constant expression assigned to infer type."); return; @@ -5177,7 +5005,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_SETGET) { - tokenizer->advance(); if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) { @@ -5218,7 +5045,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { tokenizer->advance(); if (!tokenizer->is_token_literal(0, true)) { - _set_error("Expected an identifier for the constant."); return; } @@ -5334,14 +5160,11 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { while (true) { if (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) { - tokenizer->advance(); // Ignore newlines } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CURLY_BRACKET_CLOSE) { - tokenizer->advance(); break; // End of enum } else if (!tokenizer->is_token_literal(0, true)) { - if (tokenizer->get_token() == GDScriptTokenizer::TK_EOF) { _set_error("Unexpected end of file."); } else { @@ -5462,7 +5285,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } break; default: { - _set_error(String() + "Unexpected token: " + tokenizer->get_token_name(tokenizer->get_token()) + ":" + tokenizer->get_token_identifier()); return; @@ -5472,7 +5294,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive) { - if (p_class->base_type.has_type) { // Already determined } else if (p_class->extends_used) { @@ -5487,7 +5308,6 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive //path (and optionally subclasses) if (path.is_rel_path()) { - String base = base_path; if (base == "" || base.is_rel_path()) { @@ -5502,22 +5322,17 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive return; } if (!script->is_valid()) { - _set_error("Script isn't fully loaded (cyclic preload?): " + path, p_class->line); return; } if (p_class->extends_class.size()) { - for (int i = 0; i < p_class->extends_class.size(); i++) { - String sub = p_class->extends_class[i]; if (script->get_subclasses().has(sub)) { - Ref<Script> subclass = script->get_subclasses()[sub]; //avoid reference from disappearing script = subclass; } else { - _set_error("Couldn't find the subclass: " + sub, p_class->line); return; } @@ -5525,7 +5340,6 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive } } else { - if (p_class->extends_class.size() == 0) { _set_error("Parser bug: undecidable inheritance.", p_class->line); ERR_FAIL(); @@ -5572,7 +5386,6 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive } while (p) { - bool found = false; for (int i = 0; i < p->subclasses.size(); i++) { @@ -5601,10 +5414,12 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive } } - if (base_class) + if (base_class) { break; - if (found) + } + if (found) { continue; + } if (p->constant_expressions.has(base)) { if (p->constant_expressions[base].expression->type != Node::TYPE_CONSTANT) { @@ -5624,21 +5439,17 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive } if (base_script.is_valid()) { - String ident = base; Ref<GDScript> find_subclass = base_script; for (int i = extend_iter; i < p_class->extends_class.size(); i++) { - String subclass = p_class->extends_class[i]; ident += ("." + subclass); if (find_subclass->get_subclasses().has(subclass)) { - find_subclass = find_subclass->get_subclasses()[subclass]; } else if (find_subclass->get_constants().has(subclass)) { - Ref<GDScript> new_base_class = find_subclass->get_constants()[subclass]; if (new_base_class.is_null()) { _set_error("Constant isn't a class: " + ident, p_class->line); @@ -5646,7 +5457,6 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive } find_subclass = new_base_class; } else { - _set_error("Couldn't find the subclass: " + ident, p_class->line); return; } @@ -5655,15 +5465,12 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive script = find_subclass; } else if (!base_class) { - if (p_class->extends_class.size() > 1) { - _set_error("Invalid inheritance (unknown class + subclasses).", p_class->line); return; } //if not found, try engine classes if (!GDScriptLanguage::get_singleton()->get_global_map().has(base)) { - _set_error("Unknown class: \"" + base + "\"", p_class->line); return; } @@ -5706,12 +5513,14 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive } String GDScriptParser::DataType::to_string() const { - if (!has_type) + if (!has_type) { return "var"; + } switch (kind) { case BUILTIN: { - if (builtin_type == Variant::NIL) + if (builtin_type == Variant::NIL) { return "null"; + } return Variant::get_type_name(builtin_type); } break; case NATIVE: { @@ -5875,10 +5684,12 @@ bool GDScriptParser::_parse_type(DataType &r_type, bool p_can_be_void) { } GDScriptParser::DataType GDScriptParser::_resolve_type(const DataType &p_source, int p_line) { - if (!p_source.has_type) + if (!p_source.has_type) { return p_source; - if (p_source.kind != DataType::UNRESOLVED) + } + if (p_source.kind != DataType::UNRESOLVED) { return p_source; + } Vector<String> full_name = p_source.native_type.operator String().split(".", false); int name_part = 0; @@ -5887,7 +5698,6 @@ GDScriptParser::DataType GDScriptParser::_resolve_type(const DataType &p_source, result.has_type = true; while (name_part < full_name.size()) { - bool found = false; StringName id = full_name[name_part]; DataType base_type = result; @@ -6549,7 +6359,6 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) { DataType source_type = _reduce_node_type(cn->source_node); cn->cast_type = _resolve_type(cn->cast_type, cn->line); if (source_type.has_type) { - bool valid = false; if (check_types) { if (cn->cast_type.kind == DataType::BUILTIN && source_type.kind == DataType::BUILTIN) { @@ -6603,7 +6412,6 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) { } break; case OperatorNode::OP_IS: case OperatorNode::OP_IS_BUILTIN: { - if (op->arguments.size() != 2) { _set_error("Parser bug: binary operation without 2 arguments.", op->line); ERR_FAIL_V(DataType()); @@ -6639,7 +6447,6 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) { case OperatorNode::OP_POS: case OperatorNode::OP_NOT: case OperatorNode::OP_BIT_INVERT: { - DataType argument_type = _reduce_node_type(op->arguments[0]); if (!argument_type.has_type) { break; @@ -6677,7 +6484,6 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) { case OperatorNode::OP_BIT_AND: case OperatorNode::OP_BIT_OR: case OperatorNode::OP_BIT_XOR: { - if (op->arguments.size() != 2) { _set_error("Parser bug: binary operation without 2 arguments.", op->line); ERR_FAIL_V(DataType()); @@ -6745,7 +6551,6 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) { case OperatorNode::OP_ASSIGN_BIT_OR: case OperatorNode::OP_ASSIGN_BIT_XOR: case OperatorNode::OP_INIT_ASSIGN: { - _set_error("Assignment inside an expression isn't allowed (parser bug?).", op->line); return DataType(); @@ -6808,7 +6613,6 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) { } } break; case OperatorNode::OP_INDEX: { - if (op->arguments[1]->type == Node::TYPE_CONSTANT) { ConstantNode *cn = static_cast<ConstantNode *>(op->arguments[1]); if (cn->value.get_type() == Variant::STRING) { @@ -7007,7 +6811,6 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) { } bool GDScriptParser::_get_function_signature(DataType &p_base_type, const StringName &p_function, DataType &r_return_type, List<DataType> &r_arg_types, int &r_default_arg_count, bool &r_static, bool &r_vararg) const { - r_static = false; r_default_arg_count = 0; @@ -7118,8 +6921,9 @@ bool GDScriptParser::_get_function_signature(DataType &p_base_type, const String native = "_" + native.operator String(); } if (!ClassDB::class_exists(native)) { - if (!check_types) + if (!check_types) { return false; + } ERR_FAIL_V_MSG(false, "Parser bug: Class '" + String(native) + "' not found."); } @@ -7210,8 +7014,9 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat par_types.write[i - 1] = _reduce_node_type(p_call->arguments[i]); } - if (error_set) + if (error_set) { return DataType(); + } // Special case: check copy constructor. Those are defined implicitly in Variant. if (par_types.size() == 1) { @@ -7279,8 +7084,9 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat err += "' matches the signature '"; err += Variant::get_type_name(tn->vtype) + "("; for (int i = 0; i < par_types.size(); i++) { - if (i > 0) + if (i > 0) { err += ", "; + } err += par_types[i].to_string(); } err += ")'."; @@ -7520,8 +7326,9 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN while (base) { if (base->constant_expressions.has(p_member)) { - if (r_is_const) + if (r_is_const) { *r_is_const = true; + } r_member_type = base->constant_expressions[p_member].expression->get_datatype(); return true; } @@ -7640,8 +7447,9 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN native = "_" + native.operator String(); } if (!ClassDB::class_exists(native)) { - if (!check_types) + if (!check_types) { return false; + } ERR_FAIL_V_MSG(false, "Parser bug: Class \"" + String(native) + "\" not found."); } @@ -7729,7 +7537,6 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN } GDScriptParser::DataType GDScriptParser::_reduce_identifier_type(const DataType *p_base_type, const StringName &p_identifier, int p_line, bool p_is_indexing) { - if (p_base_type && !p_base_type->has_type) { return DataType(); } @@ -7903,7 +7710,6 @@ GDScriptParser::DataType GDScriptParser::_reduce_identifier_type(const DataType } void GDScriptParser::_check_class_level_types(ClassNode *p_class) { - // Names of internal object properties that we check to avoid overriding them. // "__meta__" could also be in here, but since it doesn't really affect object metadata, // it is okay to override it on script. @@ -7939,14 +7745,16 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) { // Function declarations for (int i = 0; i < p_class->static_functions.size(); i++) { _check_function_types(p_class->static_functions[i]); - if (error_set) + if (error_set) { return; + } } for (int i = 0; i < p_class->functions.size(); i++) { _check_function_types(p_class->functions[i]); - if (error_set) + if (error_set) { return; + } } // Class variables @@ -8005,6 +7813,10 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) { _set_error("The assigned value doesn't have a set type; the variable type can't be inferred.", v.line); return; } + if (expr_type.kind == DataType::BUILTIN && expr_type.builtin_type == Variant::NIL) { + _set_error("The variable type cannot be inferred because its value is \"null\".", v.line); + return; + } v.data_type = expr_type; v.data_type.is_constant = false; } @@ -8022,8 +7834,9 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) { } // Setter and getter - if (v.setter == StringName() && v.getter == StringName()) + if (v.setter == StringName() && v.getter == StringName()) { continue; + } bool found_getter = false; bool found_setter = false; @@ -8066,12 +7879,14 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) { return; } } - if (found_getter && found_setter) + if (found_getter && found_setter) { break; + } } - if ((found_getter || v.getter == StringName()) && (found_setter || v.setter == StringName())) + if ((found_getter || v.getter == StringName()) && (found_setter || v.setter == StringName())) { continue; + } // Check for static functions for (int j = 0; j < p_class->static_functions.size(); j++) { @@ -8102,14 +7917,14 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) { for (int i = 0; i < p_class->subclasses.size(); i++) { current_class = p_class->subclasses[i]; _check_class_level_types(current_class); - if (error_set) + if (error_set) { return; + } current_class = p_class; } } void GDScriptParser::_check_function_types(FunctionNode *p_function) { - p_function->return_type = _resolve_type(p_function->return_type, p_function->line); // Arguments @@ -8228,21 +8043,9 @@ void GDScriptParser::_check_function_types(FunctionNode *p_function) { p_function->return_type.has_type = false; p_function->return_type.may_yield = true; } - -#ifdef DEBUG_ENABLED - for (Map<StringName, LocalVarNode *>::Element *E = p_function->body->variables.front(); E; E = E->next()) { - LocalVarNode *lv = E->get(); - for (int i = 0; i < current_class->variables.size(); i++) { - if (current_class->variables[i].identifier == lv->name) { - _add_warning(GDScriptWarning::SHADOWED_VARIABLE, lv->line, lv->name, itos(current_class->variables[i].line)); - } - } - } -#endif // DEBUG_ENABLED } void GDScriptParser::_check_class_blocks_types(ClassNode *p_class) { - // Function blocks for (int i = 0; i < p_class->static_functions.size(); i++) { current_function = p_class->static_functions[i]; @@ -8251,8 +8054,9 @@ void GDScriptParser::_check_class_blocks_types(ClassNode *p_class) { _check_block_types(current_block); current_block = nullptr; current_function = nullptr; - if (error_set) + if (error_set) { return; + } } for (int i = 0; i < p_class->functions.size(); i++) { @@ -8262,8 +8066,9 @@ void GDScriptParser::_check_class_blocks_types(ClassNode *p_class) { _check_block_types(current_block); current_block = nullptr; current_function = nullptr; - if (error_set) + if (error_set) { return; + } } #ifdef DEBUG_ENABLED @@ -8284,8 +8089,9 @@ void GDScriptParser::_check_class_blocks_types(ClassNode *p_class) { for (int i = 0; i < p_class->subclasses.size(); i++) { current_class = p_class->subclasses[i]; _check_class_blocks_types(current_class); - if (error_set) + if (error_set) { return; + } current_class = p_class; } } @@ -8311,7 +8117,6 @@ static String _find_function_name(const GDScriptParser::OperatorNode *p_call) { #endif // DEBUG_ENABLED void GDScriptParser::_check_block_types(BlockNode *p_block) { - Node *last_var_assign = nullptr; // Check each statement @@ -8349,6 +8154,11 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) { if (lv->datatype.has_type && assign_type.may_yield && lv->assign->type == Node::TYPE_OPERATOR) { _add_warning(GDScriptWarning::FUNCTION_MAY_YIELD, lv->line, _find_function_name(static_cast<OperatorNode *>(lv->assign))); } + for (int i = 0; i < current_class->variables.size(); i++) { + if (current_class->variables[i].identifier == lv->name) { + _add_warning(GDScriptWarning::SHADOWED_VARIABLE, lv->line, lv->name, itos(current_class->variables[i].line)); + } + } #endif // DEBUG_ENABLED if (!_is_type_compatible(lv->datatype, assign_type)) { @@ -8394,6 +8204,10 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) { _set_error("The assigned value doesn't have a set type; the variable type can't be inferred.", lv->line); return; } + if (assign_type.kind == DataType::BUILTIN && assign_type.builtin_type == Variant::NIL) { + _set_error("The variable type cannot be inferred because its value is \"null\".", lv->line); + return; + } lv->datatype = assign_type; lv->datatype.is_constant = false; } @@ -8548,8 +8362,9 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) { _add_warning(GDScriptWarning::RETURN_VALUE_DISCARDED, op->line, func_name); } #endif // DEBUG_ENABLED - if (error_set) + if (error_set) { return; + } } break; case OperatorNode::OP_YIELD: { _mark_line_as_safe(op->line); @@ -8584,8 +8399,9 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) { } } - if (!function_type.has_type) + if (!function_type.has_type) { break; + } if (function_type.kind == DataType::BUILTIN && function_type.builtin_type == Variant::NIL) { // Return void, should not have arguments @@ -8645,8 +8461,9 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) { current_block = p_block->sub_blocks[i]; _check_block_types(current_block); current_block = p_block; - if (error_set) + if (error_set) { return; + } } #ifdef DEBUG_ENABLED @@ -8665,9 +8482,9 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) { } void GDScriptParser::_set_error(const String &p_error, int p_line, int p_column) { - - if (error_set) + if (error_set) { return; //allow no further errors + } error = p_error; error_line = p_line < 0 ? tokenizer->get_token_line() : p_line; @@ -8729,16 +8546,14 @@ void GDScriptParser::_add_warning(int p_code, int p_line, const Vector<String> & #endif // DEBUG_ENABLED String GDScriptParser::get_error() const { - return error; } int GDScriptParser::get_error_line() const { - return error_line; } -int GDScriptParser::get_error_column() const { +int GDScriptParser::get_error_column() const { return error_column; } @@ -8747,7 +8562,6 @@ bool GDScriptParser::has_error() const { } Error GDScriptParser::_parse(const String &p_base_path) { - base_path = p_base_path; //assume class @@ -8789,8 +8603,9 @@ Error GDScriptParser::_parse(const String &p_base_path) { current_function = nullptr; current_block = nullptr; - if (for_completion) + if (for_completion) { check_types = false; + } // Resolve all class-level stuff before getting into function blocks _check_class_level_types(main_class); @@ -8846,7 +8661,6 @@ Error GDScriptParser::_parse(const String &p_base_path) { } Error GDScriptParser::parse_bytecode(const Vector<uint8_t> &p_bytecode, const String &p_base_path, const String &p_self_path) { - clear(); self_path = p_self_path; @@ -8860,7 +8674,6 @@ Error GDScriptParser::parse_bytecode(const Vector<uint8_t> &p_bytecode, const St } Error GDScriptParser::parse(const String &p_code, const String &p_base_path, bool p_just_validate, const String &p_self_path, bool p_for_completion, Set<int> *r_safe_lines, bool p_dependencies_only) { - clear(); self_path = p_self_path; @@ -8881,19 +8694,15 @@ Error GDScriptParser::parse(const String &p_code, const String &p_base_path, boo } bool GDScriptParser::is_tool_script() const { - return (head && head->type == Node::TYPE_CLASS && static_cast<const ClassNode *>(head)->tool); } const GDScriptParser::Node *GDScriptParser::get_parse_tree() const { - return head; } void GDScriptParser::clear() { - while (list) { - Node *l = list; list = list->next; memdelete(l); @@ -8935,57 +8744,46 @@ void GDScriptParser::clear() { } GDScriptParser::CompletionType GDScriptParser::get_completion_type() { - return completion_type; } StringName GDScriptParser::get_completion_cursor() { - return completion_cursor; } int GDScriptParser::get_completion_line() { - return completion_line; } Variant::Type GDScriptParser::get_completion_built_in_constant() { - return completion_built_in_constant; } GDScriptParser::Node *GDScriptParser::get_completion_node() { - return completion_node; } GDScriptParser::BlockNode *GDScriptParser::get_completion_block() { - return completion_block; } GDScriptParser::ClassNode *GDScriptParser::get_completion_class() { - return completion_class; } GDScriptParser::FunctionNode *GDScriptParser::get_completion_function() { - return completion_function; } int GDScriptParser::get_completion_argument_index() { - return completion_argument; } bool GDScriptParser::get_completion_identifier_is_function() { - return completion_ident_is_call; } GDScriptParser::GDScriptParser() { - head = nullptr; list = nullptr; tokenizer = nullptr; @@ -8994,6 +8792,5 @@ GDScriptParser::GDScriptParser() { } GDScriptParser::~GDScriptParser() { - clear(); } diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index 035af30b6a..cfcca9584e 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -100,7 +100,6 @@ public: }; struct Node { - enum Type { TYPE_CLASS, TYPE_FUNCTION, @@ -139,7 +138,6 @@ public: struct OperatorNode; struct ClassNode : public Node { - bool tool; StringName name; bool extends_used; @@ -200,7 +198,6 @@ public: }; struct FunctionNode : public Node { - bool _static; MultiplayerAPI::RPCMode rpc_mode; bool has_yield; @@ -229,7 +226,6 @@ public: }; struct BlockNode : public Node { - ClassNode *parent_class = nullptr; BlockNode *parent_block = nullptr; List<Node *> statements; @@ -316,7 +312,6 @@ public: }; struct DictionaryNode : public Node { - struct Pair { Node *key; Node *value; @@ -406,7 +401,6 @@ public: }; struct PatternNode : public Node { - enum PatternType { PT_CONSTANT, PT_BIND, @@ -647,14 +641,16 @@ private: void _check_block_types(BlockNode *p_block); _FORCE_INLINE_ void _mark_line_as_safe(int p_line) const { #ifdef DEBUG_ENABLED - if (safe_lines) + if (safe_lines) { safe_lines->insert(p_line); + } #endif // DEBUG_ENABLED } _FORCE_INLINE_ void _mark_line_as_unsafe(int p_line) const { #ifdef DEBUG_ENABLED - if (safe_lines) + if (safe_lines) { safe_lines->erase(p_line); + } #endif // DEBUG_ENABLED } diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp index 1c8282e13e..2db42601c6 100644 --- a/modules/gdscript/gdscript_tokenizer.cpp +++ b/modules/gdscript/gdscript_tokenizer.cpp @@ -240,7 +240,6 @@ static const _kws _keyword_list[] = { }; const char *GDScriptTokenizer::get_token_name(Token p_token) { - ERR_FAIL_INDEX_V(p_token, TK_MAX, "<error>"); return token_names[p_token]; } @@ -364,27 +363,22 @@ StringName GDScriptTokenizer::get_token_literal(int p_offset) const { } static bool _is_text_char(CharType c) { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_'; } static bool _is_number(CharType c) { - return (c >= '0' && c <= '9'); } static bool _is_hex(CharType c) { - return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); } static bool _is_bin(CharType c) { - return (c == '0' || c == '1'); } void GDScriptTokenizerText::_make_token(Token p_type) { - TokenData &tk = tk_rb[tk_rb_pos]; tk.type = p_type; @@ -393,8 +387,8 @@ void GDScriptTokenizerText::_make_token(Token p_type) { tk_rb_pos = (tk_rb_pos + 1) % TK_RB_SIZE; } -void GDScriptTokenizerText::_make_identifier(const StringName &p_identifier) { +void GDScriptTokenizerText::_make_identifier(const StringName &p_identifier) { TokenData &tk = tk_rb[tk_rb_pos]; tk.type = TK_IDENTIFIER; @@ -406,7 +400,6 @@ void GDScriptTokenizerText::_make_identifier(const StringName &p_identifier) { } void GDScriptTokenizerText::_make_built_in_func(GDScriptFunctions::Function p_func) { - TokenData &tk = tk_rb[tk_rb_pos]; tk.type = TK_BUILT_IN_FUNC; @@ -416,8 +409,8 @@ void GDScriptTokenizerText::_make_built_in_func(GDScriptFunctions::Function p_fu tk_rb_pos = (tk_rb_pos + 1) % TK_RB_SIZE; } -void GDScriptTokenizerText::_make_constant(const Variant &p_constant) { +void GDScriptTokenizerText::_make_constant(const Variant &p_constant) { TokenData &tk = tk_rb[tk_rb_pos]; tk.type = TK_CONSTANT; @@ -429,7 +422,6 @@ void GDScriptTokenizerText::_make_constant(const Variant &p_constant) { } void GDScriptTokenizerText::_make_type(const Variant::Type &p_type) { - TokenData &tk = tk_rb[tk_rb_pos]; tk.type = TK_BUILT_IN_TYPE; @@ -441,7 +433,6 @@ void GDScriptTokenizerText::_make_type(const Variant::Type &p_type) { } void GDScriptTokenizerText::_make_error(const String &p_error) { - error_flag = true; last_error = p_error; @@ -454,7 +445,6 @@ void GDScriptTokenizerText::_make_error(const String &p_error) { } void GDScriptTokenizerText::_make_newline(int p_indentation, int p_tabs) { - TokenData &tk = tk_rb[tk_rb_pos]; tk.type = TK_NEWLINE; tk.constant = Vector2(p_indentation, p_tabs); @@ -464,7 +454,6 @@ void GDScriptTokenizerText::_make_newline(int p_indentation, int p_tabs) { } void GDScriptTokenizerText::_advance() { - if (error_flag) { //parser broke _make_error(last_error); @@ -482,7 +471,6 @@ void GDScriptTokenizerText::_advance() { column += m_amount; \ } while (true) { - bool is_string_name = false; StringMode string_mode = STRING_DOUBLE_QUOTE; @@ -570,7 +558,6 @@ void GDScriptTokenizerText::_advance() { return; } case '/': { - switch (GETCHAR(1)) { case '=': { // diveq @@ -587,13 +574,13 @@ void GDScriptTokenizerText::_advance() { _make_token(TK_OP_EQUAL); INCPOS(1); - } else + } else { _make_token(TK_OP_ASSIGN); + } } break; case '<': { if (GETCHAR(1) == '=') { - _make_token(TK_OP_LESS_EQUAL); INCPOS(1); } else if (GETCHAR(1) == '<') { @@ -604,8 +591,9 @@ void GDScriptTokenizerText::_advance() { _make_token(TK_OP_SHIFT_LEFT); } INCPOS(1); - } else + } else { _make_token(TK_OP_LESS); + } } break; case '>': { @@ -684,7 +672,6 @@ void GDScriptTokenizerText::_advance() { break; case '&': { if (GETCHAR(1) == '&') { - _make_token(TK_OP_AND); INCPOS(1); } else if (GETCHAR(1) == '=') { @@ -696,7 +683,6 @@ void GDScriptTokenizerText::_advance() { } break; case '|': { if (GETCHAR(1) == '|') { - _make_token(TK_OP_OR); INCPOS(1); } else if (GETCHAR(1) == '=') { @@ -707,7 +693,6 @@ void GDScriptTokenizerText::_advance() { } } break; case '*': { - if (GETCHAR(1) == '=') { _make_token(TK_OP_ASSIGN_MUL); INCPOS(1); @@ -716,7 +701,6 @@ void GDScriptTokenizerText::_advance() { } } break; case '+': { - if (GETCHAR(1) == '=') { _make_token(TK_OP_ASSIGN_ADD); INCPOS(1); @@ -731,7 +715,6 @@ void GDScriptTokenizerText::_advance() { } break; case '-': { - if (GETCHAR(1) == '=') { _make_token(TK_OP_ASSIGN_SUB); INCPOS(1); @@ -743,7 +726,6 @@ void GDScriptTokenizerText::_advance() { } } break; case '%': { - if (GETCHAR(1) == '=') { _make_token(TK_OP_ASSIGN_MOD); INCPOS(1); @@ -761,9 +743,9 @@ void GDScriptTokenizerText::_advance() { [[fallthrough]]; case '\'': case '"': { - - if (GETCHAR(0) == '\'') + if (GETCHAR(0) == '\'') { string_mode = STRING_SINGLE_QUOTE; + } int i = 1; if (string_mode == STRING_DOUBLE_QUOTE && GETCHAR(i) == '"' && GETCHAR(i + 1) == '"') { @@ -774,7 +756,6 @@ void GDScriptTokenizerText::_advance() { String str; while (true) { if (CharType(GETCHAR(i)) == 0) { - _make_error("Unterminated String"); return; } else if (string_mode == STRING_DOUBLE_QUOTE && CharType(GETCHAR(i)) == '"') { @@ -802,7 +783,6 @@ void GDScriptTokenizerText::_advance() { CharType res = 0; switch (next) { - case 'a': res = '\a'; break; @@ -869,14 +849,14 @@ void GDScriptTokenizerText::_advance() { column = 1; } break; default: { - _make_error("Invalid escape sequence"); return; } break; } - if (next != '\n') + if (next != '\n') { str += res; + } } else { if (CharType(GETCHAR(i)) == '\n') { @@ -901,7 +881,6 @@ void GDScriptTokenizerText::_advance() { _make_token(TK_CURSOR); } break; default: { - if (_is_number(GETCHAR(0)) || (GETCHAR(0) == '.' && _is_number(GETCHAR(1)))) { // parse number bool period_found = false; @@ -933,7 +912,6 @@ void GDScriptTokenizerText::_advance() { } hexa_found = true; } else if (hexa_found && _is_hex(GETCHAR(i))) { - } else if (!hexa_found && GETCHAR(i) == 'b') { if (bin_found || str.length() != 1 || !((i == 1 && str[0] == '0') || (i == 2 && str[1] == '0' && str[0] == '-'))) { _make_error("Invalid numeric constant at 'b'"); @@ -950,7 +928,6 @@ void GDScriptTokenizerText::_advance() { //all ok } else if (bin_found && _is_bin(GETCHAR(i))) { - } else if ((GETCHAR(i) == '-' || GETCHAR(i) == '+') && exponent_found) { if (sign_found) { _make_error("Invalid numeric constant at '-'"); @@ -960,8 +937,9 @@ void GDScriptTokenizerText::_advance() { } else if (GETCHAR(i) == '_') { i++; continue; // Included for readability, shouldn't be a part of the string - } else + } else { break; + } str += CharType(GETCHAR(i)); i++; @@ -1018,15 +996,12 @@ void GDScriptTokenizerText::_advance() { } else if (str == "false") { _make_constant(false); } else { - bool found = false; { - int idx = 0; while (_type_list[idx].text) { - if (str == _type_list[idx].text) { _make_type(_type_list[idx].type); found = true; @@ -1037,13 +1012,10 @@ void GDScriptTokenizerText::_advance() { } if (!found) { - //built in func? for (int j = 0; j < GDScriptFunctions::FUNC_MAX; j++) { - if (str == GDScriptFunctions::get_func_name(GDScriptFunctions::Function(j))) { - _make_built_in_func(GDScriptFunctions::Function(j)); found = true; break; @@ -1058,7 +1030,6 @@ void GDScriptTokenizerText::_advance() { found = false; while (_keyword_list[idx].text) { - if (str == _keyword_list[idx].text) { _make_token(_keyword_list[idx].token); found = true; @@ -1068,8 +1039,9 @@ void GDScriptTokenizerText::_advance() { } } - if (!found) + if (!found) { identifier = true; + } } if (identifier) { @@ -1091,7 +1063,6 @@ void GDScriptTokenizerText::_advance() { } void GDScriptTokenizerText::set_code(const String &p_code) { - code = p_code; len = p_code.length(); if (len) { @@ -1108,8 +1079,9 @@ void GDScriptTokenizerText::set_code(const String &p_code) { ignore_warnings = false; #endif // DEBUG_ENABLED last_error = ""; - for (int i = 0; i < MAX_LOOKAHEAD + 1; i++) + for (int i = 0; i < MAX_LOOKAHEAD + 1; i++) { _advance(); + } } GDScriptTokenizerText::Token GDScriptTokenizerText::get_token(int p_offset) const { @@ -1146,7 +1118,6 @@ const Variant &GDScriptTokenizerText::get_token_constant(int p_offset) const { } StringName GDScriptTokenizerText::get_token_identifier(int p_offset) const { - ERR_FAIL_COND_V(p_offset <= -MAX_LOOKAHEAD, StringName()); ERR_FAIL_COND_V(p_offset >= MAX_LOOKAHEAD, StringName()); @@ -1156,7 +1127,6 @@ StringName GDScriptTokenizerText::get_token_identifier(int p_offset) const { } GDScriptFunctions::Function GDScriptTokenizerText::get_token_built_in_func(int p_offset) const { - ERR_FAIL_COND_V(p_offset <= -MAX_LOOKAHEAD, GDScriptFunctions::FUNC_MAX); ERR_FAIL_COND_V(p_offset >= MAX_LOOKAHEAD, GDScriptFunctions::FUNC_MAX); @@ -1166,7 +1136,6 @@ GDScriptFunctions::Function GDScriptTokenizerText::get_token_built_in_func(int p } Variant::Type GDScriptTokenizerText::get_token_type(int p_offset) const { - ERR_FAIL_COND_V(p_offset <= -MAX_LOOKAHEAD, Variant::NIL); ERR_FAIL_COND_V(p_offset >= MAX_LOOKAHEAD, Variant::NIL); @@ -1176,7 +1145,6 @@ Variant::Type GDScriptTokenizerText::get_token_type(int p_offset) const { } int GDScriptTokenizerText::get_token_line_indent(int p_offset) const { - ERR_FAIL_COND_V(p_offset <= -MAX_LOOKAHEAD, 0); ERR_FAIL_COND_V(p_offset >= MAX_LOOKAHEAD, 0); @@ -1186,7 +1154,6 @@ int GDScriptTokenizerText::get_token_line_indent(int p_offset) const { } int GDScriptTokenizerText::get_token_line_tab_indent(int p_offset) const { - ERR_FAIL_COND_V(p_offset <= -MAX_LOOKAHEAD, 0); ERR_FAIL_COND_V(p_offset >= MAX_LOOKAHEAD, 0); @@ -1196,7 +1163,6 @@ int GDScriptTokenizerText::get_token_line_tab_indent(int p_offset) const { } String GDScriptTokenizerText::get_token_error(int p_offset) const { - ERR_FAIL_COND_V(p_offset <= -MAX_LOOKAHEAD, String()); ERR_FAIL_COND_V(p_offset >= MAX_LOOKAHEAD, String()); @@ -1206,10 +1172,10 @@ String GDScriptTokenizerText::get_token_error(int p_offset) const { } void GDScriptTokenizerText::advance(int p_amount) { - ERR_FAIL_COND(p_amount <= 0); - for (int i = 0; i < p_amount; i++) + for (int i = 0; i < p_amount; i++) { _advance(); + } } ////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1217,7 +1183,6 @@ void GDScriptTokenizerText::advance(int p_amount) { #define BYTECODE_VERSION 13 Error GDScriptTokenizerBuffer::set_code_buffer(const Vector<uint8_t> &p_buffer) { - const uint8_t *buf = p_buffer.ptr(); int total_len = p_buffer.size(); ERR_FAIL_COND_V(p_buffer.size() < 24 || p_buffer[0] != 'G' || p_buffer[1] != 'D' || p_buffer[2] != 'S' || p_buffer[3] != 'C', ERR_INVALID_DATA); @@ -1235,7 +1200,6 @@ Error GDScriptTokenizerBuffer::set_code_buffer(const Vector<uint8_t> &p_buffer) identifiers.resize(identifier_count); for (int i = 0; i < identifier_count; i++) { - int len = decode_uint32(b); ERR_FAIL_COND_V(len > total_len, ERR_INVALID_DATA); b += 4; @@ -1255,13 +1219,13 @@ Error GDScriptTokenizerBuffer::set_code_buffer(const Vector<uint8_t> &p_buffer) constants.resize(constant_count); for (int i = 0; i < constant_count; i++) { - Variant v; int len; // An object cannot be constant, never decode objects Error err = decode_variant(v, b, total_len, &len, false); - if (err) + if (err) { return err; + } b += len; total_len -= len; constants.write[i] = v; @@ -1270,7 +1234,6 @@ Error GDScriptTokenizerBuffer::set_code_buffer(const Vector<uint8_t> &p_buffer) ERR_FAIL_COND_V(line_count * 8 > total_len, ERR_INVALID_DATA); for (int i = 0; i < line_count; i++) { - uint32_t token = decode_uint32(b); b += 4; uint32_t linecol = decode_uint32(b); @@ -1283,7 +1246,6 @@ Error GDScriptTokenizerBuffer::set_code_buffer(const Vector<uint8_t> &p_buffer) tokens.resize(token_count); for (int i = 0; i < token_count; i++) { - ERR_FAIL_COND_V(total_len < 1, ERR_INVALID_DATA); if ((*b) & TOKEN_BYTE_MASK) { //little endian always @@ -1304,7 +1266,6 @@ Error GDScriptTokenizerBuffer::set_code_buffer(const Vector<uint8_t> &p_buffer) } Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code) { - Vector<uint8_t> buf; Map<StringName, int> identifier_map; @@ -1317,16 +1278,13 @@ Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code) int line = -1; while (true) { - if (tt.get_token_line() != line) { - line = tt.get_token_line(); line_map[line] = token_array.size(); } uint32_t token = tt.get_token(); switch (tt.get_token()) { - case TK_IDENTIFIER: { StringName id = tt.get_token_identifier(); if (!identifier_map.has(id)) { @@ -1336,7 +1294,6 @@ Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code) token |= identifier_map[id] << TOKEN_BITS; } break; case TK_CONSTANT: { - const Variant &c = tt.get_token_constant(); if (!constant_map.has(c)) { int idx = constant_map.size(); @@ -1345,20 +1302,16 @@ Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code) token |= constant_map[c] << TOKEN_BITS; } break; case TK_BUILT_IN_TYPE: { - token |= tt.get_token_type() << TOKEN_BITS; } break; case TK_BUILT_IN_FUNC: { - token |= tt.get_token_built_in_func() << TOKEN_BITS; } break; case TK_NEWLINE: { - token |= tt.get_token_line_indent() << TOKEN_BITS; } break; case TK_ERROR: { - ERR_FAIL_V(Vector<uint8_t>()); } break; default: { @@ -1367,8 +1320,9 @@ Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code) token_array.push_back(token); - if (tt.get_token() == TK_EOF) + if (tt.get_token() == TK_EOF) { break; + } tt.advance(); } @@ -1405,12 +1359,12 @@ Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code) //save identifiers for (Map<int, StringName>::Element *E = rev_identifier_map.front(); E; E = E->next()) { - CharString cs = String(E->get()).utf8(); int len = cs.length() + 1; int extra = 4 - (len % 4); - if (extra == 4) + if (extra == 4) { extra = 0; + } uint8_t ibuf[4]; encode_uint32(len + extra, ibuf); @@ -1426,7 +1380,6 @@ Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code) } for (Map<int, Variant>::Element *E = rev_constant_map.front(); E; E = E->next()) { - int len; // Objects cannot be constant, never encode objects Error err = encode_variant(E->get(), nullptr, len, false); @@ -1437,16 +1390,15 @@ Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code) } for (Map<int, uint32_t>::Element *E = rev_line_map.front(); E; E = E->next()) { - uint8_t ibuf[8]; encode_uint32(E->key(), &ibuf[0]); encode_uint32(E->get(), &ibuf[4]); - for (int i = 0; i < 8; i++) + for (int i = 0; i < 8; i++) { buf.push_back(ibuf[i]); + } } for (int i = 0; i < token_array.size(); i++) { - uint32_t token = token_array[i]; if (token & ~TOKEN_MASK) { @@ -1464,17 +1416,16 @@ Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code) } GDScriptTokenizerBuffer::Token GDScriptTokenizerBuffer::get_token(int p_offset) const { - int offset = token + p_offset; - if (offset < 0 || offset >= tokens.size()) + if (offset < 0 || offset >= tokens.size()) { return TK_EOF; + } return GDScriptTokenizerBuffer::Token(tokens[offset] & TOKEN_MASK); } StringName GDScriptTokenizerBuffer::get_token_identifier(int p_offset) const { - int offset = token + p_offset; ERR_FAIL_INDEX_V(offset, tokens.size(), StringName()); @@ -1485,14 +1436,12 @@ StringName GDScriptTokenizerBuffer::get_token_identifier(int p_offset) const { } GDScriptFunctions::Function GDScriptTokenizerBuffer::get_token_built_in_func(int p_offset) const { - int offset = token + p_offset; ERR_FAIL_INDEX_V(offset, tokens.size(), GDScriptFunctions::FUNC_MAX); return GDScriptFunctions::Function(tokens[offset] >> TOKEN_BITS); } Variant::Type GDScriptTokenizerBuffer::get_token_type(int p_offset) const { - int offset = token + p_offset; ERR_FAIL_INDEX_V(offset, tokens.size(), Variant::NIL); @@ -1500,55 +1449,57 @@ Variant::Type GDScriptTokenizerBuffer::get_token_type(int p_offset) const { } int GDScriptTokenizerBuffer::get_token_line(int p_offset) const { - int offset = token + p_offset; int pos = lines.find_nearest(offset); - if (pos < 0) + if (pos < 0) { return -1; - if (pos >= lines.size()) + } + if (pos >= lines.size()) { pos = lines.size() - 1; + } uint32_t l = lines.getv(pos); return l & TOKEN_LINE_MASK; } -int GDScriptTokenizerBuffer::get_token_column(int p_offset) const { +int GDScriptTokenizerBuffer::get_token_column(int p_offset) const { int offset = token + p_offset; int pos = lines.find_nearest(offset); - if (pos < 0) + if (pos < 0) { return -1; - if (pos >= lines.size()) + } + if (pos >= lines.size()) { pos = lines.size() - 1; + } uint32_t l = lines.getv(pos); return l >> TOKEN_LINE_BITS; } -int GDScriptTokenizerBuffer::get_token_line_indent(int p_offset) const { +int GDScriptTokenizerBuffer::get_token_line_indent(int p_offset) const { int offset = token + p_offset; ERR_FAIL_INDEX_V(offset, tokens.size(), 0); return tokens[offset] >> TOKEN_BITS; } -const Variant &GDScriptTokenizerBuffer::get_token_constant(int p_offset) const { +const Variant &GDScriptTokenizerBuffer::get_token_constant(int p_offset) const { int offset = token + p_offset; ERR_FAIL_INDEX_V(offset, tokens.size(), nil); uint32_t constant = tokens[offset] >> TOKEN_BITS; ERR_FAIL_UNSIGNED_INDEX_V(constant, (uint32_t)constants.size(), nil); return constants[constant]; } -String GDScriptTokenizerBuffer::get_token_error(int p_offset) const { +String GDScriptTokenizerBuffer::get_token_error(int p_offset) const { ERR_FAIL_V(String()); } void GDScriptTokenizerBuffer::advance(int p_amount) { - ERR_FAIL_INDEX(p_amount + token, tokens.size()); token += p_amount; } -GDScriptTokenizerBuffer::GDScriptTokenizerBuffer() { +GDScriptTokenizerBuffer::GDScriptTokenizerBuffer() { token = 0; } diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h index 76410433de..32603c010f 100644 --- a/modules/gdscript/gdscript_tokenizer.h +++ b/modules/gdscript/gdscript_tokenizer.h @@ -180,7 +180,6 @@ public: }; class GDScriptTokenizerText : public GDScriptTokenizer { - enum { MAX_LOOKAHEAD = 4, TK_RB_SIZE = MAX_LOOKAHEAD * 2 + 1 @@ -252,7 +251,6 @@ public: }; class GDScriptTokenizerBuffer : public GDScriptTokenizer { - enum { TOKEN_BYTE_MASK = 0x80, diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp index a6b749059a..f87e8687e5 100644 --- a/modules/gdscript/language_server/gdscript_extend_parser.cpp +++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp @@ -35,7 +35,6 @@ #include "gdscript_workspace.h" void ExtendGDScriptParser::update_diagnostics() { - diagnostics.clear(); if (has_error()) { @@ -80,12 +79,10 @@ void ExtendGDScriptParser::update_diagnostics() { } void ExtendGDScriptParser::update_symbols() { - members.clear(); const GDScriptParser::Node *head = get_parse_tree(); if (const GDScriptParser::ClassNode *gdclass = dynamic_cast<const GDScriptParser::ClassNode *>(head)) { - parse_class_symbol(gdclass, class_symbol); for (int i = 0; i < class_symbol.children.size(); i++) { @@ -141,15 +138,15 @@ void ExtendGDScriptParser::update_document_links(const String &p_code) { } void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p_class, lsp::DocumentSymbol &r_symbol) { - const String uri = get_uri(); r_symbol.uri = uri; r_symbol.script_path = path; r_symbol.children.clear(); r_symbol.name = p_class->name; - if (r_symbol.name.empty()) + if (r_symbol.name.empty()) { r_symbol.name = path.get_file(); + } r_symbol.kind = lsp::SymbolKind::Class; r_symbol.deprecated = false; r_symbol.range.start.line = LINE_NUMBER_TO_INDEX(p_class->line); @@ -161,7 +158,6 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p r_symbol.documentation = parse_documentation(is_root_class ? 0 : LINE_NUMBER_TO_INDEX(p_class->line), is_root_class); for (int i = 0; i < p_class->variables.size(); ++i) { - const GDScriptParser::ClassNode::Member &m = p_class->variables[i]; lsp::DocumentSymbol symbol; @@ -289,7 +285,6 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p } void ExtendGDScriptParser::parse_function_symbol(const GDScriptParser::FunctionNode *p_func, lsp::DocumentSymbol &r_symbol) { - const String uri = get_uri(); r_symbol.name = p_func->name; @@ -384,9 +379,9 @@ String ExtendGDScriptParser::parse_documentation(int p_line, bool p_docs_down) { int step = p_docs_down ? 1 : -1; int start_line = p_docs_down ? p_line : p_line - 1; for (int i = start_line; true; i += step) { - - if (i < 0 || i >= lines.size()) + if (i < 0 || i >= lines.size()) { break; + } String line_comment = lines[i].strip_edges(true, false); if (line_comment.begins_with("#")) { @@ -409,22 +404,20 @@ String ExtendGDScriptParser::parse_documentation(int p_line, bool p_docs_down) { } String ExtendGDScriptParser::get_text_for_completion(const lsp::Position &p_cursor) const { - String longthing; int len = lines.size(); for (int i = 0; i < len; i++) { - if (i == p_cursor.line) { longthing += lines[i].substr(0, p_cursor.character); longthing += String::chr(0xFFFF); //not unicode, represents the cursor longthing += lines[i].substr(p_cursor.character, lines[i].size()); } else { - longthing += lines[i]; } - if (i != len - 1) + if (i != len - 1) { longthing += "\n"; + } } return longthing; @@ -434,7 +427,6 @@ String ExtendGDScriptParser::get_text_for_lookup_symbol(const lsp::Position &p_c String longthing; int len = lines.size(); for (int i = 0; i < len; i++) { - if (i == p_cursor.line) { String line = lines[i]; String first_part = line.substr(0, p_cursor.character); @@ -458,19 +450,18 @@ String ExtendGDScriptParser::get_text_for_lookup_symbol(const lsp::Position &p_c } longthing += last_part; } else { - longthing += lines[i]; } - if (i != len - 1) + if (i != len - 1) { longthing += "\n"; + } } return longthing; } String ExtendGDScriptParser::get_identifier_under_position(const lsp::Position &p_position, Vector2i &p_offset) const { - ERR_FAIL_INDEX_V(p_position.line, lines.size(), ""); String line = lines[p_position.line]; ERR_FAIL_INDEX_V(p_position.character, line.size(), ""); @@ -525,7 +516,6 @@ const lsp::DocumentSymbol *ExtendGDScriptParser::search_symbol_defined_at_line(i } Error ExtendGDScriptParser::get_left_function_call(const lsp::Position &p_position, lsp::Position &r_func_pos, int &r_arg_index) const { - ERR_FAIL_INDEX_V(p_position.line, lines.size(), ERR_INVALID_PARAMETER); int bracket_stack = 0; @@ -577,7 +567,6 @@ const lsp::DocumentSymbol *ExtendGDScriptParser::get_symbol_defined_at_line(int } const lsp::DocumentSymbol *ExtendGDScriptParser::get_member_symbol(const String &p_name, const String &p_subclass) const { - if (p_subclass.empty()) { const lsp::DocumentSymbol *const *ptr = members.getptr(p_name); if (ptr) { @@ -600,12 +589,9 @@ const List<lsp::DocumentLink> &ExtendGDScriptParser::get_document_links() const } const Array &ExtendGDScriptParser::get_member_completions() { - if (member_completions.empty()) { - const String *name = members.next(nullptr); while (name) { - const lsp::DocumentSymbol *symbol = members.get(*name); lsp::CompletionItem item = symbol->make_completion_item(); item.data = JOIN_SYMBOLS(path, *name); @@ -616,7 +602,6 @@ const Array &ExtendGDScriptParser::get_member_completions() { const String *_class = inner_classes.next(nullptr); while (_class) { - const ClassMembers *inner_class = inner_classes.getptr(*_class); const String *member_name = inner_class->next(nullptr); while (member_name) { @@ -697,7 +682,6 @@ Dictionary ExtendGDScriptParser::dump_class_api(const GDScriptParser::ClassNode Array constants; for (Map<StringName, GDScriptParser::ClassNode::Constant>::Element *E = p_class->constant_expressions.front(); E; E = E->next()) { - const GDScriptParser::ClassNode::Constant &c = E->value(); const GDScriptParser::ConstantNode *node = dynamic_cast<const GDScriptParser::ConstantNode *>(c.expression); ERR_FAIL_COND_V(!node, class_api); @@ -766,7 +750,6 @@ Dictionary ExtendGDScriptParser::dump_class_api(const GDScriptParser::ClassNode } Dictionary ExtendGDScriptParser::generate_api() const { - Dictionary api; const GDScriptParser::Node *head = get_parse_tree(); if (const GDScriptParser::ClassNode *gdclass = dynamic_cast<const GDScriptParser::ClassNode *>(head)) { diff --git a/modules/gdscript/language_server/gdscript_extend_parser.h b/modules/gdscript/language_server/gdscript_extend_parser.h index 43dfce994b..0c031d7883 100644 --- a/modules/gdscript/language_server/gdscript_extend_parser.h +++ b/modules/gdscript/language_server/gdscript_extend_parser.h @@ -50,7 +50,6 @@ typedef HashMap<String, const lsp::DocumentSymbol *> ClassMembers; class ExtendGDScriptParser : public GDScriptParser { - String path; Vector<String> lines; diff --git a/modules/gdscript/language_server/gdscript_language_protocol.cpp b/modules/gdscript/language_server/gdscript_language_protocol.cpp index 69662e96f7..35bf4287b8 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.cpp +++ b/modules/gdscript/language_server/gdscript_language_protocol.cpp @@ -47,10 +47,11 @@ Error GDScriptLanguageProtocol::LSPeer::handle_data() { ERR_FAIL_COND_V_MSG(true, ERR_OUT_OF_MEMORY, "Response header too big"); } Error err = connection->get_partial_data(&req_buf[req_pos], 1, read); - if (err != OK) + if (err != OK) { return FAILED; - else if (read != 1) // Busy, wait until next poll + } else if (read != 1) { // Busy, wait until next poll return ERR_BUSY; + } char *r = (char *)req_buf; int l = req_pos; @@ -75,10 +76,11 @@ Error GDScriptLanguageProtocol::LSPeer::handle_data() { ERR_FAIL_COND_V_MSG(req_pos >= LSP_MAX_BUFFER_SIZE, ERR_OUT_OF_MEMORY, "Response content too big"); } Error err = connection->get_partial_data(&req_buf[req_pos], 1, read); - if (err != OK) + if (err != OK) { return FAILED; - else if (read != 1) + } else if (read != 1) { return ERR_BUSY; + } req_pos++; } @@ -145,7 +147,6 @@ String GDScriptLanguageProtocol::process_message(const String &p_text) { } String GDScriptLanguageProtocol::format_output(const String &p_text) { - String header = "Content-Length: "; CharString charstr = p_text.utf8(); size_t len = charstr.length(); @@ -168,7 +169,6 @@ void GDScriptLanguageProtocol::_bind_methods() { } Dictionary GDScriptLanguageProtocol::initialize(const Dictionary &p_params) { - lsp::InitializeResult ret; String root_uri = p_params["rootUri"]; @@ -183,7 +183,6 @@ Dictionary GDScriptLanguageProtocol::initialize(const Dictionary &p_params) { if (root_uri.length() && is_same_workspace) { workspace->root_uri = root_uri; } else { - workspace->root_uri = "file://" + workspace->root; Dictionary params; @@ -208,12 +207,10 @@ Dictionary GDScriptLanguageProtocol::initialize(const Dictionary &p_params) { } void GDScriptLanguageProtocol::initialized(const Variant &p_params) { - lsp::GodotCapabilities capabilities; DocData *doc = EditorHelp::get_doc_data(); for (Map<String, DocData::ClassDoc>::Element *E = doc->class_list.front(); E; E = E->next()) { - lsp::GodotNativeClassInfo gdclass; gdclass.name = E->get().name; gdclass.class_doc = &(E->get()); diff --git a/modules/gdscript/language_server/gdscript_language_server.cpp b/modules/gdscript/language_server/gdscript_language_server.cpp index e1d86ecdd4..d53914814f 100644 --- a/modules/gdscript/language_server/gdscript_language_server.cpp +++ b/modules/gdscript/language_server/gdscript_language_server.cpp @@ -48,7 +48,6 @@ GDScriptLanguageServer::GDScriptLanguageServer() { } void GDScriptLanguageServer::_notification(int p_what) { - switch (p_what) { case NOTIFICATION_ENTER_TREE: start(); diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp index f065b33570..778cb4d254 100644 --- a/modules/gdscript/language_server/gdscript_text_document.cpp +++ b/modules/gdscript/language_server/gdscript_text_document.cpp @@ -85,19 +85,15 @@ void GDScriptTextDocument::notify_client_show_symbol(const lsp::DocumentSymbol * } void GDScriptTextDocument::initialize() { - if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) { - const HashMap<StringName, ClassMembers> &native_members = GDScriptLanguageProtocol::get_singleton()->get_workspace()->native_members; const StringName *class_ptr = native_members.next(nullptr); while (class_ptr) { - const ClassMembers &members = native_members.get(*class_ptr); const String *name = members.next(nullptr); while (name) { - const lsp::DocumentSymbol *symbol = members.get(*name); lsp::CompletionItem item = symbol->make_completion_item(); item.data = JOIN_SYMBOLS(String(*class_ptr), *name); @@ -112,7 +108,6 @@ void GDScriptTextDocument::initialize() { } Variant GDScriptTextDocument::nativeSymbol(const Dictionary &p_params) { - Variant ret; lsp::NativeSymbolInspectParams params; @@ -142,7 +137,6 @@ Array GDScriptTextDocument::documentSymbol(const Dictionary &p_params) { } Array GDScriptTextDocument::completion(const Dictionary &p_params) { - Array arr; lsp::CompletionParams params; @@ -153,12 +147,10 @@ Array GDScriptTextDocument::completion(const Dictionary &p_params) { GDScriptLanguageProtocol::get_singleton()->get_workspace()->completion(params, &options); if (!options.empty()) { - int i = 0; arr.resize(options.size()); for (const List<ScriptCodeCompletionOption>::Element *E = options.front(); E; E = E->next()) { - const ScriptCodeCompletionOption &option = E->get(); lsp::CompletionItem item; item.label = option.display; @@ -201,11 +193,9 @@ Array GDScriptTextDocument::completion(const Dictionary &p_params) { i++; } } else if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) { - arr = native_member_completions.duplicate(); for (Map<String, ExtendGDScriptParser *>::Element *E = GDScriptLanguageProtocol::get_singleton()->get_workspace()->scripts.front(); E; E = E->next()) { - ExtendGDScriptParser *script = E->get(); const Array &items = script->get_member_completions(); @@ -220,7 +210,6 @@ Array GDScriptTextDocument::completion(const Dictionary &p_params) { } Dictionary GDScriptTextDocument::resolve(const Dictionary &p_params) { - lsp::CompletionItem item; item.load(p_params); @@ -230,18 +219,15 @@ Dictionary GDScriptTextDocument::resolve(const Dictionary &p_params) { const lsp::DocumentSymbol *symbol = nullptr; if (data.get_type() == Variant::DICTIONARY) { - params.load(p_params["data"]); symbol = GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_symbol(params, item.label, item.kind == lsp::CompletionItemKind::Method || item.kind == lsp::CompletionItemKind::Function); } else if (data.get_type() == Variant::STRING) { - String query = data; Vector<String> param_symbols = query.split(SYMBOL_SEPERATOR, false); if (param_symbols.size() >= 2) { - String class_ = param_symbols[0]; StringName class_name = class_; String member_name = param_symbols[param_symbols.size() - 1]; @@ -313,13 +299,11 @@ Array GDScriptTextDocument::colorPresentation(const Dictionary &p_params) { } Variant GDScriptTextDocument::hover(const Dictionary &p_params) { - lsp::TextDocumentPositionParams params; params.load(p_params); const lsp::DocumentSymbol *symbol = GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_symbol(params); if (symbol) { - lsp::Hover hover; hover.contents = symbol->render(); hover.range.start = params.position; @@ -327,7 +311,6 @@ Variant GDScriptTextDocument::hover(const Dictionary &p_params) { return hover.to_json(); } else if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) { - Dictionary ret; Array contents; List<const lsp::DocumentSymbol *> list; diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp index be036b44c4..9285d88157 100644 --- a/modules/gdscript/language_server/gdscript_workspace.cpp +++ b/modules/gdscript/language_server/gdscript_workspace.cpp @@ -71,7 +71,6 @@ void GDScriptWorkspace::remove_cache_parser(const String &p_path) { } const lsp::DocumentSymbol *GDScriptWorkspace::get_native_symbol(const String &p_class, const String &p_member) const { - StringName class_name = p_class; StringName empty; @@ -185,12 +184,12 @@ Array GDScriptWorkspace::symbol(const Dictionary &p_params) { } Error GDScriptWorkspace::initialize() { - if (initialized) + if (initialized) { return OK; + } DocData *doc = EditorHelp::get_doc_data(); for (Map<String, DocData::ClassDoc>::Element *E = doc->class_list.front(); E; E = E->next()) { - const DocData::ClassDoc &class_data = E->value(); lsp::DocumentSymbol class_symbol; String class_name = E->key(); @@ -315,14 +314,12 @@ Error GDScriptWorkspace::initialize() { } Error GDScriptWorkspace::parse_script(const String &p_path, const String &p_content) { - ExtendGDScriptParser *parser = memnew(ExtendGDScriptParser); Error err = parser->parse(p_content, p_path); Map<String, ExtendGDScriptParser *>::Element *last_parser = parse_results.find(p_path); Map<String, ExtendGDScriptParser *>::Element *last_script = scripts.find(p_path); if (err == OK) { - remove_cache_parser(p_path); parse_results[p_path] = parser; scripts[p_path] = parser; @@ -378,15 +375,15 @@ void GDScriptWorkspace::publish_diagnostics(const String &p_path) { } void GDScriptWorkspace::_get_owners(EditorFileSystemDirectory *efsd, String p_path, List<String> &owners) { - if (!efsd) + if (!efsd) { return; + } for (int i = 0; i < efsd->get_subdir_count(); i++) { _get_owners(efsd->get_subdir(i), p_path, owners); } for (int i = 0; i < efsd->get_file_count(); i++) { - Vector<String> deps = efsd->get_file_deps(i); bool found = false; for (int j = 0; j < deps.size(); j++) { @@ -395,8 +392,9 @@ void GDScriptWorkspace::_get_owners(EditorFileSystemDirectory *efsd, String p_pa break; } } - if (!found) + if (!found) { continue; + } owners.push_back(efsd->get_file_path(i)); } @@ -422,7 +420,6 @@ Node *GDScriptWorkspace::_get_owner_scene_node(String p_path) { } void GDScriptWorkspace::completion(const lsp::CompletionParams &p_params, List<ScriptCodeCompletionOption> *r_options) { - String path = get_file_path(p_params.textDocument.uri); String call_hint; bool forced = false; @@ -438,12 +435,10 @@ void GDScriptWorkspace::completion(const lsp::CompletionParams &p_params, List<S } const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocumentPositionParams &p_doc_pos, const String &p_symbol_name, bool p_func_requred) { - const lsp::DocumentSymbol *symbol = nullptr; String path = get_file_path(p_doc_pos.textDocument.uri); if (const ExtendGDScriptParser *parser = get_parse_result(path)) { - String symbol_identifier = p_symbol_name; Vector<String> identifier_parts = symbol_identifier.split("("); if (identifier_parts.size()) { @@ -458,19 +453,14 @@ const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocu } if (!symbol_identifier.empty()) { - if (ScriptServer::is_global_class(symbol_identifier)) { - String class_path = ScriptServer::get_global_class_path(symbol_identifier); symbol = get_script_symbol(class_path); } else { - ScriptLanguage::LookupResult ret; if (OK == GDScriptLanguage::get_singleton()->lookup_code(parser->get_text_for_lookup_symbol(pos, symbol_identifier, p_func_requred), symbol_identifier, path, nullptr, ret)) { - if (ret.type == ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION) { - String target_script_path = path; if (!ret.script.is_null()) { target_script_path = ret.script->get_path(); @@ -481,7 +471,6 @@ const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocu } } else { - String member = ret.class_member; if (member.empty() && symbol_identifier != ret.class_name) { member = symbol_identifier; @@ -499,10 +488,8 @@ const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocu } void GDScriptWorkspace::resolve_related_symbols(const lsp::TextDocumentPositionParams &p_doc_pos, List<const lsp::DocumentSymbol *> &r_list) { - String path = get_file_path(p_doc_pos.textDocument.uri); if (const ExtendGDScriptParser *parser = get_parse_result(path)) { - String symbol_identifier; Vector2i offset; symbol_identifier = parser->get_identifier_under_position(p_doc_pos.position, offset); @@ -526,7 +513,6 @@ void GDScriptWorkspace::resolve_related_symbols(const lsp::TextDocumentPositionP const HashMap<String, ClassMembers> &inner_classes = script->get_inner_classes(); const String *_class = inner_classes.next(nullptr); while (_class) { - const ClassMembers *inner_class = inner_classes.getptr(*_class); if (const lsp::DocumentSymbol *const *symbol = inner_class->getptr(symbol_identifier)) { r_list.push_back(*symbol); @@ -539,7 +525,6 @@ void GDScriptWorkspace::resolve_related_symbols(const lsp::TextDocumentPositionP } const lsp::DocumentSymbol *GDScriptWorkspace::resolve_native_symbol(const lsp::NativeSymbolInspectParams &p_params) { - if (Map<StringName, lsp::DocumentSymbol>::Element *E = native_symbols.find(p_params.native_class)) { const lsp::DocumentSymbol &symbol = E->get(); if (p_params.symbol_name.empty() || p_params.symbol_name == symbol.name) { @@ -575,12 +560,10 @@ Dictionary GDScriptWorkspace::generate_script_api(const String &p_path) { Error GDScriptWorkspace::resolve_signature(const lsp::TextDocumentPositionParams &p_doc_pos, lsp::SignatureHelp &r_signature) { if (const ExtendGDScriptParser *parser = get_parse_result(get_file_path(p_doc_pos.textDocument.uri))) { - lsp::TextDocumentPositionParams text_pos; text_pos.textDocument = p_doc_pos.textDocument; if (parser->get_left_function_call(p_doc_pos.position, text_pos.position, r_signature.activeParameter) == OK) { - List<const lsp::DocumentSymbol *> symbols; if (const lsp::DocumentSymbol *symbol = resolve_symbol(text_pos)) { @@ -592,7 +575,6 @@ Error GDScriptWorkspace::resolve_signature(const lsp::TextDocumentPositionParams for (List<const lsp::DocumentSymbol *>::Element *E = symbols.front(); E; E = E->next()) { const lsp::DocumentSymbol *symbol = E->get(); if (symbol->kind == lsp::SymbolKind::Method || symbol->kind == lsp::SymbolKind::Function) { - lsp::SignatureInformation signature_info; signature_info.label = symbol->detail; signature_info.documentation = symbol->render(); diff --git a/modules/gdscript/language_server/lsp.hpp b/modules/gdscript/language_server/lsp.hpp index e469a26df8..44a0076107 100644 --- a/modules/gdscript/language_server/lsp.hpp +++ b/modules/gdscript/language_server/lsp.hpp @@ -149,7 +149,6 @@ struct Location { * Represents a link between a source and a target location. */ struct LocationLink { - /** * Span of the origin of this link. * @@ -220,7 +219,6 @@ struct DocumentLinkParams { * text document or a web site. */ struct DocumentLink { - /** * The range this link applies to. */ @@ -282,8 +280,9 @@ struct Command { Dictionary dict; dict["title"] = title; dict["command"] = command; - if (arguments.size()) + if (arguments.size()) { dict["arguments"] = arguments; + } return dict; } }; @@ -947,20 +946,24 @@ struct CompletionItem { dict["preselect"] = preselect; dict["sortText"] = sortText; dict["filterText"] = filterText; - if (commitCharacters.size()) + if (commitCharacters.size()) { dict["commitCharacters"] = commitCharacters; + } dict["command"] = command.to_json(); } return dict; } void load(const Dictionary &p_dict) { - if (p_dict.has("label")) + if (p_dict.has("label")) { label = p_dict["label"]; - if (p_dict.has("kind")) + } + if (p_dict.has("kind")) { kind = p_dict["kind"]; - if (p_dict.has("detail")) + } + if (p_dict.has("detail")) { detail = p_dict["detail"]; + } if (p_dict.has("documentation")) { Variant doc = p_dict["documentation"]; if (doc.get_type() == Variant::STRING) { @@ -970,18 +973,24 @@ struct CompletionItem { documentation.value = v["value"]; } } - if (p_dict.has("deprecated")) + if (p_dict.has("deprecated")) { deprecated = p_dict["deprecated"]; - if (p_dict.has("preselect")) + } + if (p_dict.has("preselect")) { preselect = p_dict["preselect"]; - if (p_dict.has("sortText")) + } + if (p_dict.has("sortText")) { sortText = p_dict["sortText"]; - if (p_dict.has("filterText")) + } + if (p_dict.has("filterText")) { filterText = p_dict["filterText"]; - if (p_dict.has("insertText")) + } + if (p_dict.has("insertText")) { insertText = p_dict["insertText"]; - if (p_dict.has("data")) + } + if (p_dict.has("data")) { data = p_dict["data"]; + } } }; @@ -1107,7 +1116,6 @@ struct DocumentedSymbolInformation : public SymbolInformation { * e.g. the range of an identifier. */ struct DocumentSymbol { - /** * The name of this symbol. Will be displayed in the user interface and therefore must not be * an empty string or a string only consisting of white spaces. @@ -1216,7 +1224,6 @@ struct DocumentSymbol { } _FORCE_INLINE_ CompletionItem make_completion_item(bool resolved = false) const { - lsp::CompletionItem item; item.label = name; @@ -1260,7 +1267,6 @@ struct DocumentSymbol { }; struct NativeSymbolInspectParams { - String native_class; String symbol_name; @@ -1292,7 +1298,6 @@ static const String Region = "region"; * Represents a folding range. */ struct FoldingRange { - /** * The zero-based line number from where the folded range starts. */ @@ -1375,7 +1380,6 @@ struct CompletionContext { }; struct CompletionParams : public TextDocumentPositionParams { - /** * The completion context. This is only available if the client specifies * to send this using `ClientCapabilities.textDocument.completion.contextSupport === true` @@ -1416,7 +1420,6 @@ struct Hover { * have a label and a doc-comment. */ struct ParameterInformation { - /** * The label of this parameter information. * @@ -1695,7 +1698,6 @@ struct InitializeResult { }; struct GodotNativeClassInfo { - String name; const DocData::ClassDoc *class_doc = nullptr; const ClassDB::ClassInfo *class_info = nullptr; @@ -1710,7 +1712,6 @@ struct GodotNativeClassInfo { /** Features not included in the standard lsp specifications */ struct GodotCapabilities { - /** * Native class list */ @@ -1729,7 +1730,6 @@ struct GodotCapabilities { /** Format BBCode documentation from DocData to markdown */ static String marked_documentation(const String &p_bbcode) { - String markdown = p_bbcode.strip_edges(); Vector<String> lines = markdown.split("\n"); diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp index 62b9d94d6c..0625123530 100644 --- a/modules/gdscript/register_types.cpp +++ b/modules/gdscript/register_types.cpp @@ -54,12 +54,10 @@ Ref<ResourceFormatSaverGDScript> resource_saver_gd; #endif // !GDSCRIPT_NO_LSP class EditorExportGDScript : public EditorExportPlugin { - GDCLASS(EditorExportGDScript, EditorExportPlugin); public: virtual void _export_file(const String &p_path, const String &p_type, const Set<String> &p_features) { - int script_mode = EditorExportPreset::MODE_SCRIPT_COMPILED; String script_key; @@ -70,21 +68,21 @@ public: script_key = preset->get_script_encryption_key().to_lower(); } - if (!p_path.ends_with(".gd") || script_mode == EditorExportPreset::MODE_SCRIPT_TEXT) + if (!p_path.ends_with(".gd") || script_mode == EditorExportPreset::MODE_SCRIPT_TEXT) { return; + } Vector<uint8_t> file = FileAccess::get_file_as_array(p_path); - if (file.empty()) + if (file.empty()) { return; + } String txt; txt.parse_utf8((const char *)file.ptr(), file.size()); file = GDScriptTokenizerBuffer::parse_code_string(txt); if (!file.empty()) { - if (script_mode == EditorExportPreset::MODE_SCRIPT_ENCRYPTED) { - String tmp_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("script.gde"); FileAccess *fa = FileAccess::open(tmp_path, FileAccess::WRITE); @@ -94,19 +92,21 @@ public: int v = 0; if (i * 2 < script_key.length()) { CharType ct = script_key[i * 2]; - if (ct >= '0' && ct <= '9') + if (ct >= '0' && ct <= '9') { ct = ct - '0'; - else if (ct >= 'a' && ct <= 'f') + } else if (ct >= 'a' && ct <= 'f') { ct = 10 + ct - 'a'; + } v |= ct << 4; } if (i * 2 + 1 < script_key.length()) { CharType ct = script_key[i * 2 + 1]; - if (ct >= '0' && ct <= '9') + if (ct >= '0' && ct <= '9') { ct = ct - '0'; - else if (ct >= 'a' && ct <= 'f') + } else if (ct >= 'a' && ct <= 'f') { ct = 10 + ct - 'a'; + } v |= ct; } key.write[i] = v; @@ -127,7 +127,6 @@ public: DirAccess::remove_file_or_error(tmp_path); } else { - add_file(p_path.get_basename() + ".gdc", file, true); } } @@ -135,7 +134,6 @@ public: }; static void _editor_init() { - Ref<EditorExportGDScript> gd_export; gd_export.instance(); EditorExport::get_singleton()->add_export_plugin(gd_export); @@ -151,7 +149,6 @@ static void _editor_init() { #endif // TOOLS_ENABLED void register_gdscript_types() { - ClassDB::register_class<GDScript>(); ClassDB::register_virtual_class<GDScriptFunctionState>(); @@ -171,11 +168,11 @@ void register_gdscript_types() { } void unregister_gdscript_types() { - ScriptServer::unregister_language(script_language_gd); - if (script_language_gd) + if (script_language_gd) { memdelete(script_language_gd); + } ResourceLoader::remove_resource_format_loader(resource_loader_gd); resource_loader_gd.unref(); |