[PATCH] D45426: [clangd] Allow using customized include path in URI.

Haojian Wu via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 9 02:24:05 PDT 2018


hokein created this revision.
hokein added a reviewer: sammccall.
Herald added subscribers: MaskRay, ioeric, jkorous-apple, ilya-biryukov, klimek.

Calculating the include path from absolute file path does not always
work for all build system, e.g. bazel uses symlink as the build working
directory. The absolute file path from editor and clang is diverged from
each other. We need to address it properly in build sysmtem integration.

This patch worksarounds the issue by providing a hook in URI which allows
clients to provide their customized include path.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D45426

Files:
  clangd/ClangdServer.cpp
  clangd/URI.cpp
  clangd/URI.h
  unittests/clangd/ClangdTests.cpp
  unittests/clangd/TestScheme.h
  unittests/clangd/URITests.cpp


Index: unittests/clangd/URITests.cpp
===================================================================
--- unittests/clangd/URITests.cpp
+++ unittests/clangd/URITests.cpp
@@ -47,6 +47,10 @@
     return URI(Scheme, /*Authority=*/"",
                AbsolutePath.substr(Pos + llvm::StringRef(TestRoot).size()));
   }
+
+  llvm::Expected<std::string> getIncludePath(const URI &U) const override {
+    return ("\"" + U.body() + "\"").str();
+  }
 };
 
 const char *TestScheme::Scheme = "unittest";
Index: unittests/clangd/ClangdTests.cpp
===================================================================
--- unittests/clangd/ClangdTests.cpp
+++ unittests/clangd/ClangdTests.cpp
@@ -961,6 +961,10 @@
                        /*Preferred=*/"<Y.h>", "<Y.h>"));
   EXPECT_TRUE(Inserted(OriginalHeader, PreferredHeader, "\"Y.h\""));
   EXPECT_TRUE(Inserted("<y.h>", PreferredHeader, "\"Y.h\""));
+  auto TestURIHeader = URI::create("/abc/test-root/x/y/z.h", "unittest");
+  EXPECT_TRUE(static_cast<bool>(TestURIHeader));
+  EXPECT_TRUE(Inserted(TestURIHeader->toString(), "", "\"x/y/z.h\""));
+
 
   // Check that includes are sorted.
   const auto Expected = R"cpp(
Index: clangd/URI.h
===================================================================
--- clangd/URI.h
+++ clangd/URI.h
@@ -60,6 +60,14 @@
   static llvm::Expected<std::string> resolve(const URI &U,
                                              llvm::StringRef HintPath = "");
 
+  /// Tries to get the include path of the file corresponding to the URI.
+  /// This allows clients to provide their customized include paths.
+  ///
+  /// If the returned string is non-empty, clangd will use it directly when
+  /// doing include insertion; otherwise we will fall back to the clang to
+  /// calculate the include path from the resolved absolute path.
+  static llvm::Expected<std::string> includePath(const URI &U);
+
   friend bool operator==(const URI &LHS, const URI &RHS) {
     return std::tie(LHS.Scheme, LHS.Authority, LHS.Body) ==
            std::tie(RHS.Scheme, RHS.Authority, RHS.Body);
@@ -94,6 +102,13 @@
 
   virtual llvm::Expected<URI>
   uriFromAbsolutePath(llvm::StringRef AbsolutePath) const = 0;
+
+  /// Returns the include path of the file corresponding to the URI, which can
+  /// be #include directly. See URI::resolveIncludePath for details.
+  virtual llvm::Expected<std::string>
+  getIncludePath(const URI& U) const {
+    return "";  // no customized include path for this scheme.
+  }
 };
 
 /// By default, a "file" scheme is supported where URI paths are always absolute
Index: clangd/URI.cpp
===================================================================
--- clangd/URI.cpp
+++ clangd/URI.cpp
@@ -196,5 +196,12 @@
   return S->get()->getAbsolutePath(Uri.Authority, Uri.Body, HintPath);
 }
 
+llvm::Expected<std::string> URI::includePath(const URI &Uri) {
+  auto S = findSchemeByName(Uri.Scheme);
+  if (!S)
+    return S.takeError();
+  return S->get()->getIncludePath(Uri);
+}
+
 } // namespace clangd
 } // namespace clang
Index: clangd/ClangdServer.cpp
===================================================================
--- clangd/ClangdServer.cpp
+++ clangd/ClangdServer.cpp
@@ -286,6 +286,13 @@
   auto U = URI::parse(Header);
   if (!U)
     return U.takeError();
+
+  auto IncludePath = URI::includePath(*U);
+  if (!IncludePath)
+    return IncludePath.takeError();
+  if (!IncludePath->empty())
+    return HeaderFile{std::move(*IncludePath), /*Verbatim=*/true};
+
   auto Resolved = URI::resolve(*U, HintPath);
   if (!Resolved)
     return Resolved.takeError();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D45426.141606.patch
Type: text/x-patch
Size: 3577 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180409/d1051076/attachment-0001.bin>


More information about the cfe-commits mailing list