Sha256: 47512f26bf3e111422b4b2ed0141de58a2a9175c35642ed3f7c96ab72dd09efc

Contents?: true

Size: 1.99 KB

Versions: 4

Compression:

Stored size: 1.99 KB

Contents

# frozen_string_literal: true

module RaaP
  class TypeSubstitution
    def initialize(type_params, type_args)
      @type_params = type_params
      @type_args = type_args
    end

    def build
      bound_map = @type_params.zip(@type_args).to_h do |(bound, arg)|
        if arg
          [bound.name, arg]
        elsif bound.upper_bound
          [bound.name, bound.upper_bound]
        else
          [bound.name, ::RBS::Types::Variable.new(name: bound.name, location: nil)]
        end
      end
      ::RBS::Substitution.build(bound_map.keys, bound_map.values)
    end

    def method_type_sub(method_type, self_type: nil, instance_type: nil, class_type: nil)
      self_type = self_type.is_a?(::String) ? RBS.parse_type(self_type) : self_type
      instance_type = instance_type.is_a?(::String) ? RBS.parse_type(instance_type) : instance_type
      class_type = class_type.is_a?(::String) ? RBS.parse_type(class_type) : class_type
      sub = build
      if sub.empty? && self_type.nil? && instance_type.nil? && class_type.nil?
        return method_type
      end

      ::RBS::MethodType.new(
        type_params: [],
        type: method_type.type.sub(sub).then { |ty| sub(ty, self_type: self_type, instance_type: instance_type, class_type: class_type) },
        block: method_type.block&.sub(sub)&.then { |bl| sub(bl, self_type: self_type, instance_type: instance_type, class_type: class_type) },
        location: method_type.location
      )
    end

    private

    def sub(search, self_type:, instance_type:, class_type:)
      if self_type.nil? && instance_type.nil? && class_type.nil?
        return search
      end

      search.map_type do |ty|
        case ty
        when ::RBS::Types::Bases::Self
          self_type || ty
        when ::RBS::Types::Bases::Instance
          instance_type || ty
        when ::RBS::Types::Bases::Class
          class_type || ty
        else
          sub(ty, self_type: self_type, instance_type: instance_type, class_type: class_type)
        end
      end
    end
  end
end

Version data entries

4 entries across 4 versions & 1 rubygems

Version Path
raap-1.0.0 lib/raap/type_substitution.rb
raap-0.10.0 lib/raap/type_substitution.rb
raap-0.9.0 lib/raap/type_substitution.rb
raap-0.8.0 lib/raap/type_substitution.rb