robotcode-robot 2.8.0.dev548__py3-none-any.whl → 2.8.0.dev631__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.
@@ -1 +1 @@
1
- __version__ = "2.8.0-dev.548"
1
+ __version__ = "2.8.0-dev.631"
@@ -1930,13 +1930,16 @@ class LibraryDoc:
1930
1930
  def _get_title_markdown(self, header_level: int) -> str:
1931
1931
  result = f"#{'#' * header_level} {(self.type.capitalize()) if self.type else 'Unknown'} *{self.name}*\n\n"
1932
1932
 
1933
- if self.version or self.scope:
1933
+ # resource and suite files show GLOBAL, as in Libdoc; variable files have no scope in Robot Framework
1934
+ scope = self.scope if self.type != "VARIABLES" else ""
1935
+
1936
+ if self.version or scope:
1934
1937
  result += "| | |\n| :--- | :--- |\n"
1935
1938
 
1936
1939
  if self.version:
1937
1940
  result += f"| **Library Version:** | {self.version} |\n"
1938
- if self.scope:
1939
- result += f"| **Library Scope:** | {self.scope} |\n"
1941
+ if scope:
1942
+ result += f"| **Library Scope:** | {scope} |\n"
1940
1943
 
1941
1944
  result += "\n\n"
1942
1945
 
@@ -1458,7 +1458,10 @@ class NamespaceAnalyzer(Visitor):
1458
1458
  ignore_errors=True,
1459
1459
  )
1460
1460
 
1461
- if not matcher.is_assign(allow_assign_mark=True, allow_nested=True) or matcher.name is None:
1461
+ if (
1462
+ not matcher.is_assign(allow_assign_mark=True, allow_nested=True, allow_items=True)
1463
+ or matcher.name is None
1464
+ ):
1462
1465
  return
1463
1466
 
1464
1467
  if RF_VERSION >= (7, 0) and contains_variable(matcher.base, "$@&%"):
@@ -1496,6 +1499,19 @@ class NamespaceAnalyzer(Visitor):
1496
1499
  stripped_name_token = strip_variable_token(assign_token, matcher=matcher, parse_type=True)
1497
1500
 
1498
1501
  if matcher.items:
1502
+ # Robot Framework resolves the variables in the index; the search without types keeps a type
1503
+ # in the base, so the index starts after it
1504
+ raw = search_variable(matcher.string, ignore_errors=True)
1505
+ items_start = raw.start + len(raw.identifier) + len(raw.base) + 2
1506
+ items_token = Token(
1507
+ Token.ARGUMENT,
1508
+ matcher.string[items_start : raw.end],
1509
+ assign_token.lineno,
1510
+ assign_token.col_offset + items_start,
1511
+ )
1512
+ for var_token, var in self._iter_variables_from_token(items_token):
1513
+ self._handle_find_variable_result(var_token, var)
1514
+
1499
1515
  existing_var = self._find_variable(name)
1500
1516
  if existing_var is None:
1501
1517
  self._handle_find_variable_result(
@@ -1611,18 +1627,21 @@ class NamespaceAnalyzer(Visitor):
1611
1627
  if not matcher.is_scalar_assign():
1612
1628
  return
1613
1629
 
1614
- if (
1615
- next(
1616
- (
1617
- k
1618
- for k, v in self._variables.items()
1619
- if k == matcher
1620
- and v.type in [VariableDefinitionType.ARGUMENT, VariableDefinitionType.LOCAL_VARIABLE]
1621
- ),
1622
- None,
1630
+ existing_var = next(
1631
+ (
1632
+ v
1633
+ for k, v in self._variables.items()
1634
+ if k == matcher
1635
+ and v.type in [VariableDefinitionType.ARGUMENT, VariableDefinitionType.LOCAL_VARIABLE]
1636
+ ),
1637
+ None,
1638
+ )
1639
+ if existing_var is not None:
1640
+ # EXCEPT AS sets the existing variable again, like a FOR variable of that name
1641
+ self._variable_references[existing_var].add(
1642
+ Location(self._document_uri, range_from_token(strip_variable_token(variable_token)))
1623
1643
  )
1624
- is None
1625
- ):
1644
+ else:
1626
1645
  var_def = LocalVariableDefinition(
1627
1646
  name=variable_token.value,
1628
1647
  name_token=strip_variable_token(variable_token),
@@ -405,6 +405,8 @@ class SemanticAnalyzer(Visitor):
405
405
  )
406
406
  self._logger.exception(e)
407
407
 
408
+ self._mark_argument_uses()
409
+
408
410
  # Build indexes
409
411
  self._semantic_model.build_index()
410
412
 
@@ -423,6 +425,38 @@ class SemanticAnalyzer(Visitor):
423
425
  semantic_model=self._semantic_model,
424
426
  )
425
427
 
428
+ def _mark_argument_uses(self) -> None:
429
+ """Mark every variable token whose name the analysis resolved to an argument from `[Arguments]`, the same
430
+ resolution Find References and Rename use; embedded arguments stay unmarked."""
431
+ starts = {
432
+ (location.range.start.line, location.range.start.character)
433
+ for var, locations in self._variable_references.items()
434
+ if isinstance(var, ArgumentDefinition) and not isinstance(var, EmbeddedArgumentDefinition)
435
+ for location in locations
436
+ }
437
+ if starts:
438
+ for stmt in self._semantic_model.statements:
439
+ self._mark_argument_uses_in_statement(stmt, starts)
440
+
441
+ def _mark_argument_uses_in_statement(self, stmt: SemanticStatement, starts: Set[Tuple[int, int]]) -> None:
442
+ for token in stmt.tokens:
443
+ self._mark_argument_uses_in_token(token, starts)
444
+ # the inner calls of a Run Keyword variant have tokens of their own
445
+ if isinstance(stmt, RunKeywordCallStatement):
446
+ for inner in stmt.inner_calls:
447
+ self._mark_argument_uses_in_statement(inner, starts)
448
+
449
+ def _mark_argument_uses_in_token(self, token: SemanticToken, starts: Set[Tuple[int, int]]) -> None:
450
+ for sub in token.sub_tokens or ():
451
+ self._mark_argument_uses_in_token(sub, starts)
452
+ # a reference covers the name of the variable, its base
453
+ if (
454
+ token.kind is TokenKind.VARIABLE
455
+ and sub.kind is TokenKind.VARIABLE_BASE
456
+ and (sub.range.start.line, sub.range.start.character) in starts
457
+ ):
458
+ token.modifiers = (token.modifiers or frozenset()) | {TokenModifier.ARGUMENT}
459
+
426
460
  # --- Semantic Model helpers ---
427
461
 
428
462
  # Statement kinds that act as the block-header for control-flow blocks.
@@ -3176,7 +3210,10 @@ class SemanticAnalyzer(Visitor):
3176
3210
  ignore_errors=True,
3177
3211
  )
3178
3212
 
3179
- if not matcher.is_assign(allow_assign_mark=True, allow_nested=True) or matcher.name is None:
3213
+ if (
3214
+ not matcher.is_assign(allow_assign_mark=True, allow_nested=True, allow_items=True)
3215
+ or matcher.name is None
3216
+ ):
3180
3217
  return
3181
3218
 
3182
3219
  if RF_VERSION >= (7, 0) and contains_variable(matcher.base, "$@&%"):
@@ -3220,6 +3257,19 @@ class SemanticAnalyzer(Visitor):
3220
3257
  stripped_name_token = strip_variable_token(assign_token, matcher=matcher, parse_type=True)
3221
3258
 
3222
3259
  if matcher.items:
3260
+ # Robot Framework resolves the variables in the index; the search without types keeps a type
3261
+ # in the base, so the index starts after it
3262
+ raw = search_variable(matcher.string, ignore_errors=True)
3263
+ items_start = raw.start + len(raw.identifier) + len(raw.base) + 2
3264
+ items_token = Token(
3265
+ Token.ARGUMENT,
3266
+ matcher.string[items_start : raw.end],
3267
+ assign_token.lineno,
3268
+ assign_token.col_offset + items_start,
3269
+ )
3270
+ for var_token, var in self._iter_variables_from_token(items_token):
3271
+ self._handle_find_variable_result(var_token, var)
3272
+
3223
3273
  existing_var = self._find_variable(name)
3224
3274
  if existing_var is None:
