Explorar o código

Add custom api `textDocument/nativeSymbol` to allow inspect native symbols from LSP clients

geequlim %!s(int64=5) %!d(string=hai) anos
pai
achega
e199488bc7

+ 3 - 2
modules/gdscript/language_server/gdscript_language_protocol.cpp

@@ -153,9 +153,10 @@ Error GDScriptLanguageProtocol::start(int p_port) {
 }
 
 void GDScriptLanguageProtocol::stop() {
-	const int *ptr = NULL;
-	while (ptr = clients.next(ptr)) {
+	const int *ptr = clients.next(NULL);
+	while (ptr) {
 		clients.get(*ptr)->close();
+		ptr = clients.next(ptr);
 	}
 	server->stop();
 	clients.clear();

+ 22 - 1
modules/gdscript/language_server/gdscript_text_document.cpp

@@ -39,6 +39,7 @@
 void GDScriptTextDocument::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("didOpen"), &GDScriptTextDocument::didOpen);
 	ClassDB::bind_method(D_METHOD("didChange"), &GDScriptTextDocument::didChange);
+	ClassDB::bind_method(D_METHOD("nativeSymbol"), &GDScriptTextDocument::nativeSymbol);
 	ClassDB::bind_method(D_METHOD("documentSymbol"), &GDScriptTextDocument::documentSymbol);
 	ClassDB::bind_method(D_METHOD("completion"), &GDScriptTextDocument::completion);
 	ClassDB::bind_method(D_METHOD("resolve"), &GDScriptTextDocument::resolve);
@@ -75,6 +76,11 @@ lsp::TextDocumentItem GDScriptTextDocument::load_document_item(const Variant &p_
 	return doc;
 }
 
+void GDScriptTextDocument::notify_client_show_symbol(const lsp::DocumentSymbol *symbol) {
+	ERR_FAIL_NULL(symbol);
+	GDScriptLanguageProtocol::get_singleton()->notify_client("gdscript/show_native_symbol", symbol->to_json(true));
+}
+
 void GDScriptTextDocument::initialize() {
 
 	if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) {
@@ -102,6 +108,21 @@ void GDScriptTextDocument::initialize() {
 	}
 }
 
+Variant GDScriptTextDocument::nativeSymbol(const Dictionary &p_params) {
+
+	Variant ret;
+
+	lsp::NativeSymbolInspectParams params;
+	params.load(p_params);
+
+	if (const lsp::DocumentSymbol *symbol = GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_native_symbol(params)) {
+		ret = symbol->to_json(true);
+		notify_client_show_symbol(symbol);
+	}
+
+	return ret;
+}
+
 Array GDScriptTextDocument::documentSymbol(const Dictionary &p_params) {
 	Dictionary params = p_params["textDocument"];
 	String uri = params["uri"];
@@ -362,7 +383,7 @@ Array GDScriptTextDocument::definition(const Dictionary &p_params) {
 				}
 				call_deferred("show_native_symbol_in_editor", id);
 			} else {
-				GDScriptLanguageProtocol::get_singleton()->notify_client("gdscript/show_native_symbol", symbol->to_json(true));
+				notify_client_show_symbol(symbol);
 			}
 		}
 	} else if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) {

+ 2 - 0
modules/gdscript/language_server/gdscript_text_document.h

@@ -52,8 +52,10 @@ protected:
 
 private:
 	lsp::TextDocumentItem load_document_item(const Variant &p_param);
+	void notify_client_show_symbol(const lsp::DocumentSymbol *symbol);
 
 public:
+	Variant nativeSymbol(const Dictionary &p_params);
 	Array documentSymbol(const Dictionary &p_params);
 	Array completion(const Dictionary &p_params);
 	Dictionary resolve(const Dictionary &p_params);

+ 18 - 0
modules/gdscript/language_server/gdscript_workspace.cpp

@@ -475,6 +475,24 @@ void GDScriptWorkspace::resolve_related_symbols(const lsp::TextDocumentPositionP
 	}
 }
 
+const lsp::DocumentSymbol *GDScriptWorkspace::resolve_native_symbol(const lsp::NativeSymbolInspectParams &p_params) {
+
+	if (Map<StringName, lsp::DocumentSymbol>::Element *E = native_symbols.find(p_params.native_class)) {
+		const lsp::DocumentSymbol &symbol = E->get();
+		if (p_params.symbol_name.empty() || p_params.symbol_name == symbol.name) {
+			return &symbol;
+		}
+
+		for (int i = 0; i < symbol.children.size(); ++i) {
+			if (symbol.children[i].name == p_params.symbol_name) {
+				return &(symbol.children[i]);
+			}
+		}
+	}
+
+	return NULL;
+}
+
 void GDScriptWorkspace::resolve_document_links(const String &p_uri, List<lsp::DocumentLink> &r_list) {
 	if (const ExtendGDScriptParser *parser = get_parse_successed_script(get_file_path(p_uri))) {
 		const List<lsp::DocumentLink> &links = parser->get_document_links();

+ 1 - 1
modules/gdscript/language_server/gdscript_workspace.h

@@ -80,7 +80,7 @@ public:
 
 	const lsp::DocumentSymbol *resolve_symbol(const lsp::TextDocumentPositionParams &p_doc_pos, const String &p_symbol_name = "", bool p_func_requred = false);
 	void resolve_related_symbols(const lsp::TextDocumentPositionParams &p_doc_pos, List<const lsp::DocumentSymbol *> &r_list);
-
+	const lsp::DocumentSymbol *resolve_native_symbol(const lsp::NativeSymbolInspectParams &p_params);
 	void resolve_document_links(const String &p_uri, List<lsp::DocumentLink> &r_list);
 	Dictionary generate_script_api(const String &p_path);
 

+ 12 - 1
modules/gdscript/language_server/lsp.hpp

@@ -1134,7 +1134,7 @@ struct DocumentSymbol {
 	 */
 	Vector<DocumentSymbol> children;
 
-	_FORCE_INLINE_ Dictionary to_json(bool with_doc = false) const {
+	Dictionary to_json(bool with_doc = false) const {
 		Dictionary dict;
 		dict["name"] = name;
 		dict["detail"] = detail;
@@ -1233,6 +1233,17 @@ struct DocumentSymbol {
 	}
 };
 
+struct NativeSymbolInspectParams {
+
+	String native_class;
+	String symbol_name;
+
+	void load(const Dictionary &p_params) {
+		native_class = p_params["native_class"];
+		symbol_name = p_params["symbol_name"];
+	}
+};
+
 /**
  * Enum of known range kinds
  */