debian-mirror-gitlab/rubocop/cop/prefer_class_methods_over_module.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

78 lines
2 KiB
Ruby
Raw Normal View History

2018-11-20 20:47:30 +05:30
# frozen_string_literal: true
module RuboCop
module Cop
# Enforces the use of 'class_methods' instead of 'module ClassMethods' for activesupport concerns.
2019-12-04 20:38:33 +05:30
# For more information see: https://gitlab.com/gitlab-org/gitlab-foss/issues/50414
2018-11-20 20:47:30 +05:30
#
# @example
# # bad
# module Foo
# extend ActiveSupport::Concern
#
# module ClassMethods
# def a_class_method
# end
# end
# end
#
# # good
# module Foo
# extend ActiveSupport::Concern
#
# class_methods do
# def a_class_method
# end
# end
# end
#
2022-10-11 01:57:18 +05:30
class PreferClassMethodsOverModule < RuboCop::Cop::Base
extend RuboCop::Cop::AutoCorrector
2018-11-20 20:47:30 +05:30
include RangeHelp
MSG = 'Do not use module ClassMethods, use class_methods block instead.'
def_node_matcher :extend_activesupport_concern?, <<~PATTERN
(:send nil? :extend (:const (:const nil? :ActiveSupport) :Concern))
PATTERN
def on_module(node)
2022-10-11 01:57:18 +05:30
return unless class_methods_module_in_activesupport_concern?(node)
2018-11-20 20:47:30 +05:30
2022-10-11 01:57:18 +05:30
add_offense(node) do |corrector|
2018-11-20 20:47:30 +05:30
corrector.replace(module_range(node), 'class_methods do')
end
end
private
2022-10-11 01:57:18 +05:30
def class_methods_module_in_activesupport_concern?(node)
node.defined_module_name == 'ClassMethods' &&
module_extends_activesupport_concern?(node)
end
2018-11-20 20:47:30 +05:30
def module_extends_activesupport_concern?(node)
container_module = container_module_of(node)
return false unless container_module
container_module.descendants.any? do |descendant|
extend_activesupport_concern?(descendant)
end
end
def container_module_of(node)
while node = node.parent
break if node.type == :module
end
node
end
def module_range(node)
module_node, _ = *node
range_between(node.loc.keyword.begin_pos, module_node.source_range.end_pos)
end
end
end
end