-
Notifications
You must be signed in to change notification settings - Fork 50
Description
Add --fix option (similar to ruff fix option) for linter rules.
Initial thread from: bhirsz/robotframework-cop-academy#5
As for final design, it needs to be modular (allow to easily add fixers, but don't force it) and various fixes should be compatible with each other. To solve it, there is following proposal:
- allow Rule to define 'fix', for example reference to the method that will fix given node (rename / remove / add / replace node). Each diagnostic should store the information about given available fix (and fix safety). For example:
fix = FixClass(safe=True, lines=(node.lineno, node.end_lineno)
or, to avoid creating instance of class in diagnostic we can map it in defition of rule and only mention in diagnostix which lines would be affected:
class SomeRule(Rule):
name = ...
...
fix = FixClass
...
self.report(self.some_rule, node=node, ..., fix_location=(node.lineno, node.end_lineno))
After the scan, Robocop should go over fix proposal. If there are several fixes for the same line, pick one (or decide what to pick / pick several if we will somehow tag fix if it can be applied with other fixes safely without interferring). Then apply all the fixes. We should then re-run the check if any fix was apply and repeat the fixing (for the remaining ones / new ones). We should temporarily cache the previous results to compare if we're not in cycle (after the fix issues are the same / more issues).
We use ModelVisitor for checkers and rules, and modyfing the model requires ModelTransformer. That's why we will need to introduce new type of model visitor for our needs:
class FixModel(ModelTransformer):
def __init__(safe: bool, lines..)
....
class SomeRuleFix(FixModel):
def visit_KeywordCall(node):
# do some fixing