Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Have correctors accept node instead of range #7863

Merged
merged 2 commits into from Apr 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,7 @@

### New features

* [#7863](https://github.com/rubocop-hq/rubocop/issues/7863): Corrector now accepts nodes in addition to ranges. ([@marcandre][])
* [#7862](https://github.com/rubocop-hq/rubocop/issues/7862): Corrector now has a `wrap` method. ([@marcandre][])
* [#7850](https://github.com/rubocop-hq/rubocop/issues/7850): Make it possible to enable/disable pending cops. ([@koic][])
* [#7861](https://github.com/rubocop-hq/rubocop/issues/7861): Make it to allow `Style/CaseEquality` when the receiver is a constant. ([@rafaelfranca][])
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/bundler/insecure_protocol_source.rb
Expand Up @@ -53,7 +53,7 @@ def on_send(node)
def autocorrect(node)
lambda do |corrector|
corrector.replace(
node.first_argument.loc.expression, "'https://rubygems.org'"
node.first_argument, "'https://rubygems.org'"
)
end
end
Expand Down
68 changes: 41 additions & 27 deletions lib/rubocop/cop/corrector.rb
Expand Up @@ -72,18 +72,18 @@ def rewrite

# Removes the source range.
#
# @param [Parser::Source::Range] range
def remove(range)
validate_range range
# @param [Parser::Source::Range, Rubocop::AST::Node] range or node
def remove(node_or_range)
range = to_range(node_or_range)
@source_rewriter.remove(range)
end

# Inserts new code before the given source range.
#
# @param [Parser::Source::Range] range
# @param [Parser::Source::Range, Rubocop::AST::Node] range or node
# @param [String] content
def insert_before(range, content)
validate_range range
def insert_before(node_or_range, content)
range = to_range(node_or_range)
# TODO: Fix Cops using bad ranges instead
if range.end_pos > @source_buffer.source.size
range = range.with(end_pos: @source_buffer.source.size)
Expand All @@ -94,38 +94,38 @@ def insert_before(range, content)

# Inserts new code after the given source range.
#
# @param [Parser::Source::Range] range
# @param [Parser::Source::Range, Rubocop::AST::Node] range or node
# @param [String] content
def insert_after(range, content)
validate_range range
def insert_after(node_or_range, content)
range = to_range(node_or_range)
@source_rewriter.insert_after(range, content)
end

# Wraps the given source range with the given before and after texts
#
# @param [Parser::Source::Range] range
# @param [Parser::Source::Range, Rubocop::AST::Node] range or node
# @param [String] before
# @param [String] after
def wrap(range, before, after)
validate_range range
def wrap(node_or_range, before, after)
range = to_range(node_or_range)
@source_rewriter.wrap(range, before, after)
end

# Replaces the code of the source range `range` with `content`.
#
# @param [Parser::Source::Range] range
# @param [Parser::Source::Range, Rubocop::AST::Node] range or node
# @param [String] content
def replace(range, content)
validate_range range
def replace(node_or_range, content)
range = to_range(node_or_range)
@source_rewriter.replace(range, content)
end

# Removes `size` characters prior to the source range.
#
# @param [Parser::Source::Range] range
# @param [Parser::Source::Range, Rubocop::AST::Node] range or node
# @param [Integer] size
def remove_preceding(range, size)
validate_range range
def remove_preceding(node_or_range, size)
range = to_range(node_or_range)
to_remove = Parser::Source::Range.new(range.source_buffer,
range.begin_pos - size,
range.begin_pos)
Expand All @@ -136,10 +136,10 @@ def remove_preceding(range, size)
# If `size` is greater than the size of `range`, the removed region can
# overrun the end of `range`.
#
# @param [Parser::Source::Range] range
# @param [Parser::Source::Range, Rubocop::AST::Node] range or node
# @param [Integer] size
def remove_leading(range, size)
validate_range range
def remove_leading(node_or_range, size)
range = to_range(node_or_range)
to_remove = Parser::Source::Range.new(range.source_buffer,
range.begin_pos,
range.begin_pos + size)
Expand All @@ -150,10 +150,10 @@ def remove_leading(range, size)
# If `size` is greater than the size of `range`, the removed region can
# overrun the beginning of `range`.
#
# @param [Parser::Source::Range] range
# @param [Parser::Source::Range, Rubocop::AST::Node] range or node
# @param [Integer] size
def remove_trailing(range, size)
validate_range range
def remove_trailing(node_or_range, size)
range = to_range(node_or_range)
to_remove = Parser::Source::Range.new(range.source_buffer,
range.end_pos - size,
range.end_pos)
Expand All @@ -163,11 +163,25 @@ def remove_trailing(range, size)
private

# :nodoc:
def validate_range(range)
buffer = range.source_buffer
def to_range(node_or_range)
range = case node_or_range
when ::RuboCop::AST::Node, ::Parser::Source::Comment
node_or_range.loc.expression
when ::Parser::Source::Range
node_or_range
else
raise TypeError,
'Expected a Parser::Source::Range, Comment or ' \
"Rubocop::AST::Node, got #{node_or_range.class}"
end
validate_buffer(range.source_buffer)
range
end

def validate_buffer(buffer)
return if buffer == @source_buffer

unless buffer.is_a?(Parser::Source::Buffer)
unless buffer.is_a?(::Parser::Source::Buffer)
# actually this should be enforced by parser gem
raise 'Corrector expected range source buffer to be a ' \
"Parser::Source::Buffer, but got #{buffer.class}"
Expand Down
3 changes: 1 addition & 2 deletions lib/rubocop/cop/correctors/condition_corrector.rb
Expand Up @@ -10,8 +10,7 @@ def correct_negative_condition(node)

lambda do |corrector|
corrector.replace(node.loc.keyword, node.inverse_keyword)
corrector.replace(condition.source_range,
condition.children.first.source)
corrector.replace(condition, condition.children.first.source)
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/correctors/empty_line_corrector.rb
Expand Up @@ -18,7 +18,7 @@ def correct(node)
end

def insert_before(node)
->(corrector) { corrector.insert_before(node.source_range, "\n") }
->(corrector) { corrector.insert_before(node, "\n") }
end
end
end
Expand Down
Expand Up @@ -44,13 +44,13 @@ def insert_separating_space(corrector)
end

def replace_selector(corrector)
corrector.replace(method.source_range, 'lambda')
corrector.replace(method, 'lambda')
end

def remove_arguments(corrector)
return if arguments.empty_and_without_delimiters?

corrector.remove(arguments.source_range)
corrector.remove(arguments)
end

def insert_arguments(corrector)
Expand All @@ -62,7 +62,7 @@ def insert_arguments(corrector)

def remove_leading_whitespace(corrector)
corrector.remove_preceding(
arguments.source_range,
arguments,
arguments.source_range.begin_pos -
block_node.send_node.source_range.end_pos
)
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/correctors/line_break_corrector.rb
Expand Up @@ -38,9 +38,9 @@ def move_comment(eol_comment:, node:, corrector:)
return unless eol_comment

text = eol_comment.loc.expression.source
corrector.insert_before(node.source_range,
corrector.insert_before(node,
text + "\n" + (' ' * node.loc.keyword.column))
corrector.remove(eol_comment.loc.expression)
corrector.remove(eol_comment)
end

private
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/correctors/percent_literal_corrector.rb
Expand Up @@ -26,7 +26,7 @@ def correct(node, char)
def wrap_contents(node, contents, char, delimiters)
lambda do |corrector|
corrector.replace(
node.source_range,
node,
"%#{char}#{delimiters[0]}#{contents}#{delimiters[1]}"
)
end
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/correctors/string_literal_corrector.rb
Expand Up @@ -13,9 +13,9 @@ def correct(node, style)
lambda do |corrector|
str = node.str_content
if style == :single_quotes
corrector.replace(node.source_range, to_string_literal(str))
corrector.replace(node, to_string_literal(str))
else
corrector.replace(node.source_range, str.inspect)
corrector.replace(node, str.inspect)
end
end
end
Expand Down
Expand Up @@ -28,7 +28,7 @@ def on_send(node)
def autocorrect(node)
(*, keyword) = offending_location_argument(node.parent)

->(corrector) { corrector.replace(node.source_range, ":#{keyword}") }
->(corrector) { corrector.replace(node, ":#{keyword}") }
end

private
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/layout/dot_position.rb
Expand Up @@ -44,7 +44,7 @@ def autocorrect(node)
when :leading
corrector.insert_before(selector_range(node), dot)
when :trailing
corrector.insert_after(node.receiver.source_range, dot)
corrector.insert_after(node.receiver, dot)
end
end
end
Expand Down
Expand Up @@ -169,7 +169,7 @@ def fix_closing_parenthesis(node, corrector)
end

def add_correct_closing_paren(node, corrector)
corrector.insert_after(node.arguments.last.source_range, ')')
corrector.insert_after(node.arguments.last, ')')
end

def remove_incorrect_closing_paren(node, corrector)
Expand Down Expand Up @@ -249,7 +249,7 @@ def fix_external_trailing_comma(node, corrector)
def add_correct_external_trailing_comma(node, corrector)
return unless external_trailing_comma?(node)

corrector.insert_after(node.arguments.last.source_range, ',')
corrector.insert_after(node.arguments.last, ',')
end

def remove_incorrect_external_trailing_comma(node, corrector)
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/layout/heredoc_indentation.rb
Expand Up @@ -184,14 +184,14 @@ def adjust_squiggly(corrector, node)
def adjust_minus(corrector, node)
heredoc_beginning = node.loc.expression.source
corrected = heredoc_beginning.sub(/<<-?/, '<<~')
corrector.replace(node.loc.expression, corrected)
corrector.replace(node, corrected)
end

def correct_by_library(node)
lambda do |corrector|
corrector.replace(node.loc.heredoc_body, indented_body(node))
corrected = ".#{STRIP_METHODS[style]}"
corrector.insert_after(node.loc.expression, corrected)
corrector.insert_after(node, corrected)
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/layout/multiline_block_layout.rb
Expand Up @@ -129,7 +129,7 @@ def autocorrect_body(corrector, node, block_body)

block_start_col = node.source_range.column

corrector.insert_before(first_node.source_range,
corrector.insert_before(first_node,
"\n #{' ' * block_start_col}")
end

Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/layout/space_around_block_parameters.rb
Expand Up @@ -43,9 +43,9 @@ def autocorrect(target)
lambda do |corrector|
if target.is_a?(RuboCop::AST::Node)
if target.parent.children.first == target
corrector.insert_before(target.source_range, ' ')
corrector.insert_before(target, ' ')
else
corrector.insert_after(target.source_range, ' ')
corrector.insert_after(target, ' ')
end
elsif target.source =~ /^\s+$/
corrector.remove(target)
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/layout/space_in_lambda_literal.rb
Expand Up @@ -46,7 +46,7 @@ def autocorrect(lambda_node)
children = lambda_node.parent.children
lambda do |corrector|
if style == :require_space
corrector.insert_before(children[1].source_range, ' ')
corrector.insert_before(children[1], ' ')
else
corrector.remove(space_after_arrow(lambda_node))
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/layout/space_inside_range_literal.rb
Expand Up @@ -35,7 +35,7 @@ def autocorrect(node)

lambda do |corrector|
corrector.replace(
node.source_range,
node,
expression
.sub(/\s+#{operator_escaped}/, operator)
.sub(/#{operator_escaped}\s+/, operator)
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/lint/boolean_symbol.rb
Expand Up @@ -41,7 +41,7 @@ def autocorrect(node)
corrector.remove(parent.loc.operator)
boolean_literal = "#{node.source} =>"
end
corrector.replace(node.loc.expression, boolean_literal)
corrector.replace(node, boolean_literal)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/lint/inherit_exception.rb
Expand Up @@ -77,7 +77,7 @@ def on_send(node)

def autocorrect(node)
lambda do |corrector|
corrector.replace(node.loc.expression, preferred_base_class)
corrector.replace(node, preferred_base_class)
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/lint/literal_in_interpolation.rb
Expand Up @@ -37,7 +37,7 @@ def autocorrect(node)
return if node.dstr_type? # nested, fixed in next iteration

value = autocorrected_value(node)
->(corrector) { corrector.replace(node.parent.source_range, value) }
->(corrector) { corrector.replace(node.parent, value) }
end

private
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/lint/multiple_comparison.rb
Expand Up @@ -39,7 +39,7 @@ def autocorrect(node)
new_center = "#{center.source} && #{center.source}"

lambda do |corrector|
corrector.replace(center.source_range, new_center)
corrector.replace(center, new_center)
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/lint/non_deterministic_require_order.rb
Expand Up @@ -52,12 +52,12 @@ def on_block(node)
def autocorrect(node)
if unsorted_dir_block?(node)
lambda do |corrector|
corrector.replace(node.loc.expression, "#{node.source}.sort.each")
corrector.replace(node, "#{node.source}.sort.each")
end
else
lambda do |corrector|
source = node.receiver.source
corrector.replace(node.loc.expression, "#{source}.sort.each")
corrector.replace(node, "#{source}.sort.each")
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/lint/number_conversion.rb
Expand Up @@ -55,7 +55,7 @@ def on_send(node)

def autocorrect(node)
lambda do |corrector|
corrector.replace(node.loc.expression,
corrector.replace(node,
correct_method(node, node.receiver))
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/lint/redundant_string_coercion.rb
Expand Up @@ -38,7 +38,7 @@ def autocorrect(node)
lambda do |corrector|
receiver = node.receiver
corrector.replace(
node.source_range,
node,
if receiver
receiver.source
else
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/lint/uri_regexp.rb
Expand Up @@ -54,7 +54,7 @@ def autocorrect(node)
argument = arg ? "(#{arg.source})" : ''

corrector.replace(
node.loc.expression,
node,
"#{top_level}URI::DEFAULT_PARSER.make_regexp#{argument}"
)
end
Expand Down