Skip to content

Commit 125c091

Browse files
committed
refactor(langserver): move all error messages to one place
1 parent 4c03a80 commit 125c091

File tree

4 files changed

+71
-33
lines changed

4 files changed

+71
-33
lines changed

packages/language_server/src/robotcode/language_server/robotframework/diagnostics/analyzer.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@
4444
VariableDefinitionType,
4545
VariableNotFoundDefinition,
4646
)
47+
from .errors import DIAGNOSTICS_SOURCE_NAME, Error
4748
from .library_doc import KeywordDoc, KeywordMatcher, is_embedded_keyword
4849
from .namespace import (
49-
DIAGNOSTICS_SOURCE_NAME,
5050
KeywordFinder,
5151
Namespace,
5252
)
@@ -225,7 +225,7 @@ async def visit(self, node: ast.AST) -> None:
225225
message=f"Variable '{var.name}' not found.",
226226
severity=severity,
227227
source=DIAGNOSTICS_SOURCE_NAME,
228-
code="VariableNotFound",
228+
code=Error.VARIABLE_NOT_FOUND,
229229
)
230230
else:
231231
if isinstance(var, EnvironmentVariableDefinition) and var.default_value is None:
@@ -236,7 +236,7 @@ async def visit(self, node: ast.AST) -> None:
236236
message=f"Environment variable '{var.name}' not found.",
237237
severity=severity,
238238
source=DIAGNOSTICS_SOURCE_NAME,
239-
code="EnvirommentVariableNotFound",
239+
code=Error.ENVIROMMENT_VARIABLE_NOT_FOUND,
240240
)
241241

242242
if self.namespace.document is not None:
@@ -296,7 +296,7 @@ async def visit(self, node: ast.AST) -> None:
296296
message=f"Variable '{var.name}' not found.",
297297
severity=DiagnosticSeverity.ERROR,
298298
source=DIAGNOSTICS_SOURCE_NAME,
299-
code="VariableNotFound",
299+
code=Error.VARIABLE_NOT_FOUND,
300300
)
301301
else:
302302
if self.namespace.document is not None:
@@ -507,21 +507,21 @@ async def _analyze_keyword_call(
507507
f"{f': {result.deprecated_message}' if result.deprecated_message else ''}.",
508508
severity=DiagnosticSeverity.HINT,
509509
tags=[DiagnosticTag.DEPRECATED],
510-
code="DeprecatedKeyword",
510+
code=Error.DEPRECATED_KEYWORD,
511511
)
512512
if result.is_error_handler:
513513
self.append_diagnostics(
514514
range=kw_range,
515515
message=f"Keyword definition contains errors: {result.error_handler_message}",
516516
severity=DiagnosticSeverity.ERROR,
517-
code="KeywordContainsErrors",
517+
code=Error.KEYWORD_CONTAINS_ERRORS,
518518
)
519519
if result.is_reserved():
520520
self.append_diagnostics(
521521
range=kw_range,
522522
message=f"'{result.name}' is a reserved keyword.",
523523
severity=DiagnosticSeverity.ERROR,
524-
code="ReservedKeyword",
524+
code=Error.RESERVED_KEYWORD,
525525
)
526526

527527
if get_robot_version() >= (6, 0) and result.is_resource_keyword and result.is_private():
@@ -531,7 +531,7 @@ async def _analyze_keyword_call(
531531
message=f"Keyword '{result.longname}' is private and should only be called by"
532532
f" keywords in the same file.",
533533
severity=DiagnosticSeverity.WARNING,
534-
code="PrivateKeyword",
534+
code=Error.PRIVATE_KEYWORD,
535535
)
536536

537537
if not isinstance(node, (Template, TestTemplate)):
@@ -595,7 +595,7 @@ async def _analyze_keyword_call(
595595
range=range_from_token(var_token),
596596
message=f"Variable '{var.name}' not found.",
597597
severity=DiagnosticSeverity.ERROR,
598-
code="VariableNotFound",
598+
code=Error.VARIABLE_NOT_FOUND,
599599
)
600600
else:
601601
if self.namespace.document is not None:
@@ -675,7 +675,7 @@ async def _analyse_run_keyword(
675675
range=range_from_token(t),
676676
message=f"Incorrect use of {t.value}.",
677677
severity=DiagnosticSeverity.ERROR,
678-
code="IncorrectUse",
678+
code=Error.INCORRECT_USE,
679679
)
680680
continue
681681

