Skip to content

Commit 6d4d2cc

Browse files
committed
RPC methods can now be called threaded
1 parent 9d449db commit 6d4d2cc

22 files changed

+83
-55
lines changed

robotcode/language_server/common/parts/code_lens.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from typing import TYPE_CHECKING, Any, List, Optional
55

66
from ....jsonrpc2.protocol import rpc_method
7-
from ....utils.async_tools import async_tasking_event
7+
from ....utils.async_tools import async_tasking_event, threaded
88
from ....utils.logging import LoggingDescriptor
99
from ..decorators import language_id_filter
1010
from ..has_extend_capabilities import HasExtendCapabilities
@@ -43,6 +43,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None:
4343
capabilities.code_lens_provider = CodeLensOptions(resolve_provider=True if len(self.resolve) > 0 else None)
4444

4545
@rpc_method(name="textDocument/codeLens", param_type=CodeLensParams)
46+
@threaded()
4647
async def _text_document_code_lens(
4748
self, text_document: TextDocumentIdentifier, *args: Any, **kwargs: Any
4849
) -> Optional[List[CodeLens]]:
@@ -66,6 +67,7 @@ async def _text_document_code_lens(
6667
return None
6768

6869
@rpc_method(name="codeLens/resolve", param_type=CodeLens)
70+
@threaded()
6971
async def _code_lens_resolve(self, params: CodeLens, *args: Any, **kwargs: Any) -> CodeLens:
7072

7173
results: List[CodeLens] = []

robotcode/language_server/common/parts/completion.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from typing import TYPE_CHECKING, Any, List, Optional, Union, cast
66

77
from ....jsonrpc2.protocol import rpc_method
8-
from ....utils.async_tools import async_tasking_event
8+
from ....utils.async_tools import async_tasking_event, threaded
99
from ....utils.logging import LoggingDescriptor
1010
from ..decorators import (
1111
HasAllCommitCharacters,
@@ -79,6 +79,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None:
7979
)
8080

8181
@rpc_method(name="textDocument/completion", param_type=CompletionParams)
82+
@threaded()
8283
async def _text_document_completion(
8384
self,
8485
text_document: TextDocumentIdentifier,

robotcode/language_server/common/parts/declaration.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from typing import TYPE_CHECKING, Any, List, Optional, Union
55

66
from ....jsonrpc2.protocol import rpc_method
7-
from ....utils.async_tools import async_tasking_event
7+
from ....utils.async_tools import async_tasking_event, threaded
88
from ....utils.logging import LoggingDescriptor
99
from ..decorators import language_id_filter
1010
from ..has_extend_capabilities import HasExtendCapabilities
@@ -50,6 +50,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None:
5050
capabilities.declaration_provider = True
5151

5252
@rpc_method(name="textDocument/declaration", param_type=DeclarationParams)
53+
@threaded()
5354
async def _text_document_declaration(
5455
self, text_document: TextDocumentIdentifier, position: Position, *args: Any, **kwargs: Any
5556
) -> Optional[Union[Location, List[Location], List[LocationLink]]]:

robotcode/language_server/common/parts/definition.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from typing import TYPE_CHECKING, Any, List, Optional, Union
55

66
from ....jsonrpc2.protocol import rpc_method
7-
from ....utils.async_tools import async_tasking_event
7+
from ....utils.async_tools import async_tasking_event, threaded
88
from ....utils.logging import LoggingDescriptor
99
from ..decorators import language_id_filter
1010
from ..has_extend_capabilities import HasExtendCapabilities
@@ -50,6 +50,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None:
5050
capabilities.definition_provider = True
5151

5252
@rpc_method(name="textDocument/definition", param_type=DefinitionParams)
53+
@threaded()
5354
async def _text_document_definition(
5455
self, text_document: TextDocumentIdentifier, position: Position, *args: Any, **kwargs: Any
5556
) -> Optional[Union[Location, List[Location], List[LocationLink]]]:

robotcode/language_server/common/parts/diagnostics.py

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def __init__(self, protocol: LanguageServerProtocol) -> None:
9090
] = {}
9191

9292
self._current_workspace_task: Optional[asyncio.Task[WorkspaceDiagnosticReport]] = None
93-
self.in_get_document_diagnostics = Event(True)
93+
9494
self.in_get_workspace_diagnostics = Event(True)
9595
self._collect_full_diagnostics = False
9696

@@ -159,9 +159,9 @@ async def ensure_workspace_loaded(self) -> None:
159159
await self.on_workspace_loaded(self)
160160

161161
async def get_document_diagnostics(self, document: TextDocument) -> RelatedFullDocumentDiagnosticReport:
162-
if self.collect_full_diagnostics:
163-
return await document.get_cache(self.__get_full_document_diagnostics)
164-
return await document.get_cache(self.__get_document_diagnostics)
162+
# if self.collect_full_diagnostics:
163+
return await document.get_cache(self.__get_full_document_diagnostics)
164+
# return await document.get_cache(self.__get_document_diagnostics)
165165

166166
async def __get_document_diagnostics(self, document: TextDocument) -> RelatedFullDocumentDiagnosticReport:
167167
await self.ensure_workspace_loaded()
@@ -215,39 +215,34 @@ async def _text_document_diagnostic(
215215
) -> DocumentDiagnosticReport:
216216
self._logger.debug(lambda: f"textDocument/diagnostic for {text_document}")
217217

218-
self.in_get_document_diagnostics.clear()
219-
220218
try:
221-
await self.ensure_workspace_loaded()
219+
# await self.ensure_workspace_loaded()
222220

223221
document = await self.parent.documents.get(text_document.uri)
224222
if document is None:
225223
raise JsonRPCErrorException(ErrorCodes.INVALID_PARAMS, f"Document {text_document!r} not found")
226224

227-
async def _get_diagnostics() -> Optional[RelatedFullDocumentDiagnosticReport]:
225+
async def _get_diagnostics(doc: TextDocument) -> Optional[RelatedFullDocumentDiagnosticReport]:
228226
if document is not None:
229-
return await self.get_document_diagnostics(document)
227+
return await self.get_document_diagnostics(doc)
230228

231229
return None
232230

233231
if document in self._current_document_tasks and not self._current_document_tasks[document].done():
234232
self._logger.debug(lambda: f"textDocument/diagnostic cancel old task {text_document}")
235233
self._current_document_tasks[document].cancel()
236234

237-
task = create_sub_task(_get_diagnostics())
235+
task = create_sub_task(_get_diagnostics(document))
238236
self._current_document_tasks[document] = task
239237

240238
try:
241239
result = await task
242240
if result is None:
243241
raise RuntimeError("Unexpected result.")
244242

245-
except asyncio.CancelledError as e:
243+
except asyncio.CancelledError:
246244
self._logger.debug(lambda: f"textDocument/diagnostic canceled {text_document}")
247-
248-
raise JsonRPCErrorException(
249-
ErrorCodes.SERVER_CANCELLED, "Cancelled", data=DiagnosticServerCancellationData(True)
250-
) from e
245+
raise
251246
finally:
252247
if document in self._current_document_tasks and self._current_document_tasks[document] == task:
253248
del self._current_document_tasks[document]
@@ -257,7 +252,7 @@ async def _get_diagnostics() -> Optional[RelatedFullDocumentDiagnosticReport]:
257252

258253
return result
259254
finally:
260-
self.in_get_document_diagnostics.set()
255+
261256
await self.on_document_diagnostics_ended(self)
262257

263258
self._logger.debug(lambda: f"textDocument/diagnostic ready {text_document}")
@@ -279,6 +274,13 @@ async def _get_diagnostics() -> WorkspaceDiagnosticReport:
279274
result: List[WorkspaceDocumentDiagnosticReport] = []
280275

281276
for doc in self.parent.documents.documents:
277+
if self._current_workspace_task is None:
278+
raise JsonRPCErrorException(
279+
ErrorCodes.SERVER_CANCELLED,
280+
"ServerCancelled",
281+
data=DiagnosticServerCancellationData(True),
282+
)
283+
282284
doc_result = await self.get_document_diagnostics(doc)
283285

284286
if doc_result.result_id is not None and any(
@@ -305,7 +307,6 @@ async def _get_partial_diagnostics() -> WorkspaceDiagnosticReport:
305307
) as progress:
306308

307309
async def _task(doc: TextDocument) -> None:
308-
309310
if await self.get_analysis_progress_mode(doc.uri) == AnalysisProgressMode.DETAILED:
310311
path = doc.uri.to_path()
311312
folder = self.parent.workspace.get_workspace_folder(doc.uri)
@@ -346,7 +347,14 @@ async def _task(doc: TextDocument) -> None:
346347
)
347348

