summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/gdnative/pluginscript/pluginscript_instance.cpp49
-rw-r--r--modules/gdnative/pluginscript/pluginscript_instance.h14
-rw-r--r--modules/gdscript/gdscript_function.cpp4
-rw-r--r--modules/gdscript/gdscript_parser.cpp5
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs7
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Internals/ScriptClassParser.cs11
-rw-r--r--modules/mono/editor/script_class_parser.cpp81
-rw-r--r--modules/websocket/websocket_multiplayer_peer.cpp2
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();
}