summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/gdscript/doc_classes/GDScript.xml6
-rw-r--r--modules/gdscript/gdscript.cpp23
-rw-r--r--modules/gdscript/gdscript.h4
-rw-r--r--modules/gdscript/gdscript_parser.cpp28
-rw-r--r--modules/gdscript/gdscript_parser.h5
-rw-r--r--modules/gdscript/gdscript_tokenizer.cpp62
-rw-r--r--modules/gdscript/gdscript_tokenizer.h7
-rw-r--r--modules/gdscript/gdscript_warning.cpp5
-rw-r--r--modules/gdscript/gdscript_warning.h1
-rw-r--r--modules/gdscript/language_server/gdscript_text_document.cpp1
-rw-r--r--modules/gdscript/register_types.cpp5
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/lambda_unused_arg.out2
-rw-r--r--modules/gdscript/tests/scripts/parser/errors/identifier_similar_to_keyword.gd3
-rw-r--r--modules/gdscript/tests/scripts/parser/errors/identifier_similar_to_keyword.out2
-rw-r--r--modules/gdscript/tests/scripts/parser/features/unicode_identifiers.gd35
-rw-r--r--modules/gdscript/tests/scripts/parser/features/unicode_identifiers.out14
-rw-r--r--modules/gdscript/tests/scripts/parser/warnings/confusable_identifier.gd5
-rw-r--r--modules/gdscript/tests/scripts/parser/warnings/confusable_identifier.out6
-rw-r--r--modules/gltf/gltf_document.cpp1
-rw-r--r--modules/mono/csharp_script.cpp4
-rw-r--r--modules/mono/csharp_script.h2
-rw-r--r--modules/navigation/godot_navigation_server.cpp27
-rw-r--r--modules/navigation/nav_map.cpp57
-rw-r--r--modules/navigation/navigation_mesh_generator.cpp8
-rw-r--r--modules/raycast/raycast_occlusion_cull.cpp4
25 files changed, 196 insertions, 121 deletions
diff --git a/modules/gdscript/doc_classes/GDScript.xml b/modules/gdscript/doc_classes/GDScript.xml
index 8246c96c15..1a102bd16f 100644
--- a/modules/gdscript/doc_classes/GDScript.xml
+++ b/modules/gdscript/doc_classes/GDScript.xml
@@ -11,12 +11,6 @@
<link title="GDScript documentation index">$DOCS_URL/tutorials/scripting/gdscript/index.html</link>
</tutorials>
<methods>
- <method name="get_as_byte_code" qualifiers="const">
- <return type="PackedByteArray" />
- <description>
- Returns byte code for the script source code.
- </description>
- </method>
<method name="new" qualifiers="vararg">
<return type="Variant" />
<description>
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index 28f478e9cd..6b325d6451 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -248,6 +248,10 @@ Ref<Script> GDScript::get_base_script() const {
}
}
+StringName GDScript::get_global_name() const {
+ return name;
+}
+
StringName GDScript::get_instance_base_type() const {
if (native.is_valid()) {
return native->get_name();
@@ -1007,17 +1011,6 @@ void GDScript::_get_property_list(List<PropertyInfo> *p_properties) const {
void GDScript::_bind_methods() {
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &GDScript::_new, MethodInfo("new"));
-
- ClassDB::bind_method(D_METHOD("get_as_byte_code"), &GDScript::get_as_byte_code);
-}
-
-Vector<uint8_t> GDScript::get_as_byte_code() const {
- return Vector<uint8_t>();
-};
-
-// TODO: Fully remove this. There's not this kind of "bytecode" anymore.
-Error GDScript::load_byte_code(const String &p_path) {
- return ERR_COMPILATION_FAILED;
}
void GDScript::set_path(const String &p_path, bool p_take_over) {
@@ -2647,8 +2640,6 @@ Ref<Resource> ResourceFormatLoaderGDScript::load(const String &p_path, const Str
Error err;
Ref<GDScript> scr = GDScriptCache::get_full_script(p_path, err, "", p_cache_mode == CACHE_MODE_IGNORE);
- // TODO: Reintroduce binary and encrypted scripts.
-
if (scr.is_null()) {
// Don't fail loading because of parsing error.
scr.instantiate();
@@ -2663,9 +2654,6 @@ Ref<Resource> ResourceFormatLoaderGDScript::load(const String &p_path, const Str
void ResourceFormatLoaderGDScript::get_recognized_extensions(List<String> *p_extensions) const {
p_extensions->push_back("gd");
- // TODO: Reintroduce binary and encrypted scripts.
- // p_extensions->push_back("gdc");
- // p_extensions->push_back("gde");
}
bool ResourceFormatLoaderGDScript::handles_type(const String &p_type) const {
@@ -2674,8 +2662,7 @@ bool ResourceFormatLoaderGDScript::handles_type(const String &p_type) const {
String ResourceFormatLoaderGDScript::get_resource_type(const String &p_path) const {
String el = p_path.get_extension().to_lower();
- // TODO: Reintroduce binary and encrypted scripts.
- if (el == "gd" /*|| el == "gdc" || el == "gde"*/) {
+ if (el == "gd") {
return "GDScript";
}
return "";
diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h
index a53785a98d..82d04f641c 100644
--- a/modules/gdscript/gdscript.h
+++ b/modules/gdscript/gdscript.h
@@ -228,6 +228,7 @@ public:
virtual bool can_instantiate() const override;
virtual Ref<Script> get_base_script() const override;
+ virtual StringName get_global_name() const override;
virtual StringName get_instance_base_type() const override; // this may not work in all scripts, will return empty if so
virtual ScriptInstance *instance_create(Object *p_this) override;
@@ -250,9 +251,6 @@ public:
virtual void set_path(const String &p_path, bool p_take_over = false) override;
String get_script_path() const;
Error load_source_code(const String &p_path);
- Error load_byte_code(const String &p_path);
-
- Vector<uint8_t> get_as_byte_code() const;
bool get_property_default_value(const StringName &p_property, Variant &r_value) const override;
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index f5d3306376..4228046ba2 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -41,6 +41,7 @@
#include "core/os/os.h"
#include "core/string/string_builder.h"
#include "gdscript_warning.h"
+#include "servers/text_server.h"
#endif // DEBUG_ENABLED
#ifdef TOOLS_ENABLED
@@ -186,24 +187,6 @@ void GDScriptParser::push_error(const String &p_message, const Node *p_origin) {
}
#ifdef DEBUG_ENABLED
-void GDScriptParser::push_warning(const Node *p_source, GDScriptWarning::Code p_code, const String &p_symbol1, const String &p_symbol2, const String &p_symbol3, const String &p_symbol4) {
- ERR_FAIL_COND(p_source == nullptr);
- Vector<String> symbols;
- if (!p_symbol1.is_empty()) {
- symbols.push_back(p_symbol1);
- }
- if (!p_symbol2.is_empty()) {
- symbols.push_back(p_symbol2);
- }
- if (!p_symbol3.is_empty()) {
- symbols.push_back(p_symbol3);
- }
- if (!p_symbol4.is_empty()) {
- symbols.push_back(p_symbol4);
- }
- push_warning(p_source, p_code, symbols);
-}
-
void GDScriptParser::push_warning(const Node *p_source, GDScriptWarning::Code p_code, const Vector<String> &p_symbols) {
ERR_FAIL_COND(p_source == nullptr);
if (is_ignoring_warnings) {
@@ -2251,7 +2234,14 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_expression(bool p_can_assi
}
GDScriptParser::IdentifierNode *GDScriptParser::parse_identifier() {
- return static_cast<IdentifierNode *>(parse_identifier(nullptr, false));
+ IdentifierNode *identifier = static_cast<IdentifierNode *>(parse_identifier(nullptr, false));
+#ifdef DEBUG_ENABLED
+ // Check for spoofing here (if available in TextServer) since this isn't called inside expressions. This is only relevant for declarations.
+ if (identifier && TS->has_feature(TextServer::FEATURE_UNICODE_SECURITY) && TS->spoof_check(identifier->name.operator String())) {
+ push_warning(identifier, GDScriptWarning::CONFUSABLE_IDENTIFIER, identifier->name.operator String());
+ }
+#endif
+ return identifier;
}
GDScriptParser::ExpressionNode *GDScriptParser::parse_identifier(ExpressionNode *p_previous_operand, bool p_can_assign) {
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index 0903f62061..f6d2a8feee 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -1361,8 +1361,11 @@ private:
void clear();
void push_error(const String &p_message, const Node *p_origin = nullptr);
#ifdef DEBUG_ENABLED
- void push_warning(const Node *p_source, GDScriptWarning::Code p_code, const String &p_symbol1 = String(), const String &p_symbol2 = String(), const String &p_symbol3 = String(), const String &p_symbol4 = String());
void push_warning(const Node *p_source, GDScriptWarning::Code p_code, const Vector<String> &p_symbols);
+ template <typename... Symbols>
+ void push_warning(const Node *p_source, GDScriptWarning::Code p_code, const Symbols &...p_symbols) {
+ push_warning(p_source, p_code, Vector<String>{ p_symbols... });
+ }
#endif
void make_completion_context(CompletionType p_type, Node *p_node, int p_argument = -1, bool p_force = false);
diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp
index e17a804003..d7f1114fd3 100644
--- a/modules/gdscript/gdscript_tokenizer.cpp
+++ b/modules/gdscript/gdscript_tokenizer.cpp
@@ -31,10 +31,14 @@
#include "gdscript_tokenizer.h"
#include "core/error/error_macros.h"
+#include "core/string/char_utils.h"
#ifdef TOOLS_ENABLED
#include "editor/editor_settings.h"
#endif
+#ifdef DEBUG_ENABLED
+#include "servers/text_server.h"
+#endif
static const char *token_names[] = {
"Empty", // EMPTY,
@@ -435,10 +439,12 @@ GDScriptTokenizer::Token GDScriptTokenizer::check_vcs_marker(char32_t p_test, To
}
GDScriptTokenizer::Token GDScriptTokenizer::annotation() {
- if (!is_ascii_identifier_char(_peek())) {
+ if (is_unicode_identifier_start(_peek())) {
+ _advance(); // Consume start character.
+ } else {
push_error("Expected annotation identifier after \"@\".");
}
- while (is_ascii_identifier_char(_peek())) {
+ while (is_unicode_identifier_continue(_peek())) {
// Consume all identifier characters.
_advance();
}
@@ -447,7 +453,6 @@ GDScriptTokenizer::Token GDScriptTokenizer::annotation() {
return annotation;
}
-GDScriptTokenizer::Token GDScriptTokenizer::potential_identifier() {
#define KEYWORDS(KEYWORD_GROUP, KEYWORD) \
KEYWORD_GROUP('a') \
KEYWORD("as", Token::AS) \
@@ -512,8 +517,21 @@ GDScriptTokenizer::Token GDScriptTokenizer::potential_identifier() {
#define MIN_KEYWORD_LENGTH 2
#define MAX_KEYWORD_LENGTH 10
- // Consume all alphanumeric characters.
- while (is_ascii_identifier_char(_peek())) {
+#ifdef DEBUG_ENABLED
+void GDScriptTokenizer::make_keyword_list() {
+#define KEYWORD_LINE(keyword, token_type) keyword,
+#define KEYWORD_GROUP_IGNORE(group)
+ keyword_list = {
+ KEYWORDS(KEYWORD_GROUP_IGNORE, KEYWORD_LINE)
+ };
+#undef KEYWORD_LINE
+#undef KEYWORD_GROUP_IGNORE
+}
+#endif // DEBUG_ENABLED
+
+GDScriptTokenizer::Token GDScriptTokenizer::potential_identifier() {
+ // Consume all identifier characters.
+ while (is_unicode_identifier_continue(_peek())) {
_advance();
}
@@ -565,15 +583,28 @@ GDScriptTokenizer::Token GDScriptTokenizer::potential_identifier() {
}
// Not a keyword, so must be an identifier.
- return make_identifier(name);
+ Token id = make_identifier(name);
+
+#ifdef DEBUG_ENABLED
+ // Additional checks for identifiers but only in debug and if it's available in TextServer.
+ if (TS->has_feature(TextServer::FEATURE_UNICODE_SECURITY)) {
+ int64_t confusable = TS->is_confusable(name, keyword_list);
+ if (confusable >= 0) {
+ push_error(vformat(R"(Identifier "%s" is visually similar to the GDScript keyword "%s" and thus not allowed.)", name, keyword_list[confusable]));
+ }
+ }
+#endif // DEBUG_ENABLED
+
+ return id;
-#undef KEYWORDS
-#undef MIN_KEYWORD_LENGTH
-#undef MAX_KEYWORD_LENGTH
#undef KEYWORD_GROUP_CASE
#undef KEYWORD
}
+#undef MAX_KEYWORD_LENGTH
+#undef MIN_KEYWORD_LENGTH
+#undef KEYWORDS
+
void GDScriptTokenizer::newline(bool p_make_token) {
// Don't overwrite previous newline, nor create if we want a line continuation.
if (p_make_token && !pending_newline && !line_continuation) {
@@ -720,7 +751,7 @@ GDScriptTokenizer::Token GDScriptTokenizer::number() {
error.rightmost_column = column + 1;
push_error(error);
has_error = true;
- } else if (is_ascii_identifier_char(_peek())) {
+ } else if (is_unicode_identifier_start(_peek()) || is_unicode_identifier_continue(_peek())) {
// Letter at the end of the number.
push_error("Invalid numeric notation.");
}
@@ -1311,7 +1342,7 @@ GDScriptTokenizer::Token GDScriptTokenizer::scan() {
if (is_digit(c)) {
return number();
- } else if (is_ascii_identifier_char(c)) {
+ } else if (is_unicode_identifier_start(c)) {
return potential_identifier();
}
@@ -1504,7 +1535,11 @@ GDScriptTokenizer::Token GDScriptTokenizer::scan() {
}
default:
- return make_error(vformat(R"(Unknown character "%s".)", String(&c, 1)));
+ if (is_whitespace(c)) {
+ return make_error(vformat(R"(Invalid white space character "\\u%X".)", static_cast<int32_t>(c)));
+ } else {
+ return make_error(vformat(R"(Unknown character "%s".)", String(&c, 1)));
+ }
}
}
@@ -1514,4 +1549,7 @@ GDScriptTokenizer::GDScriptTokenizer() {
tab_size = EditorSettings::get_singleton()->get_setting("text_editor/behavior/indent/size");
}
#endif // TOOLS_ENABLED
+#ifdef DEBUG_ENABLED
+ make_keyword_list();
+#endif // DEBUG_ENABLED
}
diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h
index 9588922122..608840d3f1 100644
--- a/modules/gdscript/gdscript_tokenizer.h
+++ b/modules/gdscript/gdscript_tokenizer.h
@@ -224,6 +224,9 @@ private:
char32_t indent_char = '\0';
int position = 0;
int length = 0;
+#ifdef DEBUG_ENABLED
+ Vector<String> keyword_list;
+#endif // DEBUG_ENABLED
#ifdef TOOLS_ENABLED
HashMap<int, CommentData> comments;
@@ -239,6 +242,10 @@ private:
void _skip_whitespace();
void check_indent();
+#ifdef DEBUG_ENABLED
+ void make_keyword_list();
+#endif // DEBUG_ENABLED
+
Token make_error(const String &p_message);
void push_error(const String &p_message);
void push_error(const Token &p_error);
diff --git a/modules/gdscript/gdscript_warning.cpp b/modules/gdscript/gdscript_warning.cpp
index 184cecb316..a6cbb7f6ae 100644
--- a/modules/gdscript/gdscript_warning.cpp
+++ b/modules/gdscript/gdscript_warning.cpp
@@ -155,6 +155,10 @@ String GDScriptWarning::get_message() const {
CHECK_SYMBOLS(2);
return vformat(R"(The function '%s()' is a static function but was called from an instance. Instead, it should be directly called from the type: '%s.%s()'.)", symbols[0], symbols[1], symbols[0]);
}
+ case CONFUSABLE_IDENTIFIER: {
+ CHECK_SYMBOLS(1);
+ return vformat(R"(The identifier "%s" has misleading characters and might be confused with something else.)", symbols[0]);
+ }
case WARNING_MAX:
break; // Can't happen, but silences warning
}
@@ -219,6 +223,7 @@ String GDScriptWarning::get_name_from_code(Code p_code) {
"SHADOWED_GLOBAL_IDENTIFIER",
"INT_ASSIGNED_TO_ENUM",
"STATIC_CALLED_ON_INSTANCE",
+ "CONFUSABLE_IDENTIFIER",
};
static_assert((sizeof(names) / sizeof(*names)) == WARNING_MAX, "Amount of warning types don't match the amount of warning names.");
diff --git a/modules/gdscript/gdscript_warning.h b/modules/gdscript/gdscript_warning.h
index e3aee45f33..b485f02b9c 100644
--- a/modules/gdscript/gdscript_warning.h
+++ b/modules/gdscript/gdscript_warning.h
@@ -78,6 +78,7 @@ public:
SHADOWED_GLOBAL_IDENTIFIER, // A global class or function has the same name as variable.
INT_ASSIGNED_TO_ENUM, // An integer value was assigned to an enum-typed variable without casting.
STATIC_CALLED_ON_INSTANCE, // A static method was called on an instance of a class instead of on the class itself.
+ CONFUSABLE_IDENTIFIER, // The identifier contains misleading characters that can be confused. E.g. "usеr" (has Cyrillic "е" instead of Latin "e").
WARNING_MAX,
};
diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp
index edb2e8117a..b9e6921034 100644
--- a/modules/gdscript/language_server/gdscript_text_document.cpp
+++ b/modules/gdscript/language_server/gdscript_text_document.cpp
@@ -107,6 +107,7 @@ void GDScriptTextDocument::didSave(const Variant &p_param) {
} else {
scr->reload(true);
}
+ scr->update_exports();
ScriptEditor::get_singleton()->update_docs_from_script(scr);
}
}
diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp
index 33b5ae6942..b6feaadccf 100644
--- a/modules/gdscript/register_types.cpp
+++ b/modules/gdscript/register_types.cpp
@@ -71,21 +71,18 @@ class EditorExportGDScript : public EditorExportPlugin {
public:
virtual void _export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) override {
- int script_mode = EditorExportPreset::MODE_SCRIPT_COMPILED;
String script_key;
const Ref<EditorExportPreset> &preset = get_export_preset();
if (preset.is_valid()) {
- script_mode = preset->get_script_export_mode();
script_key = preset->get_script_encryption_key().to_lower();
}
- if (!p_path.ends_with(".gd") || script_mode == EditorExportPreset::MODE_SCRIPT_TEXT) {
+ if (!p_path.ends_with(".gd")) {
return;
}
- // TODO: Re-add compiled GDScript on export.
return;
}
diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/lambda_unused_arg.out b/modules/gdscript/tests/scripts/analyzer/warnings/lambda_unused_arg.out
index b018091c18..32e230fc80 100644
--- a/modules/gdscript/tests/scripts/analyzer/warnings/lambda_unused_arg.out
+++ b/modules/gdscript/tests/scripts/analyzer/warnings/lambda_unused_arg.out
@@ -2,4 +2,4 @@ GDTEST_OK
>> WARNING
>> Line: 2
>> UNUSED_PARAMETER
->>
+>> The parameter 'unused' is never used in the function ''. If this is intended, prefix it with an underscore: '_unused'
diff --git a/modules/gdscript/tests/scripts/parser/errors/identifier_similar_to_keyword.gd b/modules/gdscript/tests/scripts/parser/errors/identifier_similar_to_keyword.gd
new file mode 100644
index 0000000000..4b1f284070
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/errors/identifier_similar_to_keyword.gd
@@ -0,0 +1,3 @@
+func test():
+ var аs # Using Cyrillic "а".
+ print(аs)
diff --git a/modules/gdscript/tests/scripts/parser/errors/identifier_similar_to_keyword.out b/modules/gdscript/tests/scripts/parser/errors/identifier_similar_to_keyword.out
new file mode 100644
index 0000000000..337dec2f4d
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/errors/identifier_similar_to_keyword.out
@@ -0,0 +1,2 @@
+GDTEST_PARSER_ERROR
+Identifier "аs" is visually similar to the GDScript keyword "as" and thus not allowed.
diff --git a/modules/gdscript/tests/scripts/parser/features/unicode_identifiers.gd b/modules/gdscript/tests/scripts/parser/features/unicode_identifiers.gd
new file mode 100644
index 0000000000..523959a016
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/features/unicode_identifiers.gd
@@ -0,0 +1,35 @@
+const π = PI
+var ㄥ = π
+
+func test():
+ var փորձարկում = "test"
+ prints("փորձարկում", փորձարկում)
+ var امتحان = "test"
+ prints("امتحان", امتحان)
+ var পরীক্ষা = "test"
+ prints("পরীক্ষা", পরীক্ষা)
+ var тест = "test"
+ prints("тест", тест)
+ var जाँच = "test"
+ prints("जाँच", जाँच)
+ var 기준 = "test"
+ prints("기준", 기준)
+ var 测试 = "test"
+ prints("测试", 测试)
+ var テスト = "test"
+ prints("テスト", テスト)
+ var 試験 = "test"
+ prints("試験", 試験)
+ var പരീക്ഷ = "test"
+ prints("പരീക്ഷ", പരീക്ഷ)
+ var ทดสอบ = "test"
+ prints("ทดสอบ", ทดสอบ)
+ var δοκιμή = "test"
+ prints("δοκιμή", δοκιμή)
+
+ const d = 1.1
+ _process(d)
+ print(is_equal_approx(ㄥ, PI + (d * PI)))
+
+func _process(Δ: float) -> void:
+ ㄥ += Δ * π
diff --git a/modules/gdscript/tests/scripts/parser/features/unicode_identifiers.out b/modules/gdscript/tests/scripts/parser/features/unicode_identifiers.out
new file mode 100644
index 0000000000..c071380a8f
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/features/unicode_identifiers.out
@@ -0,0 +1,14 @@
+GDTEST_OK
+փորձարկում test
+امتحان test
+পরীক্ষা test
+тест test
+जाँच test
+기준 test
+测试 test
+テスト test
+試験 test
+പരീക്ഷ test
+ทดสอบ test
+δοκιμή test
+true
diff --git a/modules/gdscript/tests/scripts/parser/warnings/confusable_identifier.gd b/modules/gdscript/tests/scripts/parser/warnings/confusable_identifier.gd
new file mode 100644
index 0000000000..e2caac8ffd
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/warnings/confusable_identifier.gd
@@ -0,0 +1,5 @@
+func test():
+ var port = 0 # Only latin characters.
+ var pοrt = 1 # The "ο" is Greek omicron.
+
+ prints(port, pοrt)
diff --git a/modules/gdscript/tests/scripts/parser/warnings/confusable_identifier.out b/modules/gdscript/tests/scripts/parser/warnings/confusable_identifier.out
new file mode 100644
index 0000000000..c483396443
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/warnings/confusable_identifier.out
@@ -0,0 +1,6 @@
+GDTEST_OK
+>> WARNING
+>> Line: 3
+>> CONFUSABLE_IDENTIFIER
+>> The identifier "pοrt" has misleading characters and might be confused with something else.
+0 1
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index 5634c51c61..b243ba933d 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -6072,6 +6072,7 @@ void GLTFDocument::_import_animation(Ref<GLTFState> p_state, AnimationPlayer *p_
const int track_idx = animation->get_track_count();
animation->add_track(Animation::TYPE_BLEND_SHAPE);
animation->track_set_path(track_idx, blend_path);
+ animation->track_set_imported(track_idx, true); //helps merging later
// Only LINEAR and STEP (NEAREST) can be supported out of the box by Godot's Animation,
// the other modes have to be baked.
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 7606465b8a..ca94917938 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -2606,6 +2606,10 @@ Ref<Script> CSharpScript::get_base_script() const {
return base_script;
}
+StringName CSharpScript::get_global_name() const {
+ return StringName();
+}
+
void CSharpScript::get_script_property_list(List<PropertyInfo> *r_list) const {
#ifdef TOOLS_ENABLED
const CSharpScript *top = this;
diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h
index ef381fd76a..6021555255 100644
--- a/modules/mono/csharp_script.h
+++ b/modules/mono/csharp_script.h
@@ -186,6 +186,8 @@ public:
bool inherits_script(const Ref<Script> &p_script) const override;
Ref<Script> get_base_script() const override;
+ StringName get_global_name() const override;
+
ScriptLanguage *get_language() const override;
void get_script_method_list(List<MethodInfo> *p_list) const override;
diff --git a/modules/navigation/godot_navigation_server.cpp b/modules/navigation/godot_navigation_server.cpp
index 9b5d78d465..2b5db6462c 100644
--- a/modules/navigation/godot_navigation_server.cpp
+++ b/modules/navigation/godot_navigation_server.cpp
@@ -731,24 +731,21 @@ COMMAND_1(free, RID, p_object) {
NavMap *map = map_owner.get_or_null(p_object);
// Removes any assigned region
- LocalVector<NavRegion *> regions = map->get_regions();
- for (uint32_t i = 0; i < regions.size(); i++) {
- map->remove_region(regions[i]);
- regions[i]->set_map(nullptr);
+ for (NavRegion *region : map->get_regions()) {
+ map->remove_region(region);
+ region->set_map(nullptr);
}
// Removes any assigned links
- LocalVector<NavLink *> links = map->get_links();
- for (uint32_t i = 0; i < links.size(); i++) {
- map->remove_link(links[i]);
- links[i]->set_map(nullptr);
+ for (NavLink *link : map->get_links()) {
+ map->remove_link(link);
+ link->set_map(nullptr);
}
// Remove any assigned agent
- LocalVector<RvoAgent *> agents = map->get_agents();
- for (uint32_t i = 0; i < agents.size(); i++) {
- map->remove_agent(agents[i]);
- agents[i]->set_map(nullptr);
+ for (RvoAgent *agent : map->get_agents()) {
+ map->remove_agent(agent);
+ agent->set_map(nullptr);
}
int map_index = active_maps.find(map);
@@ -806,9 +803,9 @@ void GodotNavigationServer::flush_queries() {
MutexLock lock(commands_mutex);
MutexLock lock2(operations_mutex);
- for (size_t i(0); i < commands.size(); i++) {
- commands[i]->exec(this);
- memdelete(commands[i]);
+ for (SetCommand *command : commands) {
+ command->exec(this);
+ memdelete(command);
}
commands.clear();
}
diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp
index fd735f8793..7090588c6e 100644
--- a/modules/navigation/nav_map.cpp
+++ b/modules/navigation/nav_map.cpp
@@ -103,9 +103,7 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
float begin_d = 1e20;
float end_d = 1e20;
// Find the initial poly and the end poly on this map.
- for (size_t i(0); i < polygons.size(); i++) {
- const gd::Polygon &p = polygons[i];
-
+ for (const gd::Polygon &p : polygons) {
// Only consider the polygon if it in a region with compatible layers.
if ((p_navigation_layers & p.owner->get_navigation_layers()) == 0) {
continue;
@@ -190,9 +188,7 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
while (true) {
// Takes the current least_cost_poly neighbors (iterating over its edges) and compute the traveled_distance.
- for (size_t i = 0; i < navigation_polys[least_cost_id].poly->edges.size(); i++) {
- const gd::Edge &edge = navigation_polys[least_cost_id].poly->edges[i];
-
+ for (const gd::Edge &edge : navigation_polys[least_cost_id].poly->edges) {
// Iterate over connections in this edge, then compute the new optimized travel distance assigned to this polygon.
for (int connection_index = 0; connection_index < edge.connections.size(); connection_index++) {
const gd::Edge::Connection &connection = edge.connections[connection_index];
@@ -465,9 +461,7 @@ Vector3 NavMap::get_closest_point_to_segment(const Vector3 &p_from, const Vector
Vector3 closest_point;
real_t closest_point_d = 1e20;
- for (size_t i(0); i < polygons.size(); i++) {
- const gd::Polygon &p = polygons[i];
-
+ for (const gd::Polygon &p : polygons) {
// For each face check the distance to the segment
for (size_t point_id = 2; point_id < p.points.size(); point_id += 1) {
const Face3 f(p.points[0].pos, p.points[point_id - 1].pos, p.points[point_id].pos);
@@ -623,20 +617,20 @@ void NavMap::sync() {
// Check if we need to update the links.
if (regenerate_polygons) {
- for (uint32_t r = 0; r < regions.size(); r++) {
- regions[r]->scratch_polygons();
+ for (NavRegion *region : regions) {
+ region->scratch_polygons();
}
regenerate_links = true;
}
- for (uint32_t r = 0; r < regions.size(); r++) {
- if (regions[r]->sync()) {
+ for (NavRegion *region : regions) {
+ if (region->sync()) {
regenerate_links = true;
}
}
- for (uint32_t l = 0; l < links.size(); l++) {
- if (links[l]->check_dirty()) {
+ for (NavLink *link : links) {
+ if (link->check_dirty()) {
regenerate_links = true;
}
}
@@ -649,34 +643,32 @@ void NavMap::sync() {
_new_pm_edge_free_count = 0;
// Remove regions connections.
- for (uint32_t r = 0; r < regions.size(); r++) {
- regions[r]->get_connections().clear();
+ for (NavRegion *region : regions) {
+ region->get_connections().clear();
}
// Resize the polygon count.
int count = 0;
- for (uint32_t r = 0; r < regions.size(); r++) {
- count += regions[r]->get_polygons().size();
+ for (const NavRegion *region : regions) {
+ count += region->get_polygons().size();
}
polygons.resize(count);
// Copy all region polygons in the map.
count = 0;
- for (uint32_t r = 0; r < regions.size(); r++) {
- const LocalVector<gd::Polygon> &polygons_source = regions[r]->get_polygons();
+ for (const NavRegion *region : regions) {
+ const LocalVector<gd::Polygon> &polygons_source = region->get_polygons();
for (uint32_t n = 0; n < polygons_source.size(); n++) {
polygons[count + n] = polygons_source[n];
}
- count += regions[r]->get_polygons().size();
+ count += region->get_polygons().size();
}
_new_pm_polygon_count = polygons.size();
// Group all edges per key.
HashMap<gd::EdgeKey, Vector<gd::Edge::Connection>, gd::EdgeKey> connections;
- for (uint32_t poly_id = 0; poly_id < polygons.size(); poly_id++) {
- gd::Polygon &poly(polygons[poly_id]);
-
+ for (gd::Polygon &poly : polygons) {
for (uint32_t p = 0; p < poly.points.size(); p++) {
int next_point = (p + 1) % poly.points.size();
gd::EdgeKey ek(poly.points[p].key, poly.points[next_point].key);
@@ -787,8 +779,7 @@ void NavMap::sync() {
link_polygons.resize(links.size());
// Search for polygons within range of a nav link.
- for (uint32_t l = 0; l < links.size(); l++) {
- const NavLink *link = links[l];
+ for (const NavLink *link : links) {
const Vector3 start = link->get_start_location();
const Vector3 end = link->get_end_location();
@@ -820,9 +811,7 @@ void NavMap::sync() {
}
// Find any polygons within the search radius of the end point.
- for (uint32_t end_index = 0; end_index < polygons.size(); end_index++) {
- gd::Polygon &end_poly = polygons[end_index];
-
+ for (gd::Polygon &end_poly : polygons) {
// For each face check the distance to the end
for (uint32_t end_point_id = 2; end_point_id < end_poly.points.size(); end_point_id += 1) {
const Face3 end_face(end_poly.points[0].pos, end_poly.points[end_point_id - 1].pos, end_poly.points[end_point_id].pos);
@@ -906,8 +895,8 @@ void NavMap::sync() {
// cannot use LocalVector here as RVO library expects std::vector to build KdTree
std::vector<RVO::Agent *> raw_agents;
raw_agents.reserve(agents.size());
- for (size_t i(0); i < agents.size(); i++) {
- raw_agents.push_back(agents[i]->get_agent());
+ for (RvoAgent *agent : agents) {
+ raw_agents.push_back(agent->get_agent());
}
rvo.buildAgentTree(raw_agents);
}
@@ -941,8 +930,8 @@ void NavMap::step(real_t p_deltatime) {
}
void NavMap::dispatch_callbacks() {
- for (int i(0); i < static_cast<int>(controlled_agents.size()); i++) {
- controlled_agents[i]->dispatch_callback();
+ for (RvoAgent *agent : controlled_agents) {
+ agent->dispatch_callback();
}
}
diff --git a/modules/navigation/navigation_mesh_generator.cpp b/modules/navigation/navigation_mesh_generator.cpp
index fff7a02fc4..74ff9312fd 100644
--- a/modules/navigation/navigation_mesh_generator.cpp
+++ b/modules/navigation/navigation_mesh_generator.cpp
@@ -266,9 +266,7 @@ void NavigationMeshGenerator::_parse_geometry(const Transform3D &p_navmesh_trans
if (err == OK) {
PackedVector3Array faces;
- for (uint32_t j = 0; j < md.faces.size(); ++j) {
- const Geometry3D::MeshData::Face &face = md.faces[j];
-
+ for (const Geometry3D::MeshData::Face &face : md.faces) {
for (uint32_t k = 2; k < face.indices.size(); ++k) {
faces.push_back(md.vertices[face.indices[0]]);
faces.push_back(md.vertices[face.indices[k - 1]]);
@@ -392,9 +390,7 @@ void NavigationMeshGenerator::_parse_geometry(const Transform3D &p_navmesh_trans
if (err == OK) {
PackedVector3Array faces;
- for (uint32_t j = 0; j < md.faces.size(); ++j) {
- const Geometry3D::MeshData::Face &face = md.faces[j];
-
+ for (const Geometry3D::MeshData::Face &face : md.faces) {
for (uint32_t k = 2; k < face.indices.size(); ++k) {
faces.push_back(md.vertices[face.indices[0]]);
faces.push_back(md.vertices[face.indices[k - 1]]);
diff --git a/modules/raycast/raycast_occlusion_cull.cpp b/modules/raycast/raycast_occlusion_cull.cpp
index c74799caa3..9394f71e40 100644
--- a/modules/raycast/raycast_occlusion_cull.cpp
+++ b/modules/raycast/raycast_occlusion_cull.cpp
@@ -426,8 +426,8 @@ bool RaycastOcclusionCull::Scenario::update() {
return false;
}
- for (unsigned int i = 0; i < removed_instances.size(); i++) {
- instances.erase(removed_instances[i]);
+ for (const RID &scenario : removed_instances) {
+ instances.erase(scenario);
}
if (dirty_instances_array.size() / WorkerThreadPool::get_singleton()->get_thread_count() > 128) {