Merge pull request #32544 from GodotExplorer/gdscript-lsp-show_native_symbol
Improvements for gdscript-lsp server
This commit is contained in:
commit
872af14e6f
8 changed files with 201 additions and 127 deletions
|
@ -157,7 +157,7 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p
|
||||||
r_symbol.selectionRange.start.line = r_symbol.range.start.line;
|
r_symbol.selectionRange.start.line = r_symbol.range.start.line;
|
||||||
r_symbol.detail = "class " + r_symbol.name;
|
r_symbol.detail = "class " + r_symbol.name;
|
||||||
bool is_root_class = &r_symbol == &class_symbol;
|
bool is_root_class = &r_symbol == &class_symbol;
|
||||||
r_symbol.documentation = parse_documentation_as_markdown(is_root_class ? 0 : LINE_NUMBER_TO_INDEX(p_class->line), is_root_class);
|
r_symbol.documentation = parse_documentation(is_root_class ? 0 : LINE_NUMBER_TO_INDEX(p_class->line), is_root_class);
|
||||||
|
|
||||||
for (int i = 0; i < p_class->variables.size(); ++i) {
|
for (int i = 0; i < p_class->variables.size(); ++i) {
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p
|
||||||
symbol.detail += " = " + JSON::print(m.default_value);
|
symbol.detail += " = " + JSON::print(m.default_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
symbol.documentation = parse_documentation_as_markdown(line);
|
symbol.documentation = parse_documentation(line);
|
||||||
symbol.uri = uri;
|
symbol.uri = uri;
|
||||||
symbol.script_path = path;
|
symbol.script_path = path;
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p
|
||||||
symbol.range.end.line = symbol.range.start.line;
|
symbol.range.end.line = symbol.range.start.line;
|
||||||
symbol.range.end.character = lines[line].length();
|
symbol.range.end.character = lines[line].length();
|
||||||
symbol.selectionRange.start.line = symbol.range.start.line;
|
symbol.selectionRange.start.line = symbol.range.start.line;
|
||||||
symbol.documentation = parse_documentation_as_markdown(line);
|
symbol.documentation = parse_documentation(line);
|
||||||
symbol.uri = uri;
|
symbol.uri = uri;
|
||||||
symbol.script_path = path;
|
symbol.script_path = path;
|
||||||
symbol.detail = "signal " + signal.name + "(";
|
symbol.detail = "signal " + signal.name + "(";
|
||||||
|
@ -233,7 +233,7 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p
|
||||||
symbol.range.end.line = symbol.range.start.line;
|
symbol.range.end.line = symbol.range.start.line;
|
||||||
symbol.range.end.character = lines[line].length();
|
symbol.range.end.character = lines[line].length();
|
||||||
symbol.selectionRange.start.line = symbol.range.start.line;
|
symbol.selectionRange.start.line = symbol.range.start.line;
|
||||||
symbol.documentation = parse_documentation_as_markdown(line);
|
symbol.documentation = parse_documentation(line);
|
||||||
symbol.uri = uri;
|
symbol.uri = uri;
|
||||||
symbol.script_path = path;
|
symbol.script_path = path;
|
||||||
|
|
||||||
|
@ -301,7 +301,7 @@ void ExtendGDScriptParser::parse_function_symbol(const GDScriptParser::FunctionN
|
||||||
r_symbol.range.end.line = MAX(p_func->body->end_line - 2, p_func->body->line);
|
r_symbol.range.end.line = MAX(p_func->body->end_line - 2, p_func->body->line);
|
||||||
r_symbol.range.end.character = lines[r_symbol.range.end.line].length();
|
r_symbol.range.end.character = lines[r_symbol.range.end.line].length();
|
||||||
r_symbol.selectionRange.start.line = r_symbol.range.start.line;
|
r_symbol.selectionRange.start.line = r_symbol.range.start.line;
|
||||||
r_symbol.documentation = parse_documentation_as_markdown(line);
|
r_symbol.documentation = parse_documentation(line);
|
||||||
r_symbol.uri = uri;
|
r_symbol.uri = uri;
|
||||||
r_symbol.script_path = path;
|
r_symbol.script_path = path;
|
||||||
|
|
||||||
|
@ -359,65 +359,11 @@ void ExtendGDScriptParser::parse_function_symbol(const GDScriptParser::FunctionN
|
||||||
if (var->datatype.kind != GDScriptParser::DataType::UNRESOLVED) {
|
if (var->datatype.kind != GDScriptParser::DataType::UNRESOLVED) {
|
||||||
symbol.detail += ": " + var->datatype.to_string();
|
symbol.detail += ": " + var->datatype.to_string();
|
||||||
}
|
}
|
||||||
symbol.documentation = parse_documentation_as_markdown(line);
|
symbol.documentation = parse_documentation(line);
|
||||||
r_symbol.children.push_back(symbol);
|
r_symbol.children.push_back(symbol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String ExtendGDScriptParser::marked_documentation(const String &p_bbcode) {
|
|
||||||
|
|
||||||
String markdown = p_bbcode.strip_edges();
|
|
||||||
|
|
||||||
Vector<String> lines = markdown.split("\n");
|
|
||||||
bool in_code_block = false;
|
|
||||||
int code_block_indent = -1;
|
|
||||||
|
|
||||||
markdown = "";
|
|
||||||
for (int i = 0; i < lines.size(); i++) {
|
|
||||||
String line = lines[i];
|
|
||||||
int block_start = line.find("[codeblock]");
|
|
||||||
if (block_start != -1) {
|
|
||||||
code_block_indent = block_start;
|
|
||||||
in_code_block = true;
|
|
||||||
line = "\n";
|
|
||||||
} else if (in_code_block) {
|
|
||||||
line = "\t" + line.substr(code_block_indent, line.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_code_block && line.find("[/codeblock]") != -1) {
|
|
||||||
line = "\n";
|
|
||||||
in_code_block = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!in_code_block) {
|
|
||||||
line = line.strip_edges();
|
|
||||||
line = line.replace("[code]", "`");
|
|
||||||
line = line.replace("[/code]", "`");
|
|
||||||
line = line.replace("[i]", "*");
|
|
||||||
line = line.replace("[/i]", "*");
|
|
||||||
line = line.replace("[b]", "**");
|
|
||||||
line = line.replace("[/b]", "**");
|
|
||||||
line = line.replace("[u]", "__");
|
|
||||||
line = line.replace("[/u]", "__");
|
|
||||||
line = line.replace("[method ", "`");
|
|
||||||
line = line.replace("[member ", "`");
|
|
||||||
line = line.replace("[signal ", "`");
|
|
||||||
line = line.replace("[enum ", "`");
|
|
||||||
line = line.replace("[constant ", "`");
|
|
||||||
line = line.replace("[", "`");
|
|
||||||
line = line.replace("]", "`");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!in_code_block && i < lines.size() - 1) {
|
|
||||||
line += "\n\n";
|
|
||||||
} else if (i < lines.size() - 1) {
|
|
||||||
line += "\n";
|
|
||||||
}
|
|
||||||
markdown += line;
|
|
||||||
}
|
|
||||||
return markdown;
|
|
||||||
}
|
|
||||||
|
|
||||||
String ExtendGDScriptParser::parse_documentation(int p_line, bool p_docs_down) {
|
String ExtendGDScriptParser::parse_documentation(int p_line, bool p_docs_down) {
|
||||||
ERR_FAIL_INDEX_V(p_line, lines.size(), String());
|
ERR_FAIL_INDEX_V(p_line, lines.size(), String());
|
||||||
|
|
||||||
|
@ -576,10 +522,6 @@ const lsp::DocumentSymbol *ExtendGDScriptParser::search_symbol_defined_at_line(i
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
String ExtendGDScriptParser::parse_documentation_as_markdown(int p_line, bool p_docs_down) {
|
|
||||||
return marked_documentation(parse_documentation(p_line, p_docs_down));
|
|
||||||
}
|
|
||||||
|
|
||||||
const lsp::DocumentSymbol *ExtendGDScriptParser::get_symbol_defined_at_line(int p_line) const {
|
const lsp::DocumentSymbol *ExtendGDScriptParser::get_symbol_defined_at_line(int p_line) const {
|
||||||
if (p_line <= 0) {
|
if (p_line <= 0) {
|
||||||
return &class_symbol;
|
return &class_symbol;
|
||||||
|
|
|
@ -75,11 +75,6 @@ class ExtendGDScriptParser : public GDScriptParser {
|
||||||
|
|
||||||
Array member_completions;
|
Array member_completions;
|
||||||
|
|
||||||
String parse_documentation_as_markdown(int p_line, bool p_docs_down = false);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static String marked_documentation(const String &p_bbcode);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
_FORCE_INLINE_ const String &get_path() const { return path; }
|
_FORCE_INLINE_ const String &get_path() const { return path; }
|
||||||
_FORCE_INLINE_ const Vector<String> &get_lines() const { return lines; }
|
_FORCE_INLINE_ const Vector<String> &get_lines() const { return lines; }
|
||||||
|
|
|
@ -153,7 +153,13 @@ Error GDScriptLanguageProtocol::start(int p_port) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GDScriptLanguageProtocol::stop() {
|
void GDScriptLanguageProtocol::stop() {
|
||||||
|
const int *ptr = clients.next(NULL);
|
||||||
|
while (ptr) {
|
||||||
|
clients.get(*ptr)->close();
|
||||||
|
ptr = clients.next(ptr);
|
||||||
|
}
|
||||||
server->stop();
|
server->stop();
|
||||||
|
clients.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GDScriptLanguageProtocol::notify_all_clients(const String &p_method, const Variant &p_params) {
|
void GDScriptLanguageProtocol::notify_all_clients(const String &p_method, const Variant &p_params) {
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
void GDScriptTextDocument::_bind_methods() {
|
void GDScriptTextDocument::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("didOpen"), &GDScriptTextDocument::didOpen);
|
ClassDB::bind_method(D_METHOD("didOpen"), &GDScriptTextDocument::didOpen);
|
||||||
ClassDB::bind_method(D_METHOD("didChange"), &GDScriptTextDocument::didChange);
|
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("documentSymbol"), &GDScriptTextDocument::documentSymbol);
|
||||||
ClassDB::bind_method(D_METHOD("completion"), &GDScriptTextDocument::completion);
|
ClassDB::bind_method(D_METHOD("completion"), &GDScriptTextDocument::completion);
|
||||||
ClassDB::bind_method(D_METHOD("resolve"), &GDScriptTextDocument::resolve);
|
ClassDB::bind_method(D_METHOD("resolve"), &GDScriptTextDocument::resolve);
|
||||||
|
@ -75,6 +76,11 @@ lsp::TextDocumentItem GDScriptTextDocument::load_document_item(const Variant &p_
|
||||||
return doc;
|
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() {
|
void GDScriptTextDocument::initialize() {
|
||||||
|
|
||||||
if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) {
|
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) {
|
Array GDScriptTextDocument::documentSymbol(const Dictionary &p_params) {
|
||||||
Dictionary params = p_params["textDocument"];
|
Dictionary params = p_params["textDocument"];
|
||||||
String uri = params["uri"];
|
String uri = params["uri"];
|
||||||
|
@ -335,31 +356,35 @@ Array GDScriptTextDocument::definition(const Dictionary &p_params) {
|
||||||
const String &path = GDScriptLanguageProtocol::get_singleton()->get_workspace()->get_file_path(symbol->uri);
|
const String &path = GDScriptLanguageProtocol::get_singleton()->get_workspace()->get_file_path(symbol->uri);
|
||||||
if (file_checker->file_exists(path)) {
|
if (file_checker->file_exists(path)) {
|
||||||
arr.push_back(location.to_json());
|
arr.push_back(location.to_json());
|
||||||
} else if (!symbol->native_class.empty() && GDScriptLanguageProtocol::get_singleton()->is_goto_native_symbols_enabled()) {
|
} else if (!symbol->native_class.empty()) {
|
||||||
String id;
|
if (GDScriptLanguageProtocol::get_singleton()->is_goto_native_symbols_enabled()) {
|
||||||
switch (symbol->kind) {
|
String id;
|
||||||
case lsp::SymbolKind::Class:
|
switch (symbol->kind) {
|
||||||
id = "class_name:" + symbol->name;
|
case lsp::SymbolKind::Class:
|
||||||
break;
|
id = "class_name:" + symbol->name;
|
||||||
case lsp::SymbolKind::Constant:
|
break;
|
||||||
id = "class_constant:" + symbol->native_class + ":" + symbol->name;
|
case lsp::SymbolKind::Constant:
|
||||||
break;
|
id = "class_constant:" + symbol->native_class + ":" + symbol->name;
|
||||||
case lsp::SymbolKind::Property:
|
break;
|
||||||
case lsp::SymbolKind::Variable:
|
case lsp::SymbolKind::Property:
|
||||||
id = "class_property:" + symbol->native_class + ":" + symbol->name;
|
case lsp::SymbolKind::Variable:
|
||||||
break;
|
id = "class_property:" + symbol->native_class + ":" + symbol->name;
|
||||||
case lsp::SymbolKind::Enum:
|
break;
|
||||||
id = "class_enum:" + symbol->native_class + ":" + symbol->name;
|
case lsp::SymbolKind::Enum:
|
||||||
break;
|
id = "class_enum:" + symbol->native_class + ":" + symbol->name;
|
||||||
case lsp::SymbolKind::Method:
|
break;
|
||||||
case lsp::SymbolKind::Function:
|
case lsp::SymbolKind::Method:
|
||||||
id = "class_method:" + symbol->native_class + ":" + symbol->name;
|
case lsp::SymbolKind::Function:
|
||||||
break;
|
id = "class_method:" + symbol->native_class + ":" + symbol->name;
|
||||||
default:
|
break;
|
||||||
id = "class_global:" + symbol->native_class + ":" + symbol->name;
|
default:
|
||||||
break;
|
id = "class_global:" + symbol->native_class + ":" + symbol->name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
call_deferred("show_native_symbol_in_editor", id);
|
||||||
|
} else {
|
||||||
|
notify_client_show_symbol(symbol);
|
||||||
}
|
}
|
||||||
call_deferred("show_native_symbol_in_editor", id);
|
|
||||||
}
|
}
|
||||||
} else if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) {
|
} else if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) {
|
||||||
|
|
||||||
|
|
|
@ -52,8 +52,10 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
lsp::TextDocumentItem load_document_item(const Variant &p_param);
|
lsp::TextDocumentItem load_document_item(const Variant &p_param);
|
||||||
|
void notify_client_show_symbol(const lsp::DocumentSymbol *symbol);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Variant nativeSymbol(const Dictionary &p_params);
|
||||||
Array documentSymbol(const Dictionary &p_params);
|
Array documentSymbol(const Dictionary &p_params);
|
||||||
Array completion(const Dictionary &p_params);
|
Array completion(const Dictionary &p_params);
|
||||||
Dictionary resolve(const Dictionary &p_params);
|
Dictionary resolve(const Dictionary &p_params);
|
||||||
|
|
|
@ -198,7 +198,7 @@ Error GDScriptWorkspace::initialize() {
|
||||||
if (!class_data.inherits.empty()) {
|
if (!class_data.inherits.empty()) {
|
||||||
class_symbol.detail += " extends " + class_data.inherits;
|
class_symbol.detail += " extends " + class_data.inherits;
|
||||||
}
|
}
|
||||||
class_symbol.documentation = ExtendGDScriptParser::marked_documentation(class_data.brief_description) + "\n" + ExtendGDScriptParser::marked_documentation(class_data.description);
|
class_symbol.documentation = class_data.brief_description + "\n" + class_data.description;
|
||||||
|
|
||||||
for (int i = 0; i < class_data.constants.size(); i++) {
|
for (int i = 0; i < class_data.constants.size(); i++) {
|
||||||
const DocData::ConstantDoc &const_data = class_data.constants[i];
|
const DocData::ConstantDoc &const_data = class_data.constants[i];
|
||||||
|
@ -211,7 +211,7 @@ Error GDScriptWorkspace::initialize() {
|
||||||
symbol.detail += ": " + const_data.enumeration;
|
symbol.detail += ": " + const_data.enumeration;
|
||||||
}
|
}
|
||||||
symbol.detail += " = " + const_data.value;
|
symbol.detail += " = " + const_data.value;
|
||||||
symbol.documentation = ExtendGDScriptParser::marked_documentation(const_data.description);
|
symbol.documentation = const_data.description;
|
||||||
class_symbol.children.push_back(symbol);
|
class_symbol.children.push_back(symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ Error GDScriptWorkspace::initialize() {
|
||||||
} else {
|
} else {
|
||||||
symbol.detail += ": " + data.type;
|
symbol.detail += ": " + data.type;
|
||||||
}
|
}
|
||||||
symbol.documentation = ExtendGDScriptParser::marked_documentation(data.description);
|
symbol.documentation = data.description;
|
||||||
class_symbol.children.push_back(symbol);
|
class_symbol.children.push_back(symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ Error GDScriptWorkspace::initialize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
symbol.detail = "func " + class_name + "." + data.name + "(" + params + ") -> " + data.return_type;
|
symbol.detail = "func " + class_name + "." + data.name + "(" + params + ") -> " + data.return_type;
|
||||||
symbol.documentation = ExtendGDScriptParser::marked_documentation(data.description);
|
symbol.documentation = data.description;
|
||||||
class_symbol.children.push_back(symbol);
|
class_symbol.children.push_back(symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
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))) {
|
if (const ExtendGDScriptParser *parser = get_parse_successed_script(get_file_path(p_uri))) {
|
||||||
const List<lsp::DocumentLink> &links = parser->get_document_links();
|
const List<lsp::DocumentLink> &links = parser->get_document_links();
|
||||||
|
|
|
@ -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);
|
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_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);
|
void resolve_document_links(const String &p_uri, List<lsp::DocumentLink> &r_list);
|
||||||
Dictionary generate_script_api(const String &p_path);
|
Dictionary generate_script_api(const String &p_path);
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,9 @@ namespace lsp {
|
||||||
|
|
||||||
typedef String DocumentUri;
|
typedef String DocumentUri;
|
||||||
|
|
||||||
|
/** Format BBCode documentation from DocData to markdown */
|
||||||
|
static String marked_documentation(const String &p_bbcode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Text documents are identified using a URI. On the protocol level, URIs are passed as strings.
|
* Text documents are identified using a URI. On the protocol level, URIs are passed as strings.
|
||||||
*/
|
*/
|
||||||
|
@ -282,6 +285,9 @@ struct Command {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Use namespace instead of enumeration to follow the LSP specifications
|
||||||
|
// lsp::EnumName::EnumValue is OK but lsp::EnumValue is not
|
||||||
|
|
||||||
namespace TextDocumentSyncKind {
|
namespace TextDocumentSyncKind {
|
||||||
/**
|
/**
|
||||||
* Documents should not be synced at all.
|
* Documents should not be synced at all.
|
||||||
|
@ -592,6 +598,7 @@ struct TextDocumentContentChangeEvent {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Use namespace instead of enumeration to follow the LSP specifications
|
||||||
namespace DiagnosticSeverity {
|
namespace DiagnosticSeverity {
|
||||||
/**
|
/**
|
||||||
* Reports an error.
|
* Reports an error.
|
||||||
|
@ -692,6 +699,7 @@ struct Diagnostic {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Use namespace instead of enumeration to follow the LSP specifications
|
||||||
/**
|
/**
|
||||||
* Describes the content type that a client supports in various
|
* Describes the content type that a client supports in various
|
||||||
* result literals like `Hover`, `ParameterInfo` or `CompletionItem`.
|
* result literals like `Hover`, `ParameterInfo` or `CompletionItem`.
|
||||||
|
@ -756,6 +764,9 @@ struct MarkupContent {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Use namespace instead of enumeration to follow the LSP specifications
|
||||||
|
// lsp::EnumName::EnumValue is OK but lsp::EnumValue is not
|
||||||
|
// And here C++ compilers are unhappy with our enumeration name like Color, File, Reference etc.
|
||||||
/**
|
/**
|
||||||
* The kind of a completion entry.
|
* The kind of a completion entry.
|
||||||
*/
|
*/
|
||||||
|
@ -787,6 +798,7 @@ static const int Operator = 24;
|
||||||
static const int TypeParameter = 25;
|
static const int TypeParameter = 25;
|
||||||
}; // namespace CompletionItemKind
|
}; // namespace CompletionItemKind
|
||||||
|
|
||||||
|
// Use namespace instead of enumeration to follow the LSP specifications
|
||||||
/**
|
/**
|
||||||
* Defines whether the insert text in a completion item should be interpreted as
|
* Defines whether the insert text in a completion item should be interpreted as
|
||||||
* plain text or a snippet.
|
* plain text or a snippet.
|
||||||
|
@ -979,36 +991,39 @@ struct CompletionList {
|
||||||
Vector<CompletionItem> items;
|
Vector<CompletionItem> items;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Use namespace instead of enumeration to follow the LSP specifications
|
||||||
|
// lsp::EnumName::EnumValue is OK but lsp::EnumValue is not
|
||||||
|
// And here C++ compilers are unhappy with our enumeration name like String, Array, Object etc
|
||||||
/**
|
/**
|
||||||
* A symbol kind.
|
* A symbol kind.
|
||||||
*/
|
*/
|
||||||
namespace SymbolKind {
|
namespace SymbolKind {
|
||||||
static const int File = 1;
|
static const int File = 0;
|
||||||
static const int Module = 2;
|
static const int Module = 1;
|
||||||
static const int Namespace = 3;
|
static const int Namespace = 2;
|
||||||
static const int Package = 4;
|
static const int Package = 3;
|
||||||
static const int Class = 5;
|
static const int Class = 4;
|
||||||
static const int Method = 6;
|
static const int Method = 5;
|
||||||
static const int Property = 7;
|
static const int Property = 6;
|
||||||
static const int Field = 8;
|
static const int Field = 7;
|
||||||
static const int Constructor = 9;
|
static const int Constructor = 8;
|
||||||
static const int Enum = 10;
|
static const int Enum = 9;
|
||||||
static const int Interface = 11;
|
static const int Interface = 10;
|
||||||
static const int Function = 12;
|
static const int Function = 11;
|
||||||
static const int Variable = 13;
|
static const int Variable = 12;
|
||||||
static const int Constant = 14;
|
static const int Constant = 13;
|
||||||
static const int String = 15;
|
static const int String = 14;
|
||||||
static const int Number = 16;
|
static const int Number = 15;
|
||||||
static const int Boolean = 17;
|
static const int Boolean = 16;
|
||||||
static const int Array = 18;
|
static const int Array = 17;
|
||||||
static const int Object = 19;
|
static const int Object = 18;
|
||||||
static const int Key = 20;
|
static const int Key = 19;
|
||||||
static const int Null = 21;
|
static const int Null = 20;
|
||||||
static const int EnumMember = 22;
|
static const int EnumMember = 21;
|
||||||
static const int Struct = 23;
|
static const int Struct = 22;
|
||||||
static const int Event = 24;
|
static const int Event = 23;
|
||||||
static const int Operator = 25;
|
static const int Operator = 24;
|
||||||
static const int TypeParameter = 26;
|
static const int TypeParameter = 25;
|
||||||
}; // namespace SymbolKind
|
}; // namespace SymbolKind
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1134,7 +1149,7 @@ struct DocumentSymbol {
|
||||||
*/
|
*/
|
||||||
Vector<DocumentSymbol> children;
|
Vector<DocumentSymbol> children;
|
||||||
|
|
||||||
_FORCE_INLINE_ Dictionary to_json() const {
|
Dictionary to_json(bool with_doc = false) const {
|
||||||
Dictionary dict;
|
Dictionary dict;
|
||||||
dict["name"] = name;
|
dict["name"] = name;
|
||||||
dict["detail"] = detail;
|
dict["detail"] = detail;
|
||||||
|
@ -1142,10 +1157,14 @@ struct DocumentSymbol {
|
||||||
dict["deprecated"] = deprecated;
|
dict["deprecated"] = deprecated;
|
||||||
dict["range"] = range.to_json();
|
dict["range"] = range.to_json();
|
||||||
dict["selectionRange"] = selectionRange.to_json();
|
dict["selectionRange"] = selectionRange.to_json();
|
||||||
|
if (with_doc) {
|
||||||
|
dict["documentation"] = documentation;
|
||||||
|
dict["native_class"] = native_class;
|
||||||
|
}
|
||||||
Array arr;
|
Array arr;
|
||||||
arr.resize(children.size());
|
arr.resize(children.size());
|
||||||
for (int i = 0; i < children.size(); i++) {
|
for (int i = 0; i < children.size(); i++) {
|
||||||
arr[i] = children[i].to_json();
|
arr[i] = children[i].to_json(with_doc);
|
||||||
}
|
}
|
||||||
dict["children"] = arr;
|
dict["children"] = arr;
|
||||||
return dict;
|
return dict;
|
||||||
|
@ -1177,7 +1196,7 @@ struct DocumentSymbol {
|
||||||
markdown.value = "\t" + detail + "\n\n";
|
markdown.value = "\t" + detail + "\n\n";
|
||||||
}
|
}
|
||||||
if (documentation.length()) {
|
if (documentation.length()) {
|
||||||
markdown.value += documentation + "\n\n";
|
markdown.value += marked_documentation(documentation) + "\n\n";
|
||||||
}
|
}
|
||||||
if (script_path.length()) {
|
if (script_path.length()) {
|
||||||
markdown.value += "Defined in [" + script_path + "](" + uri + ")";
|
markdown.value += "Defined in [" + script_path + "](" + uri + ")";
|
||||||
|
@ -1229,6 +1248,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
|
* Enum of known range kinds
|
||||||
*/
|
*/
|
||||||
|
@ -1289,6 +1319,7 @@ struct FoldingRange {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Use namespace instead of enumeration to follow the LSP specifications
|
||||||
/**
|
/**
|
||||||
* How a completion was triggered
|
* How a completion was triggered
|
||||||
*/
|
*/
|
||||||
|
@ -1536,6 +1567,61 @@ struct InitializeResult {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Format BBCode documentation from DocData to markdown */
|
||||||
|
static String marked_documentation(const String &p_bbcode) {
|
||||||
|
|
||||||
|
String markdown = p_bbcode.strip_edges();
|
||||||
|
|
||||||
|
Vector<String> lines = markdown.split("\n");
|
||||||
|
bool in_code_block = false;
|
||||||
|
int code_block_indent = -1;
|
||||||
|
|
||||||
|
markdown = "";
|
||||||
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
|
String line = lines[i];
|
||||||
|
int block_start = line.find("[codeblock]");
|
||||||
|
if (block_start != -1) {
|
||||||
|
code_block_indent = block_start;
|
||||||
|
in_code_block = true;
|
||||||
|
line = "\n";
|
||||||
|
} else if (in_code_block) {
|
||||||
|
line = "\t" + line.substr(code_block_indent, line.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_code_block && line.find("[/codeblock]") != -1) {
|
||||||
|
line = "\n";
|
||||||
|
in_code_block = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_code_block) {
|
||||||
|
line = line.strip_edges();
|
||||||
|
line = line.replace("[code]", "`");
|
||||||
|
line = line.replace("[/code]", "`");
|
||||||
|
line = line.replace("[i]", "*");
|
||||||
|
line = line.replace("[/i]", "*");
|
||||||
|
line = line.replace("[b]", "**");
|
||||||
|
line = line.replace("[/b]", "**");
|
||||||
|
line = line.replace("[u]", "__");
|
||||||
|
line = line.replace("[/u]", "__");
|
||||||
|
line = line.replace("[method ", "`");
|
||||||
|
line = line.replace("[member ", "`");
|
||||||
|
line = line.replace("[signal ", "`");
|
||||||
|
line = line.replace("[enum ", "`");
|
||||||
|
line = line.replace("[constant ", "`");
|
||||||
|
line = line.replace("[", "`");
|
||||||
|
line = line.replace("]", "`");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_code_block && i < lines.size() - 1) {
|
||||||
|
line += "\n\n";
|
||||||
|
} else if (i < lines.size() - 1) {
|
||||||
|
line += "\n";
|
||||||
|
}
|
||||||
|
markdown += line;
|
||||||
|
}
|
||||||
|
return markdown;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace lsp
|
} // namespace lsp
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue