Skip to content

Commit eec1627

Browse files
committed
refactor(robot): optimize RF_VERSION checks with module-level dispatch
- Remove redundant _ROBOT_VERSION alias in semantic_tokens.py - Remove always-true RF >= 5.0 guards (minimum supported version) - Use conditional class-level property/method definitions for is_private and is_reserved in library_doc.py - Add _RF7_PLUS module-level bool for BDD keyword search hot path - Move ExceptHeader/WhileHeader imports to top-level (always available)
1 parent 02cf495 commit eec1627

File tree

5 files changed

+63
-59
lines changed

5 files changed

+63
-59
lines changed

packages/language_server/src/robotcode/language_server/robotframework/parts/semantic_tokens.py

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from robot.parsing.model.statements import (
2828
Arguments,
2929
Documentation,
30+
ExceptHeader,
3031
Fixture,
3132
KeywordCall,
3233
LibraryImport,
@@ -38,6 +39,7 @@
3839
TestTemplate,
3940
Variable,
4041
VariablesImport,
42+
WhileHeader,
4143
)
4244
from robot.utils.escaping import unescape
4345

@@ -76,13 +78,7 @@
7678

7779
from .protocol_part import RobotLanguageServerProtocolPart
7880

79-
# Cache robot version at module level for conditional imports
80-
_ROBOT_VERSION = RF_VERSION
81-
82-
if _ROBOT_VERSION >= (5, 0):
83-
from robot.parsing.model.statements import ExceptHeader, WhileHeader
84-
85-
if _ROBOT_VERSION >= (7, 0):
81+
if RF_VERSION >= (7, 0):
8682
from robot.parsing.model.blocks import InvalidSection
8783

