summaryrefslogtreecommitdiff
path: root/Userland/DevTools
diff options
context:
space:
mode:
authorItamar <itamar8910@gmail.com>2021-01-23 16:55:19 +0200
committerAndreas Kling <kling@serenityos.org>2021-01-27 21:10:57 +0100
commitfa18010477821f114953015677daa789580a4683 (patch)
tree8449129a0a08038cb261284e5754e0d0673dc070 /Userland/DevTools
parent8ed96eb27c332bd86dafd3da78b362668e00e0b9 (diff)
downloadserenity-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.cpp9
-rw-r--r--Userland/DevTools/HackStudio/HackStudioWidget.h1
-rw-r--r--Userland/DevTools/HackStudio/LanguageClient.cpp6
-rw-r--r--Userland/DevTools/HackStudio/LanguageClient.h1
-rw-r--r--Userland/DevTools/HackStudio/LanguageServers/Cpp/CMakeLists.txt3
-rw-r--r--Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.cpp25
-rw-r--r--Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.h8
-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.ipc1
-rw-r--r--Userland/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.h1
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);