From 84e34d76d847d79e921c05576c1fedc774261306 Mon Sep 17 00:00:00 2001 From: Itamar Date: Tue, 23 Mar 2021 12:32:45 +0200 Subject: [PATCH] HackStudio+LanguageServers/Cpp: Show scope of symbols in Locator --- Base/home/anon/Source/little/other.cpp | 4 +++ Base/home/anon/Source/little/other.h | 5 +++ .../HackStudio/AutoCompleteResponse.h | 5 +++ .../Cpp/ParserAutoComplete.cpp | 33 +++++++++++++++---- .../LanguageServers/Cpp/ParserAutoComplete.h | 1 + .../LanguageServers/Shell/AutoComplete.cpp | 4 +-- Userland/DevTools/HackStudio/Locator.cpp | 9 +++-- Userland/Libraries/LibCpp/AST.h | 2 +- Userland/Libraries/LibCpp/Parser.h | 1 - .../Libraries/LibGUI/AutocompleteProvider.h | 1 + 10 files changed, 52 insertions(+), 13 deletions(-) diff --git a/Base/home/anon/Source/little/other.cpp b/Base/home/anon/Source/little/other.cpp index a35a49284a6..5569d78eeb7 100644 --- a/Base/home/anon/Source/little/other.cpp +++ b/Base/home/anon/Source/little/other.cpp @@ -1,6 +1,8 @@ #include "other.h" #include +namespace MyNamespace { + int func() { int x = 1; @@ -12,3 +14,5 @@ int func() printf("x+y: %d\n", x + y); return x + y; } + +} diff --git a/Base/home/anon/Source/little/other.h b/Base/home/anon/Source/little/other.h index 54f64fd686f..4acda987e79 100644 --- a/Base/home/anon/Source/little/other.h +++ b/Base/home/anon/Source/little/other.h @@ -1,3 +1,6 @@ + +namespace MyNamespace { + int func(); #define USE_VAR2 @@ -12,3 +15,5 @@ struct StructInHeader { int var3; #endif }; + +} diff --git a/Userland/DevTools/HackStudio/AutoCompleteResponse.h b/Userland/DevTools/HackStudio/AutoCompleteResponse.h index 26f2ed45ebd..457a0d5890e 100644 --- a/Userland/DevTools/HackStudio/AutoCompleteResponse.h +++ b/Userland/DevTools/HackStudio/AutoCompleteResponse.h @@ -98,6 +98,7 @@ inline bool encode(Encoder& encoder, const GUI::AutocompleteProvider::Declaratio if (!encode(encoder, declaration.position)) return false; encoder << (u32)declaration.type; + encoder << declaration.scope; return true; } @@ -109,10 +110,14 @@ inline bool decode(Decoder& decoder, GUI::AutocompleteProvider::Declaration& dec if (!decode(decoder, declaration.position)) return false; + u32 type; if (!decoder.decode(type)) return false; + if (!decoder.decode(declaration.scope)) + return false; + declaration.type = static_cast(type); return true; } diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.cpp b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.cpp index 228c2f07da2..53a58577c9c 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.cpp +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.cpp @@ -294,8 +294,7 @@ NonnullRefPtrVector ParserAutoComplete::get_global_declarations(con for (auto& decl : node.declarations()) { declarations.append(decl); - if(decl.is_namespace()) - { + if (decl.is_namespace()) { declarations.append(get_global_declarations(decl)); } } @@ -410,13 +409,12 @@ void ParserAutoComplete::update_declared_symbols(const DocumentData& document) { Vector declarations; - for(auto& decl : get_global_declarations(*document.parser().root_node())) - { - declarations.append({ decl.name(), { document.filename(), decl.start().line, decl.start().column }, type_of_declaration(decl) }); + for (auto& decl : get_global_declarations(*document.parser().root_node())) { + declarations.append({ decl.name(), { document.filename(), decl.start().line, decl.start().column }, type_of_declaration(decl), scope_of_declaration(decl) }); } for (auto& definition : document.preprocessor().definitions()) { - declarations.append({ definition.key, { document.filename(), definition.value.line, definition.value.column }, GUI::AutocompleteProvider::DeclarationType::PreprocessorDefinition }); + declarations.append({ definition.key, { document.filename(), definition.value.line, definition.value.column }, GUI::AutocompleteProvider::DeclarationType::PreprocessorDefinition, {} }); } set_declarations_of_document(document.filename(), move(declarations)); @@ -460,4 +458,27 @@ OwnPtr ParserAutoComplete::create_document_dat return document_data; } +String ParserAutoComplete::scope_of_declaration(const Declaration& decl) +{ + + auto parent = decl.parent(); + if (!parent) + return {}; + + if (!parent->is_declaration()) + return {}; + + auto& parent_decl = static_cast(*parent); + + if (parent_decl.is_namespace()) { + auto& containing_namespace = static_cast(parent_decl); + auto scope_of_parent = scope_of_declaration(parent_decl); + if (scope_of_parent.is_null()) + return containing_namespace.m_name; + return String::formatted("{}::{}", scope_of_parent, containing_namespace.m_name); + } + + return {}; +} + } diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.h b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.h index c5dcef52c62..42b22856ea9 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.h +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.h @@ -107,6 +107,7 @@ private: String document_path_from_include_path(const StringView& include_path) const; void update_declared_symbols(const DocumentData&); GUI::AutocompleteProvider::DeclarationType type_of_declaration(const Declaration&); + String scope_of_declaration(const Declaration&); Optional find_preprocessor_definition(const DocumentData&, const GUI::TextPosition&); OwnPtr create_document_data(String&& text, const String& filename); diff --git a/Userland/DevTools/HackStudio/LanguageServers/Shell/AutoComplete.cpp b/Userland/DevTools/HackStudio/LanguageServers/Shell/AutoComplete.cpp index 1302646d793..08da4bbe26f 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Shell/AutoComplete.cpp +++ b/Userland/DevTools/HackStudio/LanguageServers/Shell/AutoComplete.cpp @@ -233,7 +233,7 @@ void AutoComplete::update_declared_symbols(const DocumentData& document) if (!name.is_empty()) { dbgln("Found variable {}", name); - declarations.append({ move(name), { filename, entry.name->position().start_line.line_number, entry.name->position().start_line.line_column }, GUI::AutocompleteProvider::DeclarationType::Variable }); + declarations.append({ move(name), { filename, entry.name->position().start_line.line_number, entry.name->position().start_line.line_column }, GUI::AutocompleteProvider::DeclarationType::Variable, {} }); } } ::Shell::AST::NodeVisitor::visit(node); @@ -242,7 +242,7 @@ void AutoComplete::update_declared_symbols(const DocumentData& document) void visit(const ::Shell::AST::FunctionDeclaration* node) override { dbgln("Found function {}", node->name().name); - declarations.append({ node->name().name, { filename, node->position().start_line.line_number, node->position().start_line.line_column }, GUI::AutocompleteProvider::DeclarationType::Function }); + declarations.append({ node->name().name, { filename, node->position().start_line.line_number, node->position().start_line.line_column }, GUI::AutocompleteProvider::DeclarationType::Function, {} }); } const String& filename; diff --git a/Userland/DevTools/HackStudio/Locator.cpp b/Userland/DevTools/HackStudio/Locator.cpp index b796b2ddd48..24e8bbdf63c 100644 --- a/Userland/DevTools/HackStudio/Locator.cpp +++ b/Userland/DevTools/HackStudio/Locator.cpp @@ -77,8 +77,11 @@ public: return GUI::FileIconProvider::icon_for_path(suggestion.as_filename.value()); } if (suggestion.is_symbol_declaration()) { - if (index.column() == Column::Name) - return suggestion.as_symbol_declaration.value().name; + if (index.column() == Column::Name) { + if (suggestion.as_symbol_declaration.value().scope.is_null()) + return suggestion.as_symbol_declaration.value().name; + return String::formatted("{}::{}", suggestion.as_symbol_declaration.value().scope, suggestion.as_symbol_declaration.value().name); + } if (index.column() == Column::Filename) return suggestion.as_symbol_declaration.value().position.file; if (index.column() == Column::Icon) { @@ -225,7 +228,7 @@ void Locator::update_suggestions() for (auto& item : m_document_to_declarations) { for (auto& decl : item.value) { - if (decl.name.contains(typed_text, CaseSensitivity::CaseInsensitive)) + if (decl.name.contains(typed_text, CaseSensitivity::CaseInsensitive) || decl.scope.contains(typed_text, CaseSensitivity::CaseInsensitive)) suggestions.append((LocatorSuggestionModel::Suggestion::create_symbol_declaration(decl))); } } diff --git a/Userland/Libraries/LibCpp/AST.h b/Userland/Libraries/LibCpp/AST.h index 498ca566cbb..1fab2109ed4 100644 --- a/Userland/Libraries/LibCpp/AST.h +++ b/Userland/Libraries/LibCpp/AST.h @@ -75,6 +75,7 @@ public: virtual bool is_variable_or_parameter_declaration() const { return false; } virtual bool is_function_call() const { return false; } virtual bool is_type() const { return false; } + virtual bool is_declaration() const { return false; } protected: ASTNode(ASTNode* parent, Optional start, Optional end, const String& filename) @@ -113,7 +114,6 @@ public: virtual ~Statement() override = default; virtual const char* class_name() const override { return "Statement"; } - virtual bool is_declaration() const { return false; } virtual NonnullRefPtrVector declarations() const override; protected: diff --git a/Userland/Libraries/LibCpp/Parser.h b/Userland/Libraries/LibCpp/Parser.h index 4511e09bdad..98f9424f630 100644 --- a/Userland/Libraries/LibCpp/Parser.h +++ b/Userland/Libraries/LibCpp/Parser.h @@ -121,7 +121,6 @@ private: NonnullRefPtrVector parse_declarations_in_translation_unit(ASTNode& parent); RefPtr parse_single_declaration_in_translation_unit(ASTNode& parent); - bool match(Token::Type); Token consume(Token::Type); Token consume(); diff --git a/Userland/Libraries/LibGUI/AutocompleteProvider.h b/Userland/Libraries/LibGUI/AutocompleteProvider.h index 98ae75a89ea..8613be538b5 100644 --- a/Userland/Libraries/LibGUI/AutocompleteProvider.h +++ b/Userland/Libraries/LibGUI/AutocompleteProvider.h @@ -75,6 +75,7 @@ public: String name; ProjectLocation position; DeclarationType type; + String scope; }; virtual void provide_completions(Function)>) = 0;