class Steep::Interface::Instantiated

def ==(other)

def ==(other)
  other.is_a?(self.class) && other.type == type && other.params == params && other.methods == methods && other.ivars == ivars
end

def initialize(type:, methods:, ivar_chains:)

def initialize(type:, methods:, ivar_chains:)
  @type = type
  @methods = methods
  @ivar_chains = ivar_chains
end

def ivars

def ivars
  @ivars ||= ivar_chains.transform_values(&:type)
end

def select_method_type(&block)

def select_method_type(&block)
  self.class.new(
    type: type,
    methods: methods.each.with_object({}) do |(name, method), methods|
      methods[name] = Method.new(
        type_name: method.type_name,
        name: method.name,
        types: method.types.select(&block),
        super_method: method.super_method,
        attributes: method.attributes,
      )
    end.reject do |_, method|
      method.types.empty?
    end,
    ivar_chains: ivar_chains
  )
end

def validate(check)

def validate(check)
  methods.each do |_, method|
    validate_method(check, method)
  end
  ivar_chains.each do |name, chain|
    validate_chain(check, name, chain)
  end
end

def validate_chain(check, name, chain)

def validate_chain(check, name, chain)
  return unless chain.parent
  this_type = chain.type
  super_type = chain.parent.type
  case
  when this_type.is_a?(AST::Types::Any) && super_type.is_a?(AST::Types::Any)
    # ok
  else
    relation = Subtyping::Relation.new(sub_type: this_type, super_type: super_type)
    result1 = check.check(relation, constraints: Subtyping::Constraints.empty)
    result2 = check.check(relation.flip, constraints: Subtyping::Constraints.empty)
    if result1.failure? || result2.failure? || this_type.is_a?(AST::Types::Any) || super_type.is_a?(AST::Types::Any)
      raise InvalidIvarOverrideError.new(type: self.type, ivar_name: name, current_ivar_type: this_type, super_ivar_type: super_type)
    end
  end
  validate_chain(check, name, chain.parent)
end

def validate_method(check, method)

def validate_method(check, method)
  if method.super_method
    result = check.check_method(method.name,
                                method,
                                method.super_method,
                                assumption: Set.new,
                                trace: Subtyping::Trace.new,
                                constraints: Subtyping::Constraints.empty)
    if result.success?
      validate_method(check, method.super_method)
    else
      raise InvalidMethodOverrideError.new(type: type,
                                           current_method: method,
                                           super_method: method.super_method,
                                           result: result)
    end
  end
end