3225
3275
  self._handle_find_variable_result(
@@ -3468,18 +3518,21 @@ class SemanticAnalyzer(Visitor):
3468
3518
  if not matcher.is_scalar_assign():
3469
3519
  return
3470
3520
 
3471
- if (
3472
- next(
3473
- (
3474
- k
3475
- for k, v in self._variables.items()
3476
- if k == matcher
3477
- and v.type in [VariableDefinitionType.ARGUMENT, VariableDefinitionType.LOCAL_VARIABLE]
3478
- ),
3479
- None,
3521
+ existing_var = next(
3522
+ (
3523
+ v
3524
+ for k, v in self._variables.items()
3525
+ if k == matcher
3526
+ and v.type in [VariableDefinitionType.ARGUMENT, VariableDefinitionType.LOCAL_VARIABLE]
3527
+ ),
3528
+ None,
3529
+ )
3530
+ if existing_var is not None:
3531
+ # EXCEPT AS sets the existing variable again, like a FOR variable of that name
3532
+ self._variable_references[existing_var].add(
3533
+ Location(self._document_uri, range_from_token(strip_variable_token(variable_token)))
3480
3534
  )
3481
- is None
3482
- ):
3535
+ else:
3483
3536
  var_def = LocalVariableDefinition(
3484
3537
  name=variable_token.value,
3485
3538
  name_token=strip_variable_token(variable_token),
@@ -194,6 +194,7 @@ class TokenModifier(Enum):
194
194
  EMBEDDED = "embedded"
195
195
  DECLARATION = "declaration"
196
196
  DOCUMENTATION = "documentation"
197
+ ARGUMENT = "argument" # a variable that names an argument from the keyword's [Arguments], not an embedded one
197
198
 
198
199
 
199
200
  class ForFlavor(Enum):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: robotcode-robot
3
- Version: 2.8.0-dev.548
3
+ Version: 2.8.0-dev.631
4
4
  Summary: Support classes for RobotCode for handling Robot Framework projects.
5
5
  Project-URL: Homepage, https://robotcode.io
6
6
  Project-URL: Donate, https://opencollective.com/robotcode
@@ -27,7 +27,7 @@ Classifier: Topic :: Utilities
27
27
  Classifier: Typing :: Typed
28
28
  Requires-Python: >=3.10
29
29
  Requires-Dist: platformdirs>=4.3
30
- Requires-Dist: robotcode-core==2.8.0-dev.548
30
+ Requires-Dist: robotcode-core==2.8.0-dev.631
31
31
  Requires-Dist: robotframework>=5.0.0
32
32
  Requires-Dist: tomli>=1.1.0; python_version < '3.11'
33
33
  Description-Content-Type: text/markdown
@@ -1,5 +1,5 @@
1
1
  robotcode/robot/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- robotcode/robot/__version__.py,sha256=4qGR5Sg7VszfoERVpnszHJ_tsWJ0G_bUZdheH0_dqx4,30
2
+ robotcode/robot/__version__.py,sha256=9SGjqX5uvERIavT5Cjgw0TSLgQ-nKCFaQ13-E6K7MDA,30
3
3
  robotcode/robot/py.typed,sha256=bWew9mHgMy8LqMu7RuqQXFXLBxh2CRx0dUbSx-3wE48,27
4
4
  robotcode/robot/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  robotcode/robot/config/loader.py,sha256=HLbkZem8JiBuy9Q5naghZddAuMPOn8Tk6UBgN2T3Uyc,9073
@@ -16,17 +16,17 @@ robotcode/robot/diagnostics/errors.py,sha256=lqHDWrMNy3ZhuEIVxeEhaU0ns8PB6pVTQBf
16
16
  robotcode/robot/diagnostics/import_resolver.py,sha256=lqbJYm3i62nK-EB1tgQ-RZoUtJ6rkB9JX6AzSN-p9t4,33126
17
17
  robotcode/robot/diagnostics/imports_manager.py,sha256=SRSidp3KyPXvT7NollGu-nhYmVKon8hw2pXoQog9SlE,89243
18
18
  robotcode/robot/diagnostics/keyword_finder.py,sha256=nwTmjvhyu5H7HHzyk8gt-pny2K2xdH2qCNyKXwwXRnk,18998
19
- robotcode/robot/diagnostics/library_doc.py,sha256=GKeMFF17dH_Nq2B0xXNwNCMNXoUDCHUGguJTnPtXLVg,153417
19
+ robotcode/robot/diagnostics/library_doc.py,sha256=MYztjgnOmXAPjXn7td651oWats2qDlPrLgCkmwpdSmU,153576
20
20
  robotcode/robot/diagnostics/model_helper.py,sha256=_ySXwerkK5xvjWa82T0DFy8jpxRzcaavTJiAHnk2lXQ,29740
21
21
  robotcode/robot/diagnostics/namespace.py,sha256=f2A4K2KURxyXr5unBBN622ayoJg34pkePQMbS79WhVA,35914
22
- robotcode/robot/diagnostics/namespace_analyzer.py,sha256=CeWWQLm1grZdFKXYlXSsgMnJS8kZE6K4UGdRociTk9s,102549
22
+ robotcode/robot/diagnostics/namespace_analyzer.py,sha256=HrYdY6DM2DvR3Jh9wB-RggbxLDgez5CLk_NRSOZQRcQ,103678
23
23
  robotcode/robot/diagnostics/project_index.py,sha256=Oqs7kV279PixVS6rGeigPKXGJYGqJdTDmDBjU7ODDRA,11006
24
24
  robotcode/robot/diagnostics/scope_tree.py,sha256=UREHoFG7NWh6UTWxET1M5Jxz_XBjXaQJg1GUIYPctq0,8348
25
25
  robotcode/robot/diagnostics/variable_scope.py,sha256=bge49DM-1FfQYIeqK2DtBG7JAMm25mazZ_zjh0DoMmg,3096
26
26
  robotcode/robot/diagnostics/workspace_config.py,sha256=GlsR1VnUBHoLBvIZtUXkm1dBDFPT9qoiYZzwZlurmXM,3277
27
27
  robotcode/robot/diagnostics/semantic_analyzer/__init__.py,sha256=ObbJv-S8LDgkWKZtTZjISBodXxyoLdEiOjVYp5aYbT4,1689
28
- robotcode/robot/diagnostics/semantic_analyzer/analyzer.py,sha256=KgytESMxSZSo5Q-AV0wJptqflqPhV9EoZ1HhlBt_Zyg,202596
29
- robotcode/robot/diagnostics/semantic_analyzer/enums.py,sha256=YaKwB5rGnT0s-F-txWjHCblcEHW-6pTnEB4QzT4IlY4,8553
28
+ robotcode/robot/diagnostics/semantic_analyzer/analyzer.py,sha256=PrWfgnA2AveDaVpXQUQ-pyx5aDeIcQwA7q2b7K39_Uo,205496
29
+ robotcode/robot/diagnostics/semantic_analyzer/enums.py,sha256=FIf3bHHqYY2etzpNrZTpZxGFsdtBE15lTssI1g8T2ro,8668
30
30
  robotcode/robot/diagnostics/semantic_analyzer/json_dump.py,sha256=2Yq3CLAKF5IEqKeFDoIYn-Ize_1Ucgz82ORkx3wAguY,13836
31
31
  robotcode/robot/diagnostics/semantic_analyzer/model.py,sha256=YF8txeR5gXzhDLn3Fv3Y8hSo_vItEKkeLE2h3nx9Bmc,18465
32
32
  robotcode/robot/diagnostics/semantic_analyzer/nodes.py,sha256=lwXK648OLbNknFqAN9LP4Z-2k8tk-UuQqWYX-PZ8xIU,16379
@@ -43,6 +43,6 @@ robotcode/robot/utils/robot_path.py,sha256=ObLP8PqamTZAz5oi0eDXE_dnyZwAPXp4TJYm6
43
43
  robotcode/robot/utils/stubs.py,sha256=umugZYAyneFNgqRJBRMJPzm0u0B_TH8Sx_y-ykXnxpw,351
44
44
  robotcode/robot/utils/variables.py,sha256=M_JVe4DxV7ucL_iRW7VOQnSlY6I72NVhRfki4f3zMQY,9430
45
45
  robotcode/robot/utils/visitor.py,sha256=nP3O0qh3YYuxR6S8wYJRBFfNwIVgsgohURBlrnFkRYQ,2299
46
- robotcode_robot-2.8.0.dev548.dist-info/METADATA,sha256=n9eb-HI9tPFmJbVG3HNvEGioqRAx6KUDxFe76rg_F10,2960
47
- robotcode_robot-2.8.0.dev548.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
48
- robotcode_robot-2.8.0.dev548.dist-info/RECORD,,
46
+ robotcode_robot-2.8.0.dev631.dist-info/METADATA,sha256=EGKTTkjAa-1ACqJS7zvLOKWf6CAloJyQL-jCUAJFrC4,2960
47
+ robotcode_robot-2.8.0.dev631.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
48
+ robotcode_robot-2.8.0.dev631.dist-info/RECORD,,