from enum import Enum from tclint.syntax_tree import Visitor, BareWord, Command from tclint.violations import Violation, Rule class Rules(Enum): VALIDATION = "validation" OPTIONAL_ARG_POSITION = "optinal_args" def __str__(self): return self.value class CommandArgsCheck(Visitor): def __init__(self): self._violations = [] def check(self, _, tree): self._violations.clear() tree.accept(self, recurse=True) return self._violations def visit_command(self, command: Command): if ( not hasattr(command.routine, "contents") or command.routine.contents != "proc" ): return if len(command.args) < 2: return args_node = command.args[1] if not hasattr(args_node, "children"): return found_optional = False for arg in args_node.children: # Required argument if isinstance(arg, BareWord): if found_optional: self._violations.append( Violation( Rules.OPTIONAL_ARG_POSITION, "Required argument follows optional one", arg.pos, arg.end_pos, ) ) # Optional argument elif hasattr(arg, "children") and len(arg.children) >= 2: found_optional = True def get_checkers(): checkers = (CommandArgsCheck(),) return checkers