feat: updated engine version to 4.4-rc1

This commit is contained in:
Sara 2025-02-23 14:38:14 +01:00
parent ee00efde1f
commit 21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions

View file

@ -57,11 +57,17 @@ lsp::Position GodotPosition::to_lsp(const Vector<String> &p_lines) const {
return res;
}
res.line = line - 1;
// Special case: `column = 0` -> Starts at beginning of line.
if (column <= 0) {
return res;
}
// Note: character outside of `pos_line.length()-1` is valid.
res.character = column - 1;
String pos_line = p_lines[res.line];
if (pos_line.contains("\t")) {
if (pos_line.contains_char('\t')) {
int tab_size = get_indent_size();
int in_col = 1;
@ -238,9 +244,12 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p
r_symbol.kind = lsp::SymbolKind::Class;
r_symbol.deprecated = false;
r_symbol.range = range_of_node(p_class);
r_symbol.range.start.line = MAX(r_symbol.range.start.line, 0);
if (p_class->identifier) {
r_symbol.selectionRange = range_of_node(p_class->identifier);
} else {
// No meaningful `selectionRange`, but we must ensure that it is inside of `range`.
r_symbol.selectionRange.start = r_symbol.range.start;
r_symbol.selectionRange.end = r_symbol.range.start;
}
r_symbol.detail = "class " + r_symbol.name;
{

View file

@ -37,18 +37,18 @@
#include "core/variant/variant.h"
#ifndef LINE_NUMBER_TO_INDEX
#define LINE_NUMBER_TO_INDEX(p_line) ((p_line)-1)
#define LINE_NUMBER_TO_INDEX(p_line) ((p_line) - 1)
#endif
#ifndef COLUMN_NUMBER_TO_INDEX
#define COLUMN_NUMBER_TO_INDEX(p_column) ((p_column)-1)
#define COLUMN_NUMBER_TO_INDEX(p_column) ((p_column) - 1)
#endif
#ifndef SYMBOL_SEPERATOR
#define SYMBOL_SEPERATOR "::"
#ifndef SYMBOL_SEPARATOR
#define SYMBOL_SEPARATOR "::"
#endif
#ifndef JOIN_SYMBOLS
#define JOIN_SYMBOLS(p_path, name) ((p_path) + SYMBOL_SEPERATOR + (name))
#define JOIN_SYMBOLS(p_path, name) ((p_path) + SYMBOL_SEPARATOR + (name))
#endif
typedef HashMap<String, const lsp::DocumentSymbol *> ClassMembers;

View file

@ -196,7 +196,7 @@ Dictionary GDScriptLanguageProtocol::initialize(const Dictionary &p_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 != nullptr) {
if (peer.is_valid()) {
String msg = Variant(request).to_json_string();
msg = format_output(msg);
(*peer)->res_queue.push_back(msg.utf8());
@ -298,7 +298,7 @@ void GDScriptLanguageProtocol::notify_client(const String &p_method, const Varia
}
ERR_FAIL_COND(!clients.has(p_client_id));
Ref<LSPeer> peer = clients.get(p_client_id);
ERR_FAIL_NULL(peer);
ERR_FAIL_COND(peer.is_null());
Dictionary message = make_notification(p_method, p_params);
String msg = Variant(message).to_json_string();
@ -319,7 +319,7 @@ void GDScriptLanguageProtocol::request_client(const String &p_method, const Vari
}
ERR_FAIL_COND(!clients.has(p_client_id));
Ref<LSPeer> peer = clients.get(p_client_id);
ERR_FAIL_NULL(peer);
ERR_FAIL_COND(peer.is_null());
Dictionary message = make_request(p_method, p_params, next_server_id);
next_server_id++;

View file

@ -33,9 +33,7 @@
#include "gdscript_text_document.h"
#include "gdscript_workspace.h"
#include "godot_lsp.h"
#include "core/io/stream_peer.h"
#include "core/io/stream_peer_tcp.h"
#include "core/io/tcp_server.h"

View file

@ -30,7 +30,6 @@
#include "gdscript_language_server.h"
#include "core/io/file_access.h"
#include "core/os/os.h"
#include "editor/editor_log.h"
#include "editor/editor_node.h"
@ -39,6 +38,7 @@
int GDScriptLanguageServer::port_override = -1;
GDScriptLanguageServer::GDScriptLanguageServer() {
// TODO: Move to editor_settings.cpp
_EDITOR_DEF("network/language_server/remote_host", host);
_EDITOR_DEF("network/language_server/remote_port", port);
_EDITOR_DEF("network/language_server/enable_smart_resolve", true);

View file

@ -31,7 +31,6 @@
#ifndef GDSCRIPT_LANGUAGE_SERVER_H
#define GDSCRIPT_LANGUAGE_SERVER_H
#include "../gdscript_parser.h"
#include "gdscript_language_protocol.h"
#include "editor/plugins/editor_plugin.h"

View file

@ -34,7 +34,6 @@
#include "gdscript_extend_parser.h"
#include "gdscript_language_protocol.h"
#include "core/os/os.h"
#include "editor/editor_settings.h"
#include "editor/plugins/script_text_editor.h"
#include "servers/display_server.h"
@ -112,12 +111,21 @@ void GDScriptTextDocument::didSave(const Variant &p_param) {
}
scr->update_exports();
ScriptEditor::get_singleton()->reload_scripts(true);
ScriptEditor::get_singleton()->update_docs_from_script(scr);
ScriptEditor::get_singleton()->trigger_live_script_reload(scr->get_path());
if (!Thread::is_main_thread()) {
callable_mp(this, &GDScriptTextDocument::reload_script).call_deferred(scr);
} else {
reload_script(scr);
}
}
}
void GDScriptTextDocument::reload_script(Ref<GDScript> p_to_reload_script) {
ScriptEditor::get_singleton()->reload_scripts(true);
ScriptEditor::get_singleton()->update_docs_from_script(p_to_reload_script);
ScriptEditor::get_singleton()->trigger_live_script_reload(p_to_reload_script->get_path());
}
lsp::TextDocumentItem GDScriptTextDocument::load_document_item(const Variant &p_param) {
lsp::TextDocumentItem doc;
Dictionary params = p_param;
@ -229,19 +237,6 @@ Array GDScriptTextDocument::completion(const Dictionary &p_params) {
arr[i] = item.to_json();
i++;
}
} else if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) {
arr = native_member_completions.duplicate();
for (KeyValue<String, ExtendGDScriptParser *> &E : GDScriptLanguageProtocol::get_singleton()->get_workspace()->scripts) {
ExtendGDScriptParser *scr = E.value;
const Array &items = scr->get_member_completions();
const int start_size = arr.size();
arr.resize(start_size + items.size());
for (int i = start_size; i < arr.size(); i++) {
arr[i] = items[i - start_size];
}
}
}
return arr;
}
@ -309,10 +304,10 @@ Dictionary GDScriptTextDocument::resolve(const Dictionary &p_params) {
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) {
} else if (data.is_string()) {
String query = data;
Vector<String> param_symbols = query.split(SYMBOL_SEPERATOR, false);
Vector<String> param_symbols = query.split(SYMBOL_SEPARATOR, false);
if (param_symbols.size() >= 2) {
StringName class_name = param_symbols[0];
@ -485,8 +480,6 @@ GDScriptTextDocument::GDScriptTextDocument() {
void GDScriptTextDocument::sync_script_content(const String &p_path, const String &p_content) {
String path = GDScriptLanguageProtocol::get_singleton()->get_workspace()->get_file_path(p_path);
GDScriptLanguageProtocol::get_singleton()->get_workspace()->parse_script(path, p_content);
EditorFileSystem::get_singleton()->update_file(path);
}
void GDScriptTextDocument::show_native_symbol_in_editor(const String &p_symbol_id) {

View file

@ -36,6 +36,8 @@
#include "core/io/file_access.h"
#include "core/object/ref_counted.h"
class GDScript;
class GDScriptTextDocument : public RefCounted {
GDCLASS(GDScriptTextDocument, RefCounted)
protected:
@ -49,6 +51,7 @@ protected:
void willSaveWaitUntil(const Variant &p_param);
void didSave(const Variant &p_param);
void reload_script(Ref<GDScript> p_to_reload_script);
void sync_script_content(const String &p_path, const String &p_content);
void show_native_symbol_in_editor(const String &p_symbol_id);

View file

@ -657,7 +657,7 @@ void GDScriptWorkspace::completion(const lsp::CompletionParams &p_params, List<S
}
Ref<GDScript> scr = current->get_script();
if (!scr.is_valid() || !GDScript::is_canonically_equal_paths(scr->get_path(), path)) {
if (scr.is_null() || !GDScript::is_canonically_equal_paths(scr->get_path(), path)) {
current = owner_scene_node;
}
}
@ -699,12 +699,12 @@ const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocu
symbol_identifier = "_init";
}
if (OK == GDScriptLanguage::get_singleton()->lookup_code(parser->get_text_for_lookup_symbol(pos, symbol_identifier, p_func_required), symbol_identifier, path, nullptr, ret)) {
if (ret.type == ScriptLanguage::LOOKUP_RESULT_SCRIPT_LOCATION) {
if (ret.location >= 0) {
String target_script_path = path;
if (!ret.script.is_null()) {
if (ret.script.is_valid()) {
target_script_path = ret.script->get_path();
} else if (!ret.class_path.is_empty()) {
target_script_path = ret.class_path;
} else if (!ret.script_path.is_empty()) {
target_script_path = ret.script_path;
}
if (const ExtendGDScriptParser *target_parser = get_parse_result(target_script_path)) {
@ -720,7 +720,6 @@ const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocu
}
}
}
} else {
String member = ret.class_member;
if (member.is_empty() && symbol_identifier != ret.class_name) {

View file

@ -958,28 +958,30 @@ struct CompletionItem {
/**
* A string that should be used when comparing this item
* with other items. When `falsy` the label is used.
* with other items. When omitted the label is used
* as the filter text for this item.
*/
String sortText;
/**
* A string that should be used when filtering a set of
* completion items. When `falsy` the label is used.
* completion items. When omitted the label is used as the
* filter text for this item.
*/
String filterText;
/**
* A string that should be inserted into a document when selecting
* this completion. When `falsy` the label is used.
* this completion. When omitted the label is used as the insert text
* for this item.
*
* The `insertText` is subject to interpretation by the client side.
* Some tools might not take the string literally. For example
* VS Code when code complete is requested in this example `con<cursor position>`
* and a completion item with an `insertText` of `console` is provided it
* will only insert `sole`. Therefore it is recommended to use `textEdit` instead
* since it avoids additional client side interpretation.
*
* @deprecated Use textEdit instead.
* VS Code when code complete is requested in this example
* `con<cursor position>` and a completion item with an `insertText` of
* `console` is provided it will only insert `sole`. Therefore it is
* recommended to use `textEdit` instead since it avoids additional client
* side interpretation.
*/
String insertText;
@ -1034,14 +1036,20 @@ struct CompletionItem {
dict["label"] = label;
dict["kind"] = kind;
dict["data"] = data;
dict["insertText"] = insertText;
if (!insertText.is_empty()) {
dict["insertText"] = insertText;
}
if (resolved) {
dict["detail"] = detail;
dict["documentation"] = documentation.to_json();
dict["deprecated"] = deprecated;
dict["preselect"] = preselect;
dict["sortText"] = sortText;
dict["filterText"] = filterText;
if (!sortText.is_empty()) {
dict["sortText"] = sortText;
}
if (!filterText.is_empty()) {
dict["filterText"] = filterText;
}
if (commitCharacters.size()) {
dict["commitCharacters"] = commitCharacters;
}
@ -1064,7 +1072,7 @@ struct CompletionItem {
}
if (p_dict.has("documentation")) {
Variant doc = p_dict["documentation"];
if (doc.get_type() == Variant::STRING) {
if (doc.is_string()) {
documentation.value = doc;
} else if (doc.get_type() == Variant::DICTIONARY) {
Dictionary v = doc;