diff --git a/clang-tools-extra/clangd/test/CMakeLists.txt b/clang-tools-extra/clangd/test/CMakeLists.txt --- a/clang-tools-extra/clangd/test/CMakeLists.txt +++ b/clang-tools-extra/clangd/test/CMakeLists.txt @@ -11,8 +11,8 @@ set(CLANGD_TEST_DEPS clangd ClangdTests - # No tests for these, but we should still make sure they build. clangd-indexer + # No tests for it, but we should still make sure they build. dexp ) diff --git a/clang-tools-extra/clangd/test/lit.cfg.py b/clang-tools-extra/clangd/test/lit.cfg.py --- a/clang-tools-extra/clangd/test/lit.cfg.py +++ b/clang-tools-extra/clangd/test/lit.cfg.py @@ -23,6 +23,11 @@ # Clangd-specific lit environment. config.substitutions.append(('%clangd-benchmark-dir', config.clangd_binary_dir + "/benchmarks")) +config.substitutions.append(('%python', + config.python_executable)) if config.clangd_build_xpc: config.available_features.add('clangd-xpc-support') + +if config.clangd_enable_remote: + config.available_features.add('clangd-remote-index') diff --git a/clang-tools-extra/clangd/test/lit.site.cfg.py.in b/clang-tools-extra/clangd/test/lit.site.cfg.py.in --- a/clang-tools-extra/clangd/test/lit.site.cfg.py.in +++ b/clang-tools-extra/clangd/test/lit.site.cfg.py.in @@ -8,6 +8,7 @@ config.llvm_libs_dir = "@LLVM_LIBS_DIR@" config.target_triple = "@TARGET_TRIPLE@" config.host_triple = "@LLVM_HOST_TRIPLE@" +config.python_executable = "@Python3_EXECUTABLE@" # Support substitution of the tools and libs dirs with user parameters. This is # used when we can't determine the tool dir at configuration time. @@ -23,6 +24,7 @@ config.clangd_source_dir = "@CMAKE_CURRENT_SOURCE_DIR@/.." config.clangd_binary_dir = "@CMAKE_CURRENT_BINARY_DIR@/.." config.clangd_build_xpc = @CLANGD_BUILD_XPC@ +config.clangd_enable_remote = @CLANGD_ENABLE_REMOTE@ # Delegate logic to lit.cfg.py. lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg.py") diff --git a/clang-tools-extra/clangd/test/remote-index/Inputs/Header.h b/clang-tools-extra/clangd/test/remote-index/Inputs/Header.h new file mode 100644 --- /dev/null +++ b/clang-tools-extra/clangd/test/remote-index/Inputs/Header.h @@ -0,0 +1,10 @@ +namespace clang { +namespace clangd { +namespace remote { +int getFoo(bool Argument); +char Character; +} // namespace remote +} // namespace clangd +} // namespace clang + +namespace llvm {} // namespace llvm diff --git a/clang-tools-extra/clangd/test/remote-index/Inputs/Source.cpp b/clang-tools-extra/clangd/test/remote-index/Inputs/Source.cpp new file mode 100644 --- /dev/null +++ b/clang-tools-extra/clangd/test/remote-index/Inputs/Source.cpp @@ -0,0 +1,3 @@ +#include "Header.h" + +namespace {} // namespace diff --git a/clang-tools-extra/clangd/test/remote-index/pipeline.test b/clang-tools-extra/clangd/test/remote-index/pipeline.test new file mode 100644 --- /dev/null +++ b/clang-tools-extra/clangd/test/remote-index/pipeline.test @@ -0,0 +1,39 @@ +# RUN: rm -rf %t +# RUN: clangd-indexer %S/Inputs/Source.cpp > %t.idx +# RUN: %python %S/pipeline_helper.py --input-file-name=%s --project-root=%/S --index-file=%t.idx | FileCheck %s +# REQUIRES: clangd-remote-index + +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} +# CHECK: "id": 0, +# CHECK-NEXT: "jsonrpc": "2.0", +--- +{"jsonrpc":"2.0","id":1,"method":"workspace/symbol","params":{"query":"Character"}} +# CHECK: "id": 1, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": [ +# CHECK-NEXT: { +# CHECK-NEXT: "containerName": "clang::clangd::remote", +# CHECK-NEXT: "kind": 13, +# CHECK-NEXT: "location": { +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": {{.*}}, +# CHECK-NEXT: "line": {{.*}} +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": {{.*}}, +# CHECK-NEXT: "line": {{.*}} +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "uri": "file://{{.*}}/Header.h" +# CHECK-NEXT: }, +# CHECK-NEXT: "name": "Character", +# CHECK-NEXT: "score": {{.*}} +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT:} +--- +{"jsonrpc":"2.0","id":4,"method":"shutdown"} +--- +{"jsonrpc":"2.0","method":"exit"} +--- diff --git a/clang-tools-extra/clangd/test/remote-index/pipeline_helper.py b/clang-tools-extra/clangd/test/remote-index/pipeline_helper.py new file mode 100644 --- /dev/null +++ b/clang-tools-extra/clangd/test/remote-index/pipeline_helper.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python +# +#===- pipeline_helper.py - Remote Index pipeline Helper *- python -------*--===# +# +# 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 +# +#===------------------------------------------------------------------------===# + +import argparse +import os +import subprocess +from socket import socket +import sys + + +def main(): + server_address = 'localhost:' + # Grab an available port. + with socket() as s: + s.bind(('', 0)) + server_address += str(s.getsockname()[1]) + + parser = argparse.ArgumentParser() + parser.add_argument('--input-file-name', required=True) + parser.add_argument('--project-root', required=True) + parser.add_argument('--index-file', required=True) + + args = parser.parse_args() + + index_server_process = subprocess.Popen([ + 'clangd-index-server', '--server-address=' + server_address, + args.index_file, args.project_root + ], + stderr=subprocess.PIPE) + + # Wait for the server to warm-up. + if not b'Server listening' in index_server_process.stderr.readline(): + sys.exit(1) + + in_file = open(args.input_file_name) + + clangd_process = subprocess.Popen([ + 'clangd', '--remote-index-address=' + server_address, + '--project-root=' + args.project_root, '--lit-test', '--sync' + ], + stdin=in_file) + + clangd_process.wait() + os.kill(index_server_process.pid, 9) + + +if __name__ == '__main__': + main()