class RBS::AST::TypeParam
def self.rename(params, new_names:)
def self.rename(params, new_names:) raise unless params.size == new_names.size subst = Substitution.build(new_names, Types::Variable.build(new_names)) params.map.with_index do |param, index| new_name = new_names[index] TypeParam.new( name: new_name, variance: param.variance, upper_bound: param.upper_bound&.map_type {|type| type.sub(subst) }, location: param.location ).unchecked!(param.unchecked?) end end
def self.resolve_variables(params)
def self.resolve_variables(params) return if params.empty? vars = Set.new(params.map(&:name)) params.map! do |param| param.map_type {|bound| _ = subst_var(vars, bound) } end end
def self.subst_var(vars, type)
def self.subst_var(vars, type) case type when Types::ClassInstance namespace = type.name.namespace if namespace.relative? && namespace.empty? && vars.member?(type.name.name) return Types::Variable.new(name: type.name.name, location: type.location) end end type.map_type {|t| subst_var(vars, t) } end
def ==(other)
def ==(other) other.is_a?(TypeParam) && other.name == name && other.variance == variance && other.upper_bound == upper_bound && other.unchecked? == unchecked? end
def hash
def hash self.class.hash ^ name.hash ^ variance.hash ^ upper_bound.hash ^ unchecked?.hash end
def initialize(name:, variance:, upper_bound:, location:)
def initialize(name:, variance:, upper_bound:, location:) @name = name @variance = variance @upper_bound = upper_bound @location = location @unchecked = false end
def map_type(&block)
def map_type(&block) if b = upper_bound _upper_bound = yield(b) end TypeParam.new( name: name, variance: variance, upper_bound: _upper_bound, location: location ).unchecked!(unchecked?) end
def rename(name)
def rename(name) TypeParam.new( name: name, variance: variance, upper_bound: upper_bound, location: location ).unchecked!(unchecked?) end
def to_json(state = JSON::State.new)
def to_json(state = JSON::State.new) { name: name, variance: variance, unchecked: unchecked?, location: location, upper_bound: upper_bound }.to_json(state) end
def to_s
def to_s s = "" if unchecked? s << "unchecked " end case variance when :invariant # nop when :covariant s << "out " when :contravariant s << "in " end s << name.to_s if type = upper_bound s << " < #{type}" end s end
def unchecked!(value = true)
def unchecked!(value = true) @unchecked = value ? true : false self end
def unchecked?
def unchecked? @unchecked end