summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/gdscript/editor/gdscript_docgen.cpp48
-rw-r--r--modules/gdscript/editor/gdscript_docgen.h1
-rw-r--r--modules/gdscript/tests/README.md7
-rw-r--r--modules/gdscript/tests/scripts/completion/argument_options/argument_options.tscn3
-rw-r--r--modules/gdscript/tests/scripts/completion/argument_options/connect.cfg8
-rw-r--r--modules/gdscript/tests/scripts/completion/argument_options/connect.gd7
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/literal/dollar.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/literal/percent.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_class_scene.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_native_scene.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/literal_scene/percent_class_scene.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/literal_scene/percent_native_scene.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/local/local.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/local_interfered/local_interfered.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/class_local_interfered_scene.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/native_local_interfered_scene.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/local_scene/class_local_scene.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/local_scene/native_local_scene.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/local_typehint/class_local_typehint.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/local_typehint/native_local_typehint.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene/class_local_typehint_scene.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene/native_local_typehint_scene.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_broad/class_local_typehint_scene_broad.notest.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_broad/native_local_typehint_scene_broad.notest.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_incompatible/class_local_typehint_scene_incompatible.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_incompatible/native_local_typehint_scene_incompatible.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/member/member.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/member_interfered/member_interfered.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/class_member_interfered_scene.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/native_member_interfered_scene.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/member_scene/class_member_scene.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/member_scene/native_member_scene.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/member_typehint/class_member_typehint.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/member_typehint/native_member_typehint.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene/class_member_typehint_scene.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene/native_member_typehint_scene.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_broad/class_member_typehint_scene_broad.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_broad/native_member_typehint_scene_broad.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_incompatible/class_member_typehint_scene_incompatible.gd1
-rw-r--r--modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_incompatible/native_member_typehint_scene_incompatible.gd1
-rw-r--r--modules/gdscript/tests/test_completion.h52
-rw-r--r--modules/multiplayer/scene_cache_interface.cpp38
-rw-r--r--modules/multiplayer/scene_cache_interface.h3
43 files changed, 158 insertions, 43 deletions
diff --git a/modules/gdscript/editor/gdscript_docgen.cpp b/modules/gdscript/editor/gdscript_docgen.cpp
index 601db5414b..35b69fab8c 100644
--- a/modules/gdscript/editor/gdscript_docgen.cpp
+++ b/modules/gdscript/editor/gdscript_docgen.cpp
@@ -229,6 +229,36 @@ String GDScriptDocGen::_docvalue_from_variant(const Variant &p_variant, int p_re
}
}
+String GDScriptDocGen::_docvalue_from_expression(const GDP::ExpressionNode *p_expression) {
+ ERR_FAIL_NULL_V(p_expression, String());
+
+ if (p_expression->is_constant) {
+ return _docvalue_from_variant(p_expression->reduced_value);
+ }
+
+ switch (p_expression->type) {
+ case GDP::Node::ARRAY: {
+ const GDP::ArrayNode *array = static_cast<const GDP::ArrayNode *>(p_expression);
+ return array->elements.is_empty() ? "[]" : "[...]";
+ } break;
+ case GDP::Node::CALL: {
+ const GDP::CallNode *call = static_cast<const GDP::CallNode *>(p_expression);
+ return call->function_name.operator String() + (call->arguments.is_empty() ? "()" : "(...)");
+ } break;
+ case GDP::Node::DICTIONARY: {
+ const GDP::DictionaryNode *dict = static_cast<const GDP::DictionaryNode *>(p_expression);
+ return dict->elements.is_empty() ? "{}" : "{...}";
+ } break;
+ case GDP::Node::IDENTIFIER: {
+ const GDP::IdentifierNode *id = static_cast<const GDP::IdentifierNode *>(p_expression);
+ return id->name;
+ } break;
+ default: {
+ return "<unknown>";
+ } break;
+ }
+}
+
void GDScriptDocGen::_generate_docs(GDScript *p_script, const GDP::ClassNode *p_class) {
p_script->_clear_doc();
@@ -328,16 +358,12 @@ void GDScriptDocGen::_generate_docs(GDScript *p_script, const GDP::ClassNode *p_
method_doc.return_type = "Variant";
}
- for (const GDScriptParser::ParameterNode *p : m_func->parameters) {
+ for (const GDP::ParameterNode *p : m_func->parameters) {
DocData::ArgumentDoc arg_doc;
arg_doc.name = p->identifier->name;
_doctype_from_gdtype(p->get_datatype(), arg_doc.type, arg_doc.enumeration);
if (p->initializer != nullptr) {
- if (p->initializer->is_constant) {
- arg_doc.default_value = _docvalue_from_variant(p->initializer->reduced_value);
- } else {
- arg_doc.default_value = "<unknown>";
- }
+ arg_doc.default_value = _docvalue_from_expression(p->initializer);
}
method_doc.arguments.push_back(arg_doc);
}
@@ -359,7 +385,7 @@ void GDScriptDocGen::_generate_docs(GDScript *p_script, const GDP::ClassNode *p_
signal_doc.is_experimental = m_signal->doc_data.is_experimental;
signal_doc.experimental_message = m_signal->doc_data.experimental_message;
- for (const GDScriptParser::ParameterNode *p : m_signal->parameters) {
+ for (const GDP::ParameterNode *p : m_signal->parameters) {
DocData::ArgumentDoc arg_doc;
arg_doc.name = p->identifier->name;
_doctype_from_gdtype(p->get_datatype(), arg_doc.type, arg_doc.enumeration);
@@ -405,12 +431,8 @@ void GDScriptDocGen::_generate_docs(GDScript *p_script, const GDP::ClassNode *p_
break;
}
- if (m_var->initializer) {
- if (m_var->initializer->is_constant) {
- prop_doc.default_value = _docvalue_from_variant(m_var->initializer->reduced_value);
- } else {
- prop_doc.default_value = "<unknown>";
- }
+ if (m_var->initializer != nullptr) {
+ prop_doc.default_value = _docvalue_from_expression(m_var->initializer);
}
prop_doc.overridden = false;
diff --git a/modules/gdscript/editor/gdscript_docgen.h b/modules/gdscript/editor/gdscript_docgen.h
index 651a4fb198..0ae37c4133 100644
--- a/modules/gdscript/editor/gdscript_docgen.h
+++ b/modules/gdscript/editor/gdscript_docgen.h
@@ -45,6 +45,7 @@ class GDScriptDocGen {
static String _get_class_name(const GDP::ClassNode &p_class);
static void _doctype_from_gdtype(const GDType &p_gdtype, String &r_type, String &r_enum, bool p_is_return = false);
static String _docvalue_from_variant(const Variant &p_variant, int p_recursion_level = 1);
+ static String _docvalue_from_expression(const GDP::ExpressionNode *p_expression);
static void _generate_docs(GDScript *p_script, const GDP::ClassNode *p_class);
public:
diff --git a/modules/gdscript/tests/README.md b/modules/gdscript/tests/README.md
index 72b5316532..714e38397f 100644
--- a/modules/gdscript/tests/README.md
+++ b/modules/gdscript/tests/README.md
@@ -13,6 +13,12 @@ The `script/completion` folder contains test for the GDScript autocompletion.
Each test case consists of at least one `.gd` file, which contains the code, and one `.cfg` file, which contains expected results and configuration. Inside of the GDScript file the character `➡` represents the cursor position, at which autocompletion is invoked.
+The script files won't be parsable GDScript since it contains an invalid char and and often the code is not complete during autocompletion. To allow for a valid base when used with a scene, the
+runner will remove the line which contains `➡`. Therefore the scripts need to be valid if this line is removed, otherwise the test might behave in unexpected ways. This may for example require
+adding an additional `pass` statement.
+
+This also means, that the runner will add the script to its owner node, so the script should not be loaded through the scene file.
+
The config file contains two section:
`[input]` contains keys that configure the test environment. The following keys are possible:
@@ -20,6 +26,7 @@ The config file contains two section:
- `cs: boolean = false`: If `true`, the test will be skipped when running a non C# build.
- `use_single_quotes: boolean = false`: Configures the corresponding editor setting for the test.
- `scene: String`: Allows to specify a scene which is opened while autocompletion is performed. If this is not set the test runner will search for a `.tscn` file with the same basename as the GDScript file. If that isn't found either, autocompletion will behave as if no scene was opened.
+- `node_path: String`: The node path of the node which holds the current script inside of the scene. Defaults to the scene root node.
`[output]` specifies the expected results for the test. The following key are supported:
diff --git a/modules/gdscript/tests/scripts/completion/argument_options/argument_options.tscn b/modules/gdscript/tests/scripts/completion/argument_options/argument_options.tscn
new file mode 100644
index 0000000000..d3dea6b12b
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/argument_options/argument_options.tscn
@@ -0,0 +1,3 @@
+[gd_scene load_steps=1 format=3 uid="uid://dl28pdkxcjvym"]
+
+[node name="GetNode" type="Node"]
diff --git a/modules/gdscript/tests/scripts/completion/argument_options/connect.cfg b/modules/gdscript/tests/scripts/completion/argument_options/connect.cfg
new file mode 100644
index 0000000000..8c3fbf90da
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/argument_options/connect.cfg
@@ -0,0 +1,8 @@
+[input]
+scene="res://completion/argument_options/argument_options.tscn"
+[output]
+include=[
+ ; Node
+ {"display": "\"signal_a\""},
+ {"display": "\"child_entered_tree\""},
+]
diff --git a/modules/gdscript/tests/scripts/completion/argument_options/connect.gd b/modules/gdscript/tests/scripts/completion/argument_options/connect.gd
new file mode 100644
index 0000000000..1137070c4e
--- /dev/null
+++ b/modules/gdscript/tests/scripts/completion/argument_options/connect.gd
@@ -0,0 +1,7 @@
+extends Node
+
+signal signal_a()
+
+func _ready():
+ connect(➡)
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/literal/dollar.gd b/modules/gdscript/tests/scripts/completion/get_node/literal/dollar.gd
index df458a9435..dc7cc99554 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/literal/dollar.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/literal/dollar.gd
@@ -2,3 +2,4 @@ extends Node
func a():
%AnimationPlayer.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/literal/percent.gd b/modules/gdscript/tests/scripts/completion/get_node/literal/percent.gd
index 7050761b86..5586317938 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/literal/percent.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/literal/percent.gd
@@ -2,3 +2,4 @@ extends Node
func a():
$UniqueAnimationPlayer.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_class_scene.gd b/modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_class_scene.gd
index a84283a1de..69fcac4471 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_class_scene.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_class_scene.gd
@@ -2,3 +2,4 @@ extends Node
func a():
$A.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_native_scene.gd b/modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_native_scene.gd
index 6e3fee1696..0b13a207ff 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_native_scene.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/literal_scene/dollar_native_scene.gd
@@ -2,3 +2,4 @@ extends Node
func a():
$AnimationPlayer.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/literal_scene/percent_class_scene.gd b/modules/gdscript/tests/scripts/completion/get_node/literal_scene/percent_class_scene.gd
index 27f059c944..48945db38e 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/literal_scene/percent_class_scene.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/literal_scene/percent_class_scene.gd
@@ -2,3 +2,4 @@ extends Node
func a():
%UniqueA.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/literal_scene/percent_native_scene.gd b/modules/gdscript/tests/scripts/completion/get_node/literal_scene/percent_native_scene.gd
index 07068fc5a4..3684edc73b 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/literal_scene/percent_native_scene.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/literal_scene/percent_native_scene.gd
@@ -2,3 +2,4 @@ extends Node
func a():
%UniqueAnimationPlayer.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/local/local.gd b/modules/gdscript/tests/scripts/completion/get_node/local/local.gd
index 596ad80ef2..dcd232d82d 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/local/local.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/local/local.gd
@@ -3,3 +3,4 @@ extends Node
func a():
var test = $AnimationPlayer
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/local_interfered/local_interfered.gd b/modules/gdscript/tests/scripts/completion/get_node/local_interfered/local_interfered.gd
index 6f87af3c85..7710c2d13b 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/local_interfered/local_interfered.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/local_interfered/local_interfered.gd
@@ -3,3 +3,4 @@ extends Node
func a():
var test := $AnimationPlayer
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/class_local_interfered_scene.gd b/modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/class_local_interfered_scene.gd
index a710c8bbd7..6b29bf5526 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/class_local_interfered_scene.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/class_local_interfered_scene.gd
@@ -3,3 +3,4 @@ extends Node
func a():
var test := $A
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/native_local_interfered_scene.gd b/modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/native_local_interfered_scene.gd
index 6f87af3c85..7710c2d13b 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/native_local_interfered_scene.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/local_interfered_scene/native_local_interfered_scene.gd
@@ -3,3 +3,4 @@ extends Node
func a():
var test := $AnimationPlayer
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/local_scene/class_local_scene.gd b/modules/gdscript/tests/scripts/completion/get_node/local_scene/class_local_scene.gd
index 2fc88f93dd..02c0d2dceb 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/local_scene/class_local_scene.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/local_scene/class_local_scene.gd
@@ -3,3 +3,4 @@ extends Node
func a():
var test = $A
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/local_scene/native_local_scene.gd b/modules/gdscript/tests/scripts/completion/get_node/local_scene/native_local_scene.gd
index 596ad80ef2..dcd232d82d 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/local_scene/native_local_scene.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/local_scene/native_local_scene.gd
@@ -3,3 +3,4 @@ extends Node
func a():
var test = $AnimationPlayer
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/local_typehint/class_local_typehint.gd b/modules/gdscript/tests/scripts/completion/get_node/local_typehint/class_local_typehint.gd
index b6d2074939..3277beccab 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/local_typehint/class_local_typehint.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/local_typehint/class_local_typehint.gd
@@ -5,3 +5,4 @@ const A := preload("res://completion/class_a.notest.gd")
func a():
var test: A = $A
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/local_typehint/native_local_typehint.gd b/modules/gdscript/tests/scripts/completion/get_node/local_typehint/native_local_typehint.gd
index 13b541a35d..e6d22af296 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/local_typehint/native_local_typehint.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/local_typehint/native_local_typehint.gd
@@ -3,3 +3,4 @@ extends Node
func a():
var test: AnimationPlayer = $AnimationPlayer
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene/class_local_typehint_scene.gd b/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene/class_local_typehint_scene.gd
index b6d2074939..3277beccab 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene/class_local_typehint_scene.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene/class_local_typehint_scene.gd
@@ -5,3 +5,4 @@ const A := preload("res://completion/class_a.notest.gd")
func a():
var test: A = $A
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene/native_local_typehint_scene.gd b/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene/native_local_typehint_scene.gd
index 13b541a35d..e6d22af296 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene/native_local_typehint_scene.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene/native_local_typehint_scene.gd
@@ -3,3 +3,4 @@ extends Node
func a():
var test: AnimationPlayer = $AnimationPlayer
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_broad/class_local_typehint_scene_broad.notest.gd b/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_broad/class_local_typehint_scene_broad.notest.gd
index 5c785b3ddc..3266679a6a 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_broad/class_local_typehint_scene_broad.notest.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_broad/class_local_typehint_scene_broad.notest.gd
@@ -4,3 +4,4 @@ extends Node
func a():
var test: Node = $A
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_broad/native_local_typehint_scene_broad.notest.gd b/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_broad/native_local_typehint_scene_broad.notest.gd
index 57f4e16e3c..f637fc3d0f 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_broad/native_local_typehint_scene_broad.notest.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_broad/native_local_typehint_scene_broad.notest.gd
@@ -4,3 +4,4 @@ extends Node
func a():
var test: Node = $AnimationPlayer
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_incompatible/class_local_typehint_scene_incompatible.gd b/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_incompatible/class_local_typehint_scene_incompatible.gd
index c6adfe0dd3..8ce75d9996 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_incompatible/class_local_typehint_scene_incompatible.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_incompatible/class_local_typehint_scene_incompatible.gd
@@ -3,3 +3,4 @@ extends Node
func a():
var test: Area2D = $A
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_incompatible/native_local_typehint_scene_incompatible.gd b/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_incompatible/native_local_typehint_scene_incompatible.gd
index f53fce9bfe..2b39e3ada7 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_incompatible/native_local_typehint_scene_incompatible.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/local_typehint_scene_incompatible/native_local_typehint_scene_incompatible.gd
@@ -3,3 +3,4 @@ extends Node
func a():
var test: Area2D = $AnimationPlayer
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/member/member.gd b/modules/gdscript/tests/scripts/completion/get_node/member/member.gd
index 6bcc0a0298..80b4943953 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/member/member.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/member/member.gd
@@ -4,3 +4,4 @@ var test = $AnimationPlayer
func a():
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/member_interfered/member_interfered.gd b/modules/gdscript/tests/scripts/completion/get_node/member_interfered/member_interfered.gd
index 542197e643..97b288334e 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/member_interfered/member_interfered.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/member_interfered/member_interfered.gd
@@ -4,3 +4,4 @@ var test := $AnimationPlayer
func a():
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/class_member_interfered_scene.gd b/modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/class_member_interfered_scene.gd
index da0b1b11d4..402fd1d275 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/class_member_interfered_scene.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/class_member_interfered_scene.gd
@@ -4,3 +4,4 @@ var test := $A
func a():
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/native_member_interfered_scene.gd b/modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/native_member_interfered_scene.gd
index 542197e643..97b288334e 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/native_member_interfered_scene.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/member_interfered_scene/native_member_interfered_scene.gd
@@ -4,3 +4,4 @@ var test := $AnimationPlayer
func a():
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/member_scene/class_member_scene.gd b/modules/gdscript/tests/scripts/completion/get_node/member_scene/class_member_scene.gd
index 4a35661e94..6188a6e843 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/member_scene/class_member_scene.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/member_scene/class_member_scene.gd
@@ -4,3 +4,4 @@ var test = $A
func a():
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/member_scene/native_member_scene.gd b/modules/gdscript/tests/scripts/completion/get_node/member_scene/native_member_scene.gd
index 6bcc0a0298..80b4943953 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/member_scene/native_member_scene.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/member_scene/native_member_scene.gd
@@ -4,3 +4,4 @@ var test = $AnimationPlayer
func a():
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/member_typehint/class_member_typehint.gd b/modules/gdscript/tests/scripts/completion/get_node/member_typehint/class_member_typehint.gd
index e4edc3a4e4..01b7c76dbf 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/member_typehint/class_member_typehint.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/member_typehint/class_member_typehint.gd
@@ -6,3 +6,4 @@ var test: A = $A
func a():
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/member_typehint/native_member_typehint.gd b/modules/gdscript/tests/scripts/completion/get_node/member_typehint/native_member_typehint.gd
index eda94ae34d..7f2cb4e8cc 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/member_typehint/native_member_typehint.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/member_typehint/native_member_typehint.gd
@@ -4,3 +4,4 @@ var test: AnimationPlayer = $AnimationPlayer
func a():
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene/class_member_typehint_scene.gd b/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene/class_member_typehint_scene.gd
index 8f68f54072..43d8b666ab 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene/class_member_typehint_scene.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene/class_member_typehint_scene.gd
@@ -6,3 +6,4 @@ const A := preload("res://completion/class_a.notest.gd")
func a():
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene/native_member_typehint_scene.gd b/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene/native_member_typehint_scene.gd
index eda94ae34d..7f2cb4e8cc 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene/native_member_typehint_scene.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene/native_member_typehint_scene.gd
@@ -4,3 +4,4 @@ var test: AnimationPlayer = $AnimationPlayer
func a():
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_broad/class_member_typehint_scene_broad.gd b/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_broad/class_member_typehint_scene_broad.gd
index 7b0ed4ecd8..aac450be9f 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_broad/class_member_typehint_scene_broad.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_broad/class_member_typehint_scene_broad.gd
@@ -4,3 +4,4 @@ var test: Node = $A
func a():
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_broad/native_member_typehint_scene_broad.gd b/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_broad/native_member_typehint_scene_broad.gd
index 87342f9a21..9eb10e4933 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_broad/native_member_typehint_scene_broad.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_broad/native_member_typehint_scene_broad.gd
@@ -4,3 +4,4 @@ var test: Node = $AnimationPlayer
func a():
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_incompatible/class_member_typehint_scene_incompatible.gd b/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_incompatible/class_member_typehint_scene_incompatible.gd
index 5f78bcdf04..ff8214c463 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_incompatible/class_member_typehint_scene_incompatible.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_incompatible/class_member_typehint_scene_incompatible.gd
@@ -4,3 +4,4 @@ var test: Area2D = $A
func a():
test.➡
+ pass
diff --git a/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_incompatible/native_member_typehint_scene_incompatible.gd b/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_incompatible/native_member_typehint_scene_incompatible.gd
index c14df5cd1b..30cd7d6a21 100644
--- a/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_incompatible/native_member_typehint_scene_incompatible.gd
+++ b/modules/gdscript/tests/scripts/completion/get_node/member_typehint_scene_incompatible/native_member_typehint_scene_incompatible.gd
@@ -4,3 +4,4 @@ var test: Area2D = $AnimationPlayer
func a():
test.➡
+ pass
diff --git a/modules/gdscript/tests/test_completion.h b/modules/gdscript/tests/test_completion.h
index ac9ffcd915..327446acee 100644
--- a/modules/gdscript/tests/test_completion.h
+++ b/modules/gdscript/tests/test_completion.h
@@ -33,6 +33,7 @@
#ifdef TOOLS_ENABLED
+#include "core/config/project_settings.h"
#include "core/io/config_file.h"
#include "core/io/dir_access.h"
#include "core/io/file_access.h"
@@ -111,7 +112,10 @@ static void test_directory(const String &p_dir) {
// For ease of reading ➡ (0x27A1) acts as sentinel char instead of 0xFFFF in the files.
code = code.replace_first(String::chr(0x27A1), String::chr(0xFFFF));
// Require pointer sentinel char in scripts.
- CHECK(code.find_char(0xFFFF) != -1);
+ int location = code.find_char(0xFFFF);
+ CHECK(location != -1);
+
+ String res_path = ProjectSettings::get_singleton()->localize_path(path.path_join(next));
ConfigFile conf;
if (conf.load(path.path_join(next.get_basename() + ".cfg")) != OK) {
@@ -137,20 +141,46 @@ static void test_directory(const String &p_dir) {
String call_hint;
bool forced;
- Node *owner = nullptr;
+ Node *scene = nullptr;
if (conf.has_section_key("input", "scene")) {
- Ref<PackedScene> scene = ResourceLoader::load(conf.get_value("input", "scene"), "PackedScene", ResourceFormatLoader::CACHE_MODE_IGNORE_DEEP);
- if (scene.is_valid()) {
- owner = scene->instantiate();
+ Ref<PackedScene> packed_scene = ResourceLoader::load(conf.get_value("input", "scene"), "PackedScene", ResourceFormatLoader::CACHE_MODE_IGNORE_DEEP);
+ if (packed_scene.is_valid()) {
+ scene = packed_scene->instantiate();
}
} else if (dir->file_exists(next.get_basename() + ".tscn")) {
- Ref<PackedScene> scene = ResourceLoader::load(path.path_join(next.get_basename() + ".tscn"), "PackedScene");
- if (scene.is_valid()) {
- owner = scene->instantiate();
+ Ref<PackedScene> packed_scene = ResourceLoader::load(path.path_join(next.get_basename() + ".tscn"), "PackedScene");
+ if (packed_scene.is_valid()) {
+ scene = packed_scene->instantiate();
+ }
+ }
+ Node *owner = nullptr;
+ if (scene != nullptr) {
+ owner = scene->get_node(conf.get_value("input", "node_path", "."));
+ }
+
+ if (owner != nullptr) {
+ // Remove the line which contains the sentinel char, to get a valid script.
+ Ref<GDScript> scr;
+ scr.instantiate();
+ int start = location;
+ int end = location;
+ for (; start >= 0; --start) {
+ if (code.get(start) == '\n') {
+ break;
+ }
+ }
+ for (; end < code.size(); ++end) {
+ if (code.get(end) == '\n') {
+ break;
+ }
}
+ scr->set_source_code(code.erase(start, end - start));
+ scr->reload();
+ scr->set_path(res_path);
+ owner->set_script(scr);
}
- GDScriptLanguage::get_singleton()->complete_code(code, path.path_join(next), owner, &options, forced, call_hint);
+ GDScriptLanguage::get_singleton()->complete_code(code, res_path, owner, &options, forced, call_hint);
String contains_excluded;
for (ScriptLanguage::CodeCompletionOption &option : options) {
for (const Dictionary &E : exclude) {
@@ -179,8 +209,8 @@ static void test_directory(const String &p_dir) {
CHECK(expected_call_hint == call_hint);
CHECK(expected_forced == forced);
- if (owner) {
- memdelete(owner);
+ if (scene) {
+ memdelete(scene);
}
}
next = dir->get_next();
diff --git a/modules/multiplayer/scene_cache_interface.cpp b/modules/multiplayer/scene_cache_interface.cpp
index 33b05d4cc2..c08ccbe4cc 100644
--- a/modules/multiplayer/scene_cache_interface.cpp
+++ b/modules/multiplayer/scene_cache_interface.cpp
@@ -52,6 +52,9 @@ void SceneCacheInterface::_remove_node_cache(ObjectID p_oid) {
if (!nc) {
return;
}
+ if (nc->cache_id) {
+ assigned_ids.erase(nc->cache_id);
+ }
for (KeyValue<int, int> &E : nc->recv_ids) {
PeerInfo *pinfo = peers_info.getptr(E.key);
ERR_CONTINUE(!pinfo);
@@ -117,16 +120,12 @@ void SceneCacheInterface::process_simplify_path(int p_from, const uint8_t *p_pac
NodeCache &cache = _track(node);
cache.recv_ids.insert(p_from, id);
- // Encode path to send ack.
- CharString pname = String(path).utf8();
- int len = encode_cstring(pname.get_data(), nullptr);
-
+ // Send ack.
Vector<uint8_t> packet;
-
- packet.resize(1 + 1 + len);
+ packet.resize(1 + 1 + 4);
packet.write[0] = SceneMultiplayer::NETWORK_COMMAND_CONFIRM_PATH;
packet.write[1] = valid_rpc_checksum;
- encode_cstring(pname.get_data(), &packet.write[2]);
+ encode_uint32(id, &packet.write[2]);
Ref<MultiplayerPeer> multiplayer_peer = multiplayer->get_multiplayer_peer();
ERR_FAIL_COND(multiplayer_peer.is_null());
@@ -137,26 +136,26 @@ void SceneCacheInterface::process_simplify_path(int p_from, const uint8_t *p_pac
}
void SceneCacheInterface::process_confirm_path(int p_from, const uint8_t *p_packet, int p_packet_len) {
- ERR_FAIL_COND_MSG(p_packet_len < 3, "Invalid packet received. Size too small.");
+ ERR_FAIL_COND_MSG(p_packet_len != 6, "Invalid packet received. Size too small.");
Node *root_node = SceneTree::get_singleton()->get_root()->get_node(multiplayer->get_root_path());
ERR_FAIL_NULL(root_node);
const bool valid_rpc_checksum = p_packet[1];
+ int id = decode_uint32(&p_packet[2]);
- String paths;
- paths.parse_utf8((const char *)&p_packet[2], p_packet_len - 2);
-
- const NodePath path = paths;
+ const ObjectID *oid = assigned_ids.getptr(id);
+ if (oid == nullptr) {
+ return; // May be trying to confirm a node that was removed.
+ }
if (valid_rpc_checksum == false) {
- ERR_PRINT("The rpc node checksum failed. Make sure to have the same methods on both nodes. Node path: " + path);
+ const Node *node = Object::cast_to<Node>(ObjectDB::get_instance(*oid));
+ ERR_FAIL_NULL(node); // Bug.
+ ERR_PRINT("The rpc node checksum failed. Make sure to have the same methods on both nodes. Node path: " + node->get_path());
}
- Node *node = root_node->get_node(path);
- ERR_FAIL_NULL(node);
-
- NodeCache *cache = nodes_cache.getptr(node->get_instance_id());
- ERR_FAIL_NULL_MSG(cache, "Invalid packet received. Tries to confirm a node which was not requested.");
+ NodeCache *cache = nodes_cache.getptr(*oid);
+ ERR_FAIL_NULL(cache); // Bug.
bool *confirmed = cache->confirmed_peers.getptr(p_from);
ERR_FAIL_NULL_MSG(confirmed, "Invalid packet received. Tries to confirm a node which was not requested.");
@@ -216,6 +215,7 @@ int SceneCacheInterface::make_object_cache(Object *p_obj) {
NodeCache &cache = _track(node);
if (cache.cache_id == 0) {
cache.cache_id = last_send_cache_id++;
+ assigned_ids[cache.cache_id] = p_obj->get_instance_id();
}
return cache.cache_id;
}
@@ -227,6 +227,7 @@ bool SceneCacheInterface::send_object_cache(Object *p_obj, int p_peer_id, int &r
NodeCache &cache = _track(node);
if (cache.cache_id == 0) {
cache.cache_id = last_send_cache_id++;
+ assigned_ids[cache.cache_id] = p_obj->get_instance_id();
}
r_id = cache.cache_id;
@@ -289,5 +290,6 @@ void SceneCacheInterface::clear() {
}
peers_info.clear();
nodes_cache.clear();
+ assigned_ids.clear();
last_send_cache_id = 1;
}
diff --git a/modules/multiplayer/scene_cache_interface.h b/modules/multiplayer/scene_cache_interface.h
index ab4a20c078..73d6bde6ef 100644
--- a/modules/multiplayer/scene_cache_interface.h
+++ b/modules/multiplayer/scene_cache_interface.h
@@ -44,7 +44,7 @@ private:
//path sent caches
struct NodeCache {
- int cache_id;
+ int cache_id = 0;
HashMap<int, int> recv_ids; // peer id, remote cache id
HashMap<int, bool> confirmed_peers; // peer id, confirmed
};
@@ -55,6 +55,7 @@ private:
};
HashMap<ObjectID, NodeCache> nodes_cache;
+ HashMap<int, ObjectID> assigned_ids;
HashMap<int, PeerInfo> peers_info;
int last_send_cache_id = 1;