diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/gdscript/doc_classes/@GDScript.xml | 15 | ||||
-rw-r--r-- | modules/gdscript/gdscript.cpp | 21 | ||||
-rw-r--r-- | modules/gdscript/gdscript_compiler.cpp | 2 | ||||
-rw-r--r-- | modules/gdscript/gdscript_function.cpp | 6 | ||||
-rw-r--r-- | modules/gdscript/gdscript_functions.cpp | 2 | ||||
-rw-r--r-- | modules/gdscript/gdscript_parser.cpp | 41 | ||||
-rw-r--r-- | modules/mono/editor/script_class_parser.cpp | 55 | ||||
-rw-r--r-- | modules/mono/glue/Managed/Files/StringExtensions.cs | 14 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_android.cpp | 3 |
9 files changed, 82 insertions, 77 deletions
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index 502a68cd61..e84f84d788 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -168,14 +168,16 @@ <method name="char"> <return type="String"> </return> - <argument index="0" name="ascii" type="int"> + <argument index="0" name="code" type="int"> </argument> <description> - Returns a character as a String of the given ASCII code. + Returns a character as a String of the given Unicode code point (which is compatible with ASCII code). [codeblock] a = char(65) # a is "A" a = char(65 + 32) # a is "a" + a = char(8364) # a is "€" [/codeblock] + This is the inverse of [method ord]. </description> </method> <method name="clamp"> @@ -702,6 +704,13 @@ <argument index="0" name="char" type="String"> </argument> <description> + Returns an integer representing the Unicode code point of the given Unicode character [code]char[/code]. + [codeblock] + a = ord("A") # a is 65 + a = ord("a") # a is 97 + a = ord("€") # a is 8364 + [/codeblock] + This is the inverse of [method char]. </description> </method> <method name="parse_json"> @@ -937,7 +946,7 @@ <return type="int"> </return> <description> - Returns a random unsigned 32 bit integer. Use remainder to obtain a random value in the interval [code][0, N][/code] (where N is smaller than 2^32 -1). + Returns a random unsigned 32 bit integer. Use remainder to obtain a random value in the interval [code][0, N - 1][/code] (where N is smaller than 2^32). [codeblock] randi() # Returns random integer between 0 and 2^32 - 1 randi() % 20 # Returns random integer between 0 and 19 diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 2f620df8fb..03b51be27f 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -946,18 +946,29 @@ bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) { { const Map<StringName, GDScript::MemberInfo>::Element *E = script->member_indices.find(p_name); if (E) { - if (E->get().setter) { + const GDScript::MemberInfo *member = &E->get(); + if (member->setter) { const Variant *val = &p_value; Variant::CallError err; - call(E->get().setter, &val, 1, err); + call(member->setter, &val, 1, err); if (err.error == Variant::CallError::CALL_OK) { return true; //function exists, call was successful } } else { - if (!E->get().data_type.is_type(p_value)) { - return false; // Type mismatch + if (!member->data_type.is_type(p_value)) { + // Try conversion + Variant::CallError ce; + const Variant *value = &p_value; + Variant converted = Variant::construct(member->data_type.builtin_type, &value, 1, ce); + if (ce.error == Variant::CallError::CALL_OK) { + members.write[member->index] = converted; + return true; + } else { + return false; + } + } else { + members.write[member->index] = p_value; } - members.write[E->get().index] = p_value; } return true; } diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index dea2225e91..7ce19f5adc 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -1144,7 +1144,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: GDScriptDataType assign_type = _gdtype_from_datatype(on->arguments[0]->get_datatype()); - if (assign_type.has_type && !on->arguments[1]->get_datatype().has_type) { + if (assign_type.has_type && !on->datatype.has_type) { // Typed assignment switch (assign_type.kind) { case GDScriptDataType::BUILTIN: { diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index 0a01321851..4518a5be4b 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -764,15 +764,17 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GET_VARIANT_PTR(dst, 2); GET_VARIANT_PTR(src, 3); -#ifdef DEBUG_ENABLED Variant::Type var_type = (Variant::Type)_code_ptr[ip + 1]; GD_ERR_BREAK(var_type < 0 || var_type >= Variant::VARIANT_MAX); if (src->get_type() != var_type) { +#ifdef DEBUG_ENABLED if (Variant::can_convert_strict(src->get_type(), var_type)) { +#endif // DEBUG_ENABLED Variant::CallError ce; *dst = Variant::construct(var_type, const_cast<const Variant **>(&src), 1, ce); } else { +#ifdef DEBUG_ENABLED err_text = "Trying to assign value of type '" + Variant::get_type_name(src->get_type()) + "' to a variable of type '" + Variant::get_type_name(var_type) + "'."; OPCODE_BREAK; @@ -780,9 +782,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } else { #endif // DEBUG_ENABLED *dst = *src; -#ifdef DEBUG_ENABLED } -#endif // DEBUG_ENABLED ip += 4; } diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp index 9e05c7b574..5c0573be3f 100644 --- a/modules/gdscript/gdscript_functions.cpp +++ b/modules/gdscript/gdscript_functions.cpp @@ -1855,7 +1855,7 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { } break; case TEXT_CHAR: { - MethodInfo mi("char", PropertyInfo(Variant::INT, "ascii")); + MethodInfo mi("char", PropertyInfo(Variant::INT, "code")); mi.return_val.type = Variant::STRING; return mi; diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index ef1a282e51..4405393b96 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -8185,7 +8185,9 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) { } #endif // DEBUG_ENABLED + bool type_match = check_types; if (check_types && !_is_type_compatible(lh_type, rh_type)) { + type_match = false; // Try supertype test if (_is_type_compatible(rh_type, lh_type)) { _mark_line_as_unsafe(op->line); @@ -8197,23 +8199,27 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) { op->line); return; } - // Replace assignment with implicit conversion - BuiltInFunctionNode *convert = alloc_node<BuiltInFunctionNode>(); - convert->line = op->line; - convert->function = GDScriptFunctions::TYPE_CONVERT; - - ConstantNode *tgt_type = alloc_node<ConstantNode>(); - tgt_type->line = op->line; - tgt_type->value = (int)lh_type.builtin_type; - - OperatorNode *convert_call = alloc_node<OperatorNode>(); - convert_call->line = op->line; - convert_call->op = OperatorNode::OP_CALL; - convert_call->arguments.push_back(convert); - convert_call->arguments.push_back(op->arguments[1]); - convert_call->arguments.push_back(tgt_type); - - op->arguments.write[1] = convert_call; + if (op->op == OperatorNode::OP_ASSIGN) { + // Replace assignment with implicit conversion + BuiltInFunctionNode *convert = alloc_node<BuiltInFunctionNode>(); + convert->line = op->line; + convert->function = GDScriptFunctions::TYPE_CONVERT; + + ConstantNode *tgt_type = alloc_node<ConstantNode>(); + tgt_type->line = op->line; + tgt_type->value = (int)lh_type.builtin_type; + + OperatorNode *convert_call = alloc_node<OperatorNode>(); + convert_call->line = op->line; + convert_call->op = OperatorNode::OP_CALL; + convert_call->arguments.push_back(convert); + convert_call->arguments.push_back(op->arguments[1]); + convert_call->arguments.push_back(tgt_type); + + op->arguments.write[1] = convert_call; + + type_match = true; // Since we are converting, the type is matching + } #ifdef DEBUG_ENABLED if (lh_type.builtin_type == Variant::INT && rh_type.builtin_type == Variant::REAL) { _add_warning(GDScriptWarning::NARROWING_CONVERSION, op->line); @@ -8226,6 +8232,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) { _mark_line_as_unsafe(op->line); } #endif // DEBUG_ENABLED + op->datatype.has_type = type_match; } break; case OperatorNode::OP_CALL: case OperatorNode::OP_PARENT_CALL: { diff --git a/modules/mono/editor/script_class_parser.cpp b/modules/mono/editor/script_class_parser.cpp index dcb0ca5a80..1c3a583601 100644 --- a/modules/mono/editor/script_class_parser.cpp +++ b/modules/mono/editor/script_class_parser.cpp @@ -501,12 +501,15 @@ Error ScriptClassParser::parse(const String &p_code) { int type_curly_stack = 0; while (!error && tk != TK_EOF) { - if (tk == TK_IDENTIFIER && String(value) == "class") { + String identifier = value; + if (tk == TK_IDENTIFIER && (identifier == "class" || identifier == "struct")) { + bool is_class = identifier == "class"; + tk = get_token(); if (tk == TK_IDENTIFIER) { String name = value; - int at_level = type_curly_stack; + int at_level = curly_stack; ClassDecl class_decl; @@ -568,48 +571,22 @@ Error ScriptClassParser::parse(const String &p_code) { NameDecl name_decl; name_decl.name = name; - name_decl.type = NameDecl::CLASS_DECL; + name_decl.type = is_class ? NameDecl::CLASS_DECL : NameDecl::STRUCT_DECL; name_stack[at_level] = name_decl; - if (!generic) { // no generics, thanks - classes.push_back(class_decl); - } else if (OS::get_singleton()->is_stdout_verbose()) { - String full_name = class_decl.namespace_; - if (full_name.length()) - full_name += "."; - full_name += class_decl.name; - OS::get_singleton()->print("Ignoring generic class declaration: %s\n", class_decl.name.utf8().get_data()); - } - } - } else if (tk == TK_IDENTIFIER && String(value) == "struct") { - String name; - int at_level = type_curly_stack; - while (true) { - tk = get_token(); - if (tk == TK_IDENTIFIER && name.empty()) { - name = String(value); - } else if (tk == TK_CURLY_BRACKET_OPEN) { - if (name.empty()) { - error_str = "Expected " + get_token_name(TK_IDENTIFIER) + " after keyword 'struct', found " + get_token_name(TK_CURLY_BRACKET_OPEN); - error = true; - return ERR_PARSE_ERROR; + if (is_class) { + if (!generic) { // no generics, thanks + classes.push_back(class_decl); + } else if (OS::get_singleton()->is_stdout_verbose()) { + String full_name = class_decl.namespace_; + if (full_name.length()) + full_name += "."; + full_name += class_decl.name; + OS::get_singleton()->print("Ignoring generic class declaration: %s\n", full_name.utf8().get_data()); } - - curly_stack++; - type_curly_stack++; - break; - } else if (tk == TK_EOF) { - error_str = "Expected " + get_token_name(TK_CURLY_BRACKET_OPEN) + " after struct decl, found " + get_token_name(TK_EOF); - error = true; - return ERR_PARSE_ERROR; } } - - NameDecl name_decl; - name_decl.name = name; - name_decl.type = NameDecl::STRUCT_DECL; - name_stack[at_level] = name_decl; - } else if (tk == TK_IDENTIFIER && String(value) == "namespace") { + } else if (tk == TK_IDENTIFIER && identifier == "namespace") { if (type_curly_stack > 0) { error_str = "Found namespace nested inside type."; error = true; diff --git a/modules/mono/glue/Managed/Files/StringExtensions.cs b/modules/mono/glue/Managed/Files/StringExtensions.cs index 6045c83e95..079e9912d6 100644 --- a/modules/mono/glue/Managed/Files/StringExtensions.cs +++ b/modules/mono/glue/Managed/Files/StringExtensions.cs @@ -18,7 +18,7 @@ namespace Godot int pos = 0; int slices = 1; - while ((pos = instance.Find(splitter, pos)) >= 0) + while ((pos = instance.Find(splitter, true, pos)) >= 0) { slices++; pos += splitter.Length; @@ -325,17 +325,17 @@ namespace Godot // <summary> // Find the first occurrence of a substring, return the starting position of the substring or -1 if not found. Optionally, the initial search index can be passed. // </summary> - public static int Find(this string instance, string what, int from = 0) + public static int Find(this string instance, string what, bool caseSensitive = true, int from = 0) { - return instance.IndexOf(what, StringComparison.OrdinalIgnoreCase); + return instance.IndexOf(what, from, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase); } // <summary> // Find the last occurrence of a substring, return the starting position of the substring or -1 if not found. Optionally, the initial search index can be passed. // </summary> - public static int FindLast(this string instance, string what) + public static int FindLast(this string instance, string what, bool caseSensitive = true, int from = 0) { - return instance.LastIndexOf(what, StringComparison.OrdinalIgnoreCase); + return instance.LastIndexOf(what, from, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase); } // <summary> @@ -343,7 +343,7 @@ namespace Godot // </summary> public static int FindN(this string instance, string what, int from = 0) { - return instance.IndexOf(what, StringComparison.Ordinal); + return instance.IndexOf(what, from, StringComparison.OrdinalIgnoreCase); } // <summary> @@ -928,7 +928,7 @@ namespace Godot while (true) { - int end = instance.Find(divisor, from); + int end = instance.Find(divisor, true, from); if (end < 0) end = len; if (allowEmpty || end > from) diff --git a/modules/mono/mono_gd/gd_mono_android.cpp b/modules/mono/mono_gd/gd_mono_android.cpp index 86af8d1812..29ae4856be 100644 --- a/modules/mono/mono_gd/gd_mono_android.cpp +++ b/modules/mono/mono_gd/gd_mono_android.cpp @@ -81,7 +81,8 @@ struct ScopedLocalRef { ScopedLocalRef &operator=(const ScopedLocalRef &) = delete; ScopedLocalRef(JNIEnv *p_env, T p_local_ref) : - env(p_env), local_ref(p_local_ref) { + env(p_env), + local_ref(p_local_ref) { } ~ScopedLocalRef() { |