@@ -843,7 +843,7 @@ async def visit_KeywordCall(self, node: ast.AST) -> None: # noqa: N802
843843
range=range_from_node_or_token(value, value.get_token(RobotToken.ASSIGN)),
844844
message="Keyword name cannot be empty.",
845845
severity=DiagnosticSeverity.ERROR,
846-
code="KeywordNameEmpty",
846+
code=Error.KEYWORD_NAME_EMPTY,
847847
)
848848
else:
849849
await self._analyze_keyword_call(
@@ -856,7 +856,7 @@ async def visit_KeywordCall(self, node: ast.AST) -> None: # noqa: N802
856856
message="Code is unreachable.",
857857
severity=DiagnosticSeverity.HINT,
858858
tags=[DiagnosticTag.UNNECESSARY],
859-
code="CodeUnreachable",
859+
code=Error.CODE_UNREACHABLE,
860860
)
861861

862862
await self.generic_visit(node)
@@ -874,7 +874,7 @@ async def visit_TestCase(self, node: ast.AST) -> None: # noqa: N802
874874
range=range_from_node_or_token(testcase, name_token),
875875
message="Test case name cannot be empty.",
876876
severity=DiagnosticSeverity.ERROR,
877-
code="TestCaseNameEmpty",
877+
code=Error.TESTCASE_NAME_EMPTY,
878878
)
879879

880880
self.current_testcase_or_keyword_name = testcase.name
@@ -907,15 +907,15 @@ async def visit_Keyword(self, node: ast.AST) -> None: # noqa: N802
907907
range=range_from_node_or_token(keyword, name_token),
908908
message="Keyword cannot have both normal and embedded arguments.",
909909
severity=DiagnosticSeverity.ERROR,
910-
code="KeywordNormalAndEmbbededError",
910+
code=Error.KEYWORD_CONTAINS_NORMAL_AND_EMBBEDED_ARGUMENTS,
911911
)
912912
else:
913913
name_token = cast(KeywordName, keyword.header).get_token(RobotToken.KEYWORD_NAME)
914914
self.append_diagnostics(
915915
range=range_from_node_or_token(keyword, name_token),
916916
message="Keyword name cannot be empty.",
917917
severity=DiagnosticSeverity.ERROR,
918-
code="KeywordNameEmpty",
918+
code=Error.KEYWORD_NAME_EMPTY,
919919
)
920920

921921
self.current_testcase_or_keyword_name = keyword.name
@@ -992,7 +992,7 @@ async def visit_ForceTags(self, node: ast.AST) -> None: # noqa: N802
992992
message="`Force Tags` is deprecated in favour of new `Test Tags` setting.",
993993
severity=DiagnosticSeverity.INFORMATION,
994994
tags=[DiagnosticTag.DEPRECATED],
995-
code="DeprecatedHyphenTag",
995+
code=Error.DEPRECATED_HYPHEN_TAG,
996996
)
997997

998998
async def visit_DefaultTags(self, node: ast.AST) -> None: # noqa: N802
@@ -1006,7 +1006,7 @@ async def visit_DefaultTags(self, node: ast.AST) -> None: # noqa: N802
10061006
message="`Force Tags` is deprecated in favour of new `Test Tags` setting.",
10071007
severity=DiagnosticSeverity.INFORMATION,
10081008
tags=[DiagnosticTag.DEPRECATED],
1009-
code="DeprecatedHyphenTag",
1009+
code=Error.DEPRECATED_HYPHEN_TAG,
10101010
)
10111011

10121012
async def visit_Tags(self, node: ast.AST) -> None: # noqa: N802
@@ -1026,7 +1026,7 @@ async def visit_Tags(self, node: ast.AST) -> None: # noqa: N802
10261026
f"literal value and to avoid this warning.",
10271027
severity=DiagnosticSeverity.WARNING,
10281028
tags=[DiagnosticTag.DEPRECATED],
1029-
code="DeprecatedHyphenTag",
1029+
code=Error.DEPRECATED_HYPHEN_TAG,
10301030
)
10311031

10321032
def _check_import_name(self, value: Optional[str], node: ast.AST, type: str) -> None:
@@ -1035,7 +1035,7 @@ def _check_import_name(self, value: Optional[str], node: ast.AST, type: str) ->
10351035
range=range_from_node(node),
10361036
message=f"{type} setting requires value.",
10371037
severity=DiagnosticSeverity.ERROR,
1038-
code="ImportRequiresValue",
1038+
code=Error.IMPORT_REQUIRES_VALUE,
10391039
)
10401040

