CC Vanilla

Tokens: 5,213,813
Prompts:
- I recently added the non-optional parameter solidlsp_settings to the init of SolidLanguageServer, the create method, and the ls_resources_dir method. All language server subclasses now need to be adjusted            │
│   accordingly to use solidlsp_settings. Do that. You can have a look at relevant memories in .serena/memories to understand the repo structure
- don't execute elixir tests, they hang
This commit is contained in:
MischaPanch authored and Michael Panchenko committed 2025-07-25 15:17:03 +02:00
1 parent aeb871c040
commit 65259254fd
21 files changed
+192 -79

No files matched your search

+3
View File
@@ -5,11 +5,13 @@ from pathlib import Path
import pathspec
from serena.config.serena_config import DEFAULT_TOOL_TIMEOUT, ProjectConfig
from serena.constants import SERENA_MANAGED_DIR_IN_HOME
from serena.text_utils import MatchedConsecutiveLines, search_files
from serena.util.file_system import GitignoreParser, match_path
from solidlsp import SolidLanguageServer
from solidlsp.ls_config import Language, LanguageServerConfig
from solidlsp.ls_logger import LanguageServerLogger
from solidlsp.settings import SolidLSPSettings
log = logging.getLogger(__name__)
@@ -271,4 +273,5 @@ class Project:
ls_logger,
self.project_root,
timeout=ls_timeout,
solidlsp_settings=SolidLSPSettings(solidlsp_dir=SERENA_MANAGED_DIR_IN_HOME),
)
@@ -13,6 +13,7 @@ from solidlsp.ls_config import LanguageServerConfig
from solidlsp.ls_logger import LanguageServerLogger
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
from solidlsp.settings import SolidLSPSettings
from .common import RuntimeDependency, RuntimeDependencyCollection
@@ -24,25 +25,30 @@ class ClangdLanguageServer(SolidLanguageServer):
Also make sure compile_commands.json is created at root of the source directory. Check clangd test case for example.
"""
def __init__(self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str):
def __init__(
self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str, solidlsp_settings: SolidLSPSettings
):
"""
Creates a ClangdLanguageServer instance. This class is not meant to be instantiated directly. Use LanguageServer.create() instead.
"""
clangd_executable_path = self._setup_runtime_dependencies(logger, config)
clangd_executable_path = self._setup_runtime_dependencies(logger, config, solidlsp_settings)
super().__init__(
config,
logger,
repository_root_path,
ProcessLaunchInfo(cmd=clangd_executable_path, cwd=repository_root_path),
"cpp",
solidlsp_settings,
)
self.server_ready = threading.Event()
self.service_ready_event = threading.Event()
self.initialize_searcher_command_available = threading.Event()
self.resolve_main_method_available = threading.Event()
@staticmethod
def _setup_runtime_dependencies(logger: LanguageServerLogger, config: LanguageServerConfig) -> str:
@classmethod
def _setup_runtime_dependencies(
cls, logger: LanguageServerLogger, config: LanguageServerConfig, solidlsp_settings: SolidLSPSettings
) -> str:
"""
Setup runtime dependencies for ClangdLanguageServer and return the command to start the server.
"""
@@ -75,7 +81,7 @@ class ClangdLanguageServer(SolidLanguageServer):
]
)
clangd_ls_dir = os.path.join(os.path.dirname(__file__), "static", "clangd")
clangd_ls_dir = os.path.join(cls.ls_resources_dir(solidlsp_settings), "clangd")
dep = deps.single_for_current_platform()
clangd_executable_path = deps.binary_path(clangd_ls_dir)
if not os.path.exists(clangd_executable_path):
+10 -4
View File
@@ -15,6 +15,7 @@ from solidlsp.ls_config import LanguageServerConfig
from solidlsp.ls_logger import LanguageServerLogger
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
from solidlsp.settings import SolidLSPSettings
from .common import RuntimeDependency, RuntimeDependencyCollection
@@ -78,17 +79,20 @@ class ClojureLSP(SolidLanguageServer):
]
)
def __init__(self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str):
def __init__(
self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str, solidlsp_settings: SolidLSPSettings
):
"""
Creates a ClojureLSP instance. This class is not meant to be instantiated directly. Use LanguageServer.create() instead.
"""
clojure_lsp_executable_path = self._setup_runtime_dependencies(logger, config)
clojure_lsp_executable_path = self._setup_runtime_dependencies(logger, config, solidlsp_settings)
super().__init__(
config,
logger,
repository_root_path,
ProcessLaunchInfo(cmd=clojure_lsp_executable_path, cwd=repository_root_path),
"clojure",
solidlsp_settings,
)
self.server_ready = threading.Event()
self.initialize_searcher_command_available = threading.Event()
@@ -96,13 +100,15 @@ class ClojureLSP(SolidLanguageServer):
self.service_ready_event = threading.Event()
@classmethod
def _setup_runtime_dependencies(cls, logger: LanguageServerLogger, config: LanguageServerConfig) -> str:
def _setup_runtime_dependencies(
cls, logger: LanguageServerLogger, config: LanguageServerConfig, solidlsp_settings: SolidLSPSettings
) -> str:
"""Setup runtime dependencies for clojure-lsp and return the command to start the server."""
verify_clojure_cli()
deps = ClojureLSP.runtime_dependencies
dependency = deps.single_for_current_platform()
clojurelsp_ls_dir = cls.ls_resources_dir()
clojurelsp_ls_dir = cls.ls_resources_dir(solidlsp_settings)
clojurelsp_executable_path = deps.binary_path(clojurelsp_ls_dir)
if not os.path.exists(clojurelsp_executable_path):
logger.log(
@@ -25,6 +25,7 @@ from solidlsp.ls_logger import LanguageServerLogger
from solidlsp.ls_utils import PathUtils
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
from solidlsp.settings import SolidLSPSettings
from .common import RuntimeDependency
@@ -175,18 +176,20 @@ class CSharpLanguageServer(SolidLanguageServer):
This is the official Roslyn-based language server from Microsoft.
"""
def __init__(self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str):
def __init__(
self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str, solidlsp_settings: SolidLSPSettings
):
"""
Creates a CSharpLanguageServer instance. This class is not meant to be instantiated directly.
Use LanguageServer.create() instead.
"""
dotnet_path, language_server_path = self._ensure_server_installed(logger, config)
dotnet_path, language_server_path = self._ensure_server_installed(logger, config, solidlsp_settings)
# Find solution or project file
solution_or_project = find_solution_or_project_file(repository_root_path)
# Create log directory
log_dir = Path(self.ls_resources_dir()) / "logs"
log_dir = Path(self.ls_resources_dir(solidlsp_settings)) / "logs"
log_dir.mkdir(parents=True, exist_ok=True)
# Build command using dotnet directly
@@ -206,6 +209,7 @@ class CSharpLanguageServer(SolidLanguageServer):
repository_root_path,
ProcessLaunchInfo(cmd=cmd, cwd=repository_root_path),
"csharp",
solidlsp_settings,
)
self.initialization_complete = threading.Event()
@@ -215,15 +219,17 @@ class CSharpLanguageServer(SolidLanguageServer):
return super().is_ignored_dirname(dirname) or dirname in ["bin", "obj", "packages", ".vs"]
@classmethod
def _ensure_server_installed(cls, logger: LanguageServerLogger, config: LanguageServerConfig) -> tuple[str, str]:
def _ensure_server_installed(
cls, logger: LanguageServerLogger, config: LanguageServerConfig, solidlsp_settings: SolidLSPSettings
) -> tuple[str, str]:
"""
Ensure .NET runtime and Microsoft.CodeAnalysis.LanguageServer are available.
Returns a tuple of (dotnet_path, language_server_dll_path).
"""
runtime_id = CSharpLanguageServer._get_runtime_id()
lang_server_dep, dotnet_runtime_dep = CSharpLanguageServer._get_runtime_dependencies(runtime_id)
dotnet_path = CSharpLanguageServer._ensure_dotnet_runtime(logger, dotnet_runtime_dep)
server_dll_path = CSharpLanguageServer._ensure_language_server(logger, lang_server_dep)
dotnet_path = CSharpLanguageServer._ensure_dotnet_runtime(logger, dotnet_runtime_dep, solidlsp_settings)
server_dll_path = CSharpLanguageServer._ensure_language_server(logger, lang_server_dep, solidlsp_settings)
return dotnet_path, server_dll_path
@@ -261,8 +267,10 @@ class CSharpLanguageServer(SolidLanguageServer):
return lang_server_dep, dotnet_runtime_dep
@staticmethod
def _ensure_dotnet_runtime(logger: LanguageServerLogger, runtime_dep: RuntimeDependency) -> str:
@classmethod
def _ensure_dotnet_runtime(
cls, logger: LanguageServerLogger, runtime_dep: RuntimeDependency, solidlsp_settings: SolidLSPSettings
) -> str:
"""Ensure .NET runtime is available and return the dotnet executable path."""
# Check if dotnet is already available on the system
system_dotnet = shutil.which("dotnet")
@@ -277,15 +285,17 @@ class CSharpLanguageServer(SolidLanguageServer):
pass
# Download .NET 9 runtime using config
return CSharpLanguageServer._ensure_dotnet_runtime_from_config(logger, runtime_dep)
return cls._ensure_dotnet_runtime_from_config(logger, runtime_dep, solidlsp_settings)
@classmethod
def _ensure_language_server(cls, logger: LanguageServerLogger, lang_server_dep: RuntimeDependency) -> str:
def _ensure_language_server(
cls, logger: LanguageServerLogger, lang_server_dep: RuntimeDependency, solidlsp_settings: SolidLSPSettings
) -> str:
"""Ensure language server is available and return the DLL path."""
package_name = lang_server_dep.package_name
package_version = lang_server_dep.package_version
server_dir = Path(cls.ls_resources_dir()) / f"{package_name}.{package_version}"
server_dir = Path(cls.ls_resources_dir(solidlsp_settings)) / f"{package_name}.{package_version}"
server_dll = server_dir / lang_server_dep.binary_name
if server_dll.exists():
@@ -294,10 +304,10 @@ class CSharpLanguageServer(SolidLanguageServer):
# Download and install the language server
logger.log(f"Downloading {package_name} version {package_version}...", logging.INFO)
package_path = CSharpLanguageServer._download_nuget_package_direct(logger, package_name, package_version)
package_path = cls._download_nuget_package_direct(logger, package_name, package_version, solidlsp_settings)
# Extract and install
CSharpLanguageServer._extract_language_server(lang_server_dep, package_path, server_dir)
cls._extract_language_server(lang_server_dep, package_path, server_dir)
if not server_dll.exists():
raise LanguageServerException("Microsoft.CodeAnalysis.LanguageServer.dll not found after extraction")
@@ -333,7 +343,9 @@ class CSharpLanguageServer(SolidLanguageServer):
shutil.copytree(source_dir, server_dir, dirs_exist_ok=True)
@classmethod
def _download_nuget_package_direct(cls, logger: LanguageServerLogger, package_name: str, package_version: str) -> Path:
def _download_nuget_package_direct(
cls, logger: LanguageServerLogger, package_name: str, package_version: str, solidlsp_settings: SolidLSPSettings
) -> Path:
"""
Download a NuGet package directly from the Azure NuGet feed.
Returns the path to the extracted package directory.
@@ -341,7 +353,7 @@ class CSharpLanguageServer(SolidLanguageServer):
azure_feed_url = "https://pkgs.dev.azure.com/azure-public/vside/_packaging/vs-impl/nuget/v3/index.json"
# Create temporary directory for package download
temp_dir = Path(cls.ls_resources_dir()) / "temp_downloads"
temp_dir = Path(cls.ls_resources_dir(solidlsp_settings)) / "temp_downloads"
temp_dir.mkdir(parents=True, exist_ok=True)
try:
@@ -390,7 +402,9 @@ class CSharpLanguageServer(SolidLanguageServer):
) from e
@classmethod
def _ensure_dotnet_runtime_from_config(cls, logger: LanguageServerLogger, runtime_dep: RuntimeDependency) -> str:
def _ensure_dotnet_runtime_from_config(
cls, logger: LanguageServerLogger, runtime_dep: RuntimeDependency, solidlsp_settings: SolidLSPSettings
) -> str:
"""
Ensure .NET 9 runtime is available using runtime dependency configuration.
Returns the path to the dotnet executable.
@@ -408,7 +422,7 @@ class CSharpLanguageServer(SolidLanguageServer):
pass
# Download .NET 9 runtime using config
dotnet_dir = Path(cls.ls_resources_dir()) / "dotnet-runtime-9.0"
dotnet_dir = Path(cls.ls_resources_dir(solidlsp_settings)) / "dotnet-runtime-9.0"
dotnet_exe = dotnet_dir / runtime_dep.binary_name
if dotnet_exe.exists():
@@ -6,6 +6,7 @@ import stat
from solidlsp.ls import SolidLanguageServer
from solidlsp.ls_logger import LanguageServerLogger
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
from solidlsp.settings import SolidLSPSettings
from .common import RuntimeDependency, RuntimeDependencyCollection
@@ -15,21 +16,22 @@ class DartLanguageServer(SolidLanguageServer):
Provides Dart specific instantiation of the LanguageServer class. Contains various configurations and settings specific to Dart.
"""
def __init__(self, config, logger, repository_root_path):
def __init__(self, config, logger, repository_root_path, solidlsp_settings: SolidLSPSettings):
"""
Creates a DartServer instance. This class is not meant to be instantiated directly. Use LanguageServer.create() instead.
"""
executable_path = self._setup_runtime_dependencies(logger)
executable_path = self._setup_runtime_dependencies(logger, solidlsp_settings)
super().__init__(
config,
logger,
repository_root_path,
ProcessLaunchInfo(cmd=executable_path, cwd=repository_root_path),
"dart",
solidlsp_settings,
)
@classmethod
def _setup_runtime_dependencies(cls, logger: "LanguageServerLogger") -> str:
def _setup_runtime_dependencies(cls, logger: "LanguageServerLogger", solidlsp_settings: SolidLSPSettings) -> str:
deps = RuntimeDependencyCollection(
[
RuntimeDependency(
@@ -75,7 +77,7 @@ class DartLanguageServer(SolidLanguageServer):
]
)
dart_ls_dir = cls.ls_resources_dir()
dart_ls_dir = cls.ls_resources_dir(solidlsp_settings)
dart_executable_path = deps.binary_path(dart_ls_dir)
if not os.path.exists(dart_executable_path):
@@ -51,7 +51,7 @@ class EclipseJDTLS(SolidLanguageServer):
Creates a new EclipseJDTLS instance initializing the language server settings appropriately.
This class is not meant to be instantiated directly. Use LanguageServer.create() instead.
"""
runtime_dependency_paths = self._setupRuntimeDependencies(logger, config)
runtime_dependency_paths = self._setupRuntimeDependencies(logger, config, solidlsp_settings)
self.runtime_dependency_paths = runtime_dependency_paths
# ws_dir is the workspace directory for the EclipseJDTLS server
@@ -157,7 +157,9 @@ class EclipseJDTLS(SolidLanguageServer):
]
@classmethod
def _setupRuntimeDependencies(cls, logger: LanguageServerLogger, config: LanguageServerConfig) -> RuntimeDependencyPaths:
def _setupRuntimeDependencies(
cls, logger: LanguageServerLogger, config: LanguageServerConfig, solidlsp_settings: SolidLSPSettings
) -> RuntimeDependencyPaths:
"""
Setup runtime dependencies for EclipseJDTLS and return the paths.
"""
@@ -242,7 +244,7 @@ class EclipseJDTLS(SolidLanguageServer):
gradle_path = str(
PurePath(
cls.ls_resources_dir(),
cls.ls_resources_dir(solidlsp_settings),
"gradle-7.3.3",
)
)
@@ -258,7 +260,7 @@ class EclipseJDTLS(SolidLanguageServer):
assert os.path.exists(gradle_path)
dependency = runtime_dependencies["vscode-java"][platformId.value]
vscode_java_path = str(PurePath(cls.ls_resources_dir(), dependency["relative_extraction_path"]))
vscode_java_path = str(PurePath(cls.ls_resources_dir(solidlsp_settings), dependency["relative_extraction_path"]))
os.makedirs(vscode_java_path, exist_ok=True)
jre_home_path = str(PurePath(vscode_java_path, dependency["jre_home_path"]))
jre_path = str(PurePath(vscode_java_path, dependency["jre_path"]))
@@ -287,7 +289,7 @@ class EclipseJDTLS(SolidLanguageServer):
assert os.path.exists(jdtls_readonly_config_path)
dependency = runtime_dependencies["intellicode"]["platform-agnostic"]
intellicode_directory_path = str(PurePath(cls.ls_resources_dir(), dependency["relative_extraction_path"]))
intellicode_directory_path = str(PurePath(cls.ls_resources_dir(solidlsp_settings), dependency["relative_extraction_path"]))
os.makedirs(intellicode_directory_path, exist_ok=True)
intellicode_jar_path = str(PurePath(intellicode_directory_path, dependency["intellicode_jar_path"]))
intellisense_members_path = str(PurePath(intellicode_directory_path, dependency["intellisense_members_path"]))
@@ -14,6 +14,7 @@ from solidlsp.ls_logger import LanguageServerLogger
from solidlsp.ls_utils import FileUtils, PlatformId, PlatformUtils
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
from solidlsp.settings import SolidLSPSettings
from ..common import RuntimeDependency
@@ -80,7 +81,9 @@ class ElixirTools(SolidLanguageServer):
return None
@classmethod
def _setup_runtime_dependencies(cls, logger: LanguageServerLogger, config: LanguageServerConfig) -> str:
def _setup_runtime_dependencies(
cls, logger: LanguageServerLogger, config: LanguageServerConfig, solidlsp_settings: SolidLSPSettings
) -> str:
"""
Setup runtime dependencies for Next LS.
Downloads the Next LS binary for the current platform and returns the path to the executable.
@@ -110,7 +113,7 @@ class ElixirTools(SolidLanguageServer):
]
assert platform_id in valid_platforms, f"Platform {platform_id} is not supported for Next LS at the moment"
next_ls_dir = os.path.join(cls.ls_resources_dir(), "next-ls")
next_ls_dir = os.path.join(cls.ls_resources_dir(solidlsp_settings), "next-ls")
# Define runtime dependencies inline
runtime_deps = {
@@ -162,8 +165,10 @@ class ElixirTools(SolidLanguageServer):
logger.log(f"Next LS binary ready at: {executable_path}", logging.INFO)
return executable_path
def __init__(self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str):
nextls_executable_path = self._setup_runtime_dependencies(logger, config)
def __init__(
self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str, solidlsp_settings: SolidLSPSettings
):
nextls_executable_path = self._setup_runtime_dependencies(logger, config, solidlsp_settings)
super().__init__(
config,
@@ -171,6 +176,7 @@ class ElixirTools(SolidLanguageServer):
repository_root_path,
ProcessLaunchInfo(cmd=f'"{nextls_executable_path}" --stdio', cwd=repository_root_path),
"elixir",
solidlsp_settings,
)
self.server_ready = threading.Event()
self.request_id = 0
+5 -1
View File
@@ -11,6 +11,7 @@ from solidlsp.ls_config import LanguageServerConfig
from solidlsp.ls_logger import LanguageServerLogger
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
from solidlsp.settings import SolidLSPSettings
class Gopls(SolidLanguageServer):
@@ -70,7 +71,9 @@ class Gopls(SolidLanguageServer):
return True
def __init__(self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str):
def __init__(
self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str, solidlsp_settings: SolidLSPSettings
):
self._setup_runtime_dependency()
super().__init__(
@@ -79,6 +82,7 @@ class Gopls(SolidLanguageServer):
repository_root_path,
ProcessLaunchInfo(cmd="gopls", cwd=repository_root_path),
"go",
solidlsp_settings,
)
self.server_ready = threading.Event()
self.request_id = 0
+17 -5
View File
@@ -16,6 +16,7 @@ from solidlsp.ls_logger import LanguageServerLogger
from solidlsp.ls_utils import PlatformId, PlatformUtils
from solidlsp.lsp_protocol_handler.lsp_types import DefinitionParams, InitializeParams
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
from solidlsp.settings import SolidLSPSettings
from .common import RuntimeDependency, RuntimeDependencyCollection
@@ -34,7 +35,9 @@ class Intelephense(SolidLanguageServer):
return super().is_ignored_dirname(dirname) or dirname in ["node_modules", "vendor", "cache"]
@classmethod
def _setup_runtime_dependencies(cls, logger: LanguageServerLogger, config: LanguageServerConfig) -> str:
def _setup_runtime_dependencies(
cls, logger: LanguageServerLogger, config: LanguageServerConfig, solidlsp_settings: SolidLSPSettings
) -> str:
"""
Setup runtime dependencies for Intelephense and return the command to start the server.
"""
@@ -58,7 +61,7 @@ class Intelephense(SolidLanguageServer):
assert is_npm_installed, "npm is not installed or isn't in PATH. Please install npm and try again."
# Install intelephense if not already installed
intelephense_ls_dir = os.path.join(cls.ls_resources_dir(), "php-lsp")
intelephense_ls_dir = os.path.join(cls.ls_resources_dir(solidlsp_settings), "php-lsp")
os.makedirs(intelephense_ls_dir, exist_ok=True)
intelephense_executable_path = os.path.join(intelephense_ls_dir, "node_modules", ".bin", "intelephense")
if not os.path.exists(intelephense_executable_path):
@@ -79,11 +82,20 @@ class Intelephense(SolidLanguageServer):
return f"{intelephense_executable_path} --stdio"
def __init__(self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str):
def __init__(
self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str, solidlsp_settings: SolidLSPSettings
):
# Setup runtime dependencies before initializing
intelephense_cmd = self._setup_runtime_dependencies(logger, config)
intelephense_cmd = self._setup_runtime_dependencies(logger, config, solidlsp_settings)
super().__init__(config, logger, repository_root_path, ProcessLaunchInfo(cmd=intelephense_cmd, cwd=repository_root_path), "php")
super().__init__(
config,
logger,
repository_root_path,
ProcessLaunchInfo(cmd=intelephense_cmd, cwd=repository_root_path),
"php",
solidlsp_settings,
)
self.request_id = 0
@staticmethod
+5 -1
View File
@@ -13,6 +13,7 @@ from solidlsp.ls_config import LanguageServerConfig
from solidlsp.ls_logger import LanguageServerLogger
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
from solidlsp.settings import SolidLSPSettings
class JediServer(SolidLanguageServer):
@@ -20,7 +21,9 @@ class JediServer(SolidLanguageServer):
Provides Python specific instantiation of the LanguageServer class. Contains various configurations and settings specific to Python.
"""
def __init__(self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str):
def __init__(
self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str, solidlsp_settings: SolidLSPSettings
):
"""
Creates a JediServer instance. This class is not meant to be instantiated directly. Use LanguageServer.create() instead.
"""
@@ -30,6 +33,7 @@ class JediServer(SolidLanguageServer):
repository_root_path,
ProcessLaunchInfo(cmd="jedi-language-server", cwd=repository_root_path),
"python",
solidlsp_settings,
)
@override
@@ -14,6 +14,7 @@ from solidlsp.ls_logger import LanguageServerLogger
from solidlsp.ls_utils import FileUtils, PlatformUtils
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
from solidlsp.settings import SolidLSPSettings
@dataclasses.dataclass
@@ -32,11 +33,13 @@ class KotlinLanguageServer(SolidLanguageServer):
Provides Kotlin specific instantiation of the LanguageServer class. Contains various configurations and settings specific to Kotlin.
"""
def __init__(self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str):
def __init__(
self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str, solidlsp_settings: SolidLSPSettings
):
"""
Creates a Kotlin Language Server instance. This class is not meant to be instantiated directly. Use LanguageServer.create() instead.
"""
runtime_dependency_paths = self._setup_runtime_dependencies(logger, config)
runtime_dependency_paths = self._setup_runtime_dependencies(logger, config, solidlsp_settings)
self.runtime_dependency_paths = runtime_dependency_paths
# Create command to execute the Kotlin Language Server script
@@ -51,10 +54,13 @@ class KotlinLanguageServer(SolidLanguageServer):
repository_root_path,
ProcessLaunchInfo(cmd=cmd, env=proc_env, cwd=repository_root_path),
"kotlin",
solidlsp_settings,
)
@classmethod
def _setup_runtime_dependencies(cls, logger: LanguageServerLogger, config: LanguageServerConfig) -> KotlinRuntimeDependencyPaths:
def _setup_runtime_dependencies(
cls, logger: LanguageServerLogger, config: LanguageServerConfig, solidlsp_settings: SolidLSPSettings
) -> KotlinRuntimeDependencyPaths:
"""
Setup runtime dependencies for Kotlin Language Server and return the paths.
"""
@@ -111,7 +117,7 @@ class KotlinLanguageServer(SolidLanguageServer):
java_dependency = runtime_dependencies["java"][platform_id.value]
# Setup paths for dependencies
static_dir = os.path.join(cls.ls_resources_dir(), "kotlin_language_server")
static_dir = os.path.join(cls.ls_resources_dir(solidlsp_settings), "kotlin_language_server")
os.makedirs(static_dir, exist_ok=True)
# Setup Java paths
+13 -6
View File
@@ -19,6 +19,7 @@ from solidlsp.ls_logger import LanguageServerLogger
from solidlsp.ls_utils import DotnetVersion, FileUtils, PlatformId, PlatformUtils
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
from solidlsp.settings import SolidLSPSettings
def breadth_first_file_scan(root) -> Iterable[str]:
@@ -59,11 +60,13 @@ class OmniSharp(SolidLanguageServer):
Provides C# specific instantiation of the LanguageServer class. Contains various configurations and settings specific to C#.
"""
def __init__(self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str):
def __init__(
self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str, solidlsp_settings: SolidLSPSettings
):
"""
Creates an OmniSharp instance. This class is not meant to be instantiated directly. Use LanguageServer.create() instead.
"""
omnisharp_executable_path, dll_path = self._setup_runtime_dependencies(logger, config)
omnisharp_executable_path, dll_path = self._setup_runtime_dependencies(logger, config, solidlsp_settings)
slnfilename = find_least_depth_sln_file(repository_root_path)
if slnfilename is None:
@@ -102,7 +105,9 @@ class OmniSharp(SolidLanguageServer):
"formattingOptions:indentationSize=4",
]
)
super().__init__(config, logger, repository_root_path, ProcessLaunchInfo(cmd=cmd, cwd=repository_root_path), "csharp")
super().__init__(
config, logger, repository_root_path, ProcessLaunchInfo(cmd=cmd, cwd=repository_root_path), "csharp", solidlsp_settings
)
self.server_ready = threading.Event()
self.definition_available = threading.Event()
@@ -138,7 +143,9 @@ class OmniSharp(SolidLanguageServer):
return d
@classmethod
def _setup_runtime_dependencies(cls, logger: LanguageServerLogger, config: LanguageServerConfig) -> tuple[str, str]:
def _setup_runtime_dependencies(
cls, logger: LanguageServerLogger, config: LanguageServerConfig, solidlsp_settings: SolidLSPSettings
) -> tuple[str, str]:
"""
Setup runtime dependencies for OmniSharp.
"""
@@ -181,7 +188,7 @@ class OmniSharp(SolidLanguageServer):
assert "OmniSharp" in runtime_dependencies
assert "RazorOmnisharp" in runtime_dependencies
omnisharp_ls_dir = os.path.join(cls.ls_resources_dir(), "OmniSharp")
omnisharp_ls_dir = os.path.join(cls.ls_resources_dir(solidlsp_settings), "OmniSharp")
if not os.path.exists(omnisharp_ls_dir):
os.makedirs(omnisharp_ls_dir)
FileUtils.download_and_extract_archive(logger, runtime_dependencies["OmniSharp"]["url"], omnisharp_ls_dir, "zip")
@@ -189,7 +196,7 @@ class OmniSharp(SolidLanguageServer):
assert os.path.exists(omnisharp_executable_path)
os.chmod(omnisharp_executable_path, stat.S_IEXEC)
razor_omnisharp_ls_dir = os.path.join(cls.ls_resources_dir(), "RazorOmnisharp")
razor_omnisharp_ls_dir = os.path.join(cls.ls_resources_dir(solidlsp_settings), "RazorOmnisharp")
if not os.path.exists(razor_omnisharp_ls_dir):
os.makedirs(razor_omnisharp_ls_dir)
FileUtils.download_and_extract_archive(logger, runtime_dependencies["RazorOmnisharp"]["url"], razor_omnisharp_ls_dir, "zip")
@@ -15,6 +15,7 @@ from solidlsp.ls_config import LanguageServerConfig
from solidlsp.ls_logger import LanguageServerLogger
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
from solidlsp.settings import SolidLSPSettings
class PyrightServer(SolidLanguageServer):
@@ -23,7 +24,9 @@ class PyrightServer(SolidLanguageServer):
Contains various configurations and settings specific to Python.
"""
def __init__(self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str):
def __init__(
self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str, solidlsp_settings: SolidLSPSettings
):
"""
Creates a PyrightServer instance. This class is not meant to be instantiated directly.
Use LanguageServer.create() instead.
@@ -36,6 +39,7 @@ class PyrightServer(SolidLanguageServer):
# Note 2: we can also use `bpyright-langserver --stdio` if we ever are unhappy with pyright
ProcessLaunchInfo(cmd="python -m pyright.langserver --stdio", cwd=repository_root_path),
"python",
solidlsp_settings,
)
# Event to signal when initial workspace analysis is complete
+10 -4
View File
@@ -15,6 +15,7 @@ from solidlsp.ls_config import LanguageServerConfig
from solidlsp.ls_logger import LanguageServerLogger
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
from solidlsp.settings import SolidLSPSettings
from .common import RuntimeDependency, RuntimeDependencyCollection
@@ -24,17 +25,20 @@ class RustAnalyzer(SolidLanguageServer):
Provides Rust specific instantiation of the LanguageServer class. Contains various configurations and settings specific to Rust.
"""
def __init__(self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str):
def __init__(
self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str, solidlsp_settings: SolidLSPSettings
):
"""
Creates a RustAnalyzer instance. This class is not meant to be instantiated directly. Use LanguageServer.create() instead.
"""
rustanalyzer_executable_path = self._setup_runtime_dependencies(logger, config)
rustanalyzer_executable_path = self._setup_runtime_dependencies(logger, config, solidlsp_settings)
super().__init__(
config,
logger,
repository_root_path,
ProcessLaunchInfo(cmd=rustanalyzer_executable_path, cwd=repository_root_path),
"rust",
solidlsp_settings,
)
self.server_ready = threading.Event()
self.service_ready_event = threading.Event()
@@ -46,7 +50,9 @@ class RustAnalyzer(SolidLanguageServer):
return super().is_ignored_dirname(dirname) or dirname in ["target"]
@classmethod
def _setup_runtime_dependencies(cls, logger: LanguageServerLogger, config: LanguageServerConfig) -> str:
def _setup_runtime_dependencies(
cls, logger: LanguageServerLogger, config: LanguageServerConfig, solidlsp_settings: SolidLSPSettings
) -> str:
"""
Setup runtime dependencies for rust_analyzer and return the command to start the server.
"""
@@ -92,7 +98,7 @@ class RustAnalyzer(SolidLanguageServer):
# "win-x64",
# ], "Only linux-x64 and win-x64 platform is supported for in multilspy at the moment"
rustanalyzer_ls_dir = os.path.join(cls.ls_resources_dir(), "RustAnalyzer")
rustanalyzer_ls_dir = os.path.join(cls.ls_resources_dir(solidlsp_settings), "RustAnalyzer")
rustanalyzer_executable_path = deps.binary_path(rustanalyzer_ls_dir)
if not os.path.exists(rustanalyzer_ls_dir):
os.makedirs(rustanalyzer_ls_dir)
+5 -1
View File
@@ -18,6 +18,7 @@ from solidlsp.ls_config import LanguageServerConfig
from solidlsp.ls_logger import LanguageServerLogger
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
from solidlsp.settings import SolidLSPSettings
class Solargraph(SolidLanguageServer):
@@ -26,7 +27,9 @@ class Solargraph(SolidLanguageServer):
Contains various configurations and settings specific to Ruby.
"""
def __init__(self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str):
def __init__(
self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str, solidlsp_settings: SolidLSPSettings
):
"""
Creates a Solargraph instance. This class is not meant to be instantiated directly.
Use LanguageServer.create() instead.
@@ -38,6 +41,7 @@ class Solargraph(SolidLanguageServer):
repository_root_path,
ProcessLaunchInfo(cmd=f"{solargraph_executable_path} stdio", cwd=repository_root_path),
"ruby",
solidlsp_settings,
)
self.server_ready = threading.Event()
self.service_ready_event = threading.Event()
@@ -12,6 +12,7 @@ from solidlsp.ls_logger import LanguageServerLogger
from solidlsp.ls_utils import PathUtils, PlatformUtils
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
from solidlsp.settings import SolidLSPSettings
from .common import RuntimeDependency, RuntimeDependencyCollection
@@ -57,7 +58,7 @@ class TerraformLS(SolidLanguageServer):
)
@classmethod
def _setup_runtime_dependencies(cls, logger: LanguageServerLogger) -> str:
def _setup_runtime_dependencies(cls, logger: LanguageServerLogger, solidlsp_settings: SolidLSPSettings) -> str:
"""
Setup runtime dependencies for terraform-ls.
Downloads and installs terraform-ls if not already present.
@@ -102,10 +103,10 @@ class TerraformLS(SolidLanguageServer):
)
dependency = deps.single_for_current_platform()
terraform_ls_executable_path = deps.binary_path(cls.ls_resources_dir())
terraform_ls_executable_path = deps.binary_path(cls.ls_resources_dir(solidlsp_settings))
if not os.path.exists(terraform_ls_executable_path):
logger.log(f"Downloading terraform-ls from {dependency.url}", logging.INFO)
deps.install(logger, cls.ls_resources_dir())
deps.install(logger, cls.ls_resources_dir(solidlsp_settings))
assert os.path.exists(terraform_ls_executable_path), f"terraform-ls executable not found at {terraform_ls_executable_path}"
@@ -115,11 +116,13 @@ class TerraformLS(SolidLanguageServer):
return terraform_ls_executable_path
def __init__(self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str):
def __init__(
self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str, solidlsp_settings: SolidLSPSettings
):
"""
Creates a TerraformLS instance. This class is not meant to be instantiated directly. Use LanguageServer.create() instead.
"""
terraform_ls_executable_path = self._setup_runtime_dependencies(logger)
terraform_ls_executable_path = self._setup_runtime_dependencies(logger, solidlsp_settings)
super().__init__(
config,
@@ -127,6 +130,7 @@ class TerraformLS(SolidLanguageServer):
repository_root_path,
ProcessLaunchInfo(cmd=f"{terraform_ls_executable_path} serve", cwd=repository_root_path),
"terraform",
solidlsp_settings,
)
self.server_ready = threading.Event()
self.request_id = 0
@@ -17,6 +17,7 @@ from solidlsp.ls_logger import LanguageServerLogger
from solidlsp.ls_utils import PlatformId, PlatformUtils
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
from solidlsp.settings import SolidLSPSettings
from .common import RuntimeDependency, RuntimeDependencyCollection
@@ -41,17 +42,20 @@ class TypeScriptLanguageServer(SolidLanguageServer):
Provides TypeScript specific instantiation of the LanguageServer class. Contains various configurations and settings specific to TypeScript.
"""
def __init__(self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str):
def __init__(
self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str, solidlsp_settings: SolidLSPSettings
):
"""
Creates a TypeScriptLanguageServer instance. This class is not meant to be instantiated directly. Use LanguageServer.create() instead.
"""
ts_lsp_executable_path = self._setup_runtime_dependencies(logger, config)
ts_lsp_executable_path = self._setup_runtime_dependencies(logger, config, solidlsp_settings)
super().__init__(
config,
logger,
repository_root_path,
ProcessLaunchInfo(cmd=ts_lsp_executable_path, cwd=repository_root_path),
"typescript",
solidlsp_settings,
)
self.server_ready = threading.Event()
self.initialize_searcher_command_available = threading.Event()
@@ -66,7 +70,9 @@ class TypeScriptLanguageServer(SolidLanguageServer):
]
@classmethod
def _setup_runtime_dependencies(cls, logger: LanguageServerLogger, config: LanguageServerConfig) -> str:
def _setup_runtime_dependencies(
cls, logger: LanguageServerLogger, config: LanguageServerConfig, solidlsp_settings: SolidLSPSettings
) -> str:
"""
Setup runtime dependencies for TypeScript Language Server and return the command to start the server.
"""
@@ -113,7 +119,7 @@ class TypeScriptLanguageServer(SolidLanguageServer):
assert is_npm_installed, "npm is not installed or isn't in PATH. Please install npm and try again."
# Install typescript and typescript-language-server if not already installed
tsserver_ls_dir = os.path.join(cls.ls_resources_dir(), "ts-lsp")
tsserver_ls_dir = os.path.join(cls.ls_resources_dir(solidlsp_settings), "ts-lsp")
tsserver_executable_path = os.path.join(tsserver_ls_dir, "node_modules", ".bin", "typescript-language-server")
if not os.path.exists(tsserver_executable_path):
logger.log(f"Typescript Language Server executable not found at {tsserver_executable_path}. Installing...", logging.INFO)
@@ -19,6 +19,7 @@ from solidlsp.ls_logger import LanguageServerLogger
from solidlsp.ls_utils import PlatformId, PlatformUtils
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
from solidlsp.settings import SolidLSPSettings
from .common import RuntimeDependency, RuntimeDependencyCollection
@@ -29,17 +30,20 @@ class VtsLanguageServer(SolidLanguageServer):
Contains various configurations and settings specific to TypeScript via vtsls wrapper.
"""
def __init__(self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str):
def __init__(
self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str, solidlsp_settings: SolidLSPSettings
):
"""
Creates a VtsLanguageServer instance. This class is not meant to be instantiated directly. Use LanguageServer.create() instead.
"""
vts_lsp_executable_path = self._setup_runtime_dependencies(logger, config)
vts_lsp_executable_path = self._setup_runtime_dependencies(logger, config, solidlsp_settings)
super().__init__(
config,
logger,
repository_root_path,
ProcessLaunchInfo(cmd=vts_lsp_executable_path, cwd=repository_root_path),
"typescript",
solidlsp_settings,
)
self.server_ready = threading.Event()
self.initialize_searcher_command_available = threading.Event()
@@ -54,7 +58,9 @@ class VtsLanguageServer(SolidLanguageServer):
]
@classmethod
def _setup_runtime_dependencies(cls, logger: LanguageServerLogger, config: LanguageServerConfig) -> str:
def _setup_runtime_dependencies(
cls, logger: LanguageServerLogger, config: LanguageServerConfig, solidlsp_settings: SolidLSPSettings
) -> str:
"""
Setup runtime dependencies for VTS Language Server and return the command to start the server.
"""
@@ -81,7 +87,7 @@ class VtsLanguageServer(SolidLanguageServer):
),
]
)
vts_ls_dir = os.path.join(cls.ls_resources_dir(), "vts-lsp")
vts_ls_dir = os.path.join(cls.ls_resources_dir(solidlsp_settings), "vts-lsp")
vts_executable_path = os.path.join(vts_ls_dir, "vtsls")
# Verify both node and npm are installed
+3 -1
View File
@@ -119,8 +119,8 @@ class SolidLanguageServer(ABC):
config: LanguageServerConfig,
logger: LanguageServerLogger,
repository_root_path: str,
solidlsp_settings: SolidLSPSettings,
timeout: float | None = None,
solidlsp_settings: SolidLSPSettings | None = None,
) -> "SolidLanguageServer":
"""
Creates a language specific LanguageServer instance based on the given configuration, and appropriate settings for the programming language.
@@ -135,6 +135,8 @@ class SolidLanguageServer(ABC):
:return LanguageServer: A language specific LanguageServer instance.
"""
ls: SolidLanguageServer
if solidlsp_settings is None:
solidlsp_settings = SolidLSPSettings()
if config.code_language == Language.PYTHON:
from solidlsp.language_servers.pyright_server import (
+5 -1
View File
@@ -4,11 +4,13 @@ from pathlib import Path
import pytest
from sensai.util.logging import configure
from serena.constants import SERENA_MANAGED_DIR_IN_HOME
from serena.project import Project
from serena.util.file_system import GitignoreParser
from solidlsp.ls import SolidLanguageServer
from solidlsp.ls_config import Language, LanguageServerConfig
from solidlsp.ls_logger import LanguageServerLogger
from solidlsp.settings import SolidLSPSettings
configure(level=logging.ERROR)
@@ -43,7 +45,9 @@ def create_ls(
ignored_paths.extend(spec.patterns)
config = LanguageServerConfig(code_language=language, ignored_paths=ignored_paths, trace_lsp_communication=trace_lsp_communication)
logger = LanguageServerLogger(log_level=log_level)
return SolidLanguageServer.create(config, logger, repo_path)
return SolidLanguageServer.create(
config, logger, repo_path, solidlsp_settings=SolidLSPSettings(solidlsp_dir=SERENA_MANAGED_DIR_IN_HOME)
)
def create_default_ls(language: Language) -> SolidLanguageServer:
+7 -2
View File
@@ -13,6 +13,7 @@ from solidlsp.language_servers.csharp_language_server import (
)
from solidlsp.ls_config import Language, LanguageServerConfig
from solidlsp.ls_utils import SymbolUtils
from solidlsp.settings import SolidLSPSettings
@pytest.mark.csharp
@@ -214,7 +215,9 @@ class TestCSharpSolutionProjectOpening:
mock_config.ignored_paths = []
# Create CSharpLanguageServer instance
CSharpLanguageServer(mock_config, mock_logger, str(temp_path))
mock_settings = Mock(spec=SolidLSPSettings)
mock_settings.ls_resources_dir = "/tmp/test_ls_resources"
CSharpLanguageServer(mock_config, mock_logger, str(temp_path), mock_settings)
# Verify that logger was called with solution file discovery
mock_logger.log.assert_any_call(f"Found solution/project file: {solution_file}", 20) # logging.INFO
@@ -236,7 +239,9 @@ class TestCSharpSolutionProjectOpening:
mock_config.ignored_paths = []
# Create CSharpLanguageServer instance
CSharpLanguageServer(mock_config, mock_logger, str(temp_path))
mock_settings = Mock(spec=SolidLSPSettings)
mock_settings.ls_resources_dir = "/tmp/test_ls_resources"
CSharpLanguageServer(mock_config, mock_logger, str(temp_path), mock_settings)
# Verify that logger was called with warning about no solution/project files
mock_logger.log.assert_any_call(