Browse Source

Merge pull request #69467 from rune-scape/rune-subclass-script-path

GDScript: Fix subclass script path issues
Rémi Verschelde 2 years ago
parent
commit
f6ea295bb1

+ 12 - 6
modules/gdscript/gdscript.cpp

@@ -478,7 +478,7 @@ void GDScript::_clear_doc() {
 void GDScript::_update_doc() {
 void GDScript::_update_doc() {
 	_clear_doc();
 	_clear_doc();
 
 
-	doc.script_path = "\"" + get_path().get_slice("://", 1) + "\"";
+	doc.script_path = vformat(R"("%s")", get_script_path().get_slice("://", 1));
 	if (!name.is_empty()) {
 	if (!name.is_empty()) {
 		doc.name = name;
 		doc.name = name;
 	} else {
 	} else {
@@ -801,9 +801,9 @@ void GDScript::update_exports() {
 
 
 String GDScript::_get_debug_path() const {
 String GDScript::_get_debug_path() const {
 	if (is_built_in() && !get_name().is_empty()) {
 	if (is_built_in() && !get_name().is_empty()) {
-		return get_name() + " (" + get_path() + ")";
+		return vformat("%s(%s)", get_name(), get_script_path());
 	} else {
 	} else {
-		return get_path();
+		return get_script_path();
 	}
 	}
 }
 }
 
 
@@ -904,7 +904,7 @@ Error GDScript::reload(bool p_keep_state) {
 	for (const GDScriptWarning &warning : parser.get_warnings()) {
 	for (const GDScriptWarning &warning : parser.get_warnings()) {
 		if (EngineDebugger::is_active()) {
 		if (EngineDebugger::is_active()) {
 			Vector<ScriptLanguage::StackInfo> si;
 			Vector<ScriptLanguage::StackInfo> si;
-			EngineDebugger::get_script_debugger()->send_error("", get_path(), warning.start_line, warning.get_name(), warning.get_message(), false, ERR_HANDLER_WARNING, si);
+			EngineDebugger::get_script_debugger()->send_error("", get_script_path(), warning.start_line, warning.get_name(), warning.get_message(), false, ERR_HANDLER_WARNING, si);
 		}
 		}
 	}
 	}
 #endif
 #endif
@@ -1027,6 +1027,10 @@ void GDScript::set_path(const String &p_path, bool p_take_over) {
 	}
 	}
 }
 }
 
 
+String GDScript::get_script_path() const {
+	return path;
+}
+
 Error GDScript::load_source_code(const String &p_path) {
 Error GDScript::load_source_code(const String &p_path) {
 	if (p_path.is_empty() || ResourceLoader::get_resource_type(p_path.get_slice("::", 0)) == "PackedScene") {
 	if (p_path.is_empty() || ResourceLoader::get_resource_type(p_path.get_slice("::", 0)) == "PackedScene") {
 		return OK;
 		return OK;
@@ -2164,7 +2168,8 @@ void GDScriptLanguage::reload_all_scripts() {
 
 
 		SelfList<GDScript> *elem = script_list.first();
 		SelfList<GDScript> *elem = script_list.first();
 		while (elem) {
 		while (elem) {
-			if (elem->self()->get_path().is_resource_file()) {
+			// Scripts will reload all subclasses, so only reload root scripts.
+			if (elem->self()->is_root_script() && elem->self()->get_path().is_resource_file()) {
 				print_verbose("GDScript: Found: " + elem->self()->get_path());
 				print_verbose("GDScript: Found: " + elem->self()->get_path());
 				scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident
 				scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident
 			}
 			}
@@ -2193,7 +2198,8 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
 
 
 		SelfList<GDScript> *elem = script_list.first();
 		SelfList<GDScript> *elem = script_list.first();
 		while (elem) {
 		while (elem) {
-			if (elem->self()->get_path().is_resource_file()) {
+			// Scripts will reload all subclasses, so only reload root scripts.
+			if (elem->self()->is_root_script() && elem->self()->get_path().is_resource_file()) {
 				scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident
 				scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident
 			}
 			}
 			elem = elem->next();
 			elem = elem->next();

+ 2 - 1
modules/gdscript/gdscript.h

@@ -240,6 +240,7 @@ public:
 	virtual Error reload(bool p_keep_state = false) override;
 	virtual Error reload(bool p_keep_state = false) override;
 
 
 	virtual void set_path(const String &p_path, bool p_take_over = false) override;
 	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_source_code(const String &p_path);
 	Error load_byte_code(const String &p_path);
 	Error load_byte_code(const String &p_path);
 
 
@@ -432,7 +433,7 @@ public:
 			csi.write[_debug_call_stack_pos - i - 1].line = _call_stack[i].line ? *_call_stack[i].line : 0;
 			csi.write[_debug_call_stack_pos - i - 1].line = _call_stack[i].line ? *_call_stack[i].line : 0;
 			if (_call_stack[i].function) {
 			if (_call_stack[i].function) {
 				csi.write[_debug_call_stack_pos - i - 1].func = _call_stack[i].function->get_name();
 				csi.write[_debug_call_stack_pos - i - 1].func = _call_stack[i].function->get_name();
-				csi.write[_debug_call_stack_pos - i - 1].file = _call_stack[i].function->get_script()->get_path();
+				csi.write[_debug_call_stack_pos - i - 1].file = _call_stack[i].function->get_script()->get_script_path();
 			}
 			}
 		}
 		}
 		return csi;
 		return csi;

+ 5 - 5
modules/gdscript/gdscript_analyzer.cpp

@@ -545,9 +545,9 @@ GDScriptParser::DataType GDScriptAnalyzer::resolve_datatype(GDScriptParser::Type
 						} else if (Ref<Script>(member.constant->initializer->reduced_value).is_valid()) {
 						} else if (Ref<Script>(member.constant->initializer->reduced_value).is_valid()) {
 							Ref<GDScript> gdscript = member.constant->initializer->reduced_value;
 							Ref<GDScript> gdscript = member.constant->initializer->reduced_value;
 							if (gdscript.is_valid()) {
 							if (gdscript.is_valid()) {
-								Ref<GDScriptParserRef> ref = get_parser_for(gdscript->get_path());
+								Ref<GDScriptParserRef> ref = get_parser_for(gdscript->get_script_path());
 								if (ref->raise_status(GDScriptParserRef::INTERFACE_SOLVED) != OK) {
 								if (ref->raise_status(GDScriptParserRef::INTERFACE_SOLVED) != OK) {
-									push_error(vformat(R"(Could not parse script from "%s".)", gdscript->get_path()), p_type);
+									push_error(vformat(R"(Could not parse script from "%s".)", gdscript->get_script_path()), p_type);
 									return GDScriptParser::DataType();
 									return GDScriptParser::DataType();
 								}
 								}
 								result = ref->get_parser()->head->get_datatype();
 								result = ref->get_parser()->head->get_datatype();
@@ -3136,9 +3136,9 @@ void GDScriptAnalyzer::reduce_identifier(GDScriptParser::IdentifierNode *p_ident
 					Variant constant = GDScriptLanguage::get_singleton()->get_named_globals_map()[name];
 					Variant constant = GDScriptLanguage::get_singleton()->get_named_globals_map()[name];
 					Node *node = Object::cast_to<Node>(constant);
 					Node *node = Object::cast_to<Node>(constant);
 					if (node != nullptr) {
 					if (node != nullptr) {
-						Ref<Script> scr = node->get_script();
+						Ref<GDScript> scr = node->get_script();
 						if (scr.is_valid()) {
 						if (scr.is_valid()) {
-							Ref<GDScriptParserRef> singl_parser = get_parser_for(scr->get_path());
+							Ref<GDScriptParserRef> singl_parser = get_parser_for(scr->get_script_path());
 							if (singl_parser.is_valid()) {
 							if (singl_parser.is_valid()) {
 								Error err = singl_parser->raise_status(GDScriptParserRef::INTERFACE_SOLVED);
 								Error err = singl_parser->raise_status(GDScriptParserRef::INTERFACE_SOLVED);
 								if (err == OK) {
 								if (err == OK) {
@@ -3341,7 +3341,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri
 			Ref<GDScript> gdscr = Ref<GDScript>(p_subscript->base->reduced_value);
 			Ref<GDScript> gdscr = Ref<GDScript>(p_subscript->base->reduced_value);
 			if (!valid && gdscr.is_valid()) {
 			if (!valid && gdscr.is_valid()) {
 				Error err = OK;
 				Error err = OK;
-				GDScriptCache::get_full_script(gdscr->get_path(), err);
+				GDScriptCache::get_full_script(gdscr->get_script_path(), err);
 				if (err == OK) {
 				if (err == OK) {
 					value = p_subscript->base->reduced_value.get_named(p_subscript->attribute->name, valid);
 					value = p_subscript->base->reduced_value.get_named(p_subscript->attribute->name, valid);
 				}
 				}

+ 1 - 1
modules/gdscript/gdscript_byte_codegen.cpp

@@ -164,7 +164,7 @@ void GDScriptByteCodeGenerator::write_start(GDScript *p_script, const StringName
 
 
 	function->name = p_function_name;
 	function->name = p_function_name;
 	function->_script = p_script;
 	function->_script = p_script;
-	function->source = p_script->get_path();
+	function->source = p_script->get_script_path();
 
 
 #ifdef DEBUG_ENABLED
 #ifdef DEBUG_ENABLED
 	function->func_cname = (String(function->source) + " - " + String(p_function_name)).utf8();
 	function->func_cname = (String(function->source) + " - " + String(p_function_name)).utf8();

+ 2 - 2
modules/gdscript/gdscript_compiler.cpp

@@ -2117,8 +2117,8 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_
 	if (EngineDebugger::is_active()) {
 	if (EngineDebugger::is_active()) {
 		String signature;
 		String signature;
 		// Path.
 		// Path.
-		if (!p_script->get_path().is_empty()) {
-			signature += p_script->get_path();
+		if (!p_script->get_script_path().is_empty()) {
+			signature += p_script->get_script_path();
 		}
 		}
 		// Location.
 		// Location.
 		if (p_func) {
 		if (p_func) {

+ 3 - 2
modules/gdscript/gdscript_utility_functions.cpp

@@ -294,6 +294,7 @@ struct GDScriptUtilityFunctionsDefinitions {
 				}
 				}
 
 
 				GDScript *p = base.ptr();
 				GDScript *p = base.ptr();
+				String path = p->get_script_path();
 				Vector<StringName> sname;
 				Vector<StringName> sname;
 
 
 				while (p->_owner) {
 				while (p->_owner) {
@@ -302,7 +303,7 @@ struct GDScriptUtilityFunctionsDefinitions {
 				}
 				}
 				sname.reverse();
 				sname.reverse();
 
 
-				if (!p->path.is_resource_file()) {
+				if (!path.is_resource_file()) {
 					r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 					r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 					r_error.argument = 0;
 					r_error.argument = 0;
 					r_error.expected = Variant::DICTIONARY;
 					r_error.expected = Variant::DICTIONARY;
@@ -317,7 +318,7 @@ struct GDScriptUtilityFunctionsDefinitions {
 
 
 				Dictionary d;
 				Dictionary d;
 				d["@subpath"] = cp;
 				d["@subpath"] = cp;
-				d["@path"] = p->get_path();
+				d["@path"] = path;
 
 
 				for (const KeyValue<StringName, GDScript::MemberInfo> &E : base->member_indices) {
 				for (const KeyValue<StringName, GDScript::MemberInfo> &E : base->member_indices) {
 					if (!d.has(E.key)) {
 					if (!d.has(E.key)) {

+ 1 - 1
modules/gdscript/gdscript_vm.cpp

@@ -2227,7 +2227,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
 					}
 					}
 #ifdef DEBUG_ENABLED
 #ifdef DEBUG_ENABLED
 					gdfs->state.function_name = name;
 					gdfs->state.function_name = name;
-					gdfs->state.script_path = _script->get_path();
+					gdfs->state.script_path = _script->get_script_path();
 #endif
 #endif
 					gdfs->state.defarg = defarg;
 					gdfs->state.defarg = defarg;
 					gdfs->function = this;
 					gdfs->function = this;