tom-anders updated this revision to Diff 489284. tom-anders added a comment.
Address review comment: Introduce new AccessibleScopes variable Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D140915/new/ https://reviews.llvm.org/D140915 Files: clang-tools-extra/clangd/CodeComplete.cpp
Index: clang-tools-extra/clangd/CodeComplete.cpp =================================================================== --- clang-tools-extra/clangd/CodeComplete.cpp +++ clang-tools-extra/clangd/CodeComplete.cpp @@ -307,7 +307,7 @@ struct CodeCompletionBuilder { CodeCompletionBuilder(ASTContext *ASTCtx, const CompletionCandidate &C, CodeCompletionString *SemaCCS, - llvm::ArrayRef<std::string> QueryScopes, + llvm::ArrayRef<std::string> AccessibleScopes, const IncludeInserter &Includes, llvm::StringRef FileName, CodeCompletionContext::Kind ContextKind, @@ -361,7 +361,7 @@ // avoids unneeded qualifiers in cases like with `using ns::X`. if (Completion.RequiredQualifier.empty() && !C.SemaResult) { llvm::StringRef ShortestQualifier = C.IndexResult->Scope; - for (llvm::StringRef Scope : QueryScopes) { + for (llvm::StringRef Scope : AccessibleScopes) { llvm::StringRef Qualifier = C.IndexResult->Scope; if (Qualifier.consume_front(Scope) && Qualifier.size() < ShortestQualifier.size()) @@ -643,16 +643,27 @@ // "using namespace std; namespace ns { vec^ }" => {"ns::", "std::", ""} // // "" for global namespace, "ns::" for normal namespace. + std::vector<std::string> QueryScopes; + // Like QueryScopes, but also contains inline namespaces. std::vector<std::string> AccessibleScopes; // The full scope qualifier as typed by the user (without the leading "::"). // Set if the qualifier is not fully resolved by Sema. llvm::Optional<std::string> UnresolvedQualifier; + // Construct scopes to use for code completion. The results are deduplicated. + std::vector<std::string> scopesForCodeCompletion() { + std::set<std::string> Results; + for (llvm::StringRef AS : AccessibleScopes) + Results.insert( + (AS + (UnresolvedQualifier ? *UnresolvedQualifier : "")).str()); + return {Results.begin(), Results.end()}; + } + // Construct scopes being queried in indexes. The results are deduplicated. // This method format the scopes to match the index request representation. std::vector<std::string> scopesForIndexQuery() { std::set<std::string> Results; - for (llvm::StringRef AS : AccessibleScopes) + for (llvm::StringRef AS : QueryScopes) Results.insert( (AS + (UnresolvedQualifier ? *UnresolvedQualifier : "")).str()); return {Results.begin(), Results.end()}; @@ -662,16 +673,19 @@ // Get all scopes that will be queried in indexes and whether symbols from // any scope is allowed. The first scope in the list is the preferred scope // (e.g. enclosing namespace). -std::pair<std::vector<std::string>, bool> +std::tuple<std::vector<std::string>, std::vector<std::string>, bool> getQueryScopes(CodeCompletionContext &CCContext, const Sema &CCSema, const CompletionPrefix &HeuristicPrefix, const CodeCompleteOptions &Opts) { SpecifiedScope Scopes; for (auto *Context : CCContext.getVisitedContexts()) { - if (isa<TranslationUnitDecl>(Context)) - Scopes.AccessibleScopes.push_back(""); // global namespace - else if (isa<NamespaceDecl>(Context)) - Scopes.AccessibleScopes.push_back(printNamespaceScope(*Context)); + if (isa<TranslationUnitDecl>(Context)) { + Scopes.QueryScopes.push_back(""); + Scopes.AccessibleScopes.push_back(""); + } else if (const auto *ND = dyn_cast<NamespaceDecl>(Context)) { + Scopes.QueryScopes.push_back(printNamespaceScope(*Context)); + Scopes.AccessibleScopes.push_back(printQualifiedName(*ND) + "::"); + } } const CXXScopeSpec *SemaSpecifier = @@ -684,39 +698,52 @@ vlog("Sema said no scope specifier, but we saw {0} in the source code", HeuristicPrefix.Qualifier); StringRef SpelledSpecifier = HeuristicPrefix.Qualifier; - if (SpelledSpecifier.consume_front("::")) + if (SpelledSpecifier.consume_front("::")) { Scopes.AccessibleScopes = {""}; + Scopes.QueryScopes = {""}; + } Scopes.UnresolvedQualifier = std::string(SpelledSpecifier); - return {Scopes.scopesForIndexQuery(), false}; + return {Scopes.scopesForIndexQuery(), Scopes.scopesForCodeCompletion(), + false}; } // The enclosing namespace must be first, it gets a quality boost. - std::vector<std::string> EnclosingAtFront; + std::vector<std::string> EnclosingAtFrontForIndex; + std::vector<std::string> EnclosingAtFrontForCompletion; std::string EnclosingScope = printNamespaceScope(*CCSema.CurContext); - EnclosingAtFront.push_back(EnclosingScope); + EnclosingAtFrontForIndex.push_back(EnclosingScope); + EnclosingAtFrontForCompletion.push_back(EnclosingScope); for (auto &S : Scopes.scopesForIndexQuery()) { if (EnclosingScope != S) - EnclosingAtFront.push_back(std::move(S)); + EnclosingAtFrontForIndex.push_back(std::move(S)); + } + for (auto &S : Scopes.scopesForCodeCompletion()) { + if (EnclosingScope != S) + EnclosingAtFrontForCompletion.push_back(std::move(S)); } // Allow AllScopes completion as there is no explicit scope qualifier. - return {EnclosingAtFront, Opts.AllScopes}; + return {EnclosingAtFrontForIndex, EnclosingAtFrontForCompletion, Opts.AllScopes}; } // Case 3: sema saw and resolved a scope qualifier. if (SemaSpecifier && SemaSpecifier->isValid()) - return {Scopes.scopesForIndexQuery(), false}; + return {Scopes.scopesForIndexQuery(), Scopes.scopesForCodeCompletion(), + false}; // Case 4: There was a qualifier, and Sema didn't resolve it. - Scopes.AccessibleScopes.push_back(""); // Make sure global scope is included. + Scopes.QueryScopes.push_back(""); // Make sure global scope is included. llvm::StringRef SpelledSpecifier = Lexer::getSourceText( CharSourceRange::getCharRange(SemaSpecifier->getRange()), CCSema.SourceMgr, clang::LangOptions()); - if (SpelledSpecifier.consume_front("::")) - Scopes.AccessibleScopes = {""}; + if (SpelledSpecifier.consume_front("::")) + Scopes.QueryScopes = {""}; Scopes.UnresolvedQualifier = std::string(SpelledSpecifier); // Sema excludes the trailing "::". if (!Scopes.UnresolvedQualifier->empty()) *Scopes.UnresolvedQualifier += "::"; - return {Scopes.scopesForIndexQuery(), false}; + Scopes.AccessibleScopes = Scopes.QueryScopes; + + return {Scopes.scopesForIndexQuery(), Scopes.scopesForCodeCompletion(), + false}; } // Should we perform index-based completion in a context of the specified kind? @@ -1456,6 +1483,7 @@ llvm::Optional<FuzzyMatcher> Filter; // Initialized once Sema runs. Range ReplacedRange; std::vector<std::string> QueryScopes; // Initialized once Sema runs. + std::vector<std::string> AccessibleScopes; // Initialized once Sema runs. // Initialized once QueryScopes is initialized, if there are scopes. llvm::Optional<ScopeDistance> ScopeProximity; llvm::Optional<OpaqueType> PreferredType; // Initialized once Sema runs. @@ -1615,15 +1643,15 @@ // - accessible scopes are determined heuristically. // - all-scopes query if no qualifier was typed (and it's allowed). SpecifiedScope Scopes; - Scopes.AccessibleScopes = visibleNamespaces( + Scopes.QueryScopes = visibleNamespaces( Content.take_front(Offset), format::getFormattingLangOpts(Style)); - for (std::string &S : Scopes.AccessibleScopes) + for (std::string &S : Scopes.QueryScopes) if (!S.empty()) S.append("::"); // visibleNamespaces doesn't include trailing ::. if (HeuristicPrefix.Qualifier.empty()) AllScopes = Opts.AllScopes; else if (HeuristicPrefix.Qualifier.startswith("::")) { - Scopes.AccessibleScopes = {""}; + Scopes.QueryScopes = {""}; Scopes.UnresolvedQualifier = std::string(HeuristicPrefix.Qualifier.drop_front(2)); } else @@ -1681,7 +1709,7 @@ } Filter = FuzzyMatcher( Recorder->CCSema->getPreprocessor().getCodeCompletionFilter()); - std::tie(QueryScopes, AllScopes) = getQueryScopes( + std::tie(QueryScopes, AccessibleScopes, AllScopes) = getQueryScopes( Recorder->CCContext, *Recorder->CCSema, HeuristicPrefix, Opts); if (!QueryScopes.empty()) ScopeProximity.emplace(QueryScopes); @@ -1955,7 +1983,7 @@ : nullptr; if (!Builder) Builder.emplace(Recorder ? &Recorder->CCSema->getASTContext() : nullptr, - Item, SemaCCS, QueryScopes, *Inserter, FileName, + Item, SemaCCS, AccessibleScopes, *Inserter, FileName, CCContextKind, Opts, IsUsingDeclaration, NextTokenKind); else Builder->add(Item, SemaCCS);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits