diff options
Diffstat (limited to 'modules')
8 files changed, 112 insertions, 61 deletions
diff --git a/modules/gdnative/pluginscript/pluginscript_instance.cpp b/modules/gdnative/pluginscript/pluginscript_instance.cpp index 97897870ba..c64a00a4d9 100644 --- a/modules/gdnative/pluginscript/pluginscript_instance.cpp +++ b/modules/gdnative/pluginscript/pluginscript_instance.cpp @@ -28,11 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#include "pluginscript_instance.h" + // Godot imports #include "core/os/os.h" #include "core/variant.h" + // PluginScript imports -#include "pluginscript_instance.h" #include "pluginscript_language.h" #include "pluginscript_script.h" @@ -89,51 +91,6 @@ Variant PluginScriptInstance::call(const StringName &p_method, const Variant **p return var_ret; } -#if 0 // TODO: Don't rely on default implementations provided by ScriptInstance ? -void PluginScriptInstance::call_multilevel(const StringName& p_method,const Variant** p_args,int p_argcount) { - -#if 0 - PluginScript *sptr=script.ptr(); - Variant::CallError ce; - - while(sptr) { - Map<StringName,GDFunction*>::Element *E = sptr->member_functions.find(p_method); - if (E) { - E->get()->call(this,p_args,p_argcount,ce); - } - sptr = sptr->_base; - } -#endif - -} - -#if 0 -void PluginScriptInstance::_ml_call_reversed(PluginScript *sptr,const StringName& p_method,const Variant** p_args,int p_argcount) { - - if (sptr->_base) - _ml_call_reversed(sptr->_base,p_method,p_args,p_argcount); - - Variant::CallError ce; - - Map<StringName,GDFunction*>::Element *E = sptr->member_functions.find(p_method); - if (E) { - E->get()->call(this,p_args,p_argcount,ce); - } - -} -#endif - - -void PluginScriptInstance::call_multilevel_reversed(const StringName& p_method,const Variant** p_args,int p_argcount) { - -#if 0 - if (script.ptr()) { - _ml_call_reversed(script.ptr(),p_method,p_args,p_argcount); - } -#endif -} -#endif // Multilevel stuff - void PluginScriptInstance::notification(int p_notification) { _desc->notification(_data, p_notification); } diff --git a/modules/gdnative/pluginscript/pluginscript_instance.h b/modules/gdnative/pluginscript/pluginscript_instance.h index d92d3ace77..dc1229a44d 100644 --- a/modules/gdnative/pluginscript/pluginscript_instance.h +++ b/modules/gdnative/pluginscript/pluginscript_instance.h @@ -33,6 +33,7 @@ // Godot imports #include "core/script_language.h" + // PluginScript imports #include <pluginscript/godot_pluginscript.h> @@ -60,13 +61,12 @@ public: virtual bool has_method(const StringName &p_method) const; virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error); -#if 0 - // Rely on default implementations provided by ScriptInstance for the moment. - // Note that multilevel call could be removed in 3.0 release, so stay tuned - // (see https://godotengine.org/qa/9244/can-override-the-_ready-and-_process-functions-child-classes) - virtual void call_multilevel(const StringName& p_method,const Variant** p_args,int p_argcount); - virtual void call_multilevel_reversed(const StringName& p_method,const Variant** p_args,int p_argcount); -#endif + + // Rely on default implementations provided by ScriptInstance for the moment. + // Note that multilevel call could be removed in 3.0 release, so stay tuned + // (see https://godotengine.org/qa/9244/can-override-the-_ready-and-_process-functions-child-classes) + //virtual void call_multilevel(const StringName& p_method,const Variant** p_args,int p_argcount); + //virtual void call_multilevel_reversed(const StringName& p_method,const Variant** p_args,int p_argcount); virtual void notification(int p_notification); diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index 524be480d7..452b1933eb 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -1550,10 +1550,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE_BREAK; } -// Enable for debugging -#if 0 +#if 0 // Enable for debugging. default: { - err_text = "Illegal opcode " + itos(_code_ptr[ip]) + " at address " + itos(ip); OPCODE_BREAK; } diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index aec7110ee5..d125da5b79 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -1868,6 +1868,10 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to _set_error("Can't assign to constant", tokenizer->get_token_line() - 1); error_line = op->line; return op; + } else if (op->arguments[0]->type == Node::TYPE_SELF) { + _set_error("Can't assign to self.", op->line); + error_line = op->line; + return op; } if (op->arguments[0]->type == Node::TYPE_OPERATOR) { @@ -6290,6 +6294,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) { node_type.has_type = true; node_type.kind = DataType::CLASS; node_type.class_type = current_class; + node_type.is_constant = true; } break; case Node::TYPE_IDENTIFIER: { IdentifierNode *id = static_cast<IdentifierNode *>(p_node); diff --git a/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs b/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs index 174509dc5b..9abfda4538 100644 --- a/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs +++ b/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs @@ -81,7 +81,12 @@ namespace GodotTools } } - ScriptClassParser.ParseFileOrThrow(projectIncludeFile, out var classes); + Error parseError = ScriptClassParser.ParseFile(projectIncludeFile, out var classes, out string errorStr); + if (parseError != Error.Ok) + { + GD.PushError($"Failed to determine namespace and class for script: {projectIncludeFile}. Parse error: {errorStr ?? parseError.ToString()}"); + continue; + } string searchName = System.IO.Path.GetFileNameWithoutExtension(projectIncludeFile); diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/ScriptClassParser.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/ScriptClassParser.cs index 11afa8773e..7fb087467f 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Internals/ScriptClassParser.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Internals/ScriptClassParser.cs @@ -27,12 +27,15 @@ namespace GodotTools.Internals [MethodImpl(MethodImplOptions.InternalCall)] private static extern Error internal_ParseFile(string filePath, Array<Dictionary> classes, out string errorStr); - public static void ParseFileOrThrow(string filePath, out IEnumerable<ClassDecl> classes) + public static Error ParseFile(string filePath, out IEnumerable<ClassDecl> classes, out string errorStr) { var classesArray = new Array<Dictionary>(); - var error = internal_ParseFile(filePath, classesArray, out string errorStr); + var error = internal_ParseFile(filePath, classesArray, out errorStr); if (error != Error.Ok) - throw new Exception($"Failed to determine namespace and class for script: {filePath}. Parse error: {errorStr ?? error.ToString()}"); + { + classes = null; + return error; + } var classesList = new List<ClassDecl>(); @@ -47,6 +50,8 @@ namespace GodotTools.Internals } classes = classesList; + + return Error.Ok; } } } diff --git a/modules/mono/editor/script_class_parser.cpp b/modules/mono/editor/script_class_parser.cpp index 84163dd952..8ac4df9952 100644 --- a/modules/mono/editor/script_class_parser.cpp +++ b/modules/mono/editor/script_class_parser.cpp @@ -631,6 +631,85 @@ Error ScriptClassParser::parse(const String &p_code) { return OK; } +static String get_preprocessor_directive(const String &p_line, int p_from) { + CRASH_COND(p_line[p_from] != '#'); + p_from++; + int i = p_from; + while (i < p_line.length() && p_line[i] != ' ' && p_line[i] != '\t') { + i++; + } + return p_line.substr(p_from, i - p_from); +} + +static void run_dummy_preprocessor(String &r_source) { + + Vector<String> lines = r_source.split("\n", /* p_allow_empty: */ true); + + bool *include_lines = memnew_arr(bool, lines.size()); + + int if_level = -1; + Vector<bool> is_branch_being_compiled; + + for (int i = 0; i < lines.size(); i++) { + const String &line = lines[i]; + + const int line_len = line.length(); + + int j = 0; + while (j < line_len) { + if (line[j] != ' ' && line[j] != '\t') { + if (line[j] == '#') { + // First non-whitespace char of the line is '#' + include_lines[i] = false; + + String directive = get_preprocessor_directive(line, j); + + if (directive == "if") { + if_level++; + is_branch_being_compiled.push_back(if_level == 0 || is_branch_being_compiled[if_level - 1]); + } else if (directive == "elif") { + ERR_CONTINUE_MSG(if_level == -1, "Found unexpected '#elif' directive."); + is_branch_being_compiled.write[if_level] = false; + } else if (directive == "else") { + ERR_CONTINUE_MSG(if_level == -1, "Found unexpected '#else' directive."); + is_branch_being_compiled.write[if_level] = false; + } else if (directive == "endif") { + ERR_CONTINUE_MSG(if_level == -1, "Found unexpected '#endif' directive."); + is_branch_being_compiled.remove(if_level); + if_level--; + } + + break; + } else { + // First non-whitespace char of the line is not '#' + include_lines[i] = if_level == -1 || is_branch_being_compiled[if_level]; + break; + } + } + + j++; + } + + if (j == line_len) { + // Loop ended without finding a non-whitespace character. + // Either the line was empty or it only contained whitespaces. + include_lines[i] = if_level == -1 || is_branch_being_compiled[if_level]; + } + } + + r_source.clear(); + + // Custom join ignoring lines removed by the preprocessor + for (int i = 0; i < lines.size(); i++) { + if (i > 0 && include_lines[i - 1]) + r_source += '\n'; + + if (include_lines[i]) { + r_source += lines[i]; + } + } +} + Error ScriptClassParser::parse_file(const String &p_filepath) { String source; @@ -643,6 +722,8 @@ Error ScriptClassParser::parse_file(const String &p_filepath) { " Please ensure that scripts are saved in valid UTF-8 unicode." : "Failed to read file: '" + p_filepath + "'."); + run_dummy_preprocessor(source); + return parse(source); } diff --git a/modules/websocket/websocket_multiplayer_peer.cpp b/modules/websocket/websocket_multiplayer_peer.cpp index b639c635fd..27ea50b524 100644 --- a/modules/websocket/websocket_multiplayer_peer.cpp +++ b/modules/websocket/websocket_multiplayer_peer.cpp @@ -98,7 +98,7 @@ void WebSocketMultiplayerPeer::_bind_methods() { // int WebSocketMultiplayerPeer::get_available_packet_count() const { - ERR_FAIL_COND_V_MSG(!_is_multiplayer, ERR_UNCONFIGURED, "Please use get_peer(ID).get_available_packet_count to get available packet count from peers when not using the MultiplayerAPI."); + ERR_FAIL_COND_V_MSG(!_is_multiplayer, 0, "Please use get_peer(ID).get_available_packet_count to get available packet count from peers when not using the MultiplayerAPI."); return _incoming_packets.size(); } |