lib/steep/subtyping/relation.rb
module Steep module Subtyping class Relation attr_reader :sub_type attr_reader :super_type def initialize(sub_type:, super_type:) @sub_type = sub_type @super_type = super_type end def hash self.class.hash ^ sub_type.hash ^ super_type.hash end def ==(other) other.is_a?(self.class) && other.sub_type == sub_type && other.super_type == super_type end alias eql? == def to_s "#{sub_type} <: #{super_type}" end def to_ary [sub_type, super_type] end def type? !interface? && !method? && !function? && !params? && !block? end def interface? sub_type.is_a?(Interface::Interface) && super_type.is_a?(Interface::Interface) end def method? (sub_type.is_a?(Interface::Interface::Entry) || sub_type.is_a?(Interface::MethodType)) && (super_type.is_a?(Interface::Interface::Entry) || super_type.is_a?(Interface::MethodType)) end def function? sub_type.is_a?(Interface::Function) && super_type.is_a?(Interface::Function) end def params? sub_type.is_a?(Interface::Function::Params) && super_type.is_a?(Interface::Function::Params) end def block? (sub_type.is_a?(Interface::Block) || !sub_type) && (!super_type || super_type.is_a?(Interface::Block)) end def assert_type(type) unless __send__(:"#{type}?") raise "#{type}? is expected but: sub_type=#{sub_type.class}, super_type=#{super_type.class}" end end def type! assert_type(:type) end def interface! assert_type(:interface) end def method! assert_type(:method) end def function! assert_type(:function) end def params! assert_type(:params) end def block! assert_type(:block) end def map self.class.new( sub_type: yield(sub_type), super_type: yield(super_type) ) end def flip self.class.new( sub_type: super_type, super_type: sub_type ) end end end end