class RBS::VarianceCalculator - rbs: Ruby Standard Library Documentation

# class RBS::VarianceCalculator

### Attributes

builder[R]

### Public Class Methods

new(builder:) click to toggle source

    # File rbs-3.8.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.8.0/lib/rbs/variance_calculator.rb, line 82
    def env
      builder.env
    end

function(type, result:, context:) click to toggle source

    # File rbs-3.8.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.8.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.8.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.8.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.8.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.8.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