summaryrefslogtreecommitdiff
path: root/modules/gdscript
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript')
-rw-r--r--modules/gdscript/doc_classes/@GDScript.xml106
-rw-r--r--modules/gdscript/doc_classes/GDScript.xml6
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.cpp64
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.h2
-rw-r--r--modules/gdscript/editor/gdscript_translation_parser_plugin.h1
-rw-r--r--modules/gdscript/gdscript.cpp251
-rw-r--r--modules/gdscript/gdscript.h50
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp86
-rw-r--r--modules/gdscript/gdscript_analyzer.h2
-rw-r--r--modules/gdscript/gdscript_byte_codegen.cpp136
-rw-r--r--modules/gdscript/gdscript_byte_codegen.h3
-rw-r--r--modules/gdscript/gdscript_cache.cpp8
-rw-r--r--modules/gdscript/gdscript_cache.h4
-rw-r--r--modules/gdscript/gdscript_codegen.h3
-rw-r--r--modules/gdscript/gdscript_compiler.cpp41
-rw-r--r--modules/gdscript/gdscript_disassembler.cpp6
-rw-r--r--modules/gdscript/gdscript_editor.cpp200
-rw-r--r--modules/gdscript/gdscript_function.cpp13
-rw-r--r--modules/gdscript/gdscript_function.h16
-rw-r--r--modules/gdscript/gdscript_lambda_callable.h2
-rw-r--r--modules/gdscript/gdscript_parser.cpp94
-rw-r--r--modules/gdscript/gdscript_parser.h9
-rw-r--r--modules/gdscript/gdscript_utility_functions.cpp4
-rw-r--r--modules/gdscript/gdscript_vm.cpp30
-rw-r--r--modules/gdscript/language_server/gdscript_extend_parser.cpp34
-rw-r--r--modules/gdscript/language_server/gdscript_language_protocol.cpp11
-rw-r--r--modules/gdscript/language_server/gdscript_language_protocol.h14
-rw-r--r--modules/gdscript/language_server/gdscript_language_server.cpp8
-rw-r--r--modules/gdscript/language_server/gdscript_text_document.cpp25
-rw-r--r--modules/gdscript/language_server/gdscript_text_document.h9
-rw-r--r--modules/gdscript/language_server/gdscript_workspace.cpp16
-rw-r--r--modules/gdscript/language_server/gdscript_workspace.h4
-rw-r--r--modules/gdscript/language_server/lsp.hpp56
-rw-r--r--modules/gdscript/register_types.cpp16
-rw-r--r--modules/gdscript/tests/gdscript_test_runner.cpp37
-rw-r--r--modules/gdscript/tests/gdscript_test_runner_suite.h8
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/call_self_get_name.gd9
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/call_self_get_name.out3
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.gd5
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.out6
-rw-r--r--modules/gdscript/tests/test_gdscript.cpp20
41 files changed, 680 insertions, 738 deletions
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index 9e974b6fdc..51b3452a3a 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -11,16 +11,11 @@
</tutorials>
<methods>
<method name="Color8">
- <return type="Color">
- </return>
- <argument index="0" name="r8" type="int">
- </argument>
- <argument index="1" name="g8" type="int">
- </argument>
- <argument index="2" name="b8" type="int">
- </argument>
- <argument index="3" name="a8" type="int" default="255">
- </argument>
+ <return type="Color" />
+ <argument index="0" name="r8" type="int" />
+ <argument index="1" name="g8" type="int" />
+ <argument index="2" name="b8" type="int" />
+ <argument index="3" name="a8" type="int" default="255" />
<description>
Returns a color constructed from integer red, green, blue, and alpha channels. Each channel should have 8 bits of information ranging from 0 to 255.
[code]r8[/code] red channel
@@ -33,12 +28,9 @@
</description>
</method>
<method name="assert">
- <return type="void">
- </return>
- <argument index="0" name="condition" type="bool">
- </argument>
- <argument index="1" name="message" type="String" default="&quot;&quot;">
- </argument>
+ <return type="void" />
+ <argument index="0" name="condition" type="bool" />
+ <argument index="1" name="message" type="String" default="&quot;&quot;" />
<description>
Asserts that the [code]condition[/code] is [code]true[/code]. If the [code]condition[/code] is [code]false[/code], an error is generated. When running from the editor, the running project will also be paused until you resume it. This can be used as a stronger form of [method @GlobalScope.push_error] for reporting errors to project developers or add-on users.
[b]Note:[/b] For performance reasons, the code inside [method assert] is only executed in debug builds or when running the project from the editor. Don't include code that has side effects in an [method assert] call. Otherwise, the project will behave differently when exported in release mode.
@@ -54,10 +46,8 @@
</description>
</method>
<method name="char">
- <return type="String">
- </return>
- <argument index="0" name="char" type="int">
- </argument>
+ <return type="String" />
+ <argument index="0" name="char" type="int" />
<description>
Returns a character as a String of the given Unicode code point (which is compatible with ASCII code).
[codeblock]
@@ -68,12 +58,9 @@
</description>
</method>
<method name="convert">
- <return type="Variant">
- </return>
- <argument index="0" name="what" type="Variant">
- </argument>
- <argument index="1" name="type" type="int">
- </argument>
+ <return type="Variant" />
+ <argument index="0" name="what" type="Variant" />
+ <argument index="1" name="type" type="int" />
<description>
Converts from a type to another in the best way possible. The [code]type[/code] parameter uses the [enum Variant.Type] values.
[codeblock]
@@ -87,17 +74,14 @@
</description>
</method>
<method name="dict2inst">
- <return type="Object">
- </return>
- <argument index="0" name="dictionary" type="Dictionary">
- </argument>
+ <return type="Object" />
+ <argument index="0" name="dictionary" type="Dictionary" />
<description>
Converts a dictionary (previously created with [method inst2dict]) back to an instance. Useful for deserializing.
</description>
</method>
<method name="get_stack">
- <return type="Array">
- </return>
+ <return type="Array" />
<description>
Returns an array of dictionaries representing the current call stack.
[codeblock]
@@ -117,10 +101,8 @@
</description>
</method>
<method name="inst2dict">
- <return type="Dictionary">
- </return>
- <argument index="0" name="instance" type="Object">
- </argument>
+ <return type="Dictionary" />
+ <argument index="0" name="instance" type="Object" />
<description>
Returns the passed instance converted to a dictionary (useful for serializing).
[codeblock]
@@ -138,10 +120,8 @@
</description>
</method>
<method name="len">
- <return type="int">
- </return>
- <argument index="0" name="var" type="Variant">
- </argument>
+ <return type="int" />
+ <argument index="0" name="var" type="Variant" />
<description>
Returns length of Variant [code]var[/code]. Length is the character count of String, element count of Array, size of Dictionary, etc.
[b]Note:[/b] Generates a fatal error if Variant can not provide a length.
@@ -152,10 +132,8 @@
</description>
</method>
<method name="load">
- <return type="Resource">
- </return>
- <argument index="0" name="path" type="String">
- </argument>
+ <return type="Resource" />
+ <argument index="0" name="path" type="String" />
<description>
Loads a resource from the filesystem located at [code]path[/code]. The resource is loaded on the method call (unless it's referenced already elsewhere, e.g. in another script or in the scene), which might cause slight delay, especially when loading scenes. To avoid unnecessary delays when loading something multiple times, either store the resource in a variable or use [method preload].
[b]Note:[/b] Resource paths can be obtained by right-clicking on a resource in the FileSystem dock and choosing "Copy Path" or by dragging the file from the FileSystem dock into the script.
@@ -168,29 +146,25 @@
</description>
</method>
<method name="preload">
- <return type="Resource">
- </return>
- <argument index="0" name="path" type="String">
- </argument>
+ <return type="Resource" />
+ <argument index="0" name="path" type="String" />
<description>
Returns a [Resource] from the filesystem located at [code]path[/code]. The resource is loaded during script parsing, i.e. is loaded with the script and [method preload] effectively acts as a reference to that resource. Note that the method requires a constant path. If you want to load a resource from a dynamic/variable path, use [method load].
[b]Note:[/b] Resource paths can be obtained by right clicking on a resource in the Assets Panel and choosing "Copy Path" or by dragging the file from the FileSystem dock into the script.
[codeblock]
# Instance a scene.
- var diamond = preload("res://diamond.tscn").instance()
+ var diamond = preload("res://diamond.tscn").instantiate()
[/codeblock]
</description>
</method>
<method name="print_debug" qualifiers="vararg">
- <return type="void">
- </return>
+ <return type="void" />
<description>
Like [method @GlobalScope.print], but prints only when used in debug mode.
</description>
</method>
<method name="print_stack">
- <return type="void">
- </return>
+ <return type="void" />
<description>
Prints a stack track at code location, only works when running with debugger turned on.
Output in the console would look something like this:
@@ -200,8 +174,7 @@
</description>
</method>
<method name="range" qualifiers="vararg">
- <return type="Array">
- </return>
+ <return type="Array" />
<description>
Returns an array with the given range. Range can be 1 argument N (0 to N-1), two arguments (initial, final-1) or three arguments (initial, final-1, increment).
[codeblock]
@@ -218,8 +191,7 @@
</description>
</method>
<method name="str" qualifiers="vararg">
- <return type="String">
- </return>
+ <return type="String" />
<description>
Converts one or more arguments to string in the best way possible.
[codeblock]
@@ -231,26 +203,26 @@
</description>
</method>
<method name="type_exists">
- <return type="bool">
- </return>
- <argument index="0" name="type" type="StringName">
- </argument>
+ <return type="bool" />
+ <argument index="0" name="type" type="StringName" />
<description>
</description>
</method>
</methods>
<constants>
- <constant name="PI" value="3.141593">
- Constant that represents how many times the diameter of a circle fits around its perimeter. This is equivalent to [code]TAU / 2[/code].
+ <constant name="PI" value="3.14159265358979">
+ Constant that represents how many times the diameter of a circle fits around its perimeter. This is equivalent to [code]TAU / 2[/code], or 180 degrees in rotations.
</constant>
- <constant name="TAU" value="6.283185">
- The circle constant, the circumference of the unit circle in radians.
+ <constant name="TAU" value="6.28318530717959">
+ The circle constant, the circumference of the unit circle in radians. This is equivalent to [code]PI * 2[/code], or 360 degrees in rotations.
</constant>
<constant name="INF" value="inf">
- Positive infinity. For negative infinity, use -INF.
+ Positive floating-point infinity. This is the result of floating-point division when the divisor is [code]0.0[/code]. For negative infinity, use [code]-INF[/code]. Dividing by [code]-0.0[/code] will result in negative infinity if the numerator is positive, so dividing by [code]0.0[/code] is not the same as dividing by [code]-0.0[/code] (despite [code]0.0 == -0.0[/code] returning [code]true[/code]).
+ [b]Note:[/b] Numeric infinity is only a concept with floating-point numbers, and has no equivalent for integers. Dividing an integer number by [code]0[/code] will not result in [constant INF] and will result in a run-time error instead.
</constant>
<constant name="NAN" value="nan">
- "Not a Number", an invalid value. [code]NaN[/code] has special properties, including that it is not equal to itself. It is output by some invalid operations, such as dividing zero by zero.
+ "Not a Number", an invalid floating-point value. [constant NAN] has special properties, including that it is not equal to itself ([code]NAN == NAN[/code] returns [code]false[/code]). It is output by some invalid operations, such as dividing floating-point [code]0.0[/code] by [code]0.0[/code].
+ [b]Note:[/b] "Not a Number" is only a concept with floating-point numbers, and has no equivalent for integers. Dividing an integer [code]0[/code] by [code]0[/code] will not result in [constant NAN] and will result in a run-time error instead.
</constant>
</constants>
</class>
diff --git a/modules/gdscript/doc_classes/GDScript.xml b/modules/gdscript/doc_classes/GDScript.xml
index 631a102130..72738f027a 100644
--- a/modules/gdscript/doc_classes/GDScript.xml
+++ b/modules/gdscript/doc_classes/GDScript.xml
@@ -12,15 +12,13 @@
</tutorials>
<methods>
<method name="get_as_byte_code" qualifiers="const">
- <return type="PackedByteArray">
- </return>
+ <return type="PackedByteArray" />
<description>
Returns byte code for the script source code.
</description>
</method>
<method name="new" qualifiers="vararg">
- <return type="Variant">
- </return>
+ <return type="Variant" />
<description>
Returns a new instance of the script.
For example:
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp
index ca646dff15..ed8b0a4690 100644
--- a/modules/gdscript/editor/gdscript_highlighter.cpp
+++ b/modules/gdscript/editor/gdscript_highlighter.cpp
@@ -64,6 +64,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting(int p_line)
bool in_function_args = false;
bool in_member_variable = false;
bool in_node_path = false;
+ bool in_annotation = false;
bool is_hex_notation = false;
bool is_bin_notation = false;
bool expect_type = false;
@@ -357,9 +358,18 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting(int p_line)
in_node_path = false;
}
+ if (!in_annotation && in_region == -1 && str[j] == '@') {
+ in_annotation = true;
+ } else if (in_region != -1 || is_a_symbol) {
+ in_annotation = false;
+ }
+
if (in_node_path) {
next_type = NODE_PATH;
color = node_path_color;
+ } else if (in_annotation) {
+ next_type = ANNOTATION;
+ color = annotation_color;
} else if (in_keyword) {
next_type = KEYWORD;
color = keyword_color;
@@ -438,7 +448,7 @@ void GDScriptSyntaxHighlighter::_update_cache() {
color_regions.clear();
color_region_cache.clear();
- font_color = text_edit->get_theme_color("font_color");
+ font_color = text_edit->get_theme_color(SNAME("font_color"));
symbol_color = EDITOR_GET("text_editor/highlighting/symbol_color");
function_color = EDITOR_GET("text_editor/highlighting/function_color");
number_color = EDITOR_GET("text_editor/highlighting/number_color");
@@ -448,8 +458,8 @@ void GDScriptSyntaxHighlighter::_update_cache() {
const Color types_color = EDITOR_GET("text_editor/highlighting/engine_type_color");
List<StringName> types;
ClassDB::get_class_list(&types);
- for (List<StringName>::Element *E = types.front(); E; E = E->next()) {
- String n = E->get();
+ for (const StringName &E : types) {
+ String n = E;
if (n.begins_with("_")) {
n = n.substr(1, n.length());
}
@@ -460,8 +470,8 @@ void GDScriptSyntaxHighlighter::_update_cache() {
const Color usertype_color = EDITOR_GET("text_editor/highlighting/user_type_color");
List<StringName> global_classes;
ScriptServer::get_global_class_list(&global_classes);
- for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) {
- keywords[String(E->get())] = usertype_color;
+ for (const StringName &E : global_classes) {
+ keywords[String(E)] = usertype_color;
}
/* Autoloads. */
@@ -479,8 +489,8 @@ void GDScriptSyntaxHighlighter::_update_cache() {
const Color basetype_color = EDITOR_GET("text_editor/highlighting/base_type_color");
List<String> core_types;
gdscript->get_core_type_words(&core_types);
- for (List<String>::Element *E = core_types.front(); E; E = E->next()) {
- keywords[E->get()] = basetype_color;
+ for (const String &E : core_types) {
+ keywords[E] = basetype_color;
}
/* Reserved words. */
@@ -488,11 +498,11 @@ void GDScriptSyntaxHighlighter::_update_cache() {
const Color control_flow_keyword_color = EDITOR_GET("text_editor/highlighting/control_flow_keyword_color");
List<String> keyword_list;
gdscript->get_reserved_words(&keyword_list);
- for (List<String>::Element *E = keyword_list.front(); E; E = E->next()) {
- if (gdscript->is_control_flow_keyword(E->get())) {
- keywords[E->get()] = control_flow_keyword_color;
+ for (const String &E : keyword_list) {
+ if (gdscript->is_control_flow_keyword(E)) {
+ keywords[E] = control_flow_keyword_color;
} else {
- keywords[E->get()] = keyword_color;
+ keywords[E] = keyword_color;
}
}
@@ -500,8 +510,7 @@ void GDScriptSyntaxHighlighter::_update_cache() {
const Color comment_color = EDITOR_GET("text_editor/highlighting/comment_color");
List<String> comments;
gdscript->get_comment_delimiters(&comments);
- for (List<String>::Element *E = comments.front(); E; E = E->next()) {
- String comment = E->get();
+ for (const String &comment : comments) {
String beg = comment.get_slice(" ", 0);
String end = comment.get_slice_count(" ") > 1 ? comment.get_slice(" ", 1) : String();
add_color_region(beg, end, comment_color, end == "");
@@ -511,8 +520,7 @@ void GDScriptSyntaxHighlighter::_update_cache() {
const Color string_color = EDITOR_GET("text_editor/highlighting/string_color");
List<String> strings;
gdscript->get_string_delimiters(&strings);
- for (List<String>::Element *E = strings.front(); E; E = E->next()) {
- String string = E->get();
+ for (const String &string : strings) {
String beg = string.get_slice(" ", 0);
String end = string.get_slice_count(" ") > 1 ? string.get_slice(" ", 1) : String();
add_color_region(beg, end, string_color, end == "");
@@ -526,9 +534,9 @@ void GDScriptSyntaxHighlighter::_update_cache() {
if (instance_base != StringName()) {
List<PropertyInfo> plist;
ClassDB::get_property_list(instance_base, &plist);
- for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
- String name = E->get().name;
- if (E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_GROUP || E->get().usage & PROPERTY_USAGE_SUBGROUP) {
+ for (const PropertyInfo &E : plist) {
+ String name = E.name;
+ if (E.usage & PROPERTY_USAGE_CATEGORY || E.usage & PROPERTY_USAGE_GROUP || E.usage & PROPERTY_USAGE_SUBGROUP) {
continue;
}
if (name.find("/") != -1) {
@@ -539,26 +547,29 @@ void GDScriptSyntaxHighlighter::_update_cache() {
List<String> clist;
ClassDB::get_integer_constant_list(instance_base, &clist);
- for (List<String>::Element *E = clist.front(); E; E = E->next()) {
- member_keywords[E->get()] = member_variable_color;
+ for (const String &E : clist) {
+ member_keywords[E] = member_variable_color;
}
}
}
const String text_edit_color_theme = EditorSettings::get_singleton()->get("text_editor/theme/color_theme");
- const bool default_theme = text_edit_color_theme == "Default";
+ const bool godot_2_theme = text_edit_color_theme == "Godot 2";
- if (default_theme || EditorSettings::get_singleton()->is_dark_theme()) {
+ if (godot_2_theme || EditorSettings::get_singleton()->is_dark_theme()) {
function_definition_color = Color(0.4, 0.9, 1.0);
node_path_color = Color(0.39, 0.76, 0.35);
+ annotation_color = Color(1.0, 0.7, 0.45);
} else {
function_definition_color = Color(0.0, 0.65, 0.73);
node_path_color = Color(0.32, 0.55, 0.29);
+ annotation_color = Color(0.8, 0.5, 0.25);
}
EDITOR_DEF("text_editor/highlighting/gdscript/function_definition_color", function_definition_color);
EDITOR_DEF("text_editor/highlighting/gdscript/node_path_color", node_path_color);
- if (text_edit_color_theme == "Adaptive" || default_theme) {
+ EDITOR_DEF("text_editor/highlighting/gdscript/annotation_color", annotation_color);
+ if (text_edit_color_theme == "Default" || godot_2_theme) {
EditorSettings::get_singleton()->set_initial_value(
"text_editor/highlighting/gdscript/function_definition_color",
function_definition_color,
@@ -567,10 +578,15 @@ void GDScriptSyntaxHighlighter::_update_cache() {
"text_editor/highlighting/gdscript/node_path_color",
node_path_color,
true);
+ EditorSettings::get_singleton()->set_initial_value(
+ "text_editor/highlighting/gdscript/annotation_color",
+ annotation_color,
+ true);
}
function_definition_color = EDITOR_GET("text_editor/highlighting/gdscript/function_definition_color");
node_path_color = EDITOR_GET("text_editor/highlighting/gdscript/node_path_color");
+ annotation_color = EDITOR_GET("text_editor/highlighting/gdscript/annotation_color");
type_color = EDITOR_GET("text_editor/highlighting/base_type_color");
}
@@ -604,6 +620,6 @@ void GDScriptSyntaxHighlighter::add_color_region(const String &p_start_key, cons
Ref<EditorSyntaxHighlighter> GDScriptSyntaxHighlighter::_create() const {
Ref<GDScriptSyntaxHighlighter> syntax_highlighter;
- syntax_highlighter.instance();
+ syntax_highlighter.instantiate();
return syntax_highlighter;
}
diff --git a/modules/gdscript/editor/gdscript_highlighter.h b/modules/gdscript/editor/gdscript_highlighter.h
index 1b57cb1923..d07c182aa6 100644
--- a/modules/gdscript/editor/gdscript_highlighter.h
+++ b/modules/gdscript/editor/gdscript_highlighter.h
@@ -54,6 +54,7 @@ private:
NONE,
REGION,
NODE_PATH,
+ ANNOTATION,
SYMBOL,
NUMBER,
FUNCTION,
@@ -72,6 +73,7 @@ private:
Color number_color;
Color member_color;
Color node_path_color;
+ Color annotation_color;
Color type_color;
void add_color_region(const String &p_start_key, const String &p_end_key, const Color &p_color, bool p_line_only = false);
diff --git a/modules/gdscript/editor/gdscript_translation_parser_plugin.h b/modules/gdscript/editor/gdscript_translation_parser_plugin.h
index fcf438422a..caa80fc24c 100644
--- a/modules/gdscript/editor/gdscript_translation_parser_plugin.h
+++ b/modules/gdscript/editor/gdscript_translation_parser_plugin.h
@@ -34,7 +34,6 @@
#include "core/templates/set.h"
#include "editor/editor_translation_parser.h"
#include "modules/gdscript/gdscript_parser.h"
-#include "modules/regex/regex.h"
class GDScriptEditorTranslationParserPlugin : public EditorTranslationParserPlugin {
GDCLASS(GDScriptEditorTranslationParserPlugin, EditorTranslationParserPlugin);
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index 2896420239..8957b00a1b 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -36,8 +36,8 @@
#include "core/config/project_settings.h"
#include "core/core_constants.h"
#include "core/core_string_names.h"
+#include "core/io/file_access.h"
#include "core/io/file_access_encrypted.h"
-#include "core/os/file_access.h"
#include "core/os/os.h"
#include "gdscript_analyzer.h"
#include "gdscript_cache.h"
@@ -72,19 +72,19 @@ void GDScriptNativeClass::_bind_methods() {
}
Variant GDScriptNativeClass::_new() {
- Object *o = instance();
+ Object *o = instantiate();
ERR_FAIL_COND_V_MSG(!o, Variant(), "Class type: '" + String(name) + "' is not instantiable.");
- Reference *ref = Object::cast_to<Reference>(o);
- if (ref) {
- return REF(ref);
+ RefCounted *rc = Object::cast_to<RefCounted>(o);
+ if (rc) {
+ return REF(rc);
} else {
return o;
}
}
-Object *GDScriptNativeClass::instance() {
- return ClassDB::instance(name);
+Object *GDScriptNativeClass::instantiate() {
+ return ClassDB::instantiate(name);
}
void GDScript::_super_implicit_constructor(GDScript *p_script, GDScriptInstance *p_instance, Callable::CallError &r_error) {
@@ -98,11 +98,11 @@ void GDScript::_super_implicit_constructor(GDScript *p_script, GDScriptInstance
p_script->implicit_initializer->call(p_instance, nullptr, 0, r_error);
}
-GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Callable::CallError &r_error) {
+GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_is_ref_counted, Callable::CallError &r_error) {
/* STEP 1, CREATE */
GDScriptInstance *instance = memnew(GDScriptInstance);
- instance->base_ref = p_isref;
+ instance->base_ref_counted = p_is_ref_counted;
instance->members.resize(member_indices.size());
instance->script = Ref<GDScript>(this);
instance->owner = p_owner;
@@ -170,13 +170,13 @@ Variant GDScript::_new(const Variant **p_args, int p_argcount, Callable::CallErr
ERR_FAIL_COND_V(_baseptr->native.is_null(), Variant());
if (_baseptr->native.ptr()) {
- owner = _baseptr->native->instance();
+ owner = _baseptr->native->instantiate();
} else {
- owner = memnew(Reference); //by default, no base means use reference
+ owner = memnew(RefCounted); //by default, no base means use reference
}
ERR_FAIL_COND_V_MSG(!owner, Variant(), "Can't inherit from a virtual class.");
- Reference *r = Object::cast_to<Reference>(owner);
+ RefCounted *r = Object::cast_to<RefCounted>(owner);
if (r) {
ref = REF(r);
}
@@ -196,7 +196,7 @@ Variant GDScript::_new(const Variant **p_args, int p_argcount, Callable::CallErr
}
}
-bool GDScript::can_instance() const {
+bool GDScript::can_instantiate() const {
#ifdef TOOLS_ENABLED
return valid && (tool || ScriptServer::is_scripting_enabled());
#else
@@ -291,8 +291,8 @@ void GDScript::_get_script_property_list(List<PropertyInfo> *r_list, bool p_incl
sptr = sptr->_base;
}
- for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
- r_list->push_back(E->get());
+ for (const PropertyInfo &E : props) {
+ r_list->push_back(E);
}
}
@@ -346,21 +346,21 @@ ScriptInstance *GDScript::instance_create(Object *p_this) {
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() + "'");
+ GDScriptLanguage::get_singleton()->debug_break_parse(get_path(), 1, "Script inherits from native type '" + String(top->native->get_name()) + "', so it can't be instantiated in object of type: '" + p_this->get_class() + "'");
}
- ERR_FAIL_V_MSG(nullptr, "Script inherits from native type '" + String(top->native->get_name()) + "', so it can't be instanced in object of type '" + p_this->get_class() + "'" + ".");
+ ERR_FAIL_V_MSG(nullptr, "Script inherits from native type '" + String(top->native->get_name()) + "', so it can't be instantiated in object of type '" + p_this->get_class() + "'" + ".");
}
}
Callable::CallError unchecked_error;
- return _create_instance(nullptr, 0, p_this, Object::cast_to<Reference>(p_this) != nullptr, unchecked_error);
+ return _create_instance(nullptr, 0, p_this, Object::cast_to<RefCounted>(p_this) != nullptr, unchecked_error);
}
PlaceHolderScriptInstance *GDScript::placeholder_instance_create(Object *p_this) {
#ifdef TOOLS_ENABLED
PlaceHolderScriptInstance *si = memnew(PlaceHolderScriptInstance(GDScriptLanguage::get_singleton(), Ref<Script>(this), p_this));
placeholders.insert(si);
- _update_exports();
+ _update_exports(nullptr, false, si);
return si;
#else
return nullptr;
@@ -401,8 +401,8 @@ void GDScript::_update_exports_values(Map<StringName, Variant> &values, List<Pro
values[E->key()] = E->get();
}
- for (List<PropertyInfo>::Element *E = members_cache.front(); E; E = E->next()) {
- propnames.push_back(E->get());
+ for (const PropertyInfo &E : members_cache) {
+ propnames.push_back(E);
}
}
@@ -584,7 +584,7 @@ void GDScript::_update_doc() {
}
#endif
-bool GDScript::_update_exports(bool *r_err, bool p_recursive_call) {
+bool GDScript::_update_exports(bool *r_err, bool p_recursive_call, PlaceHolderScriptInstance *p_instance_to_update) {
#ifdef TOOLS_ENABLED
static Vector<GDScript *> base_caches;
@@ -721,15 +721,19 @@ bool GDScript::_update_exports(bool *r_err, bool p_recursive_call) {
}
}
- if (placeholders.size()) { //hm :(
+ if ((changed || p_instance_to_update) && placeholders.size()) { //hm :(
// update placeholders if any
Map<StringName, Variant> values;
List<PropertyInfo> propnames;
_update_exports_values(values, propnames);
- for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
- E->get()->update(propnames, values);
+ if (changed) {
+ for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
+ E->get()->update(propnames, values);
+ }
+ } else {
+ p_instance_to_update->update(propnames, values);
}
}
@@ -857,8 +861,7 @@ Error GDScript::reload(bool p_keep_state) {
}
}
#ifdef DEBUG_ENABLED
- for (const List<GDScriptWarning>::Element *E = parser.get_warnings().front(); E; E = E->next()) {
- const GDScriptWarning &warning = E->get();
+ for (const GDScriptWarning &warning : parser.get_warnings()) {
if (EngineDebugger::is_active()) {
Vector<ScriptLanguage::StackInfo> si;
EngineDebugger::get_script_debugger()->send_error("", get_path(), warning.start_line, warning.get_name(), warning.get_message(), ERR_HANDLER_WARNING, si);
@@ -897,68 +900,10 @@ void GDScript::get_members(Set<StringName> *p_members) {
}
}
-Vector<ScriptNetData> GDScript::get_rpc_methods() const {
+const Vector<MultiplayerAPI::RPCConfig> GDScript::get_rpc_methods() const {
return rpc_functions;
}
-uint16_t GDScript::get_rpc_method_id(const StringName &p_method) const {
- for (int i = 0; i < rpc_functions.size(); i++) {
- if (rpc_functions[i].name == p_method) {
- return i;
- }
- }
- return UINT16_MAX;
-}
-
-StringName GDScript::get_rpc_method(const uint16_t p_rpc_method_id) const {
- 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()) {
- return MultiplayerAPI::RPC_MODE_DISABLED;
- }
- return rpc_functions[p_rpc_method_id].mode;
-}
-
-MultiplayerAPI::RPCMode GDScript::get_rpc_mode(const StringName &p_method) const {
- return get_rpc_mode_by_id(get_rpc_method_id(p_method));
-}
-
-Vector<ScriptNetData> GDScript::get_rset_properties() const {
- return rpc_variables;
-}
-
-uint16_t GDScript::get_rset_property_id(const StringName &p_variable) const {
- for (int i = 0; i < rpc_variables.size(); i++) {
- if (rpc_variables[i].name == p_variable) {
- return i;
- }
- }
- return UINT16_MAX;
-}
-
-StringName GDScript::get_rset_property(const uint16_t p_rset_member_id) const {
- 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()) {
- return MultiplayerAPI::RPC_MODE_DISABLED;
- }
- return rpc_variables[p_rset_member_id].mode;
-}
-
-MultiplayerAPI::RPCMode GDScript::get_rset_mode(const StringName &p_variable) const {
- return get_rset_mode_by_id(get_rset_property_id(p_variable));
-}
-
Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
GDScript *top = this;
while (top) {
@@ -1045,7 +990,7 @@ Error GDScript::load_source_code(const String &p_path) {
ERR_FAIL_COND_V(err, err);
}
- uint64_t len = f->get_len();
+ uint64_t len = f->get_length();
sourcef.resize(len + 1);
uint8_t *w = sourcef.ptrw();
uint64_t r = f->get_buffer(w, len);
@@ -1210,10 +1155,8 @@ void GDScript::_save_orphaned_subclasses() {
void GDScript::_init_rpc_methods_properties() {
// Copy the base rpc methods so we don't mask their IDs.
rpc_functions.clear();
- rpc_variables.clear();
if (base.is_valid()) {
rpc_functions = base->rpc_functions;
- rpc_variables = base->rpc_variables;
}
GDScript *cscript = this;
@@ -1221,23 +1164,11 @@ void GDScript::_init_rpc_methods_properties() {
while (cscript) {
// RPC Methods
for (Map<StringName, GDScriptFunction *>::Element *E = cscript->member_functions.front(); E; E = E->next()) {
- if (E->get()->get_rpc_mode() != MultiplayerAPI::RPC_MODE_DISABLED) {
- ScriptNetData nd;
- nd.name = E->key();
- nd.mode = E->get()->get_rpc_mode();
- if (-1 == rpc_functions.find(nd)) {
- rpc_functions.push_back(nd);
- }
- }
- }
- // RSet
- for (Map<StringName, MemberInfo>::Element *E = cscript->member_indices.front(); E; E = E->next()) {
- if (E->get().rpc_mode != MultiplayerAPI::RPC_MODE_DISABLED) {
- ScriptNetData nd;
- nd.name = E->key();
- nd.mode = E->get().rpc_mode;
- if (-1 == rpc_variables.find(nd)) {
- rpc_variables.push_back(nd);
+ MultiplayerAPI::RPCConfig config = E->get()->get_rpc_config();
+ if (config.rpc_mode != MultiplayerAPI::RPC_MODE_DISABLED) {
+ config.name = E->get()->get_name();
+ if (rpc_functions.find(config) == -1) {
+ rpc_functions.push_back(config);
}
}
}
@@ -1254,8 +1185,7 @@ void GDScript::_init_rpc_methods_properties() {
}
// Sort so we are 100% that they are always the same.
- rpc_functions.sort_custom<SortNetData>();
- rpc_variables.sort_custom<SortNetData>();
+ rpc_functions.sort_custom<MultiplayerAPI::SortRPCConfig>();
}
GDScript::~GDScript() {
@@ -1514,8 +1444,8 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const
sptr = sptr->_base;
}
- for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
- p_properties->push_back(E->get());
+ for (const PropertyInfo &E : props) {
+ p_properties->push_back(E);
}
}
@@ -1611,46 +1541,10 @@ ScriptLanguage *GDScriptInstance::get_language() {
return GDScriptLanguage::get_singleton();
}
-Vector<ScriptNetData> GDScriptInstance::get_rpc_methods() const {
+const Vector<MultiplayerAPI::RPCConfig> GDScriptInstance::get_rpc_methods() const {
return script->get_rpc_methods();
}
-uint16_t GDScriptInstance::get_rpc_method_id(const StringName &p_method) const {
- return script->get_rpc_method_id(p_method);
-}
-
-StringName GDScriptInstance::get_rpc_method(const uint16_t p_rpc_method_id) const {
- return script->get_rpc_method(p_rpc_method_id);
-}
-
-MultiplayerAPI::RPCMode GDScriptInstance::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const {
- return script->get_rpc_mode_by_id(p_rpc_method_id);
-}
-
-MultiplayerAPI::RPCMode GDScriptInstance::get_rpc_mode(const StringName &p_method) const {
- return script->get_rpc_mode(p_method);
-}
-
-Vector<ScriptNetData> GDScriptInstance::get_rset_properties() const {
- return script->get_rset_properties();
-}
-
-uint16_t GDScriptInstance::get_rset_property_id(const StringName &p_variable) const {
- return script->get_rset_property_id(p_variable);
-}
-
-StringName GDScriptInstance::get_rset_property(const uint16_t p_rset_member_id) const {
- return script->get_rset_property(p_rset_member_id);
-}
-
-MultiplayerAPI::RPCMode GDScriptInstance::get_rset_mode_by_id(const uint16_t p_rset_member_id) const {
- return script->get_rset_mode_by_id(p_rset_member_id);
-}
-
-MultiplayerAPI::RPCMode GDScriptInstance::get_rset_mode(const StringName &p_variable) const {
- return script->get_rset_mode(p_variable);
-}
-
void GDScriptInstance::reload_members() {
#ifdef DEBUG_ENABLED
@@ -1681,7 +1575,7 @@ void GDScriptInstance::reload_members() {
GDScriptInstance::GDScriptInstance() {
owner = nullptr;
- base_ref = false;
+ base_ref_counted = false;
}
GDScriptInstance::~GDScriptInstance() {
@@ -1742,33 +1636,32 @@ void GDScriptLanguage::init() {
_add_global(StaticCString::create("PI"), Math_PI);
_add_global(StaticCString::create("TAU"), Math_TAU);
- _add_global(StaticCString::create("INF"), Math_INF);
- _add_global(StaticCString::create("NAN"), Math_NAN);
+ _add_global(StaticCString::create("INF"), INFINITY);
+ _add_global(StaticCString::create("NAN"), NAN);
//populate native classes
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();
+ for (const StringName &n : class_list) {
String s = String(n);
if (s.begins_with("_")) {
- n = s.substr(1, s.length());
+ s = s.substr(1, s.length());
}
- if (globals.has(n)) {
+ if (globals.has(s)) {
continue;
}
- Ref<GDScriptNativeClass> nc = memnew(GDScriptNativeClass(E->get()));
- _add_global(n, nc);
+ Ref<GDScriptNativeClass> nc = memnew(GDScriptNativeClass(n));
+ _add_global(s, nc);
}
//populate singletons
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);
+ for (const Engine::Singleton &E : singletons) {
+ _add_global(E.name, E.ptr);
}
#ifdef TESTS_ENABLED
@@ -1911,10 +1804,10 @@ 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);
+ for (Ref<GDScript> &script : scripts) {
+ print_verbose("GDScript: Reloading: " + script->get_path());
+ script->load_source_code(script->get_path());
+ script->reload(true);
}
#endif
}
@@ -1943,21 +1836,21 @@ 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());
+ for (Ref<GDScript> &script : scripts) {
+ bool reload = script == p_script || to_reload.has(script->get_base());
if (!reload) {
continue;
}
- to_reload.insert(E->get(), Map<ObjectID, List<Pair<StringName, Variant>>>());
+ to_reload.insert(script, 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()];
+ Map<ObjectID, List<Pair<StringName, Variant>>> &map = to_reload[script];
- while (E->get()->instances.front()) {
- Object *obj = E->get()->instances.front()->get();
+ while (script->instances.front()) {
+ Object *obj = script->instances.front()->get();
//save instance info
List<Pair<StringName, Variant>> state;
if (obj->get_script_instance()) {
@@ -1970,8 +1863,8 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
//same thing for placeholders
#ifdef TOOLS_ENABLED
- while (E->get()->placeholders.size()) {
- Object *obj = E->get()->placeholders.front()->get()->get_owner();
+ while (script->placeholders.size()) {
+ Object *obj = script->placeholders.front()->get()->get_owner();
//save instance info
if (obj->get_script_instance()) {
@@ -1981,13 +1874,13 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
obj->set_script(Variant());
} else {
// no instance found. Let's remove it so we don't loop forever
- E->get()->placeholders.erase(E->get()->placeholders.front()->get());
+ script->placeholders.erase(script->placeholders.front()->get());
}
}
#endif
- for (Map<ObjectID, List<Pair<StringName, Variant>>>::Element *F = E->get()->pending_reload_state.front(); F; F = F->next()) {
+ for (Map<ObjectID, List<Pair<StringName, Variant>>>::Element *F = script->pending_reload_state.front(); F; F = F->next()) {
map[F->key()] = F->get(); //pending to reload, use this one instead
}
}
@@ -2130,8 +2023,8 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const {
List<StringName> functions;
GDScriptUtilityFunctions::get_function_list(&functions);
- for (const List<StringName>::Element *E = functions.front(); E; E = E->next()) {
- p_words->push_back(String(E->get()));
+ for (const StringName &E : functions) {
+ p_words->push_back(String(E));
}
}
@@ -2169,7 +2062,7 @@ String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_b
if (err == OK) {
const GDScriptParser::ClassNode *c = parser.get_tree();
if (r_icon_path) {
- if (c->icon_path.is_empty() || c->icon_path.is_abs_path()) {
+ if (c->icon_path.is_empty() || c->icon_path.is_absolute_path()) {
*r_icon_path = c->icon_path;
} else if (c->icon_path.is_rel_path()) {
*r_icon_path = p_path.get_base_dir().plus_file(c->icon_path).simplify_path();
@@ -2237,7 +2130,7 @@ String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_b
break;
}
} else {
- *r_base_type = "Reference";
+ *r_base_type = "RefCounted";
subclass = nullptr;
}
}
@@ -2357,7 +2250,7 @@ RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_ori
if (script.is_null()) {
// Don't fail loading because of parsing error.
- script.instance();
+ script.instantiate();
}
if (r_error) {
@@ -2401,8 +2294,8 @@ void ResourceFormatLoaderGDScript::get_dependencies(const String &p_path, List<S
return;
}
- for (const List<String>::Element *E = parser.get_dependencies().front(); E; E = E->next()) {
- p_dependencies->push_back(E->get());
+ for (const String &E : parser.get_dependencies()) {
+ p_dependencies->push_back(E);
}
}
diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h
index 6df66e876d..24809ad5fd 100644
--- a/modules/gdscript/gdscript.h
+++ b/modules/gdscript/gdscript.h
@@ -39,8 +39,8 @@
#include "core/object/script_language.h"
#include "gdscript_function.h"
-class GDScriptNativeClass : public Reference {
- GDCLASS(GDScriptNativeClass, Reference);
+class GDScriptNativeClass : public RefCounted {
+ GDCLASS(GDScriptNativeClass, RefCounted);
StringName name;
@@ -51,7 +51,7 @@ protected:
public:
_FORCE_INLINE_ const StringName &get_name() const { return name; }
Variant _new();
- Object *instance();
+ Object *instantiate();
GDScriptNativeClass(const StringName &p_name);
};
@@ -64,7 +64,6 @@ class GDScript : public Script {
int index = 0;
StringName setter;
StringName getter;
- MultiplayerAPI::RPCMode rpc_mode;
GDScriptDataType data_type;
};
@@ -80,14 +79,13 @@ class GDScript : public Script {
GDScript *_base = nullptr; //fast pointer access
GDScript *_owner = nullptr; //for subclasses
- Set<StringName> members; //members are just indices to the instanced script.
+ Set<StringName> members; //members are just indices to the instantiated script.
Map<StringName, Variant> constants;
Map<StringName, GDScriptFunction *> member_functions;
- Map<StringName, MemberInfo> member_indices; //members are just indices to the instanced script.
+ Map<StringName, MemberInfo> member_indices; //members are just indices to the instantiated script.
Map<StringName, Ref<GDScript>> subclasses;
Map<StringName, Vector<StringName>> _signals;
- Vector<ScriptNetData> rpc_functions;
- Vector<ScriptNetData> rpc_variables;
+ Vector<MultiplayerAPI::RPCConfig> rpc_functions;
#ifdef TOOLS_ENABLED
@@ -133,7 +131,7 @@ class GDScript : public Script {
SelfList<GDScriptFunctionState>::List pending_func_states;
void _super_implicit_constructor(GDScript *p_script, GDScriptInstance *p_instance, Callable::CallError &r_error);
- GDScriptInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Callable::CallError &r_error);
+ GDScriptInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_is_ref_counted, Callable::CallError &r_error);
void _set_subclass_path(Ref<GDScript> &p_sc, const String &p_path);
@@ -149,7 +147,7 @@ class GDScript : public Script {
#endif
- bool _update_exports(bool *r_err = nullptr, bool p_recursive_call = false);
+ bool _update_exports(bool *r_err = nullptr, bool p_recursive_call = false, PlaceHolderScriptInstance *p_instance_to_update = nullptr);
void _save_orphaned_subclasses();
void _init_rpc_methods_properties();
@@ -158,7 +156,7 @@ class GDScript : public Script {
void _get_script_method_list(List<MethodInfo> *r_list, bool p_include_base) const;
void _get_script_signal_list(List<MethodInfo> *r_list, bool p_include_base) const;
- // This method will map the class name from "Reference" to "MyClass.InnerClass".
+ // This method will map the class name from "RefCounted" to "MyClass.InnerClass".
static String _get_gdscript_reference_class_name(const GDScript *p_gdscript);
protected:
@@ -197,7 +195,7 @@ public:
StringName debug_get_member_by_index(int p_idx) const;
Variant _new(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
- virtual bool can_instance() const override;
+ virtual bool can_instantiate() const override;
virtual Ref<Script> get_base_script() const override;
@@ -247,17 +245,7 @@ public:
virtual void get_constants(Map<StringName, Variant> *p_constants) override;
virtual void get_members(Set<StringName> *p_members) override;
- virtual Vector<ScriptNetData> get_rpc_methods() const override;
- virtual uint16_t get_rpc_method_id(const StringName &p_method) const override;
- virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const override;
- virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const override;
- virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const override;
-
- virtual Vector<ScriptNetData> get_rset_properties() const override;
- virtual uint16_t get_rset_property_id(const StringName &p_variable) const override;
- virtual StringName get_rset_property(const uint16_t p_variable_id) const override;
- virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const override;
- virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const override;
+ virtual const Vector<MultiplayerAPI::RPCConfig> get_rpc_methods() const override;
#ifdef TOOLS_ENABLED
virtual bool is_placeholder_fallback_enabled() const override { return placeholder_fallback_enabled; }
@@ -281,7 +269,7 @@ class GDScriptInstance : public ScriptInstance {
Map<StringName, int> member_indices_cache; //used only for hot script reloading
#endif
Vector<Variant> members;
- bool base_ref;
+ bool base_ref_counted;
SelfList<GDScriptFunctionState>::List pending_func_states;
@@ -310,17 +298,7 @@ public:
void reload_members();
- virtual Vector<ScriptNetData> get_rpc_methods() const;
- virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
- virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const;
- virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const;
- virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
-
- virtual Vector<ScriptNetData> get_rset_properties() const;
- virtual uint16_t get_rset_property_id(const StringName &p_variable) const;
- virtual StringName get_rset_property(const uint16_t p_variable_id) const;
- virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const;
- virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
+ virtual const Vector<MultiplayerAPI::RPCConfig> get_rpc_methods() const;
GDScriptInstance();
~GDScriptInstance();
@@ -468,7 +446,7 @@ public:
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
virtual bool is_using_templates();
virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script);
- virtual bool 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 = nullptr, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const;
+ virtual bool validate(const String &p_script, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptLanguage::ScriptError> *r_errors = nullptr, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const;
virtual Script *create_script() const;
virtual bool has_named_classes() const;
virtual bool supports_builtin_mode() const;
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index 7b04959227..ab37e54cf1 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -31,10 +31,10 @@
#include "gdscript_analyzer.h"
#include "core/config/project_settings.h"
+#include "core/io/file_access.h"
#include "core/io/resource_loader.h"
#include "core/object/class_db.h"
#include "core/object/script_language.h"
-#include "core/os/file_access.h"
#include "core/templates/hash_map.h"
#include "gdscript.h"
#include "gdscript_utility_functions.h"
@@ -115,8 +115,8 @@ static GDScriptParser::DataType make_native_enum_type(const StringName &p_native
StringName real_native_name = GDScriptParser::get_real_class_name(p_native_class);
ClassDB::get_enum_constants(real_native_name, p_enum_name, &enum_values);
- for (const List<StringName>::Element *E = enum_values.front(); E != nullptr; E = E->next()) {
- type.enum_values[E->get()] = ClassDB::get_integer_constant(real_native_name, E->get());
+ for (const StringName &E : enum_values) {
+ type.enum_values[E] = ClassDB::get_integer_constant(real_native_name, E);
}
return type;
@@ -163,7 +163,7 @@ Error GDScriptAnalyzer::resolve_inheritance(GDScriptParser::ClassNode *p_class,
if (!p_class->extends_used) {
result.type_source = GDScriptParser::DataType::ANNOTATED_INFERRED;
result.kind = GDScriptParser::DataType::NATIVE;
- result.native_type = "Reference";
+ result.native_type = "RefCounted";
} else {
result.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
@@ -229,7 +229,7 @@ Error GDScriptAnalyzer::resolve_inheritance(GDScriptParser::ClassNode *p_class,
push_error(vformat(R"(Could not resolve super class inheritance from "%s".)", name), p_class);
return err;
}
- } else if (class_exists(name) && ClassDB::can_instance(GDScriptParser::get_real_class_name(name))) {
+ } else if (class_exists(name) && ClassDB::can_instantiate(GDScriptParser::get_real_class_name(name))) {
base.kind = GDScriptParser::DataType::NATIVE;
base.native_type = name;
} else {
@@ -543,6 +543,7 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
} else {
// TODO: Add warning.
mark_node_unsafe(member.variable->initializer);
+ member.variable->use_conversion_assign = true;
}
} else if (datatype.builtin_type == Variant::INT && member.variable->initializer->get_datatype().builtin_type == Variant::FLOAT) {
#ifdef DEBUG_ENABLED
@@ -552,6 +553,7 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
if (member.variable->initializer->get_datatype().is_variant()) {
// TODO: Warn unsafe assign.
mark_node_unsafe(member.variable->initializer);
+ member.variable->use_conversion_assign = true;
}
}
} else if (member.variable->infer_datatype) {
@@ -571,8 +573,8 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
member.variable->set_datatype(datatype);
// Apply annotations.
- for (List<GDScriptParser::AnnotationNode *>::Element *E = member.variable->annotations.front(); E; E = E->next()) {
- E->get()->apply(parser, member.variable);
+ for (GDScriptParser::AnnotationNode *&E : member.variable->annotations) {
+ E->apply(parser, member.variable);
}
} break;
case GDScriptParser::ClassNode::Member::CONSTANT: {
@@ -620,8 +622,8 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
member.constant->set_datatype(datatype);
// Apply annotations.
- for (List<GDScriptParser::AnnotationNode *>::Element *E = member.constant->annotations.front(); E; E = E->next()) {
- E->get()->apply(parser, member.constant);
+ for (GDScriptParser::AnnotationNode *&E : member.constant->annotations) {
+ E->apply(parser, member.constant);
}
} break;
case GDScriptParser::ClassNode::Member::SIGNAL: {
@@ -639,8 +641,8 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
member.signal->set_datatype(signal_type);
// Apply annotations.
- for (List<GDScriptParser::AnnotationNode *>::Element *E = member.signal->annotations.front(); E; E = E->next()) {
- E->get()->apply(parser, member.signal);
+ for (GDScriptParser::AnnotationNode *&E : member.signal->annotations) {
+ E->apply(parser, member.signal);
}
} break;
case GDScriptParser::ClassNode::Member::ENUM: {
@@ -686,8 +688,8 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
member.m_enum->set_datatype(enum_type);
// Apply annotations.
- for (List<GDScriptParser::AnnotationNode *>::Element *E = member.m_enum->annotations.front(); E; E = E->next()) {
- E->get()->apply(parser, member.m_enum);
+ for (GDScriptParser::AnnotationNode *&E : member.m_enum->annotations) {
+ E->apply(parser, member.m_enum);
}
} break;
case GDScriptParser::ClassNode::Member::FUNCTION:
@@ -759,8 +761,8 @@ void GDScriptAnalyzer::resolve_class_body(GDScriptParser::ClassNode *p_class) {
resolve_function_body(member.function);
// Apply annotations.
- for (List<GDScriptParser::AnnotationNode *>::Element *E = member.function->annotations.front(); E; E = E->next()) {
- E->get()->apply(parser, member.function);
+ for (GDScriptParser::AnnotationNode *&E : member.function->annotations) {
+ E->apply(parser, member.function);
}
}
@@ -1145,6 +1147,7 @@ void GDScriptAnalyzer::resolve_variable(GDScriptParser::VariableNode *p_variable
} else {
// TODO: Add warning.
mark_node_unsafe(p_variable->initializer);
+ p_variable->use_conversion_assign = true;
}
#ifdef DEBUG_ENABLED
} else if (type.builtin_type == Variant::INT && p_variable->initializer->get_datatype().builtin_type == Variant::FLOAT) {
@@ -1154,6 +1157,7 @@ void GDScriptAnalyzer::resolve_variable(GDScriptParser::VariableNode *p_variable
if (p_variable->initializer->get_datatype().is_variant()) {
// TODO: Warn unsafe assign.
mark_node_unsafe(p_variable->initializer);
+ p_variable->use_conversion_assign = true;
}
}
} else if (p_variable->infer_datatype) {
@@ -1608,10 +1612,12 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig
} else {
// TODO: Add warning.
mark_node_unsafe(p_assignment);
+ p_assignment->use_conversion_assign = true;
}
} else {
// TODO: Warning in this case.
mark_node_unsafe(p_assignment);
+ p_assignment->use_conversion_assign = true;
}
}
} else {
@@ -1621,6 +1627,9 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig
if (assignee_type.has_no_type() || assigned_value_type.is_variant()) {
mark_node_unsafe(p_assignment);
+ if (assignee_type.is_hard_type()) {
+ p_assignment->use_conversion_assign = true;
+ }
}
if (p_assignment->assignee->type == GDScriptParser::Node::IDENTIFIER) {
@@ -1770,10 +1779,10 @@ void GDScriptAnalyzer::reduce_binary_op(GDScriptParser::BinaryOpNode *p_binary_o
} else {
if (p_binary_op->variant_op < Variant::OP_MAX) {
bool valid = false;
- result = get_operation_type(p_binary_op->variant_op, p_binary_op->left_operand->get_datatype(), right_type, valid, p_binary_op);
+ result = get_operation_type(p_binary_op->variant_op, left_type, right_type, valid, p_binary_op);
if (!valid) {
- push_error(vformat(R"(Invalid operands "%s" and "%s" for "%s" operator.)", p_binary_op->left_operand->get_datatype().to_string(), right_type.to_string(), Variant::get_operator_name(p_binary_op->variant_op)), p_binary_op);
+ push_error(vformat(R"(Invalid operands "%s" and "%s" for "%s" operator.)", left_type.to_string(), right_type.to_string(), Variant::get_operator_name(p_binary_op->variant_op)), p_binary_op);
}
} else {
if (p_binary_op->operation == GDScriptParser::BinaryOpNode::OP_TYPE_TEST) {
@@ -1918,9 +1927,7 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool is_awa
Variant::get_constructor_list(builtin_type, &constructors);
bool match = false;
- for (const List<MethodInfo>::Element *E = constructors.front(); E != nullptr; E = E->next()) {
- const MethodInfo &info = E->get();
-
+ for (const MethodInfo &info : constructors) {
if (p_call->arguments.size() < info.arguments.size() - info.default_arguments.size()) {
continue;
}
@@ -2059,9 +2066,11 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool is_awa
if (p_call->is_super) {
base_type = parser->current_class->base_type;
+ base_type.is_meta_type = false;
is_self = true;
} else if (callee_type == GDScriptParser::Node::IDENTIFIER) {
base_type = parser->current_class->get_datatype();
+ base_type.is_meta_type = false;
is_self = true;
} else if (callee_type == GDScriptParser::Node::SUBSCRIPT) {
GDScriptParser::SubscriptNode *subscript = static_cast<GDScriptParser::SubscriptNode *>(p_call->callee);
@@ -2315,8 +2324,7 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
Variant::construct(base.builtin_type, dummy, nullptr, 0, temp);
List<PropertyInfo> properties;
dummy.get_property_list(&properties);
- for (const List<PropertyInfo>::Element *E = properties.front(); E != nullptr; E = E->next()) {
- const PropertyInfo &prop = E->get();
+ for (const PropertyInfo &prop : properties) {
if (prop.name == name) {
p_identifier->set_datatype(type_from_property(prop));
return;
@@ -2338,6 +2346,7 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
GDScriptParser::DataType result;
result.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
result.kind = GDScriptParser::DataType::ENUM_VALUE;
+ result.builtin_type = base.builtin_type;
result.native_type = base.native_type;
result.enum_type = name;
p_identifier->set_datatype(result);
@@ -2814,7 +2823,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri
case Variant::RECT2:
case Variant::RECT2I:
case Variant::PLANE:
- case Variant::QUAT:
+ case Variant::QUATERNION:
case Variant::AABB:
case Variant::OBJECT:
error = index_type.builtin_type != Variant::STRING;
@@ -2825,8 +2834,8 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri
case Variant::VECTOR2I:
case Variant::VECTOR3:
case Variant::VECTOR3I:
- case Variant::TRANSFORM:
case Variant::TRANSFORM2D:
+ case Variant::TRANSFORM3D:
error = index_type.builtin_type != Variant::INT && index_type.builtin_type != Variant::FLOAT &&
index_type.builtin_type != Variant::STRING;
break;
@@ -2893,7 +2902,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri
case Variant::PACKED_FLOAT64_ARRAY:
case Variant::VECTOR2:
case Variant::VECTOR3:
- case Variant::QUAT:
+ case Variant::QUATERNION:
result_type.builtin_type = Variant::FLOAT;
break;
// Return Color.
@@ -2922,7 +2931,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri
result_type.builtin_type = Variant::VECTOR3;
break;
// Depends on the index.
- case Variant::TRANSFORM:
+ case Variant::TRANSFORM3D:
case Variant::PLANE:
case Variant::COLOR:
case Variant::DICTIONARY:
@@ -3113,8 +3122,8 @@ GDScriptParser::DataType GDScriptAnalyzer::type_from_variant(const Variant &p_va
GDScriptParser::ClassNode *found = ref->get_parser()->head;
// It should be okay to assume this exists, since we have a complete script already.
- for (const List<StringName>::Element *E = class_chain.front(); E; E = E->next()) {
- found = found->get_member(E->get()).m_class;
+ for (const StringName &E : class_chain) {
+ found = found->get_member(E).m_class;
}
result.class_type = found;
@@ -3210,9 +3219,9 @@ bool GDScriptAnalyzer::get_function_signature(GDScriptParser::Node *p_source, GD
List<MethodInfo> methods;
dummy.get_method_list(&methods);
- for (const List<MethodInfo>::Element *E = methods.front(); E != nullptr; E = E->next()) {
- if (E->get().name == p_function) {
- return function_signature_from_info(E->get(), r_return_type, r_par_types, r_default_arg_count, r_static, r_vararg);
+ for (const MethodInfo &E : methods) {
+ if (E.name == p_function) {
+ return function_signature_from_info(E, r_return_type, r_par_types, r_default_arg_count, r_static, r_vararg);
}
}
@@ -3309,8 +3318,8 @@ bool GDScriptAnalyzer::function_signature_from_info(const MethodInfo &p_info, GD
r_default_arg_count = p_info.default_arguments.size();
r_vararg = (p_info.flags & METHOD_FLAG_VARARG) != 0;
- for (const List<PropertyInfo>::Element *E = p_info.arguments.front(); E != nullptr; E = E->next()) {
- r_par_types.push_back(type_from_property(E->get()));
+ for (const PropertyInfo &E : p_info.arguments) {
+ r_par_types.push_back(type_from_property(E));
}
return true;
}
@@ -3318,8 +3327,8 @@ bool GDScriptAnalyzer::function_signature_from_info(const MethodInfo &p_info, GD
bool GDScriptAnalyzer::validate_call_arg(const MethodInfo &p_method, const GDScriptParser::CallNode *p_call) {
List<GDScriptParser::DataType> arg_types;
- for (const List<PropertyInfo>::Element *E = p_method.arguments.front(); E != nullptr; E = E->next()) {
- arg_types.push_back(type_from_property(E->get()));
+ for (const PropertyInfo &E : p_method.arguments) {
+ arg_types.push_back(type_from_property(E));
}
return validate_call_arg(arg_types, p_method.default_arguments.size(), (p_method.flags & METHOD_FLAG_VARARG) != 0, p_call);
@@ -3435,6 +3444,7 @@ GDScriptParser::DataType GDScriptAnalyzer::get_operation_type(Variant::Operator
}
r_valid = true;
+ result.type_source = GDScriptParser::DataType::ANNOTATED_INFERRED;
result.kind = GDScriptParser::DataType::BUILTIN;
result.builtin_type = Variant::get_operator_return_type(p_operation, a_type, b_type);
@@ -3645,11 +3655,11 @@ Error GDScriptAnalyzer::resolve_program() {
List<String> parser_keys;
depended_parsers.get_key_list(&parser_keys);
- for (const List<String>::Element *E = parser_keys.front(); E != nullptr; E = E->next()) {
- if (depended_parsers[E->get()].is_null()) {
+ for (const String &E : parser_keys) {
+ if (depended_parsers[E].is_null()) {
return ERR_PARSE_ERROR;
}
- depended_parsers[E->get()]->raise_status(GDScriptParserRef::FULLY_SOLVED);
+ depended_parsers[E]->raise_status(GDScriptParserRef::FULLY_SOLVED);
}
return parser->errors.is_empty() ? OK : ERR_PARSE_ERROR;
}
diff --git a/modules/gdscript/gdscript_analyzer.h b/modules/gdscript/gdscript_analyzer.h
index aabf407c76..8cd3fcf837 100644
--- a/modules/gdscript/gdscript_analyzer.h
+++ b/modules/gdscript/gdscript_analyzer.h
@@ -32,7 +32,7 @@
#define GDSCRIPT_ANALYZER_H
#include "core/object/object.h"
-#include "core/object/reference.h"
+#include "core/object/ref_counted.h"
#include "core/templates/set.h"
#include "gdscript_cache.h"
#include "gdscript_parser.h"
diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp
index ea34a2ca2d..5958326315 100644
--- a/modules/gdscript/gdscript_byte_codegen.cpp
+++ b/modules/gdscript/gdscript_byte_codegen.cpp
@@ -85,10 +85,10 @@ uint32_t GDScriptByteCodeGenerator::add_temporary(const GDScriptDataType &p_type
case Variant::VECTOR3I:
case Variant::TRANSFORM2D:
case Variant::PLANE:
- case Variant::QUAT:
+ case Variant::QUATERNION:
case Variant::AABB:
case Variant::BASIS:
- case Variant::TRANSFORM:
+ case Variant::TRANSFORM3D:
case Variant::COLOR:
case Variant::STRING_NAME:
case Variant::NODE_PATH:
@@ -155,7 +155,7 @@ void GDScriptByteCodeGenerator::end_parameters() {
function->default_arguments.reverse();
}
-void GDScriptByteCodeGenerator::write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, MultiplayerAPI::RPCMode p_rpc_mode, const GDScriptDataType &p_return_type) {
+void GDScriptByteCodeGenerator::write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, MultiplayerAPI::RPCConfig p_rpc_config, const GDScriptDataType &p_return_type) {
function = memnew(GDScriptFunction);
debug_stack = EngineDebugger::is_active();
@@ -170,7 +170,7 @@ void GDScriptByteCodeGenerator::write_start(GDScript *p_script, const StringName
function->_static = p_static;
function->return_type = p_return_type;
- function->rpc_mode = p_rpc_mode;
+ function->rpc_config = p_rpc_config;
function->_argument_count = 0;
}
@@ -458,8 +458,8 @@ void GDScriptByteCodeGenerator::write_type_adjust(const Address &p_target, Varia
case Variant::PLANE:
append(GDScriptFunction::OPCODE_TYPE_ADJUST_PLANE, 1);
break;
- case Variant::QUAT:
- append(GDScriptFunction::OPCODE_TYPE_ADJUST_QUAT, 1);
+ case Variant::QUATERNION:
+ append(GDScriptFunction::OPCODE_TYPE_ADJUST_QUATERNION, 1);
break;
case Variant::AABB:
append(GDScriptFunction::OPCODE_TYPE_ADJUST_AABB, 1);
@@ -467,7 +467,7 @@ void GDScriptByteCodeGenerator::write_type_adjust(const Address &p_target, Varia
case Variant::BASIS:
append(GDScriptFunction::OPCODE_TYPE_ADJUST_BASIS, 1);
break;
- case Variant::TRANSFORM:
+ case Variant::TRANSFORM3D:
append(GDScriptFunction::OPCODE_TYPE_ADJUST_TRANSFORM, 1);
break;
case Variant::COLOR:
@@ -554,6 +554,14 @@ void GDScriptByteCodeGenerator::write_unary_operator(const Address &p_target, Va
void GDScriptByteCodeGenerator::write_binary_operator(const Address &p_target, Variant::Operator p_operator, const Address &p_left_operand, const Address &p_right_operand) {
if (HAS_BUILTIN_TYPE(p_left_operand) && HAS_BUILTIN_TYPE(p_right_operand)) {
+ if (p_target.mode == Address::TEMPORARY) {
+ Variant::Type result_type = Variant::get_operator_return_type(p_operator, p_left_operand.type.builtin_type, p_right_operand.type.builtin_type);
+ Variant::Type temp_type = temporaries[p_target.address].type;
+ if (result_type != temp_type) {
+ write_type_adjust(p_target, result_type);
+ }
+ }
+
// Gather specific operator.
Variant::ValidatedOperatorEvaluator op_func = Variant::get_validated_operator_evaluator(p_operator, p_left_operand.type.builtin_type, p_right_operand.type.builtin_type);
@@ -779,63 +787,43 @@ void GDScriptByteCodeGenerator::write_get_member(const Address &p_target, const
append(p_name);
}
-void GDScriptByteCodeGenerator::write_assign(const Address &p_target, const Address &p_source) {
- if (p_target.type.has_type && !p_source.type.has_type) {
- // Typed assignment.
- switch (p_target.type.kind) {
- case GDScriptDataType::BUILTIN: {
- if (p_target.type.builtin_type == Variant::ARRAY && p_target.type.has_container_element_type()) {
- append(GDScriptFunction::OPCODE_ASSIGN_TYPED_ARRAY, 2);
- append(p_target);
- append(p_source);
- } else {
- append(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN, 2);
- append(p_target);
- append(p_source);
- append(p_target.type.builtin_type);
- }
- } break;
- case GDScriptDataType::NATIVE: {
- int class_idx = GDScriptLanguage::get_singleton()->get_global_map()[p_target.type.native_type];
- Variant nc = GDScriptLanguage::get_singleton()->get_global_array()[class_idx];
- class_idx = get_constant_pos(nc) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);
- append(GDScriptFunction::OPCODE_ASSIGN_TYPED_NATIVE, 3);
- append(p_target);
- append(p_source);
- append(class_idx);
- } break;
- case GDScriptDataType::SCRIPT:
- case GDScriptDataType::GDSCRIPT: {
- Variant script = p_target.type.script_type;
- int idx = get_constant_pos(script) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);
-
- append(GDScriptFunction::OPCODE_ASSIGN_TYPED_SCRIPT, 3);
+void GDScriptByteCodeGenerator::write_assign_with_conversion(const Address &p_target, const Address &p_source) {
+ switch (p_target.type.kind) {
+ case GDScriptDataType::BUILTIN: {
+ if (p_target.type.builtin_type == Variant::ARRAY && p_target.type.has_container_element_type()) {
+ append(GDScriptFunction::OPCODE_ASSIGN_TYPED_ARRAY, 2);
append(p_target);
append(p_source);
- append(idx);
- } break;
- default: {
- ERR_PRINT("Compiler bug: unresolved assign.");
-
- // Shouldn't get here, but fail-safe to a regular assignment
- append(GDScriptFunction::OPCODE_ASSIGN, 2);
+ } else {
+ append(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN, 2);
append(p_target);
append(p_source);
+ append(p_target.type.builtin_type);
}
- }
- } else {
- if (p_target.type.kind == GDScriptDataType::BUILTIN && p_target.type.builtin_type == Variant::ARRAY && p_target.type.has_container_element_type()) {
- append(GDScriptFunction::OPCODE_ASSIGN_TYPED_ARRAY, 2);
+ } break;
+ case GDScriptDataType::NATIVE: {
+ int class_idx = GDScriptLanguage::get_singleton()->get_global_map()[p_target.type.native_type];
+ Variant nc = GDScriptLanguage::get_singleton()->get_global_array()[class_idx];
+ class_idx = get_constant_pos(nc) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);
+ append(GDScriptFunction::OPCODE_ASSIGN_TYPED_NATIVE, 3);
append(p_target);
append(p_source);
- } else if (p_target.type.kind == GDScriptDataType::BUILTIN && p_source.type.kind == GDScriptDataType::BUILTIN && p_target.type.builtin_type != p_source.type.builtin_type) {
- // Need conversion..
- append(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN, 2);
+ append(class_idx);
+ } break;
+ case GDScriptDataType::SCRIPT:
+ case GDScriptDataType::GDSCRIPT: {
+ Variant script = p_target.type.script_type;
+ int idx = get_constant_pos(script) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);
+
+ append(GDScriptFunction::OPCODE_ASSIGN_TYPED_SCRIPT, 3);
append(p_target);
append(p_source);
- append(p_target.type.builtin_type);
- } else {
- // Either untyped assignment or already type-checked by the parser
+ append(idx);
+ } break;
+ default: {
+ ERR_PRINT("Compiler bug: unresolved assign.");
+
+ // Shouldn't get here, but fail-safe to a regular assignment
append(GDScriptFunction::OPCODE_ASSIGN, 2);
append(p_target);
append(p_source);
@@ -843,6 +831,24 @@ void GDScriptByteCodeGenerator::write_assign(const Address &p_target, const Addr
}
}
+void GDScriptByteCodeGenerator::write_assign(const Address &p_target, const Address &p_source) {
+ if (p_target.type.kind == GDScriptDataType::BUILTIN && p_target.type.builtin_type == Variant::ARRAY && p_target.type.has_container_element_type()) {
+ append(GDScriptFunction::OPCODE_ASSIGN_TYPED_ARRAY, 2);
+ append(p_target);
+ append(p_source);
+ } else if (p_target.type.kind == GDScriptDataType::BUILTIN && p_source.type.kind == GDScriptDataType::BUILTIN && p_target.type.builtin_type != p_source.type.builtin_type) {
+ // Need conversion.
+ append(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN, 2);
+ append(p_target);
+ append(p_source);
+ append(p_target.type.builtin_type);
+ } else {
+ append(GDScriptFunction::OPCODE_ASSIGN, 2);
+ append(p_target);
+ append(p_source);
+ }
+}
+
void GDScriptByteCodeGenerator::write_assign_true(const Address &p_target) {
append(GDScriptFunction::OPCODE_ASSIGN_TRUE, 1);
append(p_target);
@@ -1102,12 +1108,12 @@ void GDScriptByteCodeGenerator::write_call_ptrcall(const Address &p_target, cons
CASE_TYPE(PLANE);
CASE_TYPE(AABB);
CASE_TYPE(BASIS);
- CASE_TYPE(TRANSFORM);
+ CASE_TYPE(TRANSFORM3D);
CASE_TYPE(COLOR);
CASE_TYPE(STRING_NAME);
CASE_TYPE(NODE_PATH);
CASE_TYPE(RID);
- CASE_TYPE(QUAT);
+ CASE_TYPE(QUATERNION);
CASE_TYPE(OBJECT);
CASE_TYPE(CALLABLE);
CASE_TYPE(SIGNAL);
@@ -1453,8 +1459,8 @@ void GDScriptByteCodeGenerator::write_endfor() {
}
// Patch break statements.
- for (const List<int>::Element *E = current_breaks_to_patch.back()->get().front(); E; E = E->next()) {
- patch_jump(E->get());
+ for (const int &E : current_breaks_to_patch.back()->get()) {
+ patch_jump(E);
}
current_breaks_to_patch.pop_back();
@@ -1488,8 +1494,8 @@ void GDScriptByteCodeGenerator::write_endwhile() {
while_jmp_addrs.pop_back();
// Patch break statements.
- for (const List<int>::Element *E = current_breaks_to_patch.back()->get().front(); E; E = E->next()) {
- patch_jump(E->get());
+ for (const int &E : current_breaks_to_patch.back()->get()) {
+ patch_jump(E);
}
current_breaks_to_patch.pop_back();
}
@@ -1500,8 +1506,8 @@ void GDScriptByteCodeGenerator::start_match() {
void GDScriptByteCodeGenerator::start_match_branch() {
// Patch continue statements.
- for (const List<int>::Element *E = match_continues_to_patch.back()->get().front(); E; E = E->next()) {
- patch_jump(E->get());
+ for (const int &E : match_continues_to_patch.back()->get()) {
+ patch_jump(E);
}
match_continues_to_patch.pop_back();
// Start a new list for next branch.
@@ -1510,8 +1516,8 @@ void GDScriptByteCodeGenerator::start_match_branch() {
void GDScriptByteCodeGenerator::end_match() {
// Patch continue statements.
- for (const List<int>::Element *E = match_continues_to_patch.back()->get().front(); E; E = E->next()) {
- patch_jump(E->get());
+ for (const int &E : match_continues_to_patch.back()->get()) {
+ patch_jump(E);
}
match_continues_to_patch.pop_back();
}
diff --git a/modules/gdscript/gdscript_byte_codegen.h b/modules/gdscript/gdscript_byte_codegen.h
index f8c05fea83..3d6fb291ad 100644
--- a/modules/gdscript/gdscript_byte_codegen.h
+++ b/modules/gdscript/gdscript_byte_codegen.h
@@ -419,7 +419,7 @@ public:
virtual void start_block() override;
virtual void end_block() override;
- virtual void write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, MultiplayerAPI::RPCMode p_rpc_mode, const GDScriptDataType &p_return_type) override;
+ virtual void write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, MultiplayerAPI::RPCConfig p_rpc_config, const GDScriptDataType &p_return_type) override;
virtual GDScriptFunction *write_end() override;
#ifdef DEBUG_ENABLED
@@ -450,6 +450,7 @@ public:
virtual void write_set_member(const Address &p_value, const StringName &p_name) override;
virtual void write_get_member(const Address &p_target, const StringName &p_name) override;
virtual void write_assign(const Address &p_target, const Address &p_source) override;
+ virtual void write_assign_with_conversion(const Address &p_target, const Address &p_source) override;
virtual void write_assign_true(const Address &p_target) override;
virtual void write_assign_false(const Address &p_target) override;
virtual void write_assign_default_parameter(const Address &p_dst, const Address &p_src) override;
diff --git a/modules/gdscript/gdscript_cache.cpp b/modules/gdscript/gdscript_cache.cpp
index 6aa76703f1..1a844bf241 100644
--- a/modules/gdscript/gdscript_cache.cpp
+++ b/modules/gdscript/gdscript_cache.cpp
@@ -30,7 +30,7 @@
#include "gdscript_cache.h"
-#include "core/os/file_access.h"
+#include "core/io/file_access.h"
#include "core/templates/vector.h"
#include "gdscript.h"
#include "gdscript_analyzer.h"
@@ -134,7 +134,7 @@ Ref<GDScriptParserRef> GDScriptCache::get_parser(const String &p_path, GDScriptP
return ref;
}
GDScriptParser *parser = memnew(GDScriptParser);
- ref.instance();
+ ref.instantiate();
ref->parser = parser;
ref->path = p_path;
singleton->parser_map[p_path] = ref.ptr();
@@ -153,7 +153,7 @@ String GDScriptCache::get_source_code(const String &p_path) {
ERR_FAIL_COND_V(err, "");
}
- uint64_t len = f->get_len();
+ uint64_t len = f->get_length();
source_file.resize(len + 1);
uint64_t r = f->get_buffer(source_file.ptrw(), len);
f->close();
@@ -180,7 +180,7 @@ Ref<GDScript> GDScriptCache::get_shallow_script(const String &p_path, const Stri
}
Ref<GDScript> script;
- script.instance();
+ script.instantiate();
script->set_path(p_path, true);
script->set_script_path(p_path);
script->load_source_code(p_path);
diff --git a/modules/gdscript/gdscript_cache.h b/modules/gdscript/gdscript_cache.h
index d1d2a2abbf..943638d29f 100644
--- a/modules/gdscript/gdscript_cache.h
+++ b/modules/gdscript/gdscript_cache.h
@@ -31,7 +31,7 @@
#ifndef GDSCRIPT_CACHE_H
#define GDSCRIPT_CACHE_H
-#include "core/object/reference.h"
+#include "core/object/ref_counted.h"
#include "core/os/mutex.h"
#include "core/templates/hash_map.h"
#include "core/templates/set.h"
@@ -40,7 +40,7 @@
class GDScriptAnalyzer;
class GDScriptParser;
-class GDScriptParserRef : public Reference {
+class GDScriptParserRef : public RefCounted {
public:
enum Status {
EMPTY,
diff --git a/modules/gdscript/gdscript_codegen.h b/modules/gdscript/gdscript_codegen.h
index 399c9d6de7..ecc86c37f3 100644
--- a/modules/gdscript/gdscript_codegen.h
+++ b/modules/gdscript/gdscript_codegen.h
@@ -80,7 +80,7 @@ public:
virtual void start_block() = 0;
virtual void end_block() = 0;
- virtual void write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, MultiplayerAPI::RPCMode p_rpc_mode, const GDScriptDataType &p_return_type) = 0;
+ virtual void write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, MultiplayerAPI::RPCConfig p_rpc_config, const GDScriptDataType &p_return_type) = 0;
virtual GDScriptFunction *write_end() = 0;
#ifdef DEBUG_ENABLED
@@ -111,6 +111,7 @@ public:
virtual void write_set_member(const Address &p_value, const StringName &p_name) = 0;
virtual void write_get_member(const Address &p_target, const StringName &p_name) = 0;
virtual void write_assign(const Address &p_target, const Address &p_source) = 0;
+ virtual void write_assign_with_conversion(const Address &p_target, const Address &p_source) = 0;
virtual void write_assign_true(const Address &p_target) = 0;
virtual void write_assign_false(const Address &p_target) = 0;
virtual void write_assign_default_parameter(const Address &dst, const Address &src) = 0;
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 4ac9864d4f..7c9d08b782 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -981,8 +981,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
assigned = prev_base;
// Set back the values into their bases.
- for (List<ChainInfo>::Element *E = set_chain.front(); E; E = E->next()) {
- const ChainInfo &info = E->get();
+ for (const ChainInfo &info : set_chain) {
if (!info.is_named) {
gen->write_set(info.base, info.key, assigned);
if (info.key.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
@@ -1084,7 +1083,11 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
gen->write_call(GDScriptCodeGenerator::Address(), GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::SELF), setter_function, args);
} else {
// Just assign.
- gen->write_assign(target, op_result);
+ if (assignment->use_conversion_assign) {
+ gen->write_assign_with_conversion(target, op_result);
+ } else {
+ gen->write_assign(target, op_result);
+ }
}
if (op_result.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
@@ -1792,7 +1795,11 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Sui
if (error) {
return error;
}
- gen->write_assign(local, src_address);
+ if (lv->use_conversion_assign) {
+ gen->write_assign_with_conversion(local, src_address);
+ } else {
+ gen->write_assign(local, src_address);
+ }
if (src_address.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
codegen.generator->pop_temporary();
}
@@ -1851,7 +1858,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_
StringName func_name;
bool is_static = false;
- MultiplayerAPI::RPCMode rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
+ MultiplayerAPI::RPCConfig rpc_config;
GDScriptDataType return_type;
return_type.has_type = true;
return_type.kind = GDScriptDataType::BUILTIN;
@@ -1864,7 +1871,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_
func_name = "<anonymous lambda>";
}
is_static = p_func->is_static;
- rpc_mode = p_func->rpc_mode;
+ rpc_config = p_func->rpc_config;
return_type = _gdtype_from_datatype(p_func->get_datatype(), p_script);
} else {
if (p_for_ready) {
@@ -1875,7 +1882,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_
}
codegen.function_name = func_name;
- codegen.generator->write_start(p_script, func_name, is_static, rpc_mode, return_type);
+ codegen.generator->write_start(p_script, func_name, is_static, rpc_config, return_type);
int optional_parameters = 0;
@@ -1930,7 +1937,11 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_
return nullptr;
}
- codegen.generator->write_assign(dst_address, src_address);
+ if (field->use_conversion_assign) {
+ codegen.generator->write_assign_with_conversion(dst_address, src_address);
+ } else {
+ codegen.generator->write_assign(dst_address, src_address);
+ }
if (src_address.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
codegen.generator->pop_temporary();
}
@@ -2076,7 +2087,7 @@ Error GDScriptCompiler::_parse_setter_getter(GDScript *p_script, const GDScriptP
return_type = _gdtype_from_datatype(p_variable->get_datatype(), p_script);
}
- codegen.generator->write_start(p_script, func_name, false, p_variable->rpc_mode, return_type);
+ codegen.generator->write_start(p_script, func_name, false, MultiplayerAPI::RPCConfig(), return_type);
if (p_is_setter) {
uint32_t par_addr = codegen.generator->add_parameter(p_variable->setter_parameter->name, false, _gdtype_from_datatype(p_variable->get_datatype()));
@@ -2211,7 +2222,7 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
if (err) {
return err;
}
- if (base.is_null() && !base->is_valid()) {
+ if (base.is_null() || !base->is_valid()) {
return ERR_COMPILATION_FAILED;
}
}
@@ -2256,7 +2267,6 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
}
break;
}
- minfo.rpc_mode = variable->rpc_mode;
minfo.data_type = _gdtype_from_datatype(variable->get_datatype(), p_script);
PropertyInfo prop_info = minfo.data_type;
@@ -2270,9 +2280,10 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
}
prop_info.hint = export_info.hint;
prop_info.hint_string = export_info.hint_string;
- prop_info.usage = export_info.usage;
+ prop_info.usage = export_info.usage | PROPERTY_USAGE_SCRIPT_VARIABLE;
+ } else {
+ prop_info.usage = PROPERTY_USAGE_SCRIPT_VARIABLE;
}
- prop_info.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE;
#ifdef TOOLS_ENABLED
p_script->doc_variables[name] = variable->doc_description;
#endif
@@ -2499,7 +2510,7 @@ Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptPa
p_script->placeholders.erase(psi); //remove placeholder
GDScriptInstance *instance = memnew(GDScriptInstance);
- instance->base_ref = Object::cast_to<Reference>(E->get());
+ instance->base_ref_counted = Object::cast_to<RefCounted>(E->get());
instance->members.resize(p_script->member_indices.size());
instance->script = Ref<GDScript>(p_script);
instance->owner = E->get();
@@ -2574,7 +2585,7 @@ void GDScriptCompiler::_make_scripts(GDScript *p_script, const GDScriptParser::C
if (orphan_subclass.is_valid()) {
subclass = orphan_subclass;
} else {
- subclass.instance();
+ subclass.instantiate();
}
}
diff --git a/modules/gdscript/gdscript_disassembler.cpp b/modules/gdscript/gdscript_disassembler.cpp
index eee713aa45..1acb9ceddc 100644
--- a/modules/gdscript/gdscript_disassembler.cpp
+++ b/modules/gdscript/gdscript_disassembler.cpp
@@ -620,12 +620,12 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
DISASSEMBLE_PTRCALL(PLANE);
DISASSEMBLE_PTRCALL(AABB);
DISASSEMBLE_PTRCALL(BASIS);
- DISASSEMBLE_PTRCALL(TRANSFORM);
+ DISASSEMBLE_PTRCALL(TRANSFORM3D);
DISASSEMBLE_PTRCALL(COLOR);
DISASSEMBLE_PTRCALL(STRING_NAME);
DISASSEMBLE_PTRCALL(NODE_PATH);
DISASSEMBLE_PTRCALL(RID);
- DISASSEMBLE_PTRCALL(QUAT);
+ DISASSEMBLE_PTRCALL(QUATERNION);
DISASSEMBLE_PTRCALL(OBJECT);
DISASSEMBLE_PTRCALL(CALLABLE);
DISASSEMBLE_PTRCALL(SIGNAL);
@@ -957,7 +957,7 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
DISASSEMBLE_TYPE_ADJUST(VECTOR3I);
DISASSEMBLE_TYPE_ADJUST(TRANSFORM2D);
DISASSEMBLE_TYPE_ADJUST(PLANE);
- DISASSEMBLE_TYPE_ADJUST(QUAT);
+ DISASSEMBLE_TYPE_ADJUST(QUATERNION);
DISASSEMBLE_TYPE_ADJUST(AABB);
DISASSEMBLE_TYPE_ADJUST(BASIS);
DISASSEMBLE_TYPE_ADJUST(TRANSFORM);
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 504c7414f6..2a93bb620b 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -32,7 +32,7 @@
#include "core/config/engine.h"
#include "core/core_constants.h"
-#include "core/os/file_access.h"
+#include "core/io/file_access.h"
#include "gdscript_analyzer.h"
#include "gdscript_compiler.h"
#include "gdscript_parser.h"
@@ -104,7 +104,7 @@ Ref<Script> GDScriptLanguage::get_template(const String &p_class_name, const Str
_template = _get_processed_template(_template, p_base_class_name);
Ref<GDScript> script;
- script.instance();
+ script.instantiate();
script->set_source_code(_template);
return script;
@@ -131,7 +131,7 @@ static void get_function_names_recursively(const GDScriptParser::ClassNode *p_cl
}
}
-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 {
+bool GDScriptLanguage::validate(const String &p_script, const String &p_path, List<String> *r_functions, List<ScriptLanguage::ScriptError> *r_errors, List<ScriptLanguage::Warning> *r_warnings, Set<int> *r_safe_lines) const {
GDScriptParser parser;
GDScriptAnalyzer analyzer(&parser);
@@ -141,8 +141,8 @@ bool GDScriptLanguage::validate(const String &p_script, int &r_line_error, int &
}
#ifdef DEBUG_ENABLED
if (r_warnings) {
- for (const List<GDScriptWarning>::Element *E = parser.get_warnings().front(); E; E = E->next()) {
- const GDScriptWarning &warn = E->get();
+ for (const GDScriptWarning &E : parser.get_warnings()) {
+ const GDScriptWarning &warn = E;
ScriptLanguage::Warning w;
w.start_line = warn.start_line;
w.end_line = warn.end_line;
@@ -156,10 +156,16 @@ bool GDScriptLanguage::validate(const String &p_script, int &r_line_error, int &
}
#endif
if (err) {
- GDScriptParser::ParserError parse_error = parser.get_errors().front()->get();
- r_line_error = parse_error.line;
- r_col_error = parse_error.column;
- r_test_error = parse_error.message;
+ if (r_errors) {
+ for (const GDScriptParser::ParserError &E : parser.get_errors()) {
+ const GDScriptParser::ParserError &pe = E;
+ ScriptLanguage::ScriptError e;
+ e.line = pe.line;
+ e.column = pe.column;
+ e.message = pe.message;
+ r_errors->push_back(e);
+ }
+ }
return false;
} else {
const GDScriptParser::ClassNode *cl = parser.get_tree();
@@ -313,9 +319,9 @@ void GDScriptLanguage::debug_get_stack_level_locals(int p_level, List<String> *p
List<Pair<StringName, int>> locals;
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]);
+ for (const Pair<StringName, int> &E : locals) {
+ p_locals->push_back(E.first);
+ p_values->push_back(_call_stack[l].stack[E.second]);
}
}
@@ -415,8 +421,8 @@ void GDScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const
List<StringName> functions;
GDScriptUtilityFunctions::get_function_list(&functions);
- for (const List<StringName>::Element *E = functions.front(); E; E = E->next()) {
- p_functions->push_back(GDScriptUtilityFunctions::get_function_info(E->get()));
+ for (const StringName &E : functions) {
+ p_functions->push_back(GDScriptUtilityFunctions::get_function_info(E));
}
// Not really "functions", but show in documentation.
@@ -451,12 +457,12 @@ void GDScriptLanguage::get_public_constants(List<Pair<String, Variant>> *p_const
Pair<String, Variant> infinity;
infinity.first = "INF";
- infinity.second = Math_INF;
+ infinity.second = INFINITY;
p_constants->push_back(infinity);
Pair<String, Variant> nan;
nan.first = "NAN";
- nan.second = Math_NAN;
+ nan.second = NAN;
p_constants->push_back(nan);
}
@@ -542,7 +548,7 @@ static String _make_arguments_hint(const MethodInfo &p_info, int p_arg_idx, bool
int def_args = p_info.arguments.size() - p_info.default_arguments.size();
int i = 0;
- for (const List<PropertyInfo>::Element *E = p_info.arguments.front(); E; E = E->next()) {
+ for (const PropertyInfo &E : p_info.arguments) {
if (i > 0) {
arghint += ", ";
}
@@ -550,7 +556,7 @@ static String _make_arguments_hint(const MethodInfo &p_info, int p_arg_idx, bool
if (i == p_arg_idx) {
arghint += String::chr(0xFFFF);
}
- arghint += E->get().name + ": " + _get_visual_datatype(E->get(), true);
+ arghint += E.name + ": " + _get_visual_datatype(E, true);
if (i - def_args >= 0) {
arghint += String(" = ") + p_info.default_arguments[i - def_args].get_construct_string();
@@ -656,11 +662,11 @@ static void _find_annotation_arguments(const GDScriptParser::AnnotationNode *p_a
r_result.insert(node.display, node);
List<StringName> node_types;
ClassDB::get_inheriters_from_class("Node", &node_types);
- for (const List<StringName>::Element *E = node_types.front(); E != nullptr; E = E->next()) {
- if (!ClassDB::is_class_exposed(E->get())) {
+ for (const StringName &E : node_types) {
+ if (!ClassDB::is_class_exposed(E)) {
continue;
}
- ScriptCodeCompletionOption option(E->get(), ScriptCodeCompletionOption::KIND_CLASS);
+ ScriptCodeCompletionOption option(E, ScriptCodeCompletionOption::KIND_CLASS);
r_result.insert(option.display, option);
}
}
@@ -669,9 +675,9 @@ static void _find_annotation_arguments(const GDScriptParser::AnnotationNode *p_a
static void _list_available_types(bool p_inherit_only, GDScriptParser::CompletionContext &p_context, Map<String, ScriptCodeCompletionOption> &r_result) {
List<StringName> native_types;
ClassDB::get_class_list(&native_types);
- for (const List<StringName>::Element *E = native_types.front(); E != nullptr; E = E->next()) {
- if (ClassDB::is_class_exposed(E->get()) && !Engine::get_singleton()->has_singleton(E->get())) {
- ScriptCodeCompletionOption option(E->get(), ScriptCodeCompletionOption::KIND_CLASS);
+ for (const StringName &E : native_types) {
+ if (ClassDB::is_class_exposed(E) && !Engine::get_singleton()->has_singleton(E)) {
+ ScriptCodeCompletionOption option(E, ScriptCodeCompletionOption::KIND_CLASS);
r_result.insert(option.display, option);
}
}
@@ -681,8 +687,8 @@ static void _list_available_types(bool p_inherit_only, GDScriptParser::Completio
// Native enums from base class
List<StringName> enums;
ClassDB::get_enum_list(p_context.current_class->base_type.native_type, &enums);
- for (const List<StringName>::Element *E = enums.front(); E != nullptr; E = E->next()) {
- ScriptCodeCompletionOption option(E->get(), ScriptCodeCompletionOption::KIND_ENUM);
+ for (const StringName &E : enums) {
+ ScriptCodeCompletionOption option(E, ScriptCodeCompletionOption::KIND_ENUM);
r_result.insert(option.display, option);
}
}
@@ -719,8 +725,8 @@ static void _list_available_types(bool p_inherit_only, GDScriptParser::Completio
// Global scripts
List<StringName> global_classes;
ScriptServer::get_global_class_list(&global_classes);
- for (const List<StringName>::Element *E = global_classes.front(); E != nullptr; E = E->next()) {
- ScriptCodeCompletionOption option(E->get(), ScriptCodeCompletionOption::KIND_CLASS);
+ for (const StringName &E : global_classes) {
+ ScriptCodeCompletionOption option(E, ScriptCodeCompletionOption::KIND_CLASS);
r_result.insert(option.display, option);
}
@@ -859,8 +865,8 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
if (!_static) {
List<PropertyInfo> members;
scr->get_script_property_list(&members);
- for (List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) {
- ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_MEMBER);
+ for (const PropertyInfo &E : members) {
+ ScriptCodeCompletionOption option(E.name, ScriptCodeCompletionOption::KIND_MEMBER);
r_result.insert(option.display, option);
}
}
@@ -873,20 +879,20 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
List<MethodInfo> signals;
scr->get_script_signal_list(&signals);
- for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) {
- ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_SIGNAL);
+ for (const MethodInfo &E : signals) {
+ ScriptCodeCompletionOption option(E.name, ScriptCodeCompletionOption::KIND_SIGNAL);
r_result.insert(option.display, option);
}
}
List<MethodInfo> methods;
scr->get_script_method_list(&methods);
- for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
- if (E->get().name.begins_with("@")) {
+ for (const MethodInfo &E : methods) {
+ if (E.name.begins_with("@")) {
continue;
}
- ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_FUNCTION);
- if (E->get().arguments.size()) {
+ ScriptCodeCompletionOption option(E.name, ScriptCodeCompletionOption::KIND_FUNCTION);
+ if (E.arguments.size()) {
option.insert_text += "(";
} else {
option.insert_text += "()";
@@ -914,22 +920,22 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
if (!p_only_functions) {
List<String> constants;
ClassDB::get_integer_constant_list(type, &constants);
- for (List<String>::Element *E = constants.front(); E; E = E->next()) {
- ScriptCodeCompletionOption option(E->get(), ScriptCodeCompletionOption::KIND_CONSTANT);
+ for (const String &E : constants) {
+ ScriptCodeCompletionOption option(E, ScriptCodeCompletionOption::KIND_CONSTANT);
r_result.insert(option.display, option);
}
if (!_static || Engine::get_singleton()->has_singleton(type)) {
List<PropertyInfo> pinfo;
ClassDB::get_property_list(type, &pinfo);
- for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
- if (E->get().usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY)) {
+ for (const PropertyInfo &E : pinfo) {
+ if (E.usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY)) {
continue;
}
- if (E->get().name.find("/") != -1) {
+ if (E.name.find("/") != -1) {
continue;
}
- ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_MEMBER);
+ ScriptCodeCompletionOption option(E.name, ScriptCodeCompletionOption::KIND_MEMBER);
r_result.insert(option.display, option);
}
}
@@ -939,12 +945,12 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
List<MethodInfo> methods;
bool is_autocompleting_getters = GLOBAL_GET("debug/gdscript/completion/autocomplete_setters_and_getters").booleanize();
ClassDB::get_method_list(type, &methods, false, !is_autocompleting_getters);
- for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
- if (E->get().name.begins_with("_")) {
+ for (const MethodInfo &E : methods) {
+ if (E.name.begins_with("_")) {
continue;
}
- ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_FUNCTION);
- if (E->get().arguments.size()) {
+ ScriptCodeCompletionOption option(E.name, ScriptCodeCompletionOption::KIND_FUNCTION);
+ if (E.arguments.size()) {
option.insert_text += "(";
} else {
option.insert_text += "()";
@@ -971,9 +977,9 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
tmp.get_property_list(&members);
}
- for (List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) {
- if (String(E->get().name).find("/") == -1) {
- ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_MEMBER);
+ for (const PropertyInfo &E : members) {
+ if (String(E.name).find("/") == -1) {
+ ScriptCodeCompletionOption option(E.name, ScriptCodeCompletionOption::KIND_MEMBER);
r_result.insert(option.display, option);
}
}
@@ -981,9 +987,9 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
List<MethodInfo> methods;
tmp.get_method_list(&methods);
- for (const List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
- ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_FUNCTION);
- if (E->get().arguments.size()) {
+ for (const MethodInfo &E : methods) {
+ ScriptCodeCompletionOption option(E.name, ScriptCodeCompletionOption::KIND_FUNCTION);
+ if (E.arguments.size()) {
option.insert_text += "(";
} else {
option.insert_text += "()";
@@ -1013,9 +1019,9 @@ static void _find_identifiers(GDScriptParser::CompletionContext &p_context, bool
List<StringName> functions;
GDScriptUtilityFunctions::get_function_list(&functions);
- for (const List<StringName>::Element *E = functions.front(); E; E = E->next()) {
- MethodInfo function = GDScriptUtilityFunctions::get_function_info(E->get());
- ScriptCodeCompletionOption option(String(E->get()), ScriptCodeCompletionOption::KIND_FUNCTION);
+ for (const StringName &E : functions) {
+ MethodInfo function = GDScriptUtilityFunctions::get_function_info(E);
+ ScriptCodeCompletionOption option(String(E), ScriptCodeCompletionOption::KIND_FUNCTION);
if (function.arguments.size() || (function.flags & METHOD_FLAG_VARARG)) {
option.insert_text += "(";
} else {
@@ -1029,7 +1035,7 @@ static void _find_identifiers(GDScriptParser::CompletionContext &p_context, bool
}
static const char *_type_names[Variant::VARIANT_MAX] = {
- "null", "bool", "int", "float", "String", "StringName", "Vector2", "Vector2i", "Rect2", "Rect2i", "Vector3", "Vector3i", "Transform2D", "Plane", "Quat", "AABB", "Basis", "Transform",
+ "null", "bool", "int", "float", "String", "StringName", "Vector2", "Vector2i", "Rect2", "Rect2i", "Vector3", "Vector3i", "Transform2D", "Plane", "Quaternion", "AABB", "Basis", "Transform3D",
"Color", "NodePath", "RID", "Signal", "Callable", "Object", "Dictionary", "Array", "PackedByteArray", "PackedInt32Array", "PackedInt64Array", "PackedFloat32Array", "PackedFloat64Array", "PackedStringArray",
"PackedVector2Array", "PackedVector3Array", "PackedColorArray"
};
@@ -1762,9 +1768,9 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
StringName real_native = GDScriptParser::get_real_class_name(base_type.native_type);
MethodInfo info;
if (ClassDB::get_method_info(real_native, p_context.current_function->identifier->name, &info)) {
- for (const List<PropertyInfo>::Element *E = info.arguments.front(); E; E = E->next()) {
- if (E->get().name == p_identifier) {
- r_type = _type_from_property(E->get());
+ for (const PropertyInfo &E : info.arguments) {
+ if (E.name == p_identifier) {
+ r_type = _type_from_property(E);
return true;
}
}
@@ -1926,8 +1932,7 @@ static bool _guess_identifier_type_from_base(GDScriptParser::CompletionContext &
if (!is_static) {
List<PropertyInfo> members;
scr->get_script_property_list(&members);
- for (const List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) {
- const PropertyInfo &prop = E->get();
+ for (const PropertyInfo &prop : members) {
if (prop.name == p_identifier) {
r_type = _type_from_property(prop);
return true;
@@ -2090,8 +2095,7 @@ static bool _guess_method_return_type_from_base(GDScriptParser::CompletionContex
if (scr.is_valid()) {
List<MethodInfo> methods;
scr->get_script_method_list(&methods);
- for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
- MethodInfo &mi = E->get();
+ for (const MethodInfo &mi : methods) {
if (mi.name == p_method) {
r_type = _type_from_property(mi.return_val);
return true;
@@ -2131,8 +2135,7 @@ static bool _guess_method_return_type_from_base(GDScriptParser::CompletionContex
List<MethodInfo> methods;
tmp.get_method_list(&methods);
- for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
- MethodInfo &mi = E->get();
+ for (const MethodInfo &mi : methods) {
if (mi.name == p_method) {
r_type = _type_from_property(mi.return_val);
return true;
@@ -2177,8 +2180,8 @@ static void _find_enumeration_candidates(GDScriptParser::CompletionContext &p_co
List<StringName> enum_constants;
ClassDB::get_enum_constants(class_name, enum_name, &enum_constants);
- for (List<StringName>::Element *E = enum_constants.front(); E; E = E->next()) {
- String candidate = class_name + "." + E->get();
+ for (const StringName &E : enum_constants) {
+ String candidate = class_name + "." + E;
ScriptCodeCompletionOption option(candidate, ScriptCodeCompletionOption::KIND_ENUM);
r_result.insert(option.display, option);
}
@@ -2222,8 +2225,8 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
if (obj) {
List<String> options;
obj->get_argument_options(p_method, p_argidx, &options);
- for (List<String>::Element *F = options.front(); F; F = F->next()) {
- ScriptCodeCompletionOption option(F->get(), ScriptCodeCompletionOption::KIND_FUNCTION);
+ for (const String &F : options) {
+ ScriptCodeCompletionOption option(F, ScriptCodeCompletionOption::KIND_FUNCTION);
r_result.insert(option.display, option);
}
}
@@ -2244,8 +2247,8 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
List<PropertyInfo> props;
ProjectSettings::get_singleton()->get_property_list(&props);
- for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
- String s = E->get().name;
+ for (const PropertyInfo &E : props) {
+ String s = E.name;
if (!s.begins_with("autoload/")) {
continue;
}
@@ -2260,8 +2263,8 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
// Get input actions
List<PropertyInfo> props;
ProjectSettings::get_singleton()->get_property_list(&props);
- for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
- String s = E->get().name;
+ for (const PropertyInfo &E : props) {
+ String s = E.name;
if (!s.begins_with("input/")) {
continue;
}
@@ -2285,9 +2288,9 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
List<MethodInfo> methods;
base.get_method_list(&methods);
- for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
- if (E->get().name == p_method) {
- r_arghint = _make_arguments_hint(E->get(), p_argidx);
+ for (const MethodInfo &E : methods) {
+ if (E.name == p_method) {
+ r_arghint = _make_arguments_hint(E, p_argidx);
return;
}
}
@@ -2334,14 +2337,14 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
Variant::get_constructor_list(GDScriptParser::get_builtin_type(call->function_name), &constructors);
int i = 0;
- for (List<MethodInfo>::Element *E = constructors.front(); E; E = E->next()) {
- if (p_argidx >= E->get().arguments.size()) {
+ for (const MethodInfo &E : constructors) {
+ if (p_argidx >= E.arguments.size()) {
continue;
}
if (i > 0) {
r_arghint += "\n";
}
- r_arghint += _make_arguments_hint(E->get(), p_argidx);
+ r_arghint += _make_arguments_hint(E, p_argidx);
i++;
}
return;
@@ -2378,7 +2381,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
r_forced = r_result.size() > 0;
}
-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) {
+::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;
@@ -2400,9 +2403,9 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path
case GDScriptParser::COMPLETION_ANNOTATION: {
List<MethodInfo> annotations;
parser.get_annotation_list(&annotations);
- for (const List<MethodInfo>::Element *E = annotations.front(); E != nullptr; E = E->next()) {
- ScriptCodeCompletionOption option(E->get().name.substr(1), ScriptCodeCompletionOption::KIND_PLAIN_TEXT);
- if (E->get().arguments.size() > 0) {
+ for (const MethodInfo &E : annotations) {
+ ScriptCodeCompletionOption option(E.name.substr(1), ScriptCodeCompletionOption::KIND_PLAIN_TEXT);
+ if (E.arguments.size() > 0) {
option.insert_text += "(";
}
options.insert(option.display, option);
@@ -2420,10 +2423,10 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path
case GDScriptParser::COMPLETION_BUILT_IN_TYPE_CONSTANT: {
List<StringName> constants;
Variant::get_constants_for_type(completion_context.builtin_type, &constants);
- for (const List<StringName>::Element *E = constants.front(); E != nullptr; E = E->next()) {
- ScriptCodeCompletionOption option(E->get(), ScriptCodeCompletionOption::KIND_CONSTANT);
+ for (const StringName &E : constants) {
+ ScriptCodeCompletionOption option(E, ScriptCodeCompletionOption::KIND_CONSTANT);
bool valid = false;
- Variant default_value = Variant::get_constant_value(completion_context.builtin_type, E->get(), &valid);
+ Variant default_value = Variant::get_constant_value(completion_context.builtin_type, E, &valid);
if (valid) {
option.default_value = default_value;
}
@@ -2600,8 +2603,7 @@ 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();
+ for (const MethodInfo &mi : virtual_methods) {
String method_hint = mi.name;
if (method_hint.find(":") != -1) {
method_hint = method_hint.get_slice(":", 0);
@@ -2650,8 +2652,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path
List<String> opts;
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();
+ for (const String &E : opts) {
+ String opt = E.strip_edges();
if (opt.is_quoted()) {
r_forced = true;
String idopt = opt.unquote();
@@ -2835,8 +2837,8 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co
List<MethodInfo> virtual_methods;
ClassDB::get_virtual_methods(class_name, &virtual_methods, true);
- for (List<MethodInfo>::Element *E = virtual_methods.front(); E; E = E->next()) {
- if (E->get().name == p_symbol) {
+ for (const MethodInfo &E : virtual_methods) {
+ if (E.name == p_symbol) {
r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_METHOD;
r_result.class_name = base_type.native_type;
r_result.class_member = p_symbol;
@@ -2854,8 +2856,8 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co
List<String> constants;
ClassDB::get_integer_constant_list(class_name, &constants, true);
- for (List<String>::Element *E = constants.front(); E; E = E->next()) {
- if (E->get() == p_symbol) {
+ for (const String &E : constants) {
+ if (E == p_symbol) {
r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_CONSTANT;
r_result.class_name = base_type.native_type;
r_result.class_member = p_symbol;
@@ -2894,7 +2896,7 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co
Variant v;
REF v_ref;
if (base_type.builtin_type == Variant::OBJECT) {
- v_ref.instance();
+ v_ref.instantiate();
v = v_ref;
} else {
Callable::CallError err;
@@ -2929,7 +2931,7 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co
return ERR_CANT_RESOLVE;
}
-Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result) {
+::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;
@@ -3032,9 +3034,9 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol
if (!is_function) {
// Guess in autoloads as singletons.
if (ProjectSettings::get_singleton()->has_autoload(p_symbol)) {
- const ProjectSettings::AutoloadInfo &singleton = ProjectSettings::get_singleton()->get_autoload(p_symbol);
- if (singleton.is_singleton) {
- String script = singleton.path;
+ const ProjectSettings::AutoloadInfo &autoload = ProjectSettings::get_singleton()->get_autoload(p_symbol);
+ if (autoload.is_singleton) {
+ String script = autoload.path;
if (!script.ends_with(".gd")) {
// Not a script, try find the script anyway,
// may have some success.
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index 78399114a5..876c508689 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -94,8 +94,7 @@ struct _GDFKCS {
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();
+ for (const StackDebug &sd : stack_debug) {
if (sd.line > p_line) {
break;
}
@@ -131,10 +130,10 @@ 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()) {
+ for (_GDFKCS &E : stackpositions) {
Pair<StringName, int> p;
- p.first = E->get().id;
- p.second = E->get().pos;
+ p.first = E.id;
+ p.second = E.pos;
r_stackvars->push_back(p);
}
}
@@ -262,9 +261,9 @@ Variant GDScriptFunctionState::resume(const Variant &p_arg) {
if (completed) {
if (first_state.is_valid()) {
- first_state->emit_signal("completed", ret);
+ first_state->emit_signal(SNAME("completed"), ret);
} else {
- emit_signal("completed", ret);
+ emit_signal(SNAME("completed"), ret);
}
#ifdef DEBUG_ENABLED
diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h
index 26b8809337..9e5ef0f632 100644
--- a/modules/gdscript/gdscript_function.h
+++ b/modules/gdscript/gdscript_function.h
@@ -31,7 +31,7 @@
#ifndef GDSCRIPT_FUNCTION_H
#define GDSCRIPT_FUNCTION_H
-#include "core/object/reference.h"
+#include "core/object/ref_counted.h"
#include "core/object/script_language.h"
#include "core/os/thread.h"
#include "core/string/string_name.h"
@@ -278,10 +278,10 @@ public:
OPCODE_CALL_PTRCALL_VECTOR3I,
OPCODE_CALL_PTRCALL_TRANSFORM2D,
OPCODE_CALL_PTRCALL_PLANE,
- OPCODE_CALL_PTRCALL_QUAT,
+ OPCODE_CALL_PTRCALL_QUATERNION,
OPCODE_CALL_PTRCALL_AABB,
OPCODE_CALL_PTRCALL_BASIS,
- OPCODE_CALL_PTRCALL_TRANSFORM,
+ OPCODE_CALL_PTRCALL_TRANSFORM3D,
OPCODE_CALL_PTRCALL_COLOR,
OPCODE_CALL_PTRCALL_STRING_NAME,
OPCODE_CALL_PTRCALL_NODE_PATH,
@@ -365,7 +365,7 @@ public:
OPCODE_TYPE_ADJUST_VECTOR3I,
OPCODE_TYPE_ADJUST_TRANSFORM2D,
OPCODE_TYPE_ADJUST_PLANE,
- OPCODE_TYPE_ADJUST_QUAT,
+ OPCODE_TYPE_ADJUST_QUATERNION,
OPCODE_TYPE_ADJUST_AABB,
OPCODE_TYPE_ADJUST_BASIS,
OPCODE_TYPE_ADJUST_TRANSFORM,
@@ -472,7 +472,7 @@ private:
int _initial_line = 0;
bool _static = false;
- MultiplayerAPI::RPCMode rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
+ MultiplayerAPI::RPCConfig rpc_config;
GDScript *_script = nullptr;
@@ -592,13 +592,13 @@ public:
void disassemble(const Vector<String> &p_code_lines) const;
#endif
- _FORCE_INLINE_ MultiplayerAPI::RPCMode get_rpc_mode() const { return rpc_mode; }
+ _FORCE_INLINE_ MultiplayerAPI::RPCConfig get_rpc_config() const { return rpc_config; }
GDScriptFunction();
~GDScriptFunction();
};
-class GDScriptFunctionState : public Reference {
- GDCLASS(GDScriptFunctionState, Reference);
+class GDScriptFunctionState : public RefCounted {
+ GDCLASS(GDScriptFunctionState, RefCounted);
friend class GDScriptFunction;
GDScriptFunction *function = nullptr;
GDScriptFunction::CallState state;
diff --git a/modules/gdscript/gdscript_lambda_callable.h b/modules/gdscript/gdscript_lambda_callable.h
index 357c845250..336778d549 100644
--- a/modules/gdscript/gdscript_lambda_callable.h
+++ b/modules/gdscript/gdscript_lambda_callable.h
@@ -31,7 +31,7 @@
#ifndef GDSCRIPT_LAMBDA_CALLABLE
#define GDSCRIPT_LAMBDA_CALLABLE
-#include "core/object/reference.h"
+#include "core/object/ref_counted.h"
#include "core/templates/vector.h"
#include "core/variant/callable.h"
#include "core/variant/variant.h"
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index b61b469fbc..466ddb4b10 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -31,9 +31,9 @@
#include "gdscript_parser.h"
#include "core/config/project_settings.h"
+#include "core/io/file_access.h"
#include "core/io/resource_loader.h"
#include "core/math/math_defs.h"
-#include "core/os/file_access.h"
#include "gdscript.h"
#ifdef DEBUG_ENABLED
@@ -61,9 +61,9 @@ Variant::Type GDScriptParser::get_builtin_type(const StringName &p_type) {
builtin_types["Vector3i"] = Variant::VECTOR3I;
builtin_types["AABB"] = Variant::AABB;
builtin_types["Plane"] = Variant::PLANE;
- builtin_types["Quat"] = Variant::QUAT;
+ builtin_types["Quaternion"] = Variant::QUATERNION;
builtin_types["Basis"] = Variant::BASIS;
- builtin_types["Transform"] = Variant::TRANSFORM;
+ builtin_types["Transform3D"] = Variant::TRANSFORM3D;
builtin_types["Color"] = Variant::COLOR;
builtin_types["RID"] = Variant::RID;
builtin_types["Object"] = Variant::OBJECT;
@@ -136,8 +136,8 @@ void GDScriptParser::cleanup() {
void GDScriptParser::get_annotation_list(List<MethodInfo> *r_annotations) const {
List<StringName> keys;
valid_annotations.get_key_list(&keys);
- for (const List<StringName>::Element *E = keys.front(); E != nullptr; E = E->next()) {
- r_annotations->push_back(valid_annotations[E->get()].info);
+ for (const StringName &E : keys) {
+ r_annotations->push_back(valid_annotations[E].info);
}
}
@@ -157,7 +157,6 @@ GDScriptParser::GDScriptParser() {
register_annotation(MethodInfo("@export_multiline"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_MULTILINE_TEXT, Variant::STRING>);
register_annotation(MethodInfo("@export_placeholder"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_PLACEHOLDER_TEXT, Variant::STRING>);
register_annotation(MethodInfo("@export_range", { Variant::FLOAT, "min" }, { Variant::FLOAT, "max" }, { Variant::FLOAT, "step" }, { Variant::STRING, "slider1" }, { Variant::STRING, "slider2" }), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_RANGE, Variant::FLOAT>, 3);
- register_annotation(MethodInfo("@export_exp_range", { Variant::FLOAT, "min" }, { Variant::FLOAT, "max" }, { Variant::FLOAT, "step" }, { Variant::STRING, "slider1" }, { Variant::STRING, "slider2" }), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_EXP_RANGE, Variant::FLOAT>, 3);
register_annotation(MethodInfo("@export_exp_easing", { Variant::STRING, "hint1" }, { Variant::STRING, "hint2" }), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_EXP_EASING, Variant::FLOAT>, 2);
register_annotation(MethodInfo("@export_color_no_alpha"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_COLOR_NO_ALPHA, Variant::COLOR>);
register_annotation(MethodInfo("@export_node_path", { Variant::STRING, "type" }), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_NODE_PATH_VALID_TYPES, Variant::NODE_PATH>, 1, true);
@@ -169,12 +168,7 @@ GDScriptParser::GDScriptParser() {
register_annotation(MethodInfo("@export_flags_3d_physics"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_PHYSICS, Variant::INT>);
register_annotation(MethodInfo("@export_flags_3d_navigation"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_NAVIGATION, Variant::INT>);
// Networking.
- register_annotation(MethodInfo("@remote"), AnnotationInfo::VARIABLE | AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_REMOTE>);
- register_annotation(MethodInfo("@master"), AnnotationInfo::VARIABLE | AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_MASTER>);
- register_annotation(MethodInfo("@puppet"), AnnotationInfo::VARIABLE | AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_PUPPET>);
- register_annotation(MethodInfo("@remotesync"), AnnotationInfo::VARIABLE | AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_REMOTESYNC>);
- register_annotation(MethodInfo("@mastersync"), AnnotationInfo::VARIABLE | AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_MASTERSYNC>);
- register_annotation(MethodInfo("@puppetsync"), AnnotationInfo::VARIABLE | AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_PUPPETSYNC>);
+ register_annotation(MethodInfo("@rpc", { Variant::STRING, "mode" }, { Variant::STRING, "sync" }, { Variant::STRING, "transfer_mode" }, { Variant::INT, "transfer_channel" }), AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_MASTER>, 4, true);
// TODO: Warning annotations.
}
@@ -254,7 +248,7 @@ void GDScriptParser::push_warning(const Node *p_source, GDScriptWarning::Code p_
warning.rightmost_column = p_source->rightmost_column;
List<GDScriptWarning>::Element *before = nullptr;
- for (List<GDScriptWarning>::Element *E = warnings.front(); E != nullptr; E = E->next()) {
+ for (List<GDScriptWarning>::Element *E = warnings.front(); E; E = E->next()) {
if (E->get().start_line > warning.start_line) {
break;
}
@@ -1338,8 +1332,7 @@ GDScriptParser::AnnotationNode *GDScriptParser::parse_annotation(uint32_t p_vali
}
void GDScriptParser::clear_unused_annotations() {
- for (const List<AnnotationNode *>::Element *E = annotation_stack.front(); E != nullptr; E = E->next()) {
- AnnotationNode *annotation = E->get();
+ for (const AnnotationNode *annotation : annotation_stack) {
push_error(vformat(R"(Annotation "%s" does not precedes a valid target, so it will have no effect.)", annotation->name), annotation);
}
@@ -1802,8 +1795,8 @@ GDScriptParser::MatchBranchNode *GDScriptParser::parse_match_branch() {
List<StringName> binds;
branch->patterns[0]->binds.get_key_list(&binds);
- for (List<StringName>::Element *E = binds.front(); E != nullptr; E = E->next()) {
- SuiteNode::Local local(branch->patterns[0]->binds[E->get()], current_function);
+ for (const StringName &E : binds) {
+ SuiteNode::Local local(branch->patterns[0]->binds[E], current_function);
suite->add_local(local);
}
}
@@ -2129,10 +2122,10 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_builtin_constant(Expressio
constant->value = Math_TAU;
break;
case GDScriptTokenizer::Token::CONST_INF:
- constant->value = Math_INF;
+ constant->value = INFINITY;
break;
case GDScriptTokenizer::Token::CONST_NAN:
- constant->value = Math_NAN;
+ constant->value = NAN;
break;
default:
return nullptr; // Unreachable.
@@ -3431,27 +3424,60 @@ template <MultiplayerAPI::RPCMode t_mode>
bool GDScriptParser::network_annotations(const AnnotationNode *p_annotation, Node *p_node) {
ERR_FAIL_COND_V_MSG(p_node->type != Node::VARIABLE && p_node->type != Node::FUNCTION, false, vformat(R"("%s" annotation can only be applied to variables and functions.)", p_annotation->name));
- switch (p_node->type) {
- case Node::VARIABLE: {
- VariableNode *variable = static_cast<VariableNode *>(p_node);
- if (variable->rpc_mode != MultiplayerAPI::RPC_MODE_DISABLED) {
- push_error(R"(RPC annotations can only be used once per variable.)", p_annotation);
+ MultiplayerAPI::RPCConfig rpc_config;
+ rpc_config.rpc_mode = t_mode;
+ for (int i = 0; i < p_annotation->resolved_arguments.size(); i++) {
+ if (i == 0) {
+ String mode = p_annotation->resolved_arguments[i].operator String();
+ if (mode == "any") {
+ rpc_config.rpc_mode = MultiplayerAPI::RPC_MODE_REMOTE;
+ } else if (mode == "master") {
+ rpc_config.rpc_mode = MultiplayerAPI::RPC_MODE_MASTER;
+ } else if (mode == "puppet") {
+ rpc_config.rpc_mode = MultiplayerAPI::RPC_MODE_PUPPET;
+ } else {
+ push_error(R"(Invalid RPC mode. Must be one of: 'any', 'master', or 'puppet')", p_annotation);
+ return false;
}
- variable->rpc_mode = t_mode;
- break;
+ } else if (i == 1) {
+ String sync = p_annotation->resolved_arguments[i].operator String();
+ if (sync == "sync") {
+ rpc_config.sync = true;
+ } else if (sync == "nosync") {
+ rpc_config.sync = false;
+ } else {
+ push_error(R"(Invalid RPC sync mode. Must be one of: 'sync' or 'nosync')", p_annotation);
+ return false;
+ }
+ } else if (i == 2) {
+ String mode = p_annotation->resolved_arguments[i].operator String();
+ if (mode == "reliable") {
+ rpc_config.transfer_mode = MultiplayerPeer::TRANSFER_MODE_RELIABLE;
+ } else if (mode == "unreliable") {
+ rpc_config.transfer_mode = MultiplayerPeer::TRANSFER_MODE_UNRELIABLE;
+ } else if (mode == "ordered") {
+ rpc_config.transfer_mode = MultiplayerPeer::TRANSFER_MODE_UNRELIABLE_ORDERED;
+ } else {
+ push_error(R"(Invalid RPC transfer mode. Must be one of: 'reliable', 'unreliable', 'ordered')", p_annotation);
+ return false;
+ }
+ } else if (i == 3) {
+ rpc_config.channel = p_annotation->resolved_arguments[i].operator int();
}
+ }
+ switch (p_node->type) {
case Node::FUNCTION: {
FunctionNode *function = static_cast<FunctionNode *>(p_node);
- if (function->rpc_mode != MultiplayerAPI::RPC_MODE_DISABLED) {
+ if (function->rpc_config.rpc_mode != MultiplayerAPI::RPC_MODE_DISABLED) {
push_error(R"(RPC annotations can only be used once per function.)", p_annotation);
+ return false;
}
- function->rpc_mode = t_mode;
+ function->rpc_config = rpc_config;
break;
}
default:
return false; // Unreachable.
}
-
return true;
}
@@ -3591,7 +3617,7 @@ void GDScriptParser::TreePrinter::push_text(const String &p_text) {
printed += p_text;
}
-void GDScriptParser::TreePrinter::print_annotation(AnnotationNode *p_annotation) {
+void GDScriptParser::TreePrinter::print_annotation(const AnnotationNode *p_annotation) {
push_text(p_annotation->name);
push_text(" (");
for (int i = 0; i < p_annotation->arguments.size(); i++) {
@@ -3966,8 +3992,8 @@ void GDScriptParser::TreePrinter::print_for(ForNode *p_for) {
}
void GDScriptParser::TreePrinter::print_function(FunctionNode *p_function, const String &p_context) {
- for (const List<AnnotationNode *>::Element *E = p_function->annotations.front(); E != nullptr; E = E->next()) {
- print_annotation(E->get());
+ for (const AnnotationNode *E : p_function->annotations) {
+ print_annotation(E);
}
push_text(p_context);
push_text(" ");
@@ -4306,8 +4332,8 @@ void GDScriptParser::TreePrinter::print_unary_op(UnaryOpNode *p_unary_op) {
}
void GDScriptParser::TreePrinter::print_variable(VariableNode *p_variable) {
- for (const List<AnnotationNode *>::Element *E = p_variable->annotations.front(); E != nullptr; E = E->next()) {
- print_annotation(E->get());
+ for (const AnnotationNode *E : p_variable->annotations) {
+ print_annotation(E);
}
push_text("Variable ");
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index b1b29a7bd1..6a227a55e5 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -33,7 +33,7 @@
#include "core/io/multiplayer_api.h"
#include "core/io/resource.h"
-#include "core/object/reference.h"
+#include "core/object/ref_counted.h"
#include "core/object/script_language.h"
#include "core/string/string_name.h"
#include "core/string/ustring.h"
@@ -370,6 +370,7 @@ public:
Variant::Operator variant_op = Variant::OP_MAX;
ExpressionNode *assignee = nullptr;
ExpressionNode *assigned_value = nullptr;
+ bool use_conversion_assign = false;
AssignmentNode() {
type = ASSIGNMENT;
@@ -728,7 +729,7 @@ public:
SuiteNode *body = nullptr;
bool is_static = false;
bool is_coroutine = false;
- MultiplayerAPI::RPCMode rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
+ MultiplayerAPI::RPCConfig rpc_config;
MethodInfo info;
LambdaNode *source_lambda = nullptr;
#ifdef TOOLS_ENABLED
@@ -1116,9 +1117,9 @@ public:
bool exported = false;
bool onready = false;
PropertyInfo export_info;
- MultiplayerAPI::RPCMode rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
int assignments = 0;
int usages = 0;
+ bool use_conversion_assign = false;
#ifdef TOOLS_ENABLED
String doc_description;
#endif // TOOLS_ENABLED
@@ -1430,7 +1431,7 @@ public:
void push_line(const String &p_line = String());
void push_text(const String &p_text);
- void print_annotation(AnnotationNode *p_annotation);
+ void print_annotation(const AnnotationNode *p_annotation);
void print_array(ArrayNode *p_array);
void print_assert(AssertNode *p_assert);
void print_assignment(AssignmentNode *p_assignment);
diff --git a/modules/gdscript/gdscript_utility_functions.cpp b/modules/gdscript/gdscript_utility_functions.cpp
index 64c629662c..62531473c3 100644
--- a/modules/gdscript/gdscript_utility_functions.cpp
+++ b/modules/gdscript/gdscript_utility_functions.cpp
@@ -706,8 +706,8 @@ bool GDScriptUtilityFunctions::function_exists(const StringName &p_function) {
}
void GDScriptUtilityFunctions::get_function_list(List<StringName> *r_functions) {
- for (const List<StringName>::Element *E = utility_function_name_table.front(); E; E = E->next()) {
- r_functions->push_back(E->get());
+ for (const StringName &E : utility_function_name_table) {
+ r_functions->push_back(E);
}
}
diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp
index 56b0f6db83..8a261a88e3 100644
--- a/modules/gdscript/gdscript_vm.cpp
+++ b/modules/gdscript/gdscript_vm.cpp
@@ -166,10 +166,10 @@ void (*type_init_function_table[])(Variant *) = {
&VariantInitializer<Vector3i>::init, // VECTOR3I.
&VariantInitializer<Transform2D>::init, // TRANSFORM2D.
&VariantInitializer<Plane>::init, // PLANE.
- &VariantInitializer<Quat>::init, // QUAT.
+ &VariantInitializer<Quaternion>::init, // QUATERNION.
&VariantInitializer<AABB>::init, // AABB.
&VariantInitializer<Basis>::init, // BASIS.
- &VariantInitializer<Transform>::init, // TRANSFORM.
+ &VariantInitializer<Transform3D>::init, // TRANSFORM3D.
&VariantInitializer<Color>::init, // COLOR.
&VariantInitializer<StringName>::init, // STRING_NAME.
&VariantInitializer<NodePath>::init, // NODE_PATH.
@@ -248,10 +248,10 @@ void (*type_init_function_table[])(Variant *) = {
&&OPCODE_CALL_PTRCALL_VECTOR3I, \
&&OPCODE_CALL_PTRCALL_TRANSFORM2D, \
&&OPCODE_CALL_PTRCALL_PLANE, \
- &&OPCODE_CALL_PTRCALL_QUAT, \
+ &&OPCODE_CALL_PTRCALL_QUATERNION, \
&&OPCODE_CALL_PTRCALL_AABB, \
&&OPCODE_CALL_PTRCALL_BASIS, \
- &&OPCODE_CALL_PTRCALL_TRANSFORM, \
+ &&OPCODE_CALL_PTRCALL_TRANSFORM3D, \
&&OPCODE_CALL_PTRCALL_COLOR, \
&&OPCODE_CALL_PTRCALL_STRING_NAME, \
&&OPCODE_CALL_PTRCALL_NODE_PATH, \
@@ -335,7 +335,7 @@ void (*type_init_function_table[])(Variant *) = {
&&OPCODE_TYPE_ADJUST_VECTOR3I, \
&&OPCODE_TYPE_ADJUST_TRANSFORM2D, \
&&OPCODE_TYPE_ADJUST_PLANE, \
- &&OPCODE_TYPE_ADJUST_QUAT, \
+ &&OPCODE_TYPE_ADJUST_QUATERNION, \
&&OPCODE_TYPE_ADJUST_AABB, \
&&OPCODE_TYPE_ADJUST_BASIS, \
&&OPCODE_TYPE_ADJUST_TRANSFORM, \
@@ -398,7 +398,7 @@ void (*type_init_function_table[])(Variant *) = {
#define OP_GET_VECTOR3I get_vector3i
#define OP_GET_RECT2 get_rect2
#define OP_GET_RECT2I get_rect2i
-#define OP_GET_QUAT get_quat
+#define OP_GET_QUATERNION get_quaternion
#define OP_GET_COLOR get_color
#define OP_GET_STRING get_string
#define OP_GET_STRING_NAME get_string_name
@@ -416,7 +416,7 @@ void (*type_init_function_table[])(Variant *) = {
#define OP_GET_PACKED_VECTOR2_ARRAY get_vector2_array
#define OP_GET_PACKED_VECTOR3_ARRAY get_vector3_array
#define OP_GET_PACKED_COLOR_ARRAY get_color_array
-#define OP_GET_TRANSFORM get_transform
+#define OP_GET_TRANSFORM3D get_transform
#define OP_GET_TRANSFORM2D get_transform2d
#define OP_GET_PLANE get_plane
#define OP_GET_AABB get_aabb
@@ -1733,10 +1733,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
OPCODE_CALL_PTR(VECTOR3I);
OPCODE_CALL_PTR(TRANSFORM2D);
OPCODE_CALL_PTR(PLANE);
- OPCODE_CALL_PTR(QUAT);
+ OPCODE_CALL_PTR(QUATERNION);
OPCODE_CALL_PTR(AABB);
OPCODE_CALL_PTR(BASIS);
- OPCODE_CALL_PTR(TRANSFORM);
+ OPCODE_CALL_PTR(TRANSFORM3D);
OPCODE_CALL_PTR(COLOR);
OPCODE_CALL_PTR(STRING_NAME);
OPCODE_CALL_PTR(NODE_PATH);
@@ -1989,7 +1989,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
ip += instr_arg_count;
- int self_fun = _code_ptr[ip + 1];
+ int argc = _code_ptr[ip + 1];
+ GD_ERR_BREAK(argc < 0);
+
+ int self_fun = _code_ptr[ip + 2];
#ifdef DEBUG_ENABLED
if (self_fun < 0 || self_fun >= _global_names_count) {
err_text = "compiler bug, function name not found";
@@ -1998,9 +2001,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#endif
const StringName *methodname = &_global_names_ptr[self_fun];
- int argc = _code_ptr[ip + 2];
- GD_ERR_BREAK(argc < 0);
-
Variant **argptrs = instruction_args;
GET_INSTRUCTION_ARG(dst, argc);
@@ -3150,10 +3150,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
OPCODE_TYPE_ADJUST(VECTOR3I, Vector3i);
OPCODE_TYPE_ADJUST(TRANSFORM2D, Transform2D);
OPCODE_TYPE_ADJUST(PLANE, Plane);
- OPCODE_TYPE_ADJUST(QUAT, Quat);
+ OPCODE_TYPE_ADJUST(QUATERNION, Quaternion);
OPCODE_TYPE_ADJUST(AABB, AABB);
OPCODE_TYPE_ADJUST(BASIS, Basis);
- OPCODE_TYPE_ADJUST(TRANSFORM, Transform);
+ OPCODE_TYPE_ADJUST(TRANSFORM, Transform3D);
OPCODE_TYPE_ADJUST(COLOR, Color);
OPCODE_TYPE_ADJUST(STRING_NAME, StringName);
OPCODE_TYPE_ADJUST(NODE_PATH, NodePath);
diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp
index 15236d900d..d106b3b541 100644
--- a/modules/gdscript/language_server/gdscript_extend_parser.cpp
+++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp
@@ -32,7 +32,6 @@
#include "../gdscript.h"
#include "../gdscript_analyzer.h"
-#include "core/io/json.h"
#include "gdscript_language_protocol.h"
#include "gdscript_workspace.h"
@@ -40,8 +39,7 @@ void ExtendGDScriptParser::update_diagnostics() {
diagnostics.clear();
const List<ParserError> &errors = get_errors();
- for (const List<ParserError>::Element *E = errors.front(); E != nullptr; E = E->next()) {
- const ParserError &error = E->get();
+ for (const ParserError &error : errors) {
lsp::Diagnostic diagnostic;
diagnostic.severity = lsp::DiagnosticSeverity::Error;
diagnostic.message = error.message;
@@ -62,8 +60,7 @@ void ExtendGDScriptParser::update_diagnostics() {
}
const List<GDScriptWarning> &warnings = get_warnings();
- for (const List<GDScriptWarning>::Element *E = warnings.front(); E; E = E->next()) {
- const GDScriptWarning &warning = E->get();
+ for (const GDScriptWarning &warning : warnings) {
lsp::Diagnostic diagnostic;
diagnostic.severity = lsp::DiagnosticSeverity::Warning;
diagnostic.message = "(" + warning.get_name() + "): " + warning.get_message();
@@ -153,9 +150,9 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p
}
r_symbol.kind = lsp::SymbolKind::Class;
r_symbol.deprecated = false;
- r_symbol.range.start.line = LINE_NUMBER_TO_INDEX(p_class->start_line);
- r_symbol.range.start.character = LINE_NUMBER_TO_INDEX(p_class->start_column);
- r_symbol.range.end.line = LINE_NUMBER_TO_INDEX(p_class->end_line);
+ r_symbol.range.start.line = p_class->start_line;
+ r_symbol.range.start.character = p_class->start_column;
+ r_symbol.range.end.line = lines.size();
r_symbol.selectionRange.start.line = r_symbol.range.start.line;
r_symbol.detail = "class " + r_symbol.name;
bool is_root_class = &r_symbol == &class_symbol;
@@ -168,7 +165,7 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p
case ClassNode::Member::VARIABLE: {
lsp::DocumentSymbol symbol;
symbol.name = m.variable->identifier->name;
- symbol.kind = lsp::SymbolKind::Variable;
+ symbol.kind = m.variable->property == VariableNode::PropertyStyle::PROP_NONE ? lsp::SymbolKind::Variable : lsp::SymbolKind::Property;
symbol.deprecated = false;
symbol.range.start.line = LINE_NUMBER_TO_INDEX(m.variable->start_line);
symbol.range.start.character = LINE_NUMBER_TO_INDEX(m.variable->start_column);
@@ -183,7 +180,7 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p
symbol.detail += ": " + m.get_datatype().to_string();
}
if (m.variable->initializer != nullptr && m.variable->initializer->is_constant) {
- symbol.detail += " = " + JSON::print(m.variable->initializer->reduced_value);
+ symbol.detail += " = " + m.variable->initializer->reduced_value.to_json_string();
}
symbol.documentation = parse_documentation(LINE_NUMBER_TO_INDEX(m.variable->start_line));
@@ -224,10 +221,10 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p
}
}
} else {
- value_text = JSON::print(default_value);
+ value_text = default_value.to_json_string();
}
} else {
- value_text = JSON::print(default_value);
+ value_text = default_value.to_json_string();
}
if (!value_text.is_empty()) {
symbol.detail += " = " + value_text;
@@ -320,7 +317,7 @@ void ExtendGDScriptParser::parse_function_symbol(const GDScriptParser::FunctionN
const String uri = get_uri();
r_symbol.name = p_func->identifier->name;
- r_symbol.kind = lsp::SymbolKind::Function;
+ r_symbol.kind = p_func->is_static ? lsp::SymbolKind::Function : lsp::SymbolKind::Method;
r_symbol.detail = "func " + String(p_func->identifier->name) + "(";
r_symbol.deprecated = false;
r_symbol.range.start.line = LINE_NUMBER_TO_INDEX(p_func->start_line);
@@ -353,8 +350,7 @@ void ExtendGDScriptParser::parse_function_symbol(const GDScriptParser::FunctionN
parameters += ": " + parameter->get_datatype().to_string();
}
if (parameter->default_value != nullptr) {
- String value = JSON::print(parameter->default_value->reduced_value);
- parameters += " = " + value;
+ parameters += " = " + parameter->default_value->reduced_value.to_json_string();
}
}
r_symbol.detail += parameters + ")";
@@ -469,8 +465,8 @@ String ExtendGDScriptParser::parse_documentation(int p_line, bool p_docs_down) {
}
String doc;
- for (List<String>::Element *E = doc_lines.front(); E; E = E->next()) {
- doc += E->get() + "\n";
+ for (const String &E : doc_lines) {
+ doc += E + "\n";
}
return doc;
}
@@ -697,7 +693,9 @@ Dictionary ExtendGDScriptParser::dump_function_api(const GDScriptParser::Functio
ERR_FAIL_NULL_V(p_func, func);
func["name"] = p_func->identifier->name;
func["return_type"] = p_func->get_datatype().to_string();
- func["rpc_mode"] = p_func->rpc_mode;
+ func["rpc_mode"] = p_func->rpc_config.rpc_mode;
+ func["rpc_transfer_mode"] = p_func->rpc_config.transfer_mode;
+ func["rpc_transfer_channel"] = p_func->rpc_config.channel;
Array parameters;
for (int i = 0; i < p_func->parameters.size(); i++) {
Dictionary arg;
diff --git a/modules/gdscript/language_server/gdscript_language_protocol.cpp b/modules/gdscript/language_server/gdscript_language_protocol.cpp
index c16a7fa889..0d1f98778e 100644
--- a/modules/gdscript/language_server/gdscript_language_protocol.cpp
+++ b/modules/gdscript/language_server/gdscript_language_protocol.cpp
@@ -31,7 +31,6 @@
#include "gdscript_language_protocol.h"
#include "core/config/project_settings.h"
-#include "core/io/json.h"
#include "editor/doc_tools.h"
#include "editor/editor_log.h"
#include "editor/editor_node.h"
@@ -194,7 +193,7 @@ Dictionary GDScriptLanguageProtocol::initialize(const Dictionary &p_params) {
vformat("GDScriptLanguageProtocol: Can't initialize invalid peer '%d'.", latest_client_id));
Ref<LSPeer> peer = clients.get(latest_client_id);
if (peer != nullptr) {
- String msg = JSON::print(request);
+ String msg = Variant(request).to_json_string();
msg = format_output(msg);
(*peer)->res_queue.push_back(msg.utf8());
}
@@ -280,7 +279,7 @@ void GDScriptLanguageProtocol::notify_client(const String &p_method, const Varia
ERR_FAIL_COND(peer == nullptr);
Dictionary message = make_notification(p_method, p_params);
- String msg = JSON::print(message);
+ String msg = Variant(message).to_json_string();
msg = format_output(msg);
peer->res_queue.push_back(msg.utf8());
}
@@ -294,10 +293,10 @@ bool GDScriptLanguageProtocol::is_goto_native_symbols_enabled() const {
}
GDScriptLanguageProtocol::GDScriptLanguageProtocol() {
- server.instance();
+ server.instantiate();
singleton = this;
- workspace.instance();
- text_document.instance();
+ workspace.instantiate();
+ text_document.instantiate();
set_scope("textDocument", text_document.ptr());
set_scope("completionItem", text_document.ptr());
set_scope("workspace", workspace.ptr());
diff --git a/modules/gdscript/language_server/gdscript_language_protocol.h b/modules/gdscript/language_server/gdscript_language_protocol.h
index a5c5a233b1..5a2dd55c46 100644
--- a/modules/gdscript/language_server/gdscript_language_protocol.h
+++ b/modules/gdscript/language_server/gdscript_language_protocol.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef GDSCRIPT_PROTOCAL_SERVER_H
-#define GDSCRIPT_PROTOCAL_SERVER_H
+#ifndef GDSCRIPT_LANGUAGE_PROTOCOL_H
+#define GDSCRIPT_LANGUAGE_PROTOCOL_H
#include "core/io/stream_peer.h"
#include "core/io/stream_peer_tcp.h"
@@ -37,7 +37,13 @@
#include "gdscript_text_document.h"
#include "gdscript_workspace.h"
#include "lsp.hpp"
+
+#include "modules/modules_enabled.gen.h"
+#ifdef MODULE_JSONRPC_ENABLED
#include "modules/jsonrpc/jsonrpc.h"
+#else
+#error "Can't build GDScript LSP without JSONRPC module."
+#endif
#define LSP_MAX_BUFFER_SIZE 4194304
#define LSP_MAX_CLIENTS 8
@@ -46,7 +52,7 @@ class GDScriptLanguageProtocol : public JSONRPC {
GDCLASS(GDScriptLanguageProtocol, JSONRPC)
private:
- struct LSPeer : Reference {
+ struct LSPeer : RefCounted {
Ref<StreamPeerTCP> connection;
uint8_t req_buf[LSP_MAX_BUFFER_SIZE];
@@ -108,4 +114,4 @@ public:
GDScriptLanguageProtocol();
};
-#endif
+#endif // GDSCRIPT_LANGUAGE_PROTOCOL_H
diff --git a/modules/gdscript/language_server/gdscript_language_server.cpp b/modules/gdscript/language_server/gdscript_language_server.cpp
index 340a7b9343..c47164d95b 100644
--- a/modules/gdscript/language_server/gdscript_language_server.cpp
+++ b/modules/gdscript/language_server/gdscript_language_server.cpp
@@ -30,7 +30,7 @@
#include "gdscript_language_server.h"
-#include "core/os/file_access.h"
+#include "core/io/file_access.h"
#include "core/os/os.h"
#include "editor/editor_log.h"
#include "editor/editor_node.h"
@@ -101,7 +101,7 @@ void GDScriptLanguageServer::stop() {
}
void register_lsp_types() {
- ClassDB::register_class<GDScriptLanguageProtocol>();
- ClassDB::register_class<GDScriptTextDocument>();
- ClassDB::register_class<GDScriptWorkspace>();
+ GDREGISTER_CLASS(GDScriptLanguageProtocol);
+ GDREGISTER_CLASS(GDScriptTextDocument);
+ GDREGISTER_CLASS(GDScriptWorkspace);
}
diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp
index 030633274c..69ddbe5d1e 100644
--- a/modules/gdscript/language_server/gdscript_text_document.cpp
+++ b/modules/gdscript/language_server/gdscript_text_document.cpp
@@ -40,6 +40,7 @@
void GDScriptTextDocument::_bind_methods() {
ClassDB::bind_method(D_METHOD("didOpen"), &GDScriptTextDocument::didOpen);
+ ClassDB::bind_method(D_METHOD("didClose"), &GDScriptTextDocument::didClose);
ClassDB::bind_method(D_METHOD("didChange"), &GDScriptTextDocument::didChange);
ClassDB::bind_method(D_METHOD("nativeSymbol"), &GDScriptTextDocument::nativeSymbol);
ClassDB::bind_method(D_METHOD("documentSymbol"), &GDScriptTextDocument::documentSymbol);
@@ -61,6 +62,11 @@ void GDScriptTextDocument::didOpen(const Variant &p_param) {
sync_script_content(doc.uri, doc.text);
}
+void GDScriptTextDocument::didClose(const Variant &p_param) {
+ // Left empty on purpose. Godot does nothing special on closing a document,
+ // but it satisfies LSP clients that require didClose be implemented.
+}
+
void GDScriptTextDocument::didChange(const Variant &p_param) {
lsp::TextDocumentItem doc = load_document_item(p_param);
Dictionary dict = p_param;
@@ -151,8 +157,7 @@ Array GDScriptTextDocument::completion(const Dictionary &p_params) {
int i = 0;
arr.resize(options.size());
- for (const List<ScriptCodeCompletionOption>::Element *E = options.front(); E; E = E->next()) {
- const ScriptCodeCompletionOption &option = E->get();
+ for (const ScriptCodeCompletionOption &option : options) {
lsp::CompletionItem item;
item.label = option.display;
item.data = request_data;
@@ -288,8 +293,8 @@ Array GDScriptTextDocument::documentLink(const Dictionary &p_params) {
List<lsp::DocumentLink> links;
GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_document_links(params.textDocument.uri, links);
- for (const List<lsp::DocumentLink>::Element *E = links.front(); E; E = E->next()) {
- ret.push_back(E->get().to_json());
+ for (const lsp::DocumentLink &E : links) {
+ ret.push_back(E.to_json());
}
return ret;
}
@@ -316,8 +321,8 @@ Variant GDScriptTextDocument::hover(const Dictionary &p_params) {
Array contents;
List<const lsp::DocumentSymbol *> list;
GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_related_symbols(params, list);
- for (List<const lsp::DocumentSymbol *>::Element *E = list.front(); E; E = E->next()) {
- if (const lsp::DocumentSymbol *s = E->get()) {
+ for (const lsp::DocumentSymbol *&E : list) {
+ if (const lsp::DocumentSymbol *s = E) {
contents.push_back(s->render().value);
}
}
@@ -367,7 +372,7 @@ Variant GDScriptTextDocument::declaration(const Dictionary &p_params) {
id = "class_global:" + symbol->native_class + ":" + symbol->name;
break;
}
- call_deferred("show_native_symbol_in_editor", id);
+ call_deferred(SNAME("show_native_symbol_in_editor"), id);
} else {
notify_client_show_symbol(symbol);
}
@@ -404,7 +409,7 @@ void GDScriptTextDocument::sync_script_content(const String &p_path, const Strin
}
void GDScriptTextDocument::show_native_symbol_in_editor(const String &p_symbol_id) {
- ScriptEditor::get_singleton()->call_deferred("_help_class_goto", p_symbol_id);
+ ScriptEditor::get_singleton()->call_deferred(SNAME("_help_class_goto"), p_symbol_id);
DisplayServer::get_singleton()->window_move_to_foreground();
}
@@ -424,8 +429,8 @@ Array GDScriptTextDocument::find_symbols(const lsp::TextDocumentPositionParams &
} else if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) {
List<const lsp::DocumentSymbol *> list;
GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_related_symbols(p_location, list);
- for (List<const lsp::DocumentSymbol *>::Element *E = list.front(); E; E = E->next()) {
- if (const lsp::DocumentSymbol *s = E->get()) {
+ for (const lsp::DocumentSymbol *&E : list) {
+ if (const lsp::DocumentSymbol *s = E) {
if (!s->uri.is_empty()) {
lsp::Location location;
location.uri = s->uri;
diff --git a/modules/gdscript/language_server/gdscript_text_document.h b/modules/gdscript/language_server/gdscript_text_document.h
index 792e601bc1..e2987f779c 100644
--- a/modules/gdscript/language_server/gdscript_text_document.h
+++ b/modules/gdscript/language_server/gdscript_text_document.h
@@ -31,18 +31,19 @@
#ifndef GDSCRIPT_TEXT_DOCUMENT_H
#define GDSCRIPT_TEXT_DOCUMENT_H
-#include "core/object/reference.h"
-#include "core/os/file_access.h"
+#include "core/io/file_access.h"
+#include "core/object/ref_counted.h"
#include "lsp.hpp"
-class GDScriptTextDocument : public Reference {
- GDCLASS(GDScriptTextDocument, Reference)
+class GDScriptTextDocument : public RefCounted {
+ GDCLASS(GDScriptTextDocument, RefCounted)
protected:
static void _bind_methods();
FileAccess *file_checker;
void didOpen(const Variant &p_param);
+ void didClose(const Variant &p_param);
void didChange(const Variant &p_param);
void sync_script_content(const String &p_path, const String &p_content);
diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp
index 9b7b2b36b4..e6c819b22f 100644
--- a/modules/gdscript/language_server/gdscript_workspace.cpp
+++ b/modules/gdscript/language_server/gdscript_workspace.cpp
@@ -119,8 +119,7 @@ const lsp::DocumentSymbol *GDScriptWorkspace::get_script_symbol(const String &p_
void GDScriptWorkspace::reload_all_workspace_scripts() {
List<String> paths;
list_script_files("res://", paths);
- for (List<String>::Element *E = paths.front(); E; E = E->next()) {
- const String &path = E->get();
+ for (const String &path : paths) {
Error err;
String content = FileAccess::get_file_as_string(path, &err);
ERR_CONTINUE(err != OK);
@@ -188,7 +187,9 @@ Array GDScriptWorkspace::symbol(const Dictionary &p_params) {
E->get()->get_symbols().symbol_tree_as_list(E->key(), script_symbols);
for (int i = 0; i < script_symbols.size(); ++i) {
if (query.is_subsequence_ofi(script_symbols[i].name)) {
- arr.push_back(script_symbols[i].to_json());
+ lsp::DocumentedSymbolInformation symbol = script_symbols[i];
+ symbol.location.uri = get_file_uri(symbol.location.uri);
+ arr.push_back(symbol.to_json());
}
}
}
@@ -424,7 +425,7 @@ Node *GDScriptWorkspace::_get_owner_scene_node(String p_path) {
RES owner_res = ResourceLoader::load(owner_path);
if (Object::cast_to<PackedScene>(owner_res.ptr())) {
Ref<PackedScene> owner_packed_scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*owner_res));
- owner_scene_node = owner_packed_scene->instance();
+ owner_scene_node = owner_packed_scene->instantiate();
break;
}
}
@@ -557,8 +558,8 @@ const lsp::DocumentSymbol *GDScriptWorkspace::resolve_native_symbol(const lsp::N
void GDScriptWorkspace::resolve_document_links(const String &p_uri, List<lsp::DocumentLink> &r_list) {
if (const ExtendGDScriptParser *parser = get_parse_successed_script(get_file_path(p_uri))) {
const List<lsp::DocumentLink> &links = parser->get_document_links();
- for (const List<lsp::DocumentLink>::Element *E = links.front(); E; E = E->next()) {
- r_list.push_back(E->get());
+ for (const lsp::DocumentLink &E : links) {
+ r_list.push_back(E);
}
}
}
@@ -585,8 +586,7 @@ Error GDScriptWorkspace::resolve_signature(const lsp::TextDocumentPositionParams
GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_related_symbols(text_pos, symbols);
}
- for (List<const lsp::DocumentSymbol *>::Element *E = symbols.front(); E; E = E->next()) {
- const lsp::DocumentSymbol *symbol = E->get();
+ for (const lsp::DocumentSymbol *const &symbol : symbols) {
if (symbol->kind == lsp::SymbolKind::Method || symbol->kind == lsp::SymbolKind::Function) {
lsp::SignatureInformation signature_info;
signature_info.label = symbol->detail;
diff --git a/modules/gdscript/language_server/gdscript_workspace.h b/modules/gdscript/language_server/gdscript_workspace.h
index 27616a2989..8b166a873c 100644
--- a/modules/gdscript/language_server/gdscript_workspace.h
+++ b/modules/gdscript/language_server/gdscript_workspace.h
@@ -37,8 +37,8 @@
#include "gdscript_extend_parser.h"
#include "lsp.hpp"
-class GDScriptWorkspace : public Reference {
- GDCLASS(GDScriptWorkspace, Reference);
+class GDScriptWorkspace : public RefCounted {
+ GDCLASS(GDScriptWorkspace, RefCounted);
private:
void _get_owners(EditorFileSystemDirectory *efsd, String p_path, List<String> &owners);
diff --git a/modules/gdscript/language_server/lsp.hpp b/modules/gdscript/language_server/lsp.hpp
index 47bcfeaefc..0138f132ad 100644
--- a/modules/gdscript/language_server/lsp.hpp
+++ b/modules/gdscript/language_server/lsp.hpp
@@ -766,7 +766,7 @@ struct MarkupContent {
// Use namespace instead of enumeration to follow the LSP specifications
// lsp::EnumName::EnumValue is OK but lsp::EnumValue is not
-// And here C++ compilers are unhappy with our enumeration name like Color, File, Reference etc.
+// And here C++ compilers are unhappy with our enumeration name like Color, File, RefCounted etc.
/**
* The kind of a completion entry.
*/
@@ -788,7 +788,7 @@ static const int Keyword = 14;
static const int Snippet = 15;
static const int Color = 16;
static const int File = 17;
-static const int Reference = 18;
+static const int RefCounted = 18;
static const int Folder = 19;
static const int EnumMember = 20;
static const int Constant = 21;
@@ -1018,32 +1018,32 @@ struct CompletionList {
* A symbol kind.
*/
namespace SymbolKind {
-static const int File = 0;
-static const int Module = 1;
-static const int Namespace = 2;
-static const int Package = 3;
-static const int Class = 4;
-static const int Method = 5;
-static const int Property = 6;
-static const int Field = 7;
-static const int Constructor = 8;
-static const int Enum = 9;
-static const int Interface = 10;
-static const int Function = 11;
-static const int Variable = 12;
-static const int Constant = 13;
-static const int String = 14;
-static const int Number = 15;
-static const int Boolean = 16;
-static const int Array = 17;
-static const int Object = 18;
-static const int Key = 19;
-static const int Null = 20;
-static const int EnumMember = 21;
-static const int Struct = 22;
-static const int Event = 23;
-static const int Operator = 24;
-static const int TypeParameter = 25;
+static const int File = 1;
+static const int Module = 2;
+static const int Namespace = 3;
+static const int Package = 4;
+static const int Class = 5;
+static const int Method = 6;
+static const int Property = 7;
+static const int Field = 8;
+static const int Constructor = 9;
+static const int Enum = 10;
+static const int Interface = 11;
+static const int Function = 12;
+static const int Variable = 13;
+static const int Constant = 14;
+static const int String = 15;
+static const int Number = 16;
+static const int Boolean = 17;
+static const int Array = 18;
+static const int Object = 19;
+static const int Key = 20;
+static const int Null = 21;
+static const int EnumMember = 22;
+static const int Struct = 23;
+static const int Event = 24;
+static const int Operator = 25;
+static const int TypeParameter = 26;
}; // namespace SymbolKind
/**
diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp
index 2d2f94f5e0..c2b1981f31 100644
--- a/modules/gdscript/register_types.cpp
+++ b/modules/gdscript/register_types.cpp
@@ -30,10 +30,10 @@
#include "register_types.h"
+#include "core/io/dir_access.h"
+#include "core/io/file_access.h"
#include "core/io/file_access_encrypted.h"
#include "core/io/resource_loader.h"
-#include "core/os/dir_access.h"
-#include "core/os/file_access.h"
#include "gdscript.h"
#include "gdscript_analyzer.h"
#include "gdscript_cache.h"
@@ -92,12 +92,12 @@ public:
static void _editor_init() {
Ref<EditorExportGDScript> gd_export;
- gd_export.instance();
+ gd_export.instantiate();
EditorExport::get_singleton()->add_export_plugin(gd_export);
#ifdef TOOLS_ENABLED
Ref<GDScriptSyntaxHighlighter> gdscript_syntax_highlighter;
- gdscript_syntax_highlighter.instance();
+ gdscript_syntax_highlighter.instantiate();
ScriptEditor::get_singleton()->register_syntax_highlighter(gdscript_syntax_highlighter);
#endif
@@ -112,15 +112,15 @@ static void _editor_init() {
#endif // TOOLS_ENABLED
void register_gdscript_types() {
- ClassDB::register_class<GDScript>();
+ GDREGISTER_CLASS(GDScript);
script_language_gd = memnew(GDScriptLanguage);
ScriptServer::register_language(script_language_gd);
- resource_loader_gd.instance();
+ resource_loader_gd.instantiate();
ResourceLoader::add_resource_format_loader(resource_loader_gd);
- resource_saver_gd.instance();
+ resource_saver_gd.instantiate();
ResourceSaver::add_resource_format_saver(resource_saver_gd);
gdscript_cache = memnew(GDScriptCache);
@@ -128,7 +128,7 @@ void register_gdscript_types() {
#ifdef TOOLS_ENABLED
EditorNode::add_init_callback(_editor_init);
- gdscript_translation_parser_plugin.instance();
+ gdscript_translation_parser_plugin.instantiate();
EditorTranslationParser::get_singleton()->add_parser(gdscript_translation_parser_plugin, EditorTranslationParser::STANDARD);
#endif // TOOLS_ENABLED
diff --git a/modules/gdscript/tests/gdscript_test_runner.cpp b/modules/gdscript/tests/gdscript_test_runner.cpp
index 76ae43e792..03a48bf071 100644
--- a/modules/gdscript/tests/gdscript_test_runner.cpp
+++ b/modules/gdscript/tests/gdscript_test_runner.cpp
@@ -37,8 +37,8 @@
#include "core/config/project_settings.h"
#include "core/core_string_names.h"
+#include "core/io/dir_access.h"
#include "core/io/file_access_pack.h"
-#include "core/os/dir_access.h"
#include "core/os/os.h"
#include "core/string/string_builder.h"
#include "scene/resources/packed_scene.h"
@@ -75,14 +75,14 @@ void init_autoloads() {
Node *n = nullptr;
if (res->is_class("PackedScene")) {
Ref<PackedScene> ps = res;
- n = ps->instance();
+ n = ps->instantiate();
} else if (res->is_class("Script")) {
Ref<Script> script_res = res;
StringName ibt = script_res->get_instance_base_type();
bool valid_type = ClassDB::is_parent_class(ibt, "Node");
ERR_CONTINUE_MSG(!valid_type, "Script does not inherit a Node: " + info.path);
- Object *obj = ClassDB::instance(ibt);
+ Object *obj = ClassDB::instantiate(ibt);
ERR_CONTINUE_MSG(obj == nullptr,
"Cannot instance script for autoload, expected 'Node' inheritance, got: " +
@@ -257,6 +257,7 @@ bool GDScriptTestRunner::make_tests() {
ERR_FAIL_COND_V_MSG(err != OK, false, "Could not open specified test directory.");
+ source_dir = dir->get_current_dir() + "/"; // Make it absolute path.
return make_tests_for_dir(dir->get_current_dir());
}
@@ -294,7 +295,7 @@ void GDScriptTestRunner::handle_cmdline() {
String test_cmd = "--gdscript-test";
String gen_cmd = "--gdscript-generate-tests";
- for (List<String>::Element *E = cmdline_args.front(); E != nullptr; E = E->next()) {
+ for (List<String>::Element *E = cmdline_args.front(); E; E = E->next()) {
String &cmd = E->get();
if (cmd == test_cmd || cmd == gen_cmd) {
if (E->next() == nullptr) {
@@ -361,11 +362,9 @@ void GDScriptTest::error_handler(void *p_this, const char *p_function, const cha
break;
}
- builder.append("\n>> ");
- builder.append(p_function);
- builder.append("\n>> ");
+ builder.append("\n>> on function: ");
builder.append(p_function);
- builder.append("\n>> ");
+ builder.append("()\n>> ");
builder.append(String(p_file).trim_prefix(self->base_dir));
builder.append("\n>> ");
builder.append(itos(p_line));
@@ -421,7 +420,7 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) {
// Create script.
Ref<GDScript> script;
- script.instance();
+ script.instantiate();
script->set_path(source_file);
script->set_script_path(source_file);
err = script->load_source_code(source_file);
@@ -441,8 +440,8 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) {
result.output = get_text_for_status(result.status) + "\n";
const List<GDScriptParser::ParserError> &errors = parser.get_errors();
- for (const List<GDScriptParser::ParserError>::Element *E = errors.front(); E; E = E->next()) {
- result.output += E->get().message + "\n"; // TODO: line, column?
+ for (const GDScriptParser::ParserError &E : errors) {
+ result.output += E.message + "\n"; // TODO: line, column?
break; // Only the first error since the following might be cascading.
}
if (!p_is_generating) {
@@ -460,8 +459,8 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) {
result.output = get_text_for_status(result.status) + "\n";
const List<GDScriptParser::ParserError> &errors = parser.get_errors();
- for (const List<GDScriptParser::ParserError>::Element *E = errors.front(); E; E = E->next()) {
- result.output += E->get().message + "\n"; // TODO: line, column?
+ for (const GDScriptParser::ParserError &E : errors) {
+ result.output += E.message + "\n"; // TODO: line, column?
break; // Only the first error since the following might be cascading.
}
if (!p_is_generating) {
@@ -471,8 +470,8 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) {
}
StringBuilder warning_string;
- for (const List<GDScriptWarning>::Element *E = parser.get_warnings().front(); E != nullptr; E = E->next()) {
- const GDScriptWarning warning = E->get();
+ for (const GDScriptWarning &E : parser.get_warnings()) {
+ const GDScriptWarning warning = E;
warning_string.append(">> WARNING");
warning_string.append("\n>> Line: ");
warning_string.append(itos(warning.start_line));
@@ -511,10 +510,10 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) {
script->reload();
// Create object instance for test.
- Object *obj = ClassDB::instance(script->get_native()->get_name());
- Ref<Reference> obj_ref;
- if (obj->is_reference()) {
- obj_ref = Ref<Reference>(Object::cast_to<Reference>(obj));
+ Object *obj = ClassDB::instantiate(script->get_native()->get_name());
+ Ref<RefCounted> obj_ref;
+ if (obj->is_ref_counted()) {
+ obj_ref = Ref<RefCounted>(Object::cast_to<RefCounted>(obj));
}
obj->set_script(script);
GDScriptInstance *instance = static_cast<GDScriptInstance *>(obj->get_script_instance());
diff --git a/modules/gdscript/tests/gdscript_test_runner_suite.h b/modules/gdscript/tests/gdscript_test_runner_suite.h
index 8fd77239cd..cf4e61f07d 100644
--- a/modules/gdscript/tests/gdscript_test_runner_suite.h
+++ b/modules/gdscript/tests/gdscript_test_runner_suite.h
@@ -51,7 +51,7 @@ TEST_SUITE("[Modules][GDScript]") {
TEST_CASE("[Modules][GDScript] Load source code dynamically and run it") {
Ref<GDScript> gdscript = memnew(GDScript);
gdscript->set_source_code(R"(
-extends Reference
+extends RefCounted
func _init():
set_meta("result", 42)
@@ -64,9 +64,9 @@ func _init():
CHECK_MESSAGE(error == OK, "The script should parse successfully.");
// Run the script by assigning it to a reference-counted object.
- Ref<Reference> reference = memnew(Reference);
- reference->set_script(gdscript);
- CHECK_MESSAGE(int(reference->get_meta("result")) == 42, "The script should assign object metadata successfully.");
+ Ref<RefCounted> ref_counted = memnew(RefCounted);
+ ref_counted->set_script(gdscript);
+ CHECK_MESSAGE(int(ref_counted->get_meta("result")) == 42, "The script should assign object metadata successfully.");
}
} // namespace GDScriptTests
diff --git a/modules/gdscript/tests/scripts/analyzer/features/call_self_get_name.gd b/modules/gdscript/tests/scripts/analyzer/features/call_self_get_name.gd
new file mode 100644
index 0000000000..d21d8bce96
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/call_self_get_name.gd
@@ -0,0 +1,9 @@
+extends Node
+
+func test():
+ set_name("TestNodeName")
+ if get_name() == &"TestNodeName":
+ print("Name is equal")
+ else:
+ print("Name is not equal")
+ print(get_name() is StringName)
diff --git a/modules/gdscript/tests/scripts/analyzer/features/call_self_get_name.out b/modules/gdscript/tests/scripts/analyzer/features/call_self_get_name.out
new file mode 100644
index 0000000000..dc4348d9c3
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/call_self_get_name.out
@@ -0,0 +1,3 @@
+GDTEST_OK
+Name is equal
+True
diff --git a/modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.gd b/modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.gd
new file mode 100644
index 0000000000..10780b5379
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.gd
@@ -0,0 +1,5 @@
+func test():
+ var node := Node.new()
+ var inside_tree = node.is_inside_tree
+ node.free()
+ inside_tree.call()
diff --git a/modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.out b/modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.out
new file mode 100644
index 0000000000..e585c374e2
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.out
@@ -0,0 +1,6 @@
+GDTEST_RUNTIME_ERROR
+>> SCRIPT ERROR
+>> on function: test()
+>> runtime/errors/callable_call_after_free_object.gd
+>> 5
+>> Attempt to call function 'null::is_inside_tree (Callable)' on a null instance.
diff --git a/modules/gdscript/tests/test_gdscript.cpp b/modules/gdscript/tests/test_gdscript.cpp
index 8ad5cdacad..52e9d92223 100644
--- a/modules/gdscript/tests/test_gdscript.cpp
+++ b/modules/gdscript/tests/test_gdscript.cpp
@@ -31,8 +31,8 @@
#include "test_gdscript.h"
#include "core/config/project_settings.h"
+#include "core/io/file_access.h"
#include "core/io/file_access_pack.h"
-#include "core/os/file_access.h"
#include "core/os/main_loop.h"
#include "core/os/os.h"
#include "core/string/string_builder.h"
@@ -113,8 +113,7 @@ static void test_parser(const String &p_code, const String &p_script_path, const
if (err != OK) {
const List<GDScriptParser::ParserError> &errors = parser.get_errors();
- for (const List<GDScriptParser::ParserError>::Element *E = errors.front(); E != nullptr; E = E->next()) {
- const GDScriptParser::ParserError &error = E->get();
+ for (const GDScriptParser::ParserError &error : errors) {
print_line(vformat("%02d:%02d: %s", error.line, error.column, error.message));
}
}
@@ -124,8 +123,7 @@ static void test_parser(const String &p_code, const String &p_script_path, const
if (err != OK) {
const List<GDScriptParser::ParserError> &errors = parser.get_errors();
- for (const List<GDScriptParser::ParserError>::Element *E = errors.front(); E != nullptr; E = E->next()) {
- const GDScriptParser::ParserError &error = E->get();
+ for (const GDScriptParser::ParserError &error : errors) {
print_line(vformat("%02d:%02d: %s", error.line, error.column, error.message));
}
}
@@ -143,8 +141,7 @@ static void test_compiler(const String &p_code, const String &p_script_path, con
if (err != OK) {
print_line("Error in parser:");
const List<GDScriptParser::ParserError> &errors = parser.get_errors();
- for (const List<GDScriptParser::ParserError>::Element *E = errors.front(); E != nullptr; E = E->next()) {
- const GDScriptParser::ParserError &error = E->get();
+ for (const GDScriptParser::ParserError &error : errors) {
print_line(vformat("%02d:%02d: %s", error.line, error.column, error.message));
}
return;
@@ -156,8 +153,7 @@ static void test_compiler(const String &p_code, const String &p_script_path, con
if (err != OK) {
print_line("Error in analyzer:");
const List<GDScriptParser::ParserError> &errors = parser.get_errors();
- for (const List<GDScriptParser::ParserError>::Element *E = errors.front(); E != nullptr; E = E->next()) {
- const GDScriptParser::ParserError &error = E->get();
+ for (const GDScriptParser::ParserError &error : errors) {
print_line(vformat("%02d:%02d: %s", error.line, error.column, error.message));
}
return;
@@ -165,7 +161,7 @@ static void test_compiler(const String &p_code, const String &p_script_path, con
GDScriptCompiler compiler;
Ref<GDScript> script;
- script.instance();
+ script.instantiate();
script->set_path(p_script_path);
err = compiler.compile(&parser, script.ptr(), false);
@@ -215,8 +211,8 @@ void test(TestType p_type) {
init_language(fa->get_path_absolute().get_base_dir());
Vector<uint8_t> buf;
- uint64_t flen = fa->get_len();
- buf.resize(fa->get_len() + 1);
+ uint64_t flen = fa->get_length();
+ buf.resize(flen + 1);
fa->get_buffer(buf.ptrw(), flen);
buf.write[flen] = 0;