diff options
author | Itamar <itamar8910@gmail.com> | 2021-01-23 16:55:19 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-01-27 21:10:57 +0100 |
commit | fa18010477821f114953015677daa789580a4683 (patch) | |
tree | 8449129a0a08038cb261284e5754e0d0673dc070 /Userland/DevTools | |
parent | 8ed96eb27c332bd86dafd3da78b362668e00e0b9 (diff) | |
download | serenity-fa18010477821f114953015677daa789580a4683.zip |
HackStudio: Integate with C++ parser-based autocomplete
By default, C++ auto completion will still be performed by the
lexer-based logic.
However, the parser-based logic can be switched on via the menubar.
Diffstat (limited to 'Userland/DevTools')
-rw-r--r-- | Userland/DevTools/HackStudio/HackStudioWidget.cpp | 9 | ||||
-rw-r--r-- | Userland/DevTools/HackStudio/HackStudioWidget.h | 1 | ||||
-rw-r--r-- | Userland/DevTools/HackStudio/LanguageClient.cpp | 6 | ||||
-rw-r--r-- | Userland/DevTools/HackStudio/LanguageClient.h | 1 | ||||
-rw-r--r-- | Userland/DevTools/HackStudio/LanguageServers/Cpp/CMakeLists.txt | 3 | ||||
-rw-r--r-- | Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.cpp | 25 | ||||
-rw-r--r-- | Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.h | 8 | ||||
-rw-r--r-- | Userland/DevTools/HackStudio/LanguageServers/Cpp/LexerAutoComplete.cpp (renamed from Userland/DevTools/HackStudio/LanguageServers/Cpp/AutoComplete.cpp) | 10 | ||||
-rw-r--r-- | Userland/DevTools/HackStudio/LanguageServers/Cpp/LexerAutoComplete.h (renamed from Userland/DevTools/HackStudio/LanguageServers/Cpp/AutoComplete.h) | 4 | ||||
-rw-r--r-- | Userland/DevTools/HackStudio/LanguageServers/LanguageServer.ipc | 1 | ||||
-rw-r--r-- | Userland/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.h | 1 |
11 files changed, 59 insertions, 10 deletions
diff --git a/Userland/DevTools/HackStudio/HackStudioWidget.cpp b/Userland/DevTools/HackStudio/HackStudioWidget.cpp index 7ef0eb33d2..15dfd5a7d9 100644 --- a/Userland/DevTools/HackStudio/HackStudioWidget.cpp +++ b/Userland/DevTools/HackStudio/HackStudioWidget.cpp @@ -841,6 +841,7 @@ void HackStudioWidget::create_project_menubar(GUI::MenuBar& menubar) { auto& project_menu = menubar.add_menu("Project"); project_menu.add_action(*m_new_action); + project_menu.add_action(*create_set_autocomplete_mode_action()); } void HackStudioWidget::create_edit_menubar(GUI::MenuBar& menubar) @@ -919,6 +920,14 @@ NonnullRefPtr<GUI::Action> HackStudioWidget::create_stop_action() return action; } +NonnullRefPtr<GUI::Action> HackStudioWidget::create_set_autocomplete_mode_action() +{ + auto action = GUI::Action::create_checkable("AutoComplete C++ with Parser", [this](auto& action) { + get_language_client<LanguageClients::Cpp::ServerConnection>(project().root_path())->set_autocomplete_mode(action.is_checked() ? "Parser" : "Lexer"); + }); + return action; +} + void HackStudioWidget::initialize_menubar(GUI::MenuBar& menubar) { create_app_menubar(menubar); diff --git a/Userland/DevTools/HackStudio/HackStudioWidget.h b/Userland/DevTools/HackStudio/HackStudioWidget.h index 29ef3701e4..d35ec85284 100644 --- a/Userland/DevTools/HackStudio/HackStudioWidget.h +++ b/Userland/DevTools/HackStudio/HackStudioWidget.h @@ -94,6 +94,7 @@ private: NonnullRefPtr<GUI::Action> create_build_action(); NonnullRefPtr<GUI::Action> create_run_action(); NonnullRefPtr<GUI::Action> create_stop_action(); + NonnullRefPtr<GUI::Action> create_set_autocomplete_mode_action(); void add_new_editor(GUI::Widget& parent); NonnullRefPtr<EditorWrapper> get_editor_of_file(const String& file_name); diff --git a/Userland/DevTools/HackStudio/LanguageClient.cpp b/Userland/DevTools/HackStudio/LanguageClient.cpp index e02b2c98cf..98341a046f 100644 --- a/Userland/DevTools/HackStudio/LanguageClient.cpp +++ b/Userland/DevTools/HackStudio/LanguageClient.cpp @@ -25,6 +25,7 @@ */ #include "LanguageClient.h" +#include "DevTools/HackStudio/LanguageServers/LanguageServerEndpoint.h" #include <AK/String.h> #include <AK/Vector.h> @@ -72,4 +73,9 @@ void LanguageClient::provide_autocomplete_suggestions(const Vector<GUI::Autocomp // Otherwise, drop it on the floor :shrug: } +void LanguageClient::set_autocomplete_mode(const String& mode) +{ + m_connection.post_message(Messages::LanguageServer::SetAutoCompleteMode(mode)); +} + } diff --git a/Userland/DevTools/HackStudio/LanguageClient.h b/Userland/DevTools/HackStudio/LanguageClient.h index 03c362f6a7..c24a9e9868 100644 --- a/Userland/DevTools/HackStudio/LanguageClient.h +++ b/Userland/DevTools/HackStudio/LanguageClient.h @@ -110,6 +110,7 @@ public: virtual void insert_text(const String& path, const String& text, size_t line, size_t column); virtual void remove_text(const String& path, size_t from_line, size_t from_column, size_t to_line, size_t to_column); virtual void request_autocomplete(const String& path, size_t cursor_line, size_t cursor_column); + virtual void set_autocomplete_mode(const String& mode); void provide_autocomplete_suggestions(const Vector<GUI::AutocompleteProvider::Entry>&); diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/CMakeLists.txt b/Userland/DevTools/HackStudio/LanguageServers/Cpp/CMakeLists.txt index de9569d8ca..7d34577447 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/CMakeLists.txt +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/CMakeLists.txt @@ -1,7 +1,8 @@ set(SOURCES ClientConnection.cpp main.cpp - AutoComplete.cpp + LexerAutoComplete.cpp + ParserAutoComplete.cpp ) set(GENERATED_SOURCES diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.cpp b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.cpp index 5881dbbeee..c3cdedeef4 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.cpp +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.cpp @@ -25,7 +25,8 @@ */ #include "ClientConnection.h" -#include "AutoComplete.h" +#include "LexerAutoComplete.h" +#include "ParserAutoComplete.h" #include <AK/Debug.h> #include <AK/HashMap.h> #include <LibCore/File.h> @@ -146,7 +147,16 @@ void ClientConnection::handle(const Messages::LanguageServer::AutoCompleteSugges return; } - auto suggestions = AutoComplete::get_suggestions(document->text(), { (size_t)message.cursor_line(), (size_t)max(message.cursor_column(), message.cursor_column() - 1) }); + Vector<GUI::AutocompleteProvider::Entry> suggestions; + switch (m_auto_complete_mode) { + case AutoCompleteMode::Lexer: + suggestions = LexerAutoComplete::get_suggestions(document->text(), { (size_t)message.cursor_line(), (size_t)max(message.cursor_column(), message.cursor_column() - 1) }); + break; + case AutoCompleteMode::Parser: { + auto engine = ParserAutoComplete(document->text()); + suggestions = engine.get_suggestions({ (size_t)message.cursor_line(), (size_t)max(message.cursor_column(), message.cursor_column() - 1) }); + } + } post_message(Messages::LanguageClient::AutoCompleteSuggestions(move(suggestions))); } @@ -170,4 +180,15 @@ void ClientConnection::handle(const Messages::LanguageServer::SetFileContent& me document->set_text(content.view()); } +void ClientConnection::handle(const Messages::LanguageServer::SetAutoCompleteMode& message) +{ +#ifdef DEBUG_CPP_LANGUAGE_SERVER + dbgln("SetAutoCompleteMode: {}", message.mode()); +#endif + if (message.mode() == "Parser") + m_auto_complete_mode = AutoCompleteMode::Parser; + else + m_auto_complete_mode = AutoCompleteMode::Lexer; +} + } diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.h b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.h index d0a7b4558c..3389ba8231 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.h +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.h @@ -55,10 +55,18 @@ private: virtual void handle(const Messages::LanguageServer::FileEditRemoveText&) override; virtual void handle(const Messages::LanguageServer::SetFileContent&) override; virtual void handle(const Messages::LanguageServer::AutoCompleteSuggestions&) override; + virtual void handle(const Messages::LanguageServer::SetAutoCompleteMode&) override; RefPtr<GUI::TextDocument> document_for(const String& file_name); HashMap<String, NonnullRefPtr<GUI::TextDocument>> m_open_files; + + enum class AutoCompleteMode { + Lexer, + Parser + }; + + AutoCompleteMode m_auto_complete_mode { AutoCompleteMode::Lexer }; }; } diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/AutoComplete.cpp b/Userland/DevTools/HackStudio/LanguageServers/Cpp/LexerAutoComplete.cpp index b864563b4e..9a31679728 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/AutoComplete.cpp +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/LexerAutoComplete.cpp @@ -24,14 +24,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "AutoComplete.h" +#include "LexerAutoComplete.h" #include <AK/Debug.h> #include <AK/HashTable.h> #include <LibCpp/Lexer.h> namespace LanguageServers::Cpp { -Vector<GUI::AutocompleteProvider::Entry> AutoComplete::get_suggestions(const String& code, const GUI::TextPosition& autocomplete_position) +Vector<GUI::AutocompleteProvider::Entry> LexerAutoComplete::get_suggestions(const String& code, const GUI::TextPosition& autocomplete_position) { auto lines = code.split('\n', true); Cpp::Lexer lexer(code); @@ -52,14 +52,14 @@ Vector<GUI::AutocompleteProvider::Entry> AutoComplete::get_suggestions(const Str return suggestions; } -StringView AutoComplete::text_of_token(const Vector<String>& lines, const Cpp::Token& token) +StringView LexerAutoComplete::text_of_token(const Vector<String>& lines, const Cpp::Token& token) { ASSERT(token.m_start.line == token.m_end.line); ASSERT(token.m_start.column <= token.m_end.column); return lines[token.m_start.line].substring_view(token.m_start.column, token.m_end.column - token.m_start.column + 1); } -Optional<size_t> AutoComplete::token_in_position(const Vector<Cpp::Token>& tokens, const GUI::TextPosition& position) +Optional<size_t> LexerAutoComplete::token_in_position(const Vector<Cpp::Token>& tokens, const GUI::TextPosition& position) { for (size_t token_index = 0; token_index < tokens.size(); ++token_index) { auto& token = tokens[token_index]; @@ -74,7 +74,7 @@ Optional<size_t> AutoComplete::token_in_position(const Vector<Cpp::Token>& token return {}; } -Vector<GUI::AutocompleteProvider::Entry> AutoComplete::identifier_prefixes(const Vector<String>& lines, const Vector<Cpp::Token>& tokens, size_t target_token_index) +Vector<GUI::AutocompleteProvider::Entry> LexerAutoComplete::identifier_prefixes(const Vector<String>& lines, const Vector<Cpp::Token>& tokens, size_t target_token_index) { auto partial_input = text_of_token(lines, tokens[target_token_index]); Vector<GUI::AutocompleteProvider::Entry> suggestions; diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/AutoComplete.h b/Userland/DevTools/HackStudio/LanguageServers/Cpp/LexerAutoComplete.h index b4096bd793..e482818cfc 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/AutoComplete.h +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/LexerAutoComplete.h @@ -36,9 +36,9 @@ namespace LanguageServers::Cpp { using namespace ::Cpp; -class AutoComplete { +class LexerAutoComplete { public: - AutoComplete() = delete; + LexerAutoComplete() = delete; static Vector<GUI::AutocompleteProvider::Entry> get_suggestions(const String& code, const GUI::TextPosition& autocomplete_position); diff --git a/Userland/DevTools/HackStudio/LanguageServers/LanguageServer.ipc b/Userland/DevTools/HackStudio/LanguageServers/LanguageServer.ipc index de16fa14ec..405dbbab88 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/LanguageServer.ipc +++ b/Userland/DevTools/HackStudio/LanguageServers/LanguageServer.ipc @@ -8,4 +8,5 @@ endpoint LanguageServer = 8001 SetFileContent(String file_name, String content) =| AutoCompleteSuggestions(String file_name, i32 cursor_line, i32 cursor_column) =| + SetAutoCompleteMode(String mode) =| } diff --git a/Userland/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.h b/Userland/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.h index bb7fc14bd9..cea922037e 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.h +++ b/Userland/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.h @@ -56,6 +56,7 @@ private: virtual void handle(const Messages::LanguageServer::FileEditRemoveText&) override; virtual void handle(const Messages::LanguageServer::SetFileContent&) override; virtual void handle(const Messages::LanguageServer::AutoCompleteSuggestions&) override; + virtual void handle(const Messages::LanguageServer::SetAutoCompleteMode&) override { } RefPtr<GUI::TextDocument> document_for(const String& file_name); |