hokein added a comment. Thanks, left a few comments on the implementation.
================ Comment at: clang-tools-extra/clangd/Hover.cpp:1091 +// FIXME(bakalova): Remove after merging https://reviews.llvm.org/D143496 +std::vector<include_cleaner::SymbolReference> ---------------- I'm not sure how we can do it. https://reviews.llvm.org/D143496 doesn't expose `collectMacroReferences` function, so we still duplicate this hacky implementations in two places, which is probably fine at the moment. I think this will be fixed when we unify them with clangd's `CollectMainFileMacros`. ================ Comment at: clang-tools-extra/clangd/Hover.cpp:1093 +std::vector<include_cleaner::SymbolReference> +collectMacroReferences(ParsedAST &AST) { + const auto &SM = AST.getSourceManager(); ---------------- On a second thought, I think we might not really need it. We handle the macro vs non-macro cases separately, and we only care about the symbol reference under the cursor. so we can simply the implementation: 1) For macro case, we already have the located macro and Tok in the call site (on line1231), we can just construct a single `include_cleaner::SymbolReference` from them, and pass a single-element `Macros` and empty `ASTRoots` to the `walkUsed` API. 2) For non-macro case, we can just pass an empty macro references to `walkUsed` as we already know the symbol under the hover is not a macro. ================ Comment at: clang-tools-extra/clangd/Hover.cpp:1123 + if (!Ref.RefLocation.isFileID() || + !SM.isWrittenInMainFile(SM.getSpellingLoc(Ref.RefLocation))) + // Ignore locations within macro expansions or not in the main file ---------------- no need to do the isWrittenInMainFile check in the callback, the walkUsed implementation already does it. ================ Comment at: clang-tools-extra/clangd/Hover.cpp:1128 + if (Ref.RT != include_cleaner::RefType::Explicit) + // Ignore non-explicit references (e.g. variable names). + return; ---------------- I don't get it, why variable names are non-explicit references? ================ Comment at: clang-tools-extra/clangd/Hover.cpp:1140 + // Check that the user is hovering over the current symbol reference. + if (CurLoc < Ref.RefLocation || CurLoc > RefEndLocation) { + return; ---------------- We're using the location as a heuristic to join the symbol (Decl) from two difference sources (clangd's hover impl, and include-cleaner lib impl) This heuristics works most of time, but it will fail in the case where the symbol under the hover is a `UsingDecl` ``` // absl_string_view.h namespace absl { using std::string_view; } // main.cpp #includle "absl_string_view.h" absl::str^ing_view abc; // hover on string_view ``` - clangd's hover uses the underlying decl (std::string_view), see the `pickDeclToUse` function for details; - include-cleaner lib reports the using decl (asbl::string_view); As a result, we will show the #include of the using decl for the underlying decl in the hover card. To solve the issue, I think we need to check the equality of Decl from hover and Decl from `SymbolReference` (comparing both `getCanonicalDecl` should be enough). ================ Comment at: clang-tools-extra/clangd/Hover.cpp:1153 + SM.getFileEntryForID(SM.getMainFileID()) == + Provider.physical()) { + // Do not report main file as provider. ---------------- We probably don't need to handle this main-file case specially, in practice, main-file is hardly included in the MainFileIncludes, so the following logic will filter the main-file as well. ================ Comment at: clang-tools-extra/clangd/Hover.cpp:1163 + case include_cleaner::Header::Physical: + if (Provider.physical()->tryGetRealPathName() == Inc.Resolved) + DirectlyIncludedProviders.push_back(WrittenRef.str()); ---------------- checking the spelled string can cause subtle behavior & bugs. A robust way is to use the `include_cleaner::Includes.match API` to determine a header is used or not (this is similar to what you did in https://reviews.llvm.org/D143496, we need to expose the transformation function `convertIncludes`) ================ Comment at: clang-tools-extra/clangd/Hover.cpp:1172 + if (Provider.verbatim() == Inc.Written) + DirectlyIncludedProviders.push_back(WrittenRef.str()); + } ---------------- nit: I'd suggest adding a `break` even though it is the last case. ================ Comment at: clang-tools-extra/clangd/Hover.cpp:1181 + HI.ProviderInfo = std::optional<std::vector<std::string>>{ + std::move(DirectlyIncludedProviders)}; + }); ---------------- I wonder whether we need to deduplicate the `DirectlyIncludedProviders`, reading the code, it might be possible that we add duplicated headers, but in practice, we should only have a single Ref reported, so the deduplication is probably not needed. ================ Comment at: clang-tools-extra/clangd/Hover.cpp:1232 HI = getHoverContents(*M, Tok, AST); + if (HI) + maybeAddSymbolProviders(AST, *HI, *CurLoc); ---------------- nit: no need to check `HI`, it is always non-null as it is set by the above line. ================ Comment at: clang-tools-extra/clangd/Hover.cpp:1268 // Look for a close enclosing expression to show the value of. - if (!HI->Value) + if (HI && !HI->Value) HI->Value = printExprValue(N, AST.getASTContext()); ---------------- any reason add a null check here, the HI should always be non-null becase we have set it on Line1263. ================ Comment at: clang-tools-extra/clangd/Hover.cpp:1335 + if (ProviderInfo) { + Output.addRuler(); ---------------- Is the code position intended? It looks like we're inserting the `Provided by XXX` text in the middle of the function return type and the function parameters, which seems weird to me. I think the function return type and parameters should group together. Depending on the final UI, I think moving it before the `ReturnType` (right after the header) seems better than the current one. ================ Comment at: clang-tools-extra/clangd/Hover.cpp:1340 + P.appendSpace(); + for (unsigned I = 0; I < ProviderInfo->size() - 1; I++) { + P.appendCode((*ProviderInfo)[I]); ---------------- just use `llvm::join(*ProviderInfo, ", ");` ================ Comment at: clang-tools-extra/clangd/Hover.h:71 + /// Headers providing the symbol (directly included in the main file). + std::optional<std::vector<std::string>> ProviderInfo; std::optional<Range> SymRange; ---------------- I think we can get rid of the `std::optional` we can distinguish by checking the `ProviderInfo.empty()`. Since we have 1 header for most cases, let use `llvm::SmallVector`. We can store the `Inclusion*` as the container element, and convert to string during the `present()` call. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D144976/new/ https://reviews.llvm.org/D144976 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits