From c82fab97c171cf56d07a6cf8638442bc8b5c14f8 Mon Sep 17 00:00:00 2001 From: MischaPanch Date: Thu, 14 Aug 2025 11:47:46 +0200 Subject: [PATCH] CSharp: added waiting for request_referencing and test for cross-file references --- .../csharp_language_server.py | 9 +++++ .../repos/csharp/test_repo/Models/Person.cs | 8 +++++ test/solidlsp/csharp/test_csharp_basic.py | 33 +++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/src/solidlsp/language_servers/csharp_language_server.py b/src/solidlsp/language_servers/csharp_language_server.py index 6878901f..870e21a0 100644 --- a/src/solidlsp/language_servers/csharp_language_server.py +++ b/src/solidlsp/language_servers/csharp_language_server.py @@ -13,6 +13,7 @@ import threading import urllib.request import zipfile from pathlib import Path +from time import sleep from typing import cast from overrides import override @@ -21,6 +22,7 @@ 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 @@ -735,3 +737,10 @@ class CSharpLanguageServer(SolidLanguageServer): project_uris = [PathUtils.path_to_uri(project_file) for project_file in project_files] self.server.notify.send_notification("project/open", {"projects": project_uris}) 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(1) + return super().request_references(relative_file_path, line, column) diff --git a/test/resources/repos/csharp/test_repo/Models/Person.cs b/test/resources/repos/csharp/test_repo/Models/Person.cs index c771195c..db101886 100644 --- a/test/resources/repos/csharp/test_repo/Models/Person.cs +++ b/test/resources/repos/csharp/test_repo/Models/Person.cs @@ -1,3 +1,5 @@ +using TestProject; + namespace TestProject.Models { public class Person @@ -22,5 +24,11 @@ namespace TestProject.Models { return Age >= 18; } + + public int CalculateYearsUntilRetirement() + { + var calculator = new Calculator(); + return calculator.Subtract(65, Age); + } } } \ No newline at end of file diff --git a/test/solidlsp/csharp/test_csharp_basic.py b/test/solidlsp/csharp/test_csharp_basic.py index 89d3caea..a0c83a13 100644 --- a/test/solidlsp/csharp/test_csharp_basic.py +++ b/test/solidlsp/csharp/test_csharp_basic.py @@ -87,6 +87,39 @@ class TestCSharpLanguageServer: assert "ToString" in symbol_names assert "IsAdult" in symbol_names + @pytest.mark.parametrize("language_server", [Language.CSHARP], indirect=True) + def test_find_referencing_symbols_across_files(self, language_server: SolidLanguageServer) -> None: + """Test finding references to Calculator.Subtract method across files.""" + # First, find the Subtract method in Program.cs + file_path = os.path.join("Program.cs") + symbols = language_server.request_document_symbols(file_path) + + # Flatten the symbols if they're nested + symbol_list = symbols[0] if symbols and isinstance(symbols[0], list) else symbols + + subtract_symbol = None + for sym in symbol_list: + if sym.get("name") == "Subtract": + subtract_symbol = sym + break + + assert subtract_symbol is not None, "Could not find 'Subtract' method symbol in Program.cs" + + # Get references to the Subtract method + sel_start = subtract_symbol["selectionRange"]["start"] + 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] + 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 + ), "Should find reference in Models/Person.cs where Calculator.Subtract is called" + @pytest.mark.csharp class TestCSharpSolutionProjectOpening: