mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 17:32:44 +00:00 
			
		
		
		
	HackStudio: Do not create a new LanguageClient unless needed
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 44418cb351.
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.
			
			
This commit is contained in:
		
							parent
							
								
									7331b74731
								
							
						
					
					
						commit
						e16c24bb95
					
				
					 2 changed files with 44 additions and 22 deletions
				
			
		|  | @ -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)); | ||||
|  | @ -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()); | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -92,6 +92,8 @@ private: | |||
|     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(); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Itamar
						Itamar