Skip to content

Commit 48e747c

Browse files
authored
feat!: add deprecated-return-keyword rule fix and deprecate ReplaceReturns formatter (#1643)
New fix to deprecared-return-keyword rule which made ReplaceReturns formatter obsolete.
1 parent 113c011 commit 48e747c

30 files changed

+167
-425
lines changed

docs/formatter/formatter.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,6 @@ To see the list of formatters included with `Robocop` use ``robocop list formatt
142142
│ SmartSortKeywords │ No │
143143
│ RenameTestCases │ No │
144144
│ RenameKeywords │ No │
145-
│ ReplaceReturns │ Yes │
146145
│ ReplaceBreakContinue │ Yes │
147146
│ InlineIf │ Yes │
148147
│ Translate │ No │

docs/formatter/formatters/ReplaceReturns.md

Lines changed: 0 additions & 52 deletions
This file was deleted.

mkdocs.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ nav:
9191
- RenameVariables: formatter/formatters/RenameVariables.md
9292
- ReplaceBreakContinue: formatter/formatters/ReplaceBreakContinue.md
9393
- ReplaceEmptyValues: formatter/formatters/ReplaceEmptyValues.md
94-
- ReplaceReturns: formatter/formatters/ReplaceReturns.md
9594
- ReplaceRunKeywordIf: formatter/formatters/ReplaceRunKeywordIf.md
9695
- ReplaceWithVAR: formatter/formatters/ReplaceWithVAR.md
9796
- SmartSortKeywords: formatter/formatters/SmartSortKeywords.md

src/robocop/formatter/formatters/ReplaceReturns.py

Lines changed: 0 additions & 102 deletions
This file was deleted.

src/robocop/formatter/formatters/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@
6363
"SmartSortKeywords",
6464
"RenameTestCases",
6565
"RenameKeywords",
66-
"ReplaceReturns",
6766
"ReplaceBreakContinue",
6867
"InlineIf",
6968
"Translate",

src/robocop/formatter/utils/misc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ def create_statement_from_tokens(statement, tokens: Iterable, indent: Token):
196196
return statement([indent, Token(statement.type), *tokens])
197197

198198

199-
def wrap_in_if_and_replace_statement(node, statement, default_separator):
199+
def wrap_in_if_and_replace_statement(node, statement, default_separator: str):
200200
if len(node.data_tokens) < 2:
201201
return node
202202
condition = node.data_tokens[1]

src/robocop/linter/fix.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,21 +288,21 @@ def _apply_edit(lines: list[str], edit: TextEdit) -> None:
288288
start_line_idx = edit.start_line - 1
289289
end_line_idx = edit.end_line - 1
290290
if edit.start_col is None or edit.end_col is None: # replace_lines
291-
lines[start_line_idx : end_line_idx + 1] = [edit.replacement]
291+
lines[start_line_idx : end_line_idx + 1] = edit.replacement.splitlines(keepends=True)
292292
return
293293
start_col_idx = edit.start_col - 1
294294
end_col_idx = edit.end_col - 1
295295

296296
if start_line_idx == end_line_idx: # single line
297297
line = lines[edit.start_line - 1]
298298
new_line = line[:start_col_idx] + edit.replacement + line[end_col_idx:]
299-
lines[start_line_idx] = new_line
299+
lines[start_line_idx : start_line_idx + 1] = new_line.splitlines(keepends=True)
300300
else: # Multi-line edit
301301
# When edit is multiline, we replace the lines fully
302-
lines[start_line_idx : end_line_idx + 2] = [edit.replacement]
302+
lines[start_line_idx : end_line_idx + 2] = edit.replacement.splitlines(keepends=True)
303303
elif edit.kind == TextEditKind.INSERTION:
304304
start_line_idx = edit.start_line - 1
305-
lines.insert(start_line_idx, edit.replacement)
305+
lines[start_line_idx:start_line_idx] = edit.replacement.splitlines(keepends=True)
306306
else: # edit.kind == TextEditKind.DELETION
307307
start_line_idx = edit.start_line - 1
308308
del lines[start_line_idx : edit.end_line]

src/robocop/linter/rules/deprecated.py

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
1+
try:
2+
from robot.api.parsing import ReturnStatement
3+
except ImportError:
4+
ReturnStatement = None
5+
6+
from robocop.formatter.utils import misc as format_utils
17
from robocop.linter import sonar_qube
28
from robocop.linter.diagnostics import Diagnostic
39
from robocop.linter.fix import Fix, FixApplicability, FixAvailability, TextEdit
410
from robocop.linter.rules import FixableRule, Rule, RuleSeverity
11+
from robocop.source_file import StatementLinesCollector
512

613

714
class IfCanBeUsedRule(Rule):
@@ -345,7 +352,7 @@ class DeprecatedLoopKeywordRule(Rule):
345352
}
346353

347354

348-
class DeprecatedReturnKeyword(Rule):
355+
class DeprecatedReturnKeyword(FixableRule):
349356
"""
350357
``Return From Keyword`` and ``Return From Keyword If`` keywords are deprecated.
351358
@@ -361,8 +368,36 @@ class DeprecatedReturnKeyword(Rule):
361368
sonar_qube_attrs = sonar_qube.SonarQubeAttributes(
362369
clean_code=sonar_qube.CleanCodeAttribute.CONVENTIONAL, issue_type=sonar_qube.SonarQubeIssueType.CODE_SMELL
363370
)
364-
365371
deprecated_names = {"returnfromkeyword": "RETURN", "returnfromkeywordif": "IF and RETURN"}
372+
fix_availability = FixAvailability.ALWAYS
373+
374+
def fix(self, diag: Diagnostic, source_lines: list[str]) -> Fix | None: # noqa: ARG002
375+
"""Fix Return From Keyword. Return From Keyword If is handled inside a rule check."""
376+
if "if" in diag.reported_arguments["statement_name"].lower():
377+
if diag.node is None or not ReturnStatement:
378+
return None
379+
replacement_node = format_utils.wrap_in_if_and_replace_statement(diag.node, ReturnStatement, " ")
380+
if replacement_node is diag.node: # no changes
381+
return None
382+
replacement_text = StatementLinesCollector(replacement_node).text
383+
return Fix(
384+
edits=[
385+
TextEdit.replace_lines(
386+
rule_id=self.rule_id,
387+
rule_name=self.name,
388+
start_line=diag.node.lineno,
389+
end_line=diag.node.end_lineno,
390+
replacement=replacement_text,
391+
)
392+
],
393+
message="Replace Return From Keyword If keyword with IF and RETURN",
394+
applicability=FixApplicability.SAFE,
395+
)
396+
return Fix(
397+
edits=[TextEdit.replace_at_range(self.rule_id, self.name, diag.range, "RETURN")],
398+
message="Replace Return From Keyword keyword with RETURN",
399+
applicability=FixApplicability.SAFE,
400+
)
366401

367402

368403
class DeprecatedReturnSetting(FixableRule):

tests/formatter/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from robocop.formatter.utils.misc import decorate_diff_with_color
1515
from robocop.run import format_files
1616

17-
VERSION_MATRIX = {"ReplaceReturns": 5, "InlineIf": 5, "ReplaceBreakContinue": 5, "Translate": 6, "ReplaceWithVAR": 7}
17+
VERSION_MATRIX = {"InlineIf": 5, "ReplaceBreakContinue": 5, "Translate": 6, "ReplaceWithVAR": 7}
1818
ROBOT_VERSION = version.parse(RF_VERSION)
1919

2020

tests/formatter/formatters/ReplaceReturns/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)