From 39854c8baa96f786227a26d8ca213b4768e3486c Mon Sep 17 00:00:00 2001 From: Michael Panchenko Date: Tue, 20 May 2025 17:21:21 +0200 Subject: [PATCH] Fix minor typing issues, fix initialization of gopls, remove hack --- src/multilspy/language_server.py | 3 ++- src/multilspy/language_servers/gopls/gopls.py | 16 +--------------- .../gopls/initialize_params.json | 10 ++++++++++ src/serena/agent.py | 3 ++- test/multilspy/go/test_go_basic.py | 1 + 5 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/multilspy/language_server.py b/src/multilspy/language_server.py index 2c50fbbf..6ca98b9a 100644 --- a/src/multilspy/language_server.py +++ b/src/multilspy/language_server.py @@ -38,6 +38,7 @@ from .multilspy_exceptions import MultilspyException from .multilspy_logger import MultilspyLogger from .multilspy_utils import FileUtils, PathUtils, TextUtils from .type_helpers import ensure_all_methods_implemented +from .lsp_protocol_handler import lsp_types # Serena dependencies # We will need to watch out for circular imports, but it's probably better to not @@ -582,7 +583,7 @@ class LanguageServer: return ret # Some LS cause problems with this, so the call is isolated from the rest to allow overriding in subclasses - async def _send_references_request(self, relative_file_path: str, line: int, column: int): + async def _send_references_request(self, relative_file_path: str, line: int, column: int) -> List[lsp_types.Location] | None: return await self.server.send.references( { "textDocument": {"uri": PathUtils.path_to_uri(os.path.join(self.repository_root_path, relative_file_path))}, diff --git a/src/multilspy/language_servers/gopls/gopls.py b/src/multilspy/language_servers/gopls/gopls.py index ac474451..d17901a0 100644 --- a/src/multilspy/language_servers/gopls/gopls.py +++ b/src/multilspy/language_servers/gopls/gopls.py @@ -10,6 +10,7 @@ from typing import AsyncIterator, List from overrides import override from multilspy import multilspy_types +from multilspy.lsp_protocol_handler import lsp_types from multilspy.multilspy_exceptions import MultilspyException from multilspy.multilspy_logger import MultilspyLogger from multilspy.language_server import LanguageServer @@ -154,18 +155,3 @@ class Gopls(LanguageServer): await self.server.shutdown() await self.server.stop() - - @override - async def _send_references_request(self, relative_file_path: str, line: int, column: int) -> List[multilspy_types.Location]: - NUM_COLS_TO_TRY = 10 - """selectionRange in Gopls always contains the wrong column, - the one at the beginning of the declaration instead of the symbol. We do a dirty hack here (loop over some columns). - See https://github.com/golang/go/issues/73521 - """ - actual_column = column - for actual_column in range(column, column+NUM_COLS_TO_TRY): - try: - return await super()._send_references_request(relative_file_path, line, actual_column) - except (Error, RuntimeError, MultilspyException) as e: - self.logger.log(f"Cannot find symbol at {line=}, column={actual_column}, trying to bump column by 1", logging.INFO) - raise MultilspyException(f"Failed to find references for symbol in\n{relative_file_path=} at {line=}, {column=}") diff --git a/src/multilspy/language_servers/gopls/initialize_params.json b/src/multilspy/language_servers/gopls/initialize_params.json index 4330560e..40592e1a 100644 --- a/src/multilspy/language_servers/gopls/initialize_params.json +++ b/src/multilspy/language_servers/gopls/initialize_params.json @@ -18,6 +18,16 @@ }, "definition": { "dynamicRegistration": true + }, + "documentSymbol": { + "dynamicRegistration": true, + "hierarchicalDocumentSymbolSupport": true, + "symbolKind": { + "valueSet": [ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 + ] + } } }, "workspace": { diff --git a/src/serena/agent.py b/src/serena/agent.py index a60b09da..a8a6fcd0 100644 --- a/src/serena/agent.py +++ b/src/serena/agent.py @@ -794,7 +794,7 @@ class FindSymbolTool(Tool): or to retrieve further information using other tools. If you already anticipate that you will need to reference children of the symbol (like methods or fields contained in a class), you can specify a depth > 0. - + The name matching behavior depends on whether a qualified name or a simple name is provided. It is assumed that the provided name is a qualified name if it contains the `/` character. If substring matching is allowed, only the last element of the qualified name will be checked against @@ -836,6 +836,7 @@ class FindSymbolTool(Tool): required for the task. Instead, if the output is too long, you should make a stricter query. :return: a list of symbols (with symbol locations) that match the given name in JSON format + """ include_kinds = cast(list[SymbolKind] | None, include_kinds) exclude_kinds = cast(list[SymbolKind] | None, exclude_kinds) diff --git a/test/multilspy/go/test_go_basic.py b/test/multilspy/go/test_go_basic.py index a87e9fe1..6b5e316b 100644 --- a/test/multilspy/go/test_go_basic.py +++ b/test/multilspy/go/test_go_basic.py @@ -7,6 +7,7 @@ from multilspy.multilspy_config import Language from multilspy.multilspy_utils import SymbolUtils +@pytest.mark.go class TestGoLanguageServer: @pytest.mark.parametrize("language_server", [Language.GO], indirect=True) def test_find_symbol(self, language_server: SyncLanguageServer) -> None: