Skip to content

Commit 2fd1b39

Browse files
committed
add callback_filter to async_event, watch files for changes if files are not opened from editor
1 parent 9019b9e commit 2fd1b39

File tree

10 files changed

+105
-35
lines changed

10 files changed

+105
-35
lines changed

log.ini

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[loggers]
22
#keys: root,server,language_server,language_server_parts,jsonrpc2,jsonrpc2_message,robotframework,debugger, debugger_launcher, asyncio
3-
keys: root,robotframework,language_server,language_server_parts
3+
keys: root,server,language_server,language_server_parts,robotframework,debugger, debugger_launcher, asyncio
4+
#keys: root,server,robotframework,language_server,language_server_parts
45

56
[formatters]
67
keys: detailed,simple,colored_simple

robotcode/language_server/common/parts/diagnostics.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from ....utils.async_event import async_tasking_event_iterator
99
from ....utils.logging import LoggingDescriptor
1010
from ....utils.uri import Uri
11-
from ..language import HasLanguageId
11+
from ..language import HasLanguageId, language_id
1212
from ..lsp_types import Diagnostic, DocumentUri, PublishDiagnosticsParams
1313
from ..text_document import TextDocument
1414

@@ -141,14 +141,17 @@ def _cancel_entry(self, entry: Optional[PublishDiagnosticsEntry]) -> None:
141141

142142
entry.cancel()
143143

144+
@language_id("robotframework")
144145
@_logger.call
145146
async def on_did_open(self, sender: Any, document: TextDocument) -> None:
146147
await self.start_publish_diagnostics_task(document)
147148

149+
@language_id("robotframework")
148150
@_logger.call
149151
async def on_did_save(self, sender: Any, document: TextDocument) -> None:
150152
await self.start_publish_diagnostics_task(document)
151153

154+
@language_id("robotframework")
152155
@_logger.call
153156
async def on_did_close(self, sender: Any, document: TextDocument) -> None:
154157
async with self._task_lock:

