module ActiveSupport::DescendantsTracker

def accumulate_descendants(klass, acc)

def accumulate_descendants(klass, acc)
  if direct_descendants = @@direct_descendants[klass]
    direct_descendants.each do |direct_descendant|
      acc << direct_descendant
      accumulate_descendants(direct_descendant, acc)
    end
  end
end

def clear(classes) # :nodoc:

:nodoc:
def clear(classes) # :nodoc:
  raise "DescendantsTracker.clear was disabled because config.cache_classes = true" if @clear_disabled
  classes.each do |klass|
    @@excluded_descendants[klass] = true
    klass.descendants.each do |descendant|
      @@excluded_descendants[descendant] = true
    end
  end
end

def clear(classes) # :nodoc:

:nodoc:
def clear(classes) # :nodoc:
  raise "DescendantsTracker.clear was disabled because config.cache_classes = true" if @clear_disabled
  @@direct_descendants.each do |klass, direct_descendants_of_klass|
    if classes.member?(klass)
      @@direct_descendants.delete(klass)
    else
      direct_descendants_of_klass.reject! do |direct_descendant_of_class|
        classes.member?(direct_descendant_of_class)
      end
    end
  end
end

def descendants(klass)

def descendants(klass)
  klass.descendants
end

def descendants

def descendants
  subclasses.concat(subclasses.flat_map(&:descendants))
end

def descendants(klass)

def descendants(klass)
  arr = []
  accumulate_descendants(klass, arr)
  arr
end

def descendants

def descendants
  DescendantsTracker.descendants(self)
end

def direct_descendants(klass)

def direct_descendants(klass)
  ActiveSupport::Deprecation.warn(<<~MSG)
    ActiveSupport::DescendantsTracker.direct_descendants is deprecated and will be removed in Rails 7.1.
    Use ActiveSupport::DescendantsTracker.subclasses instead.
  MSG
  subclasses(klass)
end

def direct_descendants

def direct_descendants
  ActiveSupport::Deprecation.warn(<<~MSG)
    ActiveSupport::DescendantsTracker#direct_descendants is deprecated and will be removed in Rails 7.1.
    Use #subclasses instead.
  MSG
  subclasses
end

def direct_descendants

def direct_descendants
  ActiveSupport::Deprecation.warn(<<~MSG)
    ActiveSupport::DescendantsTracker#direct_descendants is deprecated and will be removed in Rails 7.1.
    Use #subclasses instead.
  MSG
  DescendantsTracker.subclasses(self)
end

def disable_clear! # :nodoc:

:nodoc:
def disable_clear! # :nodoc:
  unless @clear_disabled
    @clear_disabled = true
    remove_method(:subclasses)
    @@excluded_descendants = nil
  end
end

def disable_clear! # :nodoc:

:nodoc:
def disable_clear! # :nodoc:
  @clear_disabled = true
end

def inherited(base)

def inherited(base)
  DescendantsTracker.store_inherited(self, base)
  super
end

def native? # :nodoc:

:nodoc:
def native? # :nodoc:
  true
end

def native? # :nodoc:

:nodoc:
def native? # :nodoc:
  false
end

def store_inherited(klass, descendant)

during the eager loading phase.
This is the only method that is not thread safe, but is only ever called
def store_inherited(klass, descendant)
  (@@direct_descendants[klass] ||= DescendantsArray.new) << descendant
end

def subclasses(klass)

def subclasses(klass)
  klass.subclasses
end

def subclasses

def subclasses
  subclasses = super
  subclasses.reject! { |d| @@excluded_descendants[d] }
  subclasses
end

def subclasses(klass)

def subclasses(klass)
  descendants = @@direct_descendants[klass]
  descendants ? descendants.to_a : []
end

def subclasses

def subclasses
  DescendantsTracker.subclasses(self)
end