8884
if TYPE_CHECKING:
@@ -293,27 +289,26 @@ def generate_mapping(cls) -> Dict[str, Tuple[AnyTokenType, Optional[Set[AnyToken
293289
),
294290
}
295291

296-
if _ROBOT_VERSION >= (5, 0):
297-
definition.update(
298-
{
299-
frozenset(
300-
{
301-
Token.INLINE_IF,
302-
Token.TRY,
303-
Token.EXCEPT,
304-
Token.FINALLY,
305-
Token.AS,
306-
Token.WHILE,
307-
Token.RETURN_STATEMENT,
308-
Token.CONTINUE,
309-
Token.BREAK,
310-
Token.OPTION,
311-
}
312-
): (RobotSemTokenTypes.CONTROL_FLOW, None)
313-
}
314-
)
292+
definition.update(
293+
{
294+
frozenset(
295+
{
296+
Token.INLINE_IF,
297+
Token.TRY,
298+
Token.EXCEPT,
299+
Token.FINALLY,
300+
Token.AS,
301+
Token.WHILE,
302+
Token.RETURN_STATEMENT,
303+
Token.CONTINUE,
304+
Token.BREAK,
305+
Token.OPTION,
306+
}
307+
): (RobotSemTokenTypes.CONTROL_FLOW, None)
308+
}
309+
)
315310

316-
if _ROBOT_VERSION >= (6, 0):
311+
if RF_VERSION >= (6, 0):
317312
definition.update(
318313
{
319314
frozenset({Token.CONFIG}): (
@@ -326,7 +321,7 @@ def generate_mapping(cls) -> Dict[str, Tuple[AnyTokenType, Optional[Set[AnyToken
326321
),
327322
}
328323
)
329-
if _ROBOT_VERSION >= (7, 0):
324+
if RF_VERSION >= (7, 0):
330325
definition.update(
331326
{
332327
frozenset({Token.VAR}): (RobotSemTokenTypes.VAR, None),
@@ -346,7 +341,7 @@ def generate_mapping(cls) -> Dict[str, Tuple[AnyTokenType, Optional[Set[AnyToken
346341
}
347342
)
348343

349-
if _ROBOT_VERSION >= (7, 2):
344+
if RF_VERSION >= (7, 2):
350345
definition.update(
351346
{
352347
frozenset({Token.GROUP}): (RobotSemTokenTypes.CONTROL_FLOW, None),
@@ -1116,7 +1111,7 @@ def generate_sem_sub_tokens(
11161111
):
11171112
bdd_len = 0
11181113

1119-
if _ROBOT_VERSION < (6, 0):
1114+
if RF_VERSION < (6, 0):
11201115
bdd_match = self.token_mapper.BDD_TOKEN_REGEX.match(token.value)
11211116
if bdd_match:
11221117
bdd_len = len(bdd_match.group(1))
@@ -1214,9 +1209,9 @@ def generate_sem_sub_tokens(
12141209
sem_mod.add(RobotSemTokenModifiers.BUILTIN)
12151210

12161211
if kw_doc is not None and kw_doc.is_embedded and kw_doc.matcher.embedded_arguments:
1217-
if _ROBOT_VERSION >= (7, 3):
1212+
if RF_VERSION >= (7, 3):
12181213
m = kw_doc.matcher.embedded_arguments.name.fullmatch(kw)
1219-
elif _ROBOT_VERSION >= (6, 0):
1214+
elif RF_VERSION >= (6, 0):
12201215
m = kw_doc.matcher.embedded_arguments.match(kw)
12211216
else:
12221217
m = kw_doc.matcher.embedded_arguments.name.match(kw)
@@ -1285,7 +1280,7 @@ def generate_sem_sub_tokens(
12851280
col_offset,
12861281
length,
12871282
)
1288-
elif _ROBOT_VERSION >= (5, 0) and token.type == Token.OPTION:
1283+
elif token.type == Token.OPTION:
12891284
if (
12901285
cached_isinstance(node, ExceptHeader) or cached_isinstance(node, WhileHeader)
12911286
) and "=" in token.value:
@@ -1464,7 +1459,7 @@ def get_tokens() -> Iterator[Tuple[Token, ast.AST]]:
14641459
for node in iter_nodes(model):
14651460
if cached_isinstance(node, Section):
14661461
current_section = node
1467-
if _ROBOT_VERSION >= (7, 0):
1462+
if RF_VERSION >= (7, 0):
14681463
in_invalid_section = cached_isinstance(current_section, InvalidSection)
14691464

14701465
check_current_task_canceled()

packages/robot/src/robotcode/robot/diagnostics/keyword_finder.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
LibraryDoc,
2323
)
2424

25+
_RF7_PLUS = RF_VERSION >= (7, 0)
26+
2527

2628
class DiagnosticsEntry(NamedTuple):
2729
message: str
@@ -163,7 +165,7 @@ def _find_keyword(
163165

164166
result: Optional[KeywordDoc] = None
165167

166-
if RF_VERSION >= (7, 0) and handle_bdd_style:
168+
if _RF7_PLUS and handle_bdd_style:
167169
result = self._get_bdd_style_keyword(name)
168170

169171
if not result:
@@ -175,7 +177,7 @@ def _find_keyword(
175177
if not result:
176178
result = self._get_implicit_keyword(name)
177179

178-
if RF_VERSION < (7, 0) and not result and handle_bdd_style:
180+
if not _RF7_PLUS and not result and handle_bdd_style:
179181
return self._get_bdd_style_keyword(name)
180182

181183
return result
@@ -511,7 +513,7 @@ def bdd_prefix_regexp(self) -> "re.Pattern[str]":
511513
def _get_bdd_style_keyword(self, name: str) -> Optional[KeywordDoc]:
512514
match = self.bdd_prefix_regexp.match(name)
513515
if match:
514-
result = self._find_keyword(name[match.end() :], handle_bdd_style=False if RF_VERSION >= (7, 0) else True)
516+
result = self._find_keyword(name[match.end() :], handle_bdd_style=not _RF7_PLUS)
515517
if result:
516518
self.result_bdd_prefix = str(match.group(0))
517519

packages/robot/src/robotcode/robot/diagnostics/library_doc.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -818,12 +818,17 @@ def name_range(self) -> Range:
818818
def normalized_tags(self) -> List[str]:
819819
return [normalize(tag) for tag in self.tags]
820820

821-
@property
822-
def is_private(self) -> bool:
823-
if RF_VERSION < (6, 0):
824-
return False
821+
if RF_VERSION >= (6, 0):
822+
823+
@property
824+
def is_private(self) -> bool:
825+
return "robot:private" in self.normalized_tags
825826

826-
return "robot:private" in self.normalized_tags
827+
else:
828+
829+
@property
830+
def is_private(self) -> bool:
831+
return False
827832

828833
@property
829834
def range(self) -> Range:
@@ -967,11 +972,15 @@ def parameter_signature(self, full_signatures: Optional[Sequence[int]] = None) -
967972
+ ")"
968973
)
969974

970-
def is_reserved(self) -> bool:
971-
if RF_VERSION < (7, 0):
975+
if RF_VERSION < (7, 0):
976+
977+
def is_reserved(self) -> bool:
972978
return self.libname == RESERVED_LIBRARY_NAME
973979

974-
return False
980+
else:
981+
982+
def is_reserved(self) -> bool:
983+
return False
975984

976985
def is_any_run_keyword(self) -> bool:
977986
return self.libname == BUILTIN_LIBRARY_NAME and self.name in ALL_RUN_KEYWORDS

packages/robot/src/robotcode/robot/diagnostics/namespace_analyzer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ def _analyze_keyword_call(
843843
code=Error.RESERVED_KEYWORD,
844844
)
845845

846-
if RF_VERSION >= (6, 0) and result.is_resource_keyword and result.is_private:
846+
if result.is_resource_keyword and result.is_private:
847847
if self._source != result.source:
848848
self._append_diagnostics(
849849
range=kw_range,

tests/robotcode/language_server/robotframework/parts/test_semantic_tokens_unit.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -116,27 +116,25 @@ def test_robot_framework_version_specific_mappings(self) -> None:
116116
"""Test that version-specific token mappings are correct."""
117117
mapper = SemanticTokenMapper()
118118
mapping = mapper.mapping()
119-
rf_version = RF_VERSION
120-
121-
# RF 5.0+ tokens
122-
if rf_version >= (5, 0):
123-
rf5_tokens = [Token.TRY, Token.EXCEPT, Token.FINALLY, Token.WHILE, Token.CONTINUE, Token.BREAK]
124-
for token_type in rf5_tokens:
125-
if hasattr(Token, token_type): # Check if token exists in this RF version
126-
token_val = getattr(Token, token_type)
127-
assert token_val in mapping, f"RF 5.0+ token {token_type} should be in mapping"
128-
sem_type, _ = mapping[token_val]
129-
assert sem_type == RobotSemTokenTypes.CONTROL_FLOW
119+
120+
# RF 5.0+ tokens (always present, RF >= 5.0 is minimum)
121+
rf5_tokens = [Token.TRY, Token.EXCEPT, Token.FINALLY, Token.WHILE, Token.CONTINUE, Token.BREAK]
122+
for token_type in rf5_tokens:
123+
if hasattr(Token, token_type): # Check if token exists in this RF version
124+
token_val = getattr(Token, token_type)
125+
assert token_val in mapping, f"RF 5.0+ token {token_type} should be in mapping"
126+
sem_type, _ = mapping[token_val]
127+
assert sem_type == RobotSemTokenTypes.CONTROL_FLOW
130128

131129
# RF 6.0+ tokens
132-
if rf_version >= (6, 0):
130+
if RF_VERSION >= (6, 0):
133131
if hasattr(Token, "CONFIG"):
134132
assert Token.CONFIG in mapping
135133
sem_type, _ = mapping[Token.CONFIG]
136134
assert sem_type == RobotSemTokenTypes.CONFIG
137135

138136
# RF 7.0+ tokens
139-
if rf_version >= (7, 0):
137+
if RF_VERSION >= (7, 0):
140138
if hasattr(Token, "VAR"):
141139
assert Token.VAR in mapping
142140
sem_type, _ = mapping[Token.VAR]

0 commit comments

Comments
 (0)