diff options
Diffstat (limited to 'modules/gdscript')
8 files changed, 59 insertions, 7 deletions
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index d98580b771..4869573972 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -43,6 +43,7 @@ assert(speed >= 0 and speed < 20) # You can also combine the two conditional statements in one check. assert(speed < 20, "the speed limit is 20") # Show a message. [/codeblock] + [b]Note:[/b] [method assert] is a keyword, not a function. So you cannot access it as a [Callable] or use it inside expressions. </description> </method> <method name="char"> @@ -131,7 +132,7 @@ - A constant from the [enum Variant.Type] enumeration, for example [constant TYPE_INT]. - An [Object]-derived class which exists in [ClassDB], for example [Node]. - A [Script] (you can use any class, including inner one). - Unlike the right operand of the [code]is[/code] operator, [param type] can be a non-constant value. The [code]is[/code] operator supports more features (such as typed arrays) and is more performant. Use the operator instead of this method if you do not need dynamic type checking. + Unlike the right operand of the [code]is[/code] operator, [param type] can be a non-constant value. The [code]is[/code] operator supports more features (such as typed arrays). Use the operator instead of this method if you do not need dynamic type checking. Examples: [codeblock] print(is_instance_of(a, TYPE_INT)) @@ -183,6 +184,7 @@ # Create instance of a scene. var diamond = preload("res://diamond.tscn").instantiate() [/codeblock] + [b]Note:[/b] [method preload] is a keyword, not a function. So you cannot access it as a [Callable]. </description> </method> <method name="print_debug" qualifiers="vararg"> @@ -717,6 +719,8 @@ <return type="void" /> <description> Make a script with static variables to not persist after all references are lost. If the script is loaded again the static variables will revert to their default values. + [b]Note:[/b] As annotations describe their subject, the [annotation @static_unload] annotation must be placed before the class definition and inheritance. + [b]Warning:[/b] Currently, due to a bug, scripts are never freed, even if [annotation @static_unload] annotation is used. </description> </annotation> <annotation name="@tool"> diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 12ff22c878..854c944e14 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -2665,6 +2665,8 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c GDScriptParser::DataType base_type = p_base.type; const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\""; + const bool use_string_names = EDITOR_GET("text_editor/completion/add_string_name_literals"); + const bool use_node_paths = EDITOR_GET("text_editor/completion/add_node_path_literals"); while (base_type.is_set() && !base_type.is_variant()) { switch (base_type.kind) { @@ -2698,8 +2700,14 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c List<String> options; obj->get_argument_options(p_method, p_argidx, &options); for (String &opt : options) { + // Handle user preference. if (opt.is_quoted()) { - opt = opt.unquote().quote(quote_style); // Handle user preference. + opt = opt.unquote().quote(quote_style); + if (use_string_names && info.arguments[p_argidx].type == Variant::STRING_NAME) { + opt = opt.indent("&"); + } else if (use_node_paths && info.arguments[p_argidx].type == Variant::NODE_PATH) { + opt = opt.indent("^"); + } } ScriptLanguage::CodeCompletionOption option(opt, ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION); r_result.insert(option.display, option); diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 8d98c0b11c..d706f4e9a3 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -856,7 +856,7 @@ void GDScriptParser::parse_extends() { } } -template <class T> +template <typename T> void GDScriptParser::parse_class_member(T *(GDScriptParser::*p_parse_function)(bool), AnnotationInfo::TargetKind p_target, const String &p_member_kind, bool p_is_static) { advance(); diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index 583b60bf16..ea67f1eaff 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -774,7 +774,7 @@ public: bool has_function(const StringName &p_name) const { return has_member(p_name) && members[members_indices[p_name]].type == Member::FUNCTION; } - template <class T> + template <typename T> void add_member(T *p_member_node) { members_indices[p_member_node->identifier->name] = members.size(); members.push_back(Member(p_member_node)); @@ -1167,7 +1167,7 @@ public: bool has_local(const StringName &p_name) const; const Local &get_local(const StringName &p_name) const; - template <class T> + template <typename T> void add_local(T *p_local, FunctionNode *p_source_function) { locals_indices[p_local->identifier->name] = locals.size(); locals.push_back(Local(p_local, p_source_function)); @@ -1426,7 +1426,7 @@ private: void reset_extents(Node *p_node, GDScriptTokenizer::Token p_token); void reset_extents(Node *p_node, Node *p_from); - template <class T> + template <typename T> T *alloc_node() { T *node = memnew(T); @@ -1473,7 +1473,7 @@ private: void parse_class_name(); void parse_extends(); void parse_class_body(bool p_is_multiline); - template <class T> + template <typename T> void parse_class_member(T *(GDScriptParser::*p_parse_function)(bool), AnnotationInfo::TargetKind p_target, const String &p_member_kind, bool p_is_static = false); SignalNode *parse_signal(bool p_is_static); EnumNode *parse_enum(bool p_is_static); diff --git a/modules/gdscript/tests/scripts/runtime/features/emit_after_await.gd b/modules/gdscript/tests/scripts/runtime/features/emit_after_await.gd new file mode 100644 index 0000000000..21fd526acc --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/emit_after_await.gd @@ -0,0 +1,12 @@ +# https://github.com/godotengine/godot/issues/89439 +extends Node + +signal my_signal + +func async_func(): + await my_signal + my_signal.emit() + +func test(): + async_func() + my_signal.emit() diff --git a/modules/gdscript/tests/scripts/runtime/features/emit_after_await.out b/modules/gdscript/tests/scripts/runtime/features/emit_after_await.out new file mode 100644 index 0000000000..d73c5eb7cd --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/emit_after_await.out @@ -0,0 +1 @@ +GDTEST_OK diff --git a/modules/gdscript/tests/scripts/runtime/features/emit_one_shot_is_non_recursive.gd b/modules/gdscript/tests/scripts/runtime/features/emit_one_shot_is_non_recursive.gd new file mode 100644 index 0000000000..5c328dcfcd --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/emit_one_shot_is_non_recursive.gd @@ -0,0 +1,22 @@ +# https://github.com/godotengine/godot/issues/89439 + +signal my_signal + +func foo(): + print("Foo") + my_signal.emit() + +func bar(): + print("Bar") + +func baz(): + print("Baz") + +func test(): + @warning_ignore("return_value_discarded") + my_signal.connect(foo, CONNECT_ONE_SHOT) + @warning_ignore("return_value_discarded") + my_signal.connect(bar, CONNECT_ONE_SHOT) + @warning_ignore("return_value_discarded") + my_signal.connect(baz) + my_signal.emit() diff --git a/modules/gdscript/tests/scripts/runtime/features/emit_one_shot_is_non_recursive.out b/modules/gdscript/tests/scripts/runtime/features/emit_one_shot_is_non_recursive.out new file mode 100644 index 0000000000..3399e08878 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/emit_one_shot_is_non_recursive.out @@ -0,0 +1,5 @@ +GDTEST_OK +Foo +Baz +Bar +Baz |