mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 18:22:45 +00:00 
			
		
		
		
	HackStudio+CppLanguageServer: Remove lexer-based autocomplete engine
The parser-based autocomplete engine is at a point where it's stable enough that I don't think there's a need for the lexer-based alternative anymore.
This commit is contained in:
		
							parent
							
								
									ddb278ab85
								
							
						
					
					
						commit
						b1531b78f6
					
				
					 11 changed files with 0 additions and 156 deletions
				
			
		|  | @ -898,8 +898,6 @@ void HackStudioWidget::create_project_menubar(GUI::Menubar& menubar) | |||
|     auto& project_menu = menubar.add_menu("&Project"); | ||||
|     project_menu.add_action(*m_new_file_action); | ||||
|     project_menu.add_action(*m_new_directory_action); | ||||
|     project_menu.add_separator(); | ||||
|     project_menu.add_action(*create_set_autocomplete_mode_action()); | ||||
| } | ||||
| 
 | ||||
| void HackStudioWidget::create_edit_menubar(GUI::Menubar& menubar) | ||||
|  | @ -1000,15 +998,6 @@ 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"); | ||||
|     }); | ||||
|     action->set_checked(true); | ||||
|     return action; | ||||
| } | ||||
| 
 | ||||
| void HackStudioWidget::initialize_menubar(GUI::Menubar& menubar) | ||||
| { | ||||
|     create_file_menubar(menubar); | ||||
|  |  | |||
|  | @ -88,7 +88,6 @@ 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); | ||||
|     RefPtr<EditorWrapper> get_editor_of_file(const String& filename); | ||||
|  |  | |||
|  | @ -84,13 +84,6 @@ void LanguageClient::provide_autocomplete_suggestions(const Vector<GUI::Autocomp | |||
|     // Otherwise, drop it on the floor :shrug:
 | ||||
| } | ||||
| 
 | ||||
| void LanguageClient::set_autocomplete_mode(const String& mode) | ||||
| { | ||||
|     if (!m_connection_wrapper.connection()) | ||||
|         return; | ||||
|     m_connection_wrapper.connection()->async_set_auto_complete_mode(mode); | ||||
| } | ||||
| 
 | ||||
| void LanguageClient::set_active_client() | ||||
| { | ||||
|     if (!m_connection_wrapper.connection()) | ||||
|  |  | |||
|  | @ -128,7 +128,6 @@ 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); | ||||
|     virtual void search_declaration(const String& path, size_t line, size_t column); | ||||
| 
 | ||||
|     void provide_autocomplete_suggestions(const Vector<GUI::AutocompleteProvider::Entry>&) const; | ||||
|  |  | |||
|  | @ -34,7 +34,6 @@ protected: | |||
|     virtual void set_file_content(String const&, String const&) override; | ||||
|     virtual void auto_complete_suggestions(GUI::AutocompleteProvider::ProjectLocation const&) override; | ||||
|     virtual void find_declaration(GUI::AutocompleteProvider::ProjectLocation const&) override; | ||||
|     virtual void set_auto_complete_mode(String const&) override = 0; | ||||
| 
 | ||||
|     FileDB m_filedb; | ||||
|     OwnPtr<AutoCompleteEngine> m_autocomplete_engine; | ||||
|  |  | |||
|  | @ -1,5 +1,4 @@ | |||
| set(SOURCES | ||||
|     LexerAutoComplete.cpp | ||||
|     ParserAutoComplete.cpp | ||||
|     Tests.cpp | ||||
|     main.cpp | ||||
|  |  | |||
|  | @ -6,7 +6,6 @@ | |||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "LexerAutoComplete.h" | ||||
| #include "ParserAutoComplete.h" | ||||
| #include <DevTools/HackStudio/LanguageServers/ClientConnection.h> | ||||
| 
 | ||||
|  | @ -26,15 +25,5 @@ public: | |||
|     } | ||||
| 
 | ||||
|     virtual ~ClientConnection() override = default; | ||||
| 
 | ||||
| private: | ||||
|     virtual void set_auto_complete_mode(String const& mode) override | ||||
|     { | ||||
|         dbgln_if(CPP_LANGUAGE_SERVER_DEBUG, "SetAutoCompleteMode: {}", mode); | ||||
|         if (mode == "Parser") | ||||
|             m_autocomplete_engine = make<ParserAutoComplete>(m_filedb); | ||||
|         else | ||||
|             m_autocomplete_engine = make<LexerAutoComplete>(m_filedb); | ||||
|     } | ||||
| }; | ||||
| } | ||||
|  |  | |||
|  | @ -1,87 +0,0 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2020, Itamar S. <itamar8910@gmail.com> | ||||
|  * | ||||
|  * SPDX-License-Identifier: BSD-2-Clause | ||||
|  */ | ||||
| 
 | ||||
| #include "LexerAutoComplete.h" | ||||
| #include <AK/Debug.h> | ||||
| #include <AK/HashTable.h> | ||||
| #include <LibCpp/Lexer.h> | ||||
| 
 | ||||
