summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/extension/gdextension_interface.h136
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp10
-rw-r--r--modules/gdscript/gdscript_compiler.cpp35
-rw-r--r--modules/gdscript/gdscript_compiler.h5
-rw-r--r--modules/gdscript/gdscript_parser.cpp15
-rw-r--r--modules/gdscript/gdscript_parser.h2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/virtual_method_not_implemented.gd2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/virtual_method_not_implemented.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/virtual_super_not_implemented.gd5
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/virtual_super_not_implemented.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/virtual_method_implemented.gd11
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/virtual_super_implemented.gd10
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/virtual_super_implemented.out1
-rw-r--r--modules/gdscript/tests/scripts/parser/errors/lambda_no_continue_on_new_line.gd6
-rw-r--r--modules/gdscript/tests/scripts/parser/errors/lambda_no_continue_on_new_line.out2
-rw-r--r--modules/gdscript/tests/scripts/parser/features/lambda_ends_with_new_line.gd59
-rw-r--r--modules/gdscript/tests/scripts/parser/features/lambda_ends_with_new_line.out25
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/reset_local_var_on exit_block.gd10
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/reset_local_var_on exit_block.out (renamed from modules/gdscript/tests/scripts/analyzer/features/virtual_method_implemented.out)2
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/reset_unassigned_variables_in_loops.gd28
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/reset_unassigned_variables_in_loops.out14
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs22
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs54
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs12
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp5
-rw-r--r--servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl11
26 files changed, 382 insertions, 104 deletions
diff --git a/core/extension/gdextension_interface.h b/core/extension/gdextension_interface.h
index 2a328c9a34..4d7bdf9502 100644
--- a/core/extension/gdextension_interface.h
+++ b/core/extension/gdextension_interface.h
@@ -490,6 +490,7 @@ typedef struct {
/**
* @name get_godot_version
+ * @since 4.1
*
* Gets the Godot version that the GDExtension was loaded into.
*
@@ -501,6 +502,7 @@ typedef void (*GDExtensionInterfaceGetGodotVersion)(GDExtensionGodotVersion *r_g
/**
* @name mem_alloc
+ * @since 4.1
*
* Allocates memory.
*
@@ -512,6 +514,7 @@ typedef void *(*GDExtensionInterfaceMemAlloc)(size_t p_bytes);
/**
* @name mem_realloc
+ * @since 4.1
*
* Reallocates memory.
*
@@ -524,6 +527,7 @@ typedef void *(*GDExtensionInterfaceMemRealloc)(void *p_ptr, size_t p_bytes);
/**
* @name mem_free
+ * @since 4.1
*
* Frees memory.
*
@@ -535,6 +539,7 @@ typedef void (*GDExtensionInterfaceMemFree)(void *p_ptr);
/**
* @name print_error
+ * @since 4.1
*
* Logs an error to Godot's built-in debugger and to the OS terminal.
*
@@ -548,6 +553,7 @@ typedef void (*GDExtensionInterfacePrintError)(const char *p_description, const
/**
* @name print_error_with_message
+ * @since 4.1
*
* Logs an error with a message to Godot's built-in debugger and to the OS terminal.
*
@@ -562,6 +568,7 @@ typedef void (*GDExtensionInterfacePrintErrorWithMessage)(const char *p_descript
/**
* @name print_warning
+ * @since 4.1
*
* Logs a warning to Godot's built-in debugger and to the OS terminal.
*
@@ -575,6 +582,7 @@ typedef void (*GDExtensionInterfacePrintWarning)(const char *p_description, cons
/**
* @name print_warning_with_message
+ * @since 4.1
*
* Logs a warning with a message to Godot's built-in debugger and to the OS terminal.
*
@@ -589,6 +597,7 @@ typedef void (*GDExtensionInterfacePrintWarningWithMessage)(const char *p_descri
/**
* @name print_script_error
+ * @since 4.1
*
* Logs a script error to Godot's built-in debugger and to the OS terminal.
*
@@ -602,6 +611,7 @@ typedef void (*GDExtensionInterfacePrintScriptError)(const char *p_description,
/**
* @name print_script_error_with_message
+ * @since 4.1
*
* Logs a script error with a message to Godot's built-in debugger and to the OS terminal.
*
@@ -616,6 +626,7 @@ typedef void (*GDExtensionInterfacePrintScriptErrorWithMessage)(const char *p_de
/**
* @name get_native_struct_size
+ * @since 4.1
*
* Gets the size of a native struct (ex. ObjectID) in bytes.
*
@@ -629,6 +640,7 @@ typedef uint64_t (*GDExtensionInterfaceGetNativeStructSize)(GDExtensionConstStri
/**
* @name variant_new_copy
+ * @since 4.1
*
* Copies one Variant into a another.
*
@@ -639,6 +651,7 @@ typedef void (*GDExtensionInterfaceVariantNewCopy)(GDExtensionUninitializedVaria
/**
* @name variant_new_nil
+ * @since 4.1
*
* Creates a new Variant containing nil.
*
@@ -648,6 +661,7 @@ typedef void (*GDExtensionInterfaceVariantNewNil)(GDExtensionUninitializedVarian
/**
* @name variant_destroy
+ * @since 4.1
*
* Destroys a Variant.
*
@@ -657,6 +671,7 @@ typedef void (*GDExtensionInterfaceVariantDestroy)(GDExtensionVariantPtr p_self)
/**
* @name variant_call
+ * @since 4.1
*
* Calls a method on a Variant.
*
@@ -673,6 +688,7 @@ typedef void (*GDExtensionInterfaceVariantCall)(GDExtensionVariantPtr p_self, GD
/**
* @name variant_call_static
+ * @since 4.1
*
* Calls a static method on a Variant.
*
@@ -689,6 +705,7 @@ typedef void (*GDExtensionInterfaceVariantCallStatic)(GDExtensionVariantType p_t
/**
* @name variant_evaluate
+ * @since 4.1
*
* Evaluate an operator on two Variants.
*
@@ -704,6 +721,7 @@ typedef void (*GDExtensionInterfaceVariantEvaluate)(GDExtensionVariantOperator p
/**
* @name variant_set
+ * @since 4.1
*
* Sets a key on a Variant to a value.
*
@@ -718,6 +736,7 @@ typedef void (*GDExtensionInterfaceVariantSet)(GDExtensionVariantPtr p_self, GDE
/**
* @name variant_set_named
+ * @since 4.1
*
* Sets a named key on a Variant to a value.
*
@@ -732,6 +751,7 @@ typedef void (*GDExtensionInterfaceVariantSetNamed)(GDExtensionVariantPtr p_self
/**
* @name variant_set_keyed
+ * @since 4.1
*
* Sets a keyed property on a Variant to a value.
*
@@ -746,6 +766,7 @@ typedef void (*GDExtensionInterfaceVariantSetKeyed)(GDExtensionVariantPtr p_self
/**
* @name variant_set_indexed
+ * @since 4.1
*
* Sets an index on a Variant to a value.
*
@@ -759,6 +780,7 @@ typedef void (*GDExtensionInterfaceVariantSetIndexed)(GDExtensionVariantPtr p_se
/**
* @name variant_get
+ * @since 4.1
*
* Gets the value of a key from a Variant.
*
@@ -771,6 +793,7 @@ typedef void (*GDExtensionInterfaceVariantGet)(GDExtensionConstVariantPtr p_self
/**
* @name variant_get_named
+ * @since 4.1
*
* Gets the value of a named key from a Variant.
*
@@ -783,6 +806,7 @@ typedef void (*GDExtensionInterfaceVariantGetNamed)(GDExtensionConstVariantPtr p
/**
* @name variant_get_keyed
+ * @since 4.1
*
* Gets the value of a keyed property from a Variant.
*
@@ -795,6 +819,7 @@ typedef void (*GDExtensionInterfaceVariantGetKeyed)(GDExtensionConstVariantPtr p
/**
* @name variant_get_indexed
+ * @since 4.1
*
* Gets the value of an index from a Variant.
*
@@ -808,6 +833,7 @@ typedef void (*GDExtensionInterfaceVariantGetIndexed)(GDExtensionConstVariantPtr
/**
* @name variant_iter_init
+ * @since 4.1
*
* Initializes an iterator over a Variant.
*
@@ -823,6 +849,7 @@ typedef GDExtensionBool (*GDExtensionInterfaceVariantIterInit)(GDExtensionConstV
/**
* @name variant_iter_next
+ * @since 4.1
*
* Gets the next value for an iterator over a Variant.
*
@@ -838,6 +865,7 @@ typedef GDExtensionBool (*GDExtensionInterfaceVariantIterNext)(GDExtensionConstV
/**
* @name variant_iter_get
+ * @since 4.1
*
* Gets the next value for an iterator over a Variant.
*
@@ -852,6 +880,7 @@ typedef void (*GDExtensionInterfaceVariantIterGet)(GDExtensionConstVariantPtr p_
/**
* @name variant_hash
+ * @since 4.1
*
* Gets the hash of a Variant.
*
@@ -865,6 +894,7 @@ typedef GDExtensionInt (*GDExtensionInterfaceVariantHash)(GDExtensionConstVarian
/**
* @name variant_recursive_hash
+ * @since 4.1
*
* Gets the recursive hash of a Variant.
*
@@ -879,6 +909,7 @@ typedef GDExtensionInt (*GDExtensionInterfaceVariantRecursiveHash)(GDExtensionCo
/**
* @name variant_hash_compare
+ * @since 4.1
*
* Compares two Variants by their hash.
*
@@ -893,6 +924,7 @@ typedef GDExtensionBool (*GDExtensionInterfaceVariantHashCompare)(GDExtensionCon
/**
* @name variant_booleanize
+ * @since 4.1
*
* Converts a Variant to a boolean.
*
@@ -904,6 +936,7 @@ typedef GDExtensionBool (*GDExtensionInterfaceVariantBooleanize)(GDExtensionCons
/**
* @name variant_duplicate
+ * @since 4.1
*
* Duplicates a Variant.
*
@@ -915,6 +948,7 @@ typedef void (*GDExtensionInterfaceVariantDuplicate)(GDExtensionConstVariantPtr
/**
* @name variant_stringify
+ * @since 4.1
*
* Converts a Variant to a string.
*
@@ -925,6 +959,7 @@ typedef void (*GDExtensionInterfaceVariantStringify)(GDExtensionConstVariantPtr
/**
* @name variant_get_type
+ * @since 4.1
*
* Gets the type of a Variant.
*
@@ -936,6 +971,7 @@ typedef GDExtensionVariantType (*GDExtensionInterfaceVariantGetType)(GDExtension
/**
* @name variant_has_method
+ * @since 4.1
*
* Checks if a Variant has the given method.
*
@@ -948,6 +984,7 @@ typedef GDExtensionBool (*GDExtensionInterfaceVariantHasMethod)(GDExtensionConst
/**
* @name variant_has_member
+ * @since 4.1
*
* Checks if a type of Variant has the given member.
*
@@ -960,6 +997,7 @@ typedef GDExtensionBool (*GDExtensionInterfaceVariantHasMember)(GDExtensionVaria
/**
* @name variant_has_key
+ * @since 4.1
*
* Checks if a Variant has a key.
*
@@ -973,6 +1011,7 @@ typedef GDExtensionBool (*GDExtensionInterfaceVariantHasKey)(GDExtensionConstVar
/**
* @name variant_get_type_name
+ * @since 4.1
*
* Gets the name of a Variant type.
*
@@ -983,6 +1022,7 @@ typedef void (*GDExtensionInterfaceVariantGetTypeName)(GDExtensionVariantType p_
/**
* @name variant_can_convert
+ * @since 4.1
*
* Checks if Variants can be converted from one type to another.
*
@@ -995,6 +1035,7 @@ typedef GDExtensionBool (*GDExtensionInterfaceVariantCanConvert)(GDExtensionVari
/**
* @name variant_can_convert_strict
+ * @since 4.1
*
* Checks if Variant can be converted from one type to another using stricter rules.
*
@@ -1007,6 +1048,7 @@ typedef GDExtensionBool (*GDExtensionInterfaceVariantCanConvertStrict)(GDExtensi
/**
* @name get_variant_from_type_constructor
+ * @since 4.1
*
* Gets a pointer to a function that can create a Variant of the given type from a raw value.
*
@@ -1018,6 +1060,7 @@ typedef GDExtensionVariantFromTypeConstructorFunc (*GDExtensionInterfaceGetVaria
/**
* @name get_variant_to_type_constructor
+ * @since 4.1
*
* Gets a pointer to a function that can get the raw value from a Variant of the given type.
*
@@ -1029,6 +1072,7 @@ typedef GDExtensionTypeFromVariantConstructorFunc (*GDExtensionInterfaceGetVaria
/**
* @name variant_get_ptr_operator_evaluator
+ * @since 4.1
*
* Gets a pointer to a function that can evaluate the given Variant operator on the given Variant types.
*
@@ -1042,6 +1086,7 @@ typedef GDExtensionPtrOperatorEvaluator (*GDExtensionInterfaceVariantGetPtrOpera
/**
* @name variant_get_ptr_builtin_method
+ * @since 4.1
*
* Gets a pointer to a function that can call a builtin method on a type of Variant.
*
@@ -1055,6 +1100,7 @@ typedef GDExtensionPtrBuiltInMethod (*GDExtensionInterfaceVariantGetPtrBuiltinMe
/**
* @name variant_get_ptr_constructor
+ * @since 4.1
*
* Gets a pointer to a function that can call one of the constructors for a type of Variant.
*
@@ -1067,6 +1113,7 @@ typedef GDExtensionPtrConstructor (*GDExtensionInterfaceVariantGetPtrConstructor
/**
* @name variant_get_ptr_destructor
+ * @since 4.1
*
* Gets a pointer to a function than can call the destructor for a type of Variant.
*
@@ -1078,6 +1125,7 @@ typedef GDExtensionPtrDestructor (*GDExtensionInterfaceVariantGetPtrDestructor)(
/**
* @name variant_construct
+ * @since 4.1
*
* Constructs a Variant of the given type, using the first constructor that matches the given arguments.
*
@@ -1091,6 +1139,7 @@ typedef void (*GDExtensionInterfaceVariantConstruct)(GDExtensionVariantType p_ty
/**
* @name variant_get_ptr_setter
+ * @since 4.1
*
* Gets a pointer to a function that can call a member's setter on the given Variant type.
*
@@ -1103,6 +1152,7 @@ typedef GDExtensionPtrSetter (*GDExtensionInterfaceVariantGetPtrSetter)(GDExtens
/**
* @name variant_get_ptr_getter
+ * @since 4.1
*
* Gets a pointer to a function that can call a member's getter on the given Variant type.
*
@@ -1115,6 +1165,7 @@ typedef GDExtensionPtrGetter (*GDExtensionInterfaceVariantGetPtrGetter)(GDExtens
/**
* @name variant_get_ptr_indexed_setter
+ * @since 4.1
*
* Gets a pointer to a function that can set an index on the given Variant type.
*
@@ -1126,6 +1177,7 @@ typedef GDExtensionPtrIndexedSetter (*GDExtensionInterfaceVariantGetPtrIndexedSe
/**
* @name variant_get_ptr_indexed_getter
+ * @since 4.1
*
* Gets a pointer to a function that can get an index on the given Variant type.
*
@@ -1137,6 +1189,7 @@ typedef GDExtensionPtrIndexedGetter (*GDExtensionInterfaceVariantGetPtrIndexedGe
/**
* @name variant_get_ptr_keyed_setter
+ * @since 4.1
*
* Gets a pointer to a function that can set a key on the given Variant type.
*
@@ -1148,6 +1201,7 @@ typedef GDExtensionPtrKeyedSetter (*GDExtensionInterfaceVariantGetPtrKeyedSetter
/**
* @name variant_get_ptr_keyed_getter
+ * @since 4.1
*
* Gets a pointer to a function that can get a key on the given Variant type.
*
@@ -1159,6 +1213,7 @@ typedef GDExtensionPtrKeyedGetter (*GDExtensionInterfaceVariantGetPtrKeyedGetter
/**
* @name variant_get_ptr_keyed_checker
+ * @since 4.1
*
* Gets a pointer to a function that can check a key on the given Variant type.
*
@@ -1170,6 +1225,7 @@ typedef GDExtensionPtrKeyedChecker (*GDExtensionInterfaceVariantGetPtrKeyedCheck
/**
* @name variant_get_constant_value
+ * @since 4.1
*
* Gets the value of a constant from the given Variant type.
*
@@ -1181,6 +1237,7 @@ typedef void (*GDExtensionInterfaceVariantGetConstantValue)(GDExtensionVariantTy
/**
* @name variant_get_ptr_utility_function
+ * @since 4.1
*
* Gets a pointer to a function that can call a Variant utility function.
*
@@ -1195,6 +1252,7 @@ typedef GDExtensionPtrUtilityFunction (*GDExtensionInterfaceVariantGetPtrUtility
/**
* @name string_new_with_latin1_chars
+ * @since 4.1
*
* Creates a String from a Latin-1 encoded C string.
*
@@ -1205,6 +1263,7 @@ typedef void (*GDExtensionInterfaceStringNewWithLatin1Chars)(GDExtensionUninitia
/**
* @name string_new_with_utf8_chars
+ * @since 4.1
*
* Creates a String from a UTF-8 encoded C string.
*
@@ -1215,6 +1274,7 @@ typedef void (*GDExtensionInterfaceStringNewWithUtf8Chars)(GDExtensionUninitiali
/**
* @name string_new_with_utf16_chars
+ * @since 4.1
*
* Creates a String from a UTF-16 encoded C string.
*
@@ -1225,6 +1285,7 @@ typedef void (*GDExtensionInterfaceStringNewWithUtf16Chars)(GDExtensionUninitial
/**
* @name string_new_with_utf32_chars
+ * @since 4.1
*
* Creates a String from a UTF-32 encoded C string.
*
@@ -1235,6 +1296,7 @@ typedef void (*GDExtensionInterfaceStringNewWithUtf32Chars)(GDExtensionUninitial
/**
* @name string_new_with_wide_chars
+ * @since 4.1
*
* Creates a String from a wide C string.
*
@@ -1245,6 +1307,7 @@ typedef void (*GDExtensionInterfaceStringNewWithWideChars)(GDExtensionUninitiali
/**
* @name string_new_with_latin1_chars_and_len
+ * @since 4.1
*
* Creates a String from a Latin-1 encoded C string with the given length.
*
@@ -1256,6 +1319,7 @@ typedef void (*GDExtensionInterfaceStringNewWithLatin1CharsAndLen)(GDExtensionUn
/**
* @name string_new_with_utf8_chars_and_len
+ * @since 4.1
*
* Creates a String from a UTF-8 encoded C string with the given length.
*
@@ -1267,6 +1331,7 @@ typedef void (*GDExtensionInterfaceStringNewWithUtf8CharsAndLen)(GDExtensionUnin
/**
* @name string_new_with_utf16_chars_and_len
+ * @since 4.1
*
* Creates a String from a UTF-16 encoded C string with the given length.
*
@@ -1278,6 +1343,7 @@ typedef void (*GDExtensionInterfaceStringNewWithUtf16CharsAndLen)(GDExtensionUni
/**
* @name string_new_with_utf32_chars_and_len
+ * @since 4.1
*
* Creates a String from a UTF-32 encoded C string with the given length.
*
@@ -1289,6 +1355,7 @@ typedef void (*GDExtensionInterfaceStringNewWithUtf32CharsAndLen)(GDExtensionUni
/**
* @name string_new_with_wide_chars_and_len
+ * @since 4.1
*
* Creates a String from a wide C string with the given length.
*
@@ -1300,6 +1367,7 @@ typedef void (*GDExtensionInterfaceStringNewWithWideCharsAndLen)(GDExtensionUnin
/**
* @name string_to_latin1_chars
+ * @since 4.1
*
* Converts a String to a Latin-1 encoded C string.
*
@@ -1315,6 +1383,7 @@ typedef GDExtensionInt (*GDExtensionInterfaceStringToLatin1Chars)(GDExtensionCon
/**
* @name string_to_utf8_chars
+ * @since 4.1
*
* Converts a String to a UTF-8 encoded C string.
*
@@ -1330,6 +1399,7 @@ typedef GDExtensionInt (*GDExtensionInterfaceStringToUtf8Chars)(GDExtensionConst
/**
* @name string_to_utf16_chars
+ * @since 4.1
*
* Converts a String to a UTF-16 encoded C string.
*
@@ -1345,6 +1415,7 @@ typedef GDExtensionInt (*GDExtensionInterfaceStringToUtf16Chars)(GDExtensionCons
/**
* @name string_to_utf32_chars
+ * @since 4.1
*
* Converts a String to a UTF-32 encoded C string.
*
@@ -1360,6 +1431,7 @@ typedef GDExtensionInt (*GDExtensionInterfaceStringToUtf32Chars)(GDExtensionCons
/**
* @name string_to_wide_chars
+ * @since 4.1
*
* Converts a String to a wide C string.
*
@@ -1375,6 +1447,7 @@ typedef GDExtensionInt (*GDExtensionInterfaceStringToWideChars)(GDExtensionConst
/**
* @name string_operator_index
+ * @since 4.1
*
* Gets a pointer to the character at the given index from a String.
*
@@ -1387,6 +1460,7 @@ typedef char32_t *(*GDExtensionInterfaceStringOperatorIndex)(GDExtensionStringPt
/**
* @name string_operator_index_const
+ * @since 4.1
*
* Gets a const pointer to the character at the given index from a String.
*
@@ -1399,6 +1473,7 @@ typedef const char32_t *(*GDExtensionInterfaceStringOperatorIndexConst)(GDExtens
/**
* @name string_operator_plus_eq_string
+ * @since 4.1
*
* Appends another String to a String.
*
@@ -1409,6 +1484,7 @@ typedef void (*GDExtensionInterfaceStringOperatorPlusEqString)(GDExtensionString
/**
* @name string_operator_plus_eq_char
+ * @since 4.1
*
* Appends a character to a String.
*
@@ -1419,6 +1495,7 @@ typedef void (*GDExtensionInterfaceStringOperatorPlusEqChar)(GDExtensionStringPt
/**
* @name string_operator_plus_eq_cstr
+ * @since 4.1
*
* Appends a Latin-1 encoded C string to a String.
*
@@ -1429,6 +1506,7 @@ typedef void (*GDExtensionInterfaceStringOperatorPlusEqCstr)(GDExtensionStringPt
/**
* @name string_operator_plus_eq_wcstr
+ * @since 4.1
*
* Appends a wide C string to a String.
*
@@ -1439,6 +1517,7 @@ typedef void (*GDExtensionInterfaceStringOperatorPlusEqWcstr)(GDExtensionStringP
/**
* @name string_operator_plus_eq_c32str
+ * @since 4.1
*
* Appends a UTF-32 encoded C string to a String.
*
@@ -1451,6 +1530,7 @@ typedef void (*GDExtensionInterfaceStringOperatorPlusEqC32str)(GDExtensionString
/**
* @name xml_parser_open_buffer
+ * @since 4.1
*
* Opens a raw XML buffer on an XMLParser instance.
*
@@ -1468,6 +1548,7 @@ typedef GDExtensionInt (*GDExtensionInterfaceXmlParserOpenBuffer)(GDExtensionObj
/**
* @name file_access_store_buffer
+ * @since 4.1
*
* Stores the given buffer using an instance of FileAccess.
*
@@ -1481,6 +1562,7 @@ typedef void (*GDExtensionInterfaceFileAccessStoreBuffer)(GDExtensionObjectPtr p
/**
* @name file_access_get_buffer
+ * @since 4.1
*
* Reads the next p_length bytes into the given buffer using an instance of FileAccess.
*
@@ -1496,6 +1578,7 @@ typedef uint64_t (*GDExtensionInterfaceFileAccessGetBuffer)(GDExtensionConstObje
/**
* @name worker_thread_pool_add_native_group_task
+ * @since 4.1
*
* Adds a group task to an instance of WorkerThreadPool.
*
@@ -1514,6 +1597,7 @@ typedef int64_t (*GDExtensionInterfaceWorkerThreadPoolAddNativeGroupTask)(GDExte
/**
* @name worker_thread_pool_add_native_task
+ * @since 4.1
*
* Adds a task to an instance of WorkerThreadPool.
*
@@ -1531,6 +1615,7 @@ typedef int64_t (*GDExtensionInterfaceWorkerThreadPoolAddNativeTask)(GDExtension
/**
* @name packed_byte_array_operator_index
+ * @since 4.1
*
* Gets a pointer to a byte in a PackedByteArray.
*
@@ -1543,6 +1628,7 @@ typedef uint8_t *(*GDExtensionInterfacePackedByteArrayOperatorIndex)(GDExtension
/**
* @name packed_byte_array_operator_index_const
+ * @since 4.1
*
* Gets a const pointer to a byte in a PackedByteArray.
*
@@ -1555,6 +1641,7 @@ typedef const uint8_t *(*GDExtensionInterfacePackedByteArrayOperatorIndexConst)(
/**
* @name packed_color_array_operator_index
+ * @since 4.1
*
* Gets a pointer to a color in a PackedColorArray.
*
@@ -1567,6 +1654,7 @@ typedef GDExtensionTypePtr (*GDExtensionInterfacePackedColorArrayOperatorIndex)(
/**
* @name packed_color_array_operator_index_const
+ * @since 4.1
*
* Gets a const pointer to a color in a PackedColorArray.
*
@@ -1579,6 +1667,7 @@ typedef GDExtensionTypePtr (*GDExtensionInterfacePackedColorArrayOperatorIndexCo
/**
* @name packed_float32_array_operator_index
+ * @since 4.1
*
* Gets a pointer to a 32-bit float in a PackedFloat32Array.
*
@@ -1591,6 +1680,7 @@ typedef float *(*GDExtensionInterfacePackedFloat32ArrayOperatorIndex)(GDExtensio
/**
* @name packed_float32_array_operator_index_const
+ * @since 4.1
*
* Gets a const pointer to a 32-bit float in a PackedFloat32Array.
*
@@ -1603,6 +1693,7 @@ typedef const float *(*GDExtensionInterfacePackedFloat32ArrayOperatorIndexConst)
/**
* @name packed_float64_array_operator_index
+ * @since 4.1
*
* Gets a pointer to a 64-bit float in a PackedFloat64Array.
*
@@ -1615,6 +1706,7 @@ typedef double *(*GDExtensionInterfacePackedFloat64ArrayOperatorIndex)(GDExtensi
/**
* @name packed_float64_array_operator_index_const
+ * @since 4.1
*
* Gets a const pointer to a 64-bit float in a PackedFloat64Array.
*
@@ -1627,6 +1719,7 @@ typedef const double *(*GDExtensionInterfacePackedFloat64ArrayOperatorIndexConst
/**
* @name packed_int32_array_operator_index
+ * @since 4.1
*
* Gets a pointer to a 32-bit integer in a PackedInt32Array.
*
@@ -1639,6 +1732,7 @@ typedef int32_t *(*GDExtensionInterfacePackedInt32ArrayOperatorIndex)(GDExtensio
/**
* @name packed_int32_array_operator_index_const
+ * @since 4.1
*
* Gets a const pointer to a 32-bit integer in a PackedInt32Array.
*
@@ -1651,6 +1745,7 @@ typedef const int32_t *(*GDExtensionInterfacePackedInt32ArrayOperatorIndexConst)
/**
* @name packed_int64_array_operator_index
+ * @since 4.1
*
* Gets a pointer to a 64-bit integer in a PackedInt64Array.
*
@@ -1663,6 +1758,7 @@ typedef int64_t *(*GDExtensionInterfacePackedInt64ArrayOperatorIndex)(GDExtensio
/**
* @name packed_int64_array_operator_index_const
+ * @since 4.1
*
* Gets a const pointer to a 64-bit integer in a PackedInt64Array.
*
@@ -1675,6 +1771,7 @@ typedef const int64_t *(*GDExtensionInterfacePackedInt64ArrayOperatorIndexConst)
/**
* @name packed_string_array_operator_index
+ * @since 4.1
*
* Gets a pointer to a string in a PackedStringArray.
*
@@ -1687,6 +1784,7 @@ typedef GDExtensionStringPtr (*GDExtensionInterfacePackedStringArrayOperatorInde
/**
* @name packed_string_array_operator_index_const
+ * @since 4.1
*
* Gets a const pointer to a string in a PackedStringArray.
*
@@ -1699,6 +1797,7 @@ typedef GDExtensionStringPtr (*GDExtensionInterfacePackedStringArrayOperatorInde
/**
* @name packed_vector2_array_operator_index
+ * @since 4.1
*
* Gets a pointer to a Vector2 in a PackedVector2Array.
*
@@ -1711,6 +1810,7 @@ typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector2ArrayOperatorIndex
/**
* @name packed_vector2_array_operator_index_const
+ * @since 4.1
*
* Gets a const pointer to a Vector2 in a PackedVector2Array.
*
@@ -1723,6 +1823,7 @@ typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector2ArrayOperatorIndex
/**
* @name packed_vector3_array_operator_index
+ * @since 4.1
*
* Gets a pointer to a Vector3 in a PackedVector3Array.
*
@@ -1735,6 +1836,7 @@ typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector3ArrayOperatorIndex
/**
* @name packed_vector3_array_operator_index_const
+ * @since 4.1
*
* Gets a const pointer to a Vector3 in a PackedVector3Array.
*
@@ -1747,6 +1849,7 @@ typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector3ArrayOperatorIndex
/**
* @name array_operator_index
+ * @since 4.1
*
* Gets a pointer to a Variant in an Array.
*
@@ -1759,6 +1862,7 @@ typedef GDExtensionVariantPtr (*GDExtensionInterfaceArrayOperatorIndex)(GDExtens
/**
* @name array_operator_index_const
+ * @since 4.1
*
* Gets a const pointer to a Variant in an Array.
*
@@ -1771,6 +1875,7 @@ typedef GDExtensionVariantPtr (*GDExtensionInterfaceArrayOperatorIndexConst)(GDE
/**
* @name array_ref
+ * @since 4.1
*
* Sets an Array to be a reference to another Array object.
*
@@ -1781,6 +1886,7 @@ typedef void (*GDExtensionInterfaceArrayRef)(GDExtensionTypePtr p_self, GDExtens
/**
* @name array_set_typed
+ * @since 4.1
*
* Makes an Array into a typed Array.
*
@@ -1795,6 +1901,7 @@ typedef void (*GDExtensionInterfaceArraySetTyped)(GDExtensionTypePtr p_self, GDE
/**
* @name dictionary_operator_index
+ * @since 4.1
*
* Gets a pointer to a Variant in a Dictionary with the given key.
*
@@ -1807,6 +1914,7 @@ typedef GDExtensionVariantPtr (*GDExtensionInterfaceDictionaryOperatorIndex)(GDE
/**
* @name dictionary_operator_index_const
+ * @since 4.1
*
* Gets a const pointer to a Variant in a Dictionary with the given key.
*
@@ -1821,6 +1929,7 @@ typedef GDExtensionVariantPtr (*GDExtensionInterfaceDictionaryOperatorIndexConst
/**
* @name object_method_bind_call
+ * @since 4.1
*
* Calls a method on an Object.
*
@@ -1835,6 +1944,7 @@ typedef void (*GDExtensionInterfaceObjectMethodBindCall)(GDExtensionMethodBindPt
/**
* @name object_method_bind_ptrcall
+ * @since 4.1
*
* Calls a method on an Object (using a "ptrcall").
*
@@ -1847,6 +1957,7 @@ typedef void (*GDExtensionInterfaceObjectMethodBindPtrcall)(GDExtensionMethodBin
/**
* @name object_destroy
+ * @since 4.1
*
* Destroys an Object.
*
@@ -1856,6 +1967,7 @@ typedef void (*GDExtensionInterfaceObjectDestroy)(GDExtensionObjectPtr p_o);
/**
* @name global_get_singleton
+ * @since 4.1
*
* Gets a global singleton by name.
*
@@ -1867,6 +1979,7 @@ typedef GDExtensionObjectPtr (*GDExtensionInterfaceGlobalGetSingleton)(GDExtensi
/**
* @name object_get_instance_binding
+ * @since 4.1
*
* Gets a pointer representing an Object's instance binding.
*
@@ -1880,6 +1993,7 @@ typedef void *(*GDExtensionInterfaceObjectGetInstanceBinding)(GDExtensionObjectP
/**
* @name object_set_instance_binding
+ * @since 4.1
*
* Sets an Object's instance binding.
*
@@ -1892,6 +2006,7 @@ typedef void (*GDExtensionInterfaceObjectSetInstanceBinding)(GDExtensionObjectPt
/**
* @name object_set_instance
+ * @since 4.1
*
* Sets an extension class instance on a Object.
*
@@ -1903,6 +2018,7 @@ typedef void (*GDExtensionInterfaceObjectSetInstance)(GDExtensionObjectPtr p_o,
/**
* @name object_get_class_name
+ * @since 4.1
*
* Gets the class name of an Object.
*
@@ -1916,6 +2032,7 @@ typedef GDExtensionBool (*GDExtensionInterfaceObjectGetClassName)(GDExtensionCon
/**
* @name object_cast_to
+ * @since 4.1
*
* Casts an Object to a different type.
*
@@ -1928,6 +2045,7 @@ typedef GDExtensionObjectPtr (*GDExtensionInterfaceObjectCastTo)(GDExtensionCons
/**
* @name object_get_instance_from_id
+ * @since 4.1
*
* Gets an Object by its instance ID.
*
@@ -1939,6 +2057,7 @@ typedef GDExtensionObjectPtr (*GDExtensionInterfaceObjectGetInstanceFromId)(GDOb
/**
* @name object_get_instance_id
+ * @since 4.1
*
* Gets the instance ID from an Object.
*
@@ -1952,6 +2071,7 @@ typedef GDObjectInstanceID (*GDExtensionInterfaceObjectGetInstanceId)(GDExtensio
/**
* @name ref_get_object
+ * @since 4.1
*
* Gets the Object from a reference.
*
@@ -1963,6 +2083,7 @@ typedef GDExtensionObjectPtr (*GDExtensionInterfaceRefGetObject)(GDExtensionCons
/**
* @name ref_set_object
+ * @since 4.1
*
* Sets the Object referred to by a reference.
*
@@ -1975,6 +2096,7 @@ typedef void (*GDExtensionInterfaceRefSetObject)(GDExtensionRefPtr p_ref, GDExte
/**
* @name script_instance_create
+ * @since 4.1
*
* Creates a script instance that contains the given info and instance data.
*
@@ -1989,6 +2111,7 @@ typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate)
/**
* @name classdb_construct_object
+ * @since 4.1
*
* Constructs an Object of the requested class.
*
@@ -2002,6 +2125,7 @@ typedef GDExtensionObjectPtr (*GDExtensionInterfaceClassdbConstructObject)(GDExt
/**
* @name classdb_get_method_bind
+ * @since 4.1
*
* Gets a pointer to the MethodBind in ClassDB for the given class, method and hash.
*
@@ -2015,6 +2139,7 @@ typedef GDExtensionMethodBindPtr (*GDExtensionInterfaceClassdbGetMethodBind)(GDE
/**
* @name classdb_get_class_tag
+ * @since 4.1
*
* Gets a pointer uniquely identifying the given built-in class in the ClassDB.
*
@@ -2028,6 +2153,7 @@ typedef void *(*GDExtensionInterfaceClassdbGetClassTag)(GDExtensionConstStringNa
/**
* @name classdb_register_extension_class
+ * @since 4.1
*
* Registers an extension class in the ClassDB.
*
@@ -2042,6 +2168,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass)(GDExtensionCla
/**
* @name classdb_register_extension_class_method
+ * @since 4.1
*
* Registers a method on an extension class in the ClassDB.
*
@@ -2055,6 +2182,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassMethod)(GDExtens
/**
* @name classdb_register_extension_class_integer_constant
+ * @since 4.1
*
* Registers an integer constant on an extension class in the ClassDB.
*
@@ -2069,6 +2197,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant)
/**
* @name classdb_register_extension_class_property
+ * @since 4.1
*
* Registers a property on an extension class in the ClassDB.
*
@@ -2084,6 +2213,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassProperty)(GDExte
/**
* @name classdb_register_extension_class_property_group
+ * @since 4.1
*
* Registers a property group on an extension class in the ClassDB.
*
@@ -2096,6 +2226,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassPropertyGroup)(G
/**
* @name classdb_register_extension_class_property_subgroup
+ * @since 4.1
*
* Registers a property subgroup on an extension class in the ClassDB.
*
@@ -2108,6 +2239,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassPropertySubgroup
/**
* @name classdb_register_extension_class_signal
+ * @since 4.1
*
* Registers a signal on an extension class in the ClassDB.
*
@@ -2123,6 +2255,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassSignal)(GDExtens
/**
* @name classdb_unregister_extension_class
+ * @since 4.1
*
* Unregisters an extension class in the ClassDB.
*
@@ -2133,6 +2266,7 @@ typedef void (*GDExtensionInterfaceClassdbUnregisterExtensionClass)(GDExtensionC
/**
* @name get_library_path
+ * @since 4.1
*
* Gets the path to the current GDExtension library.
*
@@ -2143,6 +2277,7 @@ typedef void (*GDExtensionInterfaceGetLibraryPath)(GDExtensionClassLibraryPtr p_
/**
* @name editor_add_plugin
+ * @since 4.1
*
* Adds an editor plugin.
*
@@ -2154,6 +2289,7 @@ typedef void (*GDExtensionInterfaceEditorAddPlugin)(GDExtensionConstStringNamePt
/**
* @name editor_remove_plugin
+ * @since 4.1
*
* Removes an editor plugin.
*
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index 9d39cbf1a5..d3445b8cc0 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -3097,16 +3097,6 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_a
bool is_constructor = (base_type.is_meta_type || (p_call->callee && p_call->callee->type == GDScriptParser::Node::IDENTIFIER)) && p_call->function_name == SNAME("new");
if (get_function_signature(p_call, is_constructor, base_type, p_call->function_name, return_type, par_types, default_arg_count, method_flags)) {
- // If the method is implemented in the class hierarchy, the virtual flag will not be set for that MethodInfo and the search stops there.
- // MethodInfo's above the class that defines the method might still have the virtual flag set.
- if (method_flags.has_flag(METHOD_FLAG_VIRTUAL)) {
- if (p_call->is_super) {
- push_error(vformat(R"*(Cannot call the parent class' virtual function "%s()" because it hasn't been defined.)*", p_call->function_name), p_call);
- } else {
- push_error(vformat(R"*(Cannot call virtual function "%s()" because it hasn't been defined.)*", p_call->function_name), p_call);
- }
- }
-
// If the function require typed arrays we must make literals be typed.
for (const KeyValue<int, GDScriptParser::ArrayNode *> &E : arrays) {
int index = E.key;
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 90ee56b9de..004af80a91 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -1767,25 +1767,39 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_match_pattern(CodeGen &c
ERR_FAIL_V_MSG(p_previous_test, "Reaching the end of pattern compilation without matching a pattern.");
}
-void GDScriptCompiler::_add_locals_in_block(CodeGen &codegen, const GDScriptParser::SuiteNode *p_block) {
+List<GDScriptCodeGenerator::Address> GDScriptCompiler::_add_locals_in_block(CodeGen &codegen, const GDScriptParser::SuiteNode *p_block) {
+ List<GDScriptCodeGenerator::Address> addresses;
for (int i = 0; i < p_block->locals.size(); i++) {
if (p_block->locals[i].type == GDScriptParser::SuiteNode::Local::PARAMETER || p_block->locals[i].type == GDScriptParser::SuiteNode::Local::FOR_VARIABLE) {
// Parameters are added directly from function and loop variables are declared explicitly.
continue;
}
- codegen.add_local(p_block->locals[i].name, _gdtype_from_datatype(p_block->locals[i].get_datatype(), codegen.script));
+ addresses.push_back(codegen.add_local(p_block->locals[i].name, _gdtype_from_datatype(p_block->locals[i].get_datatype(), codegen.script)));
}
+ return addresses;
}
-Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::SuiteNode *p_block, bool p_add_locals) {
+// Avoid keeping in the stack long-lived references to objects, which may prevent RefCounted objects from being freed.
+void GDScriptCompiler::_clear_addresses(CodeGen &codegen, const List<GDScriptCodeGenerator::Address> &p_addresses) {
+ for (const List<GDScriptCodeGenerator::Address>::Element *E = p_addresses.front(); E; E = E->next()) {
+ GDScriptDataType type = E->get().type;
+ // If not an object and cannot contain an object, no need to clear.
+ if (type.kind != GDScriptDataType::BUILTIN || type.builtin_type == Variant::ARRAY || type.builtin_type == Variant::DICTIONARY) {
+ codegen.generator->write_assign_false(E->get());
+ }
+ }
+}
+
+Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::SuiteNode *p_block, bool p_add_locals, bool p_reset_locals) {
Error err = OK;
GDScriptCodeGenerator *gen = codegen.generator;
+ List<GDScriptCodeGenerator::Address> block_locals;
gen->clean_temporaries();
codegen.start_block();
if (p_add_locals) {
- _add_locals_in_block(codegen, p_block);
+ block_locals = _add_locals_in_block(codegen, p_block);
}
for (int i = 0; i < p_block->statements.size(); i++) {
@@ -1841,7 +1855,7 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Sui
codegen.start_block(); // Create an extra block around for binds.
// Add locals in block before patterns, so temporaries don't use the stack address for binds.
- _add_locals_in_block(codegen, branch->block);
+ List<GDScriptCodeGenerator::Address> branch_locals = _add_locals_in_block(codegen, branch->block);
#ifdef DEBUG_ENABLED
// Add a newline before each branch, since the debugger needs those.
@@ -1868,6 +1882,8 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Sui
return err;
}
+ _clear_addresses(codegen, branch_locals);
+
codegen.end_block(); // Get out of extra block.
}
@@ -2052,7 +2068,7 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Sui
}
// Assigns a null for the unassigned variables in loops.
- if (!initialized && p_block->is_loop) {
+ if (!initialized && p_block->is_in_loop) {
codegen.generator->write_construct(local, Variant::NIL, Vector<GDScriptCodeGenerator::Address>());
}
} break;
@@ -2088,6 +2104,10 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Sui
gen->clean_temporaries();
}
+ if (p_add_locals && p_reset_locals) {
+ _clear_addresses(codegen, block_locals);
+ }
+
codegen.end_block();
return OK;
}
@@ -2241,7 +2261,8 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_
codegen.generator->end_parameters();
}
- r_error = _parse_block(codegen, p_func->body);
+ // No need to reset locals at the end of the function, the stack will be cleared anyway.
+ r_error = _parse_block(codegen, p_func->body, true, false);
if (r_error) {
memdelete(codegen.generator);
return nullptr;
diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h
index 494eef41d9..2f522da4ea 100644
--- a/modules/gdscript/gdscript_compiler.h
+++ b/modules/gdscript/gdscript_compiler.h
@@ -129,8 +129,9 @@ class GDScriptCompiler {
GDScriptCodeGenerator::Address _parse_assign_right_expression(CodeGen &codegen, Error &r_error, const GDScriptParser::AssignmentNode *p_assignmentint, const GDScriptCodeGenerator::Address &p_index_addr = GDScriptCodeGenerator::Address());
GDScriptCodeGenerator::Address _parse_expression(CodeGen &codegen, Error &r_error, const GDScriptParser::ExpressionNode *p_expression, bool p_root = false, bool p_initializer = false, const GDScriptCodeGenerator::Address &p_index_addr = GDScriptCodeGenerator::Address());
GDScriptCodeGenerator::Address _parse_match_pattern(CodeGen &codegen, Error &r_error, const GDScriptParser::PatternNode *p_pattern, const GDScriptCodeGenerator::Address &p_value_addr, const GDScriptCodeGenerator::Address &p_type_addr, const GDScriptCodeGenerator::Address &p_previous_test, bool p_is_first, bool p_is_nested);
- void _add_locals_in_block(CodeGen &codegen, const GDScriptParser::SuiteNode *p_block);
- Error _parse_block(CodeGen &codegen, const GDScriptParser::SuiteNode *p_block, bool p_add_locals = true);
+ List<GDScriptCodeGenerator::Address> _add_locals_in_block(CodeGen &codegen, const GDScriptParser::SuiteNode *p_block);
+ void _clear_addresses(CodeGen &codegen, const List<GDScriptCodeGenerator::Address> &p_addresses);
+ Error _parse_block(CodeGen &codegen, const GDScriptParser::SuiteNode *p_block, bool p_add_locals = true, bool p_reset_locals = true);
GDScriptFunction *_parse_function(Error &r_error, GDScript *p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::FunctionNode *p_func, bool p_for_ready = false, bool p_for_lambda = false);
GDScriptFunction *_make_static_initializer(Error &r_error, GDScript *p_script, const GDScriptParser::ClassNode *p_class);
Error _parse_setter_getter(GDScript *p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::VariableNode *p_variable, bool p_is_setter);
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index cf750958ee..e17ee0668f 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -1536,6 +1536,11 @@ GDScriptParser::SuiteNode *GDScriptParser::parse_suite(const String &p_context,
suite->parent_function = current_function;
current_suite = suite;
+ if (!p_for_lambda && suite->parent_block != nullptr && suite->parent_block->is_in_loop) {
+ // Do not reset to false if true is set before calling parse_suite().
+ suite->is_in_loop = true;
+ }
+
bool multiline = false;
if (match(GDScriptTokenizer::Token::NEWLINE)) {
@@ -1871,9 +1876,8 @@ GDScriptParser::ForNode *GDScriptParser::parse_for() {
}
suite->add_local(SuiteNode::Local(n_for->variable, current_function));
}
-
+ suite->is_in_loop = true;
n_for->loop = parse_suite(R"("for" block)", suite);
- n_for->loop->is_loop = true;
complete_extents(n_for);
// Reset break/continue state.
@@ -2186,8 +2190,9 @@ GDScriptParser::WhileNode *GDScriptParser::parse_while() {
can_break = true;
can_continue = true;
- n_while->loop = parse_suite(R"("while" block)");
- n_while->loop->is_loop = true;
+ SuiteNode *suite = alloc_node<SuiteNode>();
+ suite->is_in_loop = true;
+ n_while->loop = parse_suite(R"("while" block)", suite);
complete_extents(n_while);
// Reset break/continue state.
@@ -2231,7 +2236,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_precedence(Precedence p_pr
ExpressionNode *previous_operand = (this->*prefix_rule)(nullptr, p_can_assign);
while (p_precedence <= get_rule(current.type)->precedence) {
- if (previous_operand == nullptr || (p_stop_on_assign && current.type == GDScriptTokenizer::Token::EQUAL) || (previous_operand->type == Node::LAMBDA && lambda_ended)) {
+ if (previous_operand == nullptr || (p_stop_on_assign && current.type == GDScriptTokenizer::Token::EQUAL) || lambda_ended) {
return previous_operand;
}
// Also switch multiline mode on here for infix operators.
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index ad08c3bfd6..18757eb9fd 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -1121,7 +1121,7 @@ public:
bool has_return = false;
bool has_continue = false;
bool has_unreachable_code = false; // Just so warnings aren't given more than once per block.
- bool is_loop = false;
+ bool is_in_loop = false; // The block is nested in a loop (directly or indirectly).
bool has_local(const StringName &p_name) const;
const Local &get_local(const StringName &p_name) const;
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/virtual_method_not_implemented.gd b/modules/gdscript/tests/scripts/analyzer/errors/virtual_method_not_implemented.gd
deleted file mode 100644
index c34d927035..0000000000
--- a/modules/gdscript/tests/scripts/analyzer/errors/virtual_method_not_implemented.gd
+++ /dev/null
@@ -1,2 +0,0 @@
-func test():
- _get_property_list()
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/virtual_method_not_implemented.out b/modules/gdscript/tests/scripts/analyzer/errors/virtual_method_not_implemented.out
deleted file mode 100644
index ce2f49a5e5..0000000000
--- a/modules/gdscript/tests/scripts/analyzer/errors/virtual_method_not_implemented.out
+++ /dev/null
@@ -1,2 +0,0 @@
-GDTEST_ANALYZER_ERROR
-Cannot call virtual function "_get_property_list()" because it hasn't been defined.
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/virtual_super_not_implemented.gd b/modules/gdscript/tests/scripts/analyzer/errors/virtual_super_not_implemented.gd
deleted file mode 100644
index 57dfffdbee..0000000000
--- a/modules/gdscript/tests/scripts/analyzer/errors/virtual_super_not_implemented.gd
+++ /dev/null
@@ -1,5 +0,0 @@
-func _init():
- super()
-
-func test():
- pass
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/virtual_super_not_implemented.out b/modules/gdscript/tests/scripts/analyzer/errors/virtual_super_not_implemented.out
deleted file mode 100644
index e68759223c..0000000000
--- a/modules/gdscript/tests/scripts/analyzer/errors/virtual_super_not_implemented.out
+++ /dev/null
@@ -1,2 +0,0 @@
-GDTEST_ANALYZER_ERROR
-Cannot call the parent class' virtual function "_init()" because it hasn't been defined.
diff --git a/modules/gdscript/tests/scripts/analyzer/features/virtual_method_implemented.gd b/modules/gdscript/tests/scripts/analyzer/features/virtual_method_implemented.gd
deleted file mode 100644
index 1aacd1d11c..0000000000
--- a/modules/gdscript/tests/scripts/analyzer/features/virtual_method_implemented.gd
+++ /dev/null
@@ -1,11 +0,0 @@
-class TestOne:
- func _get_property_list():
- return {}
-
-class TestTwo extends TestOne:
- func _init():
- var _x = _get_property_list()
-
-func test():
- var x = TestTwo.new()
- var _x = x._get_property_list()
diff --git a/modules/gdscript/tests/scripts/analyzer/features/virtual_super_implemented.gd b/modules/gdscript/tests/scripts/analyzer/features/virtual_super_implemented.gd
deleted file mode 100644
index c447003619..0000000000
--- a/modules/gdscript/tests/scripts/analyzer/features/virtual_super_implemented.gd
+++ /dev/null
@@ -1,10 +0,0 @@
-class TestOne:
- func _init():
- pass
-
-class TestTwo extends TestOne:
- func _init():
- super()
-
-func test():
- pass
diff --git a/modules/gdscript/tests/scripts/analyzer/features/virtual_super_implemented.out b/modules/gdscript/tests/scripts/analyzer/features/virtual_super_implemented.out
deleted file mode 100644
index d73c5eb7cd..0000000000
--- a/modules/gdscript/tests/scripts/analyzer/features/virtual_super_implemented.out
+++ /dev/null
@@ -1 +0,0 @@
-GDTEST_OK
diff --git a/modules/gdscript/tests/scripts/parser/errors/lambda_no_continue_on_new_line.gd b/modules/gdscript/tests/scripts/parser/errors/lambda_no_continue_on_new_line.gd
new file mode 100644
index 0000000000..8c5fb46109
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/errors/lambda_no_continue_on_new_line.gd
@@ -0,0 +1,6 @@
+# https://github.com/godotengine/godot/issues/73273
+
+func not_called():
+ var v
+ v=func(): v=1
+ in v
diff --git a/modules/gdscript/tests/scripts/parser/errors/lambda_no_continue_on_new_line.out b/modules/gdscript/tests/scripts/parser/errors/lambda_no_continue_on_new_line.out
new file mode 100644
index 0000000000..539240f790
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/errors/lambda_no_continue_on_new_line.out
@@ -0,0 +1,2 @@
+GDTEST_PARSER_ERROR
+Expected statement, found "in" instead.
diff --git a/modules/gdscript/tests/scripts/parser/features/lambda_ends_with_new_line.gd b/modules/gdscript/tests/scripts/parser/features/lambda_ends_with_new_line.gd
new file mode 100644
index 0000000000..df6001c7e2
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/features/lambda_ends_with_new_line.gd
@@ -0,0 +1,59 @@
+# https://github.com/godotengine/godot/issues/73273
+
+func other(callable : Callable):
+ callable.call()
+
+func four_parameters(_a, callable : Callable, b=func(): print(10)):
+ callable.call()
+ b.call()
+
+func test():
+ var v
+ v=func():v=1
+ if true: v=1
+ print(v)
+ print()
+
+ v=func(): print(2) if false else print(3)
+ @warning_ignore("unsafe_cast")
+ (v as Callable).call()
+ print()
+
+ v=func():
+ print(4)
+ print(5)
+ @warning_ignore("unsafe_cast")
+ if true: (v as Callable).call()
+ print()
+
+ other(v)
+ print()
+
+ other(func(): print(6))
+ print()
+
+ other(func():
+ print(7)
+ print(8)
+ )
+ print()
+
+ four_parameters(1,func():print(9))
+ four_parameters(1,func():print(9), func(): print(11))
+ four_parameters(1,func():
+ print(12)
+ print(13)
+ , func(): print(11))
+ print()
+
+ from_ticket()
+
+func from_ticket():
+ var _v
+ if true: _v = (func(): test())
+ if true: _v = (func(): test())
+ if true: _v = (func(): test())
+
+ if true: _v = func(): test()
+ if true: _v = func(): test()
+ print(14)
diff --git a/modules/gdscript/tests/scripts/parser/features/lambda_ends_with_new_line.out b/modules/gdscript/tests/scripts/parser/features/lambda_ends_with_new_line.out
new file mode 100644
index 0000000000..4347310960
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/features/lambda_ends_with_new_line.out
@@ -0,0 +1,25 @@
+GDTEST_OK
+1
+
+3
+
+4
+5
+
+4
+5
+
+6
+
+7
+8
+
+9
+10
+9
+11
+12
+13
+11
+
+14
diff --git a/modules/gdscript/tests/scripts/runtime/features/reset_local_var_on exit_block.gd b/modules/gdscript/tests/scripts/runtime/features/reset_local_var_on exit_block.gd
new file mode 100644
index 0000000000..c774ebf83c
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/reset_local_var_on exit_block.gd
@@ -0,0 +1,10 @@
+# GH-77666
+
+func test():
+ var ref := RefCounted.new()
+ print(ref.get_reference_count())
+
+ if true:
+ var _temp := ref
+
+ print(ref.get_reference_count())
diff --git a/modules/gdscript/tests/scripts/analyzer/features/virtual_method_implemented.out b/modules/gdscript/tests/scripts/runtime/features/reset_local_var_on exit_block.out
index d73c5eb7cd..04b4638adf 100644
--- a/modules/gdscript/tests/scripts/analyzer/features/virtual_method_implemented.out
+++ b/modules/gdscript/tests/scripts/runtime/features/reset_local_var_on exit_block.out
@@ -1 +1,3 @@
GDTEST_OK
+1
+1
diff --git a/modules/gdscript/tests/scripts/runtime/features/reset_unassigned_variables_in_loops.gd b/modules/gdscript/tests/scripts/runtime/features/reset_unassigned_variables_in_loops.gd
new file mode 100644
index 0000000000..c45f8dce48
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/reset_unassigned_variables_in_loops.gd
@@ -0,0 +1,28 @@
+# GH-56223, GH-76569
+
+func test():
+ for i in 3:
+ var a
+ if true:
+ var b
+ if true:
+ var c
+ prints("Begin:", i, a, b, c)
+ a = 1
+ b = 1
+ c = 1
+ prints("End:", i, a, b, c)
+ print("===")
+ var j := 0
+ while j < 3:
+ var a
+ if true:
+ var b
+ if true:
+ var c
+ prints("Begin:", j, a, b, c)
+ a = 1
+ b = 1
+ c = 1
+ prints("End:", j, a, b, c)
+ j += 1
diff --git a/modules/gdscript/tests/scripts/runtime/features/reset_unassigned_variables_in_loops.out b/modules/gdscript/tests/scripts/runtime/features/reset_unassigned_variables_in_loops.out
new file mode 100644
index 0000000000..7eddcbf903
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/reset_unassigned_variables_in_loops.out
@@ -0,0 +1,14 @@
+GDTEST_OK
+Begin: 0 <null> <null> <null>
+End: 0 1 1 1
+Begin: 1 <null> <null> <null>
+End: 1 1 1 1
+Begin: 2 <null> <null> <null>
+End: 2 1 1 1
+===
+Begin: 0 <null> <null> <null>
+End: 0 1 1 1
+Begin: 1 <null> <null> <null>
+End: 1 1 1 1
+Begin: 2 <null> <null> <null>
+End: 2 1 1 1
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs
index 27963be00f..312c65e364 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs
@@ -206,16 +206,16 @@ namespace GodotTools.Build
private static bool BuildProjectBlocking(BuildInfo buildInfo)
{
- if (!File.Exists(buildInfo.Solution))
- return true; // No solution to build
+ if (!File.Exists(buildInfo.Project))
+ return true; // No project to build.
using var pr = new EditorProgress("dotnet_build_project", "Building .NET project...", 1);
- pr.Step("Building project solution", 0);
+ pr.Step("Building project", 0);
if (!Build(buildInfo))
{
- ShowBuildErrorDialog("Failed to build project solution");
+ ShowBuildErrorDialog("Failed to build project");
return false;
}
@@ -224,16 +224,16 @@ namespace GodotTools.Build
private static bool CleanProjectBlocking(BuildInfo buildInfo)
{
- if (!File.Exists(buildInfo.Solution))
- return true; // No solution to clean
+ if (!File.Exists(buildInfo.Project))
+ return true; // No project to clean.
using var pr = new EditorProgress("dotnet_clean_project", "Cleaning .NET project...", 1);
- pr.Step("Cleaning project solution", 0);
+ pr.Step("Cleaning project", 0);
if (!Build(buildInfo))
{
- ShowBuildErrorDialog("Failed to clean project solution");
+ ShowBuildErrorDialog("Failed to clean project");
return false;
}
@@ -322,11 +322,11 @@ namespace GodotTools.Build
public static bool EditorBuildCallback()
{
- if (!File.Exists(GodotSharpDirs.ProjectSlnPath))
- return true; // No solution to build
+ if (!File.Exists(GodotSharpDirs.ProjectCsProjPath))
+ return true; // No project to build.
if (GodotSharpEditor.Instance.SkipBuildBeforePlaying)
- return true; // Requested play from an external editor/IDE which already built the project
+ return true; // Requested play from an external editor/IDE which already built the project.
return BuildProjectBlocking("Debug");
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs
index 8fe7d3c2d7..1bb1b3227e 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs
@@ -29,46 +29,46 @@ namespace GodotTools.Build
BuildOutputView.UpdateIssuesList();
}
- public void BuildSolution()
+ public void BuildProject()
{
- if (!File.Exists(GodotSharpDirs.ProjectSlnPath))
- return; // No solution to build
+ if (!File.Exists(GodotSharpDirs.ProjectCsProjPath))
+ return; // No project to build.
if (!BuildManager.BuildProjectBlocking("Debug"))
- return; // Build failed
+ return; // Build failed.
- // Notify running game for hot-reload
+ // Notify running game for hot-reload.
Internal.EditorDebuggerNodeReloadScripts();
- // Hot-reload in the editor
+ // Hot-reload in the editor.
GodotSharpEditor.Instance.GetNode<HotReloadAssemblyWatcher>("HotReloadAssemblyWatcher").RestartTimer();
if (Internal.IsAssembliesReloadingNeeded())
Internal.ReloadAssemblies(softReload: false);
}
- private void RebuildSolution()
+ private void RebuildProject()
{
- if (!File.Exists(GodotSharpDirs.ProjectSlnPath))
- return; // No solution to build
+ if (!File.Exists(GodotSharpDirs.ProjectCsProjPath))
+ return; // No project to build.
if (!BuildManager.BuildProjectBlocking("Debug", rebuild: true))
- return; // Build failed
+ return; // Build failed.
- // Notify running game for hot-reload
+ // Notify running game for hot-reload.
Internal.EditorDebuggerNodeReloadScripts();
- // Hot-reload in the editor
+ // Hot-reload in the editor.
GodotSharpEditor.Instance.GetNode<HotReloadAssemblyWatcher>("HotReloadAssemblyWatcher").RestartTimer();
if (Internal.IsAssembliesReloadingNeeded())
Internal.ReloadAssemblies(softReload: false);
}
- private void CleanSolution()
+ private void CleanProject()
{
- if (!File.Exists(GodotSharpDirs.ProjectSlnPath))
- return; // No solution to build
+ if (!File.Exists(GodotSharpDirs.ProjectCsProjPath))
+ return; // No project to build.
_ = BuildManager.CleanProjectBlocking("Debug");
}
@@ -83,14 +83,14 @@ namespace GodotTools.Build
{
switch ((BuildMenuOptions)id)
{
- case BuildMenuOptions.BuildSolution:
- BuildSolution();
+ case BuildMenuOptions.BuildProject:
+ BuildProject();
break;
- case BuildMenuOptions.RebuildSolution:
- RebuildSolution();
+ case BuildMenuOptions.RebuildProject:
+ RebuildProject();
break;
- case BuildMenuOptions.CleanSolution:
- CleanSolution();
+ case BuildMenuOptions.CleanProject:
+ CleanProject();
break;
default:
throw new ArgumentOutOfRangeException(nameof(id), id, "Invalid build menu option");
@@ -99,9 +99,9 @@ namespace GodotTools.Build
private enum BuildMenuOptions
{
- BuildSolution,
- RebuildSolution,
- CleanSolution
+ BuildProject,
+ RebuildProject,
+ CleanProject
}
public override void _Ready()
@@ -118,9 +118,9 @@ namespace GodotTools.Build
toolBarHBox.AddChild(_buildMenuBtn);
var buildMenu = _buildMenuBtn.GetPopup();
- buildMenu.AddItem("Build Solution".TTR(), (int)BuildMenuOptions.BuildSolution);
- buildMenu.AddItem("Rebuild Solution".TTR(), (int)BuildMenuOptions.RebuildSolution);
- buildMenu.AddItem("Clean Solution".TTR(), (int)BuildMenuOptions.CleanSolution);
+ buildMenu.AddItem("Build Project".TTR(), (int)BuildMenuOptions.BuildProject);
+ buildMenu.AddItem("Rebuild Project".TTR(), (int)BuildMenuOptions.RebuildProject);
+ buildMenu.AddItem("Clean Project".TTR(), (int)BuildMenuOptions.CleanProject);
buildMenu.IdPressed += BuildMenuOptionPressed;
_errorsBtn = new Button
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
index 4e33b38ac2..622a155d37 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
@@ -140,15 +140,15 @@ namespace GodotTools
}
}
- private void BuildSolutionPressed()
+ private void BuildProjectPressed()
{
- if (!File.Exists(GodotSharpDirs.ProjectSlnPath))
+ if (!File.Exists(GodotSharpDirs.ProjectCsProjPath))
{
if (!CreateProjectSolution())
- return; // Failed to create solution
+ return; // Failed to create project.
}
- Instance.MSBuildPanel.BuildSolution();
+ Instance.MSBuildPanel.BuildProject();
}
private enum MenuOptions
@@ -507,10 +507,10 @@ namespace GodotTools
Shortcut = buildSolutionShortcut,
ShortcutInTooltip = true
};
- _toolBarBuildButton.Pressed += BuildSolutionPressed;
+ _toolBarBuildButton.Pressed += BuildProjectPressed;
AddControlToContainer(CustomControlContainer.Toolbar, _toolBarBuildButton);
- if (File.Exists(GodotSharpDirs.ProjectSlnPath) && File.Exists(GodotSharpDirs.ProjectCsProjPath))
+ if (File.Exists(GodotSharpDirs.ProjectCsProjPath))
{
ApplyNecessaryChangesToSolution();
}
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
index 4b25f51659..a84eebc208 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -1451,6 +1451,11 @@ void RenderForwardClustered::_pre_opaque_render(RenderDataRD *p_render_data, boo
RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL_BARRIERS, RD::BARRIER_MASK_ALL_BARRIERS);
if (current_cluster_builder) {
+ // Note: when rendering stereoscopic (multiview) we are using our combined frustum projection to create
+ // our cluster data. We use reprojection in the shader to adjust for our left/right eye.
+ // This only works as we don't filter our cluster by depth buffer.
+ // If we ever make this optimisation we should make it optional and only use it in mono.
+ // What we win by filtering out a few lights, we loose by having to do the work double for stereo.
current_cluster_builder->begin(p_render_data->scene_data->cam_transform, p_render_data->scene_data->cam_projection, !p_render_data->reflection_probe.is_valid());
}
diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
index dd78e7a90f..b38f0629c0 100644
--- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
+++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
@@ -735,6 +735,10 @@ void fragment_shader(in SceneData scene_data) {
#ifdef USE_MULTIVIEW
vec3 eye_offset = scene_data.eye_offset[ViewIndex].xyz;
vec3 view = -normalize(vertex_interp - eye_offset);
+
+ // UV in our combined frustum space is used for certain screen uv processes where it's
+ // overkill to render separate left and right eye views
+ vec2 combined_uv = (combined_projected.xy / combined_projected.w) * 0.5 + 0.5;
#else
vec3 eye_offset = vec3(0.0, 0.0, 0.0);
vec3 view = -normalize(vertex_interp);
@@ -921,8 +925,7 @@ void fragment_shader(in SceneData scene_data) {
if (implementation_data.volumetric_fog_enabled) {
#ifdef USE_MULTIVIEW
- vec2 center_uv = (combined_projected.xy / combined_projected.w) * 0.5 + 0.5;
- vec4 volumetric_fog = volumetric_fog_process(center_uv, -vertex.z);
+ vec4 volumetric_fog = volumetric_fog_process(combined_uv, -vertex.z);
#else
vec4 volumetric_fog = volumetric_fog_process(screen_uv, -vertex.z);
#endif
@@ -952,7 +955,11 @@ void fragment_shader(in SceneData scene_data) {
#ifndef MODE_RENDER_DEPTH
+#ifdef USE_MULTIVIEW
+ uvec2 cluster_pos = uvec2(combined_uv.xy / scene_data.screen_pixel_size) >> implementation_data.cluster_shift;
+#else
uvec2 cluster_pos = uvec2(gl_FragCoord.xy) >> implementation_data.cluster_shift;
+#endif
uint cluster_offset = (implementation_data.cluster_width * cluster_pos.y + cluster_pos.x) * (implementation_data.max_cluster_element_count_div_32 + 32);
uint cluster_z = uint(clamp((-vertex.z / scene_data.z_far) * 32.0, 0.0, 31.0));