mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-13 14:16:21 +00:00
Introduce InitializeParamsBuilder base class and default implementation
which sets common settings centrally: - processId - rootPath - rootUri - clientInfo - workspaceFolders Apply builder in SolidLanguageServer, adding new abstract method _create_base_initialize_params to be implemented by subclasses. Applied in PyrightServer.
This commit is contained in:
1 parent
4f4b862802
commit
6f1f05407d
3 files changed
+93
-18
No files matched your search
@@ -0,0 +1,58 @@
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import TYPE_CHECKING, Any, Self, cast
|
||||
|
||||
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams, WorkspaceFolder
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from solidlsp import SolidLanguageServer
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class InitializeParamsBuilder(ABC):
|
||||
def __init__(self):
|
||||
self._params = {}
|
||||
|
||||
def with_base_options(self, options: dict | InitializeParams) -> Self:
|
||||
self._params.update(options)
|
||||
return self
|
||||
|
||||
def _set(self, key: str, value: Any) -> None:
|
||||
if key in self._params:
|
||||
log.debug("Overriding existing option '%s' with new value: %s (old value: %s)", key, value, self._params[key])
|
||||
self._params[key] = value
|
||||
|
||||
@abstractmethod
|
||||
def _apply_updates(self) -> None:
|
||||
"""
|
||||
Applies implementation-specific updates to the options.
|
||||
"""
|
||||
|
||||
def build(self) -> InitializeParams:
|
||||
self._apply_updates()
|
||||
return cast(InitializeParams, self._params)
|
||||
|
||||
|
||||
class DefaultInitializeParamsBuilder(InitializeParamsBuilder):
|
||||
def __init__(self, ls: "SolidLanguageServer", set_workspace_folders: bool = True):
|
||||
super().__init__()
|
||||
self._ls = ls
|
||||
self._set_workspace_folders = set_workspace_folders
|
||||
|
||||
@staticmethod
|
||||
def _create_workspace_folder_entry(path: str) -> WorkspaceFolder:
|
||||
abs_path = os.path.abspath(path)
|
||||
return {"uri": pathlib.Path(abs_path).as_uri(), "name": os.path.basename(abs_path)}
|
||||
|
||||
def _apply_updates(self):
|
||||
root_abs_path = self._ls.repository_root_path
|
||||
self._set("processId", os.getpid())
|
||||
self._set("rootPath", root_abs_path)
|
||||
self._set("rootUri", pathlib.Path(root_abs_path).as_uri())
|
||||
self._set("clientInfo", {"name": "Serena"})
|
||||
if self._set_workspace_folders:
|
||||
self._set("workspaceFolders", [self._create_workspace_folder_entry(root_abs_path)])
|
||||
@@ -3,8 +3,6 @@ Provides Python specific instantiation of the LanguageServer class. Contains var
|
||||
"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
import re
|
||||
import threading
|
||||
from typing import cast
|
||||
@@ -13,7 +11,6 @@ from overrides import override
|
||||
|
||||
from solidlsp.ls import LanguageServerDependencyProvider, LanguageServerDependencyProviderUvx, SolidLanguageServer
|
||||
from solidlsp.ls_config import LanguageServerConfig
|
||||
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
|
||||
from solidlsp.settings import SolidLSPSettings
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@@ -59,16 +56,8 @@ class PyrightServer(SolidLanguageServer):
|
||||
def is_ignored_dirname(self, dirname: str) -> bool:
|
||||
return super().is_ignored_dirname(dirname) or dirname in ["venv", "__pycache__"]
|
||||
|
||||
@staticmethod
|
||||
def _get_initialize_params(repository_absolute_path: str) -> InitializeParams:
|
||||
"""
|
||||
Returns the initialize params for the Pyright Language Server.
|
||||
"""
|
||||
# Create basic initialization parameters
|
||||
def _create_base_initialize_params(self) -> dict:
|
||||
initialize_params = {
|
||||
"processId": os.getpid(),
|
||||
"rootPath": repository_absolute_path,
|
||||
"rootUri": pathlib.Path(repository_absolute_path).as_uri(),
|
||||
"initializationOptions": {
|
||||
"exclude": [
|
||||
"**/__pycache__",
|
||||
@@ -111,12 +100,8 @@ class PyrightServer(SolidLanguageServer):
|
||||
"publishDiagnostics": {"relatedInformation": True},
|
||||
},
|
||||
},
|
||||
"workspaceFolders": [
|
||||
{"uri": pathlib.Path(repository_absolute_path).as_uri(), "name": os.path.basename(repository_absolute_path)}
|
||||
],
|
||||
}
|
||||
|
||||
return cast(InitializeParams, initialize_params)
|
||||
return initialize_params
|
||||
|
||||
def _start_server(self) -> None:
|
||||
"""
|
||||
@@ -230,7 +215,7 @@ class PyrightServer(SolidLanguageServer):
|
||||
self.server.start()
|
||||
|
||||
# Send proper initialization parameters
|
||||
initialize_params = self._get_initialize_params(self.repository_root_path)
|
||||
initialize_params = self._create_initialize_params()
|
||||
|
||||
log.info("Sending initialize request from LSP client to pyright server and awaiting response")
|
||||
init_response = self.server.send.initialize(initialize_params)
|
||||
|
||||
@@ -22,6 +22,7 @@ from sensai.util.string import ToStringMixin
|
||||
from serena.util.file_system import match_path
|
||||
from serena.util.text_utils import MatchedConsecutiveLines
|
||||
from solidlsp import ls_types
|
||||
from solidlsp.initialize_params import DefaultInitializeParamsBuilder, InitializeParamsBuilder
|
||||
from solidlsp.ls_config import FilenameMatcher, Language, LanguageServerConfig
|
||||
from solidlsp.ls_exceptions import SolidLSPException
|
||||
from solidlsp.ls_process import LanguageServerInterface, StdioLanguageServer
|
||||
@@ -35,6 +36,7 @@ from solidlsp.lsp_protocol_handler.lsp_types import (
|
||||
DefinitionParams,
|
||||
DocumentSymbol,
|
||||
ImplementationParams,
|
||||
InitializeParams,
|
||||
LocationLink,
|
||||
RenameParams,
|
||||
SymbolInformation,
|
||||
@@ -3281,3 +3283,33 @@ class SolidLanguageServer(ABC):
|
||||
|
||||
def is_running(self) -> bool:
|
||||
return self.server.is_running()
|
||||
|
||||
def _create_initialize_params_builder(self) -> InitializeParamsBuilder:
|
||||
return DefaultInitializeParamsBuilder(self)
|
||||
|
||||
def _create_base_initialize_params(self) -> dict | InitializeParams:
|
||||
"""
|
||||
Subclasses should override this method to provide server-specific InitializeParams settings,
|
||||
which provide the basis for the InitializeParams object sent to the language server during initialization.
|
||||
|
||||
The returned dictionary is passed to the builder constructed by _create_initialize_params_builder()
|
||||
in order to create the final InitializeParams object.
|
||||
|
||||
The default builder implementation already sets the following keys, so implementations of this method
|
||||
should not set them:
|
||||
|
||||
- processId
|
||||
- rootPath
|
||||
- rootUri
|
||||
- clientInfo
|
||||
- workspaceFolders
|
||||
|
||||
:return: the base InitializeParams settings
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def _create_initialize_params(self) -> InitializeParams:
|
||||
"""
|
||||
Create the InitializeParams object to send to the language server during initialization.
|
||||
"""
|
||||
return self._create_initialize_params_builder().with_base_options(self._create_base_initialize_params()).build()
|
||||
Reference in new issue
Block a user