348349
for doc in self.parent.documents.documents:
349-
await _task(doc)
350+
if await self.get_diagnostics_mode(doc.uri) == DiagnosticsMode.WORKSPACE:
351+
await _task(doc)
352+
if self._current_workspace_task is None:
353+
raise JsonRPCErrorException(
354+
ErrorCodes.SERVER_CANCELLED,
355+
"ServerCancelled",
356+
data=DiagnosticServerCancellationData(True),
357+
)
350358

351359
return WorkspaceDiagnosticReport(items=[])
352360

@@ -363,11 +371,9 @@ async def _task(doc: TextDocument) -> None:
363371
result = await task
364372
await self.set_collect_full_diagnostics(True)
365373
return result
366-
except asyncio.CancelledError as e:
374+
except asyncio.CancelledError:
367375
self._logger.debug("workspace/diagnostic canceled")
368-
raise JsonRPCErrorException(
369-
ErrorCodes.SERVER_CANCELLED, "ServerCancelled", data=DiagnosticServerCancellationData(True)
370-
) from e
376+
raise
371377
finally:
372378
if self._current_workspace_task == task:
373379
self._current_workspace_task = None
@@ -376,15 +382,17 @@ async def _task(doc: TextDocument) -> None:
376382
self.in_get_workspace_diagnostics.set()
377383
await self.on_workspace_diagnostics_ended(self)
378384

