class TypedRb::Types::TyFunction
Attributes
arity[RW]
block_type[RW]
from[RW]
min_arity[RW]
name[W]
parameters_info[RW]
to[RW]
Public Class Methods
new(from, to, parameters_info = nil, node = nil)
click to toggle source
Calls superclass method
TypedRb::Types::Type::new
# File lib/typed/types/ty_function.rb, line 9 def initialize(from, to, parameters_info = nil, node = nil) super(node) @from = from.is_a?(Array) ? from : [from] @to = to @parameters_info = parameters_info if @parameters_info.nil? @parameters_info = @from.map { |type| [:req, type] } end @arity = parse_function_arity @min_arity = parse_min_function_arity @block_type = nil end
Public Instance Methods
<=>(other)
click to toggle source
# File lib/typed/types/ty_function.rb, line 120 def <=>(other) if other.is_a?(TyFunction) # TODO: implement! raise 'Non implemented yet' else TyObject.new(Method, node) <=> other end end
apply_bindings(bindings_map)
click to toggle source
# File lib/typed/types/ty_function.rb, line 99 def apply_bindings(bindings_map) from.each_with_index do |from_type, i| if from_type.is_a?(Polymorphism::TypeVariable) from_type.apply_bindings(bindings_map) from[i] = from_type.bound if from_type.bound elsif from_type.is_a?(TyGenericSingletonObject) || from_type.is_a?(TyGenericObject) from_type.apply_bindings(bindings_map) end end if to.is_a?(Polymorphism::TypeVariable) @to = to.apply_bindings(bindings_map) @to = to.bound if to.bound elsif to.respond_to?(:apply_bindings) @to = to.apply_bindings(bindings_map) end block_type.apply_bindings(bindings_map) if block_type && block_type.generic? self end
arg_compatible?(num_args)
click to toggle source
# File lib/typed/types/ty_function.rb, line 27 def arg_compatible?(num_args) num_args >= min_arity && (arity == Float::INFINITY || arity == num_args) end
check_args_application(actual_arguments, context)
click to toggle source
# File lib/typed/types/ty_function.rb, line 49 def check_args_application(actual_arguments, context) parameters_info.each_with_index do |(require_info, arg_name), index| actual_argument = actual_arguments[index] from_type = from[index] if actual_argument.nil? && require_info != :opt error_msg = "Type error checking function '#{name}': Missing mandatory argument #{arg_name} in #{receiver_type}##{message}" fail TypeCheckError.new(error_msg, node) else unless actual_argument.nil? # opt if this is nil actual_argument_type = actual_argument.check_type(context) unless actual_argument_type.compatible?(from_type, :lt) error_message = "Type error checking function '#{name}': #{error_message} #{from_type} expected, #{argument_type} found" fail TypeCheckError.new(error_message, node) end end end end self end
compatible?(other_type, relation = :lt)
click to toggle source
(S1 -> S2) < (T1 -> T2) => T1 < S1 && S2 < T2 Contravariant in the input, covariant in the output
# File lib/typed/types/ty_function.rb, line 71 def compatible?(other_type, relation = :lt) if other_type.is_a?(TyGenericFunction) other_type.compatible?(self, relation == :lt ? :gt : :lt) elsif other_type.is_a?(TyFunction) other_from = deconstruct_from_arguments(other_type) from.each_with_index do |arg, i| other_arg = other_from[i] return false unless arg.compatible?(other_arg, :gt) end return false unless to.compatible?(other_type.to, :lt) else fail TypeCheckError.new("Type error checking function '#{name}': Comparing function type with no function type") end true end
deconstruct_from_arguments(other_type)
click to toggle source
# File lib/typed/types/ty_function.rb, line 87 def deconstruct_from_arguments(other_type) if from.size == other_type.from.size other_type.from elsif from.size > 1 && other_type.from.size == 1 && other_type.from.first.ruby_type.ancestors.include?(Pair) other_type.from.first.type_vars(recursive: false) elsif from.size > 1 && other_type.from.size == 1 && other_type.from.first.ruby_type.ancestors.include?(Array) other_type.from.first.type_vars(recursive: false) * from.size else other_type.from end end
dynamic?()
click to toggle source
# File lib/typed/types/ty_function.rb, line 35 def dynamic? false end
generic?()
click to toggle source
# File lib/typed/types/ty_function.rb, line 31 def generic? false end
name()
click to toggle source
# File lib/typed/types/ty_function.rb, line 45 def name @name || 'lambda' end
to_s()
click to toggle source
# File lib/typed/types/ty_function.rb, line 39 def to_s args = @from.map(&:to_s).join(', ') args = "#{args}, &#{block_type}" if block_type "(#{args} -> #{@to})" end
with_block_type(type)
click to toggle source
# File lib/typed/types/ty_function.rb, line 22 def with_block_type(type) @block_type = type self end
Protected Instance Methods
parse_function_arity()
click to toggle source
# File lib/typed/types/ty_function.rb, line 132 def parse_function_arity return Float::INFINITY if parameters_info.detect { |arg| arg.is_a?(Hash) && arg[:kind] == :rest } parameters_info.reject { |arg| arg.is_a?(Hash) && arg[:kind] == :block_arg }.count end
parse_min_function_arity()
click to toggle source
# File lib/typed/types/ty_function.rb, line 137 def parse_min_function_arity parameters_info.select do |arg| !(arg.is_a?(Hash) && (arg[:kind] == :rest || arg[:kind] == :block_arg )) end.count end