mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-12 18:16:43 +00:00
Merge pull request #490 from oraios/improve_waiting_for_cross_file_references
Improve waiting logic for cross-file references to be ready
This commit is contained in:
5 files changed
+30
-24
No files matched your search
@@ -13,7 +13,6 @@ import threading
|
||||
import urllib.request
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
from time import sleep
|
||||
from typing import cast
|
||||
|
||||
from overrides import override
|
||||
@@ -22,7 +21,6 @@ from solidlsp.ls import SolidLanguageServer
|
||||
from solidlsp.ls_config import LanguageServerConfig
|
||||
from solidlsp.ls_exceptions import SolidLSPException
|
||||
from solidlsp.ls_logger import LanguageServerLogger
|
||||
from solidlsp.ls_types import Location
|
||||
from solidlsp.ls_utils import PathUtils
|
||||
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
|
||||
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
|
||||
@@ -739,8 +737,5 @@ class CSharpLanguageServer(SolidLanguageServer):
|
||||
self.logger.log(f"Opened project files: {project_files}", logging.DEBUG)
|
||||
|
||||
@override
|
||||
def request_references(self, relative_file_path: str, line: int, column: int) -> list[Location]:
|
||||
# Like in the typescript LS, we need to wait here for the language server to
|
||||
# get correct results that include cross-file references.
|
||||
sleep(2)
|
||||
return super().request_references(relative_file_path, line, column)
|
||||
def _get_wait_time_for_cross_file_referencing(self) -> float:
|
||||
return 1
|
||||
@@ -7,7 +7,6 @@ import os
|
||||
import pathlib
|
||||
import shutil
|
||||
import threading
|
||||
from time import sleep
|
||||
|
||||
from overrides import override
|
||||
from sensai.util.logging import LogTime
|
||||
@@ -250,12 +249,5 @@ class TypeScriptLanguageServer(SolidLanguageServer):
|
||||
self.completions_available.set()
|
||||
|
||||
@override
|
||||
# For some reason, the LS may need longer to process this, so we just retry
|
||||
def _send_references_request(self, relative_file_path: str, line: int, column: int):
|
||||
# TODO: The LS doesn't return references contained in other files if it doesn't sleep. This is
|
||||
# despite the LS having processed requests already. I don't know what causes this, but sleeping
|
||||
# one second helps. It may be that sleeping only once is enough but that's hard to reliably test.
|
||||
# It may be that even this 1sec is not enough in larger TS projects, at some point we should find what
|
||||
# causes this and solve it.
|
||||
sleep(1)
|
||||
return super()._send_references_request(relative_file_path, line, column)
|
||||
def _get_wait_time_for_cross_file_referencing(self) -> float:
|
||||
return 1
|
||||
@@ -9,7 +9,6 @@ import os
|
||||
import pathlib
|
||||
import shutil
|
||||
import threading
|
||||
from time import sleep
|
||||
|
||||
from overrides import override
|
||||
|
||||
@@ -231,8 +230,6 @@ class VtsLanguageServer(SolidLanguageServer):
|
||||
self.server_ready.set()
|
||||
self.completions_available.set()
|
||||
|
||||
# VTS may need longer to process references, so we include a sleep similar to TypeScript LS
|
||||
@override
|
||||
def _send_references_request(self, relative_file_path: str, line: int, column: int):
|
||||
sleep(1)
|
||||
return super()._send_references_request(relative_file_path, line, column)
|
||||
def _get_wait_time_for_cross_file_referencing(self) -> float:
|
||||
return 1
|
||||
@@ -14,6 +14,7 @@ from collections.abc import Iterator
|
||||
from contextlib import contextmanager
|
||||
from copy import copy
|
||||
from pathlib import Path, PurePath
|
||||
from time import sleep
|
||||
from typing import Self, Union, cast
|
||||
|
||||
import pathspec
|
||||
@@ -323,6 +324,16 @@ class SolidLanguageServer(ABC):
|
||||
self._server_context = None
|
||||
self._request_timeout: float | None = None
|
||||
|
||||
self._has_waited_for_cross_file_references = False
|
||||
|
||||
def _get_wait_time_for_cross_file_referencing(self) -> float:
|
||||
"""Meant to be overridden by subclasses for LS that don't have a reliable "finished initializing" signal.
|
||||
|
||||
LS may return incomplete results on calls to `request_references` (only references found in the same file),
|
||||
if the LS is not fully initialized yet.
|
||||
"""
|
||||
return 0
|
||||
|
||||
def set_request_timeout(self, timeout: float | None) -> None:
|
||||
"""
|
||||
:param timeout: the timeout, in seconds, for requests to the language server.
|
||||
@@ -699,6 +710,12 @@ class SolidLanguageServer(ABC):
|
||||
)
|
||||
raise SolidLSPException("Language Server not started")
|
||||
|
||||
if not self._has_waited_for_cross_file_references:
|
||||
# Some LS require waiting for a while before they can return cross-file references.
|
||||
# This is a workaround for such LS that don't have a reliable "finished initializing" signal.
|
||||
sleep(self._get_wait_time_for_cross_file_referencing())
|
||||
self._has_waited_for_cross_file_references = True
|
||||
|
||||
with self.open_file(relative_file_path):
|
||||
try:
|
||||
response = self._send_references_request(relative_file_path, line=line, column=column)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import os
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from typing import cast
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
import pytest
|
||||
@@ -110,16 +111,20 @@ class TestCSharpLanguageServer:
|
||||
refs = language_server.request_references(file_path, sel_start["line"], sel_start["character"] + 1)
|
||||
|
||||
# Should find references in both Program.cs and Models/Person.cs
|
||||
ref_files = [ref.get("relativePath", "") for ref in refs]
|
||||
ref_files = cast(list[str], [ref.get("relativePath", "") for ref in refs])
|
||||
print(f"Found references: {refs}")
|
||||
print(f"Reference files: {ref_files}")
|
||||
|
||||
# Check that we have references from both files
|
||||
assert any("Program.cs" in ref_file for ref_file in ref_files), "Should find reference in Program.cs"
|
||||
assert any(
|
||||
"Models/Person.cs" in ref_file for ref_file in ref_files
|
||||
os.path.join("Models", "Person.cs") in ref_file for ref_file in ref_files
|
||||
), "Should find reference in Models/Person.cs where Calculator.Subtract is called"
|
||||
|
||||
# check for a second time, since the first call may trigger initialization and change the state of the LS
|
||||
refs_second_call = language_server.request_references(file_path, sel_start["line"], sel_start["character"] + 1)
|
||||
assert refs_second_call == refs, "Second call to request_references should return the same results"
|
||||
|
||||
|
||||
@pytest.mark.csharp
|
||||
class TestCSharpSolutionProjectOpening:
|
||||
|
||||
Reference in new issue
Block a user