robotcode-robot 0.93.1__py3-none-any.whl → 0.94.0__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/diagnostics/document_cache_helper.py +11 -6
- robotcode/robot/diagnostics/entities.py +2 -2
- robotcode/robot/diagnostics/errors.py +6 -1
- robotcode/robot/diagnostics/imports_manager.py +77 -37
- robotcode/robot/diagnostics/keyword_finder.py +458 -0
- robotcode/robot/diagnostics/library_doc.py +20 -14
- robotcode/robot/diagnostics/model_helper.py +42 -27
- robotcode/robot/diagnostics/namespace.py +142 -552
- robotcode/robot/diagnostics/namespace_analyzer.py +952 -462
- robotcode/robot/utils/markdownformatter.py +8 -11
- robotcode/robot/utils/visitor.py +7 -13
- {robotcode_robot-0.93.1.dist-info → robotcode_robot-0.94.0.dist-info}/METADATA +2 -2
- robotcode_robot-0.94.0.dist-info/RECORD +31 -0
- robotcode_robot-0.93.1.dist-info/RECORD +0 -30
- {robotcode_robot-0.93.1.dist-info → robotcode_robot-0.94.0.dist-info}/WHEEL +0 -0
- {robotcode_robot-0.93.1.dist-info → robotcode_robot-0.94.0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -6,7 +6,9 @@ import token as python_token
|
|
6
6
|
from io import StringIO
|
7
7
|
from tokenize import TokenError, generate_tokens
|
8
8
|
from typing import (
|
9
|
+
TYPE_CHECKING,
|
9
10
|
Any,
|
11
|
+
Callable,
|
10
12
|
Iterator,
|
11
13
|
List,
|
12
14
|
Optional,
|
@@ -17,6 +19,7 @@ from typing import (
|
|
17
19
|
Union,
|
18
20
|
)
|
19
21
|
|
22
|
+
from robot.errors import VariableError
|
20
23
|
from robot.parsing.lexer.tokens import Token
|
21
24
|
from robot.utils.escaping import split_from_equals, unescape
|
22
25
|
from robot.variables.finders import NOT_FOUND, NumberFinder
|
@@ -37,13 +40,16 @@ from .entities import (
|
|
37
40
|
VariableDefinition,
|
38
41
|
VariableNotFoundDefinition,
|
39
42
|
)
|
43
|
+
from .keyword_finder import DEFAULT_BDD_PREFIXES
|
40
44
|
from .library_doc import (
|
41
45
|
ArgumentInfo,
|
42
46
|
KeywordArgumentKind,
|
43
47
|
KeywordDoc,
|
44
48
|
LibraryDoc,
|
45
49
|
)
|
46
|
-
|
50
|
+
|
51
|
+
if TYPE_CHECKING:
|
52
|
+
from .namespace import Namespace
|
47
53
|
|
48
54
|
|
49
55
|
class ModelHelper:
|
@@ -52,7 +58,7 @@ class ModelHelper:
|
|
52
58
|
cls,
|
53
59
|
keyword_doc: Optional[KeywordDoc],
|
54
60
|
argument_tokens: List[Token],
|
55
|
-
namespace: Namespace,
|
61
|
+
namespace: "Namespace",
|
56
62
|
position: Position,
|
57
63
|
) -> Tuple[Optional[Tuple[Optional[KeywordDoc], Token]], List[Token]]:
|
58
64
|
if keyword_doc is None or not keyword_doc.is_any_run_keyword():
|
@@ -200,7 +206,7 @@ class ModelHelper:
|
|
200
206
|
keyword_name: Optional[str],
|
201
207
|
keyword_token: Token,
|
202
208
|
argument_tokens: List[Token],
|
203
|
-
namespace: Namespace,
|
209
|
+
namespace: "Namespace",
|
204
210
|
position: Position,
|
205
211
|
analyse_run_keywords: bool = True,
|
206
212
|
) -> Optional[Tuple[Optional[KeywordDoc], Token]]:
|
@@ -222,7 +228,7 @@ class ModelHelper:
|
|
222
228
|
|
223
229
|
@classmethod
|
224
230
|
def get_namespace_info_from_keyword_token(
|
225
|
-
cls, namespace: Namespace, keyword_token: Token
|
231
|
+
cls, namespace: "Namespace", keyword_token: Token
|
226
232
|
) -> Tuple[Optional[LibraryEntry], Optional[str]]:
|
227
233
|
lib_entry: Optional[LibraryEntry] = None
|
228
234
|
kw_namespace: Optional[str] = None
|
@@ -243,7 +249,7 @@ class ModelHelper:
|
|
243
249
|
|
244
250
|
return lib_entry, kw_namespace
|
245
251
|
|
246
|
-
|
252
|
+
match_extended = re.compile(
|
247
253
|
r"""
|
248
254
|
(.+?) # base name (group 1)
|
249
255
|
([^\s\w].+) # extended part (group 2)
|
@@ -254,7 +260,7 @@ class ModelHelper:
|
|
254
260
|
@staticmethod
|
255
261
|
def iter_expression_variables_from_token(
|
256
262
|
expression: Token,
|
257
|
-
namespace: Namespace,
|
263
|
+
namespace: "Namespace",
|
258
264
|
nodes: Optional[List[ast.AST]],
|
259
265
|
position: Optional[Position] = None,
|
260
266
|
skip_commandline_variables: bool = False,
|
@@ -354,27 +360,36 @@ class ModelHelper:
|
|
354
360
|
ignore_errors: bool = False,
|
355
361
|
*,
|
356
362
|
extra_types: Optional[Set[str]] = None,
|
363
|
+
exception_handler: Optional[Callable[[Exception, Token], None]] = None,
|
357
364
|
) -> Iterator[Token]:
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
365
|
+
if exception_handler is not None:
|
366
|
+
ignore_errors = False
|
367
|
+
try:
|
368
|
+
for t in tokenize_variables(token, identifiers, ignore_errors, extra_types=extra_types):
|
369
|
+
if t.type == Token.VARIABLE:
|
370
|
+
var, rest = cls.remove_index_from_variable_token(t)
|
371
|
+
if var is not None:
|
372
|
+
yield var
|
373
|
+
if rest is not None:
|
374
|
+
yield from cls.tokenize_variables(
|
375
|
+
rest,
|
376
|
+
identifiers,
|
377
|
+
ignore_errors,
|
378
|
+
extra_types=extra_types,
|
379
|
+
)
|
380
|
+
else:
|
381
|
+
yield t
|
382
|
+
except VariableError as e:
|
383
|
+
if exception_handler is not None:
|
384
|
+
exception_handler(e, token)
|
385
|
+
elif not ignore_errors:
|
386
|
+
raise
|
372
387
|
|
373
388
|
@classmethod
|
374
389
|
def iter_variables_from_token(
|
375
390
|
cls,
|
376
391
|
token: Token,
|
377
|
-
namespace: Namespace,
|
392
|
+
namespace: "Namespace",
|
378
393
|
nodes: Optional[List[ast.AST]],
|
379
394
|
position: Optional[Position] = None,
|
380
395
|
skip_commandline_variables: bool = False,
|
@@ -413,7 +428,7 @@ class ModelHelper:
|
|
413
428
|
):
|
414
429
|
yield v
|
415
430
|
elif base == "" and return_not_found:
|
416
|
-
yield (
|
431
|
+
yield ( # TODO: robotframework ignores this case, should we do the same or raise an error/hint?
|
417
432
|
sub_token,
|
418
433
|
VariableNotFoundDefinition(
|
419
434
|
sub_token.lineno,
|
@@ -481,7 +496,7 @@ class ModelHelper:
|
|
481
496
|
and sub_token.value[1:2] == "{"
|
482
497
|
and sub_token.value[-1:] == "}"
|
483
498
|
):
|
484
|
-
match = cls.
|
499
|
+
match = cls.match_extended.match(name[2:-1])
|
485
500
|
if match is not None:
|
486
501
|
base_name, _ = match.groups()
|
487
502
|
name = f"{name[0]}{{{base_name.strip()}}}"
|
@@ -557,7 +572,7 @@ class ModelHelper:
|
|
557
572
|
BDD_TOKEN = re.compile(r"^(Given|When|Then|And|But)$", flags=re.IGNORECASE)
|
558
573
|
|
559
574
|
@classmethod
|
560
|
-
def split_bdd_prefix(cls, namespace: Namespace, token: Token) -> Tuple[Optional[Token], Optional[Token]]:
|
575
|
+
def split_bdd_prefix(cls, namespace: "Namespace", token: Token) -> Tuple[Optional[Token], Optional[Token]]:
|
561
576
|
bdd_token = None
|
562
577
|
|
563
578
|
parts = token.value.split()
|
@@ -590,7 +605,7 @@ class ModelHelper:
|
|
590
605
|
return bdd_token, token
|
591
606
|
|
592
607
|
@classmethod
|
593
|
-
def strip_bdd_prefix(cls, namespace: Namespace, token: Token) -> Token:
|
608
|
+
def strip_bdd_prefix(cls, namespace: "Namespace", token: Token) -> Token:
|
594
609
|
if get_robot_version() < (6, 0):
|
595
610
|
bdd_match = cls.BDD_TOKEN_REGEX.match(token.value)
|
596
611
|
if bdd_match:
|
@@ -627,7 +642,7 @@ class ModelHelper:
|
|
627
642
|
return token
|
628
643
|
|
629
644
|
@classmethod
|
630
|
-
def is_bdd_token(cls, namespace: Namespace, token: Token) -> bool:
|
645
|
+
def is_bdd_token(cls, namespace: "Namespace", token: Token) -> bool:
|
631
646
|
if get_robot_version() < (6, 0):
|
632
647
|
bdd_match = cls.BDD_TOKEN.match(token.value)
|
633
648
|
return bool(bdd_match)
|
@@ -651,7 +666,7 @@ class ModelHelper:
|
|
651
666
|
@classmethod
|
652
667
|
def get_keyword_definition_at_line(cls, library_doc: LibraryDoc, value: str, line: int) -> Optional[KeywordDoc]:
|
653
668
|
return next(
|
654
|
-
(k for k in library_doc.keywords.
|
669
|
+
(k for k in library_doc.keywords.iter_all(value) if k.line_no == line),
|
655
670
|
None,
|
656
671
|
)
|
657
672
|
|