10411041
async def visit_VariablesImport(self, node: ast.AST) -> None: # noqa: N802
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from typing import final
2+
3+
DIAGNOSTICS_SOURCE_NAME = "robotcode.namespace"
4+
5+
6+
@final
7+
class Error:
8+
VARIABLE_NOT_FOUND = "VariableNotFound"
9+
ENVIROMMENT_VARIABLE_NOT_FOUND = "EnvirommentVariableNotFound"
10+
KEYWORD_NOT_FOUND = "KeywordNotFoundError"
11+
LIBRARY_CONTAINS_NO_KEYWORDS = "LibraryContainsNoKeywords"
12+
POSSIBLE_CIRCULAR_IMPORT = "PossibleCircularImport"
13+
RESOURCE_EMPTY = "ResourceEmpty"
14+
IMPORT_CONTAINS_ERRORS = "ImportContainsErrors"
15+
RECURSIVE_IMPORT = "RecursiveImport"
16+
RESOURCE_ALREADY_IMPORTED = "ResourceAlreadyImported"
17+
VARIABLES_ALREADY_IMPORTED = "VariablesAlreadyImported"
18+
LIBRARY_ALREADY_IMPORTED = "LibraryAlreadyImported"
19+
LIBRARY_OVERRIDES_BUILTIN = "LibraryOverridesBuiltIn"
20+
DEPRECATED_KEYWORD = "DeprecatedKeyword"
21+
KEYWORD_CONTAINS_ERRORS = "KeywordContainsErrors"
22+
RESERVED_KEYWORD = "ReservedKeyword"
23+
PRIVATE_KEYWORD = "PrivateKeyword"
24+
INCORRECT_USE = "IncorrectUse"
25+
KEYWORD_NAME_EMPTY = "KeywordNameEmpty"
26+
CODE_UNREACHABLE = "CodeUnreachable"
27+
TESTCASE_NAME_EMPTY = "TestCaseNameEmpty"
28+
KEYWORD_CONTAINS_NORMAL_AND_EMBBEDED_ARGUMENTS = "KeywordContainsNormalAndEmbbededArguments"
29+
DEPRECATED_HYPHEN_TAG = "DeprecatedHyphenTag"
30+
IMPORT_REQUIRES_VALUE = "ImportRequiresValue"

packages/language_server/src/robotcode/language_server/robotframework/diagnostics/namespace.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
VariablesEntry,
7373
VariablesImport,
7474
)
75+
from .errors import DIAGNOSTICS_SOURCE_NAME, Error
7576
from .imports_manager import ImportsManager
7677
from .library_doc import (
7778
BUILTIN_LIBRARY_NAME,
@@ -82,8 +83,6 @@
8283
LibraryDoc,
8384
)
8485

85-
DIAGNOSTICS_SOURCE_NAME = "robotcode.namespace"
86-
8786
EXTRACT_COMMENT_PATTERN = re.compile(r".*(?:^ *|\t+| {2,})#(?P<comment>.*)$")
8887
ROBOTCODE_PATTERN = re.compile(r"(?P<marker>\brobotcode\b)\s*:\s*(?P<rule>\b\w+\b)")
8988

