Skip to content

Conversation

@yashwanthatla
Copy link
Owner

@yashwanthatla yashwanthatla commented Jun 21, 2025

PR Summary

Add C++ Language Support via Clangd Language Server

Overview

This PR extends multilspy to support the C++ programming language by implementing a ClangdLanguageServer class and adding the necessary configurations and tests.

Change Types

Type Description
Feature Add C++ language support using clangd language server
Test Add tests for C/C++ language server functionality

Affected Modules

Module / File Change Description
multilspy/multilspy_config.py Added CPP enum value to the Language enum class
multilspy/language_server.py Extended LanguageServer.create method to handle C++ language
multilspy/language_servers/clangd_language_server/clangd_language_server.py New file implementing ClangdLanguageServer class
multilspy/test_multilspy_clangd.py New test file for C/CPP Language Server capabilities

Notes for Reviewers

  • The implementation adds a new language server for C/C++ using clangd
  • Tests have been added to verify language server capabilities

Comment on lines +54 to +56
assert platform_id.value in [
"linux-x64"
], "Only linux-x64 is supported for in multilspy at the moment"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Correctness Issue

Platform check too restrictive.

The platform check only allows Linux x64, which will cause crashes on other platforms where the code might actually work.

Current Code (Diff):

-        assert platform_id.value in [
-            "linux-x64"
-        ], "Only linux-x64 is supported for in multilspy at the moment"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
assert platform_id.value in [
"linux-x64"
], "Only linux-x64 is supported for in multilspy at the moment"
assert platform_id.value in [
"linux-x64",
"darwin-x64",
"win32-x64"
], "Platform not supported by multilspy at the moment"

logger, dependency["url"], clangd_ls_dir, dependency["archiveType"]
)
assert os.path.exists(clangd_executable_path)
os.chmod(clangd_executable_path, stat.S_IEXEC)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Correctness Issue

Missing read permissions for executable.

The executable is set with execute-only permissions (S_IEXEC), but read permissions are also required to run the file.

Current Code (Diff):

-        os.chmod(clangd_executable_path, stat.S_IEXEC)
+        os.chmod(clangd_executable_path, stat.S_IEXEC | stat.S_IREAD)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
os.chmod(clangd_executable_path, stat.S_IEXEC)
os.chmod(clangd_executable_path, stat.S_IEXEC | stat.S_IREAD)

FileUtils.download_and_extract_archive(
logger, dependency["url"], clangd_ls_dir, dependency["archiveType"]
)
assert os.path.exists(clangd_executable_path)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Correctness Issue

Missing error handling for executable.

The code asserts the executable exists but doesn't handle the case where it doesn't exist after download, causing a crash.

Current Code (Diff):

-        assert os.path.exists(clangd_executable_path)
+        if not os.path.exists(clangd_executable_path):
+            raise FileNotFoundError(f"Failed to find or download clangd executable at {clangd_executable_path}")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
assert os.path.exists(clangd_executable_path)
if not os.path.exists(clangd_executable_path):
raise FileNotFoundError(f"Failed to find or download clangd executable at {clangd_executable_path}")

# generate build
os.system('cmake --build build')
# create sym link to compile commands at the top level
os.system('ln -s build/compile_commands.json .')
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Correctness Issue

Platform Compatibility: Unix-specific command.

The 'ln -s' command is Unix-specific and will cause the test to fail on Windows systems, breaking cross-platform compatibility.

Current Code (Diff):

-     os.system('ln -s build/compile_commands.json .')
+     import platform
+     if platform.system() == 'Windows':
+         import shutil
+         shutil.copy('build/compile_commands.json', '.')
+     else:
+         os.system('ln -s build/compile_commands.json .')
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
os.system('ln -s build/compile_commands.json .')
import platform
if platform.system() == 'Windows':
import shutil
shutil.copy('build/compile_commands.json', '.')
else:
os.system('ln -s build/compile_commands.json .')

# switch to repo directory
os.chdir(source_directory_path)
# set cmake to export compile commands
os.system('cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -S . -B build')
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Correctness Issue

Error Handling: Missing command execution checks.

Using os.system() without checking return codes can lead to silent failures if commands fail, causing test failures without clear error messages.

Current Code (Diff):

-     os.system('cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -S . -B build')
+     import subprocess
+     try:
+         subprocess.run(['cmake', '-DCMAKE_EXPORT_COMPILE_COMMANDS=1', '-S', '.', '-B', 'build'], check=True)
+     except subprocess.CalledProcessError as e:
+         raise RuntimeError(f"Failed to configure CMake: {e}")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
os.system('cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -S . -B build')
import subprocess
try:
subprocess.run(['cmake', '-DCMAKE_EXPORT_COMPILE_COMMANDS=1', '-S', '.', '-B', 'build'], check=True)
except subprocess.CalledProcessError as e:
raise RuntimeError(f"Failed to configure CMake: {e}")

# set cmake to export compile commands
os.system('cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -S . -B build')
# generate build
os.system('cmake --build build')
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Correctness Issue

Error Handling: Missing command execution checks.

Using os.system() without checking return codes can lead to silent failures if commands fail, causing test failures without clear error messages.

Current Code (Diff):

-     os.system('cmake --build build')
+     try:
+         subprocess.run(['cmake', '--build', 'build'], check=True)
+     except subprocess.CalledProcessError as e:
+         raise RuntimeError(f"Failed to build project: {e}")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
os.system('cmake --build build')
try:
subprocess.run(['cmake', '--build', 'build'], check=True)
except subprocess.CalledProcessError as e:
raise RuntimeError(f"Failed to build project: {e}")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants