def _call_handler(name, node): """Handle function calls.""" assert name == "FunctionCall" line_index = node.line - 1 col_index = node.col - 1 end_of_name_index = col_index + len(node.name) num_spaces_until_openparen = 0 index = end_of_name_index while contents[line_index][index] != "(": index += 1 # AST checks will assert if the open paren is not found here num_spaces_until_openparen = index - end_of_name_index # Must be one space only if num_spaces_until_openparen != 1: extra_spaces = num_spaces_until_openparen - 1 msg = "{0} extra spaces between call of {1}".format( extra_spaces, node.name) replacement = util.replace_word(contents[line_index], end_of_name_index, " " * (extra_spaces + 1), " ") errors.append(LinterFailure(msg, node.line, replacement))
def set_variables_capitalized(contents, abstract_syntax_tree): """Check that each variable mutated is capitalized.""" errors = [] variables = find_set_variables.in_tree(abstract_syntax_tree) for evaluate in variables: evaluate_upper = evaluate.contents.upper() # Argument should be either String or Variable and a transformation # to uppercase should have no effect if (util.is_word_sink_variable(evaluate.type) and evaluate_upper != evaluate.contents): desc = "{0} must be uppercase".format(evaluate.contents) line = evaluate.line - 1 replacement = util.replace_word(contents[line], evaluate.col - 1, evaluate.contents, evaluate_upper) errors.append(LinterFailure(desc, evaluate.line, replacement)) break return errors
def _call_handler(name, node): """Handle function calls.""" assert name == "FunctionCall" line_index = node.line - 1 col_index = node.col - 1 end_of_name_index = col_index + len(node.name) num_spaces_until_openparen = 0 index = end_of_name_index while contents[line_index][index] != "(": index += 1 # AST checks will assert if the open paren is not found here num_spaces_until_openparen = index - end_of_name_index # Must be one space only if num_spaces_until_openparen != 1: extra_spaces = num_spaces_until_openparen - 1 msg = "{0} extra spaces between call of {1}".format(extra_spaces, node.name) replacement = util.replace_word(contents[line_index], end_of_name_index, " " * (extra_spaces + 1), " ") errors.append(LinterFailure(msg, node.line, replacement))
def _offset_with_space(line, align_col, arg_col): """Insert spaces as required to place arg at align_col.""" offset = max(0, arg_col - align_col) spaces = max(0, align_col - arg_col) return util.replace_word(line, arg_col - 1 - offset, " " * offset, " " * spaces)
def _call_handler(name, node): """Handle function calls.""" assert name == "FunctionCall" if node.name.lower() != node.name: msg = "{0} is not lowercase".format(node.name) replacement = util.replace_word(contents[node.line - 1], node.col - 1, node.name, node.name.lower()) errors.append(LinterFailure(msg, node.line, replacement))
def _generate_error(node): """Generate an error and replacement for node in violation.""" msg = "Path {0} must be quoted".format(node.contents) line_index = node.line - 1 col_index = node.col - 1 quoted = "\"{0}\"" replacement = util.replace_word(contents[line_index], col_index, node.contents, quoted.format(node.contents)) return LinterFailure(msg, node.line, replacement)
def _generate_error(node): """Generate an error and replacement for node in violation.""" msg = "Path {0} must be quoted".format(node.contents) line_index = node.line - 1 col_index = node.col - 1 quoted = "\"{0}\"" replacement = util.replace_word(contents[line_index], col_index, node.contents, quoted.format(node.contents)) return LinterFailure(msg, node.line, replacement)
def _call_handler(name, node): """Handle function calls.""" assert name == "FunctionCall" if node.name.lower() != node.name: msg = "{0} is not lowercase".format(node.name) replacement = util.replace_word(contents[node.line - 1], node.col - 1, node.name, node.name.lower()) errors.append(LinterFailure(msg, node.line, replacement))
def _word_visitor(name, node): """Visit all arguments.""" assert name == "Word" if node.type == WordType.String: if not _RE_DOUBLE_OUTER_QUOTES.match(node.contents): msg = "{0} must use double quotes".format(node.contents) replacement_word = "\"{0}\"".format(node.contents[1:-1]) replacement = util.replace_word(contents[node.line - 1], node.col - 1, node.contents, replacement_word) errors.append(LinterFailure(msg, node.line, replacement))
def _visit_function_call(node, depth): """Handle function calls.""" col = node.col expected = 1 + (depth * indent) if node.col != expected: delta = expected - node.col msg = "Expected {0} to be on column {1}".format( node.name, expected) replacement = util.replace_word(contents[node.line - 1], col - 1 + min(0, delta), " " * max(0, delta * -1), " " * max(0, delta)) errors.append(LinterFailure(msg, node.line, replacement))
def _word_visitor(name, node): """Visit all arguments.""" assert name == "Word" if node.type == WordType.String: if not _RE_DOUBLE_OUTER_QUOTES.match(node.contents): msg = "{0} must use double quotes".format(node.contents) replacement_word = "\"{0}\"".format(node.contents[1:-1]) replacement = util.replace_word(contents[node.line - 1], node.col - 1, node.contents, replacement_word) errors.append(LinterFailure(msg, node.line, replacement))
def _visit_function_call(node, depth): """Handle function calls.""" col = node.col expected = 1 + (depth * indent) if node.col != expected: delta = expected - node.col msg = "Expected {0} to be on column {1}".format(node.name, expected) replacement = util.replace_word(contents[node.line - 1], col - 1 + min(0, delta), " " * max(0, delta * -1), " " * max(0, delta)) errors.append(LinterFailure(msg, node.line, replacement))
def _definition_handler(name, node): """Handle function calls and macro definitions.""" assert name == "FunctionDefinition" or name == "MacroDefinition" definition_name_word = node.header.arguments[0] definition_name = definition_name_word.contents if definition_name.lower() != definition_name: msg = "{0} name {1} is not lowercase".format(name, definition_name) line_index = definition_name_word.line - 1 col_index = definition_name_word.col - 1 replacement = util.replace_word(contents[line_index], col_index, definition_name, definition_name.lower()) errors.append( LinterFailure(msg, definition_name_word.line, replacement))
def _definition_visitor(name, node): """Visit all definitions.""" assert name == "FunctionDefinition" or name == "MacroDefinition" if len(node.header.arguments) < 2: return for arg in node.header.arguments[1:]: if arg.contents.upper() != arg.contents: msg = "{0} must be uppercase".format(arg.contents) line_index = arg.line - 1 col_index = arg.col - 1 replacement = util.replace_word(contents[line_index], col_index, arg.contents, arg.contents.upper()) errors.append(LinterFailure(msg, arg.line, replacement))
def _definition_visitor(name, node): """Visit all definitions.""" assert name == "FunctionDefinition" or name == "MacroDefinition" if len(node.header.arguments) < 2: return for arg in node.header.arguments[1:]: if arg.contents.upper() != arg.contents: msg = "{0} must be uppercase".format(arg.contents) line_index = arg.line - 1 col_index = arg.col - 1 replacement = util.replace_word(contents[line_index], col_index, arg.contents, arg.contents.upper()) errors.append(LinterFailure(msg, arg.line, replacement))
def _definition_handler(name, node): """Handle function calls and macro definitions.""" assert name == "FunctionDefinition" or name == "MacroDefinition" definition_name_word = node.header.arguments[0] definition_name = definition_name_word.contents if definition_name.lower() != definition_name: msg = "{0} name {1} is not lowercase".format(name, definition_name) line_index = definition_name_word.line - 1 col_index = definition_name_word.col - 1 replacement = util.replace_word(contents[line_index], col_index, definition_name, definition_name.lower()) errors.append(LinterFailure(msg, definition_name_word.line, replacement))
def _check_horizontal_space(node, index, contents): """Check horizontal space between arguments on same line.""" if index > 0: current_column = node.arguments[index].col - 1 previous_column = node.arguments[index - 1].col - 1 previous_len = len(node.arguments[index - 1].contents) spaces_start = previous_column + previous_len num_spaces = current_column - (previous_column + previous_len) line_number = node.arguments[index].line - 1 if num_spaces != 1: cur = node.arguments[index].contents prev = node.arguments[index - 1].contents msg = "Must be a single space between {0} and {1}".format( cur, prev) replacement = util.replace_word(contents[line_number], spaces_start, " " * num_spaces, " ") return LinterFailure(msg, node.line, replacement)
def set_variables_capitalized(contents, abstract_syntax_tree): """Check that each variable mutated is capitalized.""" errors = [] variables = find_set_variables.in_tree(abstract_syntax_tree) for evaluate in variables: evaluate_upper = evaluate.contents.upper() # Argument should be either String or Variable and a transformation # to uppercase should have no effect if (util.is_word_sink_variable(evaluate.type) and evaluate_upper != evaluate.contents): desc = "{0} must be uppercase".format(evaluate.contents) line = evaluate.line - 1 replacement = util.replace_word(contents[line], evaluate.col - 1, evaluate.contents, evaluate_upper) errors.append(LinterFailure(desc, evaluate.line, replacement)) break return errors
def _check_horizontal_space(node, index, contents): """Check horizontal space between arguments on same line.""" if index > 0: current_column = node.arguments[index].col - 1 previous_column = node.arguments[index - 1].col - 1 previous_len = len(node.arguments[index - 1].contents) spaces_start = previous_column + previous_len num_spaces = current_column - (previous_column + previous_len) line_number = node.arguments[index].line - 1 if num_spaces != 1: cur = node.arguments[index].contents prev = node.arguments[index - 1].contents msg = "Must be a single space between {0} and {1}".format(cur, prev) replacement = util.replace_word(contents[line_number], spaces_start, " " * num_spaces, " ") return LinterFailure(msg, node.line, replacement)
def _definition_handler(name, node, depth): """Visit all definitions.""" assert name == "FunctionDefinition" or name == "MacroDefinition" assert len(node.header.arguments) > 0 del depth definition = node.header.arguments[0] def_name = definition.contents if not def_name.startswith((namespace, "_" + namespace)): msg = "Definition {0} does not start with {1}".format(def_name, namespace) replacement_name = "{0}_{1}".format(namespace, def_name) if def_name.startswith("_"): replacement_name = "_{0}".format(replacement_name) replacement = util.replace_word(contents[node.line - 1], definition.col - 1, def_name, replacement_name) errors.append(LinterFailure(msg, node.line, replacement))
def _offset_with_space(line, align_col, arg_col): """Insert spaces as required to place arg at align_col.""" offset = max(0, arg_col - align_col) spaces = max(0, align_col - arg_col) return util.replace_word(line, arg_col - 1 - offset, " " * offset, " " * spaces)