From 792b29d84be67a0ac162e5859676c28f3426a476 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Tue, 25 May 2021 00:01:59 +0900 Subject: [PATCH] [Fix #9819] Fix a false negative for `Style/TopLevelMethodDefinition` Fixes #9819. This PR fixes a false negative for `Style/TopLevelMethodDefinition` when defining a top-level method after a class definition. --- ...negative_for_style_top_level_method_definition.md | 1 + lib/rubocop/cop/style/top_level_method_definition.rb | 12 ++++++++++-- .../cop/style/top_level_method_definition_spec.rb | 10 ++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 changelog/fix_false_negative_for_style_top_level_method_definition.md diff --git a/changelog/fix_false_negative_for_style_top_level_method_definition.md b/changelog/fix_false_negative_for_style_top_level_method_definition.md new file mode 100644 index 00000000000..b064e29b540 --- /dev/null +++ b/changelog/fix_false_negative_for_style_top_level_method_definition.md @@ -0,0 +1 @@ +* [#9819](https://github.com/rubocop/rubocop/issues/9819): Fix a false negative for `Style/TopLevelMethodDefinition` when defining a top-level method after a class definition. ([@koic][]) diff --git a/lib/rubocop/cop/style/top_level_method_definition.rb b/lib/rubocop/cop/style/top_level_method_definition.rb index d868dbf2780..4b94428b2ae 100644 --- a/lib/rubocop/cop/style/top_level_method_definition.rb +++ b/lib/rubocop/cop/style/top_level_method_definition.rb @@ -50,7 +50,7 @@ class TopLevelMethodDefinition < Base RESTRICT_ON_SEND = %i[define_method].freeze def on_def(node) - return unless node.root? + return unless top_level_method_definition?(node) add_offense(node) end @@ -58,13 +58,21 @@ def on_def(node) alias on_send on_def def on_block(node) - return unless define_method_block?(node) && node.root? + return unless define_method_block?(node) && top_level_method_definition?(node) add_offense(node) end private + def top_level_method_definition?(node) + if node.parent&.begin_type? + node.parent.root? + else + node.root? + end + end + # @!method define_method_block?(node) def_node_matcher :define_method_block?, <<~PATTERN (block (send _ {:define_method} _) ...) diff --git a/spec/rubocop/cop/style/top_level_method_definition_spec.rb b/spec/rubocop/cop/style/top_level_method_definition_spec.rb index 3d08bb58596..e310f943964 100644 --- a/spec/rubocop/cop/style/top_level_method_definition_spec.rb +++ b/spec/rubocop/cop/style/top_level_method_definition_spec.rb @@ -40,6 +40,16 @@ def self.foo; end end end + it 'registers an offense when defining a top-level method after a class definition' do + expect_offense(<<~RUBY) + class Foo + end + + def foo; end + ^^^^^^^^^^^^ Do not define methods at the top-level. + RUBY + end + it 'does not register an offense when using module' do expect_no_offenses(<<~RUBY) module Foo