robotcode-robot 0.68.2__py3-none-any.whl → 0.68.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- robotcode/robot/__version__.py +1 -1
- robotcode/robot/config/model.py +63 -51
- robotcode/robot/diagnostics/document_cache_helper.py +523 -0
- robotcode/robot/diagnostics/entities.py +2 -1
- robotcode/robot/diagnostics/errors.py +33 -0
- robotcode/robot/diagnostics/imports_manager.py +1499 -0
- robotcode/robot/diagnostics/library_doc.py +3 -2
- robotcode/robot/diagnostics/model_helper.py +799 -0
- robotcode/robot/diagnostics/namespace.py +2165 -0
- robotcode/robot/diagnostics/namespace_analyzer.py +1121 -0
- robotcode/robot/diagnostics/workspace_config.py +50 -0
- robotcode/robot/utils/ast.py +6 -5
- robotcode/robot/utils/stubs.py +17 -1
- {robotcode_robot-0.68.2.dist-info → robotcode_robot-0.68.5.dist-info}/METADATA +2 -2
- robotcode_robot-0.68.5.dist-info/RECORD +29 -0
- robotcode_robot-0.68.2.dist-info/RECORD +0 -22
- {robotcode_robot-0.68.2.dist-info → robotcode_robot-0.68.5.dist-info}/WHEEL +0 -0
- {robotcode_robot-0.68.2.dist-info → robotcode_robot-0.68.5.dist-info}/licenses/LICENSE.txt +0 -0
@@ -0,0 +1,523 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import ast
|
4
|
+
import io
|
5
|
+
import threading
|
6
|
+
import weakref
|
7
|
+
from logging import CRITICAL
|
8
|
+
from pathlib import Path
|
9
|
+
from typing import (
|
10
|
+
Any,
|
11
|
+
Callable,
|
12
|
+
Iterable,
|
13
|
+
Iterator,
|
14
|
+
List,
|
15
|
+
Optional,
|
16
|
+
Tuple,
|
17
|
+
Union,
|
18
|
+
cast,
|
19
|
+
)
|
20
|
+
|
21
|
+
from robot.parsing.lexer.tokens import Token
|
22
|
+
from robotcode.core.documents_manager import DocumentsManager
|
23
|
+
from robotcode.core.event import event
|
24
|
+
from robotcode.core.filewatcher import FileWatcherManagerBase
|
25
|
+
from robotcode.core.language import language_id_filter
|
26
|
+
from robotcode.core.text_document import TextDocument
|
27
|
+
from robotcode.core.uri import Uri
|
28
|
+
from robotcode.core.utils.logging import LoggingDescriptor
|
29
|
+
from robotcode.core.workspace import Workspace, WorkspaceFolder
|
30
|
+
|
31
|
+
from ..config.model import RobotBaseProfile
|
32
|
+
from ..utils import get_robot_version
|
33
|
+
from ..utils.stubs import Languages
|
34
|
+
from .imports_manager import ImportsManager
|
35
|
+
from .namespace import DocumentType, Namespace
|
36
|
+
from .workspace_config import CacheConfig, RobotConfig
|
37
|
+
|
38
|
+
|
39
|
+
class UnknownFileTypeError(Exception):
|
40
|
+
pass
|
41
|
+
|
42
|
+
|
43
|
+
class DocumentsCacheHelper:
|
44
|
+
_logger = LoggingDescriptor()
|
45
|
+
|
46
|
+
def __init__(
|
47
|
+
self,
|
48
|
+
workspace: Workspace,
|
49
|
+
documents_manager: DocumentsManager,
|
50
|
+
file_watcher_manager: FileWatcherManagerBase,
|
51
|
+
robot_profile: Optional[RobotBaseProfile],
|
52
|
+
) -> None:
|
53
|
+
self.workspace = workspace
|
54
|
+
self.documents_manager = documents_manager
|
55
|
+
self.file_watcher_manager = file_watcher_manager
|
56
|
+
|
57
|
+
self.robot_profile = robot_profile or RobotBaseProfile()
|
58
|
+
|
59
|
+
self._imports_managers_lock = threading.RLock()
|
60
|
+
self._imports_managers: weakref.WeakKeyDictionary[WorkspaceFolder, ImportsManager] = weakref.WeakKeyDictionary()
|
61
|
+
self._default_imports_manager: Optional[ImportsManager] = None
|
62
|
+
self._workspace_languages: weakref.WeakKeyDictionary[
|
63
|
+
WorkspaceFolder, Optional[Languages]
|
64
|
+
] = weakref.WeakKeyDictionary()
|
65
|
+
|
66
|
+
def get_languages_for_document(self, document_or_uri: Union[TextDocument, Uri, str]) -> Optional[Languages]:
|
67
|
+
if get_robot_version() < (6, 0):
|
68
|
+
return None
|
69
|
+
|
70
|
+
from robot.conf.languages import (
|
71
|
+
Languages as RobotLanguages,
|
72
|
+
)
|
73
|
+
|
74
|
+
uri: Union[Uri, str]
|
75
|
+
|
76
|
+
if isinstance(document_or_uri, TextDocument):
|
77
|
+
uri = document_or_uri.uri
|
78
|
+
else:
|
79
|
+
uri = document_or_uri
|
80
|
+
|
81
|
+
folder = self.workspace.get_workspace_folder(uri)
|
82
|
+
|
83
|
+
if folder is None:
|
84
|
+
return None
|
85
|
+
|
86
|
+
if folder in self._workspace_languages:
|
87
|
+
return self._workspace_languages[folder]
|
88
|
+
|
89
|
+
self._logger.debug(lambda: f"Get language config for {uri} in workspace {folder.uri}")
|
90
|
+
config = self.workspace.get_configuration(RobotConfig, folder.uri)
|
91
|
+
|
92
|
+
languages = [str(v) for v in self.robot_profile.languages or []]
|
93
|
+
languages += config.languages or []
|
94
|
+
|
95
|
+
if not languages:
|
96
|
+
self._workspace_languages[folder] = None
|
97
|
+
return None
|
98
|
+
|
99
|
+
result = RobotLanguages()
|
100
|
+
for lang in languages:
|
101
|
+
try:
|
102
|
+
result.add_language(lang)
|
103
|
+
except ValueError as e:
|
104
|
+
ex = e
|
105
|
+
self._logger.exception(
|
106
|
+
lambda: f"Language configuration is not valid: {ex}"
|
107
|
+
"\nPlease check your 'robotcode.robot.language' configuration.",
|
108
|
+
exc_info=ex,
|
109
|
+
level=CRITICAL,
|
110
|
+
)
|
111
|
+
|
112
|
+
self._workspace_languages[folder] = result
|
113
|
+
|
114
|
+
return cast(Languages, RobotLanguages(result.languages))
|
115
|
+
|
116
|
+
def build_languages_from_model(
|
117
|
+
self, document: TextDocument, model: ast.AST
|
118
|
+
) -> Tuple[Optional[Languages], Optional[Languages]]:
|
119
|
+
if get_robot_version() < (6, 0):
|
120
|
+
return (None, None)
|
121
|
+
|
122
|
+
from robot.conf.languages import (
|
123
|
+
Languages as RobotLanguages,
|
124
|
+
)
|
125
|
+
|
126
|
+
# pyright: ignore[reportMissingImports]
|
127
|
+
from robot.parsing.model.blocks import File
|
128
|
+
|
129
|
+
workspace_langs = self.get_languages_for_document(document)
|
130
|
+
|
131
|
+
return (
|
132
|
+
cast(
|
133
|
+
Languages,
|
134
|
+
RobotLanguages(
|
135
|
+
[
|
136
|
+
*(workspace_langs.languages if workspace_langs else []),
|
137
|
+
*(model.languages if isinstance(model, File) else []),
|
138
|
+
]
|
139
|
+
),
|
140
|
+
),
|
141
|
+
workspace_langs,
|
142
|
+
)
|
143
|
+
|
144
|
+
def get_document_type(self, document: TextDocument) -> DocumentType:
|
145
|
+
return document.get_cache(self.__get_document_type)
|
146
|
+
|
147
|
+
def __get_document_type(self, document: TextDocument) -> DocumentType:
|
148
|
+
path = document.uri.to_path()
|
149
|
+
suffix = path.suffix.lower()
|
150
|
+
|
151
|
+
if path.name == "__init__.robot":
|
152
|
+
return DocumentType.INIT
|
153
|
+
if suffix == ".robot":
|
154
|
+
return DocumentType.GENERAL
|
155
|
+
if suffix == ".resource":
|
156
|
+
return DocumentType.RESOURCE
|
157
|
+
|
158
|
+
return DocumentType.UNKNOWN
|
159
|
+
|
160
|
+
def get_tokens(self, document: TextDocument, data_only: bool = False) -> List[Token]:
|
161
|
+
if data_only:
|
162
|
+
return document.get_cache(self.__get_tokens_data_only)
|
163
|
+
return document.get_cache(self.__get_tokens)
|
164
|
+
|
165
|
+
def __get_tokens_data_only(self, document: TextDocument) -> List[Token]:
|
166
|
+
document_type = self.get_document_type(document)
|
167
|
+
if document_type == DocumentType.INIT:
|
168
|
+
return self.get_init_tokens(document, True)
|
169
|
+
if document_type == DocumentType.GENERAL:
|
170
|
+
return self.get_general_tokens(document, True)
|
171
|
+
if document_type == DocumentType.RESOURCE:
|
172
|
+
return self.get_resource_tokens(document, True)
|
173
|
+
|
174
|
+
raise UnknownFileTypeError(str(document.uri))
|
175
|
+
|
176
|
+
def __get_tokens(self, document: TextDocument) -> List[Token]:
|
177
|
+
document_type = self.get_document_type(document)
|
178
|
+
if document_type == DocumentType.INIT:
|
179
|
+
return self.get_init_tokens(document)
|
180
|
+
if document_type == DocumentType.GENERAL:
|
181
|
+
return self.get_general_tokens(document)
|
182
|
+
if document_type == DocumentType.RESOURCE:
|
183
|
+
return self.get_resource_tokens(document)
|
184
|
+
|
185
|
+
raise UnknownFileTypeError(str(document.uri))
|
186
|
+
|
187
|
+
def get_general_tokens(self, document: TextDocument, data_only: bool = False) -> List[Token]:
|
188
|
+
if data_only:
|
189
|
+
return document.get_cache(self.__get_general_tokens_data_only)
|
190
|
+
return document.get_cache(self.__get_general_tokens)
|
191
|
+
|
192
|
+
def __internal_get_tokens(
|
193
|
+
self,
|
194
|
+
source: Any,
|
195
|
+
data_only: bool = False,
|
196
|
+
tokenize_variables: bool = False,
|
197
|
+
lang: Any = None,
|
198
|
+
) -> Any:
|
199
|
+
import robot.api
|
200
|
+
|
201
|
+
if get_robot_version() >= (6, 0):
|
202
|
+
return robot.api.get_tokens(
|
203
|
+
source,
|
204
|
+
data_only=data_only,
|
205
|
+
tokenize_variables=tokenize_variables,
|
206
|
+
lang=lang,
|
207
|
+
)
|
208
|
+
|
209
|
+
return robot.api.get_tokens(source, data_only=data_only, tokenize_variables=tokenize_variables)
|
210
|
+
|
211
|
+
def __internal_get_resource_tokens(
|
212
|
+
self,
|
213
|
+
source: Any,
|
214
|
+
data_only: bool = False,
|
215
|
+
tokenize_variables: bool = False,
|
216
|
+
lang: Any = None,
|
217
|
+
) -> Any:
|
218
|
+
import robot.api
|
219
|
+
|
220
|
+
if get_robot_version() >= (6, 0):
|
221
|
+
return robot.api.get_resource_tokens(
|
222
|
+
source,
|
223
|
+
data_only=data_only,
|
224
|
+
tokenize_variables=tokenize_variables,
|
225
|
+
lang=lang,
|
226
|
+
)
|
227
|
+
|
228
|
+
return robot.api.get_resource_tokens(source, data_only=data_only, tokenize_variables=tokenize_variables)
|
229
|
+
|
230
|
+
def __internal_get_init_tokens(
|
231
|
+
self,
|
232
|
+
source: Any,
|
233
|
+
data_only: bool = False,
|
234
|
+
tokenize_variables: bool = False,
|
235
|
+
lang: Any = None,
|
236
|
+
) -> Any:
|
237
|
+
import robot.api
|
238
|
+
|
239
|
+
if get_robot_version() >= (6, 0):
|
240
|
+
return robot.api.get_init_tokens(
|
241
|
+
source,
|
242
|
+
data_only=data_only,
|
243
|
+
tokenize_variables=tokenize_variables,
|
244
|
+
lang=lang,
|
245
|
+
)
|
246
|
+
|
247
|
+
return robot.api.get_init_tokens(source, data_only=data_only, tokenize_variables=tokenize_variables)
|
248
|
+
|
249
|
+
def __get_general_tokens_data_only(self, document: TextDocument) -> List[Token]:
|
250
|
+
lang = self.get_languages_for_document(document)
|
251
|
+
|
252
|
+
def get(text: str) -> List[Token]:
|
253
|
+
with io.StringIO(text) as content:
|
254
|
+
return [e for e in self.__internal_get_tokens(content, True, lang=lang)]
|
255
|
+
|
256
|
+
return self.__get_tokens_internal(document, get)
|
257
|
+
|
258
|
+
def __get_general_tokens(self, document: TextDocument) -> List[Token]:
|
259
|
+
lang = self.get_languages_for_document(document)
|
260
|
+
|
261
|
+
def get(text: str) -> List[Token]:
|
262
|
+
with io.StringIO(text) as content:
|
263
|
+
return [e for e in self.__internal_get_tokens(content, lang=lang)]
|
264
|
+
|
265
|
+
return self.__get_tokens_internal(document, get)
|
266
|
+
|
267
|
+
def __get_tokens_internal(self, document: TextDocument, get: Callable[[str], List[Token]]) -> List[Token]:
|
268
|
+
return get(document.text())
|
269
|
+
|
270
|
+
def get_resource_tokens(self, document: TextDocument, data_only: bool = False) -> List[Token]:
|
271
|
+
if data_only:
|
272
|
+
return document.get_cache(self.__get_resource_tokens_data_only)
|
273
|
+
|
274
|
+
return document.get_cache(self.__get_resource_tokens)
|
275
|
+
|
276
|
+
def __get_resource_tokens_data_only(self, document: TextDocument) -> List[Token]:
|
277
|
+
lang = self.get_languages_for_document(document)
|
278
|
+
|
279
|
+
def get(text: str) -> List[Token]:
|
280
|
+
with io.StringIO(text) as content:
|
281
|
+
return [e for e in self.__internal_get_resource_tokens(content, True, lang=lang)]
|
282
|
+
|
283
|
+
return self.__get_tokens_internal(document, get)
|
284
|
+
|
285
|
+
def __get_resource_tokens(self, document: TextDocument) -> List[Token]:
|
286
|
+
lang = self.get_languages_for_document(document)
|
287
|
+
|
288
|
+
def get(text: str) -> List[Token]:
|
289
|
+
with io.StringIO(text) as content:
|
290
|
+
return [e for e in self.__internal_get_resource_tokens(content, lang=lang)]
|
291
|
+
|
292
|
+
return self.__get_tokens_internal(document, get)
|
293
|
+
|
294
|
+
def get_init_tokens(self, document: TextDocument, data_only: bool = False) -> List[Token]:
|
295
|
+
if data_only:
|
296
|
+
return document.get_cache(self.__get_init_tokens_data_only)
|
297
|
+
return document.get_cache(self.__get_init_tokens)
|
298
|
+
|
299
|
+
def __get_init_tokens_data_only(self, document: TextDocument) -> List[Token]:
|
300
|
+
lang = self.get_languages_for_document(document)
|
301
|
+
|
302
|
+
def get(text: str) -> List[Token]:
|
303
|
+
with io.StringIO(text) as content:
|
304
|
+
return [e for e in self.__internal_get_init_tokens(content, True, lang=lang)]
|
305
|
+
|
306
|
+
return self.__get_tokens_internal(document, get)
|
307
|
+
|
308
|
+
def __get_init_tokens(self, document: TextDocument) -> List[Token]:
|
309
|
+
lang = self.get_languages_for_document(document)
|
310
|
+
|
311
|
+
def get(text: str) -> List[Token]:
|
312
|
+
with io.StringIO(text) as content:
|
313
|
+
return [e for e in self.__internal_get_init_tokens(content, lang=lang)]
|
314
|
+
|
315
|
+
return self.__get_tokens_internal(document, get)
|
316
|
+
|
317
|
+
def get_model(self, document: TextDocument, data_only: bool = True) -> ast.AST:
|
318
|
+
document_type = self.get_document_type(document)
|
319
|
+
|
320
|
+
if document_type == DocumentType.INIT:
|
321
|
+
return self.get_init_model(document, data_only)
|
322
|
+
if document_type == DocumentType.GENERAL:
|
323
|
+
return self.get_general_model(document, data_only)
|
324
|
+
if document_type == DocumentType.RESOURCE:
|
325
|
+
return self.get_resource_model(document, data_only)
|
326
|
+
|
327
|
+
raise UnknownFileTypeError(f"Unknown file type '{document.uri}'.")
|
328
|
+
|
329
|
+
def __get_model(
|
330
|
+
self,
|
331
|
+
document: TextDocument,
|
332
|
+
tokens: Iterable[Any],
|
333
|
+
document_type: DocumentType,
|
334
|
+
) -> ast.AST:
|
335
|
+
from robot.parsing.parser.parser import _get_model
|
336
|
+
|
337
|
+
def get_tokens(source: str, data_only: bool = False, lang: Any = None) -> Iterator[Token]:
|
338
|
+
for t in tokens:
|
339
|
+
yield t
|
340
|
+
|
341
|
+
if get_robot_version() >= (6, 0):
|
342
|
+
model = _get_model(get_tokens, document.uri.to_path(), False, None, None)
|
343
|
+
else:
|
344
|
+
model = _get_model(get_tokens, document.uri.to_path(), False, None)
|
345
|
+
|
346
|
+
model.source = str(document.uri.to_path())
|
347
|
+
model.model_type = document_type
|
348
|
+
|
349
|
+
return cast(ast.AST, model)
|
350
|
+
|
351
|
+
def get_general_model(self, document: TextDocument, data_only: bool = True) -> ast.AST:
|
352
|
+
if data_only:
|
353
|
+
return document.get_cache(
|
354
|
+
self.__get_general_model_data_only,
|
355
|
+
self.get_general_tokens(document, True),
|
356
|
+
)
|
357
|
+
return document.get_cache(self.__get_general_model, self.get_general_tokens(document))
|
358
|
+
|
359
|
+
def __get_general_model_data_only(self, document: TextDocument, tokens: Iterable[Any]) -> ast.AST:
|
360
|
+
return self.__get_model(document, tokens, DocumentType.GENERAL)
|
361
|
+
|
362
|
+
def __get_general_model(self, document: TextDocument, tokens: Iterable[Any]) -> ast.AST:
|
363
|
+
return self.__get_model(document, tokens, DocumentType.GENERAL)
|
364
|
+
|
365
|
+
def get_resource_model(self, document: TextDocument, data_only: bool = True) -> ast.AST:
|
366
|
+
if data_only:
|
367
|
+
return document.get_cache(
|
368
|
+
self.__get_resource_model_data_only,
|
369
|
+
self.get_resource_tokens(document, True),
|
370
|
+
)
|
371
|
+
|
372
|
+
return document.get_cache(self.__get_resource_model, self.get_resource_tokens(document))
|
373
|
+
|
374
|
+
def __get_resource_model_data_only(self, document: TextDocument, tokens: Iterable[Any]) -> ast.AST:
|
375
|
+
return self.__get_model(document, tokens, DocumentType.RESOURCE)
|
376
|
+
|
377
|
+
def __get_resource_model(self, document: TextDocument, tokens: Iterable[Any]) -> ast.AST:
|
378
|
+
return self.__get_model(document, tokens, DocumentType.RESOURCE)
|
379
|
+
|
380
|
+
def get_init_model(self, document: TextDocument, data_only: bool = True) -> ast.AST:
|
381
|
+
if data_only:
|
382
|
+
return document.get_cache(
|
383
|
+
self.__get_init_model_data_only,
|
384
|
+
self.get_init_tokens(document, True),
|
385
|
+
)
|
386
|
+
return document.get_cache(self.__get_init_model, self.get_init_tokens(document))
|
387
|
+
|
388
|
+
def __get_init_model_data_only(self, document: TextDocument, tokens: Iterable[Any]) -> ast.AST:
|
389
|
+
return self.__get_model(document, tokens, DocumentType.INIT)
|
390
|
+
|
391
|
+
def __get_init_model(self, document: TextDocument, tokens: Iterable[Any]) -> ast.AST:
|
392
|
+
return self.__get_model(document, tokens, DocumentType.INIT)
|
393
|
+
|
394
|
+
def get_namespace(self, document: TextDocument) -> Namespace:
|
395
|
+
return document.get_cache(self.__get_namespace)
|
396
|
+
|
397
|
+
def __get_namespace(self, document: TextDocument) -> Namespace:
|
398
|
+
return self.__get_namespace_for_document_type(document, None)
|
399
|
+
|
400
|
+
def get_resource_namespace(self, document: TextDocument) -> Namespace:
|
401
|
+
return document.get_cache(self.__get_resource_namespace)
|
402
|
+
|
403
|
+
def __get_resource_namespace(self, document: TextDocument) -> Namespace:
|
404
|
+
return self.__get_namespace_for_document_type(document, DocumentType.RESOURCE)
|
405
|
+
|
406
|
+
def get_init_namespace(self, document: TextDocument) -> Namespace:
|
407
|
+
return document.get_cache(self.__get_init_namespace)
|
408
|
+
|
409
|
+
def __get_init_namespace(self, document: TextDocument) -> Namespace:
|
410
|
+
return self.__get_namespace_for_document_type(document, DocumentType.INIT)
|
411
|
+
|
412
|
+
def get_general_namespace(self, document: TextDocument) -> Namespace:
|
413
|
+
return document.get_cache(self.__get_general_namespace)
|
414
|
+
|
415
|
+
def __get_general_namespace(self, document: TextDocument) -> Namespace:
|
416
|
+
return self.__get_namespace_for_document_type(document, DocumentType.GENERAL)
|
417
|
+
|
418
|
+
@event
|
419
|
+
def namespace_invalidated(sender, namespace: Namespace) -> None:
|
420
|
+
...
|
421
|
+
|
422
|
+
def __invalidate_namespace(self, sender: Namespace) -> None:
|
423
|
+
document = sender.document
|
424
|
+
if document is not None:
|
425
|
+
document.invalidate_cache()
|
426
|
+
|
427
|
+
self.namespace_invalidated(self, sender, callback_filter=language_id_filter(document))
|
428
|
+
|
429
|
+
def __get_namespace_for_document_type(
|
430
|
+
self, document: TextDocument, document_type: Optional[DocumentType]
|
431
|
+
) -> Namespace:
|
432
|
+
if document_type is not None and document_type == DocumentType.INIT:
|
433
|
+
model = self.get_init_model(document)
|
434
|
+
elif document_type is not None and document_type == DocumentType.RESOURCE:
|
435
|
+
model = self.get_resource_model(document)
|
436
|
+
elif document_type is not None and document_type == DocumentType.GENERAL:
|
437
|
+
model = self.get_general_model(document)
|
438
|
+
else:
|
439
|
+
model = self.get_model(document)
|
440
|
+
|
441
|
+
imports_manager = self.get_imports_manager(document)
|
442
|
+
|
443
|
+
languages, workspace_languages = self.build_languages_from_model(document, model)
|
444
|
+
|
445
|
+
result = Namespace(
|
446
|
+
imports_manager,
|
447
|
+
model,
|
448
|
+
str(document.uri.to_path()),
|
449
|
+
document,
|
450
|
+
document_type,
|
451
|
+
languages,
|
452
|
+
workspace_languages,
|
453
|
+
)
|
454
|
+
result.has_invalidated.add(self.__invalidate_namespace)
|
455
|
+
result.has_imports_changed.add(self.__invalidate_namespace)
|
456
|
+
|
457
|
+
return result
|
458
|
+
|
459
|
+
def create_imports_manager(self, root_uri: Uri) -> ImportsManager:
|
460
|
+
cache_base_path = self.calc_cache_path(root_uri)
|
461
|
+
|
462
|
+
robot_config = self.workspace.get_configuration(RobotConfig, root_uri)
|
463
|
+
|
464
|
+
cache_config = self.workspace.get_configuration(CacheConfig, root_uri)
|
465
|
+
environment = self.robot_profile.env or {}
|
466
|
+
if robot_config.env:
|
467
|
+
environment.update(robot_config.env)
|
468
|
+
|
469
|
+
variables = {
|
470
|
+
**{k1: str(v1) for k1, v1 in (self.robot_profile.variables or {}).items()},
|
471
|
+
**robot_config.variables,
|
472
|
+
}
|
473
|
+
variable_files = [
|
474
|
+
*(str(k) for k in self.robot_profile.variable_files or []),
|
475
|
+
*robot_config.variable_files,
|
476
|
+
]
|
477
|
+
|
478
|
+
return ImportsManager(
|
479
|
+
self.documents_manager,
|
480
|
+
self.file_watcher_manager,
|
481
|
+
self,
|
482
|
+
root_uri.to_path(),
|
483
|
+
variables,
|
484
|
+
variable_files,
|
485
|
+
environment,
|
486
|
+
cache_config.ignored_libraries,
|
487
|
+
cache_config.ignored_variables,
|
488
|
+
cache_base_path,
|
489
|
+
)
|
490
|
+
|
491
|
+
def default_imports_manager(self) -> ImportsManager:
|
492
|
+
with self._imports_managers_lock:
|
493
|
+
if self._default_imports_manager is None:
|
494
|
+
self._default_imports_manager = self.create_imports_manager(
|
495
|
+
self.workspace.root_uri
|
496
|
+
if self.workspace.root_uri is not None
|
497
|
+
else Uri.from_path(Path(".").absolute())
|
498
|
+
)
|
499
|
+
|
500
|
+
return self._default_imports_manager
|
501
|
+
|
502
|
+
def get_imports_manager(self, document: TextDocument) -> ImportsManager:
|
503
|
+
return self.get_imports_manager_for_uri(document.uri)
|
504
|
+
|
505
|
+
def get_imports_manager_for_uri(self, uri: Uri) -> ImportsManager:
|
506
|
+
return self.get_imports_manager_for_workspace_folder(self.workspace.get_workspace_folder(uri))
|
507
|
+
|
508
|
+
def get_imports_manager_for_workspace_folder(self, folder: Optional[WorkspaceFolder]) -> ImportsManager:
|
509
|
+
if folder is None:
|
510
|
+
if len(self.workspace.workspace_folders) == 1:
|
511
|
+
folder = self.workspace.workspace_folders[0]
|
512
|
+
else:
|
513
|
+
return self.default_imports_manager()
|
514
|
+
|
515
|
+
with self._imports_managers_lock:
|
516
|
+
if folder not in self._imports_managers:
|
517
|
+
self._imports_managers[folder] = self.create_imports_manager(folder.uri)
|
518
|
+
|
519
|
+
return self._imports_managers[folder]
|
520
|
+
|
521
|
+
def calc_cache_path(self, folder_uri: Uri) -> Path:
|
522
|
+
# TODO: cache path should be configurable, save cache in vscode workspace folder or in robotcode cache folder
|
523
|
+
return folder_uri.to_path()
|
@@ -13,7 +13,8 @@ from typing import (
|
|
13
13
|
|
14
14
|
from robot.parsing.lexer.tokens import Token
|
15
15
|
from robotcode.core.lsp.types import Position, Range
|
16
|
-
|
16
|
+
|
17
|
+
from ..utils.ast import range_from_token
|
17
18
|
|
18
19
|
if TYPE_CHECKING:
|
19
20
|
from robotcode.robot.diagnostics.library_doc import KeywordDoc, LibraryDoc
|
@@ -0,0 +1,33 @@
|
|
1
|
+
from typing import final
|
2
|
+
|
3
|
+
DIAGNOSTICS_SOURCE_NAME = "robotcode.namespace"
|
4
|
+
|
5
|
+
|
6
|
+
@final
|
7
|
+
class Error:
|
8
|
+
VARIABLE_NOT_FOUND = "VariableNotFound"
|
9
|
+
ENVIROMMENT_VARIABLE_NOT_FOUND = "EnvirommentVariableNotFound"
|
10
|
+
KEYWORD_NOT_FOUND = "KeywordNotFound"
|
11
|
+
LIBRARY_CONTAINS_NO_KEYWORDS = "LibraryContainsNoKeywords"
|
12
|
+
POSSIBLE_CIRCULAR_IMPORT = "PossibleCircularImport"
|
13
|
+
RESOURCE_EMPTY = "ResourceEmpty"
|
14
|
+
IMPORT_CONTAINS_ERRORS = "ImportContainsErrors"
|
15
|
+
RECURSIVE_IMPORT = "RecursiveImport"
|
16
|
+
RESOURCE_ALREADY_IMPORTED = "ResourceAlreadyImported"
|
17
|
+
VARIABLES_ALREADY_IMPORTED = "VariablesAlreadyImported"
|
18
|
+
LIBRARY_ALREADY_IMPORTED = "LibraryAlreadyImported"
|
19
|
+
LIBRARY_OVERRIDES_BUILTIN = "LibraryOverridesBuiltIn"
|
20
|
+
DEPRECATED_KEYWORD = "DeprecatedKeyword"
|
21
|
+
KEYWORD_CONTAINS_ERRORS = "KeywordContainsErrors"
|
22
|
+
RESERVED_KEYWORD = "ReservedKeyword"
|
23
|
+
PRIVATE_KEYWORD = "PrivateKeyword"
|
24
|
+
INCORRECT_USE = "IncorrectUse"
|
25
|
+
KEYWORD_NAME_EMPTY = "KeywordNameEmpty"
|
26
|
+
CODE_UNREACHABLE = "CodeUnreachable"
|
27
|
+
TESTCASE_NAME_EMPTY = "TestCaseNameEmpty"
|
28
|
+
KEYWORD_CONTAINS_NORMAL_AND_EMBBEDED_ARGUMENTS = "KeywordContainsNormalAndEmbbededArguments"
|
29
|
+
DEPRECATED_HYPHEN_TAG = "DeprecatedHyphenTag"
|
30
|
+
DEPRECATED_RETURN_SETTING = "DeprecatedReturnSetting"
|
31
|
+
DEPRECATED_FORCE_TAG = "DeprecatedForceTag"
|
32
|
+
IMPORT_REQUIRES_VALUE = "ImportRequiresValue"
|
33
|
+
KEYWORD_ERROR = "KeywordError"
|