diff --git a/packages/jsonrpc2/src/robotcode/jsonrpc2/protocol.py b/packages/jsonrpc2/src/robotcode/jsonrpc2/protocol.py index 974aacf29..12d502d0f 100644 --- a/packages/jsonrpc2/src/robotcode/jsonrpc2/protocol.py +++ b/packages/jsonrpc2/src/robotcode/jsonrpc2/protocol.py @@ -32,12 +32,8 @@ runtime_checkable, ) -from robotcode.core.async_tools import create_sub_task, run_coroutine_in_thread -from robotcode.core.concurrent import ( - FutureEx, - is_threaded_callable, - run_in_thread, -) +from robotcode.core.async_tools import run_coroutine_in_thread +from robotcode.core.concurrent import FutureEx, run_in_thread from robotcode.core.event import event from robotcode.core.utils.dataclasses import as_json, from_dict from robotcode.core.utils.inspect import ensure_coroutine, iter_methods @@ -150,6 +146,7 @@ class RpcMethodEntry: method: Callable[..., Any] param_type: Optional[Type[Any]] cancelable: bool + threaded: bool _is_coroutine: Optional[bool] = field(default=None, init=False) @@ -181,6 +178,7 @@ def rpc_method( name: Optional[str] = None, param_type: Optional[Type[Any]] = None, cancelable: bool = True, + threaded: bool = False, ) -> Callable[[_F], _F]: ... @@ -191,6 +189,7 @@ def rpc_method( name: Optional[str] = None, param_type: Optional[Type[Any]] = None, cancelable: bool = True, + threaded: bool = False, ) -> Callable[[_F], _F]: def _decorator(func: _F) -> Callable[[_F], _F]: if inspect.isclass(_func): @@ -207,7 +206,7 @@ def _decorator(func: _F) -> Callable[[_F], _F]: if real_name is None or not real_name: raise ValueError("name is empty.") - cast(RpcMethod, f).__rpc_method__ = RpcMethodEntry(real_name, f, param_type, cancelable) + cast(RpcMethod, f).__rpc_method__ = RpcMethodEntry(real_name, f, param_type, cancelable, threaded) return func if _func is None: @@ -274,6 +273,7 @@ def get_methods(obj: Any) -> Dict[str, RpcMethodEntry]: method, rpc_method.__rpc_method__.param_type, rpc_method.__rpc_method__.cancelable, + rpc_method.__rpc_method__.threaded, ) for method, rpc_method in map( lambda m1: (m1, cast(RpcMethod, m1)), @@ -324,10 +324,11 @@ def add_method( func: Callable[..., Any], param_type: Optional[Type[Any]] = None, cancelable: bool = True, + threaded: bool = False, ) -> None: self.__ensure_initialized() - self.__methods[name] = RpcMethodEntry(name, func, param_type, cancelable) + self.__methods[name] = RpcMethodEntry(name, func, param_type, cancelable, threaded) def remove_method(self, name: str) -> Optional[RpcMethodEntry]: self.__ensure_initialized() @@ -741,12 +742,10 @@ async def handle_request(self, message: JsonRPCRequest) -> None: params = self._convert_params(e.method, e.param_type, message.params) - is_threaded_method = is_threaded_callable(e.method) - - if not is_threaded_method and not e.is_coroutine: + if not e.threaded and not e.is_coroutine: self.send_response(message.id, e.method(*params[0], **params[1])) else: - if is_threaded_method: + if e.threaded: if e.is_coroutine: task = run_coroutine_in_thread( ensure_coroutine(cast(Callable[..., Any], e.method)), @@ -756,10 +755,7 @@ async def handle_request(self, message: JsonRPCRequest) -> None: else: task = asyncio.wrap_future(run_in_thread(e.method, *params[0], **params[1])) else: - task = create_sub_task( - ensure_coroutine(e.method)(*params[0], **params[1]), - name=message.method, - ) + task = asyncio.create_task(e.method(*params[0], **params[1]), name=message.method) with self._received_request_lock: self._received_request[message.id] = ReceivedRequestEntry(task, message, e.cancelable) @@ -845,20 +841,18 @@ async def handle_notification(self, message: JsonRPCNotification) -> None: try: params = self._convert_params(e.method, e.param_type, message.params) - if not e.is_coroutine: + if not e.threaded and not e.is_coroutine: e.method(*params[0], **params[1]) else: - if is_threaded_callable(e.method): - task = run_coroutine_in_thread( - ensure_coroutine(cast(Callable[..., Any], e.method)), - *params[0], - **params[1], - ) + if e.threaded: + if e.is_coroutine: + task = run_coroutine_in_thread( + ensure_coroutine(cast(Callable[..., Any], e.method)), *params[0], **params[1] + ) + else: + task = asyncio.wrap_future(run_in_thread(e.method, *params[0], **params[1])) else: - task = create_sub_task( - ensure_coroutine(e.method)(*params[0], **params[1]), - name=message.method, - ) + task = asyncio.create_task(e.method(*params[0], **params[1]), name=message.method) await task except asyncio.CancelledError: diff --git a/packages/language_server/src/robotcode/language_server/common/parts/code_action.py b/packages/language_server/src/robotcode/language_server/common/parts/code_action.py index 8fcb851e8..39993c6c3 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/code_action.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/code_action.py @@ -2,7 +2,7 @@ from itertools import chain from typing import TYPE_CHECKING, Any, Final, List, Optional, Union, cast -from robotcode.core.concurrent import check_current_thread_canceled, threaded +from robotcode.core.concurrent import check_current_thread_canceled from robotcode.core.event import event from robotcode.core.lsp.types import ( CodeAction, @@ -66,8 +66,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None: resolve_provider=len(self.resolve) > 0, ) - @rpc_method(name="textDocument/codeAction", param_type=CodeActionParams) - @threaded + @rpc_method(name="textDocument/codeAction", param_type=CodeActionParams, threaded=True) def _text_document_code_action( self, text_document: TextDocumentIdentifier, @@ -109,8 +108,7 @@ def _text_document_code_action( return results - @rpc_method(name="codeAction/resolve", param_type=CodeAction) - @threaded + @rpc_method(name="codeAction/resolve", param_type=CodeAction, threaded=True) def _text_document_code_action_resolve(self, params: CodeAction, *args: Any, **kwargs: Any) -> CodeAction: results: List[CodeAction] = [] diff --git a/packages/language_server/src/robotcode/language_server/common/parts/code_lens.py b/packages/language_server/src/robotcode/language_server/common/parts/code_lens.py index dbf60a300..84f9bb743 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/code_lens.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/code_lens.py @@ -1,12 +1,7 @@ from concurrent.futures import CancelledError from typing import TYPE_CHECKING, Any, Final, List, Optional -from robotcode.core.concurrent import ( - FutureEx, - check_current_thread_canceled, - run_in_thread, - threaded, -) +from robotcode.core.concurrent import FutureEx, check_current_thread_canceled, run_in_thread from robotcode.core.event import event from robotcode.core.lsp.types import ( CodeLens, @@ -46,8 +41,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None: if len(self.collect): capabilities.code_lens_provider = CodeLensOptions(resolve_provider=True if len(self.resolve) > 0 else None) - @rpc_method(name="textDocument/codeLens", param_type=CodeLensParams) - @threaded + @rpc_method(name="textDocument/codeLens", param_type=CodeLensParams, threaded=True) def _text_document_code_lens( self, text_document: TextDocumentIdentifier, *args: Any, **kwargs: Any ) -> Optional[List[CodeLens]]: @@ -74,8 +68,7 @@ def _text_document_code_lens( return results - @rpc_method(name="codeLens/resolve", param_type=CodeLens) - @threaded + @rpc_method(name="codeLens/resolve", param_type=CodeLens, threaded=True) def _code_lens_resolve(self, params: CodeLens, *args: Any, **kwargs: Any) -> CodeLens: results: List[CodeLens] = [] diff --git a/packages/language_server/src/robotcode/language_server/common/parts/commands.py b/packages/language_server/src/robotcode/language_server/common/parts/commands.py index 602ffc2bb..105903929 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/commands.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/commands.py @@ -13,7 +13,6 @@ cast, ) -from robotcode.core.concurrent import threaded from robotcode.core.lsp.types import ( ErrorCodes, ExecuteCommandOptions, @@ -82,8 +81,7 @@ def get_command_name(self, callback: _FUNC_TYPE, name: Optional[str] = None) -> def extend_capabilities(self, capabilities: ServerCapabilities) -> None: capabilities.execute_command_provider = ExecuteCommandOptions(list(self.commands.keys())) - @rpc_method(name="workspace/executeCommand", param_type=ExecuteCommandParams) - @threaded + @rpc_method(name="workspace/executeCommand", param_type=ExecuteCommandParams, threaded=True) def _workspace_execute_command( self, command: str, diff --git a/packages/language_server/src/robotcode/language_server/common/parts/completion.py b/packages/language_server/src/robotcode/language_server/common/parts/completion.py index e79768b96..f22434d57 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/completion.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/completion.py @@ -2,7 +2,7 @@ from itertools import chain from typing import TYPE_CHECKING, Any, Final, List, Optional, Union, cast -from robotcode.core.concurrent import check_current_thread_canceled, threaded +from robotcode.core.concurrent import check_current_thread_canceled from robotcode.core.event import event from robotcode.core.lsp.types import ( CompletionContext, @@ -84,8 +84,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None: completion_item=CompletionOptionsCompletionItemType(label_details_support=True), ) - @rpc_method(name="textDocument/completion", param_type=CompletionParams) - @threaded + @rpc_method(name="textDocument/completion", param_type=CompletionParams, threaded=True) def _text_document_completion( self, text_document: TextDocumentIdentifier, @@ -159,8 +158,7 @@ def update_completion_item_to_utf16(self, document: TextDocument, item: Completi item.text_edit.insert = document.range_to_utf16(item.text_edit.insert) item.text_edit.replace = document.range_to_utf16(item.text_edit.replace) - @rpc_method(name="completionItem/resolve", param_type=CompletionItem) - @threaded + @rpc_method(name="completionItem/resolve", param_type=CompletionItem, threaded=True) def _completion_item_resolve(self, params: CompletionItem, *args: Any, **kwargs: Any) -> CompletionItem: results: List[CompletionItem] = [] diff --git a/packages/language_server/src/robotcode/language_server/common/parts/declaration.py b/packages/language_server/src/robotcode/language_server/common/parts/declaration.py index 43283ea2c..37f9eac45 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/declaration.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/declaration.py @@ -1,7 +1,7 @@ from asyncio import CancelledError from typing import TYPE_CHECKING, Any, Final, List, Optional, Union -from robotcode.core.concurrent import check_current_thread_canceled, threaded +from robotcode.core.concurrent import check_current_thread_canceled from robotcode.core.event import event from robotcode.core.lsp.types import ( DeclarationParams, @@ -49,8 +49,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None: if len(self.collect): capabilities.declaration_provider = True - @rpc_method(name="textDocument/declaration", param_type=DeclarationParams) - @threaded + @rpc_method(name="textDocument/declaration", param_type=DeclarationParams, threaded=True) def _text_document_declaration( self, text_document: TextDocumentIdentifier, diff --git a/packages/language_server/src/robotcode/language_server/common/parts/definition.py b/packages/language_server/src/robotcode/language_server/common/parts/definition.py index d52895e28..349bb2a05 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/definition.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/definition.py @@ -1,7 +1,7 @@ from concurrent.futures import CancelledError from typing import TYPE_CHECKING, Any, Final, List, Optional, Union -from robotcode.core.concurrent import check_current_thread_canceled, threaded +from robotcode.core.concurrent import check_current_thread_canceled from robotcode.core.event import event from robotcode.core.lsp.types import ( DefinitionParams, @@ -49,8 +49,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None: if len(self.collect): capabilities.definition_provider = True - @rpc_method(name="textDocument/definition", param_type=DefinitionParams) - @threaded + @rpc_method(name="textDocument/definition", param_type=DefinitionParams, threaded=True) def _text_document_definition( self, text_document: TextDocumentIdentifier, diff --git a/packages/language_server/src/robotcode/language_server/common/parts/diagnostics.py b/packages/language_server/src/robotcode/language_server/common/parts/diagnostics.py index 52fbcf7b4..8f8dcdea4 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/diagnostics.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/diagnostics.py @@ -390,8 +390,7 @@ def publish_diagnostics(self, document: TextDocument, diagnostics: List[Diagnost def update_document_diagnostics(self, sender: Any, document: TextDocument) -> None: self.create_document_diagnostics_task(document, True) - @rpc_method(name="textDocument/diagnostic", param_type=DocumentDiagnosticParams) - @threaded + @rpc_method(name="textDocument/diagnostic", param_type=DocumentDiagnosticParams, threaded=True) def _text_document_diagnostic( self, text_document: TextDocumentIdentifier, @@ -431,8 +430,7 @@ def get_diagnostics_data(self, document: TextDocument) -> DiagnosticsData: return data - @rpc_method(name="workspace/diagnostic", param_type=WorkspaceDiagnosticParams) - @threaded + @rpc_method(name="workspace/diagnostic", param_type=WorkspaceDiagnosticParams, threaded=True) def _workspace_diagnostic( self, identifier: Optional[str], diff --git a/packages/language_server/src/robotcode/language_server/common/parts/document_highlight.py b/packages/language_server/src/robotcode/language_server/common/parts/document_highlight.py index cabc090b5..3b2c6beda 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/document_highlight.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/document_highlight.py @@ -1,7 +1,7 @@ from concurrent.futures import CancelledError from typing import TYPE_CHECKING, Any, Final, List, Optional -from robotcode.core.concurrent import threaded +from robotcode.core.concurrent import check_current_thread_canceled from robotcode.core.event import event from robotcode.core.lsp.types import ( DocumentHighlight, @@ -37,11 +37,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None: def collect(sender, document: TextDocument, position: Position) -> Optional[List[DocumentHighlight]]: # NOSONAR ... - @rpc_method( - name="textDocument/documentHighlight", - param_type=DocumentHighlightParams, - ) - @threaded + @rpc_method(name="textDocument/documentHighlight", param_type=DocumentHighlightParams, threaded=True) def _text_document_document_highlight( self, text_document: TextDocumentIdentifier, @@ -61,6 +57,8 @@ def _text_document_document_highlight( document.position_from_utf16(position), callback_filter=language_id_filter(document), ): + check_current_thread_canceled() + if isinstance(result, BaseException): if not isinstance(result, CancelledError): self._logger.exception(result, exc_info=result) diff --git a/packages/language_server/src/robotcode/language_server/common/parts/document_symbols.py b/packages/language_server/src/robotcode/language_server/common/parts/document_symbols.py index fc74b472d..f246f5508 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/document_symbols.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/document_symbols.py @@ -97,7 +97,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None: else: capabilities.document_symbol_provider = True - @rpc_method(name="textDocument/documentSymbol", param_type=DocumentSymbolParams) + @rpc_method(name="textDocument/documentSymbol", param_type=DocumentSymbolParams, threaded=True) @threaded def _text_document_symbol( self, text_document: TextDocumentIdentifier, *args: Any, **kwargs: Any diff --git a/packages/language_server/src/robotcode/language_server/common/parts/folding_range.py b/packages/language_server/src/robotcode/language_server/common/parts/folding_range.py index 3edcf4637..54443e38b 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/folding_range.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/folding_range.py @@ -1,7 +1,6 @@ from concurrent.futures import CancelledError from typing import TYPE_CHECKING, Any, Final, List, Optional -from robotcode.core.concurrent import threaded from robotcode.core.event import event from robotcode.core.lsp.types import ( FoldingRange, @@ -38,8 +37,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None: if len(self.collect): capabilities.folding_range_provider = True - @rpc_method(name="textDocument/foldingRange", param_type=FoldingRangeParams) - @threaded + @rpc_method(name="textDocument/foldingRange", param_type=FoldingRangeParams, threaded=True) def _text_document_folding_range( self, text_document: TextDocumentIdentifier, *args: Any, **kwargs: Any ) -> Optional[List[FoldingRange]]: diff --git a/packages/language_server/src/robotcode/language_server/common/parts/formatting.py b/packages/language_server/src/robotcode/language_server/common/parts/formatting.py index e86a2543a..d6170b21b 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/formatting.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/formatting.py @@ -1,7 +1,7 @@ from concurrent.futures import CancelledError from typing import TYPE_CHECKING, Any, Final, List, Optional -from robotcode.core.concurrent import check_current_thread_canceled, threaded +from robotcode.core.concurrent import check_current_thread_canceled from robotcode.core.event import event from robotcode.core.lsp.types import ( DocumentFormattingOptions, @@ -58,8 +58,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None: if len(self.format_range): capabilities.document_range_formatting_provider = DocumentRangeFormattingOptions(work_done_progress=True) - @rpc_method(name="textDocument/formatting", param_type=DocumentFormattingParams) - @threaded + @rpc_method(name="textDocument/formatting", param_type=DocumentFormattingParams, threaded=True) def _text_document_formatting( self, params: DocumentFormattingParams, @@ -96,11 +95,7 @@ def _text_document_formatting( return None - @rpc_method( - name="textDocument/rangeFormatting", - param_type=DocumentRangeFormattingParams, - ) - @threaded + @rpc_method(name="textDocument/rangeFormatting", param_type=DocumentRangeFormattingParams, threaded=True) def _text_document_range_formatting( self, params: DocumentFormattingParams, diff --git a/packages/language_server/src/robotcode/language_server/common/parts/hover.py b/packages/language_server/src/robotcode/language_server/common/parts/hover.py index f89c3f348..2194251f7 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/hover.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/hover.py @@ -1,7 +1,7 @@ from concurrent.futures import CancelledError from typing import TYPE_CHECKING, Any, Final, List, Optional -from robotcode.core.concurrent import check_current_thread_canceled, threaded +from robotcode.core.concurrent import check_current_thread_canceled from robotcode.core.event import event from robotcode.core.lsp.types import ( Hover, @@ -37,8 +37,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None: if len(self.collect): capabilities.hover_provider = HoverOptions(work_done_progress=True) - @rpc_method(name="textDocument/hover", param_type=HoverParams) - @threaded + @rpc_method(name="textDocument/hover", param_type=HoverParams, threaded=True) def _text_document_hover( self, text_document: TextDocumentIdentifier, diff --git a/packages/language_server/src/robotcode/language_server/common/parts/implementation.py b/packages/language_server/src/robotcode/language_server/common/parts/implementation.py index b1cb72a16..da479dbbc 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/implementation.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/implementation.py @@ -1,7 +1,7 @@ from concurrent.futures import CancelledError from typing import TYPE_CHECKING, Any, Final, List, Optional, Union -from robotcode.core.concurrent import check_current_thread_canceled, threaded +from robotcode.core.concurrent import check_current_thread_canceled from robotcode.core.event import event from robotcode.core.lsp.types import ( ImplementationParams, @@ -48,8 +48,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None: if len(self.collect): capabilities.implementation_provider = True - @rpc_method(name="textDocument/implementation", param_type=ImplementationParams) - @threaded + @rpc_method(name="textDocument/implementation", param_type=ImplementationParams, threaded=True) def _text_document_implementation( self, text_document: TextDocumentIdentifier, diff --git a/packages/language_server/src/robotcode/language_server/common/parts/inlay_hint.py b/packages/language_server/src/robotcode/language_server/common/parts/inlay_hint.py index a13e812f1..c752d6360 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/inlay_hint.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/inlay_hint.py @@ -5,7 +5,6 @@ FutureEx, check_current_thread_canceled, run_in_thread, - threaded, ) from robotcode.core.event import event from robotcode.core.lsp.types import ( @@ -50,8 +49,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None: else: capabilities.inlay_hint_provider = InlayHintOptions() - @rpc_method(name="textDocument/inlayHint", param_type=InlayHintParams) - @threaded + @rpc_method(name="textDocument/inlayHint", param_type=InlayHintParams, threaded=True) def _text_document_inlay_hint( self, text_document: TextDocumentIdentifier, @@ -87,8 +85,7 @@ def _text_document_inlay_hint( return None - @rpc_method(name="inlayHint/resolve", param_type=InlayHint) - @threaded + @rpc_method(name="inlayHint/resolve", param_type=InlayHint, threaded=True) def _inlay_hint_resolve(self, params: InlayHint, *args: Any, **kwargs: Any) -> Optional[InlayHint]: for result in self.resolve(self, params): if isinstance(result, BaseException): diff --git a/packages/language_server/src/robotcode/language_server/common/parts/inline_value.py b/packages/language_server/src/robotcode/language_server/common/parts/inline_value.py index 1284ace06..2dc68327d 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/inline_value.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/inline_value.py @@ -5,7 +5,6 @@ FutureEx, check_current_thread_canceled, run_in_thread, - threaded, ) from robotcode.core.event import event from robotcode.core.lsp.types import ( @@ -65,8 +64,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None: document_selector=document_filters if document_filters else None, ) - @rpc_method(name="textDocument/inlineValue", param_type=InlineValueParams) - @threaded + @rpc_method(name="textDocument/inlineValue", param_type=InlineValueParams, threaded=True) def _text_document_inline_value( self, text_document: TextDocumentIdentifier, diff --git a/packages/language_server/src/robotcode/language_server/common/parts/linked_editing_ranges.py b/packages/language_server/src/robotcode/language_server/common/parts/linked_editing_ranges.py index c776ed1f8..15473d4df 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/linked_editing_ranges.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/linked_editing_ranges.py @@ -1,7 +1,7 @@ from concurrent.futures import CancelledError from typing import TYPE_CHECKING, Any, Final, List, Optional -from robotcode.core.concurrent import check_current_thread_canceled, threaded +from robotcode.core.concurrent import check_current_thread_canceled from robotcode.core.event import event from robotcode.core.lsp.types import ( LinkedEditingRangeOptions, @@ -37,11 +37,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None: def collect(sender, document: TextDocument, position: Position) -> Optional[LinkedEditingRanges]: # NOSONAR ... - @rpc_method( - name="textDocument/linkedEditingRange", - param_type=LinkedEditingRangeParams, - ) - @threaded + @rpc_method(name="textDocument/linkedEditingRange", param_type=LinkedEditingRangeParams, threaded=True) def _text_document_linked_editing_range( self, text_document: TextDocumentIdentifier, diff --git a/packages/language_server/src/robotcode/language_server/common/parts/references.py b/packages/language_server/src/robotcode/language_server/common/parts/references.py index 201557466..bde64e254 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/references.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/references.py @@ -1,7 +1,7 @@ from concurrent.futures import CancelledError from typing import TYPE_CHECKING, Any, Final, List, Optional -from robotcode.core.concurrent import check_current_thread_canceled, threaded +from robotcode.core.concurrent import check_current_thread_canceled from robotcode.core.event import event from robotcode.core.lsp.types import ( Location, @@ -42,8 +42,7 @@ def collect( ) -> Optional[List[Location]]: ... - @rpc_method(name="textDocument/references", param_type=ReferenceParams) - @threaded + @rpc_method(name="textDocument/references", param_type=ReferenceParams, threaded=True) def _text_document_references( self, text_document: TextDocumentIdentifier, diff --git a/packages/language_server/src/robotcode/language_server/common/parts/rename.py b/packages/language_server/src/robotcode/language_server/common/parts/rename.py index f8db8b3f6..e0960a663 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/rename.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/rename.py @@ -1,7 +1,7 @@ from concurrent.futures import CancelledError from typing import TYPE_CHECKING, Any, Final, List, Optional -from robotcode.core.concurrent import check_current_thread_canceled, threaded +from robotcode.core.concurrent import check_current_thread_canceled from robotcode.core.event import event from robotcode.core.lsp.types import ( ErrorCodes, @@ -58,8 +58,7 @@ def collect( def collect_prepare(sender, document: TextDocument, position: Position) -> Optional[PrepareRenameResult]: # NOSONAR ... - @rpc_method(name="textDocument/rename", param_type=RenameParams) - @threaded + @rpc_method(name="textDocument/rename", param_type=RenameParams, threaded=True) def _text_document_rename( self, text_document: TextDocumentIdentifier, @@ -131,8 +130,7 @@ def _text_document_rename( return result - @rpc_method(name="textDocument/prepareRename", param_type=PrepareRenameParams) - @threaded + @rpc_method(name="textDocument/prepareRename", param_type=PrepareRenameParams, threaded=True) def _text_document_prepare_rename( self, text_document: TextDocumentIdentifier, diff --git a/packages/language_server/src/robotcode/language_server/common/parts/selection_range.py b/packages/language_server/src/robotcode/language_server/common/parts/selection_range.py index 15203bd69..50b8ffd71 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/selection_range.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/selection_range.py @@ -1,7 +1,7 @@ from concurrent.futures import CancelledError from typing import TYPE_CHECKING, Any, Final, List, Optional -from robotcode.core.concurrent import check_current_thread_canceled, threaded +from robotcode.core.concurrent import check_current_thread_canceled from robotcode.core.event import event from robotcode.core.lsp.types import ( Position, @@ -36,8 +36,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None: def collect(sender, document: TextDocument, positions: List[Position]) -> Optional[List[SelectionRange]]: # NOSONAR ... - @rpc_method(name="textDocument/selectionRange", param_type=SelectionRangeParams) - @threaded + @rpc_method(name="textDocument/selectionRange", param_type=SelectionRangeParams, threaded=True) def _text_document_selection_range( self, text_document: TextDocumentIdentifier, diff --git a/packages/language_server/src/robotcode/language_server/common/parts/semantic_tokens.py b/packages/language_server/src/robotcode/language_server/common/parts/semantic_tokens.py index dbe8c5043..61d8d633e 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/semantic_tokens.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/semantic_tokens.py @@ -2,12 +2,7 @@ from enum import Enum from typing import TYPE_CHECKING, Any, Final, List, Optional, Union -from robotcode.core.concurrent import ( - FutureEx, - check_current_thread_canceled, - run_in_thread, - threaded, -) +from robotcode.core.concurrent import FutureEx, check_current_thread_canceled, run_in_thread from robotcode.core.event import event from robotcode.core.lsp.types import ( Range, @@ -89,8 +84,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None: range=True if len(self.collect_range) else None, ) - @rpc_method(name="textDocument/semanticTokens/full", param_type=SemanticTokensParams) - @threaded + @rpc_method(name="textDocument/semanticTokens/full", param_type=SemanticTokensParams, threaded=True) def _text_document_semantic_tokens_full( self, text_document: TextDocumentIdentifier, *args: Any, **kwargs: Any ) -> Union[SemanticTokens, SemanticTokensPartialResult, None]: @@ -121,11 +115,7 @@ def _text_document_semantic_tokens_full( return None - @rpc_method( - name="textDocument/semanticTokens/full/delta", - param_type=SemanticTokensDeltaParams, - ) - @threaded + @rpc_method(name="textDocument/semanticTokens/full/delta", param_type=SemanticTokensDeltaParams, threaded=True) def _text_document_semantic_tokens_full_delta( self, text_document: TextDocumentIdentifier, @@ -166,11 +156,7 @@ def _text_document_semantic_tokens_full_delta( return None - @rpc_method( - name="textDocument/semanticTokens/range", - param_type=SemanticTokensRangeParams, - ) - @threaded + @rpc_method(name="textDocument/semanticTokens/range", param_type=SemanticTokensRangeParams, threaded=True) def _text_document_semantic_tokens_range( self, text_document: TextDocumentIdentifier, diff --git a/packages/language_server/src/robotcode/language_server/common/parts/signature_help.py b/packages/language_server/src/robotcode/language_server/common/parts/signature_help.py index e1cf1c1ee..cb31413a4 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/signature_help.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/signature_help.py @@ -2,7 +2,7 @@ from itertools import chain from typing import TYPE_CHECKING, Any, Final, List, Optional, cast -from robotcode.core.concurrent import check_current_thread_canceled, threaded +from robotcode.core.concurrent import check_current_thread_canceled from robotcode.core.event import event from robotcode.core.lsp.types import ( Position, @@ -72,8 +72,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None: retrigger_characters=retrigger_chars if retrigger_chars else None, ) - @rpc_method(name="textDocument/signatureHelp", param_type=SignatureHelpParams) - @threaded + @rpc_method(name="textDocument/signatureHelp", param_type=SignatureHelpParams, threaded=True) def _text_document_signature_help( self, text_document: TextDocumentIdentifier, diff --git a/packages/language_server/src/robotcode/language_server/common/parts/window.py b/packages/language_server/src/robotcode/language_server/common/parts/window.py index a93c7c46f..2d19dd519 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/window.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/window.py @@ -206,10 +206,7 @@ def create_progress(self) -> Optional[ProgressToken]: return None - @rpc_method( - name="window/workDoneProgress/cancel", - param_type=WorkDoneProgressCancelParams, - ) + @rpc_method(name="window/workDoneProgress/cancel", param_type=WorkDoneProgressCancelParams) def _window_work_done_progress_cancel(self, token: ProgressToken, *args: Any, **kwargs: Any) -> None: if token in self.__progress_tokens: self.__progress_tokens[token] = True diff --git a/packages/language_server/src/robotcode/language_server/common/parts/workspace.py b/packages/language_server/src/robotcode/language_server/common/parts/workspace.py index 60efde5bb..ee8208d51 100644 --- a/packages/language_server/src/robotcode/language_server/common/parts/workspace.py +++ b/packages/language_server/src/robotcode/language_server/common/parts/workspace.py @@ -246,11 +246,7 @@ def settings(self, value: Dict[str, Any]) -> None: def did_change_configuration(sender, settings: Dict[str, Any]) -> None: # NOSONAR ... - @rpc_method( - name="workspace/didChangeConfiguration", - param_type=DidChangeConfigurationParams, - ) - @threaded + @rpc_method(name="workspace/didChangeConfiguration", param_type=DidChangeConfigurationParams) def _workspace_did_change_configuration(self, settings: Dict[str, Any], *args: Any, **kwargs: Any) -> None: self.settings = settings self._settings_cache.clear() @@ -280,8 +276,7 @@ def will_delete_files(sender, files: List[str]) -> None: # NOSONAR def did_delete_files(sender, files: List[str]) -> None: # NOSONAR ... - @rpc_method(name="workspace/willCreateFiles", param_type=CreateFilesParams) - @threaded + @rpc_method(name="workspace/willCreateFiles", param_type=CreateFilesParams, threaded=True) def _workspace_will_create_files( self, files: List[FileCreate], *args: Any, **kwargs: Any ) -> Optional[WorkspaceEdit]: @@ -303,27 +298,23 @@ def _workspace_will_create_files( def _workspace_did_create_files(self, files: List[FileCreate], *args: Any, **kwargs: Any) -> None: self.did_create_files(self, [f.uri for f in files]) - @rpc_method(name="workspace/willRenameFiles", param_type=RenameFilesParams) - @threaded + @rpc_method(name="workspace/willRenameFiles", param_type=RenameFilesParams, threaded=True) def _workspace_will_rename_files(self, files: List[FileRename], *args: Any, **kwargs: Any) -> None: self.will_rename_files(self, [(f.old_uri, f.new_uri) for f in files]) # TODO: return WorkspaceEdit - @rpc_method(name="workspace/didRenameFiles", param_type=RenameFilesParams) - @threaded + @rpc_method(name="workspace/didRenameFiles", param_type=RenameFilesParams, threaded=True) def _workspace_did_rename_files(self, files: List[FileRename], *args: Any, **kwargs: Any) -> None: self.did_rename_files(self, [(f.old_uri, f.new_uri) for f in files]) - @rpc_method(name="workspace/willDeleteFiles", param_type=DeleteFilesParams) - @threaded + @rpc_method(name="workspace/willDeleteFiles", param_type=DeleteFilesParams, threaded=True) def _workspace_will_delete_files(self, files: List[FileDelete], *args: Any, **kwargs: Any) -> None: self.will_delete_files(self, [f.uri for f in files]) # TODO: return WorkspaceEdit - @rpc_method(name="workspace/didDeleteFiles", param_type=DeleteFilesParams) - @threaded + @rpc_method(name="workspace/didDeleteFiles", param_type=DeleteFilesParams, threaded=True) def _workspace_did_delete_files(self, files: List[FileDelete], *args: Any, **kwargs: Any) -> None: self.did_delete_files(self, [f.uri for f in files]) @@ -433,11 +424,7 @@ def get_workspace_folder(self, uri: Union[Uri, str]) -> Optional[WorkspaceFolder return None - @rpc_method( - name="workspace/didChangeWorkspaceFolders", - param_type=DidChangeWorkspaceFoldersParams, - ) - @threaded + @rpc_method(name="workspace/didChangeWorkspaceFolders", param_type=DidChangeWorkspaceFoldersParams) def _workspace_did_change_workspace_folders( self, event: WorkspaceFoldersChangeEvent, *args: Any, **kwargs: Any ) -> None: @@ -459,15 +446,13 @@ def _workspace_did_change_workspace_folders( for a in event.added: self._workspace_folders.append(WorkspaceFolder(a.name, Uri(a.uri), a.uri)) + # TODO: do we need an event for this? + @event def did_change_watched_files(sender, changes: List[FileEvent]) -> None: # NOSONAR ... - @rpc_method( - name="workspace/didChangeWatchedFiles", - param_type=DidChangeWatchedFilesParams, - ) - @threaded + @rpc_method(name="workspace/didChangeWatchedFiles", param_type=DidChangeWatchedFilesParams) def _workspace_did_change_watched_files(self, changes: List[FileEvent], *args: Any, **kwargs: Any) -> None: changes = [e for e in changes if not e.uri.endswith("/globalStorage")] if changes: @@ -576,7 +561,9 @@ def remove_file_watcher_entry(self, entry: FileWatcherEntry) -> None: self.parent.unregister_capability(entry.id, "workspace/didChangeWatchedFiles") # TODO: implement own filewatcher if not supported by language server client - def apply_edit(self, edit: WorkspaceEdit, label: Optional[str] = None) -> ApplyWorkspaceEditResult: + def apply_edit( + self, edit: WorkspaceEdit, label: Optional[str] = None, timeout: Optional[float] = None + ) -> ApplyWorkspaceEditResult: if edit.changes: for uri, changes in edit.changes.items(): if changes: @@ -595,7 +582,7 @@ def apply_edit(self, edit: WorkspaceEdit, label: Optional[str] = None) -> ApplyW "workspace/applyEdit", ApplyWorkspaceEditParams(edit, label), return_type=ApplyWorkspaceEditResult, - ).result(30) + ).result(timeout) assert r is not None diff --git a/packages/language_server/src/robotcode/language_server/robotframework/parts/code_action_documentation.py b/packages/language_server/src/robotcode/language_server/robotframework/parts/code_action_documentation.py index f9331a404..97b935b45 100644 --- a/packages/language_server/src/robotcode/language_server/robotframework/parts/code_action_documentation.py +++ b/packages/language_server/src/robotcode/language_server/robotframework/parts/code_action_documentation.py @@ -19,7 +19,6 @@ from robot.parsing.lexer.tokens import Token -from robotcode.core.concurrent import threaded from robotcode.core.lsp.types import ( CodeAction, CodeActionContext, @@ -418,8 +417,7 @@ def build_url( return f"{base_url}/?&{params}{f'#{target}' if target else ''}" - @rpc_method(name="robot/documentationServer/convertUri", param_type=ConvertUriParams) - @threaded + @rpc_method(name="robot/documentationServer/convertUri", param_type=ConvertUriParams, threaded=True) def _convert_uri(self, uri: str, *args: Any, **kwargs: Any) -> Optional[str]: real_uri = Uri(uri) diff --git a/packages/language_server/src/robotcode/language_server/robotframework/parts/debugging_utils.py b/packages/language_server/src/robotcode/language_server/robotframework/parts/debugging_utils.py index 0e62b4641..7b6df37f9 100644 --- a/packages/language_server/src/robotcode/language_server/robotframework/parts/debugging_utils.py +++ b/packages/language_server/src/robotcode/language_server/robotframework/parts/debugging_utils.py @@ -5,7 +5,6 @@ from robot.parsing.model.statements import Statement -from robotcode.core.concurrent import threaded from robotcode.core.lsp.types import Position, Range, TextDocumentIdentifier from robotcode.core.utils.dataclasses import CamelSnakeMixin from robotcode.core.utils.logging import LoggingDescriptor @@ -41,11 +40,7 @@ class RobotDebuggingUtilsProtocolPart(RobotLanguageServerProtocolPart, ModelHelp def __init__(self, parent: RobotLanguageServerProtocol) -> None: super().__init__(parent) - @rpc_method( - name="robot/debugging/getEvaluatableExpression", - param_type=EvaluatableExpressionParams, - ) - @threaded + @rpc_method(name="robot/debugging/getEvaluatableExpression", param_type=EvaluatableExpressionParams, threaded=True) @_logger.call async def _get_evaluatable_expression( self, diff --git a/packages/language_server/src/robotcode/language_server/robotframework/parts/robot_workspace.py b/packages/language_server/src/robotcode/language_server/robotframework/parts/robot_workspace.py index a1df076bf..2b5efbd40 100644 --- a/packages/language_server/src/robotcode/language_server/robotframework/parts/robot_workspace.py +++ b/packages/language_server/src/robotcode/language_server/robotframework/parts/robot_workspace.py @@ -187,8 +187,7 @@ def _load_workspace_documents(self, sender: Any) -> List[WorkspaceDocumentsResul finally: self._logger.info(lambda: f"Workspace loaded {len(result)} documents in {time.monotonic() - start}s") - @rpc_method(name="robot/cache/clear") - @threaded + @rpc_method(name="robot/cache/clear", threaded=True) def robot_cache_clear(self) -> None: for folder in self.parent.workspace.workspace_folders: self.parent.documents_cache.get_imports_manager_for_workspace_folder(folder).clear_cache()