ckandeler created this revision.
ckandeler added a reviewer: sammccall.
Herald added subscribers: usaxena95, kadircet, arphaman.
ckandeler requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.

It's quite useful to be able to hover over an #include and see the full
path to the header file.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D107137

Files:
  clang-tools-extra/clangd/Hover.cpp
  clang-tools-extra/clangd/Hover.h
  clang-tools-extra/clangd/XRefs.cpp
  clang-tools-extra/clangd/XRefs.h
  clang-tools-extra/clangd/unittests/HoverTests.cpp

Index: clang-tools-extra/clangd/unittests/HoverTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -2750,6 +2750,15 @@
 
 // In test::Bar
 int foo = 3)",
+      },
+      {
+          [](HoverInfo &HI)
+          {
+              HI.TargetFile = Location();
+              HI.TargetFile->uri
+                      = URIForFile::canonicalize("/usr/include/stdio.h", "/");
+          },
+          "/usr/include/stdio.h",
       }};
 
   for (const auto &C : Cases) {
Index: clang-tools-extra/clangd/XRefs.h
===================================================================
--- clang-tools-extra/clangd/XRefs.h
+++ clang-tools-extra/clangd/XRefs.h
@@ -74,6 +74,12 @@
 const syntax::Token *findNearbyIdentifier(const SpelledWord &Word,
                                           const syntax::TokenBuffer &TB);
 
+// Treat #included files as symbols, to enable go-to-definition and hover
+// on them.
+llvm::Optional<LocatedSymbol> locateFileReferent(const Position &Pos,
+                                                 ParsedAST &AST,
+                                                 llvm::StringRef MainFilePath);
+
 /// Get all document links
 std::vector<DocumentLink> getDocumentLinks(ParsedAST &AST);
 
Index: clang-tools-extra/clangd/XRefs.cpp
===================================================================
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -227,24 +227,6 @@
   return L;
 }
 
-// Treat #included files as symbols, to enable go-to-definition on them.
-llvm::Optional<LocatedSymbol> locateFileReferent(const Position &Pos,
-                                                 ParsedAST &AST,
-                                                 llvm::StringRef MainFilePath) {
-  for (auto &Inc : AST.getIncludeStructure().MainFileIncludes) {
-    if (!Inc.Resolved.empty() && Inc.HashLine == Pos.line) {
-      LocatedSymbol File;
-      File.Name = std::string(llvm::sys::path::filename(Inc.Resolved));
-      File.PreferredDeclaration = {
-          URIForFile::canonicalize(Inc.Resolved, MainFilePath), Range{}};
-      File.Definition = File.PreferredDeclaration;
-      // We're not going to find any further symbols on #include lines.
-      return File;
-    }
-  }
-  return llvm::None;
-}
-
 // Macros are simple: there's no declaration/definition distinction.
 // As a consequence, there's no need to look them up in the index either.
 llvm::Optional<LocatedSymbol>
@@ -552,6 +534,23 @@
 
 } // namespace
 
+llvm::Optional<LocatedSymbol> locateFileReferent(const Position &Pos,
+                                                 ParsedAST &AST,
+                                                 llvm::StringRef MainFilePath) {
+  for (auto &Inc : AST.getIncludeStructure().MainFileIncludes) {
+    if (!Inc.Resolved.empty() && Inc.HashLine == Pos.line) {
+      LocatedSymbol File;
+      File.Name = std::string(llvm::sys::path::filename(Inc.Resolved));
+      File.PreferredDeclaration = {
+          URIForFile::canonicalize(Inc.Resolved, MainFilePath), Range{}};
+      File.Definition = File.PreferredDeclaration;
+      // We're not going to find any further symbols on #include lines.
+      return File;
+    }
+  }
+  return llvm::None;
+}
+
 std::vector<LocatedSymbol>
 locateSymbolTextually(const SpelledWord &Word, ParsedAST &AST,
                       const SymbolIndex *Index, const std::string &MainFilePath,
@@ -1987,4 +1986,4 @@
 }
 
 } // namespace clangd
-} // namespace clang
\ No newline at end of file
+} // namespace clang
Index: clang-tools-extra/clangd/Hover.h
===================================================================
--- clang-tools-extra/clangd/Hover.h
+++ clang-tools-extra/clangd/Hover.h
@@ -58,7 +58,8 @@
   std::string Documentation;
   /// Source code containing the definition of the symbol.
   std::string Definition;
-
+  /// For #include directives, the pointed-to file.
+  llvm::Optional<Location> TargetFile;
   /// Access specifier for declarations inside class/struct/unions, empty for
   /// others.
   std::string AccessSpecifier;
Index: clang-tools-extra/clangd/Hover.cpp
===================================================================
--- clang-tools-extra/clangd/Hover.cpp
+++ clang-tools-extra/clangd/Hover.cpp
@@ -14,6 +14,7 @@
 #include "ParsedAST.h"
 #include "Selection.h"
 #include "SourceCode.h"
+#include "XRefs.h"
 #include "index/SymbolCollector.h"
 #include "support/Logger.h"
 #include "support/Markup.h"
@@ -905,6 +906,16 @@
   if (TokensTouchingCursor.empty())
     return llvm::None;
 
+  // Show full header file path if cursor is on include directive.
+  if (const auto MainFilePath
+          = getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM)) {
+      if (const auto File = locateFileReferent(Pos, AST, *MainFilePath)) {
+          HoverInfo HI;
+          HI.TargetFile = File->Definition;
+          return HI;
+      }
+  }
+
   // To be used as a backup for highlighting the selected token, we use back as
   // it aligns better with biases elsewhere (editors tend to send the position
   // for the left of the hovered token).
@@ -981,6 +992,13 @@
 
 markup::Document HoverInfo::present() const {
   markup::Document Output;
+
+  // For expanded header files, we just print the plain path.
+  if (TargetFile) {
+      Output.addParagraph().appendText(TargetFile->uri.file());
+      return Output;
+  }
+
   // Header contains a text of the form:
   // variable `var`
   //
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to