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

[Fix #7777, #7776]: Generate valid code if comment present before closing brace #7835

Closed
wants to merge 14 commits into from
Closed
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
15 changes: 14 additions & 1 deletion CHANGELOG.md
Expand Up @@ -2,6 +2,15 @@

## master (unreleased)

### Bug fixes

* [#7842](https://github.com/rubocop-hq/rubocop/issues/7842): Fix a false positive for `Lint/RaiseException` when raising Exception with explicit namespace. ([@koic][])
* [#7834](https://github.com/rubocop-hq/rubocop/issues/7834): Fix `Lint/UriRegexp` to register offense with array arguments. ([@tejasbubane][])
* [#7841](https://github.com/rubocop-hq/rubocop/issues/7841): Fix an error for `Style/TrailingCommaInBlockArgs` when lambda literal (`->`) has multiple arguments. ([@koic][])
* [#6963](https://github.com/rubocop-hq/rubocop/issues/6963): Check if iterating through Enumerator created with value returning method. ([@tomurb][])
* [#7777](https://github.com/rubocop-hq/rubocop/issues/7777): Fix crash for `Layout/MultilineArrayBraceLayout` when comment is present after last element. ([@shekhar-patil][])
* [#7776](https://github.com/rubocop-hq/rubocop/issues/7776): Fix crash for `Layout/MultilineMethodCallBraceLayout` when comment is present before closing braces. ([@shekhar-patil][])

## 0.81.0 (2020-04-01)

### New features
Expand All @@ -23,6 +32,7 @@
* [#7823](https://github.com/rubocop-hq/rubocop/pull/7823): Add `IgnoredMethods` configuration in `Metrics/AbcSize`, `Metrics/CyclomaticComplexity`, and `Metrics/PerceivedComplexity` cops. ([@drenmi][])
* [#7816](https://github.com/rubocop-hq/rubocop/pull/7816): Support Ruby 2.7's numbered parameter for `Style/Lambda`. ([@koic][])
* [#7829](https://github.com/rubocop-hq/rubocop/issues/7829): Fix an error for `Style/OneLineConditional` when one of the branches contains `next` keyword. ([@koic][])
* [#7384](https://github.com/rubocop-hq/rubocop/pull/7384): Add new `Style/DisableCopsWithinSourceCodeDirective` cop. ([@egze][])

### Bug fixes

Expand All @@ -42,7 +52,7 @@
### Changes

* [#7797](https://github.com/rubocop-hq/rubocop/pull/7797): Allow unicode-display_width dependency version 1.7.0. ([@yuritomanek][])
* [#7779](https://github.com/rubocop-hq/rubocop/issues/7779): Change `AllowComments` option of `Lint/SuppressedException` to true by default. ([@koic][])
* [#7805](https://github.com/rubocop-hq/rubocop/pull/7805): Change `AllowComments` option of `Lint/SuppressedException` to true by default. ([@koic][])
* [#7320](https://github.com/rubocop-hq/rubocop/issues/7320): `Naming/MethodName` now flags `attr_reader/attr_writer/attr_accessor/attr`. ([@denys281][])
* [#7813](https://github.com/rubocop-hq/rubocop/issues/7813): **(Breaking)** Remove `Lint/EndInMethod` cop. ([@tejasbubane][])

Expand Down Expand Up @@ -4426,3 +4436,6 @@
[@nikitasakov]: https://github.com/nikitasakov
[@dmolesUC]: https://github.com/dmolesUC
[@yuritomanek]: https://github.com/yuritomanek
[@egze]: https://github.com/egze
[@tomurb]: https://github.com/tomurb
[@shekhar-patil]: https://github.com/shekhar-patil
6 changes: 6 additions & 0 deletions config/default.yml
Expand Up @@ -2616,6 +2616,12 @@ Style/Dir:
Enabled: true
VersionAdded: '0.50'

Style/DisableCopsWithinSourceCodeDirective:
Description: >-
Forbids disabling/enabling cops within source code.
Enabled: false
VersionAdded: '0.75'

Style/Documentation:
Description: 'Document classes and non-namespace modules.'
Enabled: true
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop.rb
Expand Up @@ -423,6 +423,7 @@
require_relative 'rubocop/cop/style/date_time'
require_relative 'rubocop/cop/style/def_with_parentheses'
require_relative 'rubocop/cop/style/dir'
require_relative 'rubocop/cop/style/disable_cops_within_source_code_directive'
require_relative 'rubocop/cop/style/documentation_method'
require_relative 'rubocop/cop/style/documentation'
require_relative 'rubocop/cop/style/double_cop_disable_directive'
Expand Down Expand Up @@ -585,7 +586,6 @@
# relies on simple text
require_relative 'rubocop/formatter/clang_style_formatter'
require_relative 'rubocop/formatter/disabled_config_formatter'
require_relative 'rubocop/formatter/disabled_lines_formatter'
require_relative 'rubocop/formatter/emacs_style_formatter'
require_relative 'rubocop/formatter/file_list_formatter'
require_relative 'rubocop/formatter/fuubar_style_formatter'
Expand Down
25 changes: 25 additions & 0 deletions lib/rubocop/ast/node.rb
Expand Up @@ -290,6 +290,18 @@ def source_length

## Destructuring

def_node_matcher :lvasgn_return, <<~PATTERN
`(lvasgn $_ (send _ $_))
PATTERN

def_node_matcher :enumerated_method, <<~PATTERN
`(send (send (send _ :array) $_) :each)
PATTERN

def_node_matcher :enumerated, <<~PATTERN
^`(send (lvar $_) :each)
PATTERN

def_node_matcher :receiver, <<~PATTERN
{(send $_ ...) ({block numblock} (send $_ ...) ...)}
PATTERN
Expand Down Expand Up @@ -356,6 +368,10 @@ def empty_source?
{assignment? (send _recv :<< ...)}
PATTERN

def enumerating?(method)
enumerating_assigned?(method) || enumerating_chained?(method)
end

def literal?
LITERALS.include?(type)
end
Expand Down Expand Up @@ -559,6 +575,15 @@ def visit_descendants(types, &block)

private

def enumerating_chained?(method)
method == parent.enumerated_method
end

def enumerating_assigned?(method)
lvasgn_name, lvasgn_value = parent.parent&.lvasgn_return
lvasgn_value == method && !enumerated.nil? && enumerated == lvasgn_name
end

def visit_ancestors(types)
last_node = self

Expand Down
22 changes: 22 additions & 0 deletions lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb
Expand Up @@ -42,8 +42,30 @@ def correct_next_line_brace(corrector)

corrector.insert_before(
last_element_range_with_trailing_comma(node).end,
closing_brace_content(corrector, node)
)
end

def closing_brace_content(corrector, node)
range = range_with_surrounding_space(
range: children(node).last.source_range,
side: :right
).end.resize(1)
if range.source == '#'
trailing_content_of_closing_brace(corrector, node)
else
node.loc.end.source
end
end

def trailing_content_of_closing_brace(corrector, node)
range = range_between(
node.loc.end.begin_pos,
range_by_whole_lines(node.loc.expression).end.end_pos
)

corrector.remove(range)
range.source
end

def last_element_range_with_trailing_comma(node)
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/lint/raise_exception.rb
Expand Up @@ -16,12 +16,12 @@ class RaiseException < Cop
MSG = 'Use `StandardError` over `Exception`.'

def_node_matcher :exception?, <<~PATTERN
(send nil? ${:raise :fail} (const _ :Exception) ... )
(send nil? ${:raise :fail} (const {cbase nil?} :Exception) ... )
PATTERN

def_node_matcher :exception_new_with_message?, <<~PATTERN
(send nil? ${:raise :fail}
(send (const _ :Exception) :new ... ))
(send (const {cbase nil?} :Exception) :new ... ))
PATTERN

def on_send(node)
Expand Down
6 changes: 3 additions & 3 deletions lib/rubocop/cop/lint/uri_regexp.rb
Expand Up @@ -21,7 +21,7 @@ class UriRegexp < Cop
def_node_matcher :uri_regexp_with_argument?, <<~PATTERN
(send
(const ${nil? cbase} :URI) :regexp
(str $_))
${(str _) (array ...)})
PATTERN

def_node_matcher :uri_regexp_without_argument?, <<~PATTERN
Expand All @@ -32,7 +32,7 @@ class UriRegexp < Cop
def on_send(node)
uri_regexp_with_argument?(node) do |double_colon, arg|
register_offense(
node, top_level: double_colon ? '::' : '', arg: "('#{arg}')"
node, top_level: double_colon ? '::' : '', arg: "(#{arg.source})"
)
end

Expand All @@ -51,7 +51,7 @@ def autocorrect(node)
double_colon, arg = captured_values

top_level = double_colon ? '::' : ''
argument = arg ? "('#{arg}')" : ''
argument = arg ? "(#{arg.source})" : ''

corrector.replace(
node.loc.expression,
Expand Down
17 changes: 17 additions & 0 deletions lib/rubocop/cop/lint/void.rb
Expand Up @@ -25,6 +25,10 @@ module Lint
# do_something(some_array)
# end
#
# def some_method(some_array)
# some_array.each(&:some_other_method)
# end
#
# # good
# def some_method
# do_something
Expand All @@ -40,6 +44,11 @@ module Lint
# some_array.sort!
# do_something(some_array)
# end
#
# def some_method(some_array)
# some_array = some_array.map
# some_array.map(&:some_other_method)
# end
class Void < Cop
OP_MSG = 'Operator `%<op>s` used in void context.'
VAR_MSG = 'Variable `%<var>s` used in void context.'
Expand All @@ -60,6 +69,10 @@ class Void < Cop
shuffle slice sort sort_by squeeze strip sub
succ swapcase tr tr_s transform_values
unicode_normalize uniq upcase].freeze
VALUE_RETURNING_METHODS = %i[collect collect! delete_if drop_while
filter! find_index index keep_if map map!
reject reject! rindex select select! sort
sort! take_while uniq uniq!].freeze

def on_block(node)
return unless node.body && !node.body.begin_type?
Expand Down Expand Up @@ -143,6 +156,10 @@ def in_void_context?(node)

return false unless parent && parent.children.last == node

return false if VALUE_RETURNING_METHODS.any? do |method|
node.enumerating?(method)
end

VOID_CONTEXT_TYPES.include?(parent.type) && parent.void_context?
end
end
Expand Down
49 changes: 49 additions & 0 deletions lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb
@@ -0,0 +1,49 @@
# frozen_string_literal: true

# rubocop:disable Lint/RedundantCopDisableDirective

module RuboCop
module Cop
module Style
# Detects comments to enable/disable RuboCop.
# This is useful if want to make sure that every RuboCop error gets fixed
# and not quickly disabled with a comment.
#
# @example
# # bad
# # rubocop:disable Metrics/AbcSize
# def f
# end
# # rubocop:enable Metrics/AbcSize
#
# # good
# def fixed_method_name_and_no_rubocop_comments
# end
#
class DisableCopsWithinSourceCodeDirective < Cop
# rubocop:enable Lint/RedundantCopDisableDirective
MSG = 'Comment to disable/enable RuboCop.'

def investigate(processed_source)
processed_source.comments.each do |comment|
next unless rubocop_directive_comment?(comment)

add_offense(comment)
end
end

def autocorrect(comment)
lambda do |corrector|
corrector.replace(comment.loc.expression, '')
end
end

private

def rubocop_directive_comment?(comment)
comment.text =~ CommentConfig::COMMENT_DIRECTIVE_REGEXP
end
end
end
end
end
3 changes: 3 additions & 0 deletions lib/rubocop/cop/style/trailing_comma_in_block_args.rb
Expand Up @@ -44,6 +44,9 @@ class TrailingCommaInBlockArgs < Cop
MSG = 'Useless trailing comma present in block arguments.'

def on_block(node)
# lambda literal (`->`) never has block arguments.
return if node.send_node.lambda_literal?

return unless useless_trailing_comma?(node)

add_offense(node, location: last_comma(node).pos)
Expand Down
57 changes: 0 additions & 57 deletions lib/rubocop/formatter/disabled_lines_formatter.rb

This file was deleted.

1 change: 0 additions & 1 deletion lib/rubocop/formatter/formatter_set.rb
Expand Up @@ -11,7 +11,6 @@ class FormatterSet < Array
BUILTIN_FORMATTERS_FOR_KEYS = {
'[a]utogenconf' => AutoGenConfigFormatter,
'[c]lang' => ClangStyleFormatter,
'[d]isabled' => DisabledLinesFormatter,
'[e]macs' => EmacsStyleFormatter,
'[fi]les' => FileListFormatter,
'[fu]ubar' => FuubarStyleFormatter,
Expand Down
1 change: 1 addition & 0 deletions manual/cops.md
Expand Up @@ -334,6 +334,7 @@ In the following section you find all available cops:
* [Style/DateTime](cops_style.md#styledatetime)
* [Style/DefWithParentheses](cops_style.md#styledefwithparentheses)
* [Style/Dir](cops_style.md#styledir)
* [Style/DisableCopsWithinSourceCodeDirective](cops_style.md#styledisablecopswithinsourcecodedirective)
* [Style/Documentation](cops_style.md#styledocumentation)
* [Style/DocumentationMethod](cops_style.md#styledocumentationmethod)
* [Style/DoubleCopDisableDirective](cops_style.md#styledoublecopdisabledirective)
Expand Down
9 changes: 9 additions & 0 deletions manual/cops_lint.md
Expand Up @@ -3044,6 +3044,10 @@ def some_method(some_array)
do_something(some_array)
end

def some_method(some_array)
some_array.each(&:some_other_method)
end

# good
def some_method
do_something
Expand All @@ -3059,6 +3063,11 @@ def some_method(some_array)
some_array.sort!
do_something(some_array)
end

def some_method(some_array)
some_array = some_array.map
some_array.map(&:some_other_method)
end
```

### Configurable attributes
Expand Down