brew vendor-gems: commit updates.
This commit is contained in:
		
							parent
							
								
									bacacfcb2b
								
							
						
					
					
						commit
						b6c4f59757
					
				@ -181,6 +181,8 @@ GEM
 | 
			
		||||
    zeitwerk (2.6.12)
 | 
			
		||||
 | 
			
		||||
PLATFORMS
 | 
			
		||||
  aarch64-linux
 | 
			
		||||
  arm-linux
 | 
			
		||||
  arm64-darwin
 | 
			
		||||
  x86_64-darwin
 | 
			
		||||
  x86_64-linux
 | 
			
		||||
 | 
			
		||||
@ -71,7 +71,7 @@ $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version
 | 
			
		||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/racc-1.7.3/lib")
 | 
			
		||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/parser-3.3.0.4/lib")
 | 
			
		||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rainbow-3.1.1/lib")
 | 
			
		||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/sorbet-runtime-0.5.11155/lib")
 | 
			
		||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/sorbet-runtime-0.5.11212/lib")
 | 
			
		||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/parlour-8.1.0/lib")
 | 
			
		||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/patchelf-1.4.0/lib")
 | 
			
		||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/plist-3.7.1/lib")
 | 
			
		||||
@ -112,9 +112,9 @@ $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version
 | 
			
		||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/simplecov_json_formatter-0.1.4/lib")
 | 
			
		||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/simplecov-0.22.0/lib")
 | 
			
		||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/simplecov-cobertura-2.1.0/lib")
 | 
			
		||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/sorbet-static-0.5.11155-universal-darwin/lib")
 | 
			
		||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/sorbet-0.5.11155/lib")
 | 
			
		||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/sorbet-static-and-runtime-0.5.11155/lib")
 | 
			
		||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/sorbet-static-0.5.11212-universal-darwin/lib")
 | 
			
		||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/sorbet-0.5.11212/lib")
 | 
			
		||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/sorbet-static-and-runtime-0.5.11212/lib")
 | 
			
		||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/syntax_tree-6.2.0/lib")
 | 
			
		||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/thor-1.3.0/lib")
 | 
			
		||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/spoom-1.2.4/lib")
 | 
			
		||||
 | 
			
		||||
@ -1,162 +0,0 @@
 | 
			
		||||
# frozen_string_literal: true
 | 
			
		||||
# typed: false
 | 
			
		||||
 | 
			
		||||
# Wraps an object, exposing only the methods defined on a given class/module. The idea is that, in
 | 
			
		||||
# the absence of a static type checker that would prevent you from calling non-Bar methods on a
 | 
			
		||||
# variable of type Bar, we can use these wrappers as a way of enforcing it at runtime.
 | 
			
		||||
#
 | 
			
		||||
# Once we ship static type checking, we should get rid of this entirely.
 | 
			
		||||
class T::InterfaceWrapper
 | 
			
		||||
  extend T::Sig
 | 
			
		||||
 | 
			
		||||
  module Helpers
 | 
			
		||||
    def wrap_instance(obj)
 | 
			
		||||
      T::InterfaceWrapper.wrap_instance(obj, self)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def wrap_instances(arr)
 | 
			
		||||
      T::InterfaceWrapper.wrap_instances(arr, self)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  private_class_method :new # use `wrap_instance`
 | 
			
		||||
 | 
			
		||||
  def self.wrap_instance(obj, interface_mod)
 | 
			
		||||
    wrapper = wrapped_dynamic_cast(obj, interface_mod)
 | 
			
		||||
    if wrapper.nil?
 | 
			
		||||
      raise "#{obj.class} cannot be cast to #{interface_mod}"
 | 
			
		||||
    end
 | 
			
		||||
    wrapper
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  sig do
 | 
			
		||||
    params(
 | 
			
		||||
      arr: Array,
 | 
			
		||||
      interface_mod: T.untyped
 | 
			
		||||
    )
 | 
			
		||||
    .returns(Array)
 | 
			
		||||
  end
 | 
			
		||||
  def self.wrap_instances(arr, interface_mod)
 | 
			
		||||
    arr.map {|instance| self.wrap_instance(instance, interface_mod)}
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def initialize(target_obj, interface_mod)
 | 
			
		||||
    if target_obj.is_a?(T::InterfaceWrapper)
 | 
			
		||||
      # wrapped_dynamic_cast should guarantee this never happens.
 | 
			
		||||
      raise "Unexpected: wrapping a wrapper. Please report this bug at https://github.com/sorbet/sorbet/issues"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if !target_obj.is_a?(interface_mod)
 | 
			
		||||
      # wrapped_dynamic_cast should guarantee this never happens.
 | 
			
		||||
      raise "Unexpected: `is_a?` failed. Please report this bug at https://github.com/sorbet/sorbet/issues"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if target_obj.class == interface_mod
 | 
			
		||||
      # wrapped_dynamic_cast should guarantee this never happens.
 | 
			
		||||
      raise "Unexpected: exact class match. Please report this bug at https://github.com/sorbet/sorbet/issues"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    @target_obj = target_obj
 | 
			
		||||
    @interface_mod = interface_mod
 | 
			
		||||
    self_methods = self.class.self_methods
 | 
			
		||||
 | 
			
		||||
    # If perf becomes an issue, we can define these on an anonymous subclass, and keep a cache
 | 
			
		||||
    # so we only need to do it once per unique `interface_mod`
 | 
			
		||||
    T::Utils.methods_excluding_object(interface_mod).each do |method_name|
 | 
			
		||||
      if self_methods.include?(method_name)
 | 
			
		||||
        raise "interface_mod has a method that conflicts with #{self.class}: #{method_name}"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      define_singleton_method(method_name) do |*args, &blk|
 | 
			
		||||
        target_obj.send(method_name, *args, &blk)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      if singleton_class.respond_to?(:ruby2_keywords, true)
 | 
			
		||||
        singleton_class.send(:ruby2_keywords, method_name)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      if target_obj.singleton_class.public_method_defined?(method_name)
 | 
			
		||||
        # no-op, it's already public
 | 
			
		||||
      elsif target_obj.singleton_class.protected_method_defined?(method_name)
 | 
			
		||||
        singleton_class.send(:protected, method_name)
 | 
			
		||||
      elsif target_obj.singleton_class.private_method_defined?(method_name)
 | 
			
		||||
        singleton_class.send(:private, method_name)
 | 
			
		||||
      else
 | 
			
		||||
        raise "This should never happen. Report this bug at https://github.com/sorbet/sorbet/issues"
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def kind_of?(other)
 | 
			
		||||
    is_a?(other)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def is_a?(other)
 | 
			
		||||
    if !other.is_a?(Module)
 | 
			
		||||
      raise TypeError.new("class or module required")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # This makes is_a? return true for T::InterfaceWrapper (and its ancestors),
 | 
			
		||||
    # as well as for @interface_mod and its ancestors.
 | 
			
		||||
    self.class <= other || @interface_mod <= other
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Prefixed because we're polluting the namespace of the interface we're wrapping, and we don't
 | 
			
		||||
  # want anyone else (besides dynamic_cast) calling it.
 | 
			
		||||
  def __target_obj_DO_NOT_USE # rubocop:disable Naming/MethodName
 | 
			
		||||
    @target_obj
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Prefixed because we're polluting the namespace of the interface we're wrapping, and we don't
 | 
			
		||||
  # want anyone else (besides wrapped_dynamic_cast) calling it.
 | 
			
		||||
  def __interface_mod_DO_NOT_USE # rubocop:disable Naming/MethodName
 | 
			
		||||
    @interface_mod
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # "Cast" an object to another type. If `obj` is an InterfaceWrapper, returns the the wrapped
 | 
			
		||||
  # object if that matches `type`. Otherwise, returns `obj` if it matches `type`. Otherwise,
 | 
			
		||||
  # returns nil.
 | 
			
		||||
  #
 | 
			
		||||
  # @param obj [Object] object to cast
 | 
			
		||||
  # @param mod [Module] type to cast `obj` to
 | 
			
		||||
  #
 | 
			
		||||
  # @example
 | 
			
		||||
  #   if (impl = T::InterfaceWrapper.dynamic_cast(iface, MyImplementation))
 | 
			
		||||
  #     impl.do_things
 | 
			
		||||
  #   end
 | 
			
		||||
  def self.dynamic_cast(obj, mod)
 | 
			
		||||
    if obj.is_a?(T::InterfaceWrapper)
 | 
			
		||||
      target_obj = obj.__target_obj_DO_NOT_USE
 | 
			
		||||
      target_obj.is_a?(mod) ? target_obj : nil
 | 
			
		||||
    elsif obj.is_a?(mod)
 | 
			
		||||
      obj
 | 
			
		||||
    else
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Like dynamic_cast, but puts the result in its own wrapper if necessary.
 | 
			
		||||
  #
 | 
			
		||||
  # @param obj [Object] object to cast
 | 
			
		||||
  # @param mod [Module] type to cast `obj` to
 | 
			
		||||
  def self.wrapped_dynamic_cast(obj, mod)
 | 
			
		||||
    # Avoid unwrapping and creating an equivalent wrapper.
 | 
			
		||||
    if obj.is_a?(T::InterfaceWrapper) && obj.__interface_mod_DO_NOT_USE == mod
 | 
			
		||||
      return obj
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    cast_obj = dynamic_cast(obj, mod)
 | 
			
		||||
    if cast_obj.nil?
 | 
			
		||||
      nil
 | 
			
		||||
    elsif cast_obj.class == mod
 | 
			
		||||
      # Nothing to wrap, they want the full class
 | 
			
		||||
      cast_obj
 | 
			
		||||
    else
 | 
			
		||||
      new(cast_obj, mod)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.self_methods
 | 
			
		||||
    @self_methods ||= self.instance_methods(false).to_set
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
@ -1,197 +0,0 @@
 | 
			
		||||
# frozen_string_literal: true
 | 
			
		||||
# typed: strict
 | 
			
		||||
 | 
			
		||||