| namespace LanguageServers::Cpp { | ||||
| 
 | ||||
| LexerAutoComplete::LexerAutoComplete(const FileDB& filedb) | ||||
|     : AutoCompleteEngine(filedb) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| Vector<GUI::AutocompleteProvider::Entry> LexerAutoComplete::get_suggestions(const String& file, const GUI::TextPosition& autocomplete_position) | ||||
| { | ||||
|     auto document = filedb().get(file); | ||||
|     if (!document) { | ||||
|         dbgln("didn't find document for {}", file); | ||||
|         return {}; | ||||
|     } | ||||
|     auto code = document->text(); | ||||
|     auto lines = code.split('\n', true); | ||||
|     Cpp::Lexer lexer(code); | ||||
|     auto tokens = lexer.lex(); | ||||
| 
 | ||||
|     auto index_of_target_token = token_in_position(tokens, autocomplete_position); | ||||
|     if (!index_of_target_token.has_value()) | ||||
|         return {}; | ||||
| 
 | ||||
|     auto suggestions = identifier_prefixes(lines, tokens, index_of_target_token.value()); | ||||
| 
 | ||||
|     if constexpr (AUTOCOMPLETE_DEBUG) { | ||||
|         for (auto& suggestion : suggestions) { | ||||
|             dbgln("suggestion: {}", suggestion.completion); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return suggestions; | ||||
| } | ||||
| 
 | ||||
| StringView LexerAutoComplete::text_of_token(const Vector<String>& lines, const Cpp::Token& token) | ||||
| { | ||||
|     VERIFY(token.start().line == token.end().line); | ||||
|     VERIFY(token.start().column <= token.end().column); | ||||
|     return lines[token.start().line].substring_view(token.start().column, token.end().column - token.start().column + 1); | ||||
| } | ||||
| 
 | ||||
| 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]; | ||||
|         if (token.start().line != token.end().line) | ||||
|             continue; | ||||
|         if (token.start().line != position.line()) | ||||
|             continue; | ||||
|         if (token.start().column + 1 > position.column() || token.end().column + 1 < position.column()) | ||||
|             continue; | ||||
|         return token_index; | ||||
|     } | ||||
|     return {}; | ||||
| } | ||||
| 
 | ||||
| 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; | ||||
| 
 | ||||
|     HashTable<String> suggestions_lookup; // To avoid duplicate results
 | ||||
| 
 | ||||
|     for (size_t i = 0; i < target_token_index; ++i) { | ||||
|         auto& token = tokens[i]; | ||||
|         if (token.type() != Cpp::Token::Type::Identifier) | ||||
|             continue; | ||||
|         auto text = text_of_token(lines, token); | ||||
|         if (text.starts_with(partial_input) && suggestions_lookup.set(text) == AK::HashSetResult::InsertedNewEntry) { | ||||
|             suggestions.append({ text, partial_input.length(), GUI::AutocompleteProvider::CompletionKind::Identifier }); | ||||
|         } | ||||
|     } | ||||
|     return suggestions; | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  | @ -1,32 +0,0 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2020, Itamar S. <itamar8910@gmail.com> | ||||
|  * | ||||
|  * SPDX-License-Identifier: BSD-2-Clause | ||||
|  */ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <AK/String.h> | ||||
| #include <AK/Vector.h> | ||||
| #include <DevTools/HackStudio/AutoCompleteResponse.h> | ||||
| #include <DevTools/HackStudio/LanguageServers/AutoCompleteEngine.h> | ||||
| #include <LibCpp/Lexer.h> | ||||
| #include <LibGUI/TextPosition.h> | ||||
| 
 | ||||
| namespace LanguageServers::Cpp { | ||||
| 
 | ||||
| using namespace ::Cpp; | ||||
| 
 | ||||
| class LexerAutoComplete : public AutoCompleteEngine { | ||||
| public: | ||||
|     LexerAutoComplete(const FileDB& filedb); | ||||
| 
 | ||||
|     virtual Vector<GUI::AutocompleteProvider::Entry> get_suggestions(const String& file, const GUI::TextPosition& autocomplete_position) override; | ||||
| 
 | ||||
| private: | ||||
|     Optional<size_t> token_in_position(const Vector<Cpp::Token>&, const GUI::TextPosition&); | ||||
|     StringView text_of_token(const Vector<String>& lines, const Cpp::Token&); | ||||
|     Vector<GUI::AutocompleteProvider::Entry> identifier_prefixes(const Vector<String>& lines, const Vector<Cpp::Token>&, size_t target_token_index); | ||||
| }; | ||||
| 
 | ||||
| } | ||||
|  | @ -8,6 +8,5 @@ endpoint LanguageServer | |||
|     set_file_content(String filename, String content) =| | ||||
| 
 | ||||
|     auto_complete_suggestions(GUI::AutocompleteProvider::ProjectLocation location) =| | ||||
|     set_auto_complete_mode(String mode) =| | ||||
|     find_declaration(GUI::AutocompleteProvider::ProjectLocation location) =| | ||||
| } | ||||
|  |  | |||
|  | @ -23,8 +23,5 @@ class ClientConnection final : public LanguageServers::ClientConnection { | |||
|         }; | ||||
|     } | ||||
|     virtual ~ClientConnection() override = default; | ||||
| 
 | ||||
| private: | ||||
|     virtual void set_auto_complete_mode(String const&) override { } | ||||
| }; | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Itamar
						Itamar