class RBS::VarianceCalculator

Attributes

builder[R]

Public Class Methods

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

Public Instance Methods

env() click to toggle source
# File rbs-1.4.0/lib/rbs/variance_calculator.rb, line 65
def env
  builder.env
end
in_inherit(name:, args:, variables:) click to toggle source
# File rbs-1.4.0/lib/rbs/variance_calculator.rb, line 88
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-1.4.0/lib/rbs/variance_calculator.rb, line 69
def in_method_type(method_type:, variables:)
  result = Result.new(variables: variables)

  method_type.type.each_param do |param|
    type(param.type, result: result, context: :contravariant)
  end

  if block = method_type.block
    block.type.each_param do |param|
      type(param.type, result: result, context: :covariant)
    end
    type(block.type.return_type, result: result, context: :contravariant)
  end

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

  result
end
type(type, result:, context:) click to toggle source
# File rbs-1.4.0/lib/rbs/variance_calculator.rb, line 100
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
    NoTypeFoundError.check!(type.name,
                            env: env,
                            location: type.location)

    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
                  end

    type.args.each.with_index do |ty, i|
      var = type_params.params[i]
      case var&.variance
      when :invariant
        type(ty, result: result, context: :invariant)
      when :covariant
        type(ty, result: result, context: context)
      when :contravariant
        # @type var con: variance
        con = case context
              when :invariant
                :invariant
              when :covariant
                :contravariant
              when :contravariant
                :covariant
              else
                raise
              end
        type(ty, result: result, context: con)
      end
    end
  when Types::Tuple, Types::Record, Types::Union, Types::Intersection
    # Covariant types
    type.each_type do |ty|
      type(ty, result: result, context: context)
    end
  end
end