class TypedRb::Types::Polymorphism::TypeVariableRegister
Attributes
children[RW]
constraints[RW]
kind[RW]
parent[RW]
type_variables_register[RW]
Public Class Methods
local_var_counter()
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 9 def local_var_counter @local_var_counter ||= 0 @local_var_counter += 1 end
new(parent = nil, kind)
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 15 def initialize(parent = nil, kind) @kind = kind @parent = parent if @parent @parent.children << self @parent.children.uniq! end @children = [] @constraints = {} @type_variables_register = {} end
Public Instance Methods
add_constraint(variable_name, relation_type, type)
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 158 def add_constraint(variable_name, relation_type, type) TypedRb.log(binding, :debug, "Adding constraint #{variable_name} #{relation_type} #{type}") if type_variables_register.values.detect { |variable| variable.variable == variable_name } var_constraints = @constraints[variable_name] || [] var_constraints << [relation_type, type] @constraints[variable_name] = var_constraints elsif parent.include?(variable_name) parent.add_constraint(variable_name, relation_type, type) else key = [:local, nil, variable_name] type_variables_register[key] = TypeVariable.new(variable_name, gen_name: false) @constraints[variable_name] = [[relation_type, type]] # fail StandardError, "Cannot find variable #{variable_name} to add a constraint" end end
all_constraints()
click to toggle source
@type_variables_register code_name => type_var @constraints type_var => constraint
# File lib/typed/types/polymorphism/type_variable_register.rb, line 141 def all_constraints self_variables_constraints = @type_variables_register.values.reduce([]) do |constraints_acc, type_var| constraints_acc + type_var.constraints(self) end self_variables_constraints + (children.reject{ |r| r.kind == :module }.map(&:all_constraints).reduce(&:+) || []) end
all_variables()
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 148 def all_variables @type_variables_register.values end
bound_generic_type_var?(type_variable)
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 118 def bound_generic_type_var?(type_variable) found = type_variables_register[[:generic, false, type_variable.name]] || type_variables_register[[:generic, true, type_variable.name]] if found kind == :method || kind == :class elsif !parent.nil? parent.bound_generic_type_var?(type_variable) else false end end
clean_dynamic_bindings()
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 203 def clean_dynamic_bindings constraints.values.each do |constraint| constraint.each do |type, value| if type == :lt || type == :gt if value.is_a?(TypedRb::Types::Polymorphism::TypeVariable) value.clean_dynamic_bindings end end end end type_variables_register.values.each do |type_var| if type_var.is_a?(TypedRb::Types::Polymorphism::TypeVariable) type_var.clean_dynamic_bindings end end end
clear()
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 152 def clear @parent = nil @constraints.clear type_variables_register.clear end
clone(scope)
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 195 def clone(scope) vars = (scope == :method) ? method_var_types : class_var_types substitutions = vars.each_with_object({}) do |var_type, acc| acc[var_type.variable] = var_type.clone end [apply_type(parent, substitutions), substitutions] end
constraints_for(variable)
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 131 def constraints_for(variable) found = constraints[variable] children_found = children.map { |child_context| child_context.constraints_for(variable) }.reduce(&:+) (found || []) + (children_found || []) end
include?(variable)
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 174 def include?(variable) found = @type_variables_register.values.detect do |var| var.variable == variable end return true if found return false if parent.nil? parent.include?(variable) end
local_type_variable()
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 110 def local_type_variable var_name = "local_var_#{TypeVariableRegister.local_var_counter}" key = [:local, nil, var_name] type_var_in_registry = TypeVariable.new(var_name) type_variables_register[key] = type_var_in_registry type_var_in_registry end
print_constraints()
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 183 def print_constraints constraints.each do |(variable_name, constraints)| constraints.each do |(rel, val)| if rel == :send puts "#{variable_name} #{rel} #{val[:message]}#{val[:args].map(&:to_s).join(',')}" else puts "#{variable_name} #{rel} #{val}" end end end end
type_variable_for(type, variable, hierarchy)
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 32 def type_variable_for(type, variable, hierarchy) ensure_string(variable) upper_level = upper_class_register # we need to get a class register key = hierarchy.map do |ruby_type| [type, ruby_type, variable] end.detect do |constructed_key| upper_level.type_variables_register[constructed_key] end if key.nil? type_var = upper_level.type_variables_register[[type, hierarchy.first, variable]] if type_var.nil? new_var_name = "#{hierarchy.first}:#{variable}" type_var = if variable == :module_self ExistentialTypeVariable.new(new_var_name, :gen_name => false) else TypeVariable.new(new_var_name, :gen_name => false) end upper_level.type_variables_register[[type, hierarchy.first, variable]] = type_var type_var else type_var end else upper_level.type_variables_register[key] end end
type_variable_for_abstraction(abs_kind, variable, context)
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 83 def type_variable_for_abstraction(abs_kind, variable, context) variable = Model::GenSym.next("#{abs_kind}_ret}") if variable.nil? ensure_string(variable) key = [abs_kind.to_sym, context.context_name, variable] type_var = recursive_constraint_search(key) if type_var.nil? # don't gnerate a random fresh name for the var, use the one we're # providing new_var_name = "TV_#{context.context_name}:#{abs_kind}:#{variable}" type_var = TypeVariable.new(new_var_name, gen_name: false) type_variables_register[key] = type_var end type_var end
type_variable_for_generic_type(type_var, method = false)
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 98 def type_variable_for_generic_type(type_var, method = false) key = [:generic, method, type_var.variable] type_var_in_registry = type_variables_register[key] if type_var_in_registry type_var_in_registry else type_var_in_registry = type_var.clone type_variables_register[key] = type_var_in_registry type_var_in_registry end end
type_variable_for_global(variable)
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 59 def type_variable_for_global(variable) ensure_string(variable) upper_level = top_level_register key = [:global, nil, variable] type_var = upper_level.type_variables_register[key] if type_var.nil? type_var = TypeVariable.new(variable, :gen_name => false) upper_level.type_variables_register[key] = type_var end type_var end
type_variable_for_message(variable, message)
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 71 def type_variable_for_message(variable, message) ensure_string(variable) key = [:return, message, variable] type_var = recursive_constraint_search(key) if type_var.nil? new_var_name = "#{variable}:#{message}" type_var = TypeVariable.new(new_var_name) type_variables_register[key] = type_var end type_var end
unlink()
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 27 def unlink return if @parent.nil? @parent.children.delete(self) end
Protected Instance Methods
apply_type(parent, type_variable_mapping)
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 238 def apply_type(parent, type_variable_mapping) register = TypeVariableRegister.new(parent, kind) apply_type_to_register(register, type_variable_mapping) end
apply_type_to_register(register, type_variable_mapping)
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 243 def apply_type_to_register(register, type_variable_mapping) register.type_variables_register = type_variables_register.each_with_object({}) do |((k, i, v), var), acc| acc[[k, i, v]] = type_variable_mapping[var.variable] || var end register.constraints = rename_constraints(constraints, type_variable_mapping) register.children = children.map { |child_register| child_register.apply_type(register, type_variable_mapping) } register end
class_var_types()
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 229 def class_var_types @type_variables_register.map do |(key, value)| type = key.first if type == :instance_variable || type == :class_variable || type == :generic value end end.compact end
ensure_string(variable)
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 311 def ensure_string(variable) variable = variable.to_s if variable.is_a?(Symbol) fail StandardError, 'Variable name must be a String for register' unless variable.is_a?(String) end
method_var_types()
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 222 def method_var_types @type_variables_register.map do |(key, value)| type = key.first value if type != :instance_variable && type != :class_variable end.compact end
recursive_constraint_search(key)
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 283 def recursive_constraint_search(key) current = self found = nil while found.nil? && !current.nil? found = current.type_variables_register[key] current = current.parent unless current.nil? end found end
rename_constraints(constraints, type_variable_mapping)
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 252 def rename_constraints(constraints, type_variable_mapping) constraints.each_with_object({}) do |(variable_name, values), acc| new_variable_name = type_variable_mapping[variable_name] ? type_variable_mapping[variable_name].variable : variable_name new_values = values.map do |(rel, type)| if (rel == :send) old_return_type = type[:return] new_return_type = if old_return_type.is_a?(TypeVariable) type_variable_mapping[old_return_type.variable] ? type_variable_mapping[old_return_type.variable] : old_return_type else old_return_type end new_args = type[:args].map do |arg| if arg.is_a?(TypeVariable) type_variable_mapping[arg.variable] ? type_variable_mapping[arg.variable] : arg else arg end end [:send, { args: new_args, return: new_return_type, message: type[:message] }] else if type.is_a?(TypeVariable) && type_variable_mapping[type.variable] [rel, type_variable_mapping[type.variable]] else [rel, type] end end end acc[new_variable_name] = new_values end end
top_level_register()
click to toggle source
# File lib/typed/types/polymorphism/type_variable_register.rb, line 305 def top_level_register current = self current = current.parent while current.kind != :top_level current end
upper_class_register()
click to toggle source
We find the first registry that has been created in the context of a generic class or the top level registry if none is found. The registry can be the current one.
# File lib/typed/types/polymorphism/type_variable_register.rb, line 297 def upper_class_register current = self while current.kind != :top_level && current.kind != :class && current.kind != :module && current.kind != :sclass current = current.parent end current end