class T::Props::Decorator

def model_inherited(child)

def model_inherited(child)
  child.extend(T::Props::ClassMethods)
  child = T.cast(child, T.all(Module, T::Props::ClassMethods))
  child.plugins.concat(decorated_class.plugins)
  decorated_class.plugins.each do |mod|
    # NB: apply_class_methods must not be an instance method on the decorator itself,
    # otherwise we'd have to call child.decorator here, which would create the decorator
    # before any `decorator_class` override has a chance to take effect (see the comment below).
    T::Props::Plugin::Private.apply_class_methods(mod, child)
  end
  props.each do |name, rules|
    copied_rules = rules.dup
    # NB: Calling `child.decorator` here is a timb bomb that's going to give someone a really bad
    # time. Any class that defines props and also overrides the `decorator_class` method is going
    # to reach this line before its override take effect, turning it into a no-op.
    child.decorator.add_prop_definition(name, copied_rules)
    # It's a bit tricky to support `prop_get` hooks added by plugins without
    # sacrificing the `attr_reader` fast path or clobbering customized getters
    # defined manually on a child.
    #
    # To make this work, we _do_ clobber getters defined on the child, but only if:
    # (a) it's needed in order to support a `prop_get` hook, and
    # (b) it's safe because the getter was defined by this file.
    #
    unless rules[:without_accessors]
      if child.decorator.method(:prop_get).owner != method(:prop_get).owner &&
          child.instance_method(name).source_location&.first == __FILE__
        child.send(:define_method, name) do
          T.unsafe(self.class).decorator.prop_get(self, name, rules)
        end
      end
      unless rules[:immutable]
        if child.decorator.method(:prop_set).owner != method(:prop_set).owner &&
            child.instance_method("#{name}=").source_location&.first == __FILE__
          child.send(:define_method, "#{name}=") do |val|
            T.unsafe(self.class).decorator.prop_set(self, name, val, rules)
          end
        end
      end
    end
  end
end