robotcode/language_server/common/parts/documents.py

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from ....utils.async_event import async_event
88
from ....utils.logging import LoggingDescriptor
99
from ....utils.uri import Uri
10+
from ..language import HasLanguageId
1011
from ..lsp_types import (
1112
DidChangeTextDocumentParams,
1213
DidCloseTextDocumentParams,
@@ -56,17 +57,20 @@ async def _protocol_initialized(self, sender: Any) -> None:
5657
async def _update_filewatchers(self) -> None:
5758
await self.parent.workspace.add_file_watcher(self._file_watcher, "**/*", WatchKind.CHANGE | WatchKind.DELETE)
5859

59-
@_logger.call
6060
async def _file_watcher(self, sender: Any, changes: List[FileEvent]) -> None:
61-
self._logger.debug(f"filewatcher {changes}")
6261
to_change: Dict[str, FileEvent] = {}
6362
for change in changes:
6463
to_change[change.uri] = change
6564

6665
for change in to_change.values():
6766
document = self._documents.get(DocumentUri(Uri(change.uri).normalized()), None)
6867
if document is not None and not document.opened_in_editor:
69-
await self.did_close(self, document)
68+
await self.did_close(
69+
self,
70+
document,
71+
callback_filter=lambda c: not isinstance(c, HasLanguageId)
72+
or c.__language_id__ == document.language_id,
73+
)
7074
await self.close_document(document, True)
7175

7276
@async_event
@@ -142,7 +146,11 @@ async def _text_document_did_open(self, text_document: TextDocumentItem, *args:
142146
document.opened_in_editor = True
143147
document.references.add(self)
144148

145-
await self.did_open(self, document)
149+
await self.did_open(
150+
self,
151+
document,
152+
callback_filter=lambda c: not isinstance(c, HasLanguageId) or c.__language_id__ == document.language_id,
153+
)
146154

147155
@rpc_method(name="textDocument/didClose", param_type=DidCloseTextDocumentParams)
148156
@_logger.call
@@ -153,7 +161,11 @@ async def _text_document_did_close(self, text_document: TextDocumentIdentifier,
153161
if document is not None:
154162
document.references.remove(self)
155163
document.opened_in_editor = False
156-
await self.did_close(self, document)
164+
await self.did_close(
165+
self,
166+
document,
167+
callback_filter=lambda c: not isinstance(c, HasLanguageId) or c.__language_id__ == document.language_id,
168+
)
157169
await self.close_document(document)
158170

159171
@_logger.call
@@ -186,7 +198,11 @@ async def _text_document_did_save(
186198
if document is not None and text is not None:
187199
await document.apply_full_change(None, text)
188200

189-
await self.did_save(self, document)
201+
await self.did_save(
202+
self,
203+
document,
204+
callback_filter=lambda c: not isinstance(c, HasLanguageId) or c.__language_id__ == document.language_id,
205+
)
190206

191207
@rpc_method(name="textDocument/willSaveWaitUntil", param_type=WillSaveTextDocumentParams)
192208
@_logger.call
@@ -236,4 +252,8 @@ async def _text_document_did_change(
236252
f"for document {text_document.uri}."
237253
)
238254

239-
await self.did_change(self, document)
255+
await self.did_change(
256+
self,
257+
document,
258+
callback_filter=lambda c: not isinstance(c, HasLanguageId) or c.__language_id__ == document.language_id,
259+
)

robotcode/language_server/common/parts/workspace.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,9 +355,10 @@ async def did_change_watched_files(sender, changes: List[FileEvent]) -> None:
355355
...
356356

357357
@rpc_method(name="workspace/didChangeWatchedFiles", param_type=DidChangeWatchedFilesParams)
358-
@_logger.call
359358
async def _workspace_did_change_watched_files(self, changes: List[FileEvent], *args: Any, **kwargs: Any) -> None:
360-
await self.did_change_watched_files(self, changes)
359+
changes = [e for e in changes if not e.uri.endswith("/globalStorage")]
360+
if changes:
361+
await self.did_change_watched_files(self, changes)
361362

362363
async def add_file_watcher(
363364
self,

robotcode/language_server/robotframework/diagnostics/imports_manager.py

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from ....utils.logging import LoggingDescriptor
1414
from ....utils.path import path_is_relative_to
1515
from ....utils.uri import Uri
16+
from ...common.language import language_id
1617
from ...common.lsp_types import FileChangeType, FileEvent
1718
from ...common.parts.workspace import FileWatcherEntry
1819
from ...common.text_document import TextDocument
@@ -197,13 +198,14 @@ async def is_valid(self) -> bool:
197198
return self._lib_doc is not None
198199

199200
async def get_libdoc(self) -> LibraryDoc:
200-
async with self._lock:
201-
if self._lib_doc is None:
202-
await self._update()
201+
if self._lib_doc is None:
202+
async with self._lock:
203+
if self._lib_doc is None:
204+
await self._update()
203205

204-
assert self._lib_doc is not None
206+
assert self._lib_doc is not None
205207

206-
return self._lib_doc
208+
return self._lib_doc
207209

208210

209211
@dataclass()
@@ -230,6 +232,7 @@ def __init__(
230232
self._document: Optional[TextDocument] = None
231233
self._lock = asyncio.Lock()
232234
self._loop = asyncio.get_event_loop()
235+
self._lib_doc: Optional[LibraryDoc] = None
233236

234237
def __del__(self) -> None:
235238
if self._loop.is_running():
@@ -296,6 +299,7 @@ async def _invalidate(self) -> None:
296299
await self._remove_file_watcher()
297300

298301
self._document = None
302+
self._lib_doc = None
299303

300304
async def _remove_file_watcher(self) -> None:
301305
if self.file_watchers is not None:
@@ -308,21 +312,28 @@ async def is_valid(self) -> bool:
308312
return self._document is not None
309313

310314
async def get_document(self) -> TextDocument:
311-
async with self._lock:
312-
if self._document is None:
313-
await self._update()
315+
if self._document is None:
316+
async with self._lock:
317+
if self._document is None:
318+
await self._update()
314319

315-
assert self._document is not None
320+
assert self._document is not None
316321

317-
return self._document
322+
return self._document
318323

319324
async def get_namespace(self) -> Namespace:
320325
return await self.parent.parent_protocol.documents_cache.get_resource_namespace(await self.get_document())
321326

322327
async def get_libdoc(self) -> LibraryDoc:
323-
return await (
324-
await self.parent.parent_protocol.documents_cache.get_resource_namespace(await self.get_document())
325-
).get_library_doc()
328+
if self._lib_doc is None:
329+
async with self._lock:
330+
if self._lib_doc is None:
331+
self._lib_doc = await (
332+
await self.parent.parent_protocol.documents_cache.get_resource_namespace(
333+
await self.get_document()
334+
)
335+
).get_library_doc()
336+
return self._lib_doc
326337

327338

328339
def _shutdown_process_pool(pool: ProcessPoolExecutor) -> None:
@@ -375,6 +386,7 @@ async def libraries_changed(sender, libraries: List[LibraryDoc]) -> None:
375386
async def resources_changed(sender, resources: List[LibraryDoc]) -> None:
376387
...
377388

389+
@language_id("robotframework")
378390
async def resource_document_changed(self, sender: Any, document: TextDocument) -> None:
379391
resource_changed: List[LibraryDoc] = []
380392

robotcode/language_server/robotframework/diagnostics/namespace.py

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,7 @@ async def get(self, model: ast.AST, namespace: Namespace) -> List[Diagnostic]:
478478
self._namespace = namespace
479479

480480
self.current_testcase_or_keyword_name: Optional[str] = None
481+
self.finder = KeywordFinder(self._namespace)
481482

482483
await self.visit(model)
483484
return self._results
@@ -492,11 +493,9 @@ async def _analyze_keyword_call(
492493
) -> Optional[KeywordDoc]:
493494
result: Optional[KeywordDoc] = None
494495
try:
495-
finder = KeywordFinder(self._namespace)
496+
result = await self.finder.find_keyword(keyword)
496497

497-
result = await finder.find_keyword(keyword)
498-
499-
for e in finder.diagnostics:
498+
for e in self.finder.diagnostics:
500499
self._results.append(
501500
Diagnostic(
502501
range=range_from_token_or_node(value, keyword_token),
@@ -926,6 +925,7 @@ def __init__(
926925
def document(self) -> Optional[TextDocument]:
927926
return self._document() if self._document is not None else None
928927

928+
@_logger.call
929929
async def libraries_changed(self, sender: Any, libraries: List[LibraryDoc]) -> None:
930930
for p in libraries:
931931
if any(e for e in self._libraries.values() if e.library_doc == p):
@@ -934,6 +934,7 @@ async def libraries_changed(self, sender: Any, libraries: List[LibraryDoc]) -> N
934934
self.invalidated_callback(self)
935935
break
936936

937+
@_logger.call
937938
async def resources_changed(self, sender: Any, resources: List[LibraryDoc]) -> None:
938939
for p in resources:
939940
if any(e for e in self._resources.values() if e.library_doc.source == p.source):
@@ -956,6 +957,7 @@ async def get_libraries(self) -> OrderedDict[str, LibraryEntry]:
956957

957958
return self._libraries
958959

960+
@_logger.call
959961
async def get_libraries_matchers(self) -> Dict[KeywordMatcher, LibraryEntry]:
960962
if self._libraries_matchers is None:
961963
self._libraries_matchers = {
@@ -969,13 +971,15 @@ async def get_resources(self) -> OrderedDict[str, ResourceEntry]:
969971

970972
return self._resources
971973

974+
@_logger.call
972975
async def get_resources_matchers(self) -> Dict[KeywordMatcher, ResourceEntry]:
973976
if self._resources_matchers is None:
974977
self._resources_matchers = {
975978
KeywordMatcher(v.alias or v.name or v.import_name): v for v in (await self.get_resources()).values()
976979
}
977980
return self._resources_matchers
978981

982+
@_logger.call
979983
async def get_library_doc(self) -> LibraryDoc:
980984
if self._library_doc is None:
981985
async with self._library_doc_lock:
@@ -1049,12 +1053,14 @@ async def ensure_initialized(self) -> bool:
10491053
def initialized(self) -> bool:
10501054
return self._initialized
10511055

1056+
@_logger.call
10521057
async def get_imports(self) -> List[Import]:
10531058
if self._imports is None:
10541059
self._imports = await ImportVisitor().get(self.source, self.model)
10551060

10561061
return self._imports
10571062

1063+
@_logger.call
10581064
async def get_own_variables(self) -> List[VariableDefinition]:
10591065
if self._own_variables is None:
10601066
self._own_variables = await VariablesVisitor().get(self.source, self.model)
@@ -1070,6 +1076,7 @@ def get_builtin_variables(cls) -> List[BuiltInVariableDefinition]:
10701076

10711077
return cls._builtin_variables
10721078

1079+
@_logger.call
10731080
def get_command_line_variables(self) -> List[VariableDefinition]:
10741081
if self.imports_manager.config is None:
10751082
return []
@@ -1079,6 +1086,7 @@ def get_command_line_variables(self) -> List[VariableDefinition]:
10791086
for k in self.imports_manager.config.variables.keys()
10801087
]
10811088

1089+
@_logger.call
10821090
async def get_variables(
10831091
self, nodes: Optional[List[ast.AST]] = None, position: Optional[Position] = None
10841092
) -> Dict[VariableMatcher, VariableDefinition]:
@@ -1104,11 +1112,13 @@ async def get_variables(
11041112

11051113
return result
11061114

1115+
@_logger.call
11071116
async def find_variable(
11081117
self, name: str, nodes: Optional[List[ast.AST]], position: Optional[Position] = None
11091118
) -> Optional[VariableDefinition]:
11101119
return (await self.get_variables(nodes, position)).get(VariableMatcher(name), None)
11111120

1121+
@_logger.call
11121122
async def _import_imports(self, imports: Iterable[Import], base_dir: str, *, top_level: bool = False) -> None:
11131123
async def _import(value: Import) -> Optional[LibraryEntry]:
11141124
result: Optional[LibraryEntry] = None
@@ -1396,6 +1406,7 @@ async def _import_lib(library: str) -> Optional[LibraryEntry]:
13961406
if e is not None:
13971407
self._libraries[e.alias or e.name or e.import_name] = e
13981408

1409+
@_logger.call
13991410
async def _get_library_entry(
14001411
self,
14011412
name: str,
@@ -1412,6 +1423,7 @@ async def _get_library_entry(
14121423

14131424
return LibraryEntry(name=library.name, import_name=name, library_doc=library, args=args, alias=alias)
14141425

1426+
@_logger.call
14151427
async def _get_resource_entry(self, name: str, base_dir: str, sentinel: Any = None) -> ResourceEntry:
14161428
namespace = await self.imports_manager.get_namespace_for_resource_import(name, base_dir, sentinel=sentinel)
14171429
library_doc = await self.imports_manager.get_libdoc_for_resource_import(name, base_dir, sentinel=sentinel)
@@ -1451,6 +1463,9 @@ async def _analyze(self) -> None:
14511463
async with self._analyze_lock:
14521464
if not self._analyzed:
14531465
try:
1466+
# self._diagnostics += await asyncio.get_running_loop().run_in_executor(
1467+
# None, asyncio.run, Analyzer().get(self.model, self)
1468+
# )
14541469
self._diagnostics += await Analyzer().get(self.model, self)
14551470

14561471
lib_doc = await self.get_library_doc()
@@ -1478,6 +1493,7 @@ async def _analyze(self) -> None:
14781493
finally:
14791494
self._analyzed = True
14801495

1496+
@_logger.call
14811497
async def find_keyword(self, name: Optional[str]) -> Optional[KeywordDoc]:
14821498
await self.ensure_initialized()
14831499

@@ -1499,9 +1515,15 @@ def __init__(self, namespace: Namespace) -> None:
14991515
super().__init__()
15001516
self.namespace = namespace
15011517
self.diagnostics: List[DiagnosticsEntry] = []
1518+
self.self_library_doc: Optional[LibraryDoc] = None
1519+
1520+
def reset_diagnostics(self) -> None:
1521+
self.diagnostics = []
15021522

15031523
async def find_keyword(self, name: Optional[str]) -> Optional[KeywordDoc]:
15041524
try:
1525+
self.reset_diagnostics()
1526+
15051527
result = await self._find_keyword(name)
15061528
if result is None:
15071529
self.diagnostics.append(
@@ -1539,7 +1561,9 @@ async def _find_keyword(self, name: Optional[str]) -> Optional[KeywordDoc]:
15391561
return result
15401562

15411563
async def _get_keyword_from_self(self, name: str) -> Optional[KeywordDoc]:
1542-
return (await self.namespace.get_library_doc()).keywords.get(name, None)
1564+
if self.self_library_doc is None:
1565+
self.self_library_doc = await self.namespace.get_library_doc()
1566+
return self.self_library_doc.keywords.get(name, None)
15431567

15441568
async def _yield_owner_and_kw_names(self, full_name: str) -> AsyncIterator[Tuple[str, ...]]:
15451569
tokens = full_name.split(".")

robotcode/language_server/robotframework/parts/diagnostics.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def __init__(self, parent: RobotLanguageServerProtocol) -> None:
3333
parent.documents.did_open.add(self.namespace_invalidated)
3434
parent.documents_cache.namespace_invalidated.add(self.namespace_invalidated)
3535

36+
@language_id("robotframework")
3637
async def namespace_invalidated(self, sender: Any, document: TextDocument) -> None:
3738
await self.parent.diagnostics.start_publish_diagnostics_task(document)
3839

0 commit comments

Comments
 (0)