diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp --- a/clang-tools-extra/clangd/CodeComplete.cpp +++ b/clang-tools-extra/clangd/CodeComplete.cpp @@ -318,11 +318,8 @@ // Turn absolute path into a literal string that can be #included. auto Inserted = [&](llvm::StringRef Header) -> llvm::Expected> { - auto DeclaringURI = - URI::parse(C.IndexResult->CanonicalDeclaration.FileURI); - if (!DeclaringURI) - return DeclaringURI.takeError(); - auto ResolvedDeclaring = URI::resolve(*DeclaringURI, FileName); + auto ResolvedDeclaring = + URI::resolve(C.IndexResult->CanonicalDeclaration.FileURI, FileName); if (!ResolvedDeclaring) return ResolvedDeclaring.takeError(); auto ResolvedInserted = toHeaderFile(Header, FileName); diff --git a/clang-tools-extra/clangd/FindSymbols.cpp b/clang-tools-extra/clangd/FindSymbols.cpp --- a/clang-tools-extra/clangd/FindSymbols.cpp +++ b/clang-tools-extra/clangd/FindSymbols.cpp @@ -43,18 +43,11 @@ llvm::StringRef HintPath) { // Prefer the definition over e.g. a function declaration in a header auto &CD = Sym.Definition ? Sym.Definition : Sym.CanonicalDeclaration; - auto Uri = URI::parse(CD.FileURI); - if (!Uri) { - return llvm::make_error( - formatv("Could not parse URI '{0}' for symbol '{1}'.", CD.FileURI, - Sym.Name), - llvm::inconvertibleErrorCode()); - } - auto Path = URI::resolve(*Uri, HintPath); + auto Path = URI::resolve(CD.FileURI, HintPath); if (!Path) { return llvm::make_error( - formatv("Could not resolve path for URI '{0}' for symbol '{1}'.", - Uri->toString(), Sym.Name), + formatv("Could not resolve path for URI '{0}' for symbol '{1}': {2}", + CD.FileURI, Sym.Name, llvm::toString(Path.takeError())), llvm::inconvertibleErrorCode()); } Location L; diff --git a/clang-tools-extra/clangd/HeaderSourceSwitch.h b/clang-tools-extra/clangd/HeaderSourceSwitch.h new file mode 100644 --- /dev/null +++ b/clang-tools-extra/clangd/HeaderSourceSwitch.h @@ -0,0 +1,26 @@ +//===--- HeaderSourceSwitch.h - ----------------------------------*- C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ParsedAST.h" +#include "llvm/ADT/Optional.h" + +namespace clang { +namespace clangd { + +/// Given a header file, returns a best matching source file, and vice visa. +/// The heuristics incorporate with the AST and the index. +llvm::Optional getCorrespondingHeaderOrSource(const Path &OriginalFile, + ParsedAST &AST, + const SymbolIndex *Index); + +/// Returns all indexable decls that are present in the main file of the AST. +/// Exposed only for unittests. +std::vector getIndexableLocalDecls(ParsedAST &AST); + +} // namespace clangd +} // namespace clang diff --git a/clang-tools-extra/clangd/IncludeFixer.cpp b/clang-tools-extra/clangd/IncludeFixer.cpp --- a/clang-tools-extra/clangd/IncludeFixer.cpp +++ b/clang-tools-extra/clangd/IncludeFixer.cpp @@ -144,10 +144,8 @@ std::vector IncludeFixer::fixesForSymbols(const SymbolSlab &Syms) const { auto Inserted = [&](const Symbol &Sym, llvm::StringRef Header) -> llvm::Expected> { - auto DeclaringURI = URI::parse(Sym.CanonicalDeclaration.FileURI); - if (!DeclaringURI) - return DeclaringURI.takeError(); - auto ResolvedDeclaring = URI::resolve(*DeclaringURI, File); + auto ResolvedDeclaring = + URI::resolve(Sym.CanonicalDeclaration.FileURI, File); if (!ResolvedDeclaring) return ResolvedDeclaring.takeError(); auto ResolvedInserted = toHeaderFile(Header, File); diff --git a/clang-tools-extra/clangd/URI.h b/clang-tools-extra/clangd/URI.h --- a/clang-tools-extra/clangd/URI.h +++ b/clang-tools-extra/clangd/URI.h @@ -63,6 +63,10 @@ static llvm::Expected resolve(const URI &U, llvm::StringRef HintPath = ""); + /// Resolves the absolute path of a URI string. + static llvm::Expected resolve(llvm::StringRef FileURI, + llvm::StringRef HintPath = ""); + /// Resolves \p AbsPath into a canonical path of its URI, by converting /// \p AbsPath to URI and resolving the URI to get th canonical path. /// This ensures that paths with the same URI are resolved into consistent diff --git a/clang-tools-extra/clangd/URI.cpp b/clang-tools-extra/clangd/URI.cpp --- a/clang-tools-extra/clangd/URI.cpp +++ b/clang-tools-extra/clangd/URI.cpp @@ -183,6 +183,17 @@ return U; } +llvm::Expected URI::resolve(llvm::StringRef FileURI, + llvm::StringRef HintPath) { + auto Uri = URI::parse(FileURI); + if (!Uri) + return make_string_error(llvm::toString(Uri.takeError())); + auto Path = URI::resolve(*Uri, HintPath); + if (!Path) + return make_string_error(llvm::toString(Path.takeError())); + return *Path; +} + llvm::Expected URI::create(llvm::StringRef AbsolutePath, llvm::StringRef Scheme) { if (!llvm::sys::path::is_absolute(AbsolutePath)) diff --git a/clang-tools-extra/clangd/index/Background.cpp b/clang-tools-extra/clangd/index/Background.cpp --- a/clang-tools-extra/clangd/index/Background.cpp +++ b/clang-tools-extra/clangd/index/Background.cpp @@ -69,13 +69,7 @@ llvm::StringRef resolve(llvm::StringRef FileURI) { auto I = URIToPathCache.try_emplace(FileURI); if (I.second) { - auto U = URI::parse(FileURI); - if (!U) { - elog("Failed to parse URI {0}: {1}", FileURI, U.takeError()); - assert(false && "Failed to parse URI"); - return ""; - } - auto Path = URI::resolve(*U, HintPath); + auto Path = URI::resolve(FileURI, HintPath); if (!Path) { elog("Failed to resolve URI {0}: {1}", FileURI, Path.takeError()); assert(false && "Failed to resolve URI"); diff --git a/clang-tools-extra/clangd/index/BackgroundIndexLoader.cpp b/clang-tools-extra/clangd/index/BackgroundIndexLoader.cpp --- a/clang-tools-extra/clangd/index/BackgroundIndexLoader.cpp +++ b/clang-tools-extra/clangd/index/BackgroundIndexLoader.cpp @@ -25,12 +25,11 @@ namespace { llvm::Optional uriToAbsolutePath(llvm::StringRef URI, PathRef HintPath) { - auto U = URI::parse(URI); - if (!U) - return llvm::None; - auto AbsolutePath = URI::resolve(*U, HintPath); - if (!AbsolutePath) + auto AbsolutePath = URI::resolve(URI, HintPath); + if (!AbsolutePath) { + elog("Failed to resolve URI {0}:", URI, AbsolutePath.takeError()); return llvm::None; + } return *AbsolutePath; }