class RBS::VarianceCalculator

Attributes

builder[R]

Public Class Methods

new(builder:) click to toggle source
# File rbs-3.7.0/lib/rbs/variance_calculator.rb, line 78
def initialize(builder:)
  @builder = builder
end

Public Instance Methods

env() click to toggle source
# File rbs-3.7.0/lib/rbs/variance_calculator.rb, line 82
def env
  builder.env
end
function(type, result:, context:) click to toggle source
# File rbs-3.7.0/lib/rbs/variance_calculator.rb, line 169
def function(type, result:, context:)
  type.each_param do |param|
    type(param.type, result: result, context: negate(context))
  end
  type(type.return_type, result: result, context: context)
end
in_inherit(name:, args:, variables:) click to toggle source
# File rbs-3.7.0/lib/rbs/variance_calculator.rb, line 98
def in_inherit(name:, args:, variables:)
  type = if name.class?
           Types::ClassInstance.new(name: name, args: args, location: nil)
         else
           Types::Interface.new(name: name, args: args, location: nil)
         end

  Result.new(variables: variables).tap do |result|
    type(type, result: result, context: :covariant)
  end
end
in_method_type(method_type:, variables:) click to toggle source
# File rbs-3.7.0/lib/rbs/variance_calculator.rb, line 86
def in_method_type(method_type:, variables:)
  result = Result.new(variables: variables)

  function(method_type.type, result: result, context: :covariant)

  if block = method_type.block
    function(block.type, result: result, context: :contravariant)
  end

  result
end
in_type_alias(name:) click to toggle source
# File rbs-3.7.0/lib/rbs/variance_calculator.rb, line 110
def in_type_alias(name:)
  env.normalized_type_name!(name)

  decl = env.type_alias_decls[name].decl or raise
  variables = decl.type_params.each.map(&:name)

  Result.new(variables: variables).tap do |result|
    type(decl.type, result: result, context: :covariant)
  end
end
negate(variance) click to toggle source
# File rbs-3.7.0/lib/rbs/variance_calculator.rb, line 176
def negate(variance)
  case variance
  when :invariant
    :invariant
  when :covariant
    :contravariant
  when :contravariant
    :covariant
  else
    raise
  end
end
type(type, result:, context:) click to toggle source
# File rbs-3.7.0/lib/rbs/variance_calculator.rb, line 121
def type(type, result:, context:)
  case type
  when Types::Variable
    if result.include?(type.name)
      case context
      when :covariant
        result.covariant(type.name)
      when :contravariant
        result.contravariant(type.name)
      when :invariant
        result.invariant(type.name)
      end
    end
  when Types::ClassInstance, Types::Interface, Types::Alias
    if type_name = env.normalize_type_name?(type.name)
      type_params = case type
                    when Types::ClassInstance
                      env.class_decls[type_name].type_params
                    when Types::Interface
                      env.interface_decls[type_name].decl.type_params
                    when Types::Alias
                      env.type_alias_decls[type_name].decl.type_params
                    end

      type.args.each.with_index do |ty, i|
        if var = type_params[i]
          case var.variance
          when :invariant
            type(ty, result: result, context: :invariant)
          when :covariant
            type(ty, result: result, context: context)
          when :contravariant
            type(ty, result: result, context: negate(context))
          end
        end
      end
    else
      raise NoTypeFoundError.new(type_name: type.name, location: type.location)
    end
  when Types::Proc
    function(type.type, result: result, context: context)
  else
    type.each_type do |ty|
      type(ty, result: result, context: context)
    end
  end
end