diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/CppComprehensionEngine.cpp b/Userland/DevTools/HackStudio/LanguageServers/Cpp/CppComprehensionEngine.cpp index bcd3dc9b68..31ad3d7fd1 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/CppComprehensionEngine.cpp +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/CppComprehensionEngine.cpp @@ -401,16 +401,22 @@ Optional CppComprehensionEngine::fin return {}; const auto& document = *document_ptr; + auto decl = find_declaration_of(document, identifier_position); + if (decl) { + return GUI::AutocompleteProvider::ProjectLocation { decl->filename(), decl->start().line, decl->start().column }; + } + + return find_preprocessor_definition(document, identifier_position); +} + +RefPtr CppComprehensionEngine::find_declaration_of(const DocumentData& document, const GUI::TextPosition& identifier_position) +{ auto node = document.parser().node_at(Cpp::Position { identifier_position.line(), identifier_position.column() }); if (!node) { dbgln_if(CPP_LANGUAGE_SERVER_DEBUG, "no node at position {}:{}", identifier_position.line(), identifier_position.column()); return {}; } - auto decl = find_declaration_of(document, *node); - if (decl) - return GUI::AutocompleteProvider::ProjectLocation { decl->filename(), decl->start().line, decl->start().column }; - - return find_preprocessor_definition(document, identifier_position); + return find_declaration_of(document, *node); } Optional CppComprehensionEngine::find_preprocessor_definition(const DocumentData& document, const GUI::TextPosition& text_position) @@ -439,15 +445,27 @@ struct TargetDeclaration { String name; }; +static Optional get_target_declaration(const ASTNode& node, String name); static Optional get_target_declaration(const ASTNode& node) { - if (!node.is_identifier()) { - dbgln_if(CPP_LANGUAGE_SERVER_DEBUG, "node is not an identifier"); - return {}; + if (node.is_identifier()) { + return get_target_declaration(node, static_cast(node).name()); } - String name = static_cast(node).name(); + if (node.is_declaration()) { + return get_target_declaration(node, verify_cast(node).name()); + } + if (node.is_type() && node.parent() && node.parent()->is_declaration()) { + return get_target_declaration(*node.parent(), verify_cast(node.parent())->name()); + } + + dbgln("get_target_declaration: Invalid argument node of type: {}", node.class_name()); + return {}; +} + +static Optional get_target_declaration(const ASTNode& node, String name) +{ if ((node.parent() && node.parent()->is_function_call()) || (node.parent()->is_name() && node.parent()->parent() && node.parent()->parent()->is_function_call())) { return TargetDeclaration { TargetDeclaration::Type::Function, name }; } @@ -460,14 +478,9 @@ static Optional get_target_declaration(const ASTNode& node) return TargetDeclaration { TargetDeclaration::Type::Variable, name }; } - RefPtr CppComprehensionEngine::find_declaration_of(const DocumentData& document_data, const ASTNode& node) const { dbgln_if(CPP_LANGUAGE_SERVER_DEBUG, "find_declaration_of: {} ({})", document_data.parser().text_of_node(node), node.class_name()); - if (!node.is_identifier()) { - dbgln("node is not an identifier, can't find declaration"); - return {}; - } auto target_decl = get_target_declaration(node); if (!target_decl.has_value()) diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/CppComprehensionEngine.h b/Userland/DevTools/HackStudio/LanguageServers/Cpp/CppComprehensionEngine.h index 1b3fea9733..a656547d2a 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/CppComprehensionEngine.h +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/CppComprehensionEngine.h @@ -102,6 +102,7 @@ private: bool is_property(const ASTNode&) const; RefPtr find_declaration_of(const DocumentData&, const ASTNode&) const; RefPtr find_declaration_of(const DocumentData&, const SymbolName&) const; + RefPtr find_declaration_of(const DocumentData&, const GUI::TextPosition& identifier_position); enum class RecurseIntoScopes { No,