robotcode-robot 0.83.3__tar.gz → 0.85.0__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/.gitignore +3 -0
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/PKG-INFO +2 -2
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/pyproject.toml +1 -1
- robotcode_robot-0.85.0/src/robotcode/robot/__version__.py +1 -0
- robotcode_robot-0.85.0/src/robotcode/robot/diagnostics/diagnostics_modifier.py +201 -0
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/diagnostics/document_cache_helper.py +8 -3
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/diagnostics/entities.py +2 -6
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/diagnostics/errors.py +2 -0
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/diagnostics/library_doc.py +7 -7
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/diagnostics/namespace.py +8 -55
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/diagnostics/namespace_analyzer.py +3 -18
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/utils/ast.py +3 -3
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/utils/match.py +4 -1
- robotcode_robot-0.83.3/src/robotcode/robot/__version__.py +0 -1
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/LICENSE.txt +0 -0
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/README.md +0 -0
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/__init__.py +0 -0
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/config/__init__.py +0 -0
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/config/loader.py +0 -0
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/config/model.py +0 -0
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/config/utils.py +0 -0
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/diagnostics/__init__.py +0 -0
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/diagnostics/imports_manager.py +0 -0
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/diagnostics/model_helper.py +0 -0
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/diagnostics/workspace_config.py +0 -0
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/py.typed +0 -0
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/utils/__init__.py +0 -0
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/utils/markdownformatter.py +0 -0
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/utils/robot_path.py +0 -0
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/utils/stubs.py +0 -0
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/utils/variables.py +0 -0
- {robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/utils/visitor.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: robotcode-robot
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.85.0
|
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
|
@@ -26,7 +26,7 @@ Classifier: Topic :: Utilities
|
|
26
26
|
Classifier: Typing :: Typed
|
27
27
|
Requires-Python: >=3.8
|
28
28
|
Requires-Dist: platformdirs<4.2.0,>=3.2.0
|
29
|
-
Requires-Dist: robotcode-core==0.
|
29
|
+
Requires-Dist: robotcode-core==0.85.0
|
30
30
|
Requires-Dist: robotframework>=4.1.0
|
31
31
|
Requires-Dist: tomli>=1.1.0; python_version < '3.11'
|
32
32
|
Description-Content-Type: text/markdown
|
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = "0.85.0"
|
@@ -0,0 +1,201 @@
|
|
1
|
+
import functools
|
2
|
+
import re as re
|
3
|
+
from ast import AST
|
4
|
+
from collections import defaultdict
|
5
|
+
from dataclasses import dataclass
|
6
|
+
from typing import Dict, List, Optional, Set, Union
|
7
|
+
|
8
|
+
from robot.parsing.lexer.tokens import Token
|
9
|
+
from robot.parsing.model.blocks import Block, File
|
10
|
+
from robot.parsing.model.statements import Comment, Statement
|
11
|
+
from robotcode.core.lsp.types import Diagnostic, DiagnosticSeverity
|
12
|
+
|
13
|
+
from ..utils.visitor import Visitor
|
14
|
+
|
15
|
+
ACTIONS = ["ignore", "error", "warn", "information", "hint", "reset"]
|
16
|
+
|
17
|
+
ROBOTCODE_ACTION_AND_CODES_PATTERN = re.compile(rf"(?P<action>{'|'.join(ACTIONS)})(\[(?P<codes>[^\]]*?)\])?")
|
18
|
+
|
19
|
+
|
20
|
+
@dataclass
|
21
|
+
class RulesAndCodes:
|
22
|
+
codes: Dict[Union[str, int], Set[int]]
|
23
|
+
actions: Dict[int, Dict[Union[str, int], str]]
|
24
|
+
|
25
|
+
|
26
|
+
_translation_table = str.maketrans("", "", "_- ")
|
27
|
+
|
28
|
+
ROBOTCODE_MARKER = "robotcode:"
|
29
|
+
|
30
|
+
|
31
|
+
class DisablersVisitor(Visitor):
|
32
|
+
|
33
|
+
def __init__(self) -> None:
|
34
|
+
super().__init__()
|
35
|
+
|
36
|
+
self._file_lineno = 0
|
37
|
+
self._file_end_lineno = 0
|
38
|
+
self.current_block: Optional[Block] = None
|
39
|
+
self.rules_and_codes: RulesAndCodes = RulesAndCodes(defaultdict(set), defaultdict(dict))
|
40
|
+
|
41
|
+
@property
|
42
|
+
def file_lineno(self) -> int:
|
43
|
+
return self._file_lineno
|
44
|
+
|
45
|
+
@property
|
46
|
+
def file_end_lineno(self) -> int:
|
47
|
+
return self._file_end_lineno
|
48
|
+
|
49
|
+
def visit_File(self, node: File) -> None: # noqa: N802
|
50
|
+
self._file_lineno = node.lineno - 1
|
51
|
+
self._file_end_lineno = node.end_lineno - 1
|
52
|
+
|
53
|
+
self.generic_visit(node)
|
54
|
+
|
55
|
+
def visit_Comment(self, node: Comment) -> None: # noqa: N802
|
56
|
+
self._handle_comment(node)
|
57
|
+
|
58
|
+
self.generic_visit(node)
|
59
|
+
|
60
|
+
def visit_Block(self, node: Block) -> None: # noqa: N802
|
61
|
+
self.current_block = node
|
62
|
+
self.generic_visit(node)
|
63
|
+
|
64
|
+
def visit_Statement(self, node: Statement) -> None: # noqa: N802
|
65
|
+
self._handle_statement_comments(node)
|
66
|
+
self.generic_visit(node)
|
67
|
+
|
68
|
+
def _parse_robotcode_disabler(self, comment: str) -> Dict[str, List[str]]:
|
69
|
+
result: Dict[str, List[str]] = {}
|
70
|
+
|
71
|
+
comment = comment.strip()
|
72
|
+
m = ROBOTCODE_ACTION_AND_CODES_PATTERN.match(comment)
|
73
|
+
if m is None:
|
74
|
+
return result
|
75
|
+
|
76
|
+
for m in ROBOTCODE_ACTION_AND_CODES_PATTERN.finditer(comment):
|
77
|
+
action = m.group("action")
|
78
|
+
messages = m.group("codes")
|
79
|
+
result[action] = (
|
80
|
+
[m.strip().translate(_translation_table).lower() for m in messages.split(",")]
|
81
|
+
if messages is not None
|
82
|
+
else ["*"]
|
83
|
+
)
|
84
|
+
|
85
|
+
return result
|
86
|
+
|
87
|
+
def _handle_statement_comments(self, node: Statement) -> None:
|
88
|
+
first_comment = True
|
89
|
+
has_marker = False
|
90
|
+
|
91
|
+
for token in node.get_tokens(Token.COMMENT):
|
92
|
+
value = token.value.strip()
|
93
|
+
if first_comment and value.startswith("#"):
|
94
|
+
value = value[1:].strip()
|
95
|
+
first_comment = False
|
96
|
+
|
97
|
+
if not value:
|
98
|
+
continue
|
99
|
+
|
100
|
+
if not has_marker and value.startswith(ROBOTCODE_MARKER):
|
101
|
+
has_marker = True
|
102
|
+
value = value[10:]
|
103
|
+
|
104
|
+
if not value:
|
105
|
+
continue
|
106
|
+
|
107
|
+
if has_marker:
|
108
|
+
actions = self._parse_robotcode_disabler(value)
|
109
|
+
|
110
|
+
if not actions:
|
111
|
+
break
|
112
|
+
|
113
|
+
for action, codes in actions.items():
|
114
|
+
for code in codes:
|
115
|
+
self.rules_and_codes.codes[code].add(token.lineno - 1)
|
116
|
+
self.rules_and_codes.actions[token.lineno - 1][code] = action
|
117
|
+
|
118
|
+
def _handle_comment(self, node: Comment) -> None:
|
119
|
+
first_comment = True
|
120
|
+
has_marker = False
|
121
|
+
|
122
|
+
start_lineno = node.lineno - 1
|
123
|
+
end_lineno = self.file_end_lineno
|
124
|
+
|
125
|
+
if node.tokens[0].type == Token.SEPARATOR and self.current_block is not None:
|
126
|
+
end_lineno = self.current_block.end_lineno - 1
|
127
|
+
for token in node.get_tokens(Token.COMMENT):
|
128
|
+
value = token.value.strip()
|
129
|
+
if first_comment and value.startswith("#"):
|
130
|
+
value = value[1:].strip()
|
131
|
+
first_comment = False
|
132
|
+
|
133
|
+
if not value:
|
134
|
+
continue
|
135
|
+
|
136
|
+
if not has_marker and value.startswith(ROBOTCODE_MARKER):
|
137
|
+
has_marker = True
|
138
|
+
value = value[10:]
|
139
|
+
|
140
|
+
if not value:
|
141
|
+
continue
|
142
|
+
|
143
|
+
if has_marker:
|
144
|
+
actions = self._parse_robotcode_disabler(value)
|
145
|
+
|
146
|
+
if not actions:
|
147
|
+
break
|
148
|
+
|
149
|
+
for action, codes in actions.items():
|
150
|
+
for code in codes:
|
151
|
+
self.rules_and_codes.codes[code].update(range(start_lineno, end_lineno + 1))
|
152
|
+
for i in range(start_lineno, end_lineno + 1):
|
153
|
+
self.rules_and_codes.actions[i][code] = action
|
154
|
+
|
155
|
+
|
156
|
+
class DiagnosticsModifier:
|
157
|
+
def __init__(self, model: AST) -> None:
|
158
|
+
self.model = model
|
159
|
+
|
160
|
+
@functools.cached_property
|
161
|
+
def rules_and_codes(self) -> RulesAndCodes:
|
162
|
+
visitor = DisablersVisitor()
|
163
|
+
visitor.visit(self.model)
|
164
|
+
return visitor.rules_and_codes
|
165
|
+
|
166
|
+
def modify_diagnostic(self, diagnostic: Diagnostic) -> Optional[Diagnostic]:
|
167
|
+
if diagnostic.code is not None:
|
168
|
+
code = (
|
169
|
+
str(diagnostic.code).translate(_translation_table).lower()
|
170
|
+
if diagnostic.code is not None
|
171
|
+
else "unknowncode"
|
172
|
+
)
|
173
|
+
|
174
|
+
lines = self.rules_and_codes.codes.get(code)
|
175
|
+
|
176
|
+
if lines is None or lines is not None and diagnostic.range.start.line not in lines:
|
177
|
+
code = "*"
|
178
|
+
lines = self.rules_and_codes.codes.get(code)
|
179
|
+
|
180
|
+
if lines is not None and diagnostic.range.start.line in lines:
|
181
|
+
actions = self.rules_and_codes.actions.get(diagnostic.range.start.line)
|
182
|
+
if actions is not None:
|
183
|
+
action = actions.get(code)
|
184
|
+
if action is not None:
|
185
|
+
if action == "ignore":
|
186
|
+
return None
|
187
|
+
if action == "reset":
|
188
|
+
pass # do nothing
|
189
|
+
elif action == "error":
|
190
|
+
diagnostic.severity = DiagnosticSeverity.ERROR
|
191
|
+
elif action == "warn":
|
192
|
+
diagnostic.severity = DiagnosticSeverity.WARNING
|
193
|
+
elif action == "information":
|
194
|
+
diagnostic.severity = DiagnosticSeverity.INFORMATION
|
195
|
+
elif action == "hint":
|
196
|
+
diagnostic.severity = DiagnosticSeverity.HINT
|
197
|
+
|
198
|
+
return diagnostic
|
199
|
+
|
200
|
+
def modify_diagnostics(self, diagnostics: List[Diagnostic]) -> List[Diagnostic]:
|
201
|
+
return [d for d in map(self.modify_diagnostic, diagnostics) if d is not None]
|
@@ -26,6 +26,7 @@ from robotcode.core.text_document import TextDocument
|
|
26
26
|
from robotcode.core.uri import Uri
|
27
27
|
from robotcode.core.utils.logging import LoggingDescriptor
|
28
28
|
from robotcode.core.workspace import Workspace, WorkspaceFolder
|
29
|
+
from robotcode.robot.diagnostics.diagnostics_modifier import DiagnosticsModifier
|
29
30
|
|
30
31
|
from ..config.model import RobotBaseProfile
|
31
32
|
from ..utils import get_robot_version
|
@@ -453,9 +454,7 @@ class DocumentsCacheHelper:
|
|
453
454
|
return result
|
454
455
|
|
455
456
|
def get_only_initialized_namespace(self, document: TextDocument) -> Optional[Namespace]:
|
456
|
-
|
457
|
-
|
458
|
-
return result
|
457
|
+
return cast(Optional[Namespace], document.get_data(self.INITIALIZED_NAMESPACE))
|
459
458
|
|
460
459
|
def __get_namespace_for_document_type(
|
461
460
|
self, document: TextDocument, document_type: Optional[DocumentType]
|
@@ -579,3 +578,9 @@ class DocumentsCacheHelper:
|
|
579
578
|
def calc_cache_path(self, folder_uri: Uri) -> Path:
|
580
579
|
# TODO: cache path should be configurable, save cache in vscode workspace folder or in robotcode cache folder
|
581
580
|
return folder_uri.to_path()
|
581
|
+
|
582
|
+
def get_diagnostic_modifier(self, document: TextDocument) -> DiagnosticsModifier:
|
583
|
+
return document.get_cache(self.__get_diagnostic_modifier)
|
584
|
+
|
585
|
+
def __get_diagnostic_modifier(self, document: TextDocument) -> DiagnosticsModifier:
|
586
|
+
return DiagnosticsModifier(self.get_model(document, False))
|
{robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/diagnostics/entities.py
RENAMED
@@ -12,7 +12,9 @@ from typing import (
|
|
12
12
|
)
|
13
13
|
|
14
14
|
from robot.parsing.lexer.tokens import Token
|
15
|
+
from robot.variables.search import search_variable
|
15
16
|
from robotcode.core.lsp.types import Position, Range
|
17
|
+
from robotcode.robot.utils.match import normalize
|
16
18
|
|
17
19
|
from ..utils.ast import range_from_token
|
18
20
|
|
@@ -131,9 +133,6 @@ class InvalidVariableError(Exception):
|
|
131
133
|
|
132
134
|
class VariableMatcher:
|
133
135
|
def __init__(self, name: str) -> None:
|
134
|
-
from robot.variables.search import search_variable
|
135
|
-
from robotcode.robot.utils.match import normalize
|
136
|
-
|
137
136
|
self.name = name
|
138
137
|
|
139
138
|
match = search_variable(name, "$@&%", ignore_errors=True)
|
@@ -146,9 +145,6 @@ class VariableMatcher:
|
|
146
145
|
self.normalized_name = str(normalize(self.base))
|
147
146
|
|
148
147
|
def __eq__(self, o: object) -> bool:
|
149
|
-
from robot.utils.normalizing import normalize
|
150
|
-
from robot.variables.search import search_variable
|
151
|
-
|
152
148
|
if isinstance(o, VariableMatcher):
|
153
149
|
return o.normalized_name == self.normalized_name
|
154
150
|
|
{robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/diagnostics/library_doc.py
RENAMED
@@ -86,10 +86,10 @@ from robotcode.robot.utils.match import normalize, normalize_namespace
|
|
86
86
|
from robotcode.robot.utils.stubs import HasError, HasErrors
|
87
87
|
|
88
88
|
if get_robot_version() < (7, 0):
|
89
|
-
from robot.running.handlers import _PythonHandler, _PythonInitHandler
|
90
|
-
from robot.running.model import ResourceFile
|
91
|
-
from robot.running.usererrorhandler import UserErrorHandler
|
92
|
-
from robot.running.userkeyword import UserLibrary
|
89
|
+
from robot.running.handlers import _PythonHandler, _PythonInitHandler # pyright: ignore[reportMissingImports]
|
90
|
+
from robot.running.model import ResourceFile # pyright: ignore[reportMissingImports]
|
91
|
+
from robot.running.usererrorhandler import UserErrorHandler # pyright: ignore[reportMissingImports]
|
92
|
+
from robot.running.userkeyword import UserLibrary # pyright: ignore[reportMissingImports]
|
93
93
|
|
94
94
|
robot_notset = ArgInfo.NOTSET
|
95
95
|
|
@@ -1960,7 +1960,7 @@ def get_library_doc(
|
|
1960
1960
|
return_type=(
|
1961
1961
|
(
|
1962
1962
|
str(kw[1].args.return_type)
|
1963
|
-
if kw[1].args.return_type is not None and kw[1].args.return_type
|
1963
|
+
if kw[1].args.return_type is not None and kw[1].args.return_type is not type(None)
|
1964
1964
|
else None
|
1965
1965
|
)
|
1966
1966
|
if get_robot_version() >= (7, 0)
|
@@ -2636,7 +2636,7 @@ def get_model_doc(
|
|
2636
2636
|
message=error,
|
2637
2637
|
type_name="ModelError",
|
2638
2638
|
source=source,
|
2639
|
-
line_no=node.lineno,
|
2639
|
+
line_no=node.lineno, # type: ignore
|
2640
2640
|
)
|
2641
2641
|
)
|
2642
2642
|
if append_model_errors:
|
@@ -2648,7 +2648,7 @@ def get_model_doc(
|
|
2648
2648
|
message=e,
|
2649
2649
|
type_name="ModelError",
|
2650
2650
|
source=source,
|
2651
|
-
line_no=node.lineno,
|
2651
|
+
line_no=node.lineno, # type: ignore
|
2652
2652
|
)
|
2653
2653
|
)
|
2654
2654
|
|
{robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/diagnostics/namespace.py
RENAMED
@@ -1,7 +1,6 @@
|
|
1
1
|
import ast
|
2
2
|
import enum
|
3
3
|
import itertools
|
4
|
-
import re
|
5
4
|
import time
|
6
5
|
import weakref
|
7
6
|
from collections import OrderedDict, defaultdict
|
@@ -97,9 +96,6 @@ from .library_doc import (
|
|
97
96
|
resolve_robot_variables,
|
98
97
|
)
|
99
98
|
|
100
|
-
EXTRACT_COMMENT_PATTERN = re.compile(r".*(?:^ *|\t+| {2,})#(?P<comment>.*)$")
|
101
|
-
ROBOTCODE_PATTERN = re.compile(r"(?P<marker>\brobotcode\b)\s*:\s*(?P<rule>\b\w+\b)")
|
102
|
-
|
103
99
|
|
104
100
|
class DiagnosticsError(Exception):
|
105
101
|
pass
|
@@ -454,7 +450,7 @@ class BlockVariableVisitor(OnlyArgumentsVisitor):
|
|
454
450
|
source=self.namespace.source,
|
455
451
|
)
|
456
452
|
|
457
|
-
if var_name not in self._results or type(self._results[var_name])
|
453
|
+
if var_name not in self._results or type(self._results[var_name]) is not type(var):
|
458
454
|
if isinstance(var, LocalVariableDefinition) or not any(
|
459
455
|
l for l in self.namespace.get_global_variables() if l.matcher == var.matcher
|
460
456
|
):
|
@@ -542,7 +538,7 @@ class BlockVariableVisitor(OnlyArgumentsVisitor):
|
|
542
538
|
source=self.namespace.source,
|
543
539
|
)
|
544
540
|
|
545
|
-
if var_name not in self._results or type(self._results[var_name])
|
541
|
+
if var_name not in self._results or type(self._results[var_name]) is type(var):
|
546
542
|
if isinstance(var, LocalVariableDefinition) or not any(
|
547
543
|
l for l in self.namespace.get_global_variables() if l.matcher == var.matcher
|
548
544
|
):
|
@@ -1803,8 +1799,6 @@ class Namespace:
|
|
1803
1799
|
related_information: Optional[List[DiagnosticRelatedInformation]] = None,
|
1804
1800
|
data: Optional[Any] = None,
|
1805
1801
|
) -> None:
|
1806
|
-
if self._should_ignore(range):
|
1807
|
-
return
|
1808
1802
|
|
1809
1803
|
self._diagnostics.append(
|
1810
1804
|
Diagnostic(
|
@@ -1840,12 +1834,7 @@ class Namespace:
|
|
1840
1834
|
start_time = time.monotonic()
|
1841
1835
|
|
1842
1836
|
try:
|
1843
|
-
result = NamespaceAnalyzer(
|
1844
|
-
self.model,
|
1845
|
-
self,
|
1846
|
-
self.create_finder(),
|
1847
|
-
self.get_ignored_lines(self.document) if self.document is not None else [],
|
1848
|
-
).run()
|
1837
|
+
result = NamespaceAnalyzer(self.model, self, self.create_finder()).run()
|
1849
1838
|
|
1850
1839
|
self._diagnostics += result.diagnostics
|
1851
1840
|
self._keyword_references = result.keyword_references
|
@@ -1916,42 +1905,6 @@ class Namespace:
|
|
1916
1905
|
handle_bdd_style=handle_bdd_style,
|
1917
1906
|
)
|
1918
1907
|
|
1919
|
-
@classmethod
|
1920
|
-
def get_ignored_lines(cls, document: TextDocument) -> List[int]:
|
1921
|
-
return document.get_cache(cls.__get_ignored_lines)
|
1922
|
-
|
1923
|
-
@staticmethod
|
1924
|
-
def __get_ignored_lines(document: TextDocument) -> List[int]:
|
1925
|
-
result = []
|
1926
|
-
lines = document.get_lines()
|
1927
|
-
for line_no, line in enumerate(lines):
|
1928
|
-
comment = EXTRACT_COMMENT_PATTERN.match(line)
|
1929
|
-
if comment and comment.group("comment"):
|
1930
|
-
for match in ROBOTCODE_PATTERN.finditer(comment.group("comment")):
|
1931
|
-
if match.group("rule") == "ignore":
|
1932
|
-
result.append(line_no)
|
1933
|
-
|
1934
|
-
return result
|
1935
|
-
|
1936
|
-
@classmethod
|
1937
|
-
def should_ignore(cls, document: Optional[TextDocument], range: Range) -> bool:
|
1938
|
-
return cls.__should_ignore(
|
1939
|
-
cls.get_ignored_lines(document) if document is not None else [],
|
1940
|
-
range,
|
1941
|
-
)
|
1942
|
-
|
1943
|
-
def _should_ignore(self, range: Range) -> bool:
|
1944
|
-
if self._ignored_lines is None:
|
1945
|
-
self._ignored_lines = self.get_ignored_lines(self.document) if self.document is not None else []
|
1946
|
-
|
1947
|
-
return self.__should_ignore(self._ignored_lines, range)
|
1948
|
-
|
1949
|
-
@staticmethod
|
1950
|
-
def __should_ignore(lines: List[int], range: Range) -> bool:
|
1951
|
-
import builtins
|
1952
|
-
|
1953
|
-
return any(line_no in lines for line_no in builtins.range(range.start.line, range.end.line + 1))
|
1954
|
-
|
1955
1908
|
|
1956
1909
|
class DiagnosticsEntry(NamedTuple):
|
1957
1910
|
message: str
|
@@ -2083,7 +2036,7 @@ class KeywordFinder:
|
|
2083
2036
|
DiagnosticsEntry(
|
2084
2037
|
self._create_multiple_keywords_found_message(name, found, implicit=False),
|
2085
2038
|
DiagnosticSeverity.ERROR,
|
2086
|
-
Error.
|
2039
|
+
Error.MULTIPLE_KEYWORDS,
|
2087
2040
|
)
|
2088
2041
|
)
|
2089
2042
|
raise CancelSearchError
|
@@ -2118,7 +2071,7 @@ class KeywordFinder:
|
|
2118
2071
|
DiagnosticsEntry(
|
2119
2072
|
self._create_multiple_keywords_found_message(name, found, implicit=False),
|
2120
2073
|
DiagnosticSeverity.ERROR,
|
2121
|
-
Error.
|
2074
|
+
Error.MULTIPLE_KEYWORDS,
|
2122
2075
|
)
|
2123
2076
|
)
|
2124
2077
|
raise CancelSearchError
|
@@ -2266,7 +2219,7 @@ class KeywordFinder:
|
|
2266
2219
|
DiagnosticsEntry(
|
2267
2220
|
self._create_multiple_keywords_found_message(name, found),
|
2268
2221
|
DiagnosticSeverity.ERROR,
|
2269
|
-
Error.
|
2222
|
+
Error.MULTIPLE_KEYWORDS,
|
2270
2223
|
)
|
2271
2224
|
)
|
2272
2225
|
raise CancelSearchError
|
@@ -2320,7 +2273,7 @@ class KeywordFinder:
|
|
2320
2273
|
DiagnosticsEntry(
|
2321
2274
|
self._create_multiple_keywords_found_message(name, found),
|
2322
2275
|
DiagnosticSeverity.ERROR,
|
2323
|
-
Error.
|
2276
|
+
Error.MULTIPLE_KEYWORDS,
|
2324
2277
|
)
|
2325
2278
|
)
|
2326
2279
|
raise CancelSearchError
|
@@ -2342,7 +2295,7 @@ class KeywordFinder:
|
|
2342
2295
|
DiagnosticsEntry(
|
2343
2296
|
self._create_custom_and_standard_keyword_conflict_warning_message(custom, standard),
|
2344
2297
|
DiagnosticSeverity.WARNING,
|
2345
|
-
Error.
|
2298
|
+
Error.CONFLICTING_LIBRARY_KEYWORDS,
|
2346
2299
|
)
|
2347
2300
|
)
|
2348
2301
|
|
@@ -117,14 +117,12 @@ class NamespaceAnalyzer(Visitor, ModelHelper):
|
|
117
117
|
model: ast.AST,
|
118
118
|
namespace: Namespace,
|
119
119
|
finder: KeywordFinder,
|
120
|
-
ignored_lines: List[int],
|
121
120
|
) -> None:
|
122
121
|
super().__init__()
|
123
122
|
|
124
123
|
self.model = model
|
125
124
|
self.namespace = namespace
|
126
125
|
self.finder = finder
|
127
|
-
self._ignored_lines = ignored_lines
|
128
126
|
|
129
127
|
self.current_testcase_or_keyword_name: Optional[str] = None
|
130
128
|
self.test_template: Optional[TestTemplate] = None
|
@@ -261,8 +259,6 @@ class NamespaceAnalyzer(Visitor, ModelHelper):
|
|
261
259
|
)
|
262
260
|
)
|
263
261
|
)
|
264
|
-
# r.start.character = 0
|
265
|
-
# r.end.character = 0
|
266
262
|
|
267
263
|
var_def = self.namespace.find_variable(
|
268
264
|
name,
|
@@ -450,15 +446,6 @@ class NamespaceAnalyzer(Visitor, ModelHelper):
|
|
450
446
|
finally:
|
451
447
|
self.node_stack = self.node_stack[:-1]
|
452
448
|
|
453
|
-
def _should_ignore(self, range: Range) -> bool:
|
454
|
-
import builtins
|
455
|
-
|
456
|
-
for line_no in builtins.range(range.start.line, range.end.line + 1):
|
457
|
-
if line_no in self._ignored_lines:
|
458
|
-
return True
|
459
|
-
|
460
|
-
return False
|
461
|
-
|
462
449
|
def append_diagnostics(
|
463
450
|
self,
|
464
451
|
range: Range,
|
@@ -471,8 +458,6 @@ class NamespaceAnalyzer(Visitor, ModelHelper):
|
|
471
458
|
related_information: Optional[List[DiagnosticRelatedInformation]] = None,
|
472
459
|
data: Optional[Any] = None,
|
473
460
|
) -> None:
|
474
|
-
if self._should_ignore(range):
|
475
|
-
return
|
476
461
|
|
477
462
|
self._diagnostics.append(
|
478
463
|
Diagnostic(
|
@@ -1167,7 +1152,7 @@ class NamespaceAnalyzer(Visitor, ModelHelper):
|
|
1167
1152
|
for v in entries.values():
|
1168
1153
|
if v.import_source == self.namespace.source and v.import_range == range_from_token(name_token):
|
1169
1154
|
for k in self._namespace_references:
|
1170
|
-
if type(k)
|
1155
|
+
if type(k) is type(v) and k.library_doc.source_or_origin == v.library_doc.source_or_origin:
|
1171
1156
|
self._namespace_references[k].add(
|
1172
1157
|
Location(self.namespace.document.document_uri, v.import_range)
|
1173
1158
|
)
|
@@ -1192,7 +1177,7 @@ class NamespaceAnalyzer(Visitor, ModelHelper):
|
|
1192
1177
|
for v in entries.values():
|
1193
1178
|
if v.import_source == self.namespace.source and v.import_range == range_from_token(name_token):
|
1194
1179
|
for k in self._namespace_references:
|
1195
|
-
if type(k)
|
1180
|
+
if type(k) is type(v) and k.library_doc.source_or_origin == v.library_doc.source_or_origin:
|
1196
1181
|
self._namespace_references[k].add(
|
1197
1182
|
Location(self.namespace.document.document_uri, v.import_range)
|
1198
1183
|
)
|
@@ -1217,7 +1202,7 @@ class NamespaceAnalyzer(Visitor, ModelHelper):
|
|
1217
1202
|
for v in entries.values():
|
1218
1203
|
if v.import_source == self.namespace.source and v.import_range == range_from_token(name_token):
|
1219
1204
|
for k in self._namespace_references:
|
1220
|
-
if type(k)
|
1205
|
+
if type(k) is type(v) and k.library_doc.source_or_origin == v.library_doc.source_or_origin:
|
1221
1206
|
self._namespace_references[k].add(
|
1222
1207
|
Location(self.namespace.document.document_uri, v.import_range)
|
1223
1208
|
)
|
@@ -129,10 +129,10 @@ def range_from_node(
|
|
129
129
|
return Range(start=first_range.start, end=last_range.end)
|
130
130
|
|
131
131
|
return Range(
|
132
|
-
start=Position(line=node.lineno - 1, character=node.col_offset),
|
132
|
+
start=Position(line=node.lineno - 1, character=node.col_offset), # type: ignore
|
133
133
|
end=Position(
|
134
|
-
line=node.end_lineno - 1 if node.end_lineno is not None else -1,
|
135
|
-
character=node.end_col_offset if node.end_col_offset is not None else -1,
|
134
|
+
line=node.end_lineno - 1 if node.end_lineno is not None else -1, # type: ignore
|
135
|
+
character=node.end_col_offset if node.end_col_offset is not None else -1, # type: ignore
|
136
136
|
),
|
137
137
|
)
|
138
138
|
|
@@ -1,9 +1,12 @@
|
|
1
1
|
from functools import lru_cache
|
2
2
|
|
3
|
+
_transform_table = str.maketrans("", "", "_ ")
|
4
|
+
|
3
5
|
|
4
6
|
@lru_cache(maxsize=5000)
|
5
7
|
def normalize(text: str) -> str:
|
6
|
-
return text.lower().replace("_", "").replace(" ", "")
|
8
|
+
# return text.lower().replace("_", "").replace(" ", "")
|
9
|
+
return text.casefold().translate(_transform_table)
|
7
10
|
|
8
11
|
|
9
12
|
@lru_cache(maxsize=5000)
|
@@ -1 +0,0 @@
|
|
1
|
-
__version__ = "0.83.3"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/diagnostics/__init__.py
RENAMED
File without changes
|
{robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/diagnostics/imports_manager.py
RENAMED
File without changes
|
{robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/diagnostics/model_helper.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{robotcode_robot-0.83.3 → robotcode_robot-0.85.0}/src/robotcode/robot/utils/markdownformatter.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|