robotcode-language-server 1.3.0.dev5__tar.gz → 1.4.0__tar.gz

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.
Files changed (78) hide show
  1. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/PKG-INFO +5 -5
  2. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/pyproject.toml +4 -4
  3. robotcode_language_server-1.4.0/src/robotcode/language_server/__version__.py +1 -0
  4. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/diagnostics.py +0 -3
  5. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/workspace.py +1 -1
  6. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/protocol.py +0 -9
  7. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/formatting.py +20 -21
  8. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/hover.py +1 -1
  9. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/inlay_hint.py +1 -1
  10. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/project_info.py +5 -6
  11. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/references.py +1 -1
  12. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/robocop_diagnostics.py +84 -17
  13. robotcode_language_server-1.4.0/src/robotcode/language_server/robotframework/parts/robocop_helper.py +117 -0
  14. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/signature_help.py +1 -1
  15. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/protocol.py +2 -0
  16. robotcode_language_server-1.3.0.dev5/src/robotcode/language_server/__version__.py +0 -1
  17. robotcode_language_server-1.3.0.dev5/src/robotcode/language_server/robotframework/parts/robocop_tidy_mixin.py +0 -49
  18. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/.gitignore +0 -0
  19. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/LICENSE.txt +0 -0
  20. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/README.md +0 -0
  21. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/__init__.py +0 -0
  22. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/cli.py +0 -0
  23. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/__init__.py +0 -0
  24. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/decorators.py +0 -0
  25. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/__init__.py +0 -0
  26. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/code_action.py +0 -0
  27. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/code_lens.py +0 -0
  28. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/commands.py +0 -0
  29. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/completion.py +0 -0
  30. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/declaration.py +0 -0
  31. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/definition.py +0 -0
  32. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/document_highlight.py +0 -0
  33. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/document_symbols.py +0 -0
  34. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/documents.py +0 -0
  35. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/folding_range.py +0 -0
  36. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/formatting.py +0 -0
  37. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/hover.py +0 -0
  38. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/implementation.py +0 -0
  39. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/inlay_hint.py +0 -0
  40. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/inline_value.py +0 -0
  41. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/linked_editing_ranges.py +0 -0
  42. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/protocol_part.py +0 -0
  43. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/references.py +0 -0
  44. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/rename.py +0 -0
  45. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/selection_range.py +0 -0
  46. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/semantic_tokens.py +0 -0
  47. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/signature_help.py +0 -0
  48. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/window.py +0 -0
  49. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/parts/workspace_symbols.py +0 -0
  50. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/common/server.py +0 -0
  51. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/hooks.py +0 -0
  52. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/py.typed +0 -0
  53. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/__init__.py +0 -0
  54. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/configuration.py +0 -0
  55. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/__init__.py +0 -0
  56. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/code_action_documentation.py +0 -0
  57. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/code_action_helper_mixin.py +0 -0
  58. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/code_action_quick_fixes.py +0 -0
  59. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/code_action_refactor.py +0 -0
  60. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/code_lens.py +0 -0
  61. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/completion.py +0 -0
  62. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/debugging_utils.py +0 -0
  63. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/diagnostics.py +0 -0
  64. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/document_highlight.py +0 -0
  65. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/document_symbols.py +0 -0
  66. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/documents_cache.py +0 -0
  67. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/folding_range.py +0 -0
  68. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/goto.py +0 -0
  69. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/http_server.py +0 -0
  70. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/inline_value.py +0 -0
  71. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/keywords_treeview.py +0 -0
  72. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/protocol_part.py +0 -0
  73. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/rename.py +0 -0
  74. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/robot_workspace.py +0 -0
  75. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/selection_range.py +0 -0
  76. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/semantic_tokens.py +0 -0
  77. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/parts/workspace_symbols.py +0 -0
  78. {robotcode_language_server-1.3.0.dev5 → robotcode_language_server-1.4.0}/src/robotcode/language_server/robotframework/server.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: robotcode-language-server
3
- Version: 1.3.0.dev5
3
+ Version: 1.4.0
4
4
  Summary: RobotCode Language Server for Robot Framework
5
5
  Project-URL: Homepage, https://robotcode.io
6
6
  Project-URL: Donate, https://opencollective.com/robotcode
