diff --git a/changelog/fix_class_and_module_children_preserve_comment.md b/changelog/fix_class_and_module_children_preserve_comment.md new file mode 100644 index 00000000000..c9b001cf074 --- /dev/null +++ b/changelog/fix_class_and_module_children_preserve_comment.md @@ -0,0 +1 @@ +* [#9767](https://github.com/rubocop/rubocop/issues/9767): Fix `Style/ClassAndModuleChildren` cop to preserve comments. ([@tejasbubane][]) diff --git a/lib/rubocop/cop/style/class_and_module_children.rb b/lib/rubocop/cop/style/class_and_module_children.rb index 1a03cf43478..fa0039296f0 100644 --- a/lib/rubocop/cop/style/class_and_module_children.rb +++ b/lib/rubocop/cop/style/class_and_module_children.rb @@ -87,9 +87,18 @@ def compact_definition(corrector, node) end def compact_node(corrector, node) - replacement = "#{node.body.type} #{compact_identifier_name(node)}" range = range_between(node.loc.keyword.begin_pos, node.body.loc.name.end_pos) - corrector.replace(range, replacement) + corrector.replace(range, compact_replacement(node)) + end + + def compact_replacement(node) + replacement = "#{node.body.type} #{compact_identifier_name(node)}" + + body_comments = processed_source.ast_with_comments[node.body] + unless body_comments.empty? + replacement = body_comments.map(&:text).push(replacement).join("\n") + end + replacement end def compact_identifier_name(node) diff --git a/spec/rubocop/cop/style/class_and_module_children_spec.rb b/spec/rubocop/cop/style/class_and_module_children_spec.rb index f3b1312ad3a..ba4cc885424 100644 --- a/spec/rubocop/cop/style/class_and_module_children_spec.rb +++ b/spec/rubocop/cop/style/class_and_module_children_spec.rb @@ -129,6 +129,23 @@ module Baz RUBY end + it 'preserves comments' do + expect_offense(<<~RUBY) + # top comment + class Foo::Bar # describe Foo::Bar + ^^^^^^^^ Use nested module/class definitions instead of compact style. + end + RUBY + + expect_correction(<<~RUBY) + # top comment + module Foo + class Bar # describe Foo::Bar + end + end + RUBY + end + it 'accepts nested children' do expect_no_offenses(<<~RUBY) class FooClass @@ -251,6 +268,29 @@ module Foo::Bar::Baz RUBY end + it 'preserves comments between classes' do + expect_offense(<<~RUBY) + # describe Foo + # more Foo + class Foo + ^^^ Use compact module/class definition instead of nested style. + # describe Bar + # more Bar + class Bar + end + end + RUBY + + expect_correction(<<~RUBY) + # describe Foo + # more Foo + # describe Bar + # more Bar + class Foo::Bar + end + RUBY + end + it 'accepts compact style for classes/modules' do expect_no_offenses(<<~RUBY) class FooClass::BarClass