diff --git a/CHANGELOG.md b/CHANGELOG.md index bb66c9fec52..7ea3c066b88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### Changes * [#8646](https://github.com/rubocop-hq/rubocop/issues/8646): Faster find of all files in `TargetFinder` class which improves rubocop initial startup speed. ([@tleish][]) +* [#8102](https://github.com/rubocop-hq/rubocop/issues/8102): Consider class-length instead of block-length for `Struct.new`. ([@tejasbubane][]) ## 0.92.0 (2020-09-25) diff --git a/docs/modules/ROOT/pages/cops_metrics.adoc b/docs/modules/ROOT/pages/cops_metrics.adoc index be15e9604e3..43e1cb2b351 100644 --- a/docs/modules/ROOT/pages/cops_metrics.adoc +++ b/docs/modules/ROOT/pages/cops_metrics.adoc @@ -57,6 +57,8 @@ You can set literals you want to fold with `CountAsOne`. Available are: 'array', 'hash', and 'heredoc'. Each literal will be counted as one line regardless of its actual size. +NOTE: This cop does not apply for `Struct` definitions. + === Examples ==== CountAsOne: ['array', 'heredoc'] @@ -165,6 +167,8 @@ You can set literals you want to fold with `CountAsOne`. Available are: 'array', 'hash', and 'heredoc'. Each literal will be counted as one line regardless of its actual size. +NOTE: This cop also applies for `Struct` definitions. + === Examples ==== CountAsOne: ['array', 'heredoc'] diff --git a/lib/rubocop/cop/metrics/block_length.rb b/lib/rubocop/cop/metrics/block_length.rb index a88a9963b4f..7340184cb77 100644 --- a/lib/rubocop/cop/metrics/block_length.rb +++ b/lib/rubocop/cop/metrics/block_length.rb @@ -29,6 +29,8 @@ module Metrics # content. # HEREDOC # end # 5 points + # + # NOTE: This cop does not apply for `Struct` definitions. class BlockLength < Base include CodeLength @@ -36,7 +38,7 @@ class BlockLength < Base def on_block(node) return if excluded_method?(node) - return if node.class_constructor? + return if node.class_constructor? || node.struct_constructor? check_code_length(node) end diff --git a/lib/rubocop/cop/metrics/class_length.rb b/lib/rubocop/cop/metrics/class_length.rb index 46c0df9a5ec..1f0f7d5d243 100644 --- a/lib/rubocop/cop/metrics/class_length.rb +++ b/lib/rubocop/cop/metrics/class_length.rb @@ -29,6 +29,8 @@ module Metrics # HEREDOC # end # 5 points # + # + # NOTE: This cop also applies for `Struct` definitions. class ClassLength < Base include CodeLength @@ -37,17 +39,12 @@ def on_class(node) end def on_casgn(node) - class_definition?(node) do - check_code_length(node) - end + _scope, _name, block_node = *node + check_code_length(node) if block_node.class_definition? end private - def_node_matcher :class_definition?, <<~PATTERN - (casgn nil? _ (block (send (const {nil? cbase} :Class) :new) ...)) - PATTERN - def message(length, max_length) format('Class has too many lines. [%d/%d]', length: length, diff --git a/lib/rubocop/cop/mixin/hash_transform_method.rb b/lib/rubocop/cop/mixin/hash_transform_method.rb index 9137a1f5d3c..0d320e95803 100644 --- a/lib/rubocop/cop/mixin/hash_transform_method.rb +++ b/lib/rubocop/cop/mixin/hash_transform_method.rb @@ -137,7 +137,7 @@ def transformation_uses_both_args? end # Internal helper class to hold autocorrect data - Autocorrection = Struct.new(:match, :block_node, :leading, :trailing) do # rubocop:disable Metrics/BlockLength + Autocorrection = Struct.new(:match, :block_node, :leading, :trailing) do def self.from_each_with_object(node, match) new(match, node, 0, 0) end diff --git a/lib/rubocop/cop/variable_force/branch.rb b/lib/rubocop/cop/variable_force/branch.rb index 9d23bb562ea..33271e04df4 100644 --- a/lib/rubocop/cop/variable_force/branch.rb +++ b/lib/rubocop/cop/variable_force/branch.rb @@ -20,8 +20,6 @@ def self.of(target_node, scope: nil) nil end - # rubocop:disable Metrics/BlockLength - # Abstract base class for branch classes. # A branch represents a conditional branch in a scope. # @@ -42,8 +40,6 @@ def self.of(target_node, scope: nil) # do_something # no branch # end Base = Struct.new(:child_node, :scope) do - # rubocop:enable Metrics/BlockLength - def self.classes @classes ||= [] end diff --git a/spec/rubocop/cop/metrics/block_length_spec.rb b/spec/rubocop/cop/metrics/block_length_spec.rb index daa3a321324..3556cb7e556 100644 --- a/spec/rubocop/cop/metrics/block_length_spec.rb +++ b/spec/rubocop/cop/metrics/block_length_spec.rb @@ -159,6 +159,27 @@ end end + context 'when defining a Struct' do + it 'does not register an offense' do + expect_no_offenses(<<~'RUBY') + Person = Struct.new(:first_name, :last_name) do + def full_name + "#{first_name} #{last_name}" + end + + def foo + a = 1 + a = 2 + a = 3 + a = 4 + a = 5 + a = 6 + end + end + RUBY + end + end + context 'when CountComments is enabled' do before { cop_config['CountComments'] = true } diff --git a/spec/rubocop/cop/metrics/class_length_spec.rb b/spec/rubocop/cop/metrics/class_length_spec.rb index 65c9e590f87..85f1a741bb5 100644 --- a/spec/rubocop/cop/metrics/class_length_spec.rb +++ b/spec/rubocop/cop/metrics/class_length_spec.rb @@ -201,4 +201,20 @@ class Test RUBY end end + + context 'when inspecting a class defined with Struct.new' do + it 'registers an offense' do + expect_offense(<<~RUBY) + Foo = Struct.new(:foo, :bar) do + ^^^ Class has too many lines. [6/5] + a = 1 + a = 2 + a = 3 + a = 4 + a = 5 + a = 6 + end + RUBY + end + end end