Browse Source

Disallow class names to be the same as global names

Also forbid autoloads to have the same name as global script class.
George Marques 3 years ago
parent
commit
2e5fa124f4
2 changed files with 20 additions and 1 deletions
  1. 8 0
      editor/editor_autoload_settings.cpp
  2. 12 1
      modules/gdscript/gdscript_analyzer.cpp

+ 8 - 0
editor/editor_autoload_settings.cpp

@@ -78,6 +78,14 @@ bool EditorAutoloadSettings::_autoload_name_is_valid(const String &p_name, Strin
 		return false;
 	}
 
+	if (ScriptServer::is_global_class(p_name)) {
+		if (r_error) {
+			*r_error = TTR("Invalid name.") + "\n" + TTR("Must not collide with an existing global script class name.");
+		}
+
+		return false;
+	}
+
 	for (int i = 0; i < Variant::VARIANT_MAX; i++) {
 		if (Variant::get_type_name(Variant::Type(i)) == p_name) {
 			if (r_error) {

+ 12 - 1
modules/gdscript/gdscript_analyzer.cpp

@@ -171,7 +171,7 @@ Error GDScriptAnalyzer::check_native_member_name_conflict(const StringName &p_me
 	}
 
 	if (class_exists(p_member_name)) {
-		push_error(vformat(R"(The class "%s" shadows a native class.)", p_member_name), p_member_node);
+		push_error(vformat(R"(The member "%s" shadows a native class.)", p_member_name), p_member_node);
 		return ERR_PARSE_ERROR;
 	}
 
@@ -218,6 +218,17 @@ Error GDScriptAnalyzer::resolve_inheritance(GDScriptParser::ClassNode *p_class,
 		p_class->fqcn = p_class->outer->fqcn + "::" + String(p_class->identifier->name);
 	}
 
+	if (p_class->identifier) {
+		StringName class_name = p_class->identifier->name;
+		if (class_exists(class_name)) {
+			push_error(vformat(R"(Class "%s" hides a native class.)", class_name), p_class->identifier);
+		} else if (ScriptServer::is_global_class(class_name) && (ScriptServer::get_global_class_path(class_name) != parser->script_path || p_class != parser->head)) {
+			push_error(vformat(R"(Class "%s" hides a global script class.)", class_name), p_class->identifier);
+		} else if (ProjectSettings::get_singleton()->has_autoload(class_name) && ProjectSettings::get_singleton()->get_autoload(class_name).is_singleton) {
+			push_error(vformat(R"(Class "%s" hides an autoload singleton.)", class_name), p_class->identifier);
+		}
+	}
+
 	GDScriptParser::DataType result;
 
 	// Set datatype for class.