@@ -25,10 +25,10 @@ Classifier: Programming Language :: Python :: Implementation :: PyPy
25
25
  Classifier: Topic :: Utilities
26
26
  Classifier: Typing :: Typed
27
27
  Requires-Python: >=3.8
28
- Requires-Dist: robotcode-analyze==1.3.0-dev.5
29
- Requires-Dist: robotcode-jsonrpc2==1.3.0-dev.5
30
- Requires-Dist: robotcode-robot==1.3.0-dev.5
31
- Requires-Dist: robotcode==1.3.0-dev.5
28
+ Requires-Dist: robotcode-analyze==1.4.0
29
+ Requires-Dist: robotcode-jsonrpc2==1.4.0
30
+ Requires-Dist: robotcode-robot==1.4.0
31
+ Requires-Dist: robotcode==1.4.0
32
32
  Requires-Dist: robotframework>=4.1.0
33
33
  Description-Content-Type: text/markdown
34
34
 
@@ -27,10 +27,10 @@ classifiers = [
27
27
  ]
28
28
  dependencies = [
29
29
  "robotframework>=4.1.0",
30
- "robotcode-jsonrpc2==1.3.0-dev.5",
31
- "robotcode-robot==1.3.0-dev.5",
32
- "robotcode-analyze==1.3.0-dev.5",
33
- "robotcode==1.3.0-dev.5",
30
+ "robotcode-jsonrpc2==1.4.0",
31
+ "robotcode-robot==1.4.0",
32
+ "robotcode-analyze==1.4.0",
33
+ "robotcode==1.4.0",
34
34
  ]
35
35
  dynamic = ["version"]
36
36
 
@@ -1,7 +1,6 @@
1
1
  import concurrent.futures
2
2
  import functools
3
3
  import itertools
4
- import logging
5
4
  import time
6
5
  import uuid
7
6
  from concurrent.futures import CancelledError
@@ -361,7 +360,6 @@ class DiagnosticsProtocolPart(LanguageServerProtocolPart):
361
360
  with self._logger.measure_time(
362
361
  lambda: f"analyzing workspace for {len(documents)} documents",
363
362
  context_name="workspace_diagnostics",
364
- level=logging.CRITICAL,
365
363
  ):
366
364
  self.on_workspace_diagnostics_analyze(self)
367
365
 
@@ -444,7 +442,6 @@ class DiagnosticsProtocolPart(LanguageServerProtocolPart):
444
442
  with self._logger.measure_time(
445
443
  lambda: f"collect workspace diagnostic for {len(documents_to_collect)} documents",
446
444
  context_name="collect_workspace_diagnostics",
447
- level=logging.CRITICAL,
448
445
  ):
449
446
  breaked = False
450
447
  for document in set(documents) - set(documents_to_collect):
@@ -315,7 +315,7 @@ class Workspace(LanguageServerProtocolPart, CoreWorkspace, FileWatcherManagerBas
315
315
  List[Any],
316
316
  )
317
317
 
318
- result = self.settings
318
+ result: Any = self.settings
319
319
  for sub_key in str(section).split("."):
320
320
  if sub_key in result:
321
321
  result = result.get(sub_key, None)
@@ -98,15 +98,6 @@ class LanguageServerLogHandler(logging.Handler):
98
98
  if self.trace != TraceValues.OFF:
99
99
  self.protocol.log_trace(record.getMessage())
100
100
 
101
- type = self.MAPPING.get(record.levelno, None)
102
- if type is None:
103
- type = MessageType.LOG
104
-
105
- self.protocol.window_log_message(
106
- type=type,
107
- message=record.getMessage(),
108
- )
109
-
110
101
 
111
102
  class LanguageServerProtocol(JsonRPCProtocol):
112
103
  __logger = LoggingDescriptor()
@@ -17,13 +17,12 @@ from robotcode.robot.utils import get_robot_version
17
17
 
18
18
  from ..configuration import RoboCopConfig, RoboTidyConfig
19
19
  from .protocol_part import RobotLanguageServerProtocolPart
20
- from .robocop_tidy_mixin import RoboCopTidyMixin
21
20
 
22
21
  if TYPE_CHECKING:
