Browse Source

Improve LSP completion using scene owner
Fixes: #36473

(cherry picked from commit 06bce137e38ecf0e3c024ddff8356c8cfd9c4d5b)

Rafael Delboni 5 years ago
parent
commit
ecfe9c24a2

+ 48 - 1
modules/gdscript/language_server/gdscript_workspace.cpp

@@ -33,8 +33,11 @@
 #include "../gdscript_parser.h"
 #include "core/project_settings.h"
 #include "core/script_language.h"
+#include "editor/editor_file_system.h"
 #include "editor/editor_help.h"
+#include "editor/editor_node.h"
 #include "gdscript_language_protocol.h"
+#include "scene/resources/packed_scene.h"
 
 void GDScriptWorkspace::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("symbol"), &GDScriptWorkspace::symbol);
@@ -373,6 +376,46 @@ void GDScriptWorkspace::publish_diagnostics(const String &p_path) {
 	GDScriptLanguageProtocol::get_singleton()->notify_client("textDocument/publishDiagnostics", params);
 }
 
+void GDScriptWorkspace::_get_owners(EditorFileSystemDirectory *efsd, String p_path, List<String> &owners) {
+	if (!efsd)
+		return;
+
+	for (int i = 0; i < efsd->get_subdir_count(); i++) {
+		_get_owners(efsd->get_subdir(i), p_path, owners);
+	}
+
+	for (int i = 0; i < efsd->get_file_count(); i++) {
+
+		Vector<String> deps = efsd->get_file_deps(i);
+		bool found = false;
+		for (int j = 0; j < deps.size(); j++) {
+			if (deps[j] == p_path) {
+				found = true;
+				break;
+			}
+		}
+		if (!found)
+			continue;
+
+		owners.push_back(efsd->get_file_path(i));
+	}
+}
+
+Node *GDScriptWorkspace::_get_owner_node(String p_path) {
+	Node *owner_node = NULL;
+	List<String> owners;
+
+	_get_owners(EditorFileSystem::get_singleton()->get_filesystem(), p_path, owners);
+
+	if (owners.size() > 0) {
+		NodePath owner_path = owners[0];
+		Ref<PackedScene> owner_res = ResourceLoader::load(owner_path);
+		owner_node = owner_res->instance(PackedScene::GEN_EDIT_STATE_DISABLED);
+	}
+
+	return owner_node;
+}
+
 void GDScriptWorkspace::completion(const lsp::CompletionParams &p_params, List<ScriptCodeCompletionOption> *r_options) {
 
 	String path = get_file_path(p_params.textDocument.uri);
@@ -380,8 +423,12 @@ void GDScriptWorkspace::completion(const lsp::CompletionParams &p_params, List<S
 	bool forced = false;
 
 	if (const ExtendGDScriptParser *parser = get_parse_result(path)) {
+		Node *owner_node = _get_owner_node(path);
 		String code = parser->get_text_for_completion(p_params.position);
-		GDScriptLanguage::get_singleton()->complete_code(code, path, NULL, r_options, forced, call_hint);
+		GDScriptLanguage::get_singleton()->complete_code(code, path, owner_node, r_options, forced, call_hint);
+		if (owner_node) {
+			memdelete(owner_node);
+		}
 	}
 }
 

+ 5 - 0
modules/gdscript/language_server/gdscript_workspace.h

@@ -33,12 +33,17 @@
 
 #include "../gdscript_parser.h"
 #include "core/variant.h"
+#include "editor/editor_file_system.h"
 #include "gdscript_extend_parser.h"
 #include "lsp.hpp"
 
 class GDScriptWorkspace : public Reference {
 	GDCLASS(GDScriptWorkspace, Reference);
 
+private:
+	void _get_owners(EditorFileSystemDirectory *efsd, String p_path, List<String> &owners);
+	Node *_get_owner_node(String p_path);
+
 protected:
 	static void _bind_methods();
 	void remove_cache_parser(const String &p_path);