Prechádzať zdrojové kódy

LanguageServers/Cpp: Autocomplete declarations from included headers

We now also look at the available declarations from included header
files when autocompleting names.

Additionally, you can now request autocomplete on an empty token, which
brings up all available names, starting from the inner-most scope.
Itamar 4 rokov pred
rodič
commit
ef9bfbd383

+ 19 - 10
Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.cpp

@@ -109,22 +109,29 @@ Vector<GUI::AutocompleteProvider::Entry> ParserAutoComplete::get_suggestions(con
         return {};
     }
 
-    if (!node->is_identifier()) {
-        if (is_empty_property(document, *node, position)) {
-            ASSERT(node->is_member_expression());
-            return autocomplete_property(document, (MemberExpression&)(*node), "");
+    if (node->is_identifier()) {
+        if (is_property(*node)) {
+            return autocomplete_property(document, (MemberExpression&)(*node->parent()), document.parser.text_of_node(*node));
         }
-        return {};
+
+        return autocomplete_name(document, *node, document.parser.text_of_node(*node));
+    }
+
+    if (is_empty_property(document, *node, position)) {
+        ASSERT(node->is_member_expression());
+        return autocomplete_property(document, (MemberExpression&)(*node), "");
     }
 
-    if (is_property(*node)) {
-        return autocomplete_property(document, (MemberExpression&)(*node->parent()), document.parser.text_of_node(*node));
+    String partial_text = String::empty();
+    auto containing_token = document.parser.token_at(position);
+    if (containing_token.has_value()) {
+        partial_text = document.parser.text_of_token(containing_token.value());
     }
 
-    return autocomplete_identifier(document, *node);
+    return autocomplete_name(document, *node, partial_text.view());
 }
 
-Vector<GUI::AutocompleteProvider::Entry> ParserAutoComplete::autocomplete_identifier(const DocumentData& document, const ASTNode& node) const
+Vector<GUI::AutocompleteProvider::Entry> ParserAutoComplete::autocomplete_name(const DocumentData& document, const ASTNode& node, const StringView& partial_text) const
 {
     const Cpp::ASTNode* current = &node;
     NonnullRefPtrVector<Cpp::Declaration> available_declarations;
@@ -132,6 +139,9 @@ Vector<GUI::AutocompleteProvider::Entry> ParserAutoComplete::autocomplete_identi
         available_declarations.append(current->declarations());
         current = current->parent();
     }
+
+    available_declarations.append(get_declarations_in_outer_scope_including_headers(document));
+
     Vector<StringView> available_names;
     auto add_name = [&available_names](auto& name) {
         if (name.is_null() || name.is_empty())
@@ -151,7 +161,6 @@ Vector<GUI::AutocompleteProvider::Entry> ParserAutoComplete::autocomplete_identi
         }
     }
 
-    auto partial_text = document.parser.text_of_node(node);
     Vector<GUI::AutocompleteProvider::Entry> suggestions;
     for (auto& name : available_names) {
         if (name.starts_with(partial_text)) {

+ 1 - 1
Userland/DevTools/HackStudio/LanguageServers/Cpp/ParserAutoComplete.h

@@ -57,7 +57,7 @@ private:
     };
 
     Vector<GUI::AutocompleteProvider::Entry> autocomplete_property(const DocumentData&, const MemberExpression&, const StringView partial_text) const;
-    Vector<GUI::AutocompleteProvider::Entry> autocomplete_identifier(const DocumentData&, const ASTNode&) const;
+    Vector<GUI::AutocompleteProvider::Entry> autocomplete_name(const DocumentData&, const ASTNode&, const StringView& partial_text) const;
     String type_of(const DocumentData&, const Expression&) const;
     String type_of_property(const DocumentData&, const Identifier&) const;
     String type_of_variable(const Identifier&) const;

+ 1 - 1
Userland/Libraries/LibCpp/Parser.cpp

@@ -664,7 +664,7 @@ bool Parser::done()
     return m_state.token_index == m_tokens.size();
 }
 
-StringView Parser::text_of_token(const Cpp::Token& token)
+StringView Parser::text_of_token(const Cpp::Token& token) const
 {
     ASSERT(token.m_start.line == token.m_end.line);
     ASSERT(token.m_start.column <= token.m_end.column);

+ 1 - 1
Userland/Libraries/LibCpp/Parser.h

@@ -45,6 +45,7 @@ public:
     Optional<Token> token_at(Position) const;
     RefPtr<const TranslationUnit> root_node() const { return m_root_node; }
     StringView text_of_node(const ASTNode&) const;
+    StringView text_of_token(const Cpp::Token& token) const;
     void print_tokens() const;
     Vector<String> errors() const { return m_errors; }
 
@@ -127,7 +128,6 @@ private:
         size_t token_index { 0 };
     };
 
-    StringView text_of_token(const Cpp::Token& token);
     void error(StringView message = {});
 
     size_t node_span_size(const ASTNode& node) const;