Class: TypedRb::Types::TyGenericSingletonObject
- Inherits:
-
TySingletonObject
- Object
- Type
- TyObject
- TySingletonObject
- TypedRb::Types::TyGenericSingletonObject
- Includes:
- Polymorphism::GenericComparisons, Polymorphism::GenericObject, Polymorphism::GenericVariables, SingletonObject
- Defined in:
- lib/typed/types/ty_generic_singleton_object.rb
Instance Attribute Summary collapse
-
#local_typing_context ⇒ Object
Returns the value of attribute local_typing_context.
-
#super_type ⇒ Object
Returns the value of attribute super_type.
Attributes inherited from TyObject
#classes, #hierarchy, #modules, #ruby_type, #with_ruby_type
Attributes inherited from Type
Instance Method Summary collapse
- #apply_bindings(bindings_map) ⇒ Object
- #as_object_type ⇒ Object
- #clone ⇒ Object
- #compute_minimal_typing_context ⇒ Object
-
#find_function_type(message, num_args, block) ⇒ Object
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.
-
#initialize(ruby_type, type_vars, super_type = nil, node = nil) ⇒ TyGenericSingletonObject
constructor
A new instance of TyGenericSingletonObject.
-
#materialize(actual_arguments) ⇒ Object
materialize will be invoked by the logic handling invocations like: ts ‘MyClass[Y]’ class MyClass …
- #materialize_with_type_vars(type_vars, bound_type) ⇒ Object
- #self_materialize ⇒ Object
Methods included from SingletonObject
#actual_arguments_hash, #apply_type_argument, #apply_type_arguments, #apply_type_arguments_recursively, #clone_with_substitutions
Methods included from Polymorphism::GenericVariables
Methods included from Polymorphism::GenericComparisons
#!=, #<, #<=, #==, #>, #>=, #add_type_var_constraint, #check_generic_type_relation, #check_inferior_or_equal_binding, #check_type_var_inclusion, #compatible?, #compatible_free_type_vars?, #incompatible_free_type_vars?, #to_ty_object
Methods included from Polymorphism::GenericObject
#ancestor_of_super_type?, #generic?, #generic_singleton_object, #generic_type_var_to_applied_type_var, #materialize_found_function, #materialize_found_function_arg, #materialize_super_type_found_function, #parse_super_type_materialization_arg, #parse_super_type_materialization_args, #to_s
Methods inherited from TySingletonObject
#compatible?, #find_function_type_in_metaclass_hierarchy, #find_var_type, #resolve_ruby_method, #singleton?, #to_s
Methods inherited from TyObject
#<=>, #check_type, #compatible?, #dynamic?, #either?, #find_function_type_in_hierarchy, #find_var_type, #generic?, #join, #max, #resolve_ruby_method, #singleton?, #to_s, #union
Methods included from Comparable
Methods inherited from Type
#compatible?, #either?, #stack_jump?
Constructor Details
#initialize(ruby_type, type_vars, super_type = nil, node = nil) ⇒ TyGenericSingletonObject
Returns a new instance of TyGenericSingletonObject.
17 18 19 20 21 22 |
# 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 |
Instance Attribute Details
#local_typing_context ⇒ Object
Returns the value of attribute local_typing_context.
15 16 17 |
# File 'lib/typed/types/ty_generic_singleton_object.rb', line 15 def local_typing_context @local_typing_context end |
#super_type ⇒ Object
Returns the value of attribute super_type.
15 16 17 |
# File 'lib/typed/types/ty_generic_singleton_object.rb', line 15 def super_type @super_type end |
Instance Method Details
#apply_bindings(bindings_map) ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 109 |
# 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 ⇒ Object
87 88 89 90 91 92 |
# 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 ⇒ Object
111 112 113 114 |
# 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 ⇒ Object
94 95 96 |
# 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) ⇒ Object
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
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/typed/types/ty_generic_singleton_object.rb', line 119 def find_function_type(, num_args, block) function_klass_type, function_type = super(, 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 '#{}', generic function: #{function_type}, explicit super type #{target_class}" target_type_vars = target_class.type_vars materialize_super_type_found_function(, 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 '#{}', 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(, num_args, block, target_class, type_vars) else TypedRb.log binding, :debug, "Found message '#{}', generic function: #{function_type}" materialized_function = materialize_found_function(function_type) TypedRb.log binding, :debug, "Found message '#{}', materialized generic function: #{materialized_function}" [function_klass_type, materialized_function] end end |
#materialize(actual_arguments) ⇒ Object
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
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# 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) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# 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 ⇒ Object
40 41 42 43 44 45 |
# 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 |