@@ -1043,7 +1042,7 @@ async def _import(
10431042
message=f"Imported library '{value.name}' contains no keywords.",
10441043
severity=DiagnosticSeverity.WARNING,
10451044
source=DIAGNOSTICS_SOURCE_NAME,
1046-
code="LibraryContainsNoKeywords",
1045+
code=Error.LIBRARY_CONTAINS_NO_KEYWORDS,
10471046
)
10481047
elif isinstance(value, ResourceImport):
10491048
if value.name is None:
@@ -1066,7 +1065,7 @@ async def _import(
10661065
]
10671066
if value.source
10681067
else None,
1069-
code="PossibleCircularImport",
1068+
code=Error.POSSIBLE_CIRCULAR_IMPORT,
10701069
)
10711070
else:
10721071
result = await self._get_resource_entry(
@@ -1091,7 +1090,7 @@ async def _import(
10911090
message=f"Imported resource file '{value.name}' is empty.",
10921091
severity=DiagnosticSeverity.WARNING,
10931092
source=DIAGNOSTICS_SOURCE_NAME,
1094-
code="ResourceEmpty",
1093+
code=Error.RESOURCE_EMPTY,
10951094
)
10961095

10971096
elif isinstance(value, VariablesImport):
@@ -1146,7 +1145,7 @@ async def _import(
11461145
for err in result.library_doc.errors
11471146
if err.source is not None
11481147
],
1149-
code="ImportContainsErrors",
1148+
code=Error.IMPORT_CONTAINS_ERRORS,
11501149
)
11511150
for err in filter(
11521151
lambda e: e.source is None or not Path(e.source).is_absolute(), result.library_doc.errors
@@ -1231,7 +1230,7 @@ async def _import(
12311230
message="Recursive resource import.",
12321231
severity=DiagnosticSeverity.INFORMATION,
12331232
source=DIAGNOSTICS_SOURCE_NAME,
1234-
code="RecursiveImport",
1233+
code=Error.RECURSIVE_IMPORT,
12351234
)
12361235
elif (
12371236
already_imported_resources is not None
@@ -1253,7 +1252,7 @@ async def _import(
12531252
]
12541253
if already_imported_resources.import_source
12551254
else None,
1256-
code="ResourceAlreadyImported",
1255+
code=Error.RESOURCE_ALREADY_IMPORTED,
12571256
)
12581257

12591258
elif isinstance(entry, VariablesEntry):
@@ -1285,7 +1284,7 @@ async def _import(
12851284
]
12861285
if already_imported_variables[0].import_source
12871286
else None,
1288-
code="VariablesAlreadyImported",
1287+
code=Error.VARIABLES_ALREADY_IMPORTED,
12891288
)
12901289

12911290
if (entry.alias or entry.name or entry.import_name) not in self._variables:
@@ -1310,7 +1309,7 @@ async def _import(
13101309
]
13111310
if entry.import_source
13121311
else None,
1313-
code="LibraryOverridesBuiltIn",
1312+
code=Error.LIBRARY_OVERRIDES_BUILTIN,
13141313
)
13151314
continue
13161315

@@ -1338,7 +1337,7 @@ async def _import(
13381337
]
13391338
if already_imported_library[0].import_source
13401339
else None,
1341-
code="LibraryAlreadyImported",
1340+
code=Error.LIBRARY_ALREADY_IMPORTED,
13421341
)
13431342

13441343
if (entry.alias or entry.name or entry.import_name) not in self._libraries:

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from robotcode.core.utils.inspect import iter_methods
2424
from robotcode.language_server.common.decorators import code_action_kinds, command, language_id
2525
from robotcode.language_server.common.text_document import TextDocument
26+
from robotcode.language_server.robotframework.diagnostics.errors import DIAGNOSTICS_SOURCE_NAME, Error
2627
from robotcode.language_server.robotframework.utils.ast_utils import (
2728
Token,
2829
get_node_at_position,
@@ -147,7 +148,7 @@ async def code_action_create_keyword(
147148
(
148149
d
149150
for d in context.diagnostics
150-
if d.source == "robotcode.namespace" and d.code == "KeywordNotFoundError"
151+
if d.source == DIAGNOSTICS_SOURCE_NAME and d.code == Error.KEYWORD_NOT_FOUND
151152
),
152153
None,
153154
)
@@ -364,7 +365,11 @@ async def code_action_create_local_variable(
364365
or context.trigger_kind in [CodeActionTriggerKind.INVOKED, CodeActionTriggerKind.AUTOMATIC]
365366
):
366367
diagnostics = next(
367-
(d for d in context.diagnostics if d.source == "robotcode.namespace" and d.code == "VariableNotFound"),
368+
(
369+
d
370+
for d in context.diagnostics
371+
if d.source == DIAGNOSTICS_SOURCE_NAME and d.code == Error.VARIABLE_NOT_FOUND
372+
),
368373
None,
369374
)
370375
if (
@@ -511,7 +516,11 @@ async def code_action_create_suite_variable(
511516
or context.trigger_kind in [CodeActionTriggerKind.INVOKED, CodeActionTriggerKind.AUTOMATIC]
512517
):
513518
diagnostics = next(
514-
(d for d in context.diagnostics if d.source == "robotcode.namespace" and d.code == "VariableNotFound"),
519+
(
520+
d
521+
for d in context.diagnostics
522+
if d.source == DIAGNOSTICS_SOURCE_NAME and d.code == Error.VARIABLE_NOT_FOUND
523+
),
515524
None,
516525
)
517526
if (

0 commit comments

Comments
 (0)