class RuboCop::Cop::Style::Semicolon
Checks for multiple expressions placed on the same line. It also checks for lines terminated with a semicolon.
This cop has `AllowAsExpressionSeparator` configuration option. It allows `;` to separate several expressions on the same line.
@example
# bad foo = 1; bar = 2; baz = 3; # good foo = 1 bar = 2 baz = 3
@example AllowAsExpressionSeparator: false (default)
# bad foo = 1; bar = 2
@example AllowAsExpressionSeparator: true
# good foo = 1; bar = 2
Constants
- MSG
Public Class Methods
autocorrect_incompatible_with()
click to toggle source
# File lib/rubocop/cop/style/semicolon.rb, line 35 def self.autocorrect_incompatible_with [Style::SingleLineMethods] end
Public Instance Methods
on_begin(node)
click to toggle source
# File lib/rubocop/cop/style/semicolon.rb, line 45 def on_begin(node) return if cop_config['AllowAsExpressionSeparator'] exprs = node.children return if exprs.size < 2 expressions_per_line(exprs).each do |line, expr_on_line| # Every line with more than one expression on it is a # potential offense next unless expr_on_line.size > 1 find_semicolon_positions(line) { |pos| register_semicolon(line, pos, true) } end end
on_new_investigation()
click to toggle source
# File lib/rubocop/cop/style/semicolon.rb, line 39 def on_new_investigation return if processed_source.blank? check_for_line_terminator_or_opener end
Private Instance Methods
check_for_line_terminator_or_opener()
click to toggle source
# File lib/rubocop/cop/style/semicolon.rb, line 63 def check_for_line_terminator_or_opener # Make the obvious check first return unless processed_source.raw_source.include?(';') each_semicolon do |line, column, token_before_semicolon| register_semicolon(line, column, false, token_before_semicolon) end end
each_semicolon() { |line, last.column, tokens| ... }
click to toggle source
# File lib/rubocop/cop/style/semicolon.rb, line 72 def each_semicolon tokens_for_lines.each do |line, tokens| yield line, tokens.last.column, tokens[-2] if tokens.last.semicolon? yield line, tokens.first.column if tokens.first.semicolon? end end
expressions_per_line(exprs)
click to toggle source
# File lib/rubocop/cop/style/semicolon.rb, line 103 def expressions_per_line(exprs) # create a map matching lines to the number of expressions on them exprs_lines = exprs.map(&:first_line) exprs_lines.group_by(&:itself) end
find_range_node(token_before_semicolon)
click to toggle source
# File lib/rubocop/cop/style/semicolon.rb, line 117 def find_range_node(token_before_semicolon) range_nodes.detect do |range_node| range_node.source_range.contains?(token_before_semicolon.pos) end end
find_semicolon_positions(line) { |last_match.begin(0)| ... }
click to toggle source
# File lib/rubocop/cop/style/semicolon.rb, line 109 def find_semicolon_positions(line) # Scan for all the semicolons on the line semicolons = processed_source[line - 1].enum_for(:scan, ';') semicolons.each do yield Regexp.last_match.begin(0) end end
range_nodes()
click to toggle source
# File lib/rubocop/cop/style/semicolon.rb, line 123 def range_nodes return @range_nodes if instance_variable_defined?(:@range_nodes) ast = processed_source.ast @range_nodes = ast.range_type? ? [ast] : [] @range_nodes.concat(ast.each_descendant(:irange, :erange).to_a) end
register_semicolon(line, column, after_expression, token_before_semicolon = nil)
click to toggle source
# File lib/rubocop/cop/style/semicolon.rb, line 83 def register_semicolon(line, column, after_expression, token_before_semicolon = nil) range = source_range(processed_source.buffer, line, column) add_offense(range) do |corrector| if after_expression corrector.replace(range, "\n") else # Prevents becoming one range instance with subsequent line when endless range # without parentheses. # See: https://github.com/rubocop/rubocop/issues/10791 if token_before_semicolon&.regexp_dots? range_node = find_range_node(token_before_semicolon) corrector.wrap(range_node, '(', ')') if range_node end corrector.remove(range) end end end
tokens_for_lines()
click to toggle source
# File lib/rubocop/cop/style/semicolon.rb, line 79 def tokens_for_lines processed_source.tokens.group_by(&:line) end