class TypedRb::Types::TyGenericSingletonObject
Attributes
local_typing_context[RW]
super_type[RW]
Public Class Methods
new(ruby_type, type_vars, super_type = nil, node = nil)
click to toggle source
Calls superclass method
# File lib/typed/types/ty_generic_singleton_object.rb, line 17 def initialize(ruby_type, type_vars, super_type = nil, node = nil) super(ruby_type, node) @super_type = super_type @type_vars = type_vars @application_count = 0 end
Public Instance Methods
apply_bindings(bindings_map)
click to toggle source
# File lib/typed/types/ty_generic_singleton_object.rb, line 98 def apply_bindings(bindings_map) type_vars(recursive: false).each_with_index do |var, _i| if var.is_a?(Polymorphism::TypeVariable) && var.bound_to_generic? var.bind(var.bound.apply_bindings(bindings_map)) elsif var.is_a?(Polymorphism::TypeVariable) var.apply_bindings(bindings_map) elsif var.is_a?(TyGenericSingletonObject) || var.is_a?(TyGenericObject) var.apply_bindings(bindings_map) end end self end
as_object_type()
click to toggle source
# File lib/typed/types/ty_generic_singleton_object.rb, line 87 def as_object_type # this should only be used to check the body type of this # class. The variables are going to be unbound. # This is also used in instantiation of the generic object. TyGenericObject.new(ruby_type, @type_vars) end
clone()
click to toggle source
# File lib/typed/types/ty_generic_singleton_object.rb, line 111 def clone cloned_type_vars = type_vars.map(&:clone) TyGenericSingletonObject.new(ruby_type, cloned_type_vars, super_type, node) end
compute_minimal_typing_context()
click to toggle source
# File lib/typed/types/ty_generic_singleton_object.rb, line 94 def compute_minimal_typing_context Model::TmClass.with_fresh_bindings(self, nil, node) end
find_function_type(message, num_args, block)
click to toggle source
This object has concrete type parameters The generic Function we retrieve from the registry might be generic If it is generic we apply the bound parameters and we obtain a concrete function type
Calls superclass method
# File lib/typed/types/ty_generic_singleton_object.rb, line 119 def find_function_type(message, num_args, block) function_klass_type, function_type = super(message, num_args, block) if function_klass_type != ruby_type && ancestor_of_super_type?(generic_singleton_object.super_type, function_klass_type) target_class = ancestor_of_super_type?(generic_singleton_object.super_type, function_klass_type) TypedRb.log binding, :debug, "Found message '#{message}', generic function: #{function_type}, explicit super type #{target_class}" target_type_vars = target_class.type_vars materialize_super_type_found_function(message, num_args, block, target_class, target_type_vars) elsif function_klass_type != ruby_type && BasicObject::TypeRegistry.find_generic_type(function_klass_type) TypedRb.log binding, :debug, "Found message '#{message}', generic function: #{function_type}, implict super type #{function_klass_type}" target_class = BasicObject::TypeRegistry.find_generic_type(function_klass_type) materialize_super_type_found_function(message, num_args, block, target_class, type_vars) else TypedRb.log binding, :debug, "Found message '#{message}', generic function: #{function_type}" materialized_function = materialize_found_function(function_type) TypedRb.log binding, :debug, "Found message '#{message}', materialized generic function: #{materialized_function}" [function_klass_type, materialized_function] end end
materialize(actual_arguments)
click to toggle source
materialize will be invoked by the logic handling invocations like: ts 'MyClass[Y]' class MyClass
...
end MyClass.(TypeArg1, TypeArg2) -> make X<TypeArg1, Y<TypeArg2, X>TypeArg1, X>TypeArg2 MyClass.(TypeArg1, TypeArg2) -> Materialize here > make X<TypeArg1, Y<TypeArg2 > Unification
# File lib/typed/types/ty_generic_singleton_object.rb, line 54 def materialize(actual_arguments) TypedRb.log binding, :debug, "Materialising generic singleton object '#{self}' with args [#{actual_arguments.map(&:to_s).join(',')}]" # This can happen when we're dealing with a generic singleton object that has only been # annotated but we don't have the annotated implementation. e.g. Array[T] # We need to provide a default local_type_context based on the upper bounds provided in the # type annotation. compute_minimal_typing_context if @local_typing_context.nil? applied_typing_context, substitutions = @local_typing_context.clone(:class) fresh_vars_generic_type = clone_with_substitutions(substitutions) TypingContext.with_context(applied_typing_context) do # Appy constraints for application of Type args apply_type_arguments(fresh_vars_generic_type, actual_arguments) end # got all the constraints here # do something with the context -> unification? merge context? # applied_typing_context.all_constraints.each{|(l,t,r)| puts "#{l} #{t} #{r}" } unification = Polymorphism::Unification.new(applied_typing_context.all_constraints).run applied_typing_context.unlink # these constraints have already been satisfied # - Create a new ty_generic_object for the unified types # - Apply the unified types to all the methods in the class/instance # - this can be dynamically done with the right implementation of find_function_type # - Make the class available for the type checking system, so it can be found when # - this can be done, just returning the new ty_singleton_object with the unified types # - messages will be redirected to that instance and find_function_type/ find_var_type / as_object # will handle the mesage # - looking for messages at the instance level # - this can be accomplished with the overloading version of as_object_type, that will return # an instance of a new class ty_generic_object with overloaded versions of find_function_type /find_var_type ######################## fresh_vars_generic_type.apply_bindings(unification.bindings_map) end
materialize_with_type_vars(type_vars, bound_type)
click to toggle source
# File lib/typed/types/ty_generic_singleton_object.rb, line 24 def materialize_with_type_vars(type_vars, bound_type) TypedRb.log binding, :debug, "Materialising generic singleton object with type vars '#{self}' <= #{type_vars.map(&:to_s).join(',')} :: #{bound_type}" bound_type_vars = self.type_vars.map do |type_var| maybe_class_bound = type_vars.detect do |bound_type_var| type_var.variable == bound_type_var.variable end if maybe_class_bound.nil? # it has to be method generic variable type_var else maybe_class_bound end end materialize(bound_type_vars.map { |bound_type_var| bound_type_var.send(bound_type) }) end
self_materialize()
click to toggle source
# File lib/typed/types/ty_generic_singleton_object.rb, line 40 def self_materialize TypedRb.log binding, :debug, "Materialising self for generic singleton object '#{self}'" generic_type = BasicObject::TypeRegistry.find_generic_type(ruby_type) fail TypeCheckError.new("Missing generic type annotation for #{ruby_type}", node) if generic_type.nil? generic_type.materialize(type_vars) end