module T::Props
 | 
			
		||||
  module Private
 | 
			
		||||
    module SetterFactory
 | 
			
		||||
      extend T::Sig
 | 
			
		||||
 | 
			
		||||
      SetterProc = T.type_alias {T.proc.params(val: T.untyped).void}
 | 
			
		||||
      ValidateProc = T.type_alias {T.proc.params(prop: Symbol, value: T.untyped).void}
 | 
			
		||||
 | 
			
		||||
      sig do
 | 
			
		||||
        params(
 | 
			
		||||
          klass: T.all(Module, T::Props::ClassMethods),
 | 
			
		||||
          prop: Symbol,
 | 
			
		||||
          rules: T::Hash[Symbol, T.untyped]
 | 
			
		||||
        )
 | 
			
		||||
        .returns(SetterProc)
 | 
			
		||||
        .checked(:never)
 | 
			
		||||
      end
 | 
			
		||||
      def self.build_setter_proc(klass, prop, rules)
 | 
			
		||||
        # Our nil check works differently than a simple T.nilable for various
 | 
			
		||||
        # reasons (including the `raise_on_nil_write` setting and the existence
 | 
			
		||||
        # of defaults & factories), so unwrap any T.nilable and do a check
 | 
			
		||||
        # manually.
 | 
			
		||||
        non_nil_type = T::Utils::Nilable.get_underlying_type_object(rules.fetch(:type_object))
 | 
			
		||||
        accessor_key = rules.fetch(:accessor_key)
 | 
			
		||||
        validate = rules[:setter_validate]
 | 
			
		||||
 | 
			
		||||
        # It seems like a bug that this affects the behavior of setters, but
 | 
			
		||||
        # some existing code relies on this behavior
 | 
			
		||||
        has_explicit_nil_default = rules.key?(:default) && rules.fetch(:default).nil?
 | 
			
		||||
 | 
			
		||||
        # Use separate methods in order to ensure that we only close over necessary
 | 
			
		||||
        # variables
 | 
			
		||||
        if !T::Props::Utils.need_nil_write_check?(rules) || has_explicit_nil_default
 | 
			
		||||
          if validate.nil? && non_nil_type.is_a?(T::Types::Simple)
 | 
			
		||||
            simple_nilable_proc(prop, accessor_key, non_nil_type.raw_type, klass)
 | 
			
		||||
          else
 | 
			
		||||
            nilable_proc(prop, accessor_key, non_nil_type, klass, validate)
 | 
			
		||||
          end
 | 
			
		||||
        else
 | 
			
		||||
          if validate.nil? && non_nil_type.is_a?(T::Types::Simple)
 | 
			
		||||
            simple_non_nil_proc(prop, accessor_key, non_nil_type.raw_type, klass)
 | 
			
		||||
          else
 | 
			
		||||
            non_nil_proc(prop, accessor_key, non_nil_type, klass, validate)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      sig do
 | 
			
		||||
        params(
 | 
			
		||||
          prop: Symbol,
 | 
			
		||||
          accessor_key: Symbol,
 | 
			
		||||
          non_nil_type: Module,
 | 
			
		||||
          klass: T.all(Module, T::Props::ClassMethods),
 | 
			
		||||
        )
 | 
			
		||||
        .returns(SetterProc)
 | 
			
		||||
      end
 | 
			
		||||
      private_class_method def self.simple_non_nil_proc(prop, accessor_key, non_nil_type, klass)
 | 
			
		||||
        proc do |val|
 | 
			
		||||
          unless val.is_a?(non_nil_type)
 | 
			
		||||
            T::Props::Private::SetterFactory.raise_pretty_error(
 | 
			
		||||
              klass,
 | 
			
		||||
              prop,
 | 
			
		||||
              T::Utils.coerce(non_nil_type),
 | 
			
		||||
              val,
 | 
			
		||||
            )
 | 
			
		||||
          end
 | 
			
		||||
          instance_variable_set(accessor_key, val)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      sig do
 | 
			
		||||
        params(
 | 
			
		||||
          prop: Symbol,
 | 
			
		||||
          accessor_key: Symbol,
 | 
			
		||||
          non_nil_type: T::Types::Base,
 | 
			
		||||
          klass: T.all(Module, T::Props::ClassMethods),
 | 
			
		||||
          validate: T.nilable(ValidateProc)
 | 
			
		||||
        )
 | 
			
		||||
        .returns(SetterProc)
 | 
			
		||||
      end
 | 
			
		||||
      private_class_method def self.non_nil_proc(prop, accessor_key, non_nil_type, klass, validate)
 | 
			
		||||
        proc do |val|
 | 
			
		||||
          # this use of recursively_valid? is intentional: unlike for
 | 
			
		||||
          # methods, we want to make sure data at the 'edge'
 | 
			
		||||
          # (e.g. models that go into databases or structs serialized
 | 
			
		||||
          # from disk) are correct, so we use more thorough runtime
 | 
			
		||||
          # checks there
 | 
			
		||||
          if non_nil_type.recursively_valid?(val)
 | 
			
		||||
            validate&.call(prop, val)
 | 
			
		||||
          else
 | 
			
		||||
            T::Props::Private::SetterFactory.raise_pretty_error(
 | 
			
		||||
              klass,
 | 
			
		||||
              prop,
 | 
			
		||||
              non_nil_type,
 | 
			
		||||
              val,
 | 
			
		||||
            )
 | 
			
		||||
          end
 | 
			
		||||
          instance_variable_set(accessor_key, val)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      sig do
 | 
			
		||||
        params(
 | 
			
		||||
          prop: Symbol,
 | 
			
		||||
          accessor_key: Symbol,
 | 
			
		||||
          non_nil_type: Module,
 | 
			
		||||
          klass: T.all(Module, T::Props::ClassMethods),
 | 
			
		||||
        )
 | 
			
		||||
        .returns(SetterProc)
 | 
			
		||||
      end
 | 
			
		||||
      private_class_method def self.simple_nilable_proc(prop, accessor_key, non_nil_type, klass)
 | 
			
		||||
        proc do |val|
 | 
			
		||||
          if val.nil?
 | 
			
		||||
            instance_variable_set(accessor_key, nil)
 | 
			
		||||
          elsif val.is_a?(non_nil_type)
 | 
			
		||||
            instance_variable_set(accessor_key, val)
 | 
			
		||||
          else
 | 
			
		||||
            T::Props::Private::SetterFactory.raise_pretty_error(
 | 
			
		||||
              klass,
 | 
			
		||||
              prop,
 | 
			
		||||
              T::Utils.coerce(non_nil_type),
 | 
			
		||||
              val,
 | 
			
		||||
            )
 | 
			
		||||
            instance_variable_set(accessor_key, val)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      sig do
 | 
			
		||||
        params(
 | 
			
		||||
          prop: Symbol,
 | 
			
		||||
          accessor_key: Symbol,
 | 
			
		||||
          non_nil_type: T::Types::Base,
 | 
			
		||||
          klass: T.all(Module, T::Props::ClassMethods),
 | 
			
		||||
          validate: T.nilable(ValidateProc),
 | 
			
		||||
        )
 | 
			
		||||
        .returns(SetterProc)
 | 
			
		||||
      end
 | 
			
		||||
      private_class_method def self.nilable_proc(prop, accessor_key, non_nil_type, klass, validate)
 | 
			
		||||
        proc do |val|
 | 
			
		||||
          if val.nil?
 | 
			
		||||
            instance_variable_set(accessor_key, nil)
 | 
			
		||||
          # this use of recursively_valid? is intentional: unlike for
 | 
			
		||||
          # methods, we want to make sure data at the 'edge'
 | 
			
		||||
          # (e.g. models that go into databases or structs serialized
 | 
			
		||||
          # from disk) are correct, so we use more thorough runtime
 | 
			
		||||
          # checks there
 | 
			
		||||
          elsif non_nil_type.recursively_valid?(val)
 | 
			
		||||
            validate&.call(prop, val)
 | 
			
		||||
            instance_variable_set(accessor_key, val)
 | 
			
		||||
          else
 | 
			
		||||
            T::Props::Private::SetterFactory.raise_pretty_error(
 | 
			
		||||
              klass,
 | 
			
		||||
              prop,
 | 
			
		||||
              non_nil_type,
 | 
			
		||||
              val,
 | 
			
		||||
            )
 | 
			
		||||
            instance_variable_set(accessor_key, val)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      sig do
 | 
			
		||||
        params(
 | 
			
		||||
          klass: T.all(Module, T::Props::ClassMethods),
 | 
			
		||||
          prop: Symbol,
 | 
			
		||||
          type: T.any(T::Types::Base, Module),
 | 
			
		||||
          val: T.untyped,
 | 
			
		||||
        )
 | 
			
		||||
        .void
 | 
			
		||||
      end
 | 
			
		||||
      def self.raise_pretty_error(klass, prop, type, val)
 | 
			
		||||
        base_message = "Can't set #{klass.name}.#{prop} to #{val.inspect} (instance of #{val.class}) - need a #{type}"
 | 
			
		||||
 | 
			
		||||
        pretty_message = "Parameter '#{prop}': #{base_message}\n"
 | 
			
		||||
        caller_loc = caller_locations.find {|l| !l.to_s.include?('sorbet-runtime/lib/types/props')}
 | 
			
		||||
        if caller_loc
 | 
			
		||||
          pretty_message += "Caller: #{caller_loc.path}:#{caller_loc.lineno}\n"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        T::Configuration.call_validation_error_handler(
 | 
			
		||||
          nil,
 | 
			
		||||
          message: base_message,
 | 
			
		||||
          pretty_message: pretty_message,
 | 
			
		||||
          kind: 'Parameter',
 | 
			
		||||
          name: prop,
 | 
			
		||||
          type: type,
 | 
			
		||||
          value: val,
 | 
			
		||||
          location: caller_loc,
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
@ -73,7 +73,6 @@ require_relative 'types/private/abstract/validate'
 | 
			
		||||
 | 
			
		||||
# Catch all. Sort of built by `cd extn; find types -type f | grep -v test | sort`
 | 
			
		||||
require_relative 'types/generic'
 | 
			
		||||
require_relative 'types/interface_wrapper'
 | 
			
		||||
require_relative 'types/private/abstract/declare'
 | 
			
		||||
require_relative 'types/private/abstract/hooks'
 | 
			
		||||
require_relative 'types/private/casts'
 | 
			
		||||
@ -18,7 +18,6 @@ module T::Private::Abstract::Declare
 | 
			
		||||
    Abstract::Data.set(mod, :abstract_type, type)
 | 
			
		||||
 | 
			
		||||
    mod.extend(Abstract::Hooks)
 | 
			
		||||
    mod.extend(T::InterfaceWrapper::Helpers)
 | 
			
		||||
 | 
			
		||||
    if mod.is_a?(Class)
 | 
			
		||||
      if type == :interface
 | 
			
		||||
@ -191,12 +191,11 @@ module T::Private::Methods
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.add_module_with_final_method(mod, method_name, is_singleton_method)
 | 
			
		||||
    m = is_singleton_method ? mod.singleton_class : mod
 | 
			
		||||
    methods = @modules_with_final[m]
 | 
			
		||||
  def self.add_module_with_final_method(mod, method_name)
 | 
			
		||||
    methods = @modules_with_final[mod]
 | 
			
		||||
    if methods.nil?
 | 
			
		||||
      methods = {}
 | 
			
		||||
      @modules_with_final[m] = methods
 | 
			
		||||
      @modules_with_final[mod] = methods
 | 
			
		||||
    end
 | 
			
		||||
    methods[method_name] = true
 | 
			
		||||
    nil
 | 
			
		||||
@ -209,13 +208,12 @@ module T::Private::Methods
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Only public because it needs to get called below inside the replace_method blocks below.
 | 
			
		||||
  def self._on_method_added(hook_mod, method_name, is_singleton_method: false)
 | 
			
		||||
  def self._on_method_added(hook_mod, mod, method_name)
 | 
			
		||||
    if T::Private::DeclState.current.skip_on_method_added
 | 
			
		||||
      return
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    current_declaration = T::Private::DeclState.current.active_declaration
 | 
			
		||||
    mod = is_singleton_method ? hook_mod.singleton_class : hook_mod
 | 
			
		||||
 | 
			
		||||
    if T::Private::Final.final_module?(mod) && (current_declaration.nil? || !current_declaration.final)
 | 
			
		||||
      raise "#{mod} was declared as final but its method `#{method_name}` was not declared as final"
 | 
			
		||||
@ -286,7 +284,7 @@ module T::Private::Methods
 | 
			
		||||
      # use hook_mod, not mod, because for example, we want class C to be marked as having final if we def C.foo as
 | 
			
		||||
      # final. change this to mod to see some final_method tests fail.
 | 
			
		||||
      note_module_deals_with_final(hook_mod)
 | 
			
		||||
      add_module_with_final_method(hook_mod, method_name, is_singleton_method)
 | 
			
		||||
      add_module_with_final_method(mod, method_name)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -430,7 +428,7 @@ module T::Private::Methods
 | 
			
		||||
    run_sig_block_for_key(method_to_key(method))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  private_class_method def self.run_sig_block_for_key(key)
 | 
			
		||||
  private_class_method def self.run_sig_block_for_key(key, force_type_init: false)
 | 
			
		||||
    blk = @sig_wrappers[key]
 | 
			
		||||
    if !blk
 | 
			
		||||
      sig = @signatures_by_method[key]
 | 
			
		||||
@ -453,14 +451,17 @@ module T::Private::Methods
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    @sig_wrappers.delete(key)
 | 
			
		||||
 | 
			
		||||
    sig.force_type_init if force_type_init
 | 
			
		||||
 | 
			
		||||
    sig
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.run_all_sig_blocks
 | 
			
		||||
  def self.run_all_sig_blocks(force_type_init: true)
 | 
			
		||||
    loop do
 | 
			
		||||
      break if @sig_wrappers.empty?
 | 
			
		||||
      key, = @sig_wrappers.first
 | 
			
		||||
      run_sig_block_for_key(key)
 | 
			
		||||
      run_sig_block_for_key(key, force_type_init: force_type_init)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -540,14 +541,14 @@ module T::Private::Methods
 | 
			
		||||
  module MethodHooks
 | 
			
		||||
    def method_added(name)
 | 
			
		||||
      super(name)
 | 
			
		||||
      ::T::Private::Methods._on_method_added(self, name, is_singleton_method: false)
 | 
			
		||||
      ::T::Private::Methods._on_method_added(self, self, name)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  module SingletonMethodHooks
 | 
			
		||||
    def singleton_method_added(name)
 | 
			
		||||
      super(name)
 | 
			
		||||
      ::T::Private::Methods._on_method_added(self, name, is_singleton_method: true)
 | 
			
		||||
      ::T::Private::Methods._on_method_added(self, singleton_class, name)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -15,8 +15,6 @@ module T::Private::Methods::CallValidation
 | 
			
		||||
    original_visibility = visibility_method_name(mod, method_sig.method_name)
 | 
			
		||||
    if method_sig.mode == T::Private::Methods::Modes.abstract
 | 
			
		||||
      T::Private::ClassUtils.replace_method(mod, method_sig.method_name, true) do |*args, &blk|
 | 
			
		||||
        # TODO: write a cop to ensure that abstract methods have an empty body
 | 
			
		||||
        #
 | 
			
		||||
        # We allow abstract methods to be implemented by things further down the ancestor chain.
 | 
			
		||||
        # So, if a super method exists, call it.
 | 
			
		||||
        if defined?(super)
 | 
			
		||||
@ -67,14 +65,30 @@ module T::Private::Methods::CallValidation
 | 
			
		||||
    simple_method = all_args_are_simple && method_sig.return_type.is_a?(T::Types::Simple)
 | 
			
		||||
    simple_procedure = all_args_are_simple && method_sig.return_type.is_a?(T::Private::Types::Void)
 | 
			
		||||
 | 
			
		||||
    # All the types for which valid? unconditionally returns `true`
 | 
			
		||||
    return_is_ignorable =
 | 
			
		||||
      (method_sig.return_type.equal?(T::Types::Untyped::Private::INSTANCE) ||
 | 
			
		||||
       method_sig.return_type.equal?(T::Types::Anything::Private::INSTANCE) ||
 | 
			
		||||
       method_sig.return_type.equal?(T::Types::AttachedClassType::Private::INSTANCE) ||
 | 
			
		||||
       method_sig.return_type.equal?(T::Types::SelfType::Private::INSTANCE) ||
 | 
			
		||||
       method_sig.return_type.is_a?(T::Types::TypeParameter) ||
 | 
			
		||||
       method_sig.return_type.is_a?(T::Types::TypeVariable) ||
 | 
			
		||||
       (method_sig.return_type.is_a?(T::Types::Simple) && method_sig.return_type.raw_type.equal?(BasicObject)))
 | 
			
		||||
 | 
			
		||||
    returns_anything_method = all_args_are_simple && return_is_ignorable
 | 
			
		||||
 | 
			
		||||
    T::Configuration.without_ruby_warnings do
 | 
			
		||||
      T::Private::DeclState.current.without_on_method_added do
 | 
			
		||||
        if simple_method
 | 
			
		||||
          create_validator_method_fast(mod, original_method, method_sig, original_visibility)
 | 
			
		||||
        elsif returns_anything_method
 | 
			
		||||
          create_validator_method_skip_return_fast(mod, original_method, method_sig, original_visibility)
 | 
			
		||||
        elsif simple_procedure
 | 
			
		||||
          create_validator_procedure_fast(mod, original_method, method_sig, original_visibility)
 | 
			
		||||
        elsif ok_for_fast_path && method_sig.return_type.is_a?(T::Private::Types::Void)
 | 
			
		||||
          create_validator_procedure_medium(mod, original_method, method_sig, original_visibility)
 | 
			
		||||
        elsif ok_for_fast_path && return_is_ignorable
 | 
			
		||||
          create_validator_method_skip_return_medium(mod, original_method, method_sig, original_visibility)
 | 
			
		||||
        elsif ok_for_fast_path
 | 
			
		||||
          create_validator_method_medium(mod, original_method, method_sig, original_visibility)
 | 
			
		||||
        elsif can_skip_block_type
 | 
			
		||||
@ -343,6 +343,265 @@ module T::Private::Methods::CallValidation
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_fast(mod, original_method, method_sig, original_visibility)
 | 
			
		||||
    # trampoline to reduce stack frame size
 | 
			
		||||
    arg_types = method_sig.arg_types
 | 
			
		||||
    case arg_types.length
 | 
			
		||||
    when 0
 | 
			
		||||
      create_validator_method_skip_return_fast0(mod, original_method, method_sig, original_visibility)
 | 
			
		||||
    when 1
 | 
			
		||||
      create_validator_method_skip_return_fast1(mod, original_method, method_sig, original_visibility,
 | 
			
		||||
                                    arg_types[0][1].raw_type)
 | 
			
		||||
    when 2
 | 
			
		||||
      create_validator_method_skip_return_fast2(mod, original_method, method_sig, original_visibility,
 | 
			
		||||
                                    arg_types[0][1].raw_type,
 | 
			
		||||
                                    arg_types[1][1].raw_type)
 | 
			
		||||
    when 3
 | 
			
		||||
      create_validator_method_skip_return_fast3(mod, original_method, method_sig, original_visibility,
 | 
			
		||||
                                    arg_types[0][1].raw_type,
 | 
			
		||||
                                    arg_types[1][1].raw_type,
 | 
			
		||||
                                    arg_types[2][1].raw_type)
 | 
			
		||||
    when 4
 | 
			
		||||
      create_validator_method_skip_return_fast4(mod, original_method, method_sig, original_visibility,
 | 
			
		||||
                                    arg_types[0][1].raw_type,
 | 
			
		||||
                                    arg_types[1][1].raw_type,
 | 
			
		||||
                                    arg_types[2][1].raw_type,
 | 
			
		||||
                                    arg_types[3][1].raw_type)
 | 
			
		||||
    else
 | 
			
		||||
      raise 'should not happen'
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_fast0(mod, original_method, method_sig, original_visibility)
 | 
			
		||||
    T::Private::ClassUtils.def_with_visibility(mod, method_sig.method_name, original_visibility) do |&blk|
 | 
			
		||||
      # This method is a manually sped-up version of more general code in `validate_call`
 | 
			
		||||
      # The following line breaks are intentional to show nice pry message
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      # PRY note:
 | 
			
		||||
      # this code is sig validation code.
 | 
			
		||||
      # Please issue `finish` to step out of it
 | 
			
		||||
 | 
			
		||||
      original_method.bind(self).call(&blk)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_fast1(mod, original_method, method_sig, original_visibility, arg0_type)
 | 
			
		||||
    T::Private::ClassUtils.def_with_visibility(mod, method_sig.method_name, original_visibility) do |arg0, &blk|
 | 
			
		||||
      # This method is a manually sped-up version of more general code in `validate_call`
 | 
			
		||||
      unless arg0.is_a?(arg0_type)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[0][1].error_message_for_obj(arg0),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[0][0],
 | 
			
		||||
          arg0_type,
 | 
			
		||||
          arg0,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # The following line breaks are intentional to show nice pry message
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      # PRY note:
 | 
			
		||||
      # this code is sig validation code.
 | 
			
		||||
      # Please issue `finish` to step out of it
 | 
			
		||||
 | 
			
		||||
      original_method.bind(self).call(arg0, &blk)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_fast2(mod, original_method, method_sig, original_visibility, arg0_type, arg1_type)
 | 
			
		||||
    T::Private::ClassUtils.def_with_visibility(mod, method_sig.method_name, original_visibility) do |arg0, arg1, &blk|
 | 
			
		||||
      # This method is a manually sped-up version of more general code in `validate_call`
 | 
			
		||||
      unless arg0.is_a?(arg0_type)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[0][1].error_message_for_obj(arg0),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[0][0],
 | 
			
		||||
          arg0_type,
 | 
			
		||||
          arg0,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg1.is_a?(arg1_type)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[1][1].error_message_for_obj(arg1),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[1][0],
 | 
			
		||||
          arg1_type,
 | 
			
		||||
          arg1,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # The following line breaks are intentional to show nice pry message
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      # PRY note:
 | 
			
		||||
      # this code is sig validation code.
 | 
			
		||||
      # Please issue `finish` to step out of it
 | 
			
		||||
 | 
			
		||||
      original_method.bind(self).call(arg0, arg1, &blk)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_fast3(mod, original_method, method_sig, original_visibility, arg0_type, arg1_type, arg2_type)
 | 
			
		||||
    T::Private::ClassUtils.def_with_visibility(mod, method_sig.method_name, original_visibility) do |arg0, arg1, arg2, &blk|
 | 
			
		||||
      # This method is a manually sped-up version of more general code in `validate_call`
 | 
			
		||||
      unless arg0.is_a?(arg0_type)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[0][1].error_message_for_obj(arg0),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[0][0],
 | 
			
		||||
          arg0_type,
 | 
			
		||||
          arg0,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg1.is_a?(arg1_type)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[1][1].error_message_for_obj(arg1),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[1][0],
 | 
			
		||||
          arg1_type,
 | 
			
		||||
          arg1,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg2.is_a?(arg2_type)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[2][1].error_message_for_obj(arg2),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[2][0],
 | 
			
		||||
          arg2_type,
 | 
			
		||||
          arg2,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # The following line breaks are intentional to show nice pry message
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      # PRY note:
 | 
			
		||||
      # this code is sig validation code.
 | 
			
		||||
      # Please issue `finish` to step out of it
 | 
			
		||||
 | 
			
		||||
      original_method.bind(self).call(arg0, arg1, arg2, &blk)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_fast4(mod, original_method, method_sig, original_visibility, arg0_type, arg1_type, arg2_type, arg3_type)
 | 
			
		||||
    T::Private::ClassUtils.def_with_visibility(mod, method_sig.method_name, original_visibility) do |arg0, arg1, arg2, arg3, &blk|
 | 
			
		||||
      # This method is a manually sped-up version of more general code in `validate_call`
 | 
			
		||||
      unless arg0.is_a?(arg0_type)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[0][1].error_message_for_obj(arg0),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[0][0],
 | 
			
		||||
          arg0_type,
 | 
			
		||||
          arg0,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg1.is_a?(arg1_type)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[1][1].error_message_for_obj(arg1),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[1][0],
 | 
			
		||||
          arg1_type,
 | 
			
		||||
          arg1,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg2.is_a?(arg2_type)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[2][1].error_message_for_obj(arg2),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[2][0],
 | 
			
		||||
          arg2_type,
 | 
			
		||||
          arg2,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg3.is_a?(arg3_type)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[3][1].error_message_for_obj(arg3),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[3][0],
 | 
			
		||||
          arg3_type,
 | 
			
		||||
          arg3,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # The following line breaks are intentional to show nice pry message
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      # PRY note:
 | 
			
		||||
      # this code is sig validation code.
 | 
			
		||||
      # Please issue `finish` to step out of it
 | 
			
		||||
 | 
			
		||||
      original_method.bind(self).call(arg0, arg1, arg2, arg3, &blk)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_procedure_fast(mod, original_method, method_sig, original_visibility)
 | 
			
		||||
    # trampoline to reduce stack frame size
 | 
			
		||||
    arg_types = method_sig.arg_types
 | 
			
		||||
@ -944,6 +1203,265 @@ module T::Private::Methods::CallValidation
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_medium(mod, original_method, method_sig, original_visibility)
 | 
			
		||||
    # trampoline to reduce stack frame size
 | 
			
		||||
    arg_types = method_sig.arg_types
 | 
			
		||||
    case arg_types.length
 | 
			
		||||
    when 0
 | 
			
		||||
      create_validator_method_skip_return_medium0(mod, original_method, method_sig, original_visibility)
 | 
			
		||||
    when 1
 | 
			
		||||
      create_validator_method_skip_return_medium1(mod, original_method, method_sig, original_visibility,
 | 
			
		||||
                                    arg_types[0][1])
 | 
			
		||||
    when 2
 | 
			
		||||
      create_validator_method_skip_return_medium2(mod, original_method, method_sig, original_visibility,
 | 
			
		||||
                                    arg_types[0][1],
 | 
			
		||||
                                    arg_types[1][1])
 | 
			
		||||
    when 3
 | 
			
		||||
      create_validator_method_skip_return_medium3(mod, original_method, method_sig, original_visibility,
 | 
			
		||||
                                    arg_types[0][1],
 | 
			
		||||
                                    arg_types[1][1],
 | 
			
		||||
                                    arg_types[2][1])
 | 
			
		||||
    when 4
 | 
			
		||||
      create_validator_method_skip_return_medium4(mod, original_method, method_sig, original_visibility,
 | 
			
		||||
                                    arg_types[0][1],
 | 
			
		||||
                                    arg_types[1][1],
 | 
			
		||||
                                    arg_types[2][1],
 | 
			
		||||
                                    arg_types[3][1])
 | 
			
		||||
    else
 | 
			
		||||
      raise 'should not happen'
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_medium0(mod, original_method, method_sig, original_visibility)
 | 
			
		||||
    T::Private::ClassUtils.def_with_visibility(mod, method_sig.method_name, original_visibility) do |&blk|
 | 
			
		||||
      # This method is a manually sped-up version of more general code in `validate_call`
 | 
			
		||||
      # The following line breaks are intentional to show nice pry message
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      # PRY note:
 | 
			
		||||
      # this code is sig validation code.
 | 
			
		||||
      # Please issue `finish` to step out of it
 | 
			
		||||
 | 
			
		||||
      original_method.bind(self).call(&blk)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_medium1(mod, original_method, method_sig, original_visibility, arg0_type)
 | 
			
		||||
    T::Private::ClassUtils.def_with_visibility(mod, method_sig.method_name, original_visibility) do |arg0, &blk|
 | 
			
		||||
      # This method is a manually sped-up version of more general code in `validate_call`
 | 
			
		||||
      unless arg0_type.valid?(arg0)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[0][1].error_message_for_obj(arg0),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[0][0],
 | 
			
		||||
          arg0_type,
 | 
			
		||||
          arg0,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # The following line breaks are intentional to show nice pry message
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      # PRY note:
 | 
			
		||||
      # this code is sig validation code.
 | 
			
		||||
      # Please issue `finish` to step out of it
 | 
			
		||||
 | 
			
		||||
      original_method.bind(self).call(arg0, &blk)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_medium2(mod, original_method, method_sig, original_visibility, arg0_type, arg1_type)
 | 
			
		||||
    T::Private::ClassUtils.def_with_visibility(mod, method_sig.method_name, original_visibility) do |arg0, arg1, &blk|
 | 
			
		||||
      # This method is a manually sped-up version of more general code in `validate_call`
 | 
			
		||||
      unless arg0_type.valid?(arg0)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[0][1].error_message_for_obj(arg0),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[0][0],
 | 
			
		||||
          arg0_type,
 | 
			
		||||
          arg0,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg1_type.valid?(arg1)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[1][1].error_message_for_obj(arg1),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[1][0],
 | 
			
		||||
          arg1_type,
 | 
			
		||||
          arg1,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # The following line breaks are intentional to show nice pry message
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      # PRY note:
 | 
			
		||||
      # this code is sig validation code.
 | 
			
		||||
      # Please issue `finish` to step out of it
 | 
			
		||||
 | 
			
		||||
      original_method.bind(self).call(arg0, arg1, &blk)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_medium3(mod, original_method, method_sig, original_visibility, arg0_type, arg1_type, arg2_type)
 | 
			
		||||
    T::Private::ClassUtils.def_with_visibility(mod, method_sig.method_name, original_visibility) do |arg0, arg1, arg2, &blk|
 | 
			
		||||
      # This method is a manually sped-up version of more general code in `validate_call`
 | 
			
		||||
      unless arg0_type.valid?(arg0)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[0][1].error_message_for_obj(arg0),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[0][0],
 | 
			
		||||
          arg0_type,
 | 
			
		||||
          arg0,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg1_type.valid?(arg1)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[1][1].error_message_for_obj(arg1),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[1][0],
 | 
			
		||||
          arg1_type,
 | 
			
		||||
          arg1,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg2_type.valid?(arg2)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[2][1].error_message_for_obj(arg2),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[2][0],
 | 
			
		||||
          arg2_type,
 | 
			
		||||
          arg2,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # The following line breaks are intentional to show nice pry message
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      # PRY note:
 | 
			
		||||
      # this code is sig validation code.
 | 
			
		||||
      # Please issue `finish` to step out of it
 | 
			
		||||
 | 
			
		||||
      original_method.bind(self).call(arg0, arg1, arg2, &blk)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_medium4(mod, original_method, method_sig, original_visibility, arg0_type, arg1_type, arg2_type, arg3_type)
 | 
			
		||||
    T::Private::ClassUtils.def_with_visibility(mod, method_sig.method_name, original_visibility) do |arg0, arg1, arg2, arg3, &blk|
 | 
			
		||||
      # This method is a manually sped-up version of more general code in `validate_call`
 | 
			
		||||
      unless arg0_type.valid?(arg0)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[0][1].error_message_for_obj(arg0),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[0][0],
 | 
			
		||||
          arg0_type,
 | 
			
		||||
          arg0,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg1_type.valid?(arg1)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[1][1].error_message_for_obj(arg1),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[1][0],
 | 
			
		||||
          arg1_type,
 | 
			
		||||
          arg1,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg2_type.valid?(arg2)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[2][1].error_message_for_obj(arg2),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[2][0],
 | 
			
		||||
          arg2_type,
 | 
			
		||||
          arg2,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg3_type.valid?(arg3)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[3][1].error_message_for_obj(arg3),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[3][0],
 | 
			
		||||
          arg3_type,
 | 
			
		||||
          arg3,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # The following line breaks are intentional to show nice pry message
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      # PRY note:
 | 
			
		||||
      # this code is sig validation code.
 | 
			
		||||
      # Please issue `finish` to step out of it
 | 
			
		||||
 | 
			
		||||
      original_method.bind(self).call(arg0, arg1, arg2, arg3, &blk)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_procedure_medium(mod, original_method, method_sig, original_visibility)
 | 
			
		||||
    # trampoline to reduce stack frame size
 | 
			
		||||
    arg_types = method_sig.arg_types
 | 
			
		||||
@ -343,6 +343,265 @@ module T::Private::Methods::CallValidation
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_fast(mod, original_method, method_sig, original_visibility)
 | 
			
		||||
    # trampoline to reduce stack frame size
 | 
			
		||||
    arg_types = method_sig.arg_types
 | 
			
		||||
    case arg_types.length
 | 
			
		||||
    when 0
 | 
			
		||||
      create_validator_method_skip_return_fast0(mod, original_method, method_sig, original_visibility)
 | 
			
		||||
    when 1
 | 
			
		||||
      create_validator_method_skip_return_fast1(mod, original_method, method_sig, original_visibility,
 | 
			
		||||
                                    arg_types[0][1].raw_type)
 | 
			
		||||
    when 2
 | 
			
		||||
      create_validator_method_skip_return_fast2(mod, original_method, method_sig, original_visibility,
 | 
			
		||||
                                    arg_types[0][1].raw_type,
 | 
			
		||||
                                    arg_types[1][1].raw_type)
 | 
			
		||||
    when 3
 | 
			
		||||
      create_validator_method_skip_return_fast3(mod, original_method, method_sig, original_visibility,
 | 
			
		||||
                                    arg_types[0][1].raw_type,
 | 
			
		||||
                                    arg_types[1][1].raw_type,
 | 
			
		||||
                                    arg_types[2][1].raw_type)
 | 
			
		||||
    when 4
 | 
			
		||||
      create_validator_method_skip_return_fast4(mod, original_method, method_sig, original_visibility,
 | 
			
		||||
                                    arg_types[0][1].raw_type,
 | 
			
		||||
                                    arg_types[1][1].raw_type,
 | 
			
		||||
                                    arg_types[2][1].raw_type,
 | 
			
		||||
                                    arg_types[3][1].raw_type)
 | 
			
		||||
    else
 | 
			
		||||
      raise 'should not happen'
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_fast0(mod, original_method, method_sig, original_visibility)
 | 
			
		||||
    T::Private::ClassUtils.def_with_visibility(mod, method_sig.method_name, original_visibility) do |&blk|
 | 
			
		||||
      # This method is a manually sped-up version of more general code in `validate_call`
 | 
			
		||||
      # The following line breaks are intentional to show nice pry message
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      # PRY note:
 | 
			
		||||
      # this code is sig validation code.
 | 
			
		||||
      # Please issue `finish` to step out of it
 | 
			
		||||
 | 
			
		||||
      original_method.bind_call(self, &blk)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_fast1(mod, original_method, method_sig, original_visibility, arg0_type)
 | 
			
		||||
    T::Private::ClassUtils.def_with_visibility(mod, method_sig.method_name, original_visibility) do |arg0, &blk|
 | 
			
		||||
      # This method is a manually sped-up version of more general code in `validate_call`
 | 
			
		||||
      unless arg0.is_a?(arg0_type)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[0][1].error_message_for_obj(arg0),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[0][0],
 | 
			
		||||
          arg0_type,
 | 
			
		||||
          arg0,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # The following line breaks are intentional to show nice pry message
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      # PRY note:
 | 
			
		||||
      # this code is sig validation code.
 | 
			
		||||
      # Please issue `finish` to step out of it
 | 
			
		||||
 | 
			
		||||
      original_method.bind_call(self, arg0, &blk)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_fast2(mod, original_method, method_sig, original_visibility, arg0_type, arg1_type)
 | 
			
		||||
    T::Private::ClassUtils.def_with_visibility(mod, method_sig.method_name, original_visibility) do |arg0, arg1, &blk|
 | 
			
		||||
      # This method is a manually sped-up version of more general code in `validate_call`
 | 
			
		||||
      unless arg0.is_a?(arg0_type)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[0][1].error_message_for_obj(arg0),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[0][0],
 | 
			
		||||
          arg0_type,
 | 
			
		||||
          arg0,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg1.is_a?(arg1_type)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[1][1].error_message_for_obj(arg1),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[1][0],
 | 
			
		||||
          arg1_type,
 | 
			
		||||
          arg1,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # The following line breaks are intentional to show nice pry message
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      # PRY note:
 | 
			
		||||
      # this code is sig validation code.
 | 
			
		||||
      # Please issue `finish` to step out of it
 | 
			
		||||
 | 
			
		||||
      original_method.bind_call(self, arg0, arg1, &blk)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_fast3(mod, original_method, method_sig, original_visibility, arg0_type, arg1_type, arg2_type)
 | 
			
		||||
    T::Private::ClassUtils.def_with_visibility(mod, method_sig.method_name, original_visibility) do |arg0, arg1, arg2, &blk|
 | 
			
		||||
      # This method is a manually sped-up version of more general code in `validate_call`
 | 
			
		||||
      unless arg0.is_a?(arg0_type)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[0][1].error_message_for_obj(arg0),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[0][0],
 | 
			
		||||
          arg0_type,
 | 
			
		||||
          arg0,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg1.is_a?(arg1_type)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[1][1].error_message_for_obj(arg1),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[1][0],
 | 
			
		||||
          arg1_type,
 | 
			
		||||
          arg1,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg2.is_a?(arg2_type)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[2][1].error_message_for_obj(arg2),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[2][0],
 | 
			
		||||
          arg2_type,
 | 
			
		||||
          arg2,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # The following line breaks are intentional to show nice pry message
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      # PRY note:
 | 
			
		||||
      # this code is sig validation code.
 | 
			
		||||
      # Please issue `finish` to step out of it
 | 
			
		||||
 | 
			
		||||
      original_method.bind_call(self, arg0, arg1, arg2, &blk)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_fast4(mod, original_method, method_sig, original_visibility, arg0_type, arg1_type, arg2_type, arg3_type)
 | 
			
		||||
    T::Private::ClassUtils.def_with_visibility(mod, method_sig.method_name, original_visibility) do |arg0, arg1, arg2, arg3, &blk|
 | 
			
		||||
      # This method is a manually sped-up version of more general code in `validate_call`
 | 
			
		||||
      unless arg0.is_a?(arg0_type)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[0][1].error_message_for_obj(arg0),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[0][0],
 | 
			
		||||
          arg0_type,
 | 
			
		||||
          arg0,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg1.is_a?(arg1_type)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[1][1].error_message_for_obj(arg1),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[1][0],
 | 
			
		||||
          arg1_type,
 | 
			
		||||
          arg1,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg2.is_a?(arg2_type)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[2][1].error_message_for_obj(arg2),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[2][0],
 | 
			
		||||
          arg2_type,
 | 
			
		||||
          arg2,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg3.is_a?(arg3_type)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[3][1].error_message_for_obj(arg3),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[3][0],
 | 
			
		||||
          arg3_type,
 | 
			
		||||
          arg3,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # The following line breaks are intentional to show nice pry message
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      # PRY note:
 | 
			
		||||
      # this code is sig validation code.
 | 
			
		||||
      # Please issue `finish` to step out of it
 | 
			
		||||
 | 
			
		||||
      original_method.bind_call(self, arg0, arg1, arg2, arg3, &blk)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_procedure_fast(mod, original_method, method_sig, original_visibility)
 | 
			
		||||
    # trampoline to reduce stack frame size
 | 
			
		||||
    arg_types = method_sig.arg_types
 | 
			
		||||
@ -944,6 +1203,265 @@ module T::Private::Methods::CallValidation
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_medium(mod, original_method, method_sig, original_visibility)
 | 
			
		||||
    # trampoline to reduce stack frame size
 | 
			
		||||
    arg_types = method_sig.arg_types
 | 
			
		||||
    case arg_types.length
 | 
			
		||||
    when 0
 | 
			
		||||
      create_validator_method_skip_return_medium0(mod, original_method, method_sig, original_visibility)
 | 
			
		||||
    when 1
 | 
			
		||||
      create_validator_method_skip_return_medium1(mod, original_method, method_sig, original_visibility,
 | 
			
		||||
                                    arg_types[0][1])
 | 
			
		||||
    when 2
 | 
			
		||||
      create_validator_method_skip_return_medium2(mod, original_method, method_sig, original_visibility,
 | 
			
		||||
                                    arg_types[0][1],
 | 
			
		||||
                                    arg_types[1][1])
 | 
			
		||||
    when 3
 | 
			
		||||
      create_validator_method_skip_return_medium3(mod, original_method, method_sig, original_visibility,
 | 
			
		||||
                                    arg_types[0][1],
 | 
			
		||||
                                    arg_types[1][1],
 | 
			
		||||
                                    arg_types[2][1])
 | 
			
		||||
    when 4
 | 
			
		||||
      create_validator_method_skip_return_medium4(mod, original_method, method_sig, original_visibility,
 | 
			
		||||
                                    arg_types[0][1],
 | 
			
		||||
                                    arg_types[1][1],
 | 
			
		||||
                                    arg_types[2][1],
 | 
			
		||||
                                    arg_types[3][1])
 | 
			
		||||
    else
 | 
			
		||||
      raise 'should not happen'
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_medium0(mod, original_method, method_sig, original_visibility)
 | 
			
		||||
    T::Private::ClassUtils.def_with_visibility(mod, method_sig.method_name, original_visibility) do |&blk|
 | 
			
		||||
      # This method is a manually sped-up version of more general code in `validate_call`
 | 
			
		||||
      # The following line breaks are intentional to show nice pry message
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      # PRY note:
 | 
			
		||||
      # this code is sig validation code.
 | 
			
		||||
      # Please issue `finish` to step out of it
 | 
			
		||||
 | 
			
		||||
      original_method.bind_call(self, &blk)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_medium1(mod, original_method, method_sig, original_visibility, arg0_type)
 | 
			
		||||
    T::Private::ClassUtils.def_with_visibility(mod, method_sig.method_name, original_visibility) do |arg0, &blk|
 | 
			
		||||
      # This method is a manually sped-up version of more general code in `validate_call`
 | 
			
		||||
      unless arg0_type.valid?(arg0)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[0][1].error_message_for_obj(arg0),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[0][0],
 | 
			
		||||
          arg0_type,
 | 
			
		||||
          arg0,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # The following line breaks are intentional to show nice pry message
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      # PRY note:
 | 
			
		||||
      # this code is sig validation code.
 | 
			
		||||
      # Please issue `finish` to step out of it
 | 
			
		||||
 | 
			
		||||
      original_method.bind_call(self, arg0, &blk)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_medium2(mod, original_method, method_sig, original_visibility, arg0_type, arg1_type)
 | 
			
		||||
    T::Private::ClassUtils.def_with_visibility(mod, method_sig.method_name, original_visibility) do |arg0, arg1, &blk|
 | 
			
		||||
      # This method is a manually sped-up version of more general code in `validate_call`
 | 
			
		||||
      unless arg0_type.valid?(arg0)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[0][1].error_message_for_obj(arg0),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[0][0],
 | 
			
		||||
          arg0_type,
 | 
			
		||||
          arg0,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg1_type.valid?(arg1)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[1][1].error_message_for_obj(arg1),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[1][0],
 | 
			
		||||
          arg1_type,
 | 
			
		||||
          arg1,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # The following line breaks are intentional to show nice pry message
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      # PRY note:
 | 
			
		||||
      # this code is sig validation code.
 | 
			
		||||
      # Please issue `finish` to step out of it
 | 
			
		||||
 | 
			
		||||
      original_method.bind_call(self, arg0, arg1, &blk)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_medium3(mod, original_method, method_sig, original_visibility, arg0_type, arg1_type, arg2_type)
 | 
			
		||||
    T::Private::ClassUtils.def_with_visibility(mod, method_sig.method_name, original_visibility) do |arg0, arg1, arg2, &blk|
 | 
			
		||||
      # This method is a manually sped-up version of more general code in `validate_call`
 | 
			
		||||
      unless arg0_type.valid?(arg0)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[0][1].error_message_for_obj(arg0),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[0][0],
 | 
			
		||||
          arg0_type,
 | 
			
		||||
          arg0,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg1_type.valid?(arg1)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[1][1].error_message_for_obj(arg1),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[1][0],
 | 
			
		||||
          arg1_type,
 | 
			
		||||
          arg1,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg2_type.valid?(arg2)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[2][1].error_message_for_obj(arg2),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[2][0],
 | 
			
		||||
          arg2_type,
 | 
			
		||||
          arg2,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # The following line breaks are intentional to show nice pry message
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      # PRY note:
 | 
			
		||||
      # this code is sig validation code.
 | 
			
		||||
      # Please issue `finish` to step out of it
 | 
			
		||||
 | 
			
		||||
      original_method.bind_call(self, arg0, arg1, arg2, &blk)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_method_skip_return_medium4(mod, original_method, method_sig, original_visibility, arg0_type, arg1_type, arg2_type, arg3_type)
 | 
			
		||||
    T::Private::ClassUtils.def_with_visibility(mod, method_sig.method_name, original_visibility) do |arg0, arg1, arg2, arg3, &blk|
 | 
			
		||||
      # This method is a manually sped-up version of more general code in `validate_call`
 | 
			
		||||
      unless arg0_type.valid?(arg0)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[0][1].error_message_for_obj(arg0),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[0][0],
 | 
			
		||||
          arg0_type,
 | 
			
		||||
          arg0,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg1_type.valid?(arg1)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[1][1].error_message_for_obj(arg1),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[1][0],
 | 
			
		||||
          arg1_type,
 | 
			
		||||
          arg1,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg2_type.valid?(arg2)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[2][1].error_message_for_obj(arg2),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[2][0],
 | 
			
		||||
          arg2_type,
 | 
			
		||||
          arg2,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless arg3_type.valid?(arg3)
 | 
			
		||||
        CallValidation.report_error(
 | 
			
		||||
          method_sig,
 | 
			
		||||
          method_sig.arg_types[3][1].error_message_for_obj(arg3),
 | 
			
		||||
          'Parameter',
 | 
			
		||||
          method_sig.arg_types[3][0],
 | 
			
		||||
          arg3_type,
 | 
			
		||||
          arg3,
 | 
			
		||||
          caller_offset: -1
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # The following line breaks are intentional to show nice pry message
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      # PRY note:
 | 
			
		||||
      # this code is sig validation code.
 | 
			
		||||
      # Please issue `finish` to step out of it
 | 
			
		||||
 | 
			
		||||
      original_method.bind_call(self, arg0, arg1, arg2, arg3, &blk)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.create_validator_procedure_medium(mod, original_method, method_sig, original_visibility)
 | 
			
		||||
    # trampoline to reduce stack frame size
 | 
			
		||||
    arg_types = method_sig.arg_types
 | 
			
		||||
@ -183,7 +183,7 @@ module T::Private::Methods
 | 
			
		||||
      self
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Declares valid type paramaters which can be used with `T.type_parameter` in
 | 
			
		||||
    # Declares valid type parameters which can be used with `T.type_parameter` in
 | 
			
		||||
    # this `sig`.
 | 
			
		||||
    #
 | 
			
		||||
    # This is used for generic methods. Example usage:
 | 
			
		||||
@ -245,6 +245,15 @@ class T::Private::Methods::Signature
 | 
			
		||||
    "#{@method} at #{loc}"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def force_type_init
 | 
			
		||||
    @arg_types.each {|_, type| type.build_type}
 | 
			
		||||
    @kwarg_types.each {|_, type| type.build_type}
 | 
			
		||||
    @block_type&.build_type
 | 
			
		||||
    @rest_type&.build_type
 | 
			
		||||
    @keyrest_type&.build_type
 | 
			
		||||
    @return_type.build_type
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  EMPTY_LIST = [].freeze
 | 
			
		||||
  EMPTY_HASH = {}.freeze
 | 
			
		||||
end
 | 
			
		||||
@ -262,7 +262,14 @@ module T::Private::Methods::SignatureValidation
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # return types must be covariant
 | 
			
		||||
    if !signature.return_type.subtype_of?(super_signature.return_type)
 | 
			
		||||
    super_signature_return_type = super_signature.return_type
 | 
			
		||||
 | 
			
		||||
    if super_signature_return_type == T::Private::Types::Void::Private::INSTANCE
 | 
			
		||||
      # Treat `.void` as `T.anything` (see corresponding comment in definition_valitor for more)
 | 
			
		||||
      super_signature_return_type = T::Types::Anything::Private::INSTANCE
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if !signature.return_type.subtype_of?(super_signature_return_type)
 | 
			
		||||
      raise "Incompatible return type in signature for #{mode_noun} of method `#{signature.method_name}`:\n" \
 | 
			
		||||
            "* Base: `#{super_signature.return_type}` (in #{method_loc_str(super_signature.method)})\n" \
 | 
			
		||||
            "* #{mode_noun.capitalize}: `#{signature.return_type}` (in #{method_loc_str(signature.method)})\n" \
 | 
			
		||||
@ -6,6 +6,10 @@
 | 
			
		||||
class T::Private::Types::NotTyped < T::Types::Base
 | 
			
		||||
  ERROR_MESSAGE = "Validation is being done on a `NotTyped`. Please report this bug at https://github.com/sorbet/sorbet/issues"
 | 
			
		||||
 | 
			
		||||
  def build_type
 | 
			
		||||
    nil
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # overrides Base
 | 
			
		||||
  def name
 | 
			
		||||
    "<NOT-TYPED>"
 | 
			
		||||
@ -9,6 +9,10 @@ class T::Private::Types::StringHolder < T::Types::Base
 | 
			
		||||
    @string = string
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def build_type
 | 
			
		||||
    nil
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # overrides Base
 | 
			
		||||
  def name
 | 
			
		||||
    string
 | 
			
		||||
@ -9,6 +9,10 @@ module T::Private::Types
 | 
			
		||||
      @callable = callable
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def build_type
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def aliased_type
 | 
			
		||||
      @aliased_type ||= T::Utils.coerce(@callable.call)
 | 
			
		||||
    end
 | 
			
		||||
@ -18,6 +18,10 @@ module T::Private::Types
 | 
			
		||||
      freeze
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def build_type
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      "<VOID>"
 | 
			
		||||
@ -139,9 +139,9 @@ module T::Props
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      if cls_or_args.is_a?(Hash)
 | 
			
		||||
        self.prop(name, **cls_or_args.merge(immutable: true))
 | 
			
		||||
        self.prop(name, cls_or_args.merge(immutable: true))
 | 
			
		||||
      else
 | 
			
		||||
        self.prop(name, cls_or_args, **args.merge(immutable: true))
 | 
			
		||||
        self.prop(name, cls_or_args, args.merge(immutable: true))
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@ -100,10 +100,7 @@ class T::Props::Decorator
 | 
			
		||||
  # checked(:never) - potentially O(prop accesses) depending on usage pattern
 | 
			
		||||
  sig {params(prop: Symbol, val: T.untyped).void.checked(:never)}
 | 
			
		||||
  def validate_prop_value(prop, val)
 | 
			
		||||
    # We call `setter_proc` here without binding to an instance, so it'll run
 | 
			
		||||
    # `instance_variable_set` if validation passes, but nothing will care.
 | 
			
		||||
    # We only care about the validation.
 | 
			
		||||
    prop_rules(prop).fetch(:setter_proc).call(val)
 | 
			
		||||
    prop_rules(prop).fetch(:value_validate_proc).call(val)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # For performance, don't use named params here.
 | 
			
		||||
@ -335,7 +332,7 @@ class T::Props::Decorator
 | 
			
		||||
 | 
			
		||||
    prop_validate_definition!(name, cls, rules, type_object)
 | 
			
		||||
 | 
			
		||||
    # Retrive the possible underlying object with T.nilable.
 | 
			
		||||
    # Retrieve the possible underlying object with T.nilable.
 | 
			
		||||
    type = T::Utils::Nilable.get_underlying_type(type)
 | 
			
		||||
 | 
			
		||||
    rules_sensitivity = rules[:sensitivity]
 | 
			
		||||
@ -378,7 +375,11 @@ class T::Props::Decorator
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    rules[:setter_proc] = T::Props::Private::SetterFactory.build_setter_proc(@class, name, rules).freeze
 | 
			
		||||
    setter_proc, value_validate_proc = T::Props::Private::SetterFactory.build_setter_proc(@class, name, rules)
 | 
			
		||||
    setter_proc.freeze
 | 
			
		||||
    value_validate_proc.freeze
 | 
			
		||||
    rules[:setter_proc] = setter_proc
 | 
			
		||||
    rules[:value_validate_proc] = value_validate_proc
 | 
			
		||||
 | 
			
		||||
    add_prop_definition(name, rules)
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,257 @@
 | 
			
		||||
# frozen_string_literal: true
 | 
			
		||||
# typed: strict
 | 
			
		||||
 | 
			
		||||
module T::Props
 | 
			
		||||
  module Private
 | 
			
		||||
    module SetterFactory
 | 
			
		||||
      extend T::Sig
 | 
			
		||||
 | 
			
		||||
      SetterProc = T.type_alias {T.proc.params(val: T.untyped).void}
 | 
			
		||||
      ValueValidationProc = T.type_alias {T.proc.params(val: T.untyped).void}
 | 
			
		||||
      ValidateProc = T.type_alias {T.proc.params(prop: Symbol, value: T.untyped).void}
 | 
			
		||||
 | 
			
		||||
      sig do
 | 
			
		||||
        params(
 | 
			
		||||
          klass: T.all(Module, T::Props::ClassMethods),
 | 
			
		||||
          prop: Symbol,
 | 
			
		||||
          rules: T::Hash[Symbol, T.untyped]
 | 
			
		||||
        )
 | 
			
		||||
        .returns([SetterProc, ValueValidationProc])
 | 
			
		||||
        .checked(:never)
 | 
			
		||||
      end
 | 
			
		||||
      def self.build_setter_proc(klass, prop, rules)
 | 
			
		||||
        # Our nil check works differently than a simple T.nilable for various
 | 
			
		||||
        # reasons (including the `raise_on_nil_write` setting and the existence
 | 
			
		||||
        # of defaults & factories), so unwrap any T.nilable and do a check
 | 
			
		||||
        # manually.
 | 
			
		||||
        non_nil_type = T::Utils::Nilable.get_underlying_type_object(rules.fetch(:type_object))
 | 
			
		||||
        accessor_key = rules.fetch(:accessor_key)
 | 
			
		||||
        validate = rules[:setter_validate]
 | 
			
		||||
 | 
			
		||||
        # It seems like a bug that this affects the behavior of setters, but
 | 
			
		||||
        # some existing code relies on this behavior
 | 
			
		||||
        has_explicit_nil_default = rules.key?(:default) && rules.fetch(:default).nil?
 | 
			
		||||
 | 
			
		||||
        # Use separate methods in order to ensure that we only close over necessary
 | 
			
		||||
        # variables
 | 
			
		||||
        if !T::Props::Utils.need_nil_write_check?(rules) || has_explicit_nil_default
 | 
			
		||||
          if validate.nil? && non_nil_type.is_a?(T::Types::Simple)
 | 
			
		||||
            simple_nilable_proc(prop, accessor_key, non_nil_type.raw_type, klass)
 | 
			
		||||
          else
 | 
			
		||||
            nilable_proc(prop, accessor_key, non_nil_type, klass, validate)
 | 
			
		||||
          end
 | 
			
		||||
        else
 | 
			
		||||
          if validate.nil? && non_nil_type.is_a?(T::Types::Simple)
 | 
			
		||||
            simple_non_nil_proc(prop, accessor_key, non_nil_type.raw_type, klass)
 | 
			
		||||
          else
 | 
			
		||||
            non_nil_proc(prop, accessor_key, non_nil_type, klass, validate)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      sig do
 | 
			
		||||
        params(
 | 
			
		||||
          prop: Symbol,
 | 
			
		||||
          accessor_key: Symbol,
 | 
			
		||||
          non_nil_type: Module,
 | 
			
		||||
          klass: T.all(Module, T::Props::ClassMethods),
 | 
			
		||||
        )
 | 
			
		||||
        .returns([SetterProc, ValueValidationProc])
 | 
			
		||||
      end
 | 
			
		||||
      private_class_method def self.simple_non_nil_proc(prop, accessor_key, non_nil_type, klass)
 | 
			
		||||
        [
 | 
			
		||||
          proc do |val|
 | 
			
		||||
            unless val.is_a?(non_nil_type)
 | 
			
		||||
              T::Props::Private::SetterFactory.raise_pretty_error(
 | 
			
		||||
                klass,
 | 
			
		||||
                prop,
 | 
			
		||||
                T::Utils.coerce(non_nil_type),
 | 
			
		||||
                val,
 | 
			
		||||
              )
 | 
			
		||||
            end
 | 
			
		||||
            instance_variable_set(accessor_key, val)
 | 
			
		||||
          end,
 | 
			
		||||
          proc do |val|
 | 
			
		||||
            unless val.is_a?(non_nil_type)
 | 
			
		||||
              T::Props::Private::SetterFactory.raise_pretty_error(
 | 
			
		||||
                klass,
 | 
			
		||||
                prop,
 | 
			
		||||
                T::Utils.coerce(non_nil_type),
 | 
			
		||||
                val,
 | 
			
		||||
              )
 | 
			
		||||
            end
 | 
			
		||||
          end,
 | 
			
		||||
        ]
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      sig do
 | 
			
		||||
        params(
 | 
			
		||||
          prop: Symbol,
 | 
			
		||||
          accessor_key: Symbol,
 | 
			
		||||
          non_nil_type: T::Types::Base,
 | 
			
		||||
          klass: T.all(Module, T::Props::ClassMethods),
 | 
			
		||||
          validate: T.nilable(ValidateProc)
 | 
			
		||||
        )
 | 
			
		||||
        .returns([SetterProc, ValueValidationProc])
 | 
			
		||||
      end
 | 
			
		||||
      private_class_method def self.non_nil_proc(prop, accessor_key, non_nil_type, klass, validate)
 | 
			
		||||
        [
 | 
			
		||||
          proc do |val|
 | 
			
		||||
            # this use of recursively_valid? is intentional: unlike for
 | 
			
		||||
            # methods, we want to make sure data at the 'edge'
 | 
			
		||||
            # (e.g. models that go into databases or structs serialized
 | 
			
		||||
            # from disk) are correct, so we use more thorough runtime
 | 
			
		||||
            # checks there
 | 
			
		||||
            if non_nil_type.recursively_valid?(val)
 | 
			
		||||
              validate&.call(prop, val)
 | 
			
		||||
            else
 | 
			
		||||
              T::Props::Private::SetterFactory.raise_pretty_error(
 | 
			
		||||
                klass,
 | 
			
		||||
                prop,
 | 
			
		||||
                non_nil_type,
 | 
			
		||||
                val,
 | 
			
		||||
              )
 | 
			
		||||
            end
 | 
			
		||||
            instance_variable_set(accessor_key, val)
 | 
			
		||||
          end,
 | 
			
		||||
          proc do |val|
 | 
			
		||||
            # this use of recursively_valid? is intentional: unlike for
 | 
			
		||||
            # methods, we want to make sure data at the 'edge'
 | 
			
		||||
            # (e.g. models that go into databases or structs serialized
 | 
			
		||||
            # from disk) are correct, so we use more thorough runtime
 | 
			
		||||
            # checks there
 | 
			
		||||
            if non_nil_type.recursively_valid?(val)
 | 
			
		||||
              validate&.call(prop, val)
 | 
			
		||||
            else
 | 
			
		||||
              T::Props::Private::SetterFactory.raise_pretty_error(
 | 
			
		||||
                klass,
 | 
			
		||||
                prop,
 | 
			
		||||
                non_nil_type,
 | 
			
		||||
                val,
 | 
			
		||||
              )
 | 
			
		||||
            end
 | 
			
		||||
          end,
 | 
			
		||||
        ]
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      sig do
 | 
			
		||||
        params(
 | 
			
		||||
          prop: Symbol,
 | 
			
		||||
          accessor_key: Symbol,
 | 
			
		||||
          non_nil_type: Module,
 | 
			
		||||
          klass: T.all(Module, T::Props::ClassMethods),
 | 
			
		||||
        )
 | 
			
		||||
        .returns([SetterProc, ValueValidationProc])
 | 
			
		||||
      end
 | 
			
		||||
      private_class_method def self.simple_nilable_proc(prop, accessor_key, non_nil_type, klass)
 | 
			
		||||
        [
 | 
			
		||||
          proc do |val|
 | 
			
		||||
            unless val.nil? || val.is_a?(non_nil_type)
 | 
			
		||||
              T::Props::Private::SetterFactory.raise_pretty_error(
 | 
			
		||||
                klass,
 | 
			
		||||
                prop,
 | 
			
		||||
                T::Utils.coerce(non_nil_type),
 | 
			
		||||
                val,
 | 
			
		||||
              )
 | 
			
		||||
            end
 | 
			
		||||
            instance_variable_set(accessor_key, val)
 | 
			
		||||
          end,
 | 
			
		||||
          proc do |val|
 | 
			
		||||
            unless val.nil? || val.is_a?(non_nil_type)
 | 
			
		||||
              T::Props::Private::SetterFactory.raise_pretty_error(
 | 
			
		||||
                klass,
 | 
			
		||||
                prop,
 | 
			
		||||
                T::Utils.coerce(non_nil_type),
 | 
			
		||||
                val,
 | 
			
		||||
              )
 | 
			
		||||
            end
 | 
			
		||||
          end,
 | 
			
		||||
        ]
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      sig do
 | 
			
		||||
        params(
 | 
			
		||||
          prop: Symbol,
 | 
			
		||||
          accessor_key: Symbol,
 | 
			
		||||
          non_nil_type: T::Types::Base,
 | 
			
		||||
          klass: T.all(Module, T::Props::ClassMethods),
 | 
			
		||||
          validate: T.nilable(ValidateProc),
 | 
			
		||||
        )
 | 
			
		||||
        .returns([SetterProc, ValueValidationProc])
 | 
			
		||||
      end
 | 
			
		||||
      private_class_method def self.nilable_proc(prop, accessor_key, non_nil_type, klass, validate)
 | 
			
		||||
        [
 | 
			
		||||
          proc do |val|
 | 
			
		||||
            if val.nil?
 | 
			
		||||
              instance_variable_set(accessor_key, nil)
 | 
			
		||||
            # this use of recursively_valid? is intentional: unlike for
 | 
			
		||||
            # methods, we want to make sure data at the 'edge'
 | 
			
		||||
            # (e.g. models that go into databases or structs serialized
 | 
			
		||||
            # from disk) are correct, so we use more thorough runtime
 | 
			
		||||
            # checks there
 | 
			
		||||
            elsif non_nil_type.recursively_valid?(val)
 | 
			
		||||
              validate&.call(prop, val)
 | 
			
		||||
              instance_variable_set(accessor_key, val)
 | 
			
		||||
            else
 | 
			
		||||
              T::Props::Private::SetterFactory.raise_pretty_error(
 | 
			
		||||
                klass,
 | 
			
		||||
                prop,
 | 
			
		||||
                non_nil_type,
 | 
			
		||||
                val,
 | 
			
		||||
              )
 | 
			
		||||
              instance_variable_set(accessor_key, val)
 | 
			
		||||
            end
 | 
			
		||||
          end,
 | 
			
		||||
          proc do |val|
 | 
			
		||||
            if val.nil?
 | 
			
		||||
            # this use of recursively_valid? is intentional: unlike for
 | 
			
		||||
            # methods, we want to make sure data at the 'edge'
 | 
			
		||||
            # (e.g. models that go into databases or structs serialized
 | 
			
		||||
            # from disk) are correct, so we use more thorough runtime
 | 
			
		||||
            # checks there
 | 
			
		||||
            elsif non_nil_type.recursively_valid?(val)
 | 
			
		||||
              validate&.call(prop, val)
 | 
			
		||||
            else
 | 
			
		||||
              T::Props::Private::SetterFactory.raise_pretty_error(
 | 
			
		||||
                klass,
 | 
			
		||||
                prop,
 | 
			
		||||
                non_nil_type,
 | 
			
		||||
                val,
 | 
			
		||||
              )
 | 
			
		||||
            end
 | 
			
		||||
          end,
 | 
			
		||||
        ]
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      sig do
 | 
			
		||||
        params(
 | 
			
		||||
          klass: T.all(Module, T::Props::ClassMethods),
 | 
			
		||||
          prop: Symbol,
 | 
			
		||||
          type: T.any(T::Types::Base, Module),
 | 
			
		||||
          val: T.untyped,
 | 
			
		||||
        )
 | 
			
		||||
        .void
 | 
			
		||||
      end
 | 
			
		||||
      def self.raise_pretty_error(klass, prop, type, val)
 | 
			
		||||
        base_message = "Can't set #{klass.name}.#{prop} to #{val.inspect} (instance of #{val.class}) - need a #{type}"
 | 
			
		||||
 | 
			
		||||
        pretty_message = "Parameter '#{prop}': #{base_message}\n"
 | 
			
		||||
        caller_loc = caller_locations.find {|l| !l.to_s.include?('sorbet-runtime/lib/types/props')}
 | 
			
		||||
        if caller_loc
 | 
			
		||||
          pretty_message += "Caller: #{caller_loc.path}:#{caller_loc.lineno}\n"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        T::Configuration.call_validation_error_handler(
 | 
			
		||||
          nil,
 | 
			
		||||
          message: base_message,
 | 
			
		||||
          pretty_message: pretty_message,
 | 
			
		||||
          kind: 'Parameter',
 | 
			
		||||
          name: prop,
 | 
			
		||||
          type: type,
 | 
			
		||||
          value: val,
 | 
			
		||||
          location: caller_loc,
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
@ -6,6 +6,10 @@ module T::Types
 | 
			
		||||
  class Anything < Base
 | 
			
		||||
    def initialize; end
 | 
			
		||||
 | 
			
		||||
    def build_type
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      "T.anything"
 | 
			
		||||
@ -10,6 +10,10 @@ module T::Types
 | 
			
		||||
 | 
			
		||||
    def initialize(); end
 | 
			
		||||
 | 
			
		||||
    def build_type
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      "T.attached_class"
 | 
			
		||||
@ -33,6 +33,12 @@ module T::Types
 | 
			
		||||
      raise NotImplementedError
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Force any lazy initialization that this type might need to do
 | 
			
		||||
    # It's unusual to call this directly; you probably want to call it indirectly via `T::Utils.run_all_sig_blocks`.
 | 
			
		||||
    def build_type
 | 
			
		||||
      raise NotImplementedError
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Equality is based on name, so be sure the name reflects all relevant state when implementing.
 | 
			
		||||
    def name
 | 
			
		||||
      raise NotImplementedError
 | 
			
		||||
@ -10,6 +10,10 @@ module T::Types
 | 
			
		||||
      @type = type
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def build_type
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      "T.class_of(#{@type})"
 | 
			
		||||
@ -12,6 +12,10 @@ module T::Types
 | 
			
		||||
      @values = values
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def build_type
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def valid?(obj)
 | 
			
		||||
      @values.member?(obj)
 | 
			
		||||
@ -6,23 +6,30 @@ module T::Types
 | 
			
		||||
  # Takes a list of types. Validates each item in an array using the type in the same position
 | 
			
		||||
  # in the list.
 | 
			
		||||
  class FixedArray < Base
 | 
			
		||||
    attr_reader :types
 | 
			
		||||
 | 
			
		||||
    def initialize(types)
 | 
			
		||||
      @types = types.map {|type| T::Utils.coerce(type)}
 | 
			
		||||
      @inner_types = types
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def types
 | 
			
		||||
      @types ||= @inner_types.map {|type| T::Utils.coerce(type)}
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def build_type
 | 
			
		||||
      types
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      "[#{@types.join(', ')}]"
 | 
			
		||||
      "[#{types.join(', ')}]"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def recursively_valid?(obj)
 | 
			
		||||
      if obj.is_a?(Array) && obj.length == @types.length
 | 
			
		||||
      if obj.is_a?(Array) && obj.length == types.length
 | 
			
		||||
        i = 0
 | 
			
		||||
        while i < @types.length
 | 
			
		||||
          if !@types[i].recursively_valid?(obj[i])
 | 
			
		||||
        while i < types.length
 | 
			
		||||
          if !types[i].recursively_valid?(obj[i])
 | 
			
		||||
            return false
 | 
			
		||||
          end
 | 
			
		||||
          i += 1
 | 
			
		||||
@ -35,10 +42,10 @@ module T::Types
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def valid?(obj)
 | 
			
		||||
      if obj.is_a?(Array) && obj.length == @types.length
 | 
			
		||||
      if obj.is_a?(Array) && obj.length == types.length
 | 
			
		||||
        i = 0
 | 
			
		||||
        while i < @types.length
 | 
			
		||||
          if !@types[i].valid?(obj[i])
 | 
			
		||||
        while i < types.length
 | 
			
		||||
          if !types[i].valid?(obj[i])
 | 
			
		||||
            return false
 | 
			
		||||
          end
 | 
			
		||||
          i += 1
 | 
			
		||||
@ -56,7 +63,7 @@ module T::Types
 | 
			
		||||
        # Properly speaking, covariance here is unsound since arrays
 | 
			
		||||
        # can be mutated, but sorbet implements covariant tuples for
 | 
			
		||||
        # ease of adoption.
 | 
			
		||||
        @types.size == other.types.size && @types.zip(other.types).all? do |t1, t2|
 | 
			
		||||
        types.size == other.types.size && types.zip(other.types).all? do |t1, t2|
 | 
			
		||||
          t1.subtype_of?(t2)
 | 
			
		||||
        end
 | 
			
		||||
      when TypedArray
 | 
			
		||||
@ -85,7 +92,7 @@ module T::Types
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def describe_obj(obj)
 | 
			
		||||
      if obj.is_a?(Array)
 | 
			
		||||
        if obj.length == @types.length
 | 
			
		||||
        if obj.length == types.length
 | 
			
		||||
          item_classes = obj.map(&:class).join(', ')
 | 
			
		||||
          "type [#{item_classes}]"
 | 
			
		||||
        else
 | 
			
		||||
@ -5,30 +5,37 @@ module T::Types
 | 
			
		||||
  # Takes a hash of types. Validates each item in a hash using the type in the same position
 | 
			
		||||
  # in the list.
 | 
			
		||||
  class FixedHash < Base
 | 
			
		||||
    attr_reader :types
 | 
			
		||||
 | 
			
		||||
    def initialize(types)
 | 
			
		||||
      @types = types.transform_values {|v| T::Utils.coerce(v)}
 | 
			
		||||
      @inner_types = types
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def types
 | 
			
		||||
      @types ||= @inner_types.transform_values {|v| T::Utils.coerce(v)}
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def build_type
 | 
			
		||||
      types
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      serialize_hash(@types)
 | 
			
		||||
      serialize_hash(types)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def recursively_valid?(obj)
 | 
			
		||||
      return false unless obj.is_a?(Hash)
 | 
			
		||||
      return false if @types.any? {|key, type| !type.recursively_valid?(obj[key])}
 | 
			
		||||
      return false if obj.any? {|key, _| !@types[key]}
 | 
			
		||||
      return false if types.any? {|key, type| !type.recursively_valid?(obj[key])}
 | 
			
		||||
      return false if obj.any? {|key, _| !types[key]}
 | 
			
		||||
      true
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def valid?(obj)
 | 
			
		||||
      return false unless obj.is_a?(Hash)
 | 
			
		||||
      return false if @types.any? {|key, type| !type.valid?(obj[key])}
 | 
			
		||||
      return false if obj.any? {|key, _| !@types[key]}
 | 
			
		||||
      return false if types.any? {|key, type| !type.valid?(obj[key])}
 | 
			
		||||
      return false if obj.any? {|key, _| !types[key]}
 | 
			
		||||
      true
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@ -37,7 +44,7 @@ module T::Types
 | 
			
		||||
      case other
 | 
			
		||||
      when FixedHash
 | 
			
		||||
        # Using `subtype_of?` here instead of == would be unsound
 | 
			
		||||
        @types == other.types
 | 
			
		||||
        types == other.types
 | 
			
		||||
      when TypedHash
 | 
			
		||||
        # warning: covariant hashes
 | 
			
		||||
 | 
			
		||||
@ -4,10 +4,12 @@
 | 
			
		||||
module T::Types
 | 
			
		||||
  # Takes a list of types. Validates that an object matches all of the types.
 | 
			
		||||
  class Intersection < Base
 | 
			
		||||
    attr_reader :types
 | 
			
		||||
 | 
			
		||||
    def initialize(types)
 | 
			
		||||
      @types = types.flat_map do |type|
 | 
			
		||||
      @inner_types = types
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def types
 | 
			
		||||
      @types ||= @inner_types.flat_map do |type|
 | 
			
		||||
        type = T::Utils.resolve_alias(type)
 | 
			
		||||
        if type.is_a?(Intersection)
 | 
			
		||||
          # Simplify nested intersections (mostly so `name` returns a nicer value)
 | 
			
		||||
@ -18,19 +20,24 @@ module T::Types
 | 
			
		||||
      end.uniq
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def build_type
 | 
			
		||||
      types
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      "T.all(#{@types.map(&:name).compact.sort.join(', ')})"
 | 
			
		||||
      "T.all(#{types.map(&:name).compact.sort.join(', ')})"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def recursively_valid?(obj)
 | 
			
		||||
      @types.all? {|type| type.recursively_valid?(obj)}
 | 
			
		||||
      types.all? {|type| type.recursively_valid?(obj)}
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def valid?(obj)
 | 
			
		||||
      @types.all? {|type| type.valid?(obj)}
 | 
			
		||||
      types.all? {|type| type.valid?(obj)}
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
@ -6,6 +6,10 @@ module T::Types
 | 
			
		||||
  class NoReturn < Base
 | 
			
		||||
    def initialize; end
 | 
			
		||||
 | 
			
		||||
    def build_type
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      "T.noreturn"
 | 
			
		||||
@ -8,21 +8,31 @@ module T::Types
 | 
			
		||||
  # At present, we only support fixed-arity procs with no optional or
 | 
			
		||||
  # keyword arguments.
 | 
			
		||||
  class Proc < Base
 | 
			
		||||
    attr_reader :arg_types
 | 
			
		||||
    attr_reader :returns
 | 
			
		||||
 | 
			
		||||
    def initialize(arg_types, returns)
 | 
			
		||||
      @arg_types = {}
 | 
			
		||||
      arg_types.each do |key, raw_type|
 | 
			
		||||
        @arg_types[key] = T::Utils.coerce(raw_type)
 | 
			
		||||
      end
 | 
			
		||||
      @returns = T::Utils.coerce(returns)
 | 
			
		||||
      @inner_arg_types = arg_types
 | 
			
		||||
      @inner_returns = returns
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def arg_types
 | 
			
		||||
      @arg_types ||= @inner_arg_types.map do |key, raw_type|
 | 
			
		||||
        [key, T::Utils.coerce(raw_type)]
 | 
			
		||||
      end.to_h
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def returns
 | 
			
		||||
      @returns ||= T::Utils.coerce(@inner_returns)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def build_type
 | 
			
		||||
      arg_types
 | 
			
		||||
      returns
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      args = []
 | 
			
		||||
      @arg_types.each do |k, v|
 | 
			
		||||
      arg_types.each do |k, v|
 | 
			
		||||
        args << "#{k}: #{v.name}"
 | 
			
		||||
      end
 | 
			
		||||
      "T.proc.params(#{args.join(', ')}).returns(#{returns})"
 | 
			
		||||
@ -8,6 +8,10 @@ module T::Types
 | 
			
		||||
 | 
			
		||||
    def initialize(); end
 | 
			
		||||
 | 
			
		||||
    def build_type
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      "T.self_type"
 | 
			
		||||
@ -13,6 +13,10 @@ module T::Types
 | 
			
		||||
      @raw_type = raw_type
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def build_type
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      # Memoize to mitigate pathological performance with anonymous modules (https://bugs.ruby-lang.org/issues/11119)
 | 
			
		||||
@ -10,6 +10,10 @@ module T::Types
 | 
			
		||||
      @val = val
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def build_type
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      # Strips the #<...> off, just leaving the ...
 | 
			
		||||
@ -20,6 +20,10 @@ module T::Types
 | 
			
		||||
      @name = name
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def build_type
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def self.make(name)
 | 
			
		||||
      cached = Private.cached_entry(name)
 | 
			
		||||
      return cached if cached
 | 
			
		||||
@ -19,6 +19,10 @@ module T::Types
 | 
			
		||||
      @variance = variance
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def build_type
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def valid?(obj)
 | 
			
		||||
      true
 | 
			
		||||
    end
 | 
			
		||||
@ -5,7 +5,7 @@ module T::Types
 | 
			
		||||
  class TypedArray < TypedEnumerable
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      "T::Array[#{@type.name}]"
 | 
			
		||||
      "T::Array[#{type.name}]"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def underlying_class
 | 
			
		||||
@ -60,6 +60,11 @@ module T::Types
 | 
			
		||||
        obj.is_a?(Array)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def freeze
 | 
			
		||||
        build_type # force lazy initialization before freezing the object
 | 
			
		||||
        super
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      module Private
 | 
			
		||||
        INSTANCE = Untyped.new.freeze
 | 
			
		||||
      end
 | 
			
		||||
@ -3,15 +3,22 @@
 | 
			
		||||
 | 
			
		||||
module T::Types
 | 
			
		||||
  class TypedClass < T::Types::Base
 | 
			
		||||
    attr_reader :type
 | 
			
		||||
 | 
			
		||||
    def initialize(type)
 | 
			
		||||
      @type = T::Utils.coerce(type)
 | 
			
		||||
      @inner_type = type
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def type
 | 
			
		||||
      @type ||= T::Utils.coerce(@inner_type)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def build_type
 | 
			
		||||
      type
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      "T::Class[#{@type.name}]"
 | 
			
		||||
      "T::Class[#{type.name}]"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def underlying_class
 | 
			
		||||
@ -67,6 +74,11 @@ module T::Types
 | 
			
		||||
        super(T.untyped)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def freeze
 | 
			
		||||
        build_type # force lazy initialization before freezing the object
 | 
			
		||||
        super
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      module Private
 | 
			
		||||
        INSTANCE = Untyped.new.freeze
 | 
			
		||||
      end
 | 
			
		||||
@ -77,6 +89,11 @@ module T::Types
 | 
			
		||||
        super(T.anything)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def freeze
 | 
			
		||||
        build_type # force lazy initialization before freezing the object
 | 
			
		||||
        super
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      module Private
 | 
			
		||||
        INSTANCE = Anything.new.freeze
 | 
			
		||||
      end
 | 
			
		||||
@ -6,10 +6,17 @@ module T::Types
 | 
			
		||||
  # `case` statement below in `describe_obj` in order to get better
 | 
			
		||||
  # error messages.
 | 
			
		||||
  class TypedEnumerable < Base
 | 
			
		||||
    attr_reader :type
 | 
			
		||||
 | 
			
		||||
    def initialize(type)
 | 
			
		||||
      @type = T::Utils.coerce(type)
 | 
			
		||||
      @inner_type = type
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def type
 | 
			
		||||
      @type ||= T::Utils.coerce(@inner_type)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def build_type
 | 
			
		||||
      type
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def underlying_class
 | 
			
		||||
@ -18,7 +25,7 @@ module T::Types
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      "T::Enumerable[#{@type.name}]"
 | 
			
		||||
      "T::Enumerable[#{type.name}]"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
@ -34,20 +41,20 @@ module T::Types
 | 
			
		||||
        begin
 | 
			
		||||
          it = 0
 | 
			
		||||
          while it < obj.count
 | 
			
		||||
            return false unless @type.recursively_valid?(obj[it])
 | 
			
		||||
            return false unless type.recursively_valid?(obj[it])
 | 
			
		||||
            it += 1
 | 
			
		||||
          end
 | 
			
		||||
          true
 | 
			
		||||
        end
 | 
			
		||||
      when Hash
 | 
			
		||||
        return false unless @type.is_a?(FixedArray)
 | 
			
		||||
        types = @type.types
 | 
			
		||||
        return false unless type.is_a?(FixedArray)
 | 
			
		||||
        types = type.types
 | 
			
		||||
        return false if types.count != 2
 | 
			
		||||
        key_type = types[0]
 | 
			
		||||
        value_type = types[1]
 | 
			
		||||
        obj.each_pair do |key, val|
 | 
			
		||||
          # Some objects (I'm looking at you Rack::Utils::HeaderHash) don't
 | 
			
		||||
          # iterate over a [key, value] array, so we can't juse use the @type.recursively_valid?(v)
 | 
			
		||||
          # iterate over a [key, value] array, so we can't just use the type.recursively_valid?(v)
 | 
			
		||||
          return false if !key_type.recursively_valid?(key) || !value_type.recursively_valid?(val)
 | 
			
		||||
        end
 | 
			
		||||
        true
 | 
			
		||||
@ -65,10 +72,10 @@ module T::Types
 | 
			
		||||
        # boundlessness, it does not express a type. For example `(nil...nil)` is not a T::Range[NilClass], its a range
 | 
			
		||||
        # of unknown types (T::Range[T.untyped]).
 | 
			
		||||
        # Similarly, `(nil...1)` is not a `T::Range[T.nilable(Integer)]`, it's a boundless range of Integer.
 | 
			
		||||
        (obj.begin.nil? || @type.recursively_valid?(obj.begin)) && (obj.end.nil? || @type.recursively_valid?(obj.end))
 | 
			
		||||
        (obj.begin.nil? || type.recursively_valid?(obj.begin)) && (obj.end.nil? || type.recursively_valid?(obj.end))
 | 
			
		||||
      when Set
 | 
			
		||||
        obj.each do |item|
 | 
			
		||||
          return false unless @type.recursively_valid?(item)
 | 
			
		||||
          return false unless type.recursively_valid?(item)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        true
 | 
			
		||||
@ -90,7 +97,7 @@ module T::Types
 | 
			
		||||
        # should be invariant because they are mutable and support
 | 
			
		||||
        # both reading and writing. However, Sorbet treats *all*
 | 
			
		||||
        # Enumerable subclasses as covariant for ease of adoption.
 | 
			
		||||
        @type.subtype_of?(other.type)
 | 
			
		||||
        type.subtype_of?(other.type)
 | 
			
		||||
      elsif other.class <= Simple
 | 
			
		||||
        underlying_class <= other.raw_type
 | 
			
		||||
      else
 | 
			
		||||
@ -3,15 +3,13 @@
 | 
			
		||||
 | 
			
		||||
module T::Types
 | 
			
		||||
  class TypedEnumerator < TypedEnumerable
 | 
			
		||||
    attr_reader :type
 | 
			
		||||
 | 
			
		||||
    def underlying_class
 | 
			
		||||
      Enumerator
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      "T::Enumerator[#{@type.name}]"
 | 
			
		||||
      "T::Enumerator[#{type.name}]"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
@ -3,15 +3,13 @@
 | 
			
		||||
 | 
			
		||||
module T::Types
 | 
			
		||||
  class TypedEnumeratorChain < TypedEnumerable
 | 
			
		||||
    attr_reader :type
 | 
			
		||||
 | 
			
		||||
    def underlying_class
 | 
			
		||||
      Enumerator::Chain
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      "T::Enumerator::Chain[#{@type.name}]"
 | 
			
		||||
      "T::Enumerator::Chain[#{type.name}]"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
@ -3,15 +3,13 @@
 | 
			
		||||
 | 
			
		||||
module T::Types
 | 
			
		||||
  class TypedEnumeratorLazy < TypedEnumerable
 | 
			
		||||
    attr_reader :type
 | 
			
		||||
 | 
			
		||||
    def underlying_class
 | 
			
		||||
      Enumerator::Lazy
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      "T::Enumerator::Lazy[#{@type.name}]"
 | 
			
		||||
      "T::Enumerator::Lazy[#{type.name}]"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
@ -3,22 +3,32 @@
 | 
			
		||||
 | 
			
		||||
module T::Types
 | 
			
		||||
  class TypedHash < TypedEnumerable
 | 
			
		||||
    # Technically we don't need these, but they are a nice api
 | 
			
		||||
    attr_reader :keys, :values
 | 
			
		||||
 | 
			
		||||
    def underlying_class
 | 
			
		||||
      Hash
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def initialize(keys:, values:)
 | 
			
		||||
      @keys = T::Utils.coerce(keys)
 | 
			
		||||
      @values = T::Utils.coerce(values)
 | 
			
		||||
      @type = T::Utils.coerce([keys, values])
 | 
			
		||||
      @inner_keys = keys
 | 
			
		||||
      @inner_values = values
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Technically we don't need this, but it is a nice api
 | 
			
		||||
    def keys
 | 
			
		||||
      @keys ||= T::Utils.coerce(@inner_keys)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Technically we don't need this, but it is a nice api
 | 
			
		||||
    def values
 | 
			
		||||
      @values ||= T::Utils.coerce(@inner_values)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def type
 | 
			
		||||
      @type ||= T::Utils.coerce([keys, values])
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      "T::Hash[#{@keys.name}, #{@values.name}]"
 | 
			
		||||
      "T::Hash[#{keys.name}, #{values.name}]"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
@ -3,15 +3,13 @@
 | 
			
		||||
 | 
			
		||||
module T::Types
 | 
			
		||||
  class TypedRange < TypedEnumerable
 | 
			
		||||
    attr_reader :type
 | 
			
		||||
 | 
			
		||||
    def underlying_class
 | 
			
		||||
      Hash
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      "T::Range[#{@type.name}]"
 | 
			
		||||
      "T::Range[#{type.name}]"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
@ -3,15 +3,13 @@
 | 
			
		||||
 | 
			
		||||
module T::Types
 | 
			
		||||
  class TypedSet < TypedEnumerable
 | 
			
		||||
    attr_reader :type
 | 
			
		||||
 | 
			
		||||
    def underlying_class
 | 
			
		||||
      Hash
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      "T::Set[#{@type.name}]"
 | 
			
		||||
      "T::Set[#{type.name}]"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
@ -4,12 +4,14 @@
 | 
			
		||||
module T::Types
 | 
			
		||||
  # Takes a list of types. Validates that an object matches at least one of the types.
 | 
			
		||||
  class Union < Base
 | 
			
		||||
    attr_reader :types
 | 
			
		||||
 | 
			
		||||
    # Don't use Union.new directly, use `Private::Pool.union_of_types`
 | 
			
		||||
    # inside sorbet-runtime and `T.any` elsewhere.
 | 
			
		||||
    def initialize(types)
 | 
			
		||||
      @types = types.flat_map do |type|
 | 
			
		||||
      @inner_types = types
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def types
 | 
			
		||||
      @types ||= @inner_types.flat_map do |type|
 | 
			
		||||
        type = T::Utils.coerce(type)
 | 
			
		||||
        if type.is_a?(Union)
 | 
			
		||||
          # Simplify nested unions (mostly so `name` returns a nicer value)
 | 
			
		||||
@ -20,6 +22,11 @@ module T::Types
 | 
			
		||||
      end.uniq
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def build_type
 | 
			
		||||
      types
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      # Use the attr_reader here so we can override it in SimplePairUnion
 | 
			
		||||
@ -51,12 +58,12 @@ module T::Types
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def recursively_valid?(obj)
 | 
			
		||||
      @types.any? {|type| type.recursively_valid?(obj)}
 | 
			
		||||
      types.any? {|type| type.recursively_valid?(obj)}
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def valid?(obj)
 | 
			
		||||
      @types.any? {|type| type.valid?(obj)}
 | 
			
		||||
      types.any? {|type| type.valid?(obj)}
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
@ -7,6 +7,10 @@ module T::Types
 | 
			
		||||
 | 
			
		||||
    def initialize; end
 | 
			
		||||
 | 
			
		||||
    def build_type
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # overrides Base
 | 
			
		||||
    def name
 | 
			
		||||
      "T.untyped"
 | 
			
		||||
@ -79,8 +79,8 @@ module T::Utils
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Unwraps all the sigs.
 | 
			
		||||
  def self.run_all_sig_blocks
 | 
			
		||||
    T::Private::Methods.run_all_sig_blocks
 | 
			
		||||
  def self.run_all_sig_blocks(force_type_init: true)
 | 
			
		||||
    T::Private::Methods.run_all_sig_blocks(force_type_init: force_type_init)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Return the underlying type for a type alias. Otherwise returns type.
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user