23
22
  from ..protocol import RobotLanguageServerProtocol
24
23
 
25
24
 
26
- class RobotFormattingProtocolPart(RobotLanguageServerProtocolPart, RoboCopTidyMixin):
25
+ class RobotFormattingProtocolPart(RobotLanguageServerProtocolPart):
27
26
  _logger = LoggingDescriptor()
28
27
 
29
28
  def __init__(self, parent: "RobotLanguageServerProtocol") -> None:
@@ -31,7 +30,9 @@ class RobotFormattingProtocolPart(RobotLanguageServerProtocolPart, RoboCopTidyMi
31
30
 
32
31
  parent.formatting.format.add(self.format)
33
32
 
34
- if self.robotidy_installed or (self.robocop_installed and self.robocop_version >= (6, 0)):
33
+ if self.parent.robocop_helper.robotidy_installed or (
34
+ self.parent.robocop_helper.robocop_installed and self.parent.robocop_helper.robocop_version >= (6, 0)
35
+ ):
35
36
  parent.formatting.format_range.add(self.format_range)
36
37
 
37
38
  self.space_count = 4
@@ -64,8 +65,8 @@ class RobotFormattingProtocolPart(RobotLanguageServerProtocolPart, RoboCopTidyMi
64
65
  options: FormattingOptions,
65
66
  **further_options: Any,
66
67
  ) -> Optional[List[TextEdit]]:
67
- if (get_robot_version() >= (5, 0)) and self.robocop_installed and self.robocop_version >= (6, 0):
68
- if not self.is_robocop_notification_shown and self.robotidy_installed:
68
+ if self.parent.robocop_helper.robocop_installed and self.parent.robocop_helper.robocop_version >= (6, 0):
69
+ if not self.is_robocop_notification_shown and self.parent.robocop_helper.robotidy_installed:
69
70
  self.parent.window.show_message(
70
71
  "`robotframework-robocop >= 6.0` is installed and will be used for formatting.\n\n"
71
72
  "`robotframework-tidy` is also detected in the workspace, but its use is redundant.\n"
@@ -78,7 +79,7 @@ class RobotFormattingProtocolPart(RobotLanguageServerProtocolPart, RoboCopTidyMi
78
79
  return self.format_robocop(document, options, **further_options)
79
80
 
80
81
  tidy_config = self.get_tidy_config(document)
81
- if (tidy_config.enabled or get_robot_version() >= (5, 0)) and self.robotidy_installed:
82
+ if (tidy_config.enabled or get_robot_version() >= (5, 0)) and self.parent.robocop_helper.robotidy_installed:
82
83
  return self.format_robot_tidy(document, options, config=tidy_config, **further_options)
83
84
 
84
85
  if get_robot_version() < (5, 0):
@@ -105,18 +106,18 @@ class RobotFormattingProtocolPart(RobotLanguageServerProtocolPart, RoboCopTidyMi
105
106
 
106
107
  model = self.parent.documents_cache.get_model(document, False)
107
108
 
108
- if self.robotidy_version >= (3, 0):
109
+ if self.parent.robocop_helper.robotidy_version >= (3, 0):
109
110
  from robotidy.api import get_robotidy
110
111
  from robotidy.disablers import RegisterDisablers
111
112
 
112
- if self.robotidy_version >= (4, 2):
113
+ if self.parent.robocop_helper.robotidy_version >= (4, 2):
113
114
  robot_tidy = get_robotidy(
114
115
  document.uri.to_path(),
115
116
  None,
116
117
  ignore_git_dir=config.ignore_git_dir,
117
118
  config=config.config,
118
119
  )
119
- elif self.robotidy_version >= (4, 1):
120
+ elif self.parent.robocop_helper.robotidy_version >= (4, 1):
120
121
  robot_tidy = get_robotidy(
121
122
  document.uri.to_path(),
122
123
  None,
@@ -135,14 +136,14 @@ class RobotFormattingProtocolPart(RobotLanguageServerProtocolPart, RoboCopTidyMi
135
136
  )
136
137
  disabler_finder.visit(model)
137
138
 
138
- if self.robotidy_version >= (4, 11):
139
+ if self.parent.robocop_helper.robotidy_version >= (4, 11):
139
140
  if disabler_finder.is_disabled_in_file():
140
141
  return None
141
142
  else:
142
143
  if disabler_finder.file_disabled:
143
144
  return None
144
145
 
145
- if self.robotidy_version >= (4, 0):
146
+ if self.parent.robocop_helper.robotidy_version >= (4, 0):
146
147
  _, _, new, _ = robot_tidy.transform_until_stable(model, disabler_finder)
147
148
  else:
148
149
  _, _, new = robot_tidy.transform(model, disabler_finder.disablers)
@@ -156,7 +157,7 @@ class RobotFormattingProtocolPart(RobotLanguageServerProtocolPart, RoboCopTidyMi
156
157
  robot_tidy.formatting_config.start_line = range.start.line + 1
157
158
  robot_tidy.formatting_config.end_line = range.end.line + 1
158
159
 
159
- if self.robotidy_version >= (2, 2):
160
+ if self.parent.robocop_helper.robotidy_version >= (2, 2):
160
161
  from robotidy.disablers import RegisterDisablers
161
162
 
162
163
  disabler_finder = RegisterDisablers(
@@ -197,17 +198,13 @@ class RobotFormattingProtocolPart(RobotLanguageServerProtocolPart, RoboCopTidyMi
197
198
  range: Optional[Range] = None,
198
199
  **further_options: Any,
199
200
  ) -> Optional[List[TextEdit]]:
200
- from robocop.config import ConfigManager
201
201
  from robocop.formatter.runner import RobocopFormatter
202
202
 
203
- robocop_config = self.get_robocop_config(document)
203
+ workspace_folder = self.parent.workspace.get_workspace_folder(document.uri)
204
+ if workspace_folder is None:
205
+ return None
204
206
 
205
- config_manager = ConfigManager(
206
- [document.uri.to_path()],
207
- config=robocop_config.config_file,
208
- ignore_git_dir=robocop_config.ignore_git_dir,
209
- ignore_file_config=robocop_config.ignore_file_config,
210
- )
207
+ config_manager = self.parent.robocop_helper.get_config_manager(workspace_folder)
211
208
 
212
209
  config = config_manager.get_config_for_source_file(document.uri.to_path())
213
210
 
@@ -282,7 +279,9 @@ class RobotFormattingProtocolPart(RobotLanguageServerProtocolPart, RoboCopTidyMi
282
279
  **further_options: Any,
283
280
  ) -> Optional[List[TextEdit]]:
284
281
  config = self.get_tidy_config(document)
285
- if (config.enabled and self.robotidy_installed) or (self.robocop_installed and self.robocop_version >= (6, 0)):
282
+ if (config.enabled and self.parent.robocop_helper.robotidy_installed) or (
283
+ self.parent.robocop_helper.robocop_installed and self.parent.robocop_helper.robocop_version >= (6, 0)
284
+ ):
286
285
  return self.format_robot_tidy(document, options, range=range, config=config, **further_options)
287
286
 
288
287
  return None
@@ -73,7 +73,7 @@ class RobotHoverProtocolPart(RobotLanguageServerProtocolPart, ModelHelper):
73
73
  for base in cls.__bases__:
74
74
  method = self._find_method(base)
75
75
  if method:
76
- return cast(_HoverMethod, method)
76
+ return method
77
77
 
78
78
  return None
79
79
 
@@ -61,7 +61,7 @@ class RobotInlayHintProtocolPart(RobotLanguageServerProtocolPart, ModelHelper):
61
61
  for base in cls.__bases__:
62
62
  method = self._find_method(base)
63
63
  if method:
64
- return cast(_HandlerMethod, method)
64
+ return method
65
65
 
66
66
  return None
67
67
 
@@ -10,7 +10,6 @@ from robotcode.jsonrpc2.protocol import rpc_method
10
10
 
11
11
  from ...__version__ import __version__ as robotcode_version
12
12
  from .protocol_part import RobotLanguageServerProtocolPart
13
- from .robocop_tidy_mixin import RoboCopTidyMixin
14
13
 
15
14
  if TYPE_CHECKING:
16
15
  from ..protocol import RobotLanguageServerProtocol
@@ -26,7 +25,7 @@ class ProjectInfo(CamelSnakeMixin):
26
25
  robot_code_version_string: Optional[str] = None
27
26
 
28
27
 
29
- class ProjectInfoPart(RobotLanguageServerProtocolPart, RoboCopTidyMixin):
28
+ class ProjectInfoPart(RobotLanguageServerProtocolPart):
30
29
  _logger = LoggingDescriptor()
31
30
 
32
31
  def __init__(self, parent: "RobotLanguageServerProtocol") -> None:
@@ -40,12 +39,12 @@ class ProjectInfoPart(RobotLanguageServerProtocolPart, RoboCopTidyMixin):
40
39
  **kwargs: Any,
41
40
  ) -> ProjectInfo:
42
41
  robocop_version_string = None
43
- if self.robocop_installed:
44
- robocop_version_string = self.robocop_version_str
42
+ if self.parent.robocop_helper.robocop_installed:
43
+ robocop_version_string = self.parent.robocop_helper.robocop_version_str
45
44
 
46
45
  tidy_version_string = None
47
- if self.robotidy_installed:
48
- tidy_version_string = self.robotidy_version_str
46
+ if self.parent.robocop_helper.robotidy_installed:
47
+ tidy_version_string = self.parent.robocop_helper.robotidy_version_str
49
48
 
50
49
  return ProjectInfo(
51
50
  robot_version_string=get_version(),
@@ -113,7 +113,7 @@ class RobotReferencesProtocolPart(RobotLanguageServerProtocolPart, ModelHelper):
113
113
  for base in cls.__bases__:
114
114
  method = self._find_method(base)
115
115
  if method:
116
- return cast(_ReferencesMethod, method)
116
+ return method
117
117
  return None
118
118
 
119
119
  @language_id("robotframework")
@@ -1,5 +1,6 @@
1
1
  import io
2
2
  from typing import TYPE_CHECKING, Any, List, Optional
3
+ from weakref import WeakKeyDictionary
3
4
 
4
5
  from robotcode.core.language import language_id
5
6
  from robotcode.core.lsp.types import (
@@ -17,21 +18,23 @@ from robotcode.core.workspace import WorkspaceFolder
17
18
  from ...common.parts.diagnostics import DiagnosticsCollectType, DiagnosticsResult
18
19
  from ..configuration import RoboCopConfig
19
20
  from .protocol_part import RobotLanguageServerProtocolPart
20
- from .robocop_tidy_mixin import RoboCopTidyMixin
21
21
 
22
22
  if TYPE_CHECKING:
23
+ from robocop.linter.runner import RobocopLinter
24
+
23
25
  from ..protocol import RobotLanguageServerProtocol
24
26
 
25
27
 
26
- class RobotRoboCopDiagnosticsProtocolPart(RobotLanguageServerProtocolPart, RoboCopTidyMixin):
28
+ class RobotRoboCopDiagnosticsProtocolPart(RobotLanguageServerProtocolPart):
27
29
  _logger = LoggingDescriptor()
28
30
 
29
31
  def __init__(self, parent: "RobotLanguageServerProtocol") -> None:
30
32
  super().__init__(parent)
31
33
 
32
34
  self.source_name = "robocop"
35
+ self._robocop_linters: WeakKeyDictionary[WorkspaceFolder, "RobocopLinter"] = WeakKeyDictionary()
33
36
 
34
- if self.robocop_installed and self.robocop_version < (6, 0):
37
+ if self.parent.robocop_helper.robocop_installed:
35
38
  parent.diagnostics.collect.add(self.collect_diagnostics)
36
39
 
37
40
  def get_config(self, document: TextDocument) -> Optional[RoboCopConfig]:
@@ -45,21 +48,80 @@ class RobotRoboCopDiagnosticsProtocolPart(RobotLanguageServerProtocolPart, RoboC
45
48
  @_logger.call
46
49
  def collect_diagnostics(
47
50
  self, sender: Any, document: TextDocument, diagnostics_type: DiagnosticsCollectType
48
- ) -> DiagnosticsResult:
49
- workspace_folder = self.parent.workspace.get_workspace_folder(document.uri)
50
- if workspace_folder is not None:
51
- extension_config = self.get_config(document)
52
-
53
- if extension_config is not None and extension_config.enabled:
54
- return DiagnosticsResult(
55
- self.collect_diagnostics,
56
- self.collect(document, workspace_folder, extension_config),
57
- )
51
+ ) -> Optional[DiagnosticsResult]:
52
+ if self.parent.robocop_helper.robocop_installed:
53
+ workspace_folder = self.parent.workspace.get_workspace_folder(document.uri)
54
+ if workspace_folder is not None:
55
+ config = self.get_config(document)
56
+
57
+ if config is not None and config.enabled:
58
+ if self.parent.robocop_helper.robocop_version >= (6, 0):
59
+ # In Robocop 6.0, the diagnostics are collected in a different way
60
+ return DiagnosticsResult(self.collect_diagnostics, self.collect(document, workspace_folder))
61
+
62
+ return DiagnosticsResult(
63
+ self.collect_diagnostics,
64
+ self.collect_old(document, workspace_folder, config),
65
+ )
66
+
67
+ return None
68
+
69
+ @_logger.call
70
+ def collect(self, document: TextDocument, workspace_folder: WorkspaceFolder) -> List[Diagnostic]:
71
+ from robocop.linter.rules import RuleSeverity
72
+ from robocop.linter.runner import RobocopLinter
73
+
74
+ linter = self._robocop_linters.get(workspace_folder, None)
75
+
76
+ if linter is None:
77
+ config_manager = self.parent.robocop_helper.get_config_manager(workspace_folder)
78
+
79
+ config = config_manager.get_config_for_source_file(document.uri.to_path())
58
80
 
59
- return DiagnosticsResult(self.collect_diagnostics, [])
81
+ linter = RobocopLinter(config_manager)
82
+ self._robocop_linters[workspace_folder] = linter
83
+
84
+ source = document.uri.to_path()
85
+
86
+ config = linter.config_manager.get_config_for_source_file(source)
87
+ model = self.parent.documents_cache.get_model(document, False)
88
+ diagnostics = linter.run_check(model, source, config)
89
+
90
+ return [
91
+ Diagnostic(
92
+ range=Range(
93
+ start=Position(
94
+ line=diagnostic.range.start.line - 1,
95
+ character=diagnostic.range.start.character - 1,
96
+ ),
97
+ end=Position(
98
+ line=max(0, diagnostic.range.end.line - 1),
99
+ character=max(0, diagnostic.range.end.character - 1),
100
+ ),
101
+ ),
102
+ message=diagnostic.message,
103
+ severity=(
104
+ DiagnosticSeverity.INFORMATION
105
+ if diagnostic.severity == RuleSeverity.INFO
106
+ else (
107
+ DiagnosticSeverity.WARNING
108
+ if diagnostic.severity == RuleSeverity.WARNING
109
+ else (
110
+ DiagnosticSeverity.ERROR
111
+ if diagnostic.severity == RuleSeverity.ERROR
112
+ else DiagnosticSeverity.HINT
113
+ )
114
+ )
115
+ ),
116
+ source=self.source_name,
117
+ code=f"{diagnostic.rule.rule_id}-{diagnostic.rule.name}",
118
+ code_description=self.get_code_description(self.parent.robocop_helper.robocop_version, diagnostic),
119
+ )
120
+ for diagnostic in diagnostics
121
+ ]
60
122
 
61
123
  @_logger.call
62
- def collect(
124
+ def collect_old(
63
125
  self,
64
126
  document: TextDocument,
65
127
  workspace_folder: WorkspaceFolder,
@@ -174,7 +236,9 @@ class RobotRoboCopDiagnosticsProtocolPart(RobotLanguageServerProtocolPart, RoboC
174
236
  if version < (3, 0):
175
237
  return None
176
238
 
177
- base = f"https://robocop.readthedocs.io/en/{version.major}.{version.minor}.{version.patch}"
239
+ version_letter = "v" if version.major >= 6 else ""
240
+
241
+ base = f"https://robocop.readthedocs.io/en/{version_letter}{version.major}.{version.minor}.{version.patch}"
178
242
 
179
243
  if version < (4, 0):
180
244
  return CodeDescription(href=f"{base}/rules.html#{issue.name}".lower())
@@ -187,4 +251,7 @@ class RobotRoboCopDiagnosticsProtocolPart(RobotLanguageServerProtocolPart, RoboC
187
251
  href=f"{base}/rules_list.html#{issue.name}-{issue.severity.value}{issue.rule_id}".lower()
188
252
  )
189
253
 
190
- return CodeDescription(href=f"{base}/rules_list.html#{issue.name}".lower())
254
+ if version < (6, 0):
255
+ return CodeDescription(href=f"{base}/rules_list.html#{issue.name}".lower())
256
+
257
+ return CodeDescription(href=f"{base}/rules/rules_list.html#{issue.rule.rule_id}-{issue.rule.name}".lower())
@@ -0,0 +1,117 @@
1
+ import functools
2
+ from pathlib import Path
3
+ from typing import TYPE_CHECKING, Dict, Union
4
+
5
+ from robotcode.core.lsp.types import MessageType
6
+ from robotcode.core.text_document import TextDocument
7
+ from robotcode.core.utils.logging import LoggingDescriptor
8
+ from robotcode.core.utils.version import Version, create_version_from_str
9
+ from robotcode.core.workspace import WorkspaceFolder
10
+
11
+ from ..configuration import RoboCopConfig
12
+ from .protocol_part import RobotLanguageServerProtocolPart
13
+
14
+ if TYPE_CHECKING:
15
+ from ..protocol import RobotLanguageServerProtocol
16
+
17
+ if TYPE_CHECKING:
18
+ from robocop.config import ConfigManager
19
+
20
+
21
+ class RobocopConfigError(Exception):
22
+ """Robocop configuration errors."""
23
+
24
+
25
+ class RoboCopHelper(RobotLanguageServerProtocolPart):
26
+ _logger = LoggingDescriptor()
27
+
28
+ def __init__(self, parent: "RobotLanguageServerProtocol") -> None:
29
+ super().__init__(parent)
30
+ self._config_managers: Dict[WorkspaceFolder, "ConfigManager"] = {}
31
+
32
+ @functools.cached_property
33
+ def robotidy_installed(self) -> bool:
34
+ try:
35
+ __import__("robotidy")
36
+ except ImportError:
37
+ return False
38
+ return True
39
+
40
+ @functools.cached_property
41
+ def robotidy_version(self) -> Version:
42
+ from robotidy.version import __version__
43
+
44
+ return create_version_from_str(__version__)
45
+
46
+ @functools.cached_property
47
+ def robotidy_version_str(self) -> str:
48
+ from robotidy.version import __version__
49
+
50
+ return str(__version__)
51
+
52
+ @functools.cached_property
53
+ def robocop_installed(self) -> bool:
54
+ try:
55
+ __import__("robocop")
56
+ except ImportError:
57
+ return False
58
+ return True
59
+
60
+ @functools.cached_property
61
+ def robocop_version(self) -> Version:
62
+ from robocop import __version__
63
+
64
+ return create_version_from_str(__version__)
65
+
66
+ @functools.cached_property
67
+ def robocop_version_str(self) -> str:
68
+ from robocop import __version__
69
+
70
+ return str(__version__)
71
+
72
+ def get_robocop_config(self, resource: Union[TextDocument, WorkspaceFolder]) -> RoboCopConfig:
73
+ folder = (
74
+ self.parent.workspace.get_workspace_folder(resource.uri) if isinstance(resource, TextDocument) else resource
75
+ )
76
+ if folder is None:
77
+ return RoboCopConfig()
78
+
79
+ return self.parent.workspace.get_configuration(RoboCopConfig, folder.uri)
80
+
81
+ def get_config_manager(self, workspace_folder: WorkspaceFolder) -> "ConfigManager":
82
+ from robocop.config import ConfigManager
83
+
84
+ if workspace_folder in self._config_managers:
85
+ return self._config_managers[workspace_folder]
86
+
87
+ config = self.get_robocop_config(workspace_folder)
88
+
89
+ result = None
90
+ try:
91
+ config_path = None
92
+
93
+ if config.config_file:
94
+ config_path = Path(config.config_file)
95
+ if not config_path.exists():
96
+ raise RobocopConfigError(f"Config file {config_path} does not exist.")
97
+
98
+ result = ConfigManager(
99
+ [],
100
+ root=workspace_folder.uri.to_path(),
101
+ config=config_path,
102
+ ignore_git_dir=config.ignore_git_dir,
103
+ ignore_file_config=config.ignore_file_config,
104
+ )
105
+ self._config_managers[workspace_folder] = result
106
+ return result
107
+ except Exception as e:
108
+ self._logger.exception(e)
109
+ e_msg = str(e)
110
+ error_details = f": {e_msg}" if e_msg else ""
111
+ self.parent.window.show_message(
112
+ f"Robocop configuration could not be loaded{error_details}. "
113
+ f"Please verify your configuration files "
114
+ f"and workspace settings. Check the output logs for detailed error information.",
115
+ MessageType.ERROR,
116
+ )
117
+ raise RobocopConfigError(f"Failed to load Robocop configuration: {e} ({e.__class__.__qualname__})") from e
@@ -68,7 +68,7 @@ class RobotSignatureHelpProtocolPart(RobotLanguageServerProtocolPart, ModelHelpe
68
68
  for base in cls.__bases__:
69
69
  method = self._find_method(base)
70
70
  if method:
71
- return cast(_SignatureHelpMethod, method)
71
+ return method
72
72
  return None
73
73
 
74
74
  @language_id("robotframework")
@@ -48,6 +48,7 @@ from .parts.project_info import ProjectInfoPart
48
48
  from .parts.references import RobotReferencesProtocolPart
49
49
  from .parts.rename import RobotRenameProtocolPart
50
50
  from .parts.robocop_diagnostics import RobotRoboCopDiagnosticsProtocolPart
51
+ from .parts.robocop_helper import RoboCopHelper
51
52
  from .parts.robot_workspace import RobotWorkspaceProtocolPart
52
53
  from .parts.selection_range import RobotSelectionRangeProtocolPart
53
54
  from .parts.semantic_tokens import RobotSemanticTokenProtocolPart
@@ -102,6 +103,7 @@ class RobotLanguageServerProtocol(LanguageServerProtocol):
102
103
  robot_completion = ProtocolPartDescriptor(RobotCompletionProtocolPart)
103
104
  robot_signature_help = ProtocolPartDescriptor(RobotSignatureHelpProtocolPart)
104
105
  robot_document_symbols = ProtocolPartDescriptor(RobotDocumentSymbolsProtocolPart)
106
+ robocop_helper = ProtocolPartDescriptor(RoboCopHelper)
105
107
  robot_robocop_diagnostics = ProtocolPartDescriptor(RobotRoboCopDiagnosticsProtocolPart)
106
108
  robot_formatting = ProtocolPartDescriptor(RobotFormattingProtocolPart)
107
109
  robot_semantic_tokens = ProtocolPartDescriptor(RobotSemanticTokenProtocolPart)
@@ -1 +0,0 @@
1
- __version__ = "1.3.0-dev.5"
@@ -1,49 +0,0 @@
1
- import functools
2
-
3
- from robotcode.core.utils.version import Version, create_version_from_str
4
-
5
-
6
- class RoboCopTidyMixin:
7
- """
8
- Mixin class for handling Robocop tidy operations.
9
- """
10
-
11
- @functools.cached_property
12
- def robotidy_installed(self) -> bool:
13
- try:
14
- __import__("robotidy")
15
- except ImportError:
16
- return False
17
- return True
18
-
19
- @functools.cached_property
20
- def robotidy_version(self) -> Version:
21
- from robotidy.version import __version__
22
-
23
- return create_version_from_str(__version__)
24
-
25
- @functools.cached_property
26
- def robotidy_version_str(self) -> str:
27
- from robotidy.version import __version__
28
-
29
- return str(__version__)
30
-
31
- @functools.cached_property
32
- def robocop_installed(self) -> bool:
33
- try:
34
- __import__("robocop")
35
- except ImportError:
36
- return False
37
- return True
38
-
39
- @functools.cached_property
40
- def robocop_version(self) -> Version:
41
- from robocop import __version__
42
-
43
- return create_version_from_str(__version__)
44
-
45
- @functools.cached_property
46
- def robocop_version_str(self) -> str:
47
- from robocop import __version__
48
-
49
- return str(__version__)