robotcode-robot 0.94.0__py3-none-any.whl → 0.95.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- robotcode/robot/__version__.py +1 -1
- robotcode/robot/diagnostics/data_cache.py +83 -0
- robotcode/robot/diagnostics/entities.py +1 -1
- robotcode/robot/diagnostics/errors.py +1 -1
- robotcode/robot/diagnostics/imports_manager.py +100 -99
- robotcode/robot/diagnostics/keyword_finder.py +51 -24
- robotcode/robot/diagnostics/library_doc.py +165 -105
- robotcode/robot/diagnostics/model_helper.py +7 -3
- robotcode/robot/diagnostics/namespace.py +17 -28
- robotcode/robot/diagnostics/namespace_analyzer.py +120 -43
- robotcode/robot/utils/match.py +2 -2
- robotcode/robot/utils/robot_path.py +14 -15
- robotcode/robot/utils/variables.py +35 -0
- {robotcode_robot-0.94.0.dist-info → robotcode_robot-0.95.0.dist-info}/METADATA +2 -2
- robotcode_robot-0.95.0.dist-info/RECORD +32 -0
- robotcode_robot-0.94.0.dist-info/RECORD +0 -31
- {robotcode_robot-0.94.0.dist-info → robotcode_robot-0.95.0.dist-info}/WHEEL +0 -0
- {robotcode_robot-0.94.0.dist-info → robotcode_robot-0.95.0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -1,6 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import ast
|
4
|
+
import functools
|
4
5
|
import hashlib
|
5
6
|
import importlib
|
6
7
|
import importlib.util
|
@@ -61,7 +62,6 @@ from robot.variables import Variables
|
|
61
62
|
from robot.variables.filesetter import PythonImporter, YamlImporter
|
62
63
|
from robot.variables.finders import VariableFinder
|
63
64
|
from robot.variables.replacer import VariableReplacer
|
64
|
-
from robot.variables.search import contains_variable
|
65
65
|
from robotcode.core.lsp.types import Position, Range
|
66
66
|
from robotcode.core.utils.path import normalized_path
|
67
67
|
from robotcode.robot.diagnostics.entities import (
|
@@ -83,6 +83,8 @@ from robotcode.robot.utils.markdownformatter import MarkDownFormatter
|
|
83
83
|
from robotcode.robot.utils.match import normalize, normalize_namespace
|
84
84
|
from robotcode.robot.utils.stubs import HasError, HasErrors
|
85
85
|
|
86
|
+
from ..utils.variables import contains_variable
|
87
|
+
|
86
88
|
if get_robot_version() < (7, 0):
|
87
89
|
from robot.running.handlers import _PythonHandler, _PythonInitHandler # pyright: ignore[reportMissingImports]
|
88
90
|
from robot.running.model import ResourceFile # pyright: ignore[reportMissingImports]
|
@@ -197,14 +199,29 @@ def convert_from_rest(text: str) -> str:
|
|
197
199
|
return text
|
198
200
|
|
199
201
|
|
202
|
+
if get_robot_version() >= (6, 0):
|
203
|
+
|
204
|
+
@functools.lru_cache(maxsize=None)
|
205
|
+
def _get_embedded_arguments(name: str) -> Any:
|
206
|
+
try:
|
207
|
+
return EmbeddedArguments.from_name(name)
|
208
|
+
except (VariableError, DataError):
|
209
|
+
return ()
|
210
|
+
|
211
|
+
else:
|
212
|
+
|
213
|
+
@functools.lru_cache(maxsize=None)
|
214
|
+
def _get_embedded_arguments(name: str) -> Any:
|
215
|
+
try:
|
216
|
+
return EmbeddedArguments(name)
|
217
|
+
except (VariableError, DataError):
|
218
|
+
return ()
|
219
|
+
|
220
|
+
|
200
221
|
def is_embedded_keyword(name: str) -> bool:
|
201
222
|
try:
|
202
|
-
if
|
203
|
-
|
204
|
-
return True
|
205
|
-
else:
|
206
|
-
if EmbeddedArguments(name):
|
207
|
-
return True
|
223
|
+
if _get_embedded_arguments(name):
|
224
|
+
return True
|
208
225
|
except (VariableError, DataError):
|
209
226
|
return True
|
210
227
|
|
@@ -235,18 +252,22 @@ class KeywordMatcher:
|
|
235
252
|
def embedded_arguments(self) -> Any:
|
236
253
|
if self._embedded_arguments is None:
|
237
254
|
if self._can_have_embedded:
|
238
|
-
|
239
|
-
if get_robot_version() >= (6, 0):
|
240
|
-
self._embedded_arguments = EmbeddedArguments.from_name(self.name)
|
241
|
-
else:
|
242
|
-
self._embedded_arguments = EmbeddedArguments(self.name)
|
243
|
-
except (VariableError, DataError):
|
244
|
-
self._embedded_arguments = ()
|
255
|
+
self._embedded_arguments = _get_embedded_arguments(self.name)
|
245
256
|
else:
|
246
257
|
self._embedded_arguments = ()
|
247
258
|
|
248
259
|
return self._embedded_arguments
|
249
260
|
|
261
|
+
if get_robot_version() >= (6, 0):
|
262
|
+
|
263
|
+
def __match_embedded(self, name: str) -> bool:
|
264
|
+
return self.embedded_arguments.match(name) is not None
|
265
|
+
|
266
|
+
else:
|
267
|
+
|
268
|
+
def __match_embedded(self, name: str) -> bool:
|
269
|
+
return self.embedded_arguments.name.match(name) is not None
|
270
|
+
|
250
271
|
def __eq__(self, o: object) -> bool:
|
251
272
|
if cached_isinstance(o, KeywordMatcher):
|
252
273
|
if self._is_namespace != o._is_namespace:
|
@@ -261,10 +282,7 @@ class KeywordMatcher:
|
|
261
282
|
return False
|
262
283
|
|
263
284
|
if self.embedded_arguments:
|
264
|
-
|
265
|
-
return self.embedded_arguments.match(o) is not None
|
266
|
-
|
267
|
-
return self.embedded_arguments.name.match(o) is not None
|
285
|
+
return self.__match_embedded(o)
|
268
286
|
|
269
287
|
return self.normalized_name == str(normalize_namespace(o) if self._is_namespace else normalize(o))
|
270
288
|
|
@@ -908,8 +926,7 @@ class KeywordStore:
|
|
908
926
|
return self.__matchers
|
909
927
|
|
910
928
|
def __getitem__(self, key: str) -> KeywordDoc:
|
911
|
-
|
912
|
-
items = [(k, v) for k, v in self._matchers.items() if k == key_matcher]
|
929
|
+
items = [(k, v) for k, v in self._matchers.items() if k == key]
|
913
930
|
|
914
931
|
if not items:
|
915
932
|
raise KeyError
|
@@ -936,8 +953,6 @@ class KeywordStore:
|
|
936
953
|
)
|
937
954
|
|
938
955
|
def __contains__(self, _x: object) -> bool:
|
939
|
-
if not isinstance(_x, KeywordMatcher):
|
940
|
-
_x = KeywordMatcher(str(_x))
|
941
956
|
return any(k == _x for k in self._matchers.keys())
|
942
957
|
|
943
958
|
def __len__(self) -> int:
|
@@ -968,8 +983,7 @@ class KeywordStore:
|
|
968
983
|
return list(self.iter_all(key))
|
969
984
|
|
970
985
|
def iter_all(self, key: str) -> Iterable[KeywordDoc]:
|
971
|
-
|
972
|
-
yield from (v for k, v in self._matchers.items() if k == key_matcher)
|
986
|
+
yield from (v for k, v in self._matchers.items() if k == key)
|
973
987
|
|
974
988
|
|
975
989
|
@dataclass
|
@@ -1282,10 +1296,12 @@ class VariablesDoc(LibraryDoc):
|
|
1282
1296
|
return result
|
1283
1297
|
|
1284
1298
|
|
1299
|
+
@functools.lru_cache(maxsize=256)
|
1285
1300
|
def is_library_by_path(path: str) -> bool:
|
1286
1301
|
return path.lower().endswith((".py", "/", os.sep))
|
1287
1302
|
|
1288
1303
|
|
1304
|
+
@functools.lru_cache(maxsize=256)
|
1289
1305
|
def is_variables_by_path(path: str) -> bool:
|
1290
1306
|
if get_robot_version() >= (6, 1):
|
1291
1307
|
return path.lower().endswith((".py", ".yml", ".yaml", ".json", "/", os.sep))
|
@@ -1656,9 +1672,8 @@ def _find_library_internal(
|
|
1656
1672
|
|
1657
1673
|
robot_variables = None
|
1658
1674
|
|
1659
|
-
robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
1660
|
-
|
1661
1675
|
if contains_variable(name, "$@&%"):
|
1676
|
+
robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
1662
1677
|
try:
|
1663
1678
|
name = robot_variables.replace_string(name, ignore_errors=False)
|
1664
1679
|
except DataError as error:
|
@@ -1711,6 +1726,52 @@ def get_robot_library_html_doc_str(
|
|
1711
1726
|
return output.getvalue()
|
1712
1727
|
|
1713
1728
|
|
1729
|
+
class _Logger(AbstractLogger):
|
1730
|
+
def __init__(self) -> None:
|
1731
|
+
super().__init__()
|
1732
|
+
self.messages: List[Tuple[str, str, bool]] = []
|
1733
|
+
|
1734
|
+
def write(self, message: str, level: str, html: bool = False) -> None:
|
1735
|
+
self.messages.append((message, level, html))
|
1736
|
+
|
1737
|
+
|
1738
|
+
def _import_test_library(name: str) -> Union[Any, Tuple[Any, str]]:
|
1739
|
+
with OutputCapturer(library_import=True):
|
1740
|
+
importer = Importer("test library", LOGGER)
|
1741
|
+
return importer.import_class_or_module(name, return_source=True)
|
1742
|
+
|
1743
|
+
|
1744
|
+
def _get_test_library(
|
1745
|
+
libcode: Any,
|
1746
|
+
source: str,
|
1747
|
+
name: str,
|
1748
|
+
args: Optional[Tuple[Any, ...]] = None,
|
1749
|
+
variables: Optional[Dict[str, Optional[Any]]] = None,
|
1750
|
+
create_handlers: bool = True,
|
1751
|
+
logger: Any = LOGGER,
|
1752
|
+
) -> Any:
|
1753
|
+
if get_robot_version() < (7, 0):
|
1754
|
+
libclass = robot.running.testlibraries._get_lib_class(libcode)
|
1755
|
+
lib = libclass(libcode, name, args or [], source, logger, variables)
|
1756
|
+
if create_handlers:
|
1757
|
+
lib.create_handlers()
|
1758
|
+
else:
|
1759
|
+
lib = robot.running.testlibraries.TestLibrary.from_code(
|
1760
|
+
libcode,
|
1761
|
+
name,
|
1762
|
+
source=Path(source),
|
1763
|
+
args=args or [],
|
1764
|
+
variables=variables,
|
1765
|
+
create_keywords=create_handlers,
|
1766
|
+
logger=logger,
|
1767
|
+
)
|
1768
|
+
|
1769
|
+
return lib
|
1770
|
+
|
1771
|
+
|
1772
|
+
_T = TypeVar("_T")
|
1773
|
+
|
1774
|
+
|
1714
1775
|
def get_library_doc(
|
1715
1776
|
name: str,
|
1716
1777
|
args: Optional[Tuple[Any, ...]] = None,
|
@@ -1719,45 +1780,6 @@ def get_library_doc(
|
|
1719
1780
|
command_line_variables: Optional[Dict[str, Optional[Any]]] = None,
|
1720
1781
|
variables: Optional[Dict[str, Optional[Any]]] = None,
|
1721
1782
|
) -> LibraryDoc:
|
1722
|
-
class Logger(AbstractLogger):
|
1723
|
-
def __init__(self) -> None:
|
1724
|
-
super().__init__()
|
1725
|
-
self.messages: List[Tuple[str, str, bool]] = []
|
1726
|
-
|
1727
|
-
def write(self, message: str, level: str, html: bool = False) -> None:
|
1728
|
-
self.messages.append((message, level, html))
|
1729
|
-
|
1730
|
-
def import_test_library(name: str) -> Union[Any, Tuple[Any, str]]:
|
1731
|
-
with OutputCapturer(library_import=True):
|
1732
|
-
importer = Importer("test library", LOGGER)
|
1733
|
-
return importer.import_class_or_module(name, return_source=True)
|
1734
|
-
|
1735
|
-
def get_test_library(
|
1736
|
-
libcode: Any,
|
1737
|
-
source: str,
|
1738
|
-
name: str,
|
1739
|
-
args: Optional[Tuple[Any, ...]] = None,
|
1740
|
-
variables: Optional[Dict[str, Optional[Any]]] = None,
|
1741
|
-
create_handlers: bool = True,
|
1742
|
-
logger: Any = LOGGER,
|
1743
|
-
) -> Any:
|
1744
|
-
if get_robot_version() < (7, 0):
|
1745
|
-
libclass = robot.running.testlibraries._get_lib_class(libcode)
|
1746
|
-
lib = libclass(libcode, name, args or [], source, logger, variables)
|
1747
|
-
if create_handlers:
|
1748
|
-
lib.create_handlers()
|
1749
|
-
else:
|
1750
|
-
lib = robot.running.testlibraries.TestLibrary.from_code(
|
1751
|
-
libcode,
|
1752
|
-
name,
|
1753
|
-
source=Path(source),
|
1754
|
-
args=args or [],
|
1755
|
-
variables=variables,
|
1756
|
-
create_keywords=create_handlers,
|
1757
|
-
logger=logger,
|
1758
|
-
)
|
1759
|
-
|
1760
|
-
return lib
|
1761
1783
|
|
1762
1784
|
with _std_capture() as std_capturer:
|
1763
1785
|
import_name, robot_variables = _find_library_internal(
|
@@ -1781,7 +1803,7 @@ def get_library_doc(
|
|
1781
1803
|
|
1782
1804
|
source = None
|
1783
1805
|
try:
|
1784
|
-
libcode, source =
|
1806
|
+
libcode, source = _import_test_library(import_name)
|
1785
1807
|
except (SystemExit, KeyboardInterrupt):
|
1786
1808
|
raise
|
1787
1809
|
except BaseException as e:
|
@@ -1821,13 +1843,17 @@ def get_library_doc(
|
|
1821
1843
|
|
1822
1844
|
lib = None
|
1823
1845
|
try:
|
1824
|
-
lib =
|
1846
|
+
lib = _get_test_library(
|
1825
1847
|
libcode,
|
1826
1848
|
source,
|
1827
1849
|
library_name,
|
1828
1850
|
args,
|
1829
1851
|
create_handlers=False,
|
1830
|
-
variables=
|
1852
|
+
variables=(
|
1853
|
+
robot_variables
|
1854
|
+
if robot_variables is not None
|
1855
|
+
else resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
1856
|
+
),
|
1831
1857
|
)
|
1832
1858
|
if get_robot_version() < (7, 0):
|
1833
1859
|
_ = lib.get_instance()
|
@@ -1847,7 +1873,7 @@ def get_library_doc(
|
|
1847
1873
|
|
1848
1874
|
if args:
|
1849
1875
|
try:
|
1850
|
-
lib =
|
1876
|
+
lib = _get_test_library(libcode, source, library_name, (), create_handlers=False)
|
1851
1877
|
if get_robot_version() < (7, 0):
|
1852
1878
|
_ = lib.get_instance()
|
1853
1879
|
else:
|
@@ -1862,6 +1888,10 @@ def get_library_doc(
|
|
1862
1888
|
libdoc = LibraryDoc(
|
1863
1889
|
name=library_name,
|
1864
1890
|
source=real_source,
|
1891
|
+
line_no=lib.lineno if lib is not None else -1,
|
1892
|
+
version=str(lib.version) if lib is not None else "",
|
1893
|
+
scope=str(lib.scope) if lib is not None else ROBOT_DEFAULT_SCOPE,
|
1894
|
+
doc_format=(str(lib.doc_format) or ROBOT_DOC_FORMAT) if lib is not None else ROBOT_DOC_FORMAT,
|
1865
1895
|
module_spec=(
|
1866
1896
|
module_spec
|
1867
1897
|
if module_spec is not None
|
@@ -1870,16 +1900,33 @@ def get_library_doc(
|
|
1870
1900
|
else None
|
1871
1901
|
),
|
1872
1902
|
python_path=sys.path,
|
1873
|
-
line_no=lib.lineno if lib is not None else -1,
|
1874
|
-
doc=str(lib.doc) if lib is not None else "",
|
1875
|
-
version=str(lib.version) if lib is not None else "",
|
1876
|
-
scope=str(lib.scope) if lib is not None else ROBOT_DEFAULT_SCOPE,
|
1877
|
-
doc_format=(str(lib.doc_format) or ROBOT_DOC_FORMAT) if lib is not None else ROBOT_DOC_FORMAT,
|
1878
1903
|
member_name=module_spec.member_name if module_spec is not None else None,
|
1879
1904
|
)
|
1880
1905
|
|
1881
1906
|
if lib is not None:
|
1882
1907
|
try:
|
1908
|
+
|
1909
|
+
def _get(handler: Callable[[], _T]) -> Optional[_T]:
|
1910
|
+
try:
|
1911
|
+
return handler()
|
1912
|
+
except (SystemExit, KeyboardInterrupt):
|
1913
|
+
raise
|
1914
|
+
except BaseException as e:
|
1915
|
+
errors.append(
|
1916
|
+
error_from_exception(
|
1917
|
+
e,
|
1918
|
+
source or module_spec.origin if module_spec is not None else None,
|
1919
|
+
(
|
1920
|
+
1
|
1921
|
+
if source is not None or module_spec is not None and module_spec.origin is not None
|
1922
|
+
else None
|
1923
|
+
),
|
1924
|
+
)
|
1925
|
+
)
|
1926
|
+
return None
|
1927
|
+
|
1928
|
+
libdoc.doc = _get(lambda: str(lib.doc) if lib is not None else "") or ""
|
1929
|
+
|
1883
1930
|
if get_robot_version() < (7, 0):
|
1884
1931
|
libdoc.has_listener = lib.has_listener
|
1885
1932
|
|
@@ -1909,10 +1956,10 @@ def get_library_doc(
|
|
1909
1956
|
keywords=[
|
1910
1957
|
KeywordDoc(
|
1911
1958
|
name=libdoc.name,
|
1912
|
-
arguments=[ArgumentInfo.from_robot(a) for a in kw[0].args],
|
1913
|
-
doc=kw[0].doc,
|
1914
|
-
tags=list(kw[0].tags),
|
1915
|
-
source=kw[0].source,
|
1959
|
+
arguments=_get(lambda: [ArgumentInfo.from_robot(a) for a in kw[0].args]) or [],
|
1960
|
+
doc=_get(lambda: kw[0].doc) or "",
|
1961
|
+
tags=_get(lambda: list(kw[0].tags)) or [],
|
1962
|
+
source=_get(lambda: kw[0].source) or "",
|
1916
1963
|
line_no=kw[0].lineno if kw[0].lineno is not None else -1,
|
1917
1964
|
col_offset=-1,
|
1918
1965
|
end_col_offset=-1,
|
@@ -1923,20 +1970,23 @@ def get_library_doc(
|
|
1923
1970
|
longname=f"{libdoc.name}.{kw[0].name}",
|
1924
1971
|
doc_format=str(lib.doc_format) or ROBOT_DOC_FORMAT,
|
1925
1972
|
is_initializer=True,
|
1926
|
-
arguments_spec=
|
1927
|
-
|
1973
|
+
arguments_spec=_get(
|
1974
|
+
lambda: ArgumentSpec.from_robot_argument_spec(
|
1975
|
+
kw[1].arguments if get_robot_version() < (7, 0) else kw[1].args
|
1976
|
+
)
|
1928
1977
|
),
|
1929
1978
|
)
|
1930
1979
|
for kw in init_keywords
|
1931
1980
|
]
|
1932
1981
|
)
|
1933
1982
|
|
1934
|
-
logger =
|
1935
|
-
lib.logger = logger
|
1983
|
+
logger = _Logger()
|
1936
1984
|
|
1937
1985
|
if get_robot_version() < (7, 0):
|
1986
|
+
lib.logger = logger
|
1938
1987
|
lib.create_handlers()
|
1939
1988
|
else:
|
1989
|
+
lib._logger = logger
|
1940
1990
|
lib.create_keywords()
|
1941
1991
|
|
1942
1992
|
for m in logger.messages:
|
@@ -1969,10 +2019,10 @@ def get_library_doc(
|
|
1969
2019
|
keywords=[
|
1970
2020
|
KeywordDoc(
|
1971
2021
|
name=kw[0].name,
|
1972
|
-
arguments=[ArgumentInfo.from_robot(a) for a in kw[0].args],
|
1973
|
-
doc=kw[0].doc,
|
1974
|
-
tags=list(kw[0].tags),
|
1975
|
-
source=kw[0].source,
|
2022
|
+
arguments=_get(lambda: [ArgumentInfo.from_robot(a) for a in kw[0].args]) or [],
|
2023
|
+
doc=_get(lambda: kw[0].doc) or "",
|
2024
|
+
tags=_get(lambda: list(kw[0].tags)) or [],
|
2025
|
+
source=_get(lambda: kw[0].source) or "",
|
1976
2026
|
line_no=kw[0].lineno if kw[0].lineno is not None else -1,
|
1977
2027
|
col_offset=-1,
|
1978
2028
|
end_col_offset=-1,
|
@@ -1987,21 +2037,26 @@ def get_library_doc(
|
|
1987
2037
|
is_registered_run_keyword=RUN_KW_REGISTER.is_run_keyword(libdoc.name, kw[0].name),
|
1988
2038
|
args_to_process=get_args_to_process(libdoc.name, kw[0].name),
|
1989
2039
|
deprecated=kw[0].deprecated,
|
1990
|
-
arguments_spec=(
|
1991
|
-
|
1992
|
-
|
2040
|
+
arguments_spec=_get(
|
2041
|
+
lambda: (
|
2042
|
+
ArgumentSpec.from_robot_argument_spec(
|
2043
|
+
kw[1].arguments if get_robot_version() < (7, 0) else kw[1].args
|
2044
|
+
)
|
2045
|
+
if not kw[1].is_error_handler
|
2046
|
+
else None
|
1993
2047
|
)
|
1994
|
-
if not kw[1].is_error_handler
|
1995
|
-
else None
|
1996
2048
|
),
|
1997
|
-
return_type=(
|
1998
|
-
(
|
1999
|
-
|
2000
|
-
|
2049
|
+
return_type=_get(
|
2050
|
+
lambda: (
|
2051
|
+
(
|
2052
|
+
str(kw[1].args.return_type)
|
2053
|
+
if kw[1].args.return_type is not None
|
2054
|
+
and kw[1].args.return_type is not type(None)
|
2055
|
+
else None
|
2056
|
+
)
|
2057
|
+
if get_robot_version() >= (7, 0)
|
2001
2058
|
else None
|
2002
2059
|
)
|
2003
|
-
if get_robot_version() >= (7, 0)
|
2004
|
-
else None
|
2005
2060
|
),
|
2006
2061
|
)
|
2007
2062
|
for kw in keyword_docs
|
@@ -2086,9 +2141,8 @@ def _find_variables_internal(
|
|
2086
2141
|
|
2087
2142
|
_update_env(working_dir)
|
2088
2143
|
|
2089
|
-
robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
2090
|
-
|
2091
2144
|
if contains_variable(name, "$@&%"):
|
2145
|
+
robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
2092
2146
|
try:
|
2093
2147
|
name = robot_variables.replace_string(name, ignore_errors=False)
|
2094
2148
|
except DataError as error:
|
@@ -2109,12 +2163,18 @@ def resolve_args(
|
|
2109
2163
|
command_line_variables: Optional[Dict[str, Optional[Any]]] = None,
|
2110
2164
|
variables: Optional[Dict[str, Optional[Any]]] = None,
|
2111
2165
|
) -> Tuple[Any, ...]:
|
2112
|
-
robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
2166
|
+
# robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
2167
|
+
robot_variables: Any = None
|
2113
2168
|
|
2114
2169
|
result = []
|
2115
2170
|
for arg in args:
|
2116
2171
|
if isinstance(arg, str):
|
2117
|
-
|
2172
|
+
if contains_variable(arg, "$@&%"):
|
2173
|
+
if robot_variables is None:
|
2174
|
+
robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
2175
|
+
result.append(robot_variables.replace_string(arg, ignore_errors=True))
|
2176
|
+
else:
|
2177
|
+
result.append(arg)
|
2118
2178
|
else:
|
2119
2179
|
result.append(arg)
|
2120
2180
|
|
@@ -2389,8 +2449,8 @@ def find_file(
|
|
2389
2449
|
) -> str:
|
2390
2450
|
_update_env(working_dir)
|
2391
2451
|
|
2392
|
-
robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
2393
2452
|
if contains_variable(name, "$@&%"):
|
2453
|
+
robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
2394
2454
|
try:
|
2395
2455
|
name = robot_variables.replace_string(name, ignore_errors=False)
|
2396
2456
|
except DataError as error:
|
@@ -2492,7 +2552,7 @@ def complete_library_import(
|
|
2492
2552
|
if e not in DEFAULT_LIBRARIES
|
2493
2553
|
]
|
2494
2554
|
|
2495
|
-
if name is not None:
|
2555
|
+
if name is not None and contains_variable(name, "$@&%"):
|
2496
2556
|
robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
2497
2557
|
|
2498
2558
|
name = robot_variables.replace_string(name, ignore_errors=True)
|
@@ -2568,7 +2628,7 @@ def complete_resource_import(
|
|
2568
2628
|
|
2569
2629
|
result: List[CompleteResult] = []
|
2570
2630
|
|
2571
|
-
if name is not None:
|
2631
|
+
if name is not None and contains_variable(name, "$@&%"):
|
2572
2632
|
robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
2573
2633
|
|
2574
2634
|
name = robot_variables.replace_string(name, ignore_errors=True)
|
@@ -2608,7 +2668,7 @@ def complete_variables_import(
|
|
2608
2668
|
|
2609
2669
|
result: List[CompleteResult] = []
|
2610
2670
|
|
2611
|
-
if name is not None:
|
2671
|
+
if name is not None and contains_variable(name, "$@&%"):
|
2612
2672
|
robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
2613
2673
|
|
2614
2674
|
name = robot_variables.replace_string(name, ignore_errors=True)
|
@@ -21,9 +21,8 @@ from typing import (
|
|
21
21
|
|
22
22
|
from robot.errors import VariableError
|
23
23
|
from robot.parsing.lexer.tokens import Token
|
24
|
-
from robot.utils.escaping import
|
24
|
+
from robot.utils.escaping import unescape
|
25
25
|
from robot.variables.finders import NOT_FOUND, NumberFinder
|
26
|
-
from robot.variables.search import contains_variable, search_variable
|
27
26
|
from robotcode.core.lsp.types import Position
|
28
27
|
|
29
28
|
from ..utils import get_robot_version
|
@@ -35,6 +34,7 @@ from ..utils.ast import (
|
|
35
34
|
whitespace_at_begin_of_token,
|
36
35
|
whitespace_from_begin_of_token,
|
37
36
|
)
|
37
|
+
from ..utils.variables import contains_variable, search_variable, split_from_equals
|
38
38
|
from .entities import (
|
39
39
|
LibraryEntry,
|
40
40
|
VariableDefinition,
|
@@ -210,10 +210,14 @@ class ModelHelper:
|
|
210
210
|
position: Position,
|
211
211
|
analyse_run_keywords: bool = True,
|
212
212
|
) -> Optional[Tuple[Optional[KeywordDoc], Token]]:
|
213
|
-
|
213
|
+
finder = namespace.get_finder()
|
214
|
+
keyword_doc = finder.find_keyword(keyword_name, raise_keyword_error=False)
|
214
215
|
if keyword_doc is None:
|
215
216
|
return None
|
216
217
|
|
218
|
+
if finder.result_bdd_prefix:
|
219
|
+
keyword_token = ModelHelper.strip_bdd_prefix(namespace, keyword_token)
|
220
|
+
|
217
221
|
if position.is_in_range(range_from_token(keyword_token)):
|
218
222
|
return keyword_doc, keyword_token
|
219
223
|
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import ast
|
2
2
|
import enum
|
3
3
|
import itertools
|
4
|
-
import time
|
5
4
|
import weakref
|
6
5
|
from collections import OrderedDict, defaultdict
|
7
6
|
from concurrent.futures import CancelledError
|
@@ -29,11 +28,6 @@ from robot.parsing.model.statements import ResourceImport as RobotResourceImport
|
|
29
28
|
from robot.parsing.model.statements import (
|
30
29
|
VariablesImport as RobotVariablesImport,
|
31
30
|
)
|
32
|
-
from robot.variables.search import (
|
33
|
-
is_scalar_assign,
|
34
|
-
is_variable,
|
35
|
-
search_variable,
|
36
|
-
)
|
37
31
|
from robotcode.core.concurrent import RLock
|
38
32
|
from robotcode.core.event import event
|
39
33
|
from robotcode.core.lsp.types import (
|
@@ -58,7 +52,12 @@ from ..utils.ast import (
|
|
58
52
|
tokenize_variables,
|
59
53
|
)
|
60
54
|
from ..utils.stubs import Languages
|
61
|
-
from ..utils.variables import
|
55
|
+
from ..utils.variables import (
|
56
|
+
BUILTIN_VARIABLES,
|
57
|
+
is_scalar_assign,
|
58
|
+
is_variable,
|
59
|
+
search_variable,
|
60
|
+
)
|
62
61
|
from ..utils.visitor import Visitor
|
63
62
|
from .entities import (
|
64
63
|
ArgumentDefinition,
|
@@ -894,6 +893,7 @@ class Namespace:
|
|
894
893
|
self._namespaces[KeywordMatcher(v.alias or v.name or v.import_name, is_namespace=True)].append(v)
|
895
894
|
for v in (self.get_resources()).values():
|
896
895
|
self._namespaces[KeywordMatcher(v.alias or v.name or v.import_name, is_namespace=True)].append(v)
|
896
|
+
|
897
897
|
return self._namespaces
|
898
898
|
|
899
899
|
def get_resources(self) -> Dict[str, ResourceEntry]:
|
@@ -1794,38 +1794,27 @@ class Namespace:
|
|
1794
1794
|
|
1795
1795
|
libdoc = self.get_library_doc()
|
1796
1796
|
|
1797
|
-
|
1797
|
+
yield from itertools.chain(
|
1798
1798
|
self.get_imported_keywords(),
|
1799
1799
|
libdoc.keywords if libdoc is not None else [],
|
1800
|
-
)
|
1801
|
-
yield doc
|
1800
|
+
)
|
1802
1801
|
|
1803
1802
|
@_logger.call
|
1804
1803
|
def get_keywords(self) -> List[KeywordDoc]:
|
1805
1804
|
with self._keywords_lock:
|
1806
1805
|
if self._keywords is None:
|
1807
|
-
current_time = time.monotonic()
|
1808
|
-
self._logger.debug("start collecting keywords")
|
1809
|
-
try:
|
1810
|
-
i = 0
|
1811
1806
|
|
1812
|
-
|
1807
|
+
i = 0
|
1813
1808
|
|
1814
|
-
|
1809
|
+
self.ensure_initialized()
|
1815
1810
|
|
1816
|
-
|
1817
|
-
i += 1
|
1818
|
-
result[doc.matcher] = doc
|
1811
|
+
result: Dict[KeywordMatcher, KeywordDoc] = {}
|
1819
1812
|
|
1820
|
-
|
1821
|
-
|
1822
|
-
|
1823
|
-
|
1824
|
-
|
1825
|
-
self._logger.debug(
|
1826
|
-
lambda: f"end collecting {len(self._keywords) if self._keywords else 0}"
|
1827
|
-
f" keywords in {time.monotonic() - current_time}s analyze {i} keywords"
|
1828
|
-
)
|
1813
|
+
for doc in self.iter_all_keywords():
|
1814
|
+
i += 1
|
1815
|
+
result[doc.matcher] = doc
|
1816
|
+
|
1817
|
+
self._keywords = list(result.values())
|
1829
1818
|
|
1830
1819
|
return self._keywords
|
1831
1820
|
|