Index: clang-tools-extra/clangd/benchmarks/IndexBenchmark.cpp =================================================================== --- clang-tools-extra/clangd/benchmarks/IndexBenchmark.cpp +++ clang-tools-extra/clangd/benchmarks/IndexBenchmark.cpp @@ -19,56 +19,50 @@ #include const char *IndexFilename; -const char *LogFilename; +const char *RequestsFilename; namespace clang { namespace clangd { namespace { -std::unique_ptr buildMem() { - return clang::clangd::loadIndex(IndexFilename, {}, false); +std::unique_ptr buildMem() { + return loadIndex(IndexFilename, {}, false); } -std::unique_ptr buildDex() { - return clang::clangd::loadIndex(IndexFilename, {}, true); +std::unique_ptr buildDex() { + return loadIndex(IndexFilename, {}, true); } -// This function processes user-provided Log file with fuzzy find requests in -// the following format: -// -// fuzzyFind("UnqualifiedName", scopes=["clang::", "clang::clangd::"]) -// -// It constructs vector of FuzzyFindRequests which is later used for the -// benchmarks. -std::vector extractQueriesFromLogs() { - llvm::Regex RequestMatcher("fuzzyFind\\(\"([a-zA-Z]*)\", scopes=\\[(.*)\\]"); - llvm::SmallVector Matches; - std::ifstream InputStream(LogFilename); +// Reads JSON array of serialized FuzzyFindRequest's from user-provided file. +std::vector extractQueriesFromLogs() { + std::ifstream InputStream(RequestsFilename); std::string Log((std::istreambuf_iterator(InputStream)), std::istreambuf_iterator()); - llvm::StringRef Temporary(Log); - llvm::SmallVector Strings; - Temporary.split(Strings, '\n'); - clang::clangd::FuzzyFindRequest R; - R.MaxCandidateCount = 100; + std::vector Requests; + auto JSONArray = llvm::json::parse(Log); - llvm::SmallVector CommaSeparatedValues; + // Panic if the provided file couldn't be parsed. + if (!JSONArray) { + llvm::errs() << "Error when parsing JSON requests file: " + << llvm::toString(JSONArray.takeError()); + exit(1); + } + if (!JSONArray->getAsArray()) { + llvm::errs() << "Error when parsing JSON array: " << Log << '\n'; + exit(1); + } - std::vector RealRequests; - for (auto Line : Strings) { - if (RequestMatcher.match(Line, &Matches)) { - R.Query = Matches[1]; - CommaSeparatedValues.clear(); - Line.split(CommaSeparatedValues, ','); - R.Scopes.clear(); - for (auto C : CommaSeparatedValues) { - R.Scopes.push_back(C); - } - RealRequests.push_back(R); + for (const auto &Item : *JSONArray->getAsArray()) { + FuzzyFindRequest Request; + // Panic if the provided file couldn't be parsed. + if (!fromJSON(Item, Request)) { + llvm::errs() << "Error when parsing request: " << Item << '\n'; + exit(1); } + Requests.push_back(Request); } - return RealRequests; + return Requests; } static void MemQueries(benchmark::State &State) { @@ -100,12 +94,12 @@ int main(int argc, char *argv[]) { if (argc < 3) { llvm::errs() << "Usage: " << argv[0] - << " global-symbol-index.yaml fuzzy-find-requests.log " + << " global-symbol-index.yaml requests.json " "BENCHMARK_OPTIONS...\n"; return -1; } IndexFilename = argv[1]; - LogFilename = argv[2]; + RequestsFilename = argv[2]; // Trim first two arguments of the benchmark invocation. argv += 3; argc -= 3; Index: clang-tools-extra/test/clangd/Inputs/requests.json =================================================================== --- /dev/null +++ clang-tools-extra/test/clangd/Inputs/requests.json @@ -0,0 +1,7 @@ +[{"MaxCandidateCount":100,"ProximityPaths":["/usr/home/user/clang-tools-extra/clangd/benchmarks/IndexBenchmark.cpp"],"Query":"OMP","RestrictForCodeCompletion":true,"Scopes":["clang::"]}, +{"MaxCandidateCount":100,"ProximityPaths":[],"Query":"s","RestrictForCodeCompletion":true,"Scopes":["llvm::", ""]}, +{"MaxCandidateCount":100,"ProximityPaths":[],"Query":"sy","RestrictForCodeCompletion":true,"Scopes":["llvm::", ""]}, +{"MaxCandidateCount":100,"ProximityPaths":[],"Query":"sys","RestrictForCodeCompletion":true,"Scopes":["llvm::", ""]}, +{"MaxCandidateCount":100,"ProximityPaths":[],"Query":"sys","RestrictForCodeCompletion":true,"Scopes":["llvm::", ""]}, +{"MaxCandidateCount":100,"ProximityPaths":[],"Query":"Dex","RestrictForCodeCompletion":true,"Scopes":["clang::clangd::", "clang::", "clang::clangd::dex::"]}, +{"MaxCandidateCount":100,"ProximityPaths":[],"Query":"Variable","RestrictForCodeCompletion":true,"Scopes":[""]}] Index: clang-tools-extra/test/clangd/Inputs/requests.log =================================================================== --- clang-tools-extra/test/clangd/Inputs/requests.log +++ /dev/null @@ -1,5 +0,0 @@ -V[09:08:34.301] Code complete: fuzzyFind("s", scopes=[llvm::]) -V[09:08:34.368] Code complete: fuzzyFind("sy", scopes=[llvm::]) -V[09:08:34.442] Code complete: fuzzyFind("sys", scopes=[llvm::]) -V[09:09:12.075] Code complete: fuzzyFind("Dex", scopes=[clang::clangd::, clang::, clang::clangd::dex::]) -V[09:09:12.075] Code complete: fuzzyFind("Variable", scopes=[]) Index: clang-tools-extra/test/clangd/index-tools.test =================================================================== --- clang-tools-extra/test/clangd/index-tools.test +++ clang-tools-extra/test/clangd/index-tools.test @@ -1,3 +1,5 @@ # RUN: clangd-indexer %p/Inputs/BenchmarkSource.cpp -- -I%p/Inputs > %t.index # FIXME: By default, benchmarks are excluded from the list of default targets hence not built. Find a way to depend on benchmarks to run the next command. -# RUN: if [ -f %clangd-benchmark-dir/IndexBenchmark ]; then %clangd-benchmark-dir/IndexBenchmark %t.index %p/Inputs/requests.log --benchmark_min_time=0.01 ; fi +# RUN: if [ -f %clangd-benchmark-dir/IndexBenchmark ]; then %clangd-benchmark-dir/IndexBenchmark %t.index %p/Inputs/requests.json --benchmark_min_time=0.01 ; fi +# Pass invalid JSON file and check that IndexBenchmark fails to parse it. +# RUN: if [ -f %clangd-benchmark-dir/IndexBenchmark ]; then not %clangd-benchmark-dir/IndexBenchmark %t.index %t --benchmark_min_time=0.01 ; fi