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:
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:
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:
def disable_clear! # :nodoc: unless @clear_disabled @clear_disabled = true remove_method(:subclasses) @@excluded_descendants = nil end end
def disable_clear! # :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:
def native? # :nodoc: true end
def native? # :nodoc:
def native? # :nodoc: false end
def store_inherited(klass, descendant)
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