mirror of
https://github.com/godotengine/godot
synced 2024-09-05 04:28:29 +00:00
Implement DocumentLink of GDScript LSP Server
This commit is contained in:
parent
d1a6964d39
commit
6a8303f82f
|
@ -105,6 +105,40 @@ void ExtendGDScriptParser::update_symbols() {
|
|||
}
|
||||
}
|
||||
|
||||
void ExtendGDScriptParser::update_document_links(const String &p_code) {
|
||||
document_links.clear();
|
||||
|
||||
GDScriptTokenizerText tokenizer;
|
||||
FileAccessRef fs = FileAccess::create(FileAccess::ACCESS_RESOURCES);
|
||||
tokenizer.set_code(p_code);
|
||||
while (true) {
|
||||
if (tokenizer.get_token() == GDScriptTokenizer::TK_EOF) {
|
||||
break;
|
||||
} else if (tokenizer.get_token() == GDScriptTokenizer::TK_CONSTANT) {
|
||||
Variant const_val = tokenizer.get_token_constant();
|
||||
if (const_val.get_type() == Variant::STRING) {
|
||||
String path = const_val;
|
||||
bool exists = fs->file_exists(path);
|
||||
if (!exists) {
|
||||
path = get_path().get_base_dir() + "/" + path;
|
||||
exists = fs->file_exists(path);
|
||||
}
|
||||
if (exists) {
|
||||
String value = const_val;
|
||||
lsp::DocumentLink link;
|
||||
link.target = GDScriptLanguageProtocol::get_singleton()->get_workspace()->get_file_uri(path);
|
||||
link.range.start.line = LINE_NUMBER_TO_INDEX(tokenizer.get_token_line());
|
||||
link.range.end.line = link.range.start.line;
|
||||
link.range.end.character = LINE_NUMBER_TO_INDEX(tokenizer.get_token_column());
|
||||
link.range.start.character = link.range.end.character - value.length();
|
||||
document_links.push_back(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
tokenizer.advance();
|
||||
}
|
||||
}
|
||||
|
||||
void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p_class, lsp::DocumentSymbol &r_symbol) {
|
||||
|
||||
const String uri = get_uri();
|
||||
|
@ -572,6 +606,10 @@ const lsp::DocumentSymbol *ExtendGDScriptParser::get_member_symbol(const String
|
|||
return NULL;
|
||||
}
|
||||
|
||||
const List<lsp::DocumentLink> &ExtendGDScriptParser::get_document_links() const {
|
||||
return document_links;
|
||||
}
|
||||
|
||||
const Array &ExtendGDScriptParser::get_member_completions() {
|
||||
|
||||
if (member_completions.empty()) {
|
||||
|
@ -755,5 +793,6 @@ Error ExtendGDScriptParser::parse(const String &p_code, const String &p_path) {
|
|||
Error err = GDScriptParser::parse(p_code, p_path.get_base_dir(), false, p_path, false, NULL, false);
|
||||
update_diagnostics();
|
||||
update_symbols();
|
||||
update_document_links(p_code);
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -56,12 +56,14 @@ class ExtendGDScriptParser : public GDScriptParser {
|
|||
|
||||
lsp::DocumentSymbol class_symbol;
|
||||
Vector<lsp::Diagnostic> diagnostics;
|
||||
List<lsp::DocumentLink> document_links;
|
||||
ClassMembers members;
|
||||
HashMap<String, ClassMembers> inner_classes;
|
||||
|
||||
void update_diagnostics();
|
||||
|
||||
void update_symbols();
|
||||
void update_document_links(const String &p_code);
|
||||
void parse_class_symbol(const GDScriptParser::ClassNode *p_class, lsp::DocumentSymbol &r_symbol);
|
||||
void parse_function_symbol(const GDScriptParser::FunctionNode *p_func, lsp::DocumentSymbol &r_symbol);
|
||||
|
||||
|
@ -93,6 +95,7 @@ public:
|
|||
|
||||
const lsp::DocumentSymbol *get_symbol_defined_at_line(int p_line) const;
|
||||
const lsp::DocumentSymbol *get_member_symbol(const String &p_name, const String &p_subclass = "") const;
|
||||
const List<lsp::DocumentLink> &get_document_links() const;
|
||||
|
||||
const Array &get_member_completions();
|
||||
Dictionary generate_api() const;
|
||||
|
|
|
@ -271,8 +271,17 @@ Array GDScriptTextDocument::codeLens(const Dictionary &p_params) {
|
|||
return arr;
|
||||
}
|
||||
|
||||
Variant GDScriptTextDocument::documentLink(const Dictionary &p_params) {
|
||||
Variant ret;
|
||||
Array GDScriptTextDocument::documentLink(const Dictionary &p_params) {
|
||||
Array ret;
|
||||
|
||||
lsp::DocumentLinkParams params;
|
||||
params.load(p_params);
|
||||
|
||||
List<lsp::DocumentLink> links;
|
||||
GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_document_links(params.textDocument.uri, links);
|
||||
for (const List<lsp::DocumentLink>::Element *E = links.front(); E; E = E->next()) {
|
||||
ret.push_back(E->get().to_json());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ public:
|
|||
Dictionary resolve(const Dictionary &p_params);
|
||||
Array foldingRange(const Dictionary &p_params);
|
||||
Array codeLens(const Dictionary &p_params);
|
||||
Variant documentLink(const Dictionary &p_params);
|
||||
Array documentLink(const Dictionary &p_params);
|
||||
Array colorPresentation(const Dictionary &p_params);
|
||||
Variant hover(const Dictionary &p_params);
|
||||
Array definition(const Dictionary &p_params);
|
||||
|
|
|
@ -475,6 +475,15 @@ void GDScriptWorkspace::resolve_related_symbols(const lsp::TextDocumentPositionP
|
|||
}
|
||||
}
|
||||
|
||||
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();
|
||||
for (const List<lsp::DocumentLink>::Element *E = links.front(); E; E = E->next()) {
|
||||
r_list.push_back(E->get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary GDScriptWorkspace::generate_script_api(const String &p_path) {
|
||||
Dictionary api;
|
||||
if (const ExtendGDScriptParser *parser = get_parse_successed_script(p_path)) {
|
||||
|
|
|
@ -53,7 +53,6 @@ protected:
|
|||
ExtendGDScriptParser *get_parse_successed_script(const String &p_path);
|
||||
ExtendGDScriptParser *get_parse_result(const String &p_path);
|
||||
|
||||
void strip_flat_symbols(const String &p_branch);
|
||||
void list_script_files(const String &p_root_dir, List<String> &r_files);
|
||||
|
||||
public:
|
||||
|
@ -82,6 +81,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);
|
||||
|
||||
void resolve_document_links(const String &p_uri, List<lsp::DocumentLink> &r_list);
|
||||
Dictionary generate_script_api(const String &p_path);
|
||||
|
||||
GDScriptWorkspace();
|
||||
|
|
|
@ -199,6 +199,41 @@ struct TextDocumentPositionParams {
|
|||
}
|
||||
};
|
||||
|
||||
struct DocumentLinkParams {
|
||||
/**
|
||||
* The document to provide document links for.
|
||||
*/
|
||||
TextDocumentIdentifier textDocument;
|
||||
|
||||
_FORCE_INLINE_ void load(const Dictionary &p_params) {
|
||||
textDocument.load(p_params["textDocument"]);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A document link is a range in a text document that links to an internal or external resource, like another
|
||||
* text document or a web site.
|
||||
*/
|
||||
struct DocumentLink {
|
||||
|
||||
/**
|
||||
* The range this link applies to.
|
||||
*/
|
||||
Range range;
|
||||
|
||||
/**
|
||||
* The uri this link points to. If missing a resolve request is sent later.
|
||||
*/
|
||||
DocumentUri target;
|
||||
|
||||
Dictionary to_json() const {
|
||||
Dictionary dict;
|
||||
dict["range"] = range.to_json();
|
||||
dict["target"] = target;
|
||||
return dict;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A textual edit applicable to a text document.
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue