Преглед изворни кода

Mono: Avoid invalid class names.

Disallow reserved keywords as class names and prefix base class with the Godot
namespace if it's the same as the class name.

Fixes #12483
Andreas Haas пре 7 година
родитељ
комит
700d07cf7c
4 измењених фајлова са 33 додато и 2 уклоњено
  1. 1 0
      core/script_language.h
  2. 7 0
      editor/script_create_dialog.cpp
  3. 24 2
      modules/mono/csharp_script.cpp
  4. 1 0
      modules/mono/csharp_script.h

+ 1 - 0
core/script_language.h

@@ -203,6 +203,7 @@ public:
 	virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {}
 	virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {}
 	virtual bool is_using_templates() { return false; }
 	virtual bool is_using_templates() { return false; }
 	virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL) const = 0;
 	virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL) const = 0;
+	virtual String validate_path(const String &p_path) const { return ""; }
 	virtual Script *create_script() const = 0;
 	virtual Script *create_script() const = 0;
 	virtual bool has_named_classes() const = 0;
 	virtual bool has_named_classes() const = 0;
 	virtual bool supports_builtin_mode() const = 0;
 	virtual bool supports_builtin_mode() const = 0;

+ 7 - 0
editor/script_create_dialog.cpp

@@ -434,6 +434,13 @@ void ScriptCreateDialog::_path_changed(const String &p_path) {
 		return;
 		return;
 	}
 	}
 
 
+	String path_error = ScriptServer::get_language(language_menu->get_selected())->validate_path(p);
+	if (path_error != "") {
+		_msg_path_valid(false, path_error);
+		_update_dialog();
+		return;
+	}
+
 	/* All checks passed */
 	/* All checks passed */
 
 
 	is_path_valid = true;
 	is_path_valid = true;

+ 24 - 2
modules/mono/csharp_script.cpp

@@ -282,6 +282,15 @@ void CSharpLanguage::get_string_delimiters(List<String> *p_delimiters) const {
 	p_delimiters->push_back("@\" \""); // verbatim string literal
 	p_delimiters->push_back("@\" \""); // verbatim string literal
 }
 }
 
 
+static String get_base_class_name(const String &p_base_class_name, const String p_class_name) {
+
+	String base_class = p_base_class_name;
+	if (p_class_name == base_class) {
+		base_class = "Godot." + base_class;
+	}
+	return base_class;
+}
+
 Ref<Script> CSharpLanguage::get_template(const String &p_class_name, const String &p_base_class_name) const {
 Ref<Script> CSharpLanguage::get_template(const String &p_class_name, const String &p_base_class_name) const {
 
 
 	String script_template = "using " BINDINGS_NAMESPACE ";\n"
 	String script_template = "using " BINDINGS_NAMESPACE ";\n"
@@ -308,7 +317,8 @@ Ref<Script> CSharpLanguage::get_template(const String &p_class_name, const Strin
 							 "//    }\n"
 							 "//    }\n"
 							 "}\n";
 							 "}\n";
 
 
-	script_template = script_template.replace("%BASE_CLASS_NAME%", p_base_class_name)
+	String base_class_name = get_base_class_name(p_base_class_name, p_class_name);
+	script_template = script_template.replace("%BASE_CLASS_NAME%", base_class_name)
 							  .replace("%CLASS_NAME%", p_class_name);
 							  .replace("%CLASS_NAME%", p_class_name);
 
 
 	Ref<CSharpScript> script;
 	Ref<CSharpScript> script;
@@ -327,12 +337,24 @@ bool CSharpLanguage::is_using_templates() {
 void CSharpLanguage::make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {
 void CSharpLanguage::make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {
 
 
 	String src = p_script->get_source_code();
 	String src = p_script->get_source_code();
-	src = src.replace("%BASE%", p_base_class_name)
+	String base_class_name = get_base_class_name(p_base_class_name, p_class_name);
+	src = src.replace("%BASE%", base_class_name)
 				  .replace("%CLASS%", p_class_name)
 				  .replace("%CLASS%", p_class_name)
 				  .replace("%TS%", _get_indentation());
 				  .replace("%TS%", _get_indentation());
 	p_script->set_source_code(src);
 	p_script->set_source_code(src);
 }
 }
 
 
+String CSharpLanguage::validate_path(const String &p_path) const {
+
+	String class_name = p_path.get_file().get_basename();
+	List<String> keywords;
+	get_reserved_words(&keywords);
+	if (keywords.find(class_name)) {
+		return TTR("Class name can't be a reserved keyword");
+	}
+	return "";
+}
+
 Script *CSharpLanguage::create_script() const {
 Script *CSharpLanguage::create_script() const {
 
 
 	return memnew(CSharpScript);
 	return memnew(CSharpScript);

+ 1 - 0
modules/mono/csharp_script.h

@@ -294,6 +294,7 @@ public:
 	virtual bool is_using_templates();
 	virtual bool is_using_templates();
 	virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script);
 	virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script);
 	/* TODO */ virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions) const { return true; }
 	/* TODO */ virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions) const { return true; }
+	virtual String validate_path(const String &p_path) const;
 	virtual Script *create_script() const;
 	virtual Script *create_script() const;
 	virtual bool has_named_classes() const;
 	virtual bool has_named_classes() const;
 	virtual bool supports_builtin_mode() const;
 	virtual bool supports_builtin_mode() const;