summaryrefslogtreecommitdiff
path: root/modules/gdscript/language_server
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript/language_server')
-rw-r--r--modules/gdscript/language_server/gdscript_extend_parser.cpp51
-rw-r--r--modules/gdscript/language_server/gdscript_extend_parser.h1
-rw-r--r--modules/gdscript/language_server/gdscript_language_protocol.cpp44
-rw-r--r--modules/gdscript/language_server/gdscript_language_protocol.h8
-rw-r--r--modules/gdscript/language_server/gdscript_language_server.cpp10
-rw-r--r--modules/gdscript/language_server/gdscript_text_document.cpp28
-rw-r--r--modules/gdscript/language_server/gdscript_workspace.cpp90
-rw-r--r--modules/gdscript/language_server/gdscript_workspace.h2
-rw-r--r--modules/gdscript/language_server/lsp.hpp69
9 files changed, 136 insertions, 167 deletions
diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp
index 0f6f13944b..330530be80 100644
--- a/modules/gdscript/language_server/gdscript_extend_parser.cpp
+++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp
@@ -29,13 +29,13 @@
/*************************************************************************/
#include "gdscript_extend_parser.h"
+
#include "../gdscript.h"
#include "core/io/json.h"
#include "gdscript_language_protocol.h"
#include "gdscript_workspace.h"
void ExtendGDScriptParser::update_diagnostics() {
-
diagnostics.clear();
if (has_error()) {
@@ -80,12 +80,10 @@ void ExtendGDScriptParser::update_diagnostics() {
}
void ExtendGDScriptParser::update_symbols() {
-
members.clear();
const GDScriptParser::Node *head = get_parse_tree();
if (const GDScriptParser::ClassNode *gdclass = dynamic_cast<const GDScriptParser::ClassNode *>(head)) {
-
parse_class_symbol(gdclass, class_symbol);
for (int i = 0; i < class_symbol.children.size(); i++) {
@@ -141,15 +139,15 @@ void ExtendGDScriptParser::update_document_links(const String &p_code) {
}
void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p_class, lsp::DocumentSymbol &r_symbol) {
-
const String uri = get_uri();
r_symbol.uri = uri;
r_symbol.script_path = path;
r_symbol.children.clear();
r_symbol.name = p_class->name;
- if (r_symbol.name.empty())
+ if (r_symbol.name.empty()) {
r_symbol.name = path.get_file();
+ }
r_symbol.kind = lsp::SymbolKind::Class;
r_symbol.deprecated = false;
r_symbol.range.start.line = LINE_NUMBER_TO_INDEX(p_class->line);
@@ -161,7 +159,6 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p
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) {
-
const GDScriptParser::ClassNode::Member &m = p_class->variables[i];
lsp::DocumentSymbol symbol;
@@ -289,7 +286,6 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p
}
void ExtendGDScriptParser::parse_function_symbol(const GDScriptParser::FunctionNode *p_func, lsp::DocumentSymbol &r_symbol) {
-
const String uri = get_uri();
r_symbol.name = p_func->name;
@@ -327,7 +323,7 @@ void ExtendGDScriptParser::parse_function_symbol(const GDScriptParser::FunctionN
int default_value_idx = i - (p_func->arguments.size() - p_func->default_values.size());
if (default_value_idx >= 0) {
const GDScriptParser::ConstantNode *const_node = dynamic_cast<const GDScriptParser::ConstantNode *>(p_func->default_values[default_value_idx]);
- if (const_node == NULL) {
+ if (const_node == nullptr) {
const GDScriptParser::OperatorNode *operator_node = dynamic_cast<const GDScriptParser::OperatorNode *>(p_func->default_values[default_value_idx]);
if (operator_node) {
const_node = dynamic_cast<const GDScriptParser::ConstantNode *>(operator_node->next);
@@ -384,8 +380,9 @@ String ExtendGDScriptParser::parse_documentation(int p_line, bool p_docs_down) {
int step = p_docs_down ? 1 : -1;
int start_line = p_docs_down ? p_line : p_line - 1;
for (int i = start_line; true; i += step) {
-
- if (i < 0 || i >= lines.size()) break;
+ if (i < 0 || i >= lines.size()) {
+ break;
+ }
String line_comment = lines[i].strip_edges(true, false);
if (line_comment.begins_with("#")) {
@@ -408,22 +405,20 @@ String ExtendGDScriptParser::parse_documentation(int p_line, bool p_docs_down) {
}
String ExtendGDScriptParser::get_text_for_completion(const lsp::Position &p_cursor) const {
-
String longthing;
int len = lines.size();
for (int i = 0; i < len; i++) {
-
if (i == p_cursor.line) {
longthing += lines[i].substr(0, p_cursor.character);
longthing += String::chr(0xFFFF); //not unicode, represents the cursor
longthing += lines[i].substr(p_cursor.character, lines[i].size());
} else {
-
longthing += lines[i];
}
- if (i != len - 1)
+ if (i != len - 1) {
longthing += "\n";
+ }
}
return longthing;
@@ -433,7 +428,6 @@ String ExtendGDScriptParser::get_text_for_lookup_symbol(const lsp::Position &p_c
String longthing;
int len = lines.size();
for (int i = 0; i < len; i++) {
-
if (i == p_cursor.line) {
String line = lines[i];
String first_part = line.substr(0, p_cursor.character);
@@ -457,19 +451,18 @@ String ExtendGDScriptParser::get_text_for_lookup_symbol(const lsp::Position &p_c
}
longthing += last_part;
} else {
-
longthing += lines[i];
}
- if (i != len - 1)
+ if (i != len - 1) {
longthing += "\n";
+ }
}
return longthing;
}
String ExtendGDScriptParser::get_identifier_under_position(const lsp::Position &p_position, Vector2i &p_offset) const {
-
ERR_FAIL_INDEX_V(p_position.line, lines.size(), "");
String line = lines[p_position.line];
ERR_FAIL_INDEX_V(p_position.character, line.size(), "");
@@ -507,7 +500,7 @@ String ExtendGDScriptParser::get_uri() const {
}
const lsp::DocumentSymbol *ExtendGDScriptParser::search_symbol_defined_at_line(int p_line, const lsp::DocumentSymbol &p_parent) const {
- const lsp::DocumentSymbol *ret = NULL;
+ const lsp::DocumentSymbol *ret = nullptr;
if (p_line < p_parent.range.start.line) {
return ret;
} else if (p_parent.range.start.line == p_line) {
@@ -524,7 +517,6 @@ const lsp::DocumentSymbol *ExtendGDScriptParser::search_symbol_defined_at_line(i
}
Error ExtendGDScriptParser::get_left_function_call(const lsp::Position &p_position, lsp::Position &r_func_pos, int &r_arg_index) const {
-
ERR_FAIL_INDEX_V(p_position.line, lines.size(), ERR_INVALID_PARAMETER);
int bracket_stack = 0;
@@ -576,7 +568,6 @@ const lsp::DocumentSymbol *ExtendGDScriptParser::get_symbol_defined_at_line(int
}
const lsp::DocumentSymbol *ExtendGDScriptParser::get_member_symbol(const String &p_name, const String &p_subclass) const {
-
if (p_subclass.empty()) {
const lsp::DocumentSymbol *const *ptr = members.getptr(p_name);
if (ptr) {
@@ -591,7 +582,7 @@ const lsp::DocumentSymbol *ExtendGDScriptParser::get_member_symbol(const String
}
}
- return NULL;
+ return nullptr;
}
const List<lsp::DocumentLink> &ExtendGDScriptParser::get_document_links() const {
@@ -599,12 +590,9 @@ const List<lsp::DocumentLink> &ExtendGDScriptParser::get_document_links() const
}
const Array &ExtendGDScriptParser::get_member_completions() {
-
if (member_completions.empty()) {
-
- const String *name = members.next(NULL);
+ const String *name = members.next(nullptr);
while (name) {
-
const lsp::DocumentSymbol *symbol = members.get(*name);
lsp::CompletionItem item = symbol->make_completion_item();
item.data = JOIN_SYMBOLS(path, *name);
@@ -613,11 +601,10 @@ const Array &ExtendGDScriptParser::get_member_completions() {
name = members.next(name);
}
- const String *_class = inner_classes.next(NULL);
+ const String *_class = inner_classes.next(nullptr);
while (_class) {
-
const ClassMembers *inner_class = inner_classes.getptr(*_class);
- const String *member_name = inner_class->next(NULL);
+ const String *member_name = inner_class->next(nullptr);
while (member_name) {
const lsp::DocumentSymbol *symbol = inner_class->get(*member_name);
lsp::CompletionItem item = symbol->make_completion_item();
@@ -648,7 +635,7 @@ Dictionary ExtendGDScriptParser::dump_function_api(const GDScriptParser::Functio
int default_value_idx = i - (p_func->arguments.size() - p_func->default_values.size());
if (default_value_idx >= 0) {
const GDScriptParser::ConstantNode *const_node = dynamic_cast<const GDScriptParser::ConstantNode *>(p_func->default_values[default_value_idx]);
- if (const_node == NULL) {
+ if (const_node == nullptr) {
const GDScriptParser::OperatorNode *operator_node = dynamic_cast<const GDScriptParser::OperatorNode *>(p_func->default_values[default_value_idx]);
if (operator_node) {
const_node = dynamic_cast<const GDScriptParser::ConstantNode *>(operator_node->next);
@@ -696,7 +683,6 @@ Dictionary ExtendGDScriptParser::dump_class_api(const GDScriptParser::ClassNode
Array constants;
for (Map<StringName, GDScriptParser::ClassNode::Constant>::Element *E = p_class->constant_expressions.front(); E; E = E->next()) {
-
const GDScriptParser::ClassNode::Constant &c = E->value();
const GDScriptParser::ConstantNode *node = dynamic_cast<const GDScriptParser::ConstantNode *>(c.expression);
ERR_FAIL_COND_V(!node, class_api);
@@ -765,7 +751,6 @@ Dictionary ExtendGDScriptParser::dump_class_api(const GDScriptParser::ClassNode
}
Dictionary ExtendGDScriptParser::generate_api() const {
-
Dictionary api;
const GDScriptParser::Node *head = get_parse_tree();
if (const GDScriptParser::ClassNode *gdclass = dynamic_cast<const GDScriptParser::ClassNode *>(head)) {
@@ -778,7 +763,7 @@ Error ExtendGDScriptParser::parse(const String &p_code, const String &p_path) {
path = p_path;
lines = p_code.split("\n");
- Error err = GDScriptParser::parse(p_code, p_path.get_base_dir(), false, p_path, false, NULL, false);
+ Error err = GDScriptParser::parse(p_code, p_path.get_base_dir(), false, p_path, false, nullptr, false);
update_diagnostics();
update_symbols();
update_document_links(p_code);
diff --git a/modules/gdscript/language_server/gdscript_extend_parser.h b/modules/gdscript/language_server/gdscript_extend_parser.h
index 43dfce994b..0c031d7883 100644
--- a/modules/gdscript/language_server/gdscript_extend_parser.h
+++ b/modules/gdscript/language_server/gdscript_extend_parser.h
@@ -50,7 +50,6 @@
typedef HashMap<String, const lsp::DocumentSymbol *> ClassMembers;
class ExtendGDScriptParser : public GDScriptParser {
-
String path;
Vector<String> lines;
diff --git a/modules/gdscript/language_server/gdscript_language_protocol.cpp b/modules/gdscript/language_server/gdscript_language_protocol.cpp
index 2243a7b81d..2a67d2ff4f 100644
--- a/modules/gdscript/language_server/gdscript_language_protocol.cpp
+++ b/modules/gdscript/language_server/gdscript_language_protocol.cpp
@@ -29,13 +29,14 @@
/*************************************************************************/
#include "gdscript_language_protocol.h"
+
#include "core/io/json.h"
#include "core/os/copymem.h"
#include "core/project_settings.h"
#include "editor/editor_log.h"
#include "editor/editor_node.h"
-GDScriptLanguageProtocol *GDScriptLanguageProtocol::singleton = NULL;
+GDScriptLanguageProtocol *GDScriptLanguageProtocol::singleton = nullptr;
Error GDScriptLanguageProtocol::LSPeer::handle_data() {
int read = 0;
@@ -47,10 +48,11 @@ Error GDScriptLanguageProtocol::LSPeer::handle_data() {
ERR_FAIL_COND_V_MSG(true, ERR_OUT_OF_MEMORY, "Response header too big");
}
Error err = connection->get_partial_data(&req_buf[req_pos], 1, read);
- if (err != OK)
+ if (err != OK) {
return FAILED;
- else if (read != 1) // Busy, wait until next poll
+ } else if (read != 1) { // Busy, wait until next poll
return ERR_BUSY;
+ }
char *r = (char *)req_buf;
int l = req_pos;
@@ -75,10 +77,11 @@ Error GDScriptLanguageProtocol::LSPeer::handle_data() {
ERR_FAIL_COND_V_MSG(req_pos >= LSP_MAX_BUFFER_SIZE, ERR_OUT_OF_MEMORY, "Response content too big");
}
Error err = connection->get_partial_data(&req_buf[req_pos], 1, read);
- if (err != OK)
+ if (err != OK) {
return FAILED;
- else if (read != 1)
+ } else if (read != 1) {
return ERR_BUSY;
+ }
req_pos++;
}
@@ -145,7 +148,6 @@ String GDScriptLanguageProtocol::process_message(const String &p_text) {
}
String GDScriptLanguageProtocol::format_output(const String &p_text) {
-
String header = "Content-Length: ";
CharString charstr = p_text.utf8();
size_t len = charstr.length();
@@ -160,7 +162,7 @@ void GDScriptLanguageProtocol::_bind_methods() {
ClassDB::bind_method(D_METHOD("initialized", "params"), &GDScriptLanguageProtocol::initialized);
ClassDB::bind_method(D_METHOD("on_client_connected"), &GDScriptLanguageProtocol::on_client_connected);
ClassDB::bind_method(D_METHOD("on_client_disconnected"), &GDScriptLanguageProtocol::on_client_disconnected);
- ClassDB::bind_method(D_METHOD("notify_client", "p_method", "p_params"), &GDScriptLanguageProtocol::notify_client, DEFVAL(Variant()), DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("notify_client", "method", "params"), &GDScriptLanguageProtocol::notify_client, DEFVAL(Variant()), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("is_smart_resolve_enabled"), &GDScriptLanguageProtocol::is_smart_resolve_enabled);
ClassDB::bind_method(D_METHOD("get_text_document"), &GDScriptLanguageProtocol::get_text_document);
ClassDB::bind_method(D_METHOD("get_workspace"), &GDScriptLanguageProtocol::get_workspace);
@@ -168,7 +170,6 @@ void GDScriptLanguageProtocol::_bind_methods() {
}
Dictionary GDScriptLanguageProtocol::initialize(const Dictionary &p_params) {
-
lsp::InitializeResult ret;
String root_uri = p_params["rootUri"];
@@ -183,15 +184,16 @@ Dictionary GDScriptLanguageProtocol::initialize(const Dictionary &p_params) {
if (root_uri.length() && is_same_workspace) {
workspace->root_uri = root_uri;
} else {
-
workspace->root_uri = "file://" + workspace->root;
Dictionary params;
params["path"] = workspace->root;
- Dictionary request = make_notification("gdscrip_client/changeWorkspace", params);
+ Dictionary request = make_notification("gdscript_client/changeWorkspace", params);
+ ERR_FAIL_COND_V_MSG(!clients.has(latest_client_id), ret.to_json(),
+ vformat("GDScriptLanguageProtocol: Can't initialize invalid peer '%d'.", latest_client_id));
Ref<LSPeer> peer = clients.get(latest_client_id);
- if (peer != NULL) {
+ if (peer != nullptr) {
String msg = JSON::print(request);
msg = format_output(msg);
(*peer)->res_queue.push_back(msg.utf8());
@@ -208,12 +210,10 @@ Dictionary GDScriptLanguageProtocol::initialize(const Dictionary &p_params) {
}
void GDScriptLanguageProtocol::initialized(const Variant &p_params) {
-
lsp::GodotCapabilities capabilities;
DocData *doc = EditorHelp::get_doc_data();
for (Map<String, DocData::ClassDoc>::Element *E = doc->class_list.front(); E; E = E->next()) {
-
lsp::GodotNativeClassInfo gdclass;
gdclass.name = E->get().name;
gdclass.class_doc = &(E->get());
@@ -230,26 +230,26 @@ void GDScriptLanguageProtocol::poll() {
if (server->is_connection_available()) {
on_client_connected();
}
- const int *id = NULL;
+ const int *id = nullptr;
while ((id = clients.next(id))) {
Ref<LSPeer> peer = clients.get(*id);
StreamPeerTCP::Status status = peer->connection->get_status();
if (status == StreamPeerTCP::STATUS_NONE || status == StreamPeerTCP::STATUS_ERROR) {
on_client_disconnected(*id);
- id = NULL;
+ id = nullptr;
} else {
if (peer->connection->get_available_bytes() > 0) {
latest_client_id = *id;
Error err = peer->handle_data();
if (err != OK && err != ERR_BUSY) {
on_client_disconnected(*id);
- id = NULL;
+ id = nullptr;
}
}
Error err = peer->send_data();
if (err != OK && err != ERR_BUSY) {
on_client_disconnected(*id);
- id = NULL;
+ id = nullptr;
}
}
}
@@ -260,7 +260,7 @@ Error GDScriptLanguageProtocol::start(int p_port, const IP_Address &p_bind_ip) {
}
void GDScriptLanguageProtocol::stop() {
- const int *id = NULL;
+ const int *id = nullptr;
while ((id = clients.next(id))) {
Ref<LSPeer> peer = clients.get(*id);
peer->connection->disconnect_from_host();
@@ -271,10 +271,13 @@ void GDScriptLanguageProtocol::stop() {
void GDScriptLanguageProtocol::notify_client(const String &p_method, const Variant &p_params, int p_client_id) {
if (p_client_id == -1) {
+ ERR_FAIL_COND_MSG(latest_client_id == -1,
+ "GDScript LSP: Can't notify client as none was connected.");
p_client_id = latest_client_id;
}
+ ERR_FAIL_COND(!clients.has(p_client_id));
Ref<LSPeer> peer = clients.get(p_client_id);
- ERR_FAIL_COND(peer == NULL);
+ ERR_FAIL_COND(peer == nullptr);
Dictionary message = make_notification(p_method, p_params);
String msg = JSON::print(message);
@@ -293,13 +296,10 @@ bool GDScriptLanguageProtocol::is_goto_native_symbols_enabled() const {
GDScriptLanguageProtocol::GDScriptLanguageProtocol() {
server.instance();
singleton = this;
- _initialized = false;
workspace.instance();
text_document.instance();
set_scope("textDocument", text_document.ptr());
set_scope("completionItem", text_document.ptr());
set_scope("workspace", workspace.ptr());
workspace->root = ProjectSettings::get_singleton()->get_resource_path();
- latest_client_id = 0;
- next_client_id = 0;
}
diff --git a/modules/gdscript/language_server/gdscript_language_protocol.h b/modules/gdscript/language_server/gdscript_language_protocol.h
index 3f0ae36af2..cf5242e8c5 100644
--- a/modules/gdscript/language_server/gdscript_language_protocol.h
+++ b/modules/gdscript/language_server/gdscript_language_protocol.h
@@ -68,10 +68,10 @@ private:
static GDScriptLanguageProtocol *singleton;
- HashMap<int, Ref<LSPeer> > clients;
+ HashMap<int, Ref<LSPeer>> clients;
Ref<TCP_Server> server;
- int latest_client_id;
- int next_client_id;
+ int latest_client_id = 0;
+ int next_client_id = 0;
Ref<GDScriptTextDocument> text_document;
Ref<GDScriptWorkspace> workspace;
@@ -82,7 +82,7 @@ private:
String process_message(const String &p_text);
String format_output(const String &p_text);
- bool _initialized;
+ bool _initialized = false;
protected:
static void _bind_methods();
diff --git a/modules/gdscript/language_server/gdscript_language_server.cpp b/modules/gdscript/language_server/gdscript_language_server.cpp
index 7170c63058..3387d262f8 100644
--- a/modules/gdscript/language_server/gdscript_language_server.cpp
+++ b/modules/gdscript/language_server/gdscript_language_server.cpp
@@ -29,13 +29,14 @@
/*************************************************************************/
#include "gdscript_language_server.h"
+
#include "core/os/file_access.h"
#include "core/os/os.h"
#include "editor/editor_log.h"
#include "editor/editor_node.h"
GDScriptLanguageServer::GDScriptLanguageServer() {
- thread = NULL;
+ thread = nullptr;
thread_running = false;
started = false;
@@ -48,7 +49,6 @@ GDScriptLanguageServer::GDScriptLanguageServer() {
}
void GDScriptLanguageServer::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
start();
@@ -87,7 +87,7 @@ void GDScriptLanguageServer::start() {
if (protocol.start(port, IP_Address("127.0.0.1")) == OK) {
EditorNode::get_log()->add_message("--- GDScript language server started ---", EditorLog::MSG_TYPE_EDITOR);
if (use_thread) {
- ERR_FAIL_COND(thread != NULL);
+ ERR_FAIL_COND(thread != nullptr);
thread_running = true;
thread = Thread::create(GDScriptLanguageServer::thread_main, this);
}
@@ -98,11 +98,11 @@ void GDScriptLanguageServer::start() {
void GDScriptLanguageServer::stop() {
if (use_thread) {
- ERR_FAIL_COND(NULL == thread);
+ ERR_FAIL_COND(nullptr == thread);
thread_running = false;
Thread::wait_to_finish(thread);
memdelete(thread);
- thread = NULL;
+ thread = nullptr;
}
protocol.stop();
started = false;
diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp
index d5723fd20f..c6fe3169dc 100644
--- a/modules/gdscript/language_server/gdscript_text_document.cpp
+++ b/modules/gdscript/language_server/gdscript_text_document.cpp
@@ -29,12 +29,14 @@
/*************************************************************************/
#include "gdscript_text_document.h"
+
#include "../gdscript.h"
#include "core/os/os.h"
#include "editor/editor_settings.h"
#include "editor/plugins/script_text_editor.h"
#include "gdscript_extend_parser.h"
#include "gdscript_language_protocol.h"
+#include "servers/display_server.h"
void GDScriptTextDocument::_bind_methods() {
ClassDB::bind_method(D_METHOD("didOpen"), &GDScriptTextDocument::didOpen);
@@ -84,19 +86,15 @@ void GDScriptTextDocument::notify_client_show_symbol(const lsp::DocumentSymbol *
}
void GDScriptTextDocument::initialize() {
-
if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) {
-
const HashMap<StringName, ClassMembers> &native_members = GDScriptLanguageProtocol::get_singleton()->get_workspace()->native_members;
- const StringName *class_ptr = native_members.next(NULL);
+ const StringName *class_ptr = native_members.next(nullptr);
while (class_ptr) {
-
const ClassMembers &members = native_members.get(*class_ptr);
- const String *name = members.next(NULL);
+ const String *name = members.next(nullptr);
while (name) {
-
const lsp::DocumentSymbol *symbol = members.get(*name);
lsp::CompletionItem item = symbol->make_completion_item();
item.data = JOIN_SYMBOLS(String(*class_ptr), *name);
@@ -111,7 +109,6 @@ void GDScriptTextDocument::initialize() {
}
Variant GDScriptTextDocument::nativeSymbol(const Dictionary &p_params) {
-
Variant ret;
lsp::NativeSymbolInspectParams params;
@@ -141,7 +138,6 @@ Array GDScriptTextDocument::documentSymbol(const Dictionary &p_params) {
}
Array GDScriptTextDocument::completion(const Dictionary &p_params) {
-
Array arr;
lsp::CompletionParams params;
@@ -152,12 +148,10 @@ Array GDScriptTextDocument::completion(const Dictionary &p_params) {
GDScriptLanguageProtocol::get_singleton()->get_workspace()->completion(params, &options);
if (!options.empty()) {
-
int i = 0;
arr.resize(options.size());
for (const List<ScriptCodeCompletionOption>::Element *E = options.front(); E; E = E->next()) {
-
const ScriptCodeCompletionOption &option = E->get();
lsp::CompletionItem item;
item.label = option.display;
@@ -200,11 +194,9 @@ Array GDScriptTextDocument::completion(const Dictionary &p_params) {
i++;
}
} else if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) {
-
arr = native_member_completions.duplicate();
for (Map<String, ExtendGDScriptParser *>::Element *E = GDScriptLanguageProtocol::get_singleton()->get_workspace()->scripts.front(); E; E = E->next()) {
-
ExtendGDScriptParser *script = E->get();
const Array &items = script->get_member_completions();
@@ -219,28 +211,24 @@ Array GDScriptTextDocument::completion(const Dictionary &p_params) {
}
Dictionary GDScriptTextDocument::resolve(const Dictionary &p_params) {
-
lsp::CompletionItem item;
item.load(p_params);
lsp::CompletionParams params;
Variant data = p_params["data"];
- const lsp::DocumentSymbol *symbol = NULL;
+ const lsp::DocumentSymbol *symbol = nullptr;
if (data.get_type() == Variant::DICTIONARY) {
-
params.load(p_params["data"]);
symbol = GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_symbol(params, item.label, item.kind == lsp::CompletionItemKind::Method || item.kind == lsp::CompletionItemKind::Function);
} else if (data.get_type() == Variant::STRING) {
-
String query = data;
Vector<String> param_symbols = query.split(SYMBOL_SEPERATOR, false);
if (param_symbols.size() >= 2) {
-
String class_ = param_symbols[0];
StringName class_name = class_;
String member_name = param_symbols[param_symbols.size() - 1];
@@ -312,13 +300,11 @@ Array GDScriptTextDocument::colorPresentation(const Dictionary &p_params) {
}
Variant GDScriptTextDocument::hover(const Dictionary &p_params) {
-
lsp::TextDocumentPositionParams params;
params.load(p_params);
const lsp::DocumentSymbol *symbol = GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_symbol(params);
if (symbol) {
-
lsp::Hover hover;
hover.contents = symbol->render();
hover.range.start = params.position;
@@ -326,7 +312,6 @@ Variant GDScriptTextDocument::hover(const Dictionary &p_params) {
return hover.to_json();
} else if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) {
-
Dictionary ret;
Array contents;
List<const lsp::DocumentSymbol *> list;
@@ -419,7 +404,8 @@ void GDScriptTextDocument::sync_script_content(const String &p_path, const Strin
void GDScriptTextDocument::show_native_symbol_in_editor(const String &p_symbol_id) {
ScriptEditor::get_singleton()->call_deferred("_help_class_goto", p_symbol_id);
- OS::get_singleton()->move_window_to_foreground();
+
+ DisplayServer::get_singleton()->window_move_to_foreground();
}
Array GDScriptTextDocument::find_symbols(const lsp::TextDocumentPositionParams &p_location, List<const lsp::DocumentSymbol *> &r_list) {
diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp
index ea54784f96..a203b9bfdb 100644
--- a/modules/gdscript/language_server/gdscript_workspace.cpp
+++ b/modules/gdscript/language_server/gdscript_workspace.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "gdscript_workspace.h"
+
#include "../gdscript.h"
#include "../gdscript_parser.h"
#include "core/project_settings.h"
@@ -41,19 +42,19 @@
void GDScriptWorkspace::_bind_methods() {
ClassDB::bind_method(D_METHOD("symbol"), &GDScriptWorkspace::symbol);
- ClassDB::bind_method(D_METHOD("parse_script", "p_path", "p_content"), &GDScriptWorkspace::parse_script);
- ClassDB::bind_method(D_METHOD("parse_local_script", "p_path"), &GDScriptWorkspace::parse_local_script);
- ClassDB::bind_method(D_METHOD("get_file_path", "p_uri"), &GDScriptWorkspace::get_file_path);
- ClassDB::bind_method(D_METHOD("get_file_uri", "p_path"), &GDScriptWorkspace::get_file_uri);
- ClassDB::bind_method(D_METHOD("publish_diagnostics", "p_path"), &GDScriptWorkspace::publish_diagnostics);
- ClassDB::bind_method(D_METHOD("generate_script_api", "p_path"), &GDScriptWorkspace::generate_script_api);
+ ClassDB::bind_method(D_METHOD("parse_script", "path", "content"), &GDScriptWorkspace::parse_script);
+ ClassDB::bind_method(D_METHOD("parse_local_script", "path"), &GDScriptWorkspace::parse_local_script);
+ ClassDB::bind_method(D_METHOD("get_file_path", "uri"), &GDScriptWorkspace::get_file_path);
+ ClassDB::bind_method(D_METHOD("get_file_uri", "path"), &GDScriptWorkspace::get_file_uri);
+ ClassDB::bind_method(D_METHOD("publish_diagnostics", "path"), &GDScriptWorkspace::publish_diagnostics);
+ ClassDB::bind_method(D_METHOD("generate_script_api", "path"), &GDScriptWorkspace::generate_script_api);
}
void GDScriptWorkspace::remove_cache_parser(const String &p_path) {
Map<String, ExtendGDScriptParser *>::Element *parser = parse_results.find(p_path);
Map<String, ExtendGDScriptParser *>::Element *script = scripts.find(p_path);
if (parser && script) {
- if (script->get() && script->get() == script->get()) {
+ if (script->get() && script->get() == parser->get()) {
memdelete(script->get());
} else {
memdelete(script->get());
@@ -71,7 +72,6 @@ void GDScriptWorkspace::remove_cache_parser(const String &p_path) {
}
const lsp::DocumentSymbol *GDScriptWorkspace::get_native_symbol(const String &p_class, const String &p_member) const {
-
StringName class_name = p_class;
StringName empty;
@@ -93,7 +93,7 @@ const lsp::DocumentSymbol *GDScriptWorkspace::get_native_symbol(const String &p_
class_name = ClassDB::get_parent_class(class_name);
}
- return NULL;
+ return nullptr;
}
const lsp::DocumentSymbol *GDScriptWorkspace::get_script_symbol(const String &p_path) const {
@@ -101,7 +101,7 @@ const lsp::DocumentSymbol *GDScriptWorkspace::get_script_symbol(const String &p_
if (S) {
return &(S->get()->get_symbols());
}
- return NULL;
+ return nullptr;
}
void GDScriptWorkspace::reload_all_workspace_scripts() {
@@ -152,7 +152,7 @@ ExtendGDScriptParser *GDScriptWorkspace::get_parse_successed_script(const String
if (S) {
return S->get();
}
- return NULL;
+ return nullptr;
}
ExtendGDScriptParser *GDScriptWorkspace::get_parse_result(const String &p_path) {
@@ -164,7 +164,7 @@ ExtendGDScriptParser *GDScriptWorkspace::get_parse_result(const String &p_path)
if (S) {
return S->get();
}
- return NULL;
+ return nullptr;
}
Array GDScriptWorkspace::symbol(const Dictionary &p_params) {
@@ -185,11 +185,12 @@ Array GDScriptWorkspace::symbol(const Dictionary &p_params) {
}
Error GDScriptWorkspace::initialize() {
- if (initialized) return OK;
+ if (initialized) {
+ return OK;
+ }
DocData *doc = EditorHelp::get_doc_data();
for (Map<String, DocData::ClassDoc>::Element *E = doc->class_list.front(); E; E = E->next()) {
-
const DocData::ClassDoc &class_data = E->value();
lsp::DocumentSymbol class_symbol;
String class_name = E->key();
@@ -314,14 +315,12 @@ Error GDScriptWorkspace::initialize() {
}
Error GDScriptWorkspace::parse_script(const String &p_path, const String &p_content) {
-
ExtendGDScriptParser *parser = memnew(ExtendGDScriptParser);
Error err = parser->parse(p_content, p_path);
Map<String, ExtendGDScriptParser *>::Element *last_parser = parse_results.find(p_path);
Map<String, ExtendGDScriptParser *>::Element *last_script = scripts.find(p_path);
if (err == OK) {
-
remove_cache_parser(p_path);
parse_results[p_path] = parser;
scripts[p_path] = parser;
@@ -377,15 +376,15 @@ void GDScriptWorkspace::publish_diagnostics(const String &p_path) {
}
void GDScriptWorkspace::_get_owners(EditorFileSystemDirectory *efsd, String p_path, List<String> &owners) {
- if (!efsd)
+ 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++) {
@@ -394,51 +393,53 @@ void GDScriptWorkspace::_get_owners(EditorFileSystemDirectory *efsd, String p_pa
break;
}
}
- if (!found)
+ if (!found) {
continue;
+ }
owners.push_back(efsd->get_file_path(i));
}
}
-Node *GDScriptWorkspace::_get_owner_node(String p_path) {
- Node *owner_node = NULL;
+Node *GDScriptWorkspace::_get_owner_scene_node(String p_path) {
+ Node *owner_scene_node = nullptr;
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);
+ for (int i = 0; i < owners.size(); i++) {
+ NodePath owner_path = owners[i];
+ RES owner_res = ResourceLoader::load(owner_path);
+ if (Object::cast_to<PackedScene>(owner_res.ptr())) {
+ Ref<PackedScene> owner_packed_scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*owner_res));
+ owner_scene_node = owner_packed_scene->instance();
+ break;
+ }
}
- return owner_node;
+ return owner_scene_node;
}
void GDScriptWorkspace::completion(const lsp::CompletionParams &p_params, List<ScriptCodeCompletionOption> *r_options) {
-
String path = get_file_path(p_params.textDocument.uri);
String call_hint;
bool forced = false;
if (const ExtendGDScriptParser *parser = get_parse_result(path)) {
- Node *owner_node = _get_owner_node(path);
+ Node *owner_scene_node = _get_owner_scene_node(path);
String code = parser->get_text_for_completion(p_params.position);
- GDScriptLanguage::get_singleton()->complete_code(code, path, owner_node, r_options, forced, call_hint);
- if (owner_node) {
- memdelete(owner_node);
+ GDScriptLanguage::get_singleton()->complete_code(code, path, owner_scene_node, r_options, forced, call_hint);
+ if (owner_scene_node) {
+ memdelete(owner_scene_node);
}
}
}
const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocumentPositionParams &p_doc_pos, const String &p_symbol_name, bool p_func_requred) {
-
- const lsp::DocumentSymbol *symbol = NULL;
+ const lsp::DocumentSymbol *symbol = nullptr;
String path = get_file_path(p_doc_pos.textDocument.uri);
if (const ExtendGDScriptParser *parser = get_parse_result(path)) {
-
String symbol_identifier = p_symbol_name;
Vector<String> identifier_parts = symbol_identifier.split("(");
if (identifier_parts.size()) {
@@ -453,19 +454,14 @@ const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocu
}
if (!symbol_identifier.empty()) {
-
if (ScriptServer::is_global_class(symbol_identifier)) {
-
String class_path = ScriptServer::get_global_class_path(symbol_identifier);
symbol = get_script_symbol(class_path);
} else {
-
ScriptLanguage::LookupResult ret;
- if (OK == GDScriptLanguage::get_singleton()->lookup_code(parser->get_text_for_lookup_symbol(pos, symbol_identifier, p_func_requred), symbol_identifier, path, NULL, ret)) {
-
+ if (OK == GDScriptLanguage::get_singleton()->lookup_code(parser->get_text_for_lookup_symbol(pos, symbol_identifier, p_func_requred), symbol_identifier, path, nullptr, ret)) {
if (ret.type == ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION) {
-
String target_script_path = path;
if (!ret.script.is_null()) {
target_script_path = ret.script->get_path();
@@ -476,7 +472,6 @@ const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocu
}
} else {
-
String member = ret.class_member;
if (member.empty() && symbol_identifier != ret.class_name) {
member = symbol_identifier;
@@ -494,15 +489,13 @@ const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocu
}
void GDScriptWorkspace::resolve_related_symbols(const lsp::TextDocumentPositionParams &p_doc_pos, List<const lsp::DocumentSymbol *> &r_list) {
-
String path = get_file_path(p_doc_pos.textDocument.uri);
if (const ExtendGDScriptParser *parser = get_parse_result(path)) {
-
String symbol_identifier;
Vector2i offset;
symbol_identifier = parser->get_identifier_under_position(p_doc_pos.position, offset);
- const StringName *class_ptr = native_members.next(NULL);
+ const StringName *class_ptr = native_members.next(nullptr);
while (class_ptr) {
const ClassMembers &members = native_members.get(*class_ptr);
if (const lsp::DocumentSymbol *const *symbol = members.getptr(symbol_identifier)) {
@@ -519,9 +512,8 @@ void GDScriptWorkspace::resolve_related_symbols(const lsp::TextDocumentPositionP
}
const HashMap<String, ClassMembers> &inner_classes = script->get_inner_classes();
- const String *_class = inner_classes.next(NULL);
+ const String *_class = inner_classes.next(nullptr);
while (_class) {
-
const ClassMembers *inner_class = inner_classes.getptr(*_class);
if (const lsp::DocumentSymbol *const *symbol = inner_class->getptr(symbol_identifier)) {
r_list.push_back(*symbol);
@@ -534,7 +526,6 @@ 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) {
@@ -548,7 +539,7 @@ const lsp::DocumentSymbol *GDScriptWorkspace::resolve_native_symbol(const lsp::N
}
}
- return NULL;
+ return nullptr;
}
void GDScriptWorkspace::resolve_document_links(const String &p_uri, List<lsp::DocumentLink> &r_list) {
@@ -570,12 +561,10 @@ Dictionary GDScriptWorkspace::generate_script_api(const String &p_path) {
Error GDScriptWorkspace::resolve_signature(const lsp::TextDocumentPositionParams &p_doc_pos, lsp::SignatureHelp &r_signature) {
if (const ExtendGDScriptParser *parser = get_parse_result(get_file_path(p_doc_pos.textDocument.uri))) {
-
lsp::TextDocumentPositionParams text_pos;
text_pos.textDocument = p_doc_pos.textDocument;
if (parser->get_left_function_call(p_doc_pos.position, text_pos.position, r_signature.activeParameter) == OK) {
-
List<const lsp::DocumentSymbol *> symbols;
if (const lsp::DocumentSymbol *symbol = resolve_symbol(text_pos)) {
@@ -587,7 +576,6 @@ Error GDScriptWorkspace::resolve_signature(const lsp::TextDocumentPositionParams
for (List<const lsp::DocumentSymbol *>::Element *E = symbols.front(); E; E = E->next()) {
const lsp::DocumentSymbol *symbol = E->get();
if (symbol->kind == lsp::SymbolKind::Method || symbol->kind == lsp::SymbolKind::Function) {
-
lsp::SignatureInformation signature_info;
signature_info.label = symbol->detail;
signature_info.documentation = symbol->render();
diff --git a/modules/gdscript/language_server/gdscript_workspace.h b/modules/gdscript/language_server/gdscript_workspace.h
index 8b46d345d9..e45b06747d 100644
--- a/modules/gdscript/language_server/gdscript_workspace.h
+++ b/modules/gdscript/language_server/gdscript_workspace.h
@@ -42,7 +42,7 @@ class GDScriptWorkspace : public Reference {
private:
void _get_owners(EditorFileSystemDirectory *efsd, String p_path, List<String> &owners);
- Node *_get_owner_node(String p_path);
+ Node *_get_owner_scene_node(String p_path);
protected:
static void _bind_methods();
diff --git a/modules/gdscript/language_server/lsp.hpp b/modules/gdscript/language_server/lsp.hpp
index a2dcc48820..cf27a1578c 100644
--- a/modules/gdscript/language_server/lsp.hpp
+++ b/modules/gdscript/language_server/lsp.hpp
@@ -33,7 +33,7 @@
#include "core/class_db.h"
#include "core/list.h"
-#include "editor/doc/doc_data.h"
+#include "editor/doc_data.h"
namespace lsp {
@@ -149,14 +149,13 @@ struct Location {
* Represents a link between a source and a target location.
*/
struct LocationLink {
-
/**
* Span of the origin of this link.
*
* Used as the underlined span for mouse interaction. Defaults to the word range at
* the mouse position.
*/
- Range *originSelectionRange = NULL;
+ Range *originSelectionRange = nullptr;
/**
* The target resource identifier of this link.
@@ -220,7 +219,6 @@ struct DocumentLinkParams {
* text document or a web site.
*/
struct DocumentLink {
-
/**
* The range this link applies to.
*/
@@ -282,7 +280,9 @@ struct Command {
Dictionary dict;
dict["title"] = title;
dict["command"] = command;
- if (arguments.size()) dict["arguments"] = arguments;
+ if (arguments.size()) {
+ dict["arguments"] = arguments;
+ }
return dict;
}
};
@@ -486,7 +486,7 @@ struct TextDocumentSyncOptions {
* If present save notifications are sent to the server. If omitted the notification should not be
* sent.
*/
- SaveOptions save;
+ bool save = false;
Dictionary to_json() {
Dictionary dict;
@@ -494,7 +494,7 @@ struct TextDocumentSyncOptions {
dict["willSave"] = willSave;
dict["openClose"] = openClose;
dict["change"] = change;
- dict["save"] = save.to_json();
+ dict["save"] = save;
return dict;
}
};
@@ -946,16 +946,24 @@ struct CompletionItem {
dict["preselect"] = preselect;
dict["sortText"] = sortText;
dict["filterText"] = filterText;
- if (commitCharacters.size()) dict["commitCharacters"] = commitCharacters;
+ if (commitCharacters.size()) {
+ dict["commitCharacters"] = commitCharacters;
+ }
dict["command"] = command.to_json();
}
return dict;
}
void load(const Dictionary &p_dict) {
- if (p_dict.has("label")) label = p_dict["label"];
- if (p_dict.has("kind")) kind = p_dict["kind"];
- if (p_dict.has("detail")) detail = p_dict["detail"];
+ if (p_dict.has("label")) {
+ label = p_dict["label"];
+ }
+ if (p_dict.has("kind")) {
+ kind = p_dict["kind"];
+ }
+ if (p_dict.has("detail")) {
+ detail = p_dict["detail"];
+ }
if (p_dict.has("documentation")) {
Variant doc = p_dict["documentation"];
if (doc.get_type() == Variant::STRING) {
@@ -965,12 +973,24 @@ struct CompletionItem {
documentation.value = v["value"];
}
}
- if (p_dict.has("deprecated")) deprecated = p_dict["deprecated"];
- if (p_dict.has("preselect")) preselect = p_dict["preselect"];
- if (p_dict.has("sortText")) sortText = p_dict["sortText"];
- if (p_dict.has("filterText")) filterText = p_dict["filterText"];
- if (p_dict.has("insertText")) insertText = p_dict["insertText"];
- if (p_dict.has("data")) data = p_dict["data"];
+ if (p_dict.has("deprecated")) {
+ deprecated = p_dict["deprecated"];
+ }
+ if (p_dict.has("preselect")) {
+ preselect = p_dict["preselect"];
+ }
+ if (p_dict.has("sortText")) {
+ sortText = p_dict["sortText"];
+ }
+ if (p_dict.has("filterText")) {
+ filterText = p_dict["filterText"];
+ }
+ if (p_dict.has("insertText")) {
+ insertText = p_dict["insertText"];
+ }
+ if (p_dict.has("data")) {
+ data = p_dict["data"];
+ }
}
};
@@ -1096,7 +1116,6 @@ struct DocumentedSymbolInformation : public SymbolInformation {
* e.g. the range of an identifier.
*/
struct DocumentSymbol {
-
/**
* The name of this symbol. Will be displayed in the user interface and therefore must not be
* an empty string or a string only consisting of white spaces.
@@ -1205,7 +1224,6 @@ struct DocumentSymbol {
}
_FORCE_INLINE_ CompletionItem make_completion_item(bool resolved = false) const {
-
lsp::CompletionItem item;
item.label = name;
@@ -1249,7 +1267,6 @@ struct DocumentSymbol {
};
struct NativeSymbolInspectParams {
-
String native_class;
String symbol_name;
@@ -1281,7 +1298,6 @@ static const String Region = "region";
* Represents a folding range.
*/
struct FoldingRange {
-
/**
* The zero-based line number from where the folded range starts.
*/
@@ -1364,7 +1380,6 @@ struct CompletionContext {
};
struct CompletionParams : public TextDocumentPositionParams {
-
/**
* The completion context. This is only available if the client specifies
* to send this using `ClientCapabilities.textDocument.completion.contextSupport === true`
@@ -1405,7 +1420,6 @@ struct Hover {
* have a label and a doc-comment.
*/
struct ParameterInformation {
-
/**
* The label of this parameter information.
*
@@ -1642,7 +1656,7 @@ struct ServerCapabilities {
_FORCE_INLINE_ Dictionary to_json() {
Dictionary dict;
- dict["textDocumentSync"] = (int)textDocumentSync.change;
+ dict["textDocumentSync"] = textDocumentSync.to_json();
dict["completionProvider"] = completionProvider.to_json();
signatureHelpProvider.triggerCharacters.push_back(",");
signatureHelpProvider.triggerCharacters.push_back("(");
@@ -1684,10 +1698,9 @@ struct InitializeResult {
};
struct GodotNativeClassInfo {
-
String name;
- const DocData::ClassDoc *class_doc = NULL;
- const ClassDB::ClassInfo *class_info = NULL;
+ const DocData::ClassDoc *class_doc = nullptr;
+ const ClassDB::ClassInfo *class_info = nullptr;
Dictionary to_json() {
Dictionary dict;
@@ -1699,7 +1712,6 @@ struct GodotNativeClassInfo {
/** Features not included in the standard lsp specifications */
struct GodotCapabilities {
-
/**
* Native class list
*/
@@ -1718,7 +1730,6 @@ struct GodotCapabilities {
/** 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");