Repository: godotengine/godot (language: cpp)

Issue:
Text files generate .uid when saved from editor
### Tested versions

4.4 beta2

### System information

W10

### Issue description

When you open a text file (.txt, .cfg, etc.) in script editor and save it, it will create .uid file.
This is wrong for a couple reasons:
- .uid files should be generated automatically when resource is detected. In this case it happens only when saving with the built-in editor.
- TextFile does not expose any API that would allow to do anything useful, so the UID is useless. Surprisingly though, you can load it and it does return TextFile.
Both come from the fact that TextFile is a fake resource. It does not exist in filesystem, only in memory when you decide to edit a text file. Thus it should not be treated as Resource.

### Steps to reproduce

1. Create a .txt file in a project.
2. Open it in Script editor.
3. Save.
4. Look inside the folder 👀

### Minimal reproduction project (MRP)

N/A


Discussion / hints:
Reproduced on 71d80b26a4c47e1b5e1bab9ed8ef1512e359b5e9.

The weird thing is, that uid files exactly get created when you save from within the script editor:
No uid created for non-empty files added outside the editor.

I do agree, that uids for .txt (given no ImporterPlugin) make little sense, as they cannot be loaded as resources.

Also: 
`FileAccess.open("uid:://uid-to-resource", FLAGS)` works,
 while `FileAccess.open("uid:://uid-to-text-file", FLAGS)` throws "Invalid uid".


Fix patch:
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 7cc91ef4318b..04fd641f2446 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -1196,6 +1196,20 @@ bool ResourceLoader::has_custom_uid_support(const String &p_path) {
 	return false;
 }
 
+bool ResourceLoader::should_create_uid_file(const String &p_path) {
+	const String local_path = _validate_local_path(p_path);
+	if (FileAccess::exists(local_path + ".uid")) {
+		return false;
+	}
+
+	for (int i = 0; i < loader_count; i++) {
+		if (loader[i]->recognize_path(local_path)) {
+			return !loader[i]->has_custom_uid_support();
+		}
+	}
+	return false;
+}
+
 String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_remapped) {
 	String new_path = p_path;
 
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index 56052b6a6fc4..10a82e811d0f 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -246,6 +246,7 @@ class ResourceLoader {
 	static String get_resource_script_class(const String &p_path);
 	static ResourceUID::ID get_resource_uid(const String &p_path);
 	static bool has_custom_uid_support(const String &p_path);
+	static bool should_create_uid_file(const String &p_path);
 	static void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
 	static Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map);
 	static bool is_import_valid(const String &p_path);
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index 1db6c2a188e4..2d10e4305eaa 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -1263,7 +1263,7 @@ void EditorFileSystem::_process_file_system(const ScannedDirectory *p_scan_dir,
 				}
 			}
 
-			if (ResourceLoader::exists(path) && !ResourceLoader::has_custom_uid_support(path) && !FileAccess::exists(path + ".uid")) {
+			if (ResourceLoader::should_create_uid_file(path)) {
 				// Create a UID file and new UID, if it's invalid.
 				Ref<FileAccess> f = FileAccess::open(path + ".uid", FileAccess::WRITE);
 				if (f.is_valid()) {
@@ -2345,7 +2345,7 @@ void EditorFileSystem::update_files(const Vector<String> &p_script_paths) {
 
 				ResourceUID::get_singleton()->update_cache();
 			} else {
-				if (ResourceLoader::exists(file) && !ResourceLoader::has_custom_uid_support(file) && !FileAccess::exists(file + ".uid")) {
+				if (ResourceLoader::should_create_uid_file(file)) {
 					Ref<FileAccess> f = FileAccess::open(file + ".uid", FileAccess::WRITE);
 					if (f.is_valid()) {
 						const ResourceUID::ID id = ResourceUID::get_singleton()->create_id();


Test patch: