Skip to content

feat: Add clangd integration tests and documentation #29

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,39 @@ jobs:

- name: Run TypeScript integration tests
run: go test ./integrationtests/tests/typescript/...

clangd-integration-tests:
name: Clangd Integration Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.24"
check-latest: true
cache: true

- name: Install LLVM, Clang and bear
run: |
sudo apt-get update
sudo apt-get install -y clang-16 llvm-16 clangd-16 bear

- name: Verify Clangd Installation
run: |
sudo ln -s /usr/bin/clangd-16 /usr/bin/clangd
clangd-16 --version
clangd --version

- name: Create compile commands
run: |
cd integrationtests/workspaces/clangd
bear -- make
cd ../../../..

- name: Run Clangd definition tests
run: go test ./integrationtests/tests/clangd/definition...

- name: Run Clangd diagnostics tests
run: go test ./integrationtests/tests/clangd/diagnostics...
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ mcp-language-server
# Test output
test-output/
*.diff
integrationtests/workspaces/clangd/compile_commands.json
integrationtests/workspaces/clangd/src/*.o
integrationtests/workspaces/clangd/clean_program
integrationtests/workspaces/clangd/program
integrationtests/workspaces/clangd/.cache


# Temporary files
*~
Expand Down
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,37 @@ This is an [MCP](https://modelcontextprotocol.io/introduction) server that runs
</pre>
</div>
</details>
<details>
<summary>C/C++ (clangd)</summary>
<div>
<p><strong>Install clangd</strong>: Download prebuilt binaries from the <a href="https://github.com/clangd/clangd/releases">official LLVM releases page</a> or install via your system's package manager (e.g., <code>apt install clangd</code>, <code>brew install clangd</code>).</p>
<p><strong>Configure your MCP client</strong>: This will be different but similar for each client. For Claude Desktop, add the following to <code>~/Library/Application\\ Support/Claude/claude_desktop_config.json</code></p>

<pre>
{
"mcpServers": {
"language-server": {
"command": "mcp-language-server",
"args": [
"--workspace",
"/Users/you/dev/yourproject/",
"--lsp",
"/path/to/your/clangd_binary",
"--",
"--compile-commands-dir=/path/to/yourproject/build_or_compile_commands_dir"
]
}
}
}
</pre>
<p><strong>Note</strong>:</p>
<ul>
<li>Replace <code>/path/to/your/clangd_binary</code> with the actual path to your clangd executable.</li>
<li><code>--compile-commands-dir</code> should point to the directory containing your <code>compile_commands.json</code> file (e.g., <code>./build</code>, <code>./cmake-build-debug</code>).</li>
<li>Ensure <code>compile_commands.json</code> is generated for your project for clangd to work effectively.</li>
</ul>
</div>
</details>
<details>
<summary>Other</summary>
<div>
Expand Down
16 changes: 16 additions & 0 deletions integrationtests/snapshots/clangd/definition/class.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---

Symbol: TestClass
/TEST_OUTPUT/workspace/clangd/src/consumer.cpp
Range: L7:C1 - L15:C2

7|class TestClass {
8| public:
9| /**
10| * @brief A method that takes an integer parameter.
11| *
12| * @param param The integer parameter to be processed.
13| */
14| void method(int param) { helperFunction(); }
15|};

8 changes: 8 additions & 0 deletions integrationtests/snapshots/clangd/definition/constant.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---

Symbol: TEST_CONSTANT
/TEST_OUTPUT/workspace/clangd/src/helper.cpp
Range: L4:C1 - L4:C29

4|const int TEST_CONSTANT = 42;

11 changes: 11 additions & 0 deletions integrationtests/snapshots/clangd/definition/foobar.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---

Symbol: foo_bar
/TEST_OUTPUT/workspace/src/main.cpp
Range: L5:C1 - L8:C2

5|void foo_bar() {
6| std::cout << "Hello, World!" << std::endl;
7| return;
8|}

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---

Symbol: helperFunction
/TEST_OUTPUT/workspace/clangd/src/helper.cpp
Range: L7:C1 - L7:C71

7|void helperFunction() { std::cout << "Helper function" << std::endl; }

16 changes: 16 additions & 0 deletions integrationtests/snapshots/clangd/definition/method.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---

Symbol: method
/TEST_OUTPUT/workspace/clangd/src/consumer.cpp
Range: L7:C1 - L15:C2

7|class TestClass {
8| public:
9| /**
10| * @brief A method that takes an integer parameter.
11| *
12| * @param param The integer parameter to be processed.
13| */
14| void method(int param) { helperFunction(); }
15|};

10 changes: 10 additions & 0 deletions integrationtests/snapshots/clangd/definition/struct.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---

Symbol: TestStruct
/TEST_OUTPUT/workspace/clangd/src/types.cpp
Range: L6:C1 - L8:C2

6|struct TestStruct {
7| int value;
8|};

8 changes: 8 additions & 0 deletions integrationtests/snapshots/clangd/definition/type.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---

Symbol: TestType
/TEST_OUTPUT/workspace/clangd/src/types.cpp
Range: L10:C1 - L10:C21

10|using TestType = int;

8 changes: 8 additions & 0 deletions integrationtests/snapshots/clangd/definition/variable.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---

Symbol: TEST_VARIABLE
/TEST_OUTPUT/workspace/clangd/src/helper.cpp
Range: L5:C1 - L5:C24

5|int TEST_VARIABLE = 100; // A test variable used for integration testing purposes.

1 change: 1 addition & 0 deletions integrationtests/snapshots/clangd/diagnostics/clean.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/TEST_OUTPUT/workspace/src/clean.cpp
11 changes: 11 additions & 0 deletions integrationtests/snapshots/clangd/diagnostics/unreachable.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/TEST_OUTPUT/workspace/src/main.cpp
Diagnostics in File: 1
WARNING at L14:C3: Code will never be executed (Source: clang, Code: -Wunreachable-code)

10|int main() {
...
12| return 0;
13|
14| foo_bar();
15|
16| // Intentional error: unreachable code
10 changes: 10 additions & 0 deletions integrationtests/snapshots/clangd/hover/class-method.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
instance-method method

→ void
Parameters:
- int param
@brief A method that takes an integer parameter.
@param param The integer parameter to be processed.

// In TestClass
public: void method(int param)
5 changes: 5 additions & 0 deletions integrationtests/snapshots/clangd/hover/class-type.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class TestClass

Size: 1 byte

class TestClass {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function helperFunction

→ void

void helperFunction()
6 changes: 6 additions & 0 deletions integrationtests/snapshots/clangd/hover/function-main.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
function foo_bar

→ void
FooBar is a simple function for testing

void foo_bar()
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
No hover information available for this position on the following line:
// FooBar is a simple function for testing
1 change: 1 addition & 0 deletions integrationtests/snapshots/clangd/hover/outside-file.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
No hover information available for this position on the following line:
7 changes: 7 additions & 0 deletions integrationtests/snapshots/clangd/hover/variable.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
variable TEST_VARIABLE

Type: int
Value = 100 (0x64)
A test variable used for integration testing purposes.

int TEST_VARIABLE = 100
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---

/TEST_OUTPUT/workspace/clangd/src/main.cpp
References in File: 1
At: L14:C3

10|int main() {
11| helperFunction();
12| return 0;
13|
14| foo_bar();
15|
16| // Intentional error: unreachable code
17| std::cout << "This is unreachable" << std::endl;
18|}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---

/TEST_OUTPUT/workspace/clangd/src/consumer.cpp
References in File: 1
At: L14:C28

9| /**
10| * @brief A method that takes an integer parameter.
11| *
12| * @param param The integer parameter to be processed.
13| */
14| void method(int param) { helperFunction(); }
15|};

---

/TEST_OUTPUT/workspace/clangd/src/main.cpp
References in File: 1
At: L11:C3

6| std::cout << "Hello, World!" << std::endl;
7| return;
8|}
9|
10|int main() {
11| helperFunction();
12| return 0;
13|
14| foo_bar();
15|
16| // Intentional error: unreachable code
19 changes: 19 additions & 0 deletions integrationtests/tests/clangd/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
\
# Clangd Integration Tests

This directory contains integration tests for `clangd`, the C/C++ language server.

## Prerequisites

Before running these tests, you must generate the `compile_commands.json` file in the `integrationtests/workspaces/clangd` directory. This can typically be done by navigating to that directory and running a tool like `bear` with your build command (e.g., `bear -- make`).

The GitHub Actions workflow for these tests uses the following command from the root of the repository:
```bash
cd integrationtests/workspaces/clangd
bear -- make
cd ../../../..
```

## Clangd Version

These tests are currently run against **clangd version 16**. While they may pass with other versions of clangd, compatibility is not guaranteed.
Loading
Loading