379-
def cancel_workspace_diagnostics(self) -> None:
385+
async def cancel_workspace_diagnostics(self) -> None:
380386
if self._current_workspace_task is not None and not self._current_workspace_task.done():
381-
self._current_workspace_task.cancel()
387+
task = self._current_workspace_task
388+
self._current_workspace_task = None
389+
task.get_loop().call_soon_threadsafe(task.cancel)
382390

383-
def cancel_document_diagnostics(self, document: TextDocument) -> None:
391+
async def cancel_document_diagnostics(self, document: TextDocument) -> None:
384392
task = self._current_document_tasks.get(document, None)
385393
if task is not None:
386394
self._logger.critical(lambda: f"textDocument/diagnostic canceled {document}")
387-
task.cancel()
395+
task.get_loop().call_soon_threadsafe(task.cancel)
388396

389397
async def get_analysis_progress_mode(self, uri: Uri) -> AnalysisProgressMode:
390398
for e in await self.on_get_analysis_progress_mode(self, uri):

robotcode/language_server/common/parts/document_highlight.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from typing import TYPE_CHECKING, Any, List, Optional
55

66
from ....jsonrpc2.protocol import rpc_method
7-
from ....utils.async_tools import async_tasking_event
7+
from ....utils.async_tools import async_tasking_event, threaded
88
from ....utils.logging import LoggingDescriptor
99
from ..decorators import language_id_filter
1010
from ..has_extend_capabilities import HasExtendCapabilities
@@ -42,6 +42,7 @@ async def collect(
4242
...
4343

4444
@rpc_method(name="textDocument/documentHighlight", param_type=DocumentHighlightParams)
45+
@threaded()
4546
async def _text_document_document_highlight(
4647
self,
4748
text_document: TextDocumentIdentifier,

robotcode/language_server/common/parts/document_symbols.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
)
1616

1717
from ....jsonrpc2.protocol import rpc_method
18-
from ....utils.async_tools import async_tasking_event
18+
from ....utils.async_tools import async_tasking_event, threaded
1919
from ....utils.logging import LoggingDescriptor
2020
from ..decorators import language_id_filter
2121
from ..has_extend_capabilities import HasExtendCapabilities
@@ -98,6 +98,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None:
9898
capabilities.document_symbol_provider = True
9999

100100
@rpc_method(name="textDocument/documentSymbol", param_type=DocumentSymbolParams)
101+
@threaded()
101102
async def _text_document_symbol(
102103
self, text_document: TextDocumentIdentifier, *args: Any, **kwargs: Any
103104
) -> Optional[Union[List[DocumentSymbol], List[SymbolInformation], None]]:

robotcode/language_server/common/parts/documents.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ async def _text_document_did_change(
354354
*args: Any,
355355
**kwargs: Any,
356356
) -> None:
357-
document = await self.get(str(Uri(text_document.uri).normalized()))
357+
document = self.get_sync(str(Uri(text_document.uri).normalized()))
358358
if document is None:
359359
raise LanguageServerDocumentException(f"Document {text_document.uri} is not opened.")
360360

robotcode/language_server/common/parts/folding_range.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from typing import TYPE_CHECKING, Any, List, Optional
55

66
from ....jsonrpc2.protocol import rpc_method
7-
from ....utils.async_tools import async_tasking_event
7+
from ....utils.async_tools import async_tasking_event, threaded
88
from ....utils.logging import LoggingDescriptor
99
from ..decorators import language_id_filter
1010
from ..has_extend_capabilities import HasExtendCapabilities
@@ -38,6 +38,7 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None:
3838
capabilities.folding_range_provider = True
3939

4040
@rpc_method(name="textDocument/foldingRange", param_type=FoldingRangeParams)
41+
@threaded()
4142
async def _text_document_folding_range(
4243
self, text_document: TextDocumentIdentifier, *args: Any, **kwargs: Any
4344
) -> Optional[List[FoldingRange]]:

robotcode/language_server/common/parts/formatting.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from typing import TYPE_CHECKING, Any, List, Optional
55

66
from ....jsonrpc2.protocol import rpc_method
7-
from ....utils.async_tools import async_tasking_event
7+
from ....utils.async_tools import async_tasking_event, threaded
88
from ....utils.logging import LoggingDescriptor
99
from ..decorators import language_id_filter
1010
from ..has_extend_capabilities import HasExtendCapabilities
@@ -90,6 +90,7 @@ async def _text_document_formatting(
9090
return None
9191

9292
@rpc_method(name="textDocument/rangeFormatting", param_type=DocumentRangeFormattingParams)
93+
@threaded()
9394
async def _text_document_range_formatting(
9495
self,
9596
params: DocumentFormattingParams,

0 commit comments

Comments
 (0)