Browse Source

Merge pull request #90860 from vnen/gdscript-get-dependencies

GDScript: Implement `get_dependencies()`
Rémi Verschelde 1 year ago
parent
commit
c4733e8003

+ 7 - 2
modules/gdscript/gdscript.cpp

@@ -2892,7 +2892,7 @@ String ResourceFormatLoaderGDScript::get_resource_type(const String &p_path) con
 	return "";
 }
 
-void ResourceFormatLoaderGDScript::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
+void ResourceFormatLoaderGDScript::get_dependencies(const String &p_path, List<String> *r_dependencies, bool p_add_types) {
 	Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::READ);
 	ERR_FAIL_COND_MSG(file.is_null(), "Cannot open file '" + p_path + "'.");
 
@@ -2906,8 +2906,13 @@ void ResourceFormatLoaderGDScript::get_dependencies(const String &p_path, List<S
 		return;
 	}
 
+	GDScriptAnalyzer analyzer(&parser);
+	if (OK != analyzer.analyze()) {
+		return;
+	}
+
 	for (const String &E : parser.get_dependencies()) {
-		p_dependencies->push_back(E);
+		r_dependencies->push_back(E);
 	}
 }
 

+ 1 - 1
modules/gdscript/gdscript.h

@@ -633,7 +633,7 @@ public:
 	virtual void get_recognized_extensions(List<String> *p_extensions) const override;
 	virtual bool handles_type(const String &p_type) const override;
 	virtual String get_resource_type(const String &p_path) const override;
-	virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false) override;
+	virtual void get_dependencies(const String &p_path, List<String> *r_dependencies, bool p_add_types = false) override;
 };
 
 class ResourceFormatSaverGDScript : public ResourceFormatSaver {

+ 14 - 1
modules/gdscript/gdscript_analyzer.cpp

@@ -562,6 +562,11 @@ Error GDScriptAnalyzer::resolve_class_inheritance(GDScriptParser::ClassNode *p_c
 	class_type.native_type = result.native_type;
 	p_class->set_datatype(class_type);
 
+	// Add base class to the list of dependencies.
+	if (result.kind == GDScriptParser::DataType::CLASS) {
+		parser->add_dependency(result.script_path);
+	}
+
 	// Apply annotations.
 	for (GDScriptParser::AnnotationNode *&E : p_class->annotations) {
 		resolve_annotation(E);
@@ -868,6 +873,11 @@ GDScriptParser::DataType GDScriptAnalyzer::resolve_datatype(GDScriptParser::Type
 	}
 
 	p_type->set_datatype(result);
+
+	if (result.kind == GDScriptParser::DataType::CLASS || result.kind == GDScriptParser::DataType::SCRIPT) {
+		parser->add_dependency(result.script_path);
+	}
+
 	return result;
 }
 
@@ -4082,6 +4092,7 @@ void GDScriptAnalyzer::reduce_identifier(GDScriptParser::IdentifierNode *p_ident
 
 	if (ScriptServer::is_global_class(name)) {
 		p_identifier->set_datatype(make_global_class_meta_type(name, p_identifier));
+		parser->add_dependency(p_identifier->get_datatype().script_path);
 		return;
 	}
 
@@ -4124,6 +4135,7 @@ void GDScriptAnalyzer::reduce_identifier(GDScriptParser::IdentifierNode *p_ident
 			}
 			result.is_constant = true;
 			p_identifier->set_datatype(result);
+			parser->add_dependency(autoload.path);
 			return;
 		}
 	}
@@ -4243,7 +4255,6 @@ void GDScriptAnalyzer::reduce_preload(GDScriptParser::PreloadNode *p_preload) {
 		push_error("Preloaded path must be a constant string.", p_preload->path);
 	} else {
 		p_preload->resolved_path = p_preload->path->reduced_value;
-		// TODO: Save this as script dependency.
 		if (p_preload->resolved_path.is_relative_path()) {
 			p_preload->resolved_path = parser->script_path.get_base_dir().path_join(p_preload->resolved_path);
 		}
@@ -4274,6 +4285,8 @@ void GDScriptAnalyzer::reduce_preload(GDScriptParser::PreloadNode *p_preload) {
 					push_error(vformat(R"(Could not preload resource file "%s".)", p_preload->resolved_path), p_preload->path);
 				}
 			}
+
+			parser->add_dependency(p_preload->resolved_path);
 		}
 	}
 

+ 7 - 3
modules/gdscript/gdscript_parser.h

@@ -1429,6 +1429,8 @@ private:
 	void reset_extents(Node *p_node, GDScriptTokenizer::Token p_token);
 	void reset_extents(Node *p_node, Node *p_from);
 
+	HashSet<String> dependencies;
+
 	template <typename T>
 	T *alloc_node() {
 		T *node = memnew(T);
@@ -1572,9 +1574,11 @@ public:
 	bool annotation_exists(const String &p_annotation_name) const;
 
 	const List<ParserError> &get_errors() const { return errors; }
-	const List<String> get_dependencies() const {
-		// TODO: Keep track of deps.
-		return List<String>();
+	const HashSet<String> &get_dependencies() const {
+		return dependencies;
+	}
+	void add_dependency(const String &p_dependency) {
+		dependencies.insert(p_dependency);
 	}
 #ifdef DEBUG_ENABLED
 	const List<GDScriptWarning> &get_warnings() const { return warnings; }