Index: clangd/ClangdLSPServer.cpp =================================================================== --- clangd/ClangdLSPServer.cpp +++ clangd/ClangdLSPServer.cpp @@ -23,43 +23,6 @@ namespace clangd { namespace { -/// \brief Supports a test URI scheme with relaxed constraints for lit tests. -/// The path in a test URI will be combined with a platform-specific fake -/// directory to form an absolute path. For example, test:///a.cpp is resolved -/// C:\clangd-test\a.cpp on Windows and /clangd-test/a.cpp on Unix. -class TestScheme : public URIScheme { -public: - Expected getAbsolutePath(StringRef /*Authority*/, StringRef Body, - StringRef /*HintPath*/) const override { - using namespace llvm::sys; - // Still require "/" in body to mimic file scheme, as we want lengths of an - // equivalent URI in both schemes to be the same. - if (!Body.startswith("/")) - return make_error( - "Expect URI body to be an absolute path starting with '/': " + Body, - inconvertibleErrorCode()); - Body = Body.ltrim('/'); -#ifdef _WIN32 - constexpr char TestDir[] = "C:\\clangd-test"; -#else - constexpr char TestDir[] = "/clangd-test"; -#endif - SmallVector Path(Body.begin(), Body.end()); - path::native(Path); - auto Err = fs::make_absolute(TestDir, Path); - if (Err) - llvm_unreachable("Failed to make absolute path in test scheme."); - return std::string(Path.begin(), Path.end()); - } - - Expected uriFromAbsolutePath(StringRef AbsolutePath) const override { - llvm_unreachable("Clangd must never create a test URI."); - } -}; - -static URISchemeRegistry::Add - X("test", "Test scheme for clangd lit tests."); - SymbolKindBitset defaultSymbolKinds() { SymbolKindBitset Defaults; for (size_t I = SymbolKindMin; I <= static_cast(SymbolKind::Array); Index: clangd/ClangdServer.h =================================================================== --- clangd/ClangdServer.h +++ clangd/ClangdServer.h @@ -79,10 +79,6 @@ /// FIXME: we should make this true if it isn't too slow to build!. bool HeavyweightDynamicSymbolIndex = false; - /// URI schemes to use when building the dynamic index. - /// If empty, the default schemes in SymbolCollector will be used. - std::vector URISchemes; - /// If set, use this index to augment code completion results. SymbolIndex *StaticIndex = nullptr; Index: clangd/ClangdServer.cpp =================================================================== --- clangd/ClangdServer.cpp +++ clangd/ClangdServer.cpp @@ -106,8 +106,7 @@ ResourceDir(Opts.ResourceDir ? *Opts.ResourceDir : getStandardResourceDir()), DynamicIdx(Opts.BuildDynamicSymbolIndex - ? new FileIndex(Opts.URISchemes, - Opts.HeavyweightDynamicSymbolIndex) + ? new FileIndex(Opts.HeavyweightDynamicSymbolIndex) : nullptr), WorkspaceRoot(Opts.WorkspaceRoot), PCHs(std::make_shared()), Index: clangd/URI.h =================================================================== --- clangd/URI.h +++ clangd/URI.h @@ -45,10 +45,9 @@ static llvm::Expected create(llvm::StringRef AbsolutePath, llvm::StringRef Scheme); - // Similar to above except this uses the first scheme in \p Schemes that - // works. - static llvm::Expected create(llvm::StringRef AbsolutePath, - const std::vector &Schemes); + // Similar to above except this picks a registered scheme that works. If none + // works, this falls back to "file" scheme. + static URI create(llvm::StringRef AbsolutePath); /// This creates a file:// URI for \p AbsolutePath. The path must be absolute. static URI createFile(llvm::StringRef AbsolutePath); Index: clangd/URI.cpp =================================================================== --- clangd/URI.cpp +++ clangd/URI.cpp @@ -195,12 +195,15 @@ return S->get()->uriFromAbsolutePath(AbsolutePath); } -Expected URI::create(StringRef AbsolutePath, - const std::vector &Schemes) { +URI URI::create(StringRef AbsolutePath) { if (!sys::path::is_absolute(AbsolutePath)) - return make_string_error("Not a valid absolute path: " + AbsolutePath); - for (const auto &Scheme : Schemes) { - auto URI = URI::create(AbsolutePath, Scheme); + llvm_unreachable( + ("Not a valid absolute path: " + AbsolutePath).str().c_str()); + for (auto &Entry : URISchemeRegistry::entries()) { + if (Entry.getName() == "file") + continue; + + auto URI = Entry.instantiate()->uriFromAbsolutePath(AbsolutePath); // For some paths, conversion to different URI schemes is impossible. These // should be just skipped. if (!URI) { @@ -208,10 +211,10 @@ consumeError(URI.takeError()); continue; } - return URI; + return std::move(*URI); } - return make_string_error("Couldn't convert " + AbsolutePath + - " to any given scheme: " + join(Schemes, ", ")); + // Fallback to file: scheme which should work for any paths. + return URI::createFile(AbsolutePath); } URI URI::createFile(StringRef AbsolutePath) { Index: clangd/index/Background.h =================================================================== --- clangd/index/Background.h +++ clangd/index/Background.h @@ -63,7 +63,7 @@ public: // FIXME: resource-dir injection should be hoisted somewhere common. BackgroundIndex(Context BackgroundContext, llvm::StringRef ResourceDir, - const FileSystemProvider &, ArrayRef URISchemes, + const FileSystemProvider &, BackgroundIndexStorage::Factory IndexStorageFactory, size_t ThreadPoolSize = llvm::hardware_concurrency()); ~BackgroundIndex(); // Blocks while the current task finishes. @@ -95,7 +95,6 @@ std::string ResourceDir; const FileSystemProvider &FSProvider; Context BackgroundContext; - std::vector URISchemes; // index state llvm::Error index(tooling::CompileCommand, Index: clangd/index/Background.cpp =================================================================== --- clangd/index/Background.cpp +++ clangd/index/Background.cpp @@ -36,11 +36,10 @@ BackgroundIndex::BackgroundIndex( Context BackgroundContext, StringRef ResourceDir, - const FileSystemProvider &FSProvider, ArrayRef URISchemes, + const FileSystemProvider &FSProvider, BackgroundIndexStorage::Factory IndexStorageFactory, size_t ThreadPoolSize) : SwapIndex(make_unique()), ResourceDir(ResourceDir), FSProvider(FSProvider), BackgroundContext(std::move(BackgroundContext)), - URISchemes(URISchemes), IndexStorageFactory(std::move(IndexStorageFactory)) { assert(ThreadPoolSize > 0 && "Thread pool size can't be zero."); assert(this->IndexStorageFactory && "Storage factory can not be null!"); @@ -341,7 +340,6 @@ "Couldn't build compiler instance"); SymbolCollector::Options IndexOpts; - IndexOpts.URISchemes = URISchemes; StringMap FilesToUpdate; IndexOpts.FileFilter = createFileFilter(DigestsSnapshot, FilesToUpdate); SymbolSlab Symbols; @@ -379,8 +377,7 @@ // FIXME: this should rebuild once-in-a-while, not after every file. // At that point we should use Dex, too. vlog("Rebuilding automatic index"); - reset(IndexedSymbols.buildIndex(IndexType::Light, DuplicateHandling::Merge, - URISchemes)); + reset(IndexedSymbols.buildIndex(IndexType::Light, DuplicateHandling::Merge)); return Error::success(); } Index: clangd/index/FileIndex.h =================================================================== --- clangd/index/FileIndex.h +++ clangd/index/FileIndex.h @@ -65,8 +65,7 @@ // The index keeps the symbols alive. std::unique_ptr buildIndex(IndexType, - DuplicateHandling DuplicateHandle = DuplicateHandling::PickOne, - ArrayRef URISchemes = {}); + DuplicateHandling DuplicateHandle = DuplicateHandling::PickOne); private: mutable std::mutex Mutex; @@ -81,9 +80,7 @@ /// FIXME: Expose an interface to remove files that are closed. class FileIndex : public MergedIndex { public: - /// If URISchemes is empty, the default schemes in SymbolCollector will be - /// used. - FileIndex(std::vector URISchemes = {}, bool UseDex = true); + FileIndex(bool UseDex = true); /// Update preamble symbols of file \p Path with all declarations in \p AST /// and macros in \p PP. @@ -96,7 +93,6 @@ private: bool UseDex; // FIXME: this should be always on. - std::vector URISchemes; // Contains information from each file's preamble only. // These are large, but update fairly infrequently (preambles are stable). @@ -125,15 +121,12 @@ /// Retrieves symbols and refs of local top level decls in \p AST (i.e. /// `AST.getLocalTopLevelDecls()`). /// Exposed to assist in unit tests. -/// If URISchemes is empty, the default schemes in SymbolCollector will be used. -std::pair -indexMainDecls(ParsedAST &AST, llvm::ArrayRef URISchemes = {}); +std::pair indexMainDecls(ParsedAST &AST); /// Idex declarations from \p AST and macros from \p PP that are declared in /// included headers. -/// If URISchemes is empty, the default schemes in SymbolCollector will be used. -SymbolSlab indexHeaderSymbols(ASTContext &AST, std::shared_ptr PP, - llvm::ArrayRef URISchemes = {}); +SymbolSlab indexHeaderSymbols(ASTContext &AST, + std::shared_ptr PP); } // namespace clangd } // namespace clang Index: clangd/index/FileIndex.cpp =================================================================== --- clangd/index/FileIndex.cpp +++ clangd/index/FileIndex.cpp @@ -30,8 +30,7 @@ static std::pair indexSymbols(ASTContext &AST, std::shared_ptr PP, - ArrayRef DeclsToIndex, bool IsIndexMainAST, - ArrayRef URISchemes) { + ArrayRef DeclsToIndex, bool IsIndexMainAST) { SymbolCollector::Options CollectorOpts; // FIXME(ioeric): we might also want to collect include headers. We would need // to make sure all includes are canonicalized (with CanonicalIncludes), which @@ -41,8 +40,6 @@ CollectorOpts.CollectIncludePath = false; CollectorOpts.CountReferences = false; CollectorOpts.Origin = SymbolOrigin::Dynamic; - if (!URISchemes.empty()) - CollectorOpts.URISchemes = URISchemes; index::IndexingOptions IndexOpts; // We only need declarations, because we don't count references. @@ -75,20 +72,19 @@ return {std::move(Syms), std::move(Refs)}; } -std::pair -indexMainDecls(ParsedAST &AST, ArrayRef URISchemes) { +std::pair indexMainDecls(ParsedAST &AST) { return indexSymbols(AST.getASTContext(), AST.getPreprocessorPtr(), AST.getLocalTopLevelDecls(), - /*IsIndexMainAST=*/true, URISchemes); + /*IsIndexMainAST=*/true); } -SymbolSlab indexHeaderSymbols(ASTContext &AST, std::shared_ptr PP, - ArrayRef URISchemes) { +SymbolSlab indexHeaderSymbols(ASTContext &AST, + std::shared_ptr PP) { std::vector DeclsToIndex( AST.getTranslationUnitDecl()->decls().begin(), AST.getTranslationUnitDecl()->decls().end()); return indexSymbols(AST, std::move(PP), DeclsToIndex, - /*IsIndexMainAST=*/false, URISchemes) + /*IsIndexMainAST=*/false) .first; } @@ -106,8 +102,7 @@ } std::unique_ptr -FileSymbols::buildIndex(IndexType Type, DuplicateHandling DuplicateHandle, - ArrayRef URISchemes) { +FileSymbols::buildIndex(IndexType Type, DuplicateHandling DuplicateHandle) { std::vector> SymbolSlabs; std::vector> RefSlabs; { @@ -191,35 +186,34 @@ make_pointee_range(AllSymbols), std::move(AllRefs), std::make_tuple(std::move(SymbolSlabs), std::move(RefSlabs), std::move(RefsStorage), std::move(SymsStorage)), - StorageSize, std::move(URISchemes)); + StorageSize); } llvm_unreachable("Unknown clangd::IndexType"); } -FileIndex::FileIndex(std::vector URISchemes, bool UseDex) +FileIndex::FileIndex(bool UseDex) : MergedIndex(&MainFileIndex, &PreambleIndex), UseDex(UseDex), - URISchemes(std::move(URISchemes)), PreambleIndex(llvm::make_unique()), MainFileIndex(llvm::make_unique()) {} void FileIndex::updatePreamble(PathRef Path, ASTContext &AST, std::shared_ptr PP) { - auto Symbols = indexHeaderSymbols(AST, std::move(PP), URISchemes); + auto Symbols = indexHeaderSymbols(AST, std::move(PP)); PreambleSymbols.update(Path, llvm::make_unique(std::move(Symbols)), llvm::make_unique()); PreambleIndex.reset( PreambleSymbols.buildIndex(UseDex ? IndexType::Heavy : IndexType::Light, - DuplicateHandling::PickOne, URISchemes)); + DuplicateHandling::PickOne)); } void FileIndex::updateMain(PathRef Path, ParsedAST &AST) { - auto Contents = indexMainDecls(AST, URISchemes); + auto Contents = indexMainDecls(AST); MainFileSymbols.update( Path, llvm::make_unique(std::move(Contents.first)), llvm::make_unique(std::move(Contents.second))); - MainFileIndex.reset(MainFileSymbols.buildIndex( - IndexType::Light, DuplicateHandling::PickOne, URISchemes)); + MainFileIndex.reset( + MainFileSymbols.buildIndex(IndexType::Light, DuplicateHandling::PickOne)); } } // namespace clangd Index: clangd/index/Serialization.h =================================================================== --- clangd/index/Serialization.h +++ clangd/index/Serialization.h @@ -70,7 +70,6 @@ // Build an in-memory static index from an index file. // The size should be relatively small, so data can be managed in memory. std::unique_ptr loadIndex(llvm::StringRef Filename, - llvm::ArrayRef URISchemes, bool UseDex = true); } // namespace clangd Index: clangd/index/Serialization.cpp =================================================================== --- clangd/index/Serialization.cpp +++ clangd/index/Serialization.cpp @@ -488,9 +488,7 @@ } } -std::unique_ptr loadIndex(StringRef SymbolFilename, - ArrayRef URISchemes, - bool UseDex) { +std::unique_ptr loadIndex(StringRef SymbolFilename, bool UseDex) { trace::Span OverallTracer("LoadIndex"); auto Buffer = MemoryBuffer::getFile(SymbolFilename); if (!Buffer) { @@ -517,9 +515,8 @@ size_t NumRefs = Refs.numRefs(); trace::Span Tracer("BuildIndex"); - auto Index = - UseDex ? dex::Dex::build(std::move(Symbols), std::move(Refs), URISchemes) - : MemIndex::build(std::move(Symbols), std::move(Refs)); + auto Index = UseDex ? dex::Dex::build(std::move(Symbols), std::move(Refs)) + : MemIndex::build(std::move(Symbols), std::move(Refs)); vlog("Loaded {0} from {1} with estimated memory usage {2} bytes\n" " - number of symbols: {3}\n" " - number of refs: {4}\n", Index: clangd/index/SymbolCollector.h =================================================================== --- clangd/index/SymbolCollector.h +++ clangd/index/SymbolCollector.h @@ -48,10 +48,6 @@ /// with symbols' paths to get absolute paths. This must be an absolute /// path. std::string FallbackDir; - /// Specifies URI schemes that can be used to generate URIs for file paths - /// in symbols. The list of schemes will be tried in order until a working - /// scheme is found. If no scheme works, symbol location will be dropped. - std::vector URISchemes = {"file"}; bool CollectIncludePath = false; /// If set, this is used to map symbol #include path to a potentially /// different #include path. Index: clangd/index/SymbolCollector.cpp =================================================================== --- clangd/index/SymbolCollector.cpp +++ clangd/index/SymbolCollector.cpp @@ -83,16 +83,7 @@ } sys::path::remove_dots(AbsolutePath, /*remove_dot_dot=*/true); - - std::string ErrMsg; - for (const auto &Scheme : Opts.URISchemes) { - auto U = URI::create(AbsolutePath, Scheme); - if (U) - return U->toString(); - ErrMsg += toString(U.takeError()) + "\n"; - } - log("Failed to create an URI for file {0}: {1}", AbsolutePath, ErrMsg); - return None; + return URI::create(AbsolutePath).toString(); } // All proto generated headers should start with this line. Index: clangd/index/dex/Dex.h =================================================================== --- clangd/index/dex/Dex.h +++ clangd/index/dex/Dex.h @@ -43,15 +43,7 @@ public: // All data must outlive this index. template - Dex(SymbolRange &&Symbols, RefsRange &&Refs, - llvm::ArrayRef Schemes) - : Corpus(0), URISchemes(Schemes) { - // If Schemes don't contain any items, fall back to SymbolCollector's - // default URI schemes. - if (URISchemes.empty()) { - SymbolCollector::Options Opts; - URISchemes = Opts.URISchemes; - } + Dex(SymbolRange &&Symbols, RefsRange &&Refs) : Corpus(0) { for (auto &&Sym : Symbols) this->Symbols.push_back(&Sym); for (auto &&Ref : Refs) @@ -61,17 +53,15 @@ // Symbols and Refs are owned by BackingData, Index takes ownership. template Dex(SymbolRange &&Symbols, RefsRange &&Refs, Payload &&BackingData, - size_t BackingDataSize, llvm::ArrayRef URISchemes) - : Dex(std::forward(Symbols), std::forward(Refs), - URISchemes) { + size_t BackingDataSize) + : Dex(std::forward(Symbols), std::forward(Refs)) { KeepAlive = std::shared_ptr( std::make_shared(std::move(BackingData)), nullptr); this->BackingDataSize = BackingDataSize; } /// Builds an index from slabs. The index takes ownership of the slab. - static std::unique_ptr - build(SymbolSlab, RefSlab, llvm::ArrayRef URISchemes); + static std::unique_ptr build(SymbolSlab, RefSlab); bool fuzzyFind(const FuzzyFindRequest &Req, @@ -106,8 +96,6 @@ std::shared_ptr KeepAlive; // poor man's move-only std::any // Size of memory retained by KeepAlive. size_t BackingDataSize = 0; - - std::vector URISchemes; }; /// Returns Search Token for a number of parent directories of given Path. Index: clangd/index/dex/Dex.cpp =================================================================== --- clangd/index/dex/Dex.cpp +++ clangd/index/dex/Dex.cpp @@ -25,12 +25,10 @@ namespace clangd { namespace dex { -std::unique_ptr Dex::build(SymbolSlab Symbols, RefSlab Refs, - ArrayRef URISchemes) { +std::unique_ptr Dex::build(SymbolSlab Symbols, RefSlab Refs) { auto Size = Symbols.bytes() + Refs.bytes(); auto Data = std::make_pair(std::move(Symbols), std::move(Refs)); - return llvm::make_unique(Data.first, Data.second, std::move(Data), Size, - std::move(URISchemes)); + return llvm::make_unique(Data.first, Data.second, std::move(Data), Size); } namespace { @@ -62,24 +60,18 @@ } // Constructs BOOST iterators for Path Proximities. -std::unique_ptr createFileProximityIterator( - ArrayRef ProximityPaths, ArrayRef URISchemes, - const DenseMap &InvertedIndex, const Corpus &Corpus) { +std::unique_ptr +createFileProximityIterator(ArrayRef ProximityPaths, + const DenseMap &InvertedIndex, + const Corpus &Corpus) { std::vector> BoostingIterators; // Deduplicate parent URIs extracted from the ProximityPaths. StringSet<> ParentURIs; StringMap Sources; for (const auto &Path : ProximityPaths) { Sources[Path] = SourceParams(); - auto PathURI = URI::create(Path, URISchemes); - if (!PathURI) { - elog("Given ProximityPath {0} is can not be converted to any known URI " - "scheme. fuzzyFind request will ignore it.", - Path); - consumeError(PathURI.takeError()); - continue; - } - const auto PathProximityURIs = generateProximityURIs(PathURI->toString()); + auto PathURI = URI::create(Path); + const auto PathProximityURIs = generateProximityURIs(PathURI.toString()); for (const auto &ProximityURI : PathProximityURIs) ParentURIs.insert(ProximityURI); } @@ -184,8 +176,8 @@ Criteria.push_back(Corpus.unionOf(move(ScopeIterators))); // Add proximity paths boosting (all symbols, some boosted). - Criteria.push_back(createFileProximityIterator(Req.ProximityPaths, URISchemes, - InvertedIndex, Corpus)); + Criteria.push_back( + createFileProximityIterator(Req.ProximityPaths, InvertedIndex, Corpus)); if (Req.RestrictForCodeCompletion) Criteria.push_back(iterator(RestrictedForCodeCompletion)); Index: clangd/index/dex/dexp/Dexp.cpp =================================================================== --- clangd/index/dex/dexp/Dexp.cpp +++ clangd/index/dex/dexp/Dexp.cpp @@ -257,7 +257,7 @@ }; std::unique_ptr openIndex(StringRef Index) { - return loadIndex(Index, /*URISchemes=*/{}, /*UseDex=*/true); + return loadIndex(Index, /*UseDex=*/true); } } // namespace Index: clangd/tool/ClangdMain.cpp =================================================================== --- clangd/tool/ClangdMain.cpp +++ clangd/tool/ClangdMain.cpp @@ -83,11 +83,16 @@ clEnumValN(Logger::Debug, "verbose", "Low level details")), cl::init(Logger::Info)); -static cl::opt Test( - "lit-test", - cl::desc( - "Abbreviation for -input-style=delimited -pretty -run-synchronously. " - "Intended to simplify lit tests."), +static cl::opt + Test("lit-test", + cl::desc("Abbreviation for -input-style=delimited -pretty " + "-run-synchronously -enable-test-scheme. " + "Intended to simplify lit tests."), + cl::init(false), cl::Hidden); + +static cl::opt EnableTestScheme( + "enable-test-uri-scheme", + cl::desc("Enable 'test:' URI scheme. Only use in lit tests."), cl::init(false), cl::Hidden); enum PCHStorageFlag { Disk, Memory }; @@ -177,6 +182,55 @@ "placeholders for method parameters."), cl::init(clangd::CodeCompleteOptions().EnableFunctionArgSnippets)); +namespace { + +/// \brief Supports a test URI scheme with relaxed constraints for lit tests. +/// The path in a test URI will be combined with a platform-specific fake +/// directory to form an absolute path. For example, test:///a.cpp is resolved +/// C:\clangd-test\a.cpp on Windows and /clangd-test/a.cpp on Unix. +class TestScheme : public URIScheme { +public: + Expected getAbsolutePath(StringRef /*Authority*/, StringRef Body, + StringRef /*HintPath*/) const override { + using namespace llvm::sys; + // Still require "/" in body to mimic file scheme, as we want lengths of an + // equivalent URI in both schemes to be the same. + if (!Body.startswith("/")) + return make_error( + "Expect URI body to be an absolute path starting with '/': " + Body, + inconvertibleErrorCode()); + Body = Body.ltrim('/'); + SmallVector Path(Body.begin(), Body.end()); + path::native(Path); + auto Err = fs::make_absolute(TestScheme::TestDir, Path); + if (Err) + llvm_unreachable("Failed to make absolute path in test scheme."); + return std::string(Path.begin(), Path.end()); + } + + Expected uriFromAbsolutePath(StringRef AbsolutePath) const override { + StringRef Body = AbsolutePath; + if (!Body.consume_front(TestScheme::TestDir)) { + return make_error("Path " + AbsolutePath + + " doesn't start with root " + TestDir, + inconvertibleErrorCode()); + } + + return URI("test", /*Authority=*/"", sys::path::convert_to_slash(Body)); + } + +private: + const static char TestDir[]; +}; + +#ifdef _WIN32 +const char TestScheme::TestDir[] = "C:\\clangd-test"; +#else +const char TestScheme::TestDir[] = "/clangd-test"; +#endif + +} + int main(int argc, char *argv[]) { sys::PrintStackTraceOnErrorSignal(argv[0]); cl::SetVersionPrinter([](raw_ostream &OS) { @@ -195,6 +249,10 @@ InputStyle = JSONStreamStyle::Delimited; PrettyPrint = true; } + if (Test || EnableTestScheme) { + static URISchemeRegistry::Add X( + "test", "Test scheme for clangd lit tests."); + } if (!RunSynchronously && WorkerThreadsCount == 0) { errs() << "A number of worker threads cannot be 0. Did you mean to " @@ -292,8 +350,8 @@ // Load the index asynchronously. Meanwhile SwapIndex returns no results. SwapIndex *Placeholder; StaticIdx.reset(Placeholder = new SwapIndex(llvm::make_unique())); - AsyncIndexLoad = runAsync([Placeholder, &Opts] { - if (auto Idx = loadIndex(IndexFile, Opts.URISchemes, /*UseDex=*/true)) + AsyncIndexLoad = runAsync([Placeholder] { + if (auto Idx = loadIndex(IndexFile, /*UseDex=*/true)) Placeholder->reset(std::move(Idx)); }); if (RunSynchronously) Index: test/clangd/protocol.test =================================================================== --- test/clangd/protocol.test +++ test/clangd/protocol.test @@ -1,5 +1,5 @@ -# RUN: not clangd -pretty -run-synchronously < %s | FileCheck -strict-whitespace %s -# RUN: not clangd -pretty -run-synchronously < %s 2>&1 | FileCheck -check-prefix=STDERR %s +# RUN: not clangd -pretty -run-synchronously -enable-test-uri-scheme < %s | FileCheck -strict-whitespace %s +# RUN: not clangd -pretty -run-synchronously -enable-test-uri-scheme < %s 2>&1 | FileCheck -check-prefix=STDERR %s # vim: fileformat=dos # It is absolutely vital that this file has CRLF line endings. # Index: unittests/clangd/BackgroundIndexTests.cpp =================================================================== --- unittests/clangd/BackgroundIndexTests.cpp +++ unittests/clangd/BackgroundIndexTests.cpp @@ -80,7 +80,7 @@ llvm::StringMap Storage; size_t CacheHits = 0; MemoryShardStorage MSS(Storage, CacheHits); - BackgroundIndex Idx(Context::empty(), "", FS, /*URISchemes=*/{"unittest"}, + BackgroundIndex Idx(Context::empty(), "", FS, [&](llvm::StringRef) { return &MSS; }); tooling::CompileCommand Cmd; @@ -136,7 +136,7 @@ Cmd.CommandLine = {"clang++", testPath("root/A.cc")}; // Check nothing is loaded from Storage, but A.cc and A.h has been stored. { - BackgroundIndex Idx(Context::empty(), "", FS, /*URISchemes=*/{"unittest"}, + BackgroundIndex Idx(Context::empty(), "", FS, [&](llvm::StringRef) { return &MSS; }); Idx.enqueue(testPath("root"), Cmd); Idx.blockUntilIdleForTest(); Index: unittests/clangd/CodeCompleteTests.cpp =================================================================== --- unittests/clangd/CodeCompleteTests.cpp +++ unittests/clangd/CodeCompleteTests.cpp @@ -581,7 +581,7 @@ IgnoreDiagnostics DiagConsumer; ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); - auto BarURI = URI::createFile(BarHeader).toString(); + auto BarURI = URI::create(BarHeader).toString(); Symbol Sym = cls("ns::X"); Sym.CanonicalDeclaration.FileURI = BarURI.c_str(); Sym.IncludeHeaders.emplace_back(BarURI, 1); @@ -613,7 +613,7 @@ Symbol SymX = cls("ns::X"); Symbol SymY = cls("ns::Y"); std::string BarHeader = testPath("bar.h"); - auto BarURI = URI::createFile(BarHeader).toString(); + auto BarURI = URI::create(BarHeader).toString(); SymX.CanonicalDeclaration.FileURI = BarURI.c_str(); SymY.CanonicalDeclaration.FileURI = BarURI.c_str(); SymX.IncludeHeaders.emplace_back("", 1); @@ -1251,7 +1251,7 @@ UnorderedElementsAre(Labeled("GFuncC(…)"), Labeled("GFuncD(int)"))); // Differences in header-to-insert suppress bundling. - std::string DeclFile = URI::createFile(testPath("foo")).toString(); + std::string DeclFile = URI::create(testPath("foo")).toString(); NoArgsGFunc.CanonicalDeclaration.FileURI = DeclFile.c_str(); NoArgsGFunc.IncludeHeaders.emplace_back("", 1); EXPECT_THAT( @@ -1957,7 +1957,7 @@ } TEST(CompletionTest, InsertTheMostPopularHeader) { - std::string DeclFile = URI::createFile(testPath("foo")).toString(); + std::string DeclFile = URI::create(testPath("foo")).toString(); Symbol sym = func("Func"); sym.CanonicalDeclaration.FileURI = DeclFile.c_str(); sym.IncludeHeaders.emplace_back("\"foo.h\"", 2); @@ -1979,7 +1979,7 @@ IgnoreDiagnostics DiagConsumer; ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); - std::string DeclFile = URI::createFile(testPath("foo")).toString(); + std::string DeclFile = URI::create(testPath("foo")).toString(); Symbol sym = func("Func"); sym.CanonicalDeclaration.FileURI = DeclFile.c_str(); sym.IncludeHeaders.emplace_back("\"foo.h\"", 2); Index: unittests/clangd/DexTests.cpp =================================================================== --- unittests/clangd/DexTests.cpp +++ unittests/clangd/DexTests.cpp @@ -33,8 +33,6 @@ namespace dex { namespace { -std::vector URISchemes = {"unittest"}; - //===----------------------------------------------------------------------===// // Query iterator tests. //===----------------------------------------------------------------------===// @@ -457,8 +455,7 @@ //===----------------------------------------------------------------------===// TEST(Dex, Lookup) { - auto I = Dex::build(generateSymbols({"ns::abc", "ns::xyz"}), RefSlab(), - URISchemes); + auto I = Dex::build(generateSymbols({"ns::abc", "ns::xyz"}), RefSlab()); EXPECT_THAT(lookup(*I, SymbolID("ns::abc")), UnorderedElementsAre("ns::abc")); EXPECT_THAT(lookup(*I, {SymbolID("ns::abc"), SymbolID("ns::xyz")}), UnorderedElementsAre("ns::abc", "ns::xyz")); @@ -471,7 +468,7 @@ auto Index = Dex::build(generateSymbols({"ns::ABC", "ns::BCD", "::ABC", "ns::nested::ABC", "other::ABC", "other::A"}), - RefSlab(), URISchemes); + RefSlab()); FuzzyFindRequest Req; Req.Query = "ABC"; Req.Scopes = {"ns::"}; @@ -493,7 +490,7 @@ } TEST(DexTest, DexLimitedNumMatches) { - auto I = Dex::build(generateNumSymbols(0, 100), RefSlab(), URISchemes); + auto I = Dex::build(generateNumSymbols(0, 100), RefSlab()); FuzzyFindRequest Req; Req.Query = "5"; Req.AnyScope = true; @@ -508,7 +505,7 @@ TEST(DexTest, FuzzyMatch) { auto I = Dex::build( generateSymbols({"LaughingOutLoud", "LionPopulation", "LittleOldLady"}), - RefSlab(), URISchemes); + RefSlab()); FuzzyFindRequest Req; Req.Query = "lol"; Req.AnyScope = true; @@ -518,8 +515,7 @@ } TEST(DexTest, ShortQuery) { - auto I = - Dex::build(generateSymbols({"OneTwoThreeFour"}), RefSlab(), URISchemes); + auto I = Dex::build(generateSymbols({"OneTwoThreeFour"}), RefSlab()); FuzzyFindRequest Req; Req.AnyScope = true; bool Incomplete; @@ -541,8 +537,7 @@ } TEST(DexTest, MatchQualifiedNamesWithoutSpecificScope) { - auto I = Dex::build(generateSymbols({"a::y1", "b::y2", "y3"}), RefSlab(), - URISchemes); + auto I = Dex::build(generateSymbols({"a::y1", "b::y2", "y3"}), RefSlab()); FuzzyFindRequest Req; Req.AnyScope = true; Req.Query = "y"; @@ -550,8 +545,7 @@ } TEST(DexTest, MatchQualifiedNamesWithGlobalScope) { - auto I = Dex::build(generateSymbols({"a::y1", "b::y2", "y3"}), RefSlab(), - URISchemes); + auto I = Dex::build(generateSymbols({"a::y1", "b::y2", "y3"}), RefSlab()); FuzzyFindRequest Req; Req.Query = "y"; Req.Scopes = {""}; @@ -559,9 +553,8 @@ } TEST(DexTest, MatchQualifiedNamesWithOneScope) { - auto I = - Dex::build(generateSymbols({"a::y1", "a::y2", "a::x", "b::y2", "y3"}), - RefSlab(), URISchemes); + auto I = Dex::build( + generateSymbols({"a::y1", "a::y2", "a::x", "b::y2", "y3"}), RefSlab()); FuzzyFindRequest Req; Req.Query = "y"; Req.Scopes = {"a::"}; @@ -570,7 +563,7 @@ TEST(DexTest, MatchQualifiedNamesWithMultipleScopes) { auto I = Dex::build( - generateSymbols({"a::y1", "a::y2", "a::x", "b::y3", "y3"}), RefSlab(), URISchemes); + generateSymbols({"a::y1", "a::y2", "a::x", "b::y3", "y3"}), RefSlab()); FuzzyFindRequest Req; Req.Query = "y"; Req.Scopes = {"a::", "b::"}; @@ -578,7 +571,7 @@ } TEST(DexTest, NoMatchNestedScopes) { - auto I = Dex::build(generateSymbols({"a::y1", "a::b::y2"}), RefSlab(), URISchemes); + auto I = Dex::build(generateSymbols({"a::y1", "a::b::y2"}), RefSlab()); FuzzyFindRequest Req; Req.Query = "y"; Req.Scopes = {"a::"}; @@ -587,7 +580,7 @@ TEST(DexTest, WildcardScope) { auto I = - Dex::build(generateSymbols({"a::y1", "a::b::y2", "c::y3"}), RefSlab(), URISchemes); + Dex::build(generateSymbols({"a::y1", "a::b::y2", "c::y3"}), RefSlab()); FuzzyFindRequest Req; Req.AnyScope = true; Req.Query = "y"; @@ -597,7 +590,7 @@ } TEST(DexTest, IgnoreCases) { - auto I = Dex::build(generateSymbols({"ns::ABC", "ns::abc"}), RefSlab(), URISchemes); + auto I = Dex::build(generateSymbols({"ns::ABC", "ns::abc"}), RefSlab()); FuzzyFindRequest Req; Req.Query = "AB"; Req.Scopes = {"ns::"}; @@ -606,15 +599,14 @@ TEST(DexTest, UnknownPostingList) { // Regression test: we used to ignore unknown scopes and accept any symbol. - auto I = Dex::build(generateSymbols({"ns::ABC", "ns::abc"}), RefSlab(), - URISchemes); + auto I = Dex::build(generateSymbols({"ns::ABC", "ns::abc"}), RefSlab()); FuzzyFindRequest Req; Req.Scopes = {"ns2::"}; EXPECT_THAT(match(*I, Req), UnorderedElementsAre()); } TEST(DexTest, Lookup) { - auto I = Dex::build(generateSymbols({"ns::abc", "ns::xyz"}), RefSlab(), URISchemes); + auto I = Dex::build(generateSymbols({"ns::abc", "ns::xyz"}), RefSlab()); EXPECT_THAT(lookup(*I, SymbolID("ns::abc")), UnorderedElementsAre("ns::abc")); EXPECT_THAT(lookup(*I, {SymbolID("ns::abc"), SymbolID("ns::xyz")}), UnorderedElementsAre("ns::abc", "ns::xyz")); @@ -629,7 +621,7 @@ CodeCompletionSymbol.Flags = Symbol::SymbolFlag::IndexedForCodeCompletion; NonCodeCompletionSymbol.Flags = Symbol::SymbolFlag::None; std::vector Symbols{CodeCompletionSymbol, NonCodeCompletionSymbol}; - Dex I(Symbols, RefSlab(), URISchemes); + Dex I(Symbols, RefSlab()); FuzzyFindRequest Req; Req.AnyScope = true; Req.RestrictForCodeCompletion = false; @@ -645,7 +637,7 @@ CloseSymbol.CanonicalDeclaration.FileURI = "unittest:///a/b/c/d/e/f/file.h"; std::vector Symbols{CloseSymbol, RootSymbol}; - Dex I(Symbols, RefSlab(), URISchemes); + Dex I(Symbols, RefSlab()); FuzzyFindRequest Req; Req.AnyScope = true; @@ -682,7 +674,7 @@ RefsRequest Req; Req.IDs.insert(Foo.ID); Req.Filter = RefKind::Declaration | RefKind::Definition; - Dex(std::vector{Foo, Bar}, Refs, {}).refs(Req, [&](const Ref &R) { + Dex(std::vector{Foo, Bar}, Refs).refs(Req, [&](const Ref &R) { Files.push_back(R.Location.FileURI); }); Index: unittests/clangd/FileIndexTests.cpp =================================================================== --- unittests/clangd/FileIndexTests.cpp +++ unittests/clangd/FileIndexTests.cpp @@ -152,7 +152,7 @@ } TEST(FileIndexTest, CustomizedURIScheme) { - FileIndex M({"unittest"}); + FileIndex M; update(M, "f", "class string {};"); EXPECT_THAT(runFuzzyFind(M, ""), ElementsAre(DeclURI("unittest:///f.h"))); @@ -302,7 +302,7 @@ RefsRequest Request; Request.IDs = {Foo.ID}; - FileIndex Index(/*URISchemes*/ {"unittest"}); + FileIndex Index; // Add test.cc TestTU Test; Test.HeaderCode = HeaderCode; Index: unittests/clangd/FindSymbolsTests.cpp =================================================================== --- unittests/clangd/FindSymbolsTests.cpp +++ unittests/clangd/FindSymbolsTests.cpp @@ -44,7 +44,6 @@ auto ServerOpts = ClangdServer::optsForTest(); ServerOpts.WorkspaceRoot = testRoot(); ServerOpts.BuildDynamicSymbolIndex = true; - ServerOpts.URISchemes = {"unittest", "file"}; return ServerOpts; } Index: unittests/clangd/IndexTests.cpp =================================================================== --- unittests/clangd/IndexTests.cpp +++ unittests/clangd/IndexTests.cpp @@ -253,8 +253,8 @@ } TEST(MergeIndexTest, Refs) { - FileIndex Dyn({"unittest"}); - FileIndex StaticIndex({"unittest"}); + FileIndex Dyn; + FileIndex StaticIndex; MergedIndex Merge(&Dyn, &StaticIndex); const char *HeaderCode = "class Foo;"; Index: unittests/clangd/SymbolCollectorTests.cpp =================================================================== --- unittests/clangd/SymbolCollectorTests.cpp +++ unittests/clangd/SymbolCollectorTests.cpp @@ -227,8 +227,8 @@ : InMemoryFileSystem(new vfs::InMemoryFileSystem), TestHeaderName(testPath("symbol.h")), TestFileName(testPath("symbol.cc")) { - TestHeaderURI = URI::createFile(TestHeaderName).toString(); - TestFileURI = URI::createFile(TestFileName).toString(); + TestHeaderURI = URI::create(TestHeaderName).toString(); + TestFileURI = URI::create(TestFileName).toString(); } bool runSymbolCollector(StringRef HeaderCode, StringRef MainCode, @@ -391,7 +391,7 @@ - (void)someMethodName3:(void*)name3; @end )"; - TestFileName = "test.m"; + TestFileName = testPath("test.m"); runSymbolCollector(Header, /*Main=*/"", {"-fblocks", "-xobjective-c++"}); EXPECT_THAT(Symbols, UnorderedElementsAre( @@ -534,16 +534,15 @@ TEST_F(SymbolCollectorTest, SymbolRelativeWithFallback) { TestHeaderName = "x.h"; TestFileName = "x.cpp"; - TestHeaderURI = URI::createFile(testPath(TestHeaderName)).toString(); + TestHeaderURI = URI::create(testPath(TestHeaderName)).toString(); CollectorOpts.FallbackDir = testRoot(); runSymbolCollector("class Foo {};", /*Main=*/""); EXPECT_THAT(Symbols, UnorderedElementsAre(AllOf(QName("Foo"), DeclURI(TestHeaderURI)))); } -TEST_F(SymbolCollectorTest, CustomURIScheme) { +TEST_F(SymbolCollectorTest, UnittestURIScheme) { // Use test URI scheme from URITests.cpp - CollectorOpts.URISchemes.insert(CollectorOpts.URISchemes.begin(), "unittest"); TestHeaderName = testPath("x.h"); TestFileName = testPath("x.cpp"); runSymbolCollector("class Foo {};", /*Main=*/""); @@ -551,21 +550,6 @@ AllOf(QName("Foo"), DeclURI("unittest:///x.h")))); } -TEST_F(SymbolCollectorTest, InvalidURIScheme) { - // Use test URI scheme from URITests.cpp - CollectorOpts.URISchemes = {"invalid"}; - runSymbolCollector("class Foo {};", /*Main=*/""); - EXPECT_THAT(Symbols, UnorderedElementsAre(AllOf(QName("Foo"), DeclURI("")))); -} - -TEST_F(SymbolCollectorTest, FallbackToFileURI) { - // Use test URI scheme from URITests.cpp - CollectorOpts.URISchemes = {"invalid", "file"}; - runSymbolCollector("class Foo {};", /*Main=*/""); - EXPECT_THAT(Symbols, UnorderedElementsAre( - AllOf(QName("Foo"), DeclURI(TestHeaderURI)))); -} - TEST_F(SymbolCollectorTest, IncludeEnums) { const std::string Header = R"( enum { @@ -606,7 +590,7 @@ QName("(anonymous struct)::a"))); } -TEST_F(SymbolCollectorTest, SymbolFormedFromMacro) { +TEST_F(SymbolCollectorTest, SymbolFormedFromRegisteredSchemeFromMacro) { Annotations Header(R"( #define FF(name) \ @@ -765,7 +749,7 @@ // bits/basic_string.h$ should be mapped to TestHeaderName = "/nasty/bits/basic_string.h"; TestFileName = "/nasty/bits/basic_string.cpp"; - TestHeaderURI = URI::createFile(TestHeaderName).toString(); + TestHeaderURI = URI::create(TestHeaderName).toString(); runSymbolCollector("class string {};", /*Main=*/""); EXPECT_THAT(Symbols, UnorderedElementsAre(AllOf(QName("string"), DeclURI(TestHeaderURI), @@ -835,7 +819,7 @@ Includes.addMapping(TestHeaderName, ""); CollectorOpts.Includes = &Includes; auto IncFile = testPath("test.inc"); - auto IncURI = URI::createFile(IncFile).toString(); + auto IncURI = URI::create(IncFile).toString(); InMemoryFileSystem->addFile(IncFile, 0, MemoryBuffer::getMemBuffer("class X {};")); runSymbolCollector("#include \"test.inc\"\nclass Y {};", /*Main=*/"", @@ -852,9 +836,9 @@ CanonicalIncludes Includes; CollectorOpts.Includes = &Includes; TestFileName = testPath("main.h"); - TestFileURI = URI::createFile(TestFileName).toString(); + TestFileURI = URI::create(TestFileName).toString(); auto IncFile = testPath("test.inc"); - auto IncURI = URI::createFile(IncFile).toString(); + auto IncURI = URI::create(IncFile).toString(); InMemoryFileSystem->addFile(IncFile, 0, MemoryBuffer::getMemBuffer("class X {};")); runSymbolCollector("", /*Main=*/"#include \"test.inc\"", @@ -868,9 +852,9 @@ CanonicalIncludes Includes; CollectorOpts.Includes = &Includes; TestFileName = testPath("no_ext_main"); - TestFileURI = URI::createFile(TestFileName).toString(); + TestFileURI = URI::create(TestFileName).toString(); auto IncFile = testPath("test.inc"); - auto IncURI = URI::createFile(IncFile).toString(); + auto IncURI = URI::create(IncFile).toString(); InMemoryFileSystem->addFile(IncFile, 0, MemoryBuffer::getMemBuffer("class X {};")); runSymbolCollector("", /*Main=*/"#include \"test.inc\"", @@ -884,7 +868,7 @@ CanonicalIncludes Includes; CollectorOpts.Includes = &Includes; auto IncFile = testPath("test.inc"); - auto IncURI = URI::createFile(IncFile).toString(); + auto IncURI = URI::create(IncFile).toString(); InMemoryFileSystem->addFile(IncFile, 0, MemoryBuffer::getMemBuffer("class X {};")); runSymbolCollector("", /*Main=*/"#include \"test.inc\"", Index: unittests/clangd/TestTU.cpp =================================================================== --- unittests/clangd/TestTU.cpp +++ unittests/clangd/TestTU.cpp @@ -59,8 +59,7 @@ std::unique_ptr TestTU::index() const { auto AST = build(); - auto Idx = llvm::make_unique( - /*URISchemes=*/std::vector{}, /*UseDex=*/true); + auto Idx = llvm::make_unique(/*UseDex=*/true); Idx->updatePreamble(Filename, AST.getASTContext(), AST.getPreprocessorPtr()); Idx->updateMain(Filename, AST); return std::move(Idx);