lib/rubocop/cop/layout/class_structure.rb in rubocop-1.41.1 vs lib/rubocop/cop/layout/class_structure.rb in rubocop-1.42.0

- old
+ new

@@ -136,22 +136,17 @@ include VisibilityHelp extend AutoCorrector HUMANIZED_NODE_TYPE = { casgn: :constants, - defs: :class_methods, + defs: :public_class_methods, def: :public_methods, sclass: :class_singleton }.freeze MSG = '`%<category>s` is supposed to appear before `%<previous>s`.' - # @!method dynamic_constant?(node) - def_node_matcher :dynamic_constant?, <<~PATTERN - (casgn nil? _ (send ...)) - PATTERN - # Validates code style on class declaration. # Add offense when find a node out of expected order. def on_class(class_node) previous = -1 walk_over_nested_class_definition(class_node) do |node, category| @@ -219,11 +214,11 @@ end def walk_over_nested_class_definition(class_node) class_elements(class_node).each do |node| classification = classify(node) - next if ignore?(classification) + next if ignore?(node, classification) yield node, classification end end @@ -237,29 +232,56 @@ else class_def.children.compact end end - def ignore?(classification) + def ignore?(node, classification) classification.nil? || classification.to_s.end_with?('=') || - expected_order.index(classification).nil? + expected_order.index(classification).nil? || + private_constant?(node) end def ignore_for_autocorrect?(node, sibling) classification = classify(node) sibling_class = classify(sibling) - ignore?(sibling_class) || classification == sibling_class || dynamic_constant?(node) + ignore?(sibling, sibling_class) || + classification == sibling_class || + dynamic_constant?(node) end def humanize_node(node) if node.def_type? return :initializer if node.method?(:initialize) return "#{node_visibility(node)}_methods" end HUMANIZED_NODE_TYPE[node.type] || node.type + end + + def dynamic_constant?(node) + return false unless node.casgn_type? && node.namespace.nil? + + expression = node.expression + expression.send_type? && + !(expression.method?(:freeze) && expression.receiver&.recursive_basic_literal?) + end + + def private_constant?(node) + return false unless node.casgn_type? && node.namespace.nil? + return false unless (parent = node.parent) + + parent.each_child_node(:send) do |child_node| + return true if marked_as_private_constant?(child_node, node.name) + end + false + end + + def marked_as_private_constant?(node, name) + return false unless node.method?(:private_constant) + + node.arguments.any? { |arg| (arg.sym_type? || arg.str_type?) && arg.value == name } end def source_range_with_comment(node) begin_pos, end_pos = if (node.def_type? && !node.method?(:initialize)) ||