diff options
Diffstat (limited to 'modules/gdscript/language_server')
8 files changed, 116 insertions, 153 deletions
| diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp index 0f6f13944b..385d5dd7cb 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()) { @@ -62,7 +62,7 @@ void ExtendGDScriptParser::update_diagnostics() {  		const GDScriptWarning &warning = E->get();  		lsp::Diagnostic diagnostic;  		diagnostic.severity = lsp::DiagnosticSeverity::Warning; -		diagnostic.message = warning.get_message(); +		diagnostic.message = "(" + warning.get_name() + "): " + warning.get_message();  		diagnostic.source = "gdscript";  		diagnostic.code = warning.code;  		lsp::Range range; @@ -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 d929fd255d..cf5242e8c5 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.h +++ b/modules/gdscript/language_server/gdscript_language_protocol.h @@ -70,8 +70,8 @@ private:  	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 fbf8ef2f8f..c6fe3169dc 100644 --- a/modules/gdscript/language_server/gdscript_text_document.cpp +++ b/modules/gdscript/language_server/gdscript_text_document.cpp @@ -29,6 +29,7 @@  /*************************************************************************/  #include "gdscript_text_document.h" +  #include "../gdscript.h"  #include "core/os/os.h"  #include "editor/editor_settings.h" @@ -85,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); @@ -112,7 +109,6 @@ void GDScriptTextDocument::initialize() {  }  Variant GDScriptTextDocument::nativeSymbol(const Dictionary &p_params) { -  	Variant ret;  	lsp::NativeSymbolInspectParams params; @@ -142,7 +138,6 @@ Array GDScriptTextDocument::documentSymbol(const Dictionary &p_params) {  }  Array GDScriptTextDocument::completion(const Dictionary &p_params) { -  	Array arr;  	lsp::CompletionParams params; @@ -153,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; @@ -201,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(); @@ -220,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]; @@ -313,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; @@ -327,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; diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp index 205257b8f2..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,12 +42,12 @@  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) { @@ -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,15 +393,16 @@ 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_scene_node(String p_path) { -	Node *owner_scene_node = NULL; +	Node *owner_scene_node = nullptr;  	List<String> owners;  	_get_owners(EditorFileSystem::get_singleton()->get_filesystem(), p_path, owners); @@ -421,7 +421,6 @@ Node *GDScriptWorkspace::_get_owner_scene_node(String p_path) {  }  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; @@ -437,12 +436,10 @@ void GDScriptWorkspace::completion(const lsp::CompletionParams &p_params, List<S  }  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()) { @@ -457,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(); @@ -480,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; @@ -498,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)) { @@ -523,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); @@ -538,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) { @@ -552,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) { @@ -574,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)) { @@ -591,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/lsp.hpp b/modules/gdscript/language_server/lsp.hpp index 914c9742e1..cf27a1578c 100644 --- a/modules/gdscript/language_server/lsp.hpp +++ b/modules/gdscript/language_server/lsp.hpp @@ -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"); |