Skip to content

Commit

Permalink
Merge branch 'master' into struct_autocorrect
Browse files Browse the repository at this point in the history
  • Loading branch information
bbatsov committed Sep 1, 2020
2 parents 4e530f7 + 6d781b0 commit 71c4818
Show file tree
Hide file tree
Showing 131 changed files with 1,393 additions and 766 deletions.
13 changes: 12 additions & 1 deletion CHANGELOG.md
Expand Up @@ -5,6 +5,7 @@
### New features

* [#8451](https://github.com/rubocop-hq/rubocop/issues/8451): Add new `Style/RedundantSelfAssignment` cop. ([@fatkodima][])
* [#8384](https://github.com/rubocop-hq/rubocop/issues/8384): Add new `Layout/EmptyLineAfterMultilineCondition` cop. ([@fatkodima][])
* [#8390](https://github.com/rubocop-hq/rubocop/pull/8390): Add new `Style/SoleNestedConditional` cop. ([@fatkodima][])
* [#8562](https://github.com/rubocop-hq/rubocop/pull/8562): Add new `Style/KeywordParametersOrder` cop. ([@fatkodima][])
* [#8486](https://github.com/rubocop-hq/rubocop/pull/8486): Add new `Style/CombinableLoops` cop. ([@fatkodima][])
Expand All @@ -15,11 +16,13 @@
* Add new `Lint/TrailingCommaInAttributeDeclaration` cop. ([@drenmi][])
* [#8578](https://github.com/rubocop-hq/rubocop/pull/8578): Add `:restore_registry` context and `stub_cop_class` helper class. ([@marcandre][])
* [#8579](https://github.com/rubocop-hq/rubocop/pull/8579): Add `Cop.documentation_url`. ([@marcandre][])

* [#8510](https://github.com/rubocop-hq/rubocop/pull/8510): Add `RegexpNode#each_capture` and `parsed_tree`. ([@marcandre][])
* [#8365](https://github.com/rubocop-hq/rubocop/pull/8365): Cops defining `on_send` can be optimized by defining the constant `RESTRICT_ON_SEND` with a list of acceptable method names. ([@marcandre][])

### Bug fixes

* [#8508](https://github.com/rubocop-hq/rubocop/pull/8508): Fix a false positive for `Style/CaseLikeIf` when conditional contains comparison with a class. Mark `Style/CaseLikeIf` as not safe. ([@fatkodima][])
* [#8618](https://github.com/rubocop-hq/rubocop/issues/8618): Fix an infinite loop error for `Layout/EmptyLineBetweenDefs`. ([@fatkodima][])
* [#8534](https://github.com/rubocop-hq/rubocop/issues/8534): Fix `Lint/BinaryOperatorWithIdenticalOperands` for binary operators used as unary operators. ([@marcandre][])
* [#8537](https://github.com/rubocop-hq/rubocop/pull/8537): Allow a trailing comment as a description comment for `Bundler/GemComment`. ([@pocke][])
* [#8507](https://github.com/rubocop-hq/rubocop/issues/8507): Fix `Style/RescueModifier` to handle parentheses around rescue modifiers. ([@dsavochkin][])
Expand All @@ -30,13 +33,18 @@
* [#7705](https://github.com/rubocop-hq/rubocop/issues/7705): Fix `Style/OneLineConditional` cop to handle if/then/elsif/then/else/end cases. Add `AlwaysCorrectToMultiline` config option to this cop to always convert offenses to the multi-line form (false by default). ([@Lykos][], [@dsavochkin][])
* [#8590](https://github.com/rubocop-hq/rubocop/issues/8590): Fix an error when auto-correcting encoding mismatch file. ([@koic][])
* [#8321](https://github.com/rubocop-hq/rubocop/issues/8321): Enable auto-correction for `Layout/{Def}EndAlignment`, `Lint/EmptyEnsure`, `Style/ClassAndModuleChildren`. ([@marcandre][])
* [#8583](https://github.com/rubocop-hq/rubocop/issues/8583): Fix `Style/RedundantRegexpEscape` false positive for line continuations. ([@owst][])
* [#8593](https://github.com/rubocop-hq/rubocop/issues/8593): Fix `Style/RedundantRegexpCharacterClass` false positive for interpolated multi-line expressions. ([@owst][])
* [#8624](https://github.com/rubocop-hq/rubocop/pull/8624): Fix an error with the `Style/CaseLikeIf` cop where it does not properly handle overridden equality methods with no arguments. ([@Skipants][])

### Changes

* [#8413](https://github.com/rubocop-hq/rubocop/issues/8413): Pending cops warning now contains snippet that can be directly copied into `.rubocop.yml` as well as a notice about `NewCops: enable` config option. ([@colszowka][])
* [#8362](https://github.com/rubocop-hq/rubocop/issues/8362): Add numbers of correctable offenses to summary. ([@nguyenquangminh0711][])
* [#8513](https://github.com/rubocop-hq/rubocop/pull/8513): Clarify the ruby warning mentioned in the `Lint/ShadowingOuterLocalVariable` documentation. ([@chocolateboy][])
* [#8517](https://github.com/rubocop-hq/rubocop/pull/8517): Make `Style/HashTransformKeys` and `Style/HashTransformValues` aware of `to_h` with block. ([@eugeneius][])
* [#8529](https://github.com/rubocop-hq/rubocop/pull/8529): Mark `Lint/FrozenStringLiteralComment` as `Safe`, but with unsafe auto-correction. ([@marcandre][])
* [#8602](https://github.com/rubocop-hq/rubocop/pull/8602): Fix usage of `to_enum(:scan, regexp)` to work on TruffleRuby. ([@jaimerave][])

## 0.89.1 (2020-08-10)

Expand Down Expand Up @@ -4806,9 +4814,12 @@
[@knejad]: https://github.com/knejad
[@iamravitejag]: https://github.com/iamravitejag
[@volfgox]: https://github.com/volfgox
[@colszowka]: https://github.com/colszowka
[@dsavochkin]: https://github.com/dmytro-savochkin
[@sonalinavlakhe]: https://github.com/sonalinavlakhe
[@wcmonty]: https://github.com/wcmonty
[@nguyenquangminh0711]: https://github.com/nguyenquangminh0711
[@chocolateboy]: https://github.com/chocolateboy
[@Lykos]: https://github.com/Lykos
[@jaimerave]: https://github.com/jaimerave
[@Skipants]: https://github.com/Skipants
8 changes: 8 additions & 0 deletions config/default.yml
Expand Up @@ -435,6 +435,14 @@ Layout/EmptyLineAfterMagicComment:
Enabled: true
VersionAdded: '0.49'

Layout/EmptyLineAfterMultilineCondition:
Description: 'Enforces empty line after multiline condition.'
# This is disabled, because this style is not very common in practice.
Enabled: false
VersionAdded: '0.90'
Reference:
- https://github.com/airbnb/ruby#multiline-if-newline

Layout/EmptyLineBetweenDefs:
Description: 'Use empty lines between defs.'
StyleGuide: '#empty-lines-between-methods'
Expand Down
1 change: 1 addition & 0 deletions docs/modules/ROOT/pages/cops.adoc
Expand Up @@ -105,6 +105,7 @@ In the following section you find all available cops:
* xref:cops_layout.adoc#layoutemptycomment[Layout/EmptyComment]
* xref:cops_layout.adoc#layoutemptylineafterguardclause[Layout/EmptyLineAfterGuardClause]
* xref:cops_layout.adoc#layoutemptylineaftermagiccomment[Layout/EmptyLineAfterMagicComment]
* xref:cops_layout.adoc#layoutemptylineaftermultilinecondition[Layout/EmptyLineAfterMultilineCondition]
* xref:cops_layout.adoc#layoutemptylinebetweendefs[Layout/EmptyLineBetweenDefs]
* xref:cops_layout.adoc#layoutemptylines[Layout/EmptyLines]
* xref:cops_layout.adoc#layoutemptylinesaroundaccessmodifier[Layout/EmptyLinesAroundAccessModifier]
Expand Down
68 changes: 68 additions & 0 deletions docs/modules/ROOT/pages/cops_layout.adoc
Expand Up @@ -1244,6 +1244,74 @@ end

* https://rubystyle.guide#separate-magic-comments-from-code

== Layout/EmptyLineAfterMultilineCondition

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Disabled
| Yes
| Yes
| 0.90
| -
|===

This cop enforces empty line after multiline condition.

=== Examples

[source,ruby]
----
# bad
if multiline &&
condition
do_something
end
# good
if multiline &&
condition
do_something
end
# bad
case x
when foo,
bar
do_something
end
# good
case x
when foo,
bar
do_something
end
# bad
begin
do_something
rescue FooError,
BarError
handle_error
end
# good
begin
do_something
rescue FooError,
BarError
handle_error
end
----

=== References

* https://github.com/airbnb/ruby#multiline-if-newline

== Layout/EmptyLineBetweenDefs

|===
Expand Down
11 changes: 11 additions & 0 deletions docs/modules/ROOT/pages/cops_style.adoc
Expand Up @@ -3630,6 +3630,7 @@ end
# good
def test
return unless something
work
end
Expand Down Expand Up @@ -4971,9 +4972,19 @@ when reading code.

[source,ruby]
----
# bad
a do
b
end.c
# good
a { b }.c
# good
foo = a do
b
end
foo.c
----

=== References
Expand Down
5 changes: 5 additions & 0 deletions docs/modules/ROOT/pages/development.adoc
Expand Up @@ -210,6 +210,9 @@ def on_send(node)
end
----

The `on_send` callback is the most used and can be optimized by restricting the acceptable
method names with a constant `RESTRICT_ON_SEND`.

And the final cop code will look like something like this:

[source,ruby]
Expand All @@ -232,6 +235,8 @@ module RuboCop
(send (send $(...) :empty?) :!)
PATTERN
RESTRICT_ON_SEND = [:!].freeze # optimization: don't call `on_send` unless
# the method name is in this list
def on_send(node)
return unless not_empty_call?(node)
Expand Down
2 changes: 2 additions & 0 deletions lib/rubocop.rb
Expand Up @@ -9,6 +9,7 @@
require 'unicode/display_width/no_string_ext'
require 'rubocop-ast'
require_relative 'rubocop/ast_aliases'
require_relative 'rubocop/ext/regexp_node'

require_relative 'rubocop/version'

Expand Down Expand Up @@ -167,6 +168,7 @@
require_relative 'rubocop/cop/layout/empty_comment'
require_relative 'rubocop/cop/layout/empty_line_after_guard_clause'
require_relative 'rubocop/cop/layout/empty_line_after_magic_comment'
require_relative 'rubocop/cop/layout/empty_line_after_multiline_condition'
require_relative 'rubocop/cop/layout/empty_line_between_defs'
require_relative 'rubocop/cop/layout/empty_lines_around_access_modifier'
require_relative 'rubocop/cop/layout/empty_lines_around_arguments'
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cached_data.rb
Expand Up @@ -4,6 +4,7 @@

module RuboCop
# Converts RuboCop objects to and from the serialization format JSON.
# @api private
class CachedData
def initialize(filename)
@filename = filename
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cli/command.rb
Expand Up @@ -3,6 +3,7 @@
module RuboCop
class CLI
# Home of subcommands in the CLI.
# @api private
module Command
class << self
# Find the command with a given name and run it in an environment.
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cli/command/auto_genenerate_config.rb
Expand Up @@ -4,6 +4,7 @@ module RuboCop
class CLI
module Command
# Generate a configuration file acting as a TODO list.
# @api private
class AutoGenerateConfig < Base
self.command_name = :auto_gen_config

Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cli/command/base.rb
Expand Up @@ -4,6 +4,7 @@ module RuboCop
class CLI
module Command
# A subcommand in the CLI.
# @api private
class Base
attr_reader :env

Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cli/command/execute_runner.rb
Expand Up @@ -4,6 +4,7 @@ module RuboCop
class CLI
module Command
# Run all the selected cops and report the result.
# @api private
class ExecuteRunner < Base
include Formatter::TextUtil

Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cli/command/init_dotfile.rb
Expand Up @@ -4,6 +4,7 @@ module RuboCop
class CLI
module Command
# Generate a .rubocop.yml file in the current directory.
# @api private
class InitDotfile < Base
DOTFILE = ConfigLoader::DOTFILE

Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cli/command/show_cops.rb
Expand Up @@ -5,6 +5,7 @@ class CLI
module Command
# Shows the given cops, or all cops by default, and their configurations
# for the current directory.
# @api private
class ShowCops < Base
self.command_name = :show_cops

Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cli/command/version.rb
Expand Up @@ -4,6 +4,7 @@ module RuboCop
class CLI
module Command
# Display version.
# @api private
class Version < Base
self.command_name = :version

Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cli/environment.rb
Expand Up @@ -3,6 +3,7 @@
module RuboCop
class CLI
# Execution environment for a CLI command.
# @api private
class Environment
attr_reader :options, :config_store, :paths

Expand Down
5 changes: 5 additions & 0 deletions lib/rubocop/comment_config.rb
Expand Up @@ -4,12 +4,17 @@ module RuboCop
# This class parses the special `rubocop:disable` comments in a source
# and provides a way to check if each cop is enabled at arbitrary line.
class CommentConfig
# @api private
REDUNDANT_DISABLE = 'Lint/RedundantCopDisableDirective'

# @api private
COP_NAME_PATTERN = '([A-Z]\w+/)?(?:[A-Z]\w+)'
# @api private
COP_NAMES_PATTERN = "(?:#{COP_NAME_PATTERN} , )*#{COP_NAME_PATTERN}"
# @api private
COPS_PATTERN = "(all|#{COP_NAMES_PATTERN})"

# @api private
COMMENT_DIRECTIVE_REGEXP = Regexp.new(
"# rubocop : ((?:disable|enable|todo))\\b #{COPS_PATTERN}"
.gsub(' ', '\s*')
Expand Down
23 changes: 17 additions & 6 deletions lib/rubocop/config_loader.rb
Expand Up @@ -140,22 +140,33 @@ def project_root
@project_root ||= find_project_root
end

PENDING_BANNER = <<~BANNER
The following cops were added to RuboCop, but are not configured. Please set Enabled to either `true` or `false` in your `.rubocop.yml` file.
Please also note that can also opt-in to new cops by default by adding this to your config:
AllCops:
NewCops: enable
BANNER

def warn_on_pending_cops(pending_cops)
return if pending_cops.empty?

warn Rainbow('The following cops were added to RuboCop, but are not ' \
'configured. Please set Enabled to either `true` or ' \
'`false` in your `.rubocop.yml` file:').yellow
warn Rainbow(PENDING_BANNER).yellow

pending_cops.each do |cop|
version = cop.metadata['VersionAdded'] || 'N/A'

warn Rainbow(" - #{cop.name} (#{version})").yellow
warn_pending_cop cop
end

warn Rainbow('For more information: https://docs.rubocop.org/rubocop/versioning.html').yellow
end

def warn_pending_cop(cop)
version = cop.metadata['VersionAdded'] || 'N/A'

warn Rainbow("#{cop.name}: # (new in #{version})").yellow
warn Rainbow(' Enabled: true').yellow
end

# Merges the given configuration with the default one.
def merge_with_default(config, config_file, unset_nil: true)
resolver.merge_with_default(config, config_file, unset_nil: unset_nil)
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/config_loader_resolver.rb
Expand Up @@ -5,6 +5,7 @@

module RuboCop
# A help class for ConfigLoader that handles configuration resolution.
# @api private
class ConfigLoaderResolver
def resolve_requires(path, hash)
config_dir = File.dirname(path)
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/config_obsoletion.rb
Expand Up @@ -2,6 +2,7 @@

module RuboCop
# This class handles obsolete configuration.
# @api private
class ConfigObsoletion
RENAMED_COPS = {
'Layout/AlignArguments' => 'Layout/ArgumentAlignment',
Expand Down
3 changes: 3 additions & 0 deletions lib/rubocop/config_validator.rb
Expand Up @@ -8,11 +8,14 @@ module RuboCop
class ConfigValidator
extend Forwardable

# @api private
COMMON_PARAMS = %w[Exclude Include Severity inherit_mode
AutoCorrect StyleGuide Details].freeze
# @api private
INTERNAL_PARAMS = %w[Description StyleGuide
VersionAdded VersionChanged VersionRemoved
Reference Safe SafeAutoCorrect].freeze
# @api private
NEW_COPS_VALUES = %w[pending disable enable].freeze

def_delegators :@config, :smart_loaded_path, :for_all_cops
Expand Down
7 changes: 7 additions & 0 deletions lib/rubocop/cop/base.rb
Expand Up @@ -46,6 +46,9 @@ class Base # rubocop:disable Metrics/ClassLength
# Consider creation API private
InvestigationReport = Struct.new(:cop, :processed_source, :offenses, :corrector)

# List of methods names to restrict calls for `on_send` / `on_csend`
RESTRICT_ON_SEND = Set[].freeze

# List of cops that should not try to autocorrect at the same
# time as this cop
#
Expand Down Expand Up @@ -287,6 +290,10 @@ def currently_disabled_lines
@currently_disabled_lines ||= Set.new
end

private_class_method def self.restrict_on_send
@restrict_on_send ||= self::RESTRICT_ON_SEND.to_set.freeze
end

# Called before any investigation
def begin_investigation(processed_source)
@current_offenses = []
Expand Down

0 comments on commit 71c4818

Please sign in to comment.