module ActiveSupport::DescendantsTracker

def clear(classes) # :nodoc:

:nodoc:
def clear(classes) # :nodoc:
  raise "DescendantsTracker.clear was disabled because config.enable_reloading is false" if @clear_disabled
  classes.each do |klass|
    @excluded_descendants << klass
    klass.descendants.each do |descendant|
      @excluded_descendants << descendant
    end
  end
end

def descendants(klass)

def descendants(klass)
  klass.descendants
end

def descendants

def descendants
  subclasses = DescendantsTracker.reject!(self.subclasses)
  subclasses.concat(subclasses.flat_map(&:descendants))
end

def descendants(klass)

def descendants(klass)
  subclasses = self.subclasses(klass)
  subclasses.concat(subclasses.flat_map { |k| descendants(k) })
end

def descendants

def descendants
  DescendantsTracker.descendants(self)
end

def disable_clear! # :nodoc:

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

def inherited(base) # :nodoc:

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

def reject!(classes) # :nodoc:

:nodoc:
def reject!(classes) # :nodoc:
  if @excluded_descendants
    classes.reject! { |d| @excluded_descendants.include?(d) }
  end
  classes
end

def store_inherited(klass, descendant) # :nodoc:

:nodoc:
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) # :nodoc:
  (@direct_descendants[klass] ||= DescendantsArray.new) << descendant
end

def subclasses(klass)

def subclasses(klass)
  klass.subclasses
end

def subclasses(klass)

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

def subclasses

def subclasses
  DescendantsTracker.subclasses(self)
end