Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package rubygem-rubocop for openSUSE:Factory checked in at 2022-10-12 18:25:16 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rubygem-rubocop (Old) and /work/SRC/openSUSE:Factory/.rubygem-rubocop.new.2275 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-rubocop" Wed Oct 12 18:25:16 2022 rev:43 rq:1010069 version:1.36.0 Changes: -------- --- /work/SRC/openSUSE:Factory/rubygem-rubocop/rubygem-rubocop.changes 2022-08-27 11:50:15.533864832 +0200 +++ /work/SRC/openSUSE:Factory/.rubygem-rubocop.new.2275/rubygem-rubocop.changes 2022-10-12 18:27:05.442006742 +0200 @@ -1,0 +2,6 @@ +Mon Oct 10 13:19:53 UTC 2022 - Stephan Kulow <co...@suse.com> + +updated to version 1.36.0 + no changelog found + +------------------------------------------------------------------- Old: ---- rubocop-1.35.1.gem New: ---- rubocop-1.36.0.gem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rubygem-rubocop.spec ++++++ --- /var/tmp/diff_new_pack.7NNSEc/_old 2022-10-12 18:27:05.850007641 +0200 +++ /var/tmp/diff_new_pack.7NNSEc/_new 2022-10-12 18:27:05.854007649 +0200 @@ -24,7 +24,7 @@ # Name: rubygem-rubocop -Version: 1.35.1 +Version: 1.36.0 Release: 0 %define mod_name rubocop %define mod_full_name %{mod_name}-%{version} ++++++ rubocop-1.35.1.gem -> rubocop-1.36.0.gem ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/README.md new/README.md --- old/README.md 2022-08-22 07:47:33.000000000 +0200 +++ new/README.md 2022-09-01 09:58:49.000000000 +0200 @@ -53,7 +53,7 @@ in your `Gemfile`: ```rb -gem 'rubocop', '~> 1.35', require: false +gem 'rubocop', '~> 1.36', require: false ``` See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details. Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/config/default.yml new/config/default.yml --- old/config/default.yml 2022-08-22 07:47:33.000000000 +0200 +++ new/config/default.yml 2022-09-01 09:58:49.000000000 +0200 @@ -2794,6 +2794,7 @@ AllowNamesEndingInNumbers: true # Allowed names that will not register an offense AllowedNames: + - as - at - by - db @@ -2948,6 +2949,7 @@ - inline - group AllowModifiersOnSymbols: true + SafeAutoCorrect: false Style/AccessorGrouping: Description: 'Checks for grouping of accessors in `class` and `module` bodies.' @@ -3186,6 +3188,15 @@ # # good # String === "string" AllowOnConstant: false + # If `AllowOnSelfClass` option is enabled, the cop will ignore violations when the receiver of + # the case equality operator is `self.class`. + # + # # bad + # some_class === object + # + # # good + # self.class === object + AllowOnSelfClass: false Style/CaseLikeIf: Description: 'Identifies places where `if-elsif` constructions can be replaced with `case-when`.' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rubocop/cop/layout/block_alignment.rb new/lib/rubocop/cop/layout/block_alignment.rb --- old/lib/rubocop/cop/layout/block_alignment.rb 2022-08-22 07:47:33.000000000 +0200 +++ new/lib/rubocop/cop/layout/block_alignment.rb 2022-09-01 09:58:49.000000000 +0200 @@ -22,23 +22,24 @@ # # bad # # foo.bar - # .each do - # baz - # end + # .each do + # baz + # end # # # good # - # variable = lambda do |i| - # i + # foo.bar + # .each do + # baz # end # # @example EnforcedStyleAlignWith: start_of_block # # bad # # foo.bar - # .each do - # baz - # end + # .each do + # baz + # end # # # good # @@ -51,16 +52,17 @@ # # bad # # foo.bar - # .each do - # baz - # end + # .each do + # baz + # end # # # good # # foo.bar # .each do - # baz + # baz # end + # class BlockAlignment < Base include ConfigurableEnforcedStyle include RangeHelp diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rubocop/cop/layout/indentation_width.rb new/lib/rubocop/cop/layout/indentation_width.rb --- old/lib/rubocop/cop/layout/indentation_width.rb 2022-08-22 07:47:33.000000000 +0200 +++ new/lib/rubocop/cop/layout/indentation_width.rb 2022-09-01 09:58:49.000000000 +0200 @@ -148,7 +148,9 @@ check_indentation(in_pattern_node.loc.keyword, in_pattern_node.body) end - check_indentation(case_match.in_pattern_branches.last.loc.keyword, case_match.else_branch) + else_branch = case_match.else_branch&.empty_else_type? ? nil : case_match.else_branch + + check_indentation(case_match.in_pattern_branches.last.loc.keyword, else_branch) end def on_if(node, base = node) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rubocop/cop/layout/space_inside_block_braces.rb new/lib/rubocop/cop/layout/space_inside_block_braces.rb --- old/lib/rubocop/cop/layout/space_inside_block_braces.rb 2022-08-22 07:47:33.000000000 +0200 +++ new/lib/rubocop/cop/layout/space_inside_block_braces.rb 2022-09-01 09:58:49.000000000 +0200 @@ -131,7 +131,7 @@ args_delimiter = node.arguments.loc.begin if node.block_type? # Can be ( | or nil. check_left_brace(inner, node.loc.begin, args_delimiter) - check_right_brace(inner, node.loc.begin, node.loc.end, node.single_line?) + check_right_brace(node, inner, node.loc.begin, node.loc.end, node.single_line?) end def check_left_brace(inner, left_brace, args_delimiter) @@ -142,14 +142,15 @@ end end - def check_right_brace(inner, left_brace, right_brace, single_line) + def check_right_brace(node, inner, left_brace, right_brace, single_line) if single_line && /\S$/.match?(inner) no_space(right_brace.begin_pos, right_brace.end_pos, 'Space missing inside }.') else + column = node.loc.expression.column return if multiline_block?(left_brace, right_brace) && - aligned_braces?(left_brace, right_brace) + aligned_braces?(inner, right_brace, column) - space_inside_right_brace(right_brace) + space_inside_right_brace(inner, right_brace, column) end end @@ -157,8 +158,12 @@ left_brace.first_line != right_brace.first_line end - def aligned_braces?(left_brace, right_brace) - left_brace.first_line == right_brace.last_column + def aligned_braces?(inner, right_brace, column) + column == right_brace.column || column == inner_last_space_count(inner) + end + + def inner_last_space_count(inner) + inner.split("\n").last.count(' ') end def no_space_inside_left_brace(left_brace, args_delimiter) @@ -197,10 +202,21 @@ args_delimiter&.is?('|') end - def space_inside_right_brace(right_brace) + def space_inside_right_brace(inner, right_brace, column) brace_with_space = range_with_surrounding_space(right_brace, side: :left) - space(brace_with_space.begin_pos, brace_with_space.end_pos - 1, - 'Space inside } detected.') + begin_pos = brace_with_space.begin_pos + end_pos = brace_with_space.end_pos - 1 + + if brace_with_space.source.match?(/\R/) + begin_pos = end_pos - (right_brace.column - column) + end + + if inner.end_with?(']') + end_pos -= 1 + begin_pos = end_pos - (inner_last_space_count(inner) - column) + end + + space(begin_pos, end_pos, 'Space inside } detected.') end def no_space(begin_pos, end_pos, msg) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rubocop/cop/lint/ambiguous_block_association.rb new/lib/rubocop/cop/lint/ambiguous_block_association.rb --- old/lib/rubocop/cop/lint/ambiguous_block_association.rb 2022-08-22 07:47:33.000000000 +0200 +++ new/lib/rubocop/cop/lint/ambiguous_block_association.rb 2022-09-01 09:58:49.000000000 +0200 @@ -81,7 +81,7 @@ def allowed_method_pattern?(node) node.assignment? || node.operator_method? || node.method?(:[]) || allowed_method?(node.last_argument.method_name) || - matches_allowed_pattern?(node.last_argument.method_name) + matches_allowed_pattern?(node.last_argument.send_node.source) end def message(send_node) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rubocop/cop/lint/duplicate_require.rb new/lib/rubocop/cop/lint/duplicate_require.rb --- old/lib/rubocop/cop/lint/duplicate_require.rb 2022-08-22 07:47:33.000000000 +0200 +++ new/lib/rubocop/cop/lint/duplicate_require.rb 2022-09-01 09:58:49.000000000 +0200 @@ -3,7 +3,7 @@ module RuboCop module Cop module Lint - # Checks for duplicate `require`s and `require_relative`s. + # Checks for duplicate ``require``s and ``require_relative``s. # # @safety # This cop's autocorrection is unsafe because it may break the dependency order diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rubocop/cop/lint/empty_conditional_body.rb new/lib/rubocop/cop/lint/empty_conditional_body.rb --- old/lib/rubocop/cop/lint/empty_conditional_body.rb 2022-08-22 07:47:33.000000000 +0200 +++ new/lib/rubocop/cop/lint/empty_conditional_body.rb 2022-09-01 09:58:49.000000000 +0200 @@ -96,7 +96,7 @@ end def correct_other_branches(corrector, node) - return unless (node.if? || node.unless?) && node.else_branch + return unless require_other_branches_correction?(node) if node.else_branch.if_type? # Replace an orphaned `elsif` with `if` @@ -107,13 +107,43 @@ end end + def require_other_branches_correction?(node) + return false unless node.if_type? && node.else_branch + return false if !empty_if_branch?(node) && node.elsif? + + !empty_else_branch?(node) + end + + def empty_if_branch?(node) + return false unless (parent = node.parent) + return true unless parent.if_type? + return true unless (if_branch = parent.if_branch) + + if_branch.if_type? && !if_branch.body + end + + def empty_else_branch?(node) + node.else_branch.if_type? && !node.else_branch.body + end + + # rubocop:disable Metrics/AbcSize def branch_range(node) if node.loc.else node.source_range.with(end_pos: node.loc.else.begin_pos - 1) + elsif all_branches_body_missing?(node) + if_node = node.ancestors.detect(&:if?) + node.source_range.with(end_pos: if_node.loc.end.end_pos) else node.source_range end end + # rubocop:enable Metrics/AbcSize + + def all_branches_body_missing?(node) + return false unless node.parent&.if_type? + + node.parent.branches.compact.empty? + end def deletion_range(range) # Collect a range between the start of the `if` node and the next relevant node, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rubocop/cop/lint/shadowed_exception.rb new/lib/rubocop/cop/lint/shadowed_exception.rb --- old/lib/rubocop/cop/lint/shadowed_exception.rb 2022-08-22 07:47:33.000000000 +0200 +++ new/lib/rubocop/cop/lint/shadowed_exception.rb 2022-09-01 09:58:49.000000000 +0200 @@ -12,7 +12,7 @@ # same `rescue` statement. In both cases, the more specific rescue is # unnecessary because it is covered by rescuing the less specific # exception. (ie. `rescue Exception, StandardError` has the same behavior - # whether `StandardError` is included or not, because all `StandardError`s + # whether `StandardError` is included or not, because all ``StandardError``s # are rescued by `rescue Exception`). # # @example diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb new/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb --- old/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb 2022-08-22 07:47:33.000000000 +0200 +++ new/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb 2022-09-01 09:58:49.000000000 +0200 @@ -64,14 +64,26 @@ end def same_conditions_node_different_branch?(variable, outer_local_variable) - variable_node = variable.scope.node.parent + variable_node = variable_node(variable) return false unless variable_node.conditional? outer_local_variable_node = find_conditional_node_from_ascendant(outer_local_variable.declaration_node) return true unless outer_local_variable_node - outer_local_variable_node.conditional? && variable_node == outer_local_variable_node + outer_local_variable_node.conditional? && + (variable_node == outer_local_variable_node || + variable_node == outer_local_variable_node.else_branch) + end + + def variable_node(variable) + parent_node = variable.scope.node.parent + + if parent_node.when_type? + parent_node.parent + else + parent_node + end end def find_conditional_node_from_ascendant(node) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rubocop/cop/lint/unreachable_loop.rb new/lib/rubocop/cop/lint/unreachable_loop.rb --- old/lib/rubocop/cop/lint/unreachable_loop.rb 2022-08-22 07:47:33.000000000 +0200 +++ new/lib/rubocop/cop/lint/unreachable_loop.rb 2022-09-01 09:58:49.000000000 +0200 @@ -9,7 +9,7 @@ # In rare cases where only one iteration (or at most one iteration) is intended behavior, # the code should be refactored to use `if` conditionals. # - # NOTE: Block methods that are used with `Enumerable`s are considered to be loops. + # NOTE: Block methods that are used with ``Enumerable``s are considered to be loops. # # `AllowedPatterns` can be used to match against the block receiver in order to allow # code that would otherwise be registered as an offense (eg. `times` used not in an diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rubocop/cop/lint/useless_access_modifier.rb new/lib/rubocop/cop/lint/useless_access_modifier.rb --- old/lib/rubocop/cop/lint/useless_access_modifier.rb 2022-08-22 07:47:33.000000000 +0200 +++ new/lib/rubocop/cop/lint/useless_access_modifier.rb 2022-09-01 09:58:49.000000000 +0200 @@ -31,8 +31,8 @@ # # bad # class Foo # # The following is redundant (methods defined on the class' - # # singleton class are not affected by the public modifier) - # public + # # singleton class are not affected by the private modifier) + # private # # def self.method3 # end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rubocop/cop/lint/useless_ruby2_keywords.rb new/lib/rubocop/cop/lint/useless_ruby2_keywords.rb --- old/lib/rubocop/cop/lint/useless_ruby2_keywords.rb 2022-08-22 07:47:33.000000000 +0200 +++ new/lib/rubocop/cop/lint/useless_ruby2_keywords.rb 2022-09-01 09:58:49.000000000 +0200 @@ -6,7 +6,7 @@ # Looks for `ruby2_keywords` calls for methods that do not need it. # # `ruby2_keywords` should only be called on methods that accept an argument splat - # (`*args`) but do not explicit keyword arguments (`k:` or `k: true`) or + # (`\*args`) but do not explicit keyword arguments (`k:` or `k: true`) or # a keyword splat (`**kwargs`). # # @example diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rubocop/cop/mixin/allowed_methods.rb new/lib/rubocop/cop/mixin/allowed_methods.rb --- old/lib/rubocop/cop/mixin/allowed_methods.rb 2022-08-22 07:47:33.000000000 +0200 +++ new/lib/rubocop/cop/mixin/allowed_methods.rb 2022-09-01 09:58:49.000000000 +0200 @@ -17,16 +17,21 @@ # @api public def allowed_methods - deprecated_values = cop_config_deprecated_values - if deprecated_values.any?(Regexp) - cop_config.fetch('AllowedMethods', []) + if cop_config_deprecated_values.any?(Regexp) + cop_config_allowed_methods else - Array(cop_config['AllowedMethods']).concat(deprecated_values) + cop_config_allowed_methods + cop_config_deprecated_values end end + def cop_config_allowed_methods + @cop_config_allowed_methods ||= Array(cop_config.fetch('AllowedMethods', [])) + end + def cop_config_deprecated_values - Array(cop_config['IgnoredMethods']).concat(Array(cop_config['ExcludedMethods'])) + @cop_config_deprecated_values ||= + Array(cop_config.fetch('IgnoredMethods', [])) + + Array(cop_config.fetch('ExcludedMethods', [])) end end # @deprecated IgnoredMethods class has been replaced with AllowedMethods. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rubocop/cop/mixin/allowed_pattern.rb new/lib/rubocop/cop/mixin/allowed_pattern.rb --- old/lib/rubocop/cop/mixin/allowed_pattern.rb 2022-08-22 07:47:33.000000000 +0200 +++ new/lib/rubocop/cop/mixin/allowed_pattern.rb 2022-09-01 09:58:49.000000000 +0200 @@ -30,15 +30,23 @@ def allowed_patterns # Since there could be a pattern specified in the default config, merge the two # arrays together. - patterns = Array(cop_config['AllowedPatterns']).concat(Array(cop_config['IgnoredPatterns'])) - deprecated_values = cop_config_deprecated_methods_values - return patterns unless deprecated_values.any?(Regexp) + if cop_config_deprecated_methods_values.any?(Regexp) + cop_config_patterns_values + cop_config_deprecated_methods_values + else + cop_config_patterns_values + end + end - Array(patterns.concat(deprecated_values)) + def cop_config_patterns_values + @cop_config_patterns_values ||= + Array(cop_config.fetch('AllowedPatterns', [])) + + Array(cop_config.fetch('IgnoredPatterns', [])) end def cop_config_deprecated_methods_values - Array(cop_config['IgnoredMethods']).concat(Array(cop_config['ExcludedMethods'])) + @cop_config_deprecated_methods_values ||= + Array(cop_config.fetch('IgnoredMethods', [])) + + Array(cop_config.fetch('ExcludedMethods', [])) end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rubocop/cop/mixin/hash_transform_method.rb new/lib/rubocop/cop/mixin/hash_transform_method.rb --- old/lib/rubocop/cop/mixin/hash_transform_method.rb 2022-08-22 07:47:33.000000000 +0200 +++ new/lib/rubocop/cop/mixin/hash_transform_method.rb 2022-09-01 09:58:49.000000000 +0200 @@ -68,6 +68,8 @@ # `transform_values` if value transformation uses key. return if captures.transformation_uses_both_args? + return unless captures.use_transformed_argname? + message = "Prefer `#{new_method_name}` over `#{match_desc}`." add_offense(node, message: message) do |corrector| correction = prepare_correction(node) @@ -113,11 +115,7 @@ end # Internal helper class to hold match data - Captures = Struct.new( - :transformed_argname, - :transforming_body_expr, - :unchanged_body_expr - ) do + Captures = Struct.new(:transformed_argname, :transforming_body_expr, :unchanged_body_expr) do def noop_transformation? transforming_body_expr.lvar_type? && transforming_body_expr.children == [transformed_argname] @@ -126,6 +124,12 @@ def transformation_uses_both_args? transforming_body_expr.descendants.include?(unchanged_body_expr) end + + def use_transformed_argname? + transforming_body_expr.each_descendant(:lvar).any? do |node| + node.source == transformed_argname.to_s + end + end end # Internal helper class to hold autocorrect data diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rubocop/cop/style/access_modifier_declarations.rb new/lib/rubocop/cop/style/access_modifier_declarations.rb --- old/lib/rubocop/cop/style/access_modifier_declarations.rb 2022-08-22 07:47:33.000000000 +0200 +++ new/lib/rubocop/cop/style/access_modifier_declarations.rb 2022-09-01 09:58:49.000000000 +0200 @@ -9,6 +9,11 @@ # Applications of visibility methods to symbols can be controlled # using AllowModifiersOnSymbols config. # + # @safety + # Autocorrection is not safe, because the visibility of dynamically + # defined methods can vary depending on the state determined by + # the group access modifier. + # # @example EnforcedStyle: group (default) # # bad # class Foo @@ -63,7 +68,10 @@ # # end class AccessModifierDeclarations < Base + extend AutoCorrector + include ConfigurableEnforcedStyle + include RangeHelp GROUP_STYLE_MESSAGE = [ '`%<access_modifier>s` should not be', @@ -88,7 +96,10 @@ return if allow_modifiers_on_symbols?(node) if offense?(node) - add_offense(node.loc.selector) { opposite_style_detected } + add_offense(node.loc.selector) do |corrector| + autocorrect(corrector, node) + end + opposite_style_detected else correct_style_detected end @@ -96,6 +107,23 @@ private + def autocorrect(corrector, node) + case style + when :group + def_node = find_corresponding_def_node(node) + return unless def_node + + remove_node(corrector, def_node) + remove_node(corrector, node) + insert_def(corrector, node, def_node.source) + when :inline + remove_node(corrector, node) + select_grouped_def_nodes(node).each do |grouped_def_node| + insert_inline_modifier(corrector, grouped_def_node, node.method_name) + end + end + end + def allow_modifiers_on_symbols?(node) cop_config['AllowModifiersOnSymbols'] && access_modifier_with_symbol?(node) end @@ -130,6 +158,54 @@ format(INLINE_STYLE_MESSAGE, access_modifier: access_modifier) end end + + def find_corresponding_def_node(node) + if access_modifier_with_symbol?(node) + method_name = node.arguments.first.value + node.parent.each_child_node(:def).find do |child| + child.method?(method_name) + end + else + node.arguments.first + end + end + + def find_argument_less_modifier_node(node) + node.parent.each_child_node(:send).find do |child| + child.method?(node.method_name) && child.arguments.empty? + end + end + + def select_grouped_def_nodes(node) + node.right_siblings.take_while do |sibling| + !(sibling.send_type? && sibling.bare_access_modifier_declaration?) + end.select(&:def_type?) + end + + def insert_def(corrector, node, source) + argument_less_modifier_node = find_argument_less_modifier_node(node) + if argument_less_modifier_node + corrector.insert_after(argument_less_modifier_node, "\n\n#{source}") + else + corrector.insert_before( + node.each_ancestor(:block, :class, :module).first.location.end, + "#{node.method_name}\n\n#{source}\n" + ) + end + end + + def insert_inline_modifier(corrector, node, modifier_name) + corrector.insert_before(node, "#{modifier_name} ") + end + + def remove_node(corrector, node) + corrector.remove( + range_by_whole_lines( + node.location.expression, + include_final_newline: true + ) + ) + end end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rubocop/cop/style/case_equality.rb new/lib/rubocop/cop/style/case_equality.rb --- old/lib/rubocop/cop/style/case_equality.rb 2022-08-22 07:47:33.000000000 +0200 +++ new/lib/rubocop/cop/style/case_equality.rb 2022-09-01 09:58:49.000000000 +0200 @@ -7,6 +7,9 @@ # # If `AllowOnConstant` option is enabled, the cop will ignore violations when the receiver of # the case equality operator is a constant. + + # If `AllowOnSelfClass` option is enabled, the cop will ignore violations when the receiver of + # the case equality operator is `self.class`. Note intermediate variables are not accepted. # # @example # # bad @@ -26,6 +29,14 @@ # # good # Array === something # + # @example AllowOnSelfClass: false (default) + # # bad + # self.class === something + # + # @example AllowOnSelfClass: true + # # good + # self.class === something + # class CaseEquality < Base extend AutoCorrector @@ -33,7 +44,10 @@ RESTRICT_ON_SEND = %i[===].freeze # @!method case_equality?(node) - def_node_matcher :case_equality?, '(send $#const? :=== $_)' + def_node_matcher :case_equality?, '(send $#offending_receiver? :=== $_)' + + # @!method self_class?(node) + def_node_matcher :self_class?, '(send (self) :class)' def on_send(node) case_equality?(node) do |lhs, rhs| @@ -48,12 +62,11 @@ private - def const?(node) - if cop_config.fetch('AllowOnConstant', false) - !node&.const_type? - else - true - end + def offending_receiver?(node) + return false if node&.const_type? && cop_config.fetch('AllowOnConstant', false) + return false if self_class?(node) && cop_config.fetch('AllowOnSelfClass', false) + + true end def replacement(lhs, rhs) @@ -66,12 +79,29 @@ # # So here is noop. when :begin - child = lhs.children.first - "#{lhs.source}.include?(#{rhs.source})" if child&.range_type? + begin_replacement(lhs, rhs) when :const - "#{rhs.source}.is_a?(#{lhs.source})" + const_replacement(lhs, rhs) + when :send + send_replacement(lhs, rhs) end end + + def begin_replacement(lhs, rhs) + return unless lhs.children.first&.range_type? + + "#{lhs.source}.include?(#{rhs.source})" + end + + def const_replacement(lhs, rhs) + "#{rhs.source}.is_a?(#{lhs.source})" + end + + def send_replacement(lhs, rhs) + return unless self_class?(lhs) + + "#{rhs.source}.is_a?(#{lhs.source})" + end end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rubocop/cop/style/each_for_simple_loop.rb new/lib/rubocop/cop/style/each_for_simple_loop.rb --- old/lib/rubocop/cop/style/each_for_simple_loop.rb 2022-08-22 07:47:33.000000000 +0200 +++ new/lib/rubocop/cop/style/each_for_simple_loop.rb 2022-09-01 09:58:49.000000000 +0200 @@ -28,14 +28,14 @@ MSG = 'Use `Integer#times` for a simple loop which iterates a fixed number of times.' def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler - return unless offending_each_range(node) + return unless offending?(node) send_node = node.send_node range = send_node.receiver.source_range.join(send_node.loc.selector) add_offense(range) do |corrector| - range_type, min, max = offending_each_range(node) + range_type, min, max = each_range(node) max += 1 if range_type == :irange @@ -45,9 +45,44 @@ private - # @!method offending_each_range(node) - def_node_matcher :offending_each_range, <<~PATTERN - (block (send (begin (${irange erange} (int $_) (int $_))) :each) (args) ...) + def offending?(node) + each_range_with_zero_origin?(node) || each_range_without_block_argument?(node) + end + + # @!method each_range(node) + def_node_matcher :each_range, <<~PATTERN + (block + (send + (begin + (${irange erange} + (int $_) (int $_))) + :each) + (args ...) + ...) + PATTERN + + # @!method each_range_with_zero_origin?(node) + def_node_matcher :each_range_with_zero_origin?, <<~PATTERN + (block + (send + (begin + ({irange erange} + (int 0) (int _))) + :each) + (args ...) + ...) + PATTERN + + # @!method each_range_without_block_argument?(node) + def_node_matcher :each_range_without_block_argument?, <<~PATTERN + (block + (send + (begin + ({irange erange} + (int _) (int _))) + :each) + (args) + ...) PATTERN end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rubocop/cop/style/perl_backrefs.rb new/lib/rubocop/cop/style/perl_backrefs.rb --- old/lib/rubocop/cop/style/perl_backrefs.rb 2022-08-22 07:47:33.000000000 +0200 +++ new/lib/rubocop/cop/style/perl_backrefs.rb 2022-09-01 09:58:49.000000000 +0200 @@ -85,8 +85,29 @@ # @private # @param [RuboCop::AST::Node] node + # @return [String, nil] + def preferred_expression_to_node_with_constant_prefix(node) + expression = preferred_expression_to(node) + return unless expression + + "#{constant_prefix(node)}#{expression}" + end + + # @private + # @param [RuboCop::AST::Node] node + # @return [String] + def constant_prefix(node) + if node.each_ancestor(:class, :module).any? + '::' + else + '' + end + end + + # @private + # @param [RuboCop::AST::Node] node def on_back_ref_or_gvar_or_nth_ref(node) - preferred_expression = preferred_expression_to(node) + preferred_expression = preferred_expression_to_node_with_constant_prefix(node) return unless preferred_expression add_offense( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rubocop/cop/style/redundant_parentheses.rb new/lib/rubocop/cop/style/redundant_parentheses.rb --- old/lib/rubocop/cop/style/redundant_parentheses.rb 2022-08-22 07:47:33.000000000 +0200 +++ new/lib/rubocop/cop/style/redundant_parentheses.rb 2022-09-01 09:58:49.000000000 +0200 @@ -29,6 +29,9 @@ # @!method rescue?(node) def_node_matcher :rescue?, '{^resbody ^^resbody}' + # @!method allowed_pin_operator?(node) + def_node_matcher :allowed_pin_operator?, '^(pin (begin !{lvar ivar cvar gvar}))' + # @!method arg_in_call_with_block?(node) def_node_matcher :arg_in_call_with_block?, '^^(block (send _ _ equal?(%0) ...) ...)' @@ -44,6 +47,7 @@ empty_parentheses?(node) || first_arg_begins_with_hash_literal?(node) || rescue?(node) || + allowed_pin_operator?(node) || allowed_expression?(node) end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rubocop/cop/style/symbol_proc.rb new/lib/rubocop/cop/style/symbol_proc.rb --- old/lib/rubocop/cop/style/symbol_proc.rb 2022-08-22 07:47:33.000000000 +0200 +++ new/lib/rubocop/cop/style/symbol_proc.rb 2022-09-01 09:58:49.000000000 +0200 @@ -11,10 +11,11 @@ # These are customizable with `AllowedMethods` option. # # @safety - # This cop is unsafe because `proc`s and blocks work differently - # when additional arguments are passed in. A block will silently - # allow additional arguments, but a `proc` will raise - # an `ArgumentError`. + # This cop is unsafe because there is a difference that a `Proc` + # generated from `Symbol#to_proc` behaves as a lambda, while + # a `Proc` generated from a block does not. + # For example, a lambda will raise an `ArgumentError` if the + # number of arguments is wrong, but a non-lambda `Proc` will not. # # For example: # diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rubocop/runner.rb new/lib/rubocop/runner.rb --- old/lib/rubocop/runner.rb 2022-08-22 07:47:33.000000000 +0200 +++ new/lib/rubocop/runner.rb 2022-09-01 09:58:49.000000000 +0200 @@ -64,6 +64,10 @@ # instances that each inspects its allotted group of files. def warm_cache(target_files) saved_options = @options.dup + if target_files.length <= 1 + puts 'Skipping parallel inspection: only a single file needs inspection' if @options[:debug] + return + end puts 'Running parallel inspection' if @options[:debug] %i[autocorrect safe_autocorrect].each { |opt| @options[opt] = false } Parallel.each(target_files) { |target_file| file_offenses(target_file) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rubocop/version.rb new/lib/rubocop/version.rb --- old/lib/rubocop/version.rb 2022-08-22 07:47:33.000000000 +0200 +++ new/lib/rubocop/version.rb 2022-09-01 09:58:49.000000000 +0200 @@ -3,11 +3,11 @@ module RuboCop # This module holds the RuboCop version information. module Version - STRING = '1.35.1' + STRING = '1.36.0' MSG = '%<version>s (using Parser %<parser_version>s, ' \ 'rubocop-ast %<rubocop_ast_version>s, ' \ - 'running on %<ruby_engine>s %<ruby_version>s %<ruby_platform>s)' + 'running on %<ruby_engine>s %<ruby_version>s)%<server>s [%<ruby_platform>s]' CANONICAL_FEATURE_NAMES = { 'Rspec' => 'RSpec', 'Graphql' => 'GraphQL', 'Md' => 'Markdown', 'Thread_safety' => 'ThreadSafety' }.freeze @@ -19,6 +19,7 @@ verbose_version = format(MSG, version: STRING, parser_version: Parser::VERSION, rubocop_ast_version: RuboCop::AST::Version::STRING, ruby_engine: RUBY_ENGINE, ruby_version: RUBY_VERSION, + server: Server.running? ? ' +server' : '', ruby_platform: RUBY_PLATFORM) return verbose_version unless env diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/metadata new/metadata --- old/metadata 2022-08-22 07:47:33.000000000 +0200 +++ new/metadata 2022-09-01 09:58:49.000000000 +0200 @@ -1,7 +1,7 @@ --- !ruby/object:Gem::Specification name: rubocop version: !ruby/object:Gem::Version - version: 1.35.1 + version: 1.36.0 platform: ruby authors: - Bozhidar Batsov @@ -10,7 +10,7 @@ autorequire: bindir: exe cert_chain: [] -date: 2022-08-22 00:00:00.000000000 Z +date: 2022-09-01 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: json @@ -977,7 +977,7 @@ homepage_uri: https://rubocop.org/ changelog_uri: https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md source_code_uri: https://github.com/rubocop/rubocop/ - documentation_uri: https://docs.rubocop.org/rubocop/1.35/ + documentation_uri: https://docs.rubocop.org/rubocop/1.36/ bug_tracker_uri: https://github.com/rubocop/rubocop/issues rubygems_mfa_required: 'true' post_install_message: