class Rubocop::Cop::Lint::EndAlignment
end
i
variable = lambda do |i|
end
variable = if true
@example
is defined.
For blocks - with the start of the expression where the block
of the keyword.
For keywords (if, def, etc.) the end is aligned with the start
This cop checks whether the end keywords are aligned properly.
def already_processed_node?(node)
def already_processed_node?(node) @inspected_blocks.include?(node) end
def block_is_on_next_line?(begin_node, block_node)
def block_is_on_next_line?(begin_node, block_node) begin_node.loc.line != block_node.loc.line end
def check(node)
def check(node) # discard modifier forms of if/while/until return unless node.loc.end kw_loc = node.loc.keyword end_loc = node.loc.end if kw_loc.line != end_loc.line && kw_loc.column != end_loc.column add_offence(:warning, end_loc, sprintf(MSG, end_loc.line, end_loc.column, kw_loc.source, kw_loc.line, kw_loc.column)) end end
def check_block_alignment(start_loc, block_loc)
def check_block_alignment(start_loc, block_loc) end_loc = block_loc.end if block_loc.begin.line != end_loc.line && start_loc.column != end_loc.column add_offence(:warning, end_loc, sprintf(MSG, end_loc.line, end_loc.column, start_loc.source.lines.to_a.first.chomp, start_loc.line, start_loc.column)) end end
def initialize
def initialize super @inspected_blocks = [] end
def inspect(source_buffer, source, tokens, ast, comments)
def inspect(source_buffer, source, tokens, ast, comments) @inspected_blocks = [] super end
def on_and(node)
def on_and(node) return if already_processed_node?(node) _left, right = *node if right.type == :block check_block_alignment(node.loc.expression, right.loc) @inspected_blocks << right end super end
def on_block(node)
def on_block(node) return if already_processed_node?(node) check_block_alignment(node.loc.expression, node.loc) super end
def on_casgn(node)
def on_casgn(node) _, _, children = *node process_block_assignment(node, children) super end
def on_class(node)
def on_class(node) check(node) super end
def on_def(node)
def on_def(node) check(node) super end
def on_defs(node)
def on_defs(node) check(node) super end
def on_if(node)
def on_if(node) check(node) if node.loc.respond_to?(:end) super end
def on_lvasgn(node)
def on_lvasgn(node) _, children = *node process_block_assignment(node, children) super end
def on_masgn(node)
def on_masgn(node) variables, args = *node process_block_assignment(variables, args) super end
def on_module(node)
def on_module(node) check(node) super end
def on_op_asgn(node)
def on_op_asgn(node) variable, _op, args = *node process_block_assignment(variable, args) super end
def on_send(node)
def on_send(node) _receiver, _method, *args = *node process_block_assignment(node, args.last) super end
def on_until(node)
def on_until(node) check(node) super end
def on_while(node)
def on_while(node) check(node) super end
def process_block_assignment(begin_node, block_node)
def process_block_assignment(begin_node, block_node) return unless block_node return if already_processed_node?(block_node) while block_node.type == :send receiver, _method, args = *block_node if receiver && [:block, :send].include?(receiver.type) block_node = receiver elsif args && [:block, :send].include?(args.type) block_node = args else break end end if block_node.type == :block # Align with the expression that is on the same line # where the block is defined return if block_is_on_next_line?(begin_node, block_node) @inspected_blocks << block_node check_block_alignment(begin_node.loc.expression, block_node.loc) end end