Переглянути джерело

LanguageServers/Cpp: Make find_declaration_of() more flexible

Previously, find_declaration_of() only worked for AST nodes of type
Identifier. It now also works for declaration node, member variables
and function parameters.
Itamar 3 роки тому
батько
коміт
76000e9137

+ 27 - 14
Userland/DevTools/HackStudio/LanguageServers/Cpp/CppComprehensionEngine.cpp

@@ -401,16 +401,22 @@ Optional<GUI::AutocompleteProvider::ProjectLocation> 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<Declaration> 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<GUI::AutocompleteProvider::ProjectLocation> CppComprehensionEngine::find_preprocessor_definition(const DocumentData& document, const GUI::TextPosition& text_position)
@@ -439,15 +445,27 @@ struct TargetDeclaration {
     String name;
 };
 
+static Optional<TargetDeclaration> get_target_declaration(const ASTNode& node, String name);
 static Optional<TargetDeclaration> 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<const Identifier&>(node).name());
     }
 
-    String name = static_cast<const Identifier&>(node).name();
+    if (node.is_declaration()) {
+        return get_target_declaration(node, verify_cast<Declaration>(node).name());
+    }
+
+    if (node.is_type() && node.parent() && node.parent()->is_declaration()) {
+        return get_target_declaration(*node.parent(), verify_cast<Declaration>(node.parent())->name());
+    }
+
+    dbgln("get_target_declaration: Invalid argument node of type: {}", node.class_name());
+    return {};
+}
 
+static Optional<TargetDeclaration> 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<TargetDeclaration> get_target_declaration(const ASTNode& node)
 
     return TargetDeclaration { TargetDeclaration::Type::Variable, name };
 }
-
 RefPtr<Declaration> 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())

+ 1 - 0
Userland/DevTools/HackStudio/LanguageServers/Cpp/CppComprehensionEngine.h

@@ -102,6 +102,7 @@ private:
     bool is_property(const ASTNode&) const;
     RefPtr<Declaration> find_declaration_of(const DocumentData&, const ASTNode&) const;
     RefPtr<Declaration> find_declaration_of(const DocumentData&, const SymbolName&) const;
+    RefPtr<Declaration> find_declaration_of(const DocumentData&, const GUI::TextPosition& identifier_position);
 
     enum class RecurseIntoScopes {
         No,