Skip to content

Commit

Permalink
HackStudio: Do not create a new LanguageClient unless needed
Browse files Browse the repository at this point in the history
Previously, whenever Editor::set_document() was called, we destroyed
the previous LanguageClient instance of the editor and created a new
one.

We now check if the language of the existing LanguageClient matches the
new document, and if so we do not create a new LanguageClient instance.

This fixes an issue where doing "goto definition" would crash
HackStudio. This was probably introduced in 44418cb.

The crash occurred because when doing "goto definition", we called a
AK::Function callback from the LanguageClient, which internally called
Editor::set_document().

Editor::set_document() destroyed the existing LanguageClient, which
cased a VERIFY in Function::clear() to fail because we were trying to
destroy the AK::Function object while executing inside it.
  • Loading branch information
itamar8910 authored and awesomekling committed Jun 25, 2021
1 parent 7331b74 commit e16c24b
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 22 deletions.
64 changes: 42 additions & 22 deletions Userland/DevTools/HackStudio/Editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,33 +440,18 @@ CodeDocument& Editor::code_document()

void Editor::set_document(GUI::TextDocument& doc)
{
if (has_document() && &document() == &doc)
return;

VERIFY(doc.is_code_document());
GUI::TextEditor::set_document(doc);

set_override_cursor(Gfx::StandardCursor::IBeam);

CodeDocument& code_document = static_cast<CodeDocument&>(doc);
switch (code_document.language()) {
case Language::Cpp:
set_syntax_highlighter(make<Cpp::SyntaxHighlighter>());
m_language_client = get_language_client<LanguageClients::Cpp::ServerConnection>(project().root_path());
break;
case Language::GML:
set_syntax_highlighter(make<GUI::GMLSyntaxHighlighter>());
break;
case Language::JavaScript:
set_syntax_highlighter(make<JS::SyntaxHighlighter>());
break;
case Language::Ini:
set_syntax_highlighter(make<GUI::IniSyntaxHighlighter>());
break;
case Language::Shell:
set_syntax_highlighter(make<Shell::SyntaxHighlighter>());
m_language_client = get_language_client<LanguageClients::Shell::ServerConnection>(project().root_path());
break;
default:
set_syntax_highlighter({});
}
auto& code_document = static_cast<CodeDocument&>(doc);

set_syntax_highlighter_for(code_document);
set_language_client_for(code_document);

if (m_language_client) {
set_autocomplete_provider(make<LanguageServerAidedAutocompleteProvider>(*m_language_client));
Expand Down Expand Up @@ -586,4 +571,39 @@ void Editor::set_cursor(const GUI::TextPosition& a_position)
TextEditor::set_cursor(a_position);
}

void Editor::set_syntax_highlighter_for(const CodeDocument& document)
{
switch (document.language()) {
case Language::Cpp:
set_syntax_highlighter(make<Cpp::SyntaxHighlighter>());
break;
case Language::GML:
set_syntax_highlighter(make<GUI::GMLSyntaxHighlighter>());
break;
case Language::JavaScript:
set_syntax_highlighter(make<JS::SyntaxHighlighter>());
break;
case Language::Ini:
set_syntax_highlighter(make<GUI::IniSyntaxHighlighter>());
break;
case Language::Shell:
set_syntax_highlighter(make<Shell::SyntaxHighlighter>());
break;
default:
set_syntax_highlighter({});
}
}

void Editor::set_language_client_for(const CodeDocument& document)
{
if (m_language_client && m_language_client->language() == document.language())
return;

if (document.language() == Language::Cpp)
m_language_client = get_language_client<LanguageClients::Cpp::ServerConnection>(project().root_path());

if (document.language() == Language::Shell)
m_language_client = get_language_client<LanguageClients::Shell::ServerConnection>(project().root_path());
}

}
2 changes: 2 additions & 0 deletions Userland/DevTools/HackStudio/Editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ class Editor final : public GUI::TextEditor {
Optional<AutoCompleteRequestData> get_autocomplete_request_data();

void flush_file_content_to_langauge_server();
void set_syntax_highlighter_for(const CodeDocument&);
void set_language_client_for(const CodeDocument&);

explicit Editor();

Expand Down

0 comments on commit e16c24b

Please sign in to comment.