Module: TypedRb::Types::Polymorphism::GenericObject

Included in:
TyGenericExistentialType, TyGenericObject, TyGenericSingletonObject
Defined in:
lib/typed/types/polymorphism/generic_object.rb

Instance Method Summary collapse

Instance Method Details

#ancestor_of_super_type?(super_type_klasses, function_klass_type) ⇒ Boolean

Returns:

  • (Boolean)


13
14
15
16
17
# File 'lib/typed/types/polymorphism/generic_object.rb', line 13

def ancestor_of_super_type?(super_type_klasses, function_klass_type)
  super_type_klasses.detect do |super_type_klass|
    super_type_klass.ruby_type.ancestors.include?(function_klass_type)
  end
end

#generic?Boolean

Returns:

  • (Boolean)


5
6
7
# File 'lib/typed/types/polymorphism/generic_object.rb', line 5

def generic?
  true
end

#generic_singleton_objectObject



9
10
11
# File 'lib/typed/types/polymorphism/generic_object.rb', line 9

def generic_singleton_object
  @generic_singleton_object ||= BasicObject::TypeRegistry.find_generic_type(ruby_type)
end

#generic_type_var_to_applied_type_var(type_var) ⇒ Object



108
109
110
111
# File 'lib/typed/types/polymorphism/generic_object.rb', line 108

def generic_type_var_to_applied_type_var(type_var)
  i = TypeRegistry.find_generic_type(ruby_type).type_vars.find_index { |generic_type_var| generic_type_var.variable == type_var.variable }
  i && type_vars[i]
end

#materialize_found_function(function_type) ⇒ Object



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
# File 'lib/typed/types/polymorphism/generic_object.rb', line 57

def materialize_found_function(function_type)
  return function_type unless function_type.generic?
  from_args = function_type.from.map { |arg| materialize_found_function_arg(arg) }
  to_arg = materialize_found_function_arg(function_type.to)
  if function_type.block_type
    materialized_block_type = materialize_found_function(function_type.block_type)
  end

  generic_function = (from_args + [to_arg, materialized_block_type]).any? do |arg|
    next arg.bound.nil? if arg.is_a?(Polymorphism::TypeVariable)
    next false if !arg.respond_to?(:generic?) || !arg.generic?
    next true if arg.is_a?(Types::TyGenericFunction)
    unbound_vars = arg.unbound_vars
    unbound_vars.count > 0
  end

  if generic_function
    materialized_function = TyGenericFunction.new(from_args, to_arg, function_type.parameters_info, node)
    materialized_function.local_typing_context = function_type.local_typing_context
  else
    materialized_function = TyFunction.new(from_args, to_arg, function_type.parameters_info, node)
  end

  materialized_function.with_block_type(materialized_block_type)
end

#materialize_found_function_arg(arg) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/typed/types/polymorphism/generic_object.rb', line 83

def materialize_found_function_arg(arg)
  if arg.is_a?(Polymorphism::TypeVariable)
    matching_var = generic_type_var_to_applied_type_var(arg)

    # if matching_var && matching_var.wildcard? && matching_var.lower_bound
    #  matching_var.lower_bound
    # elsif matching_var
    # WILDCARD
    if matching_var
      # Type variables and generic methods => function will still be generic
      (matching_var.is_a?(Polymorphism::TypeVariable) && matching_var.bound) || matching_var
    else
      # generic_function = true
      # TyUnboundType.new(matching_var.variable, :lower_bound)
      # fail TypeCheckError, "Cannot find matching type var for #{arg.variable} instantiating #{self}", arg.node
      # method generic var?
      arg
    end
  elsif arg.is_a?(TyGenericSingletonObject)
    arg.materialize_with_type_vars(type_vars, :lower_bound).as_object_type
  else
    arg
  end
end

#materialize_super_type_found_function(message, num_args, block, super_type, super_type_vars) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/typed/types/polymorphism/generic_object.rb', line 19

def materialize_super_type_found_function(message, num_args, block,
                                          super_type,
                                          super_type_vars)
  super_type_materialization_args = parse_super_type_materialization_args(super_type_vars)
  # we build the concrete type for the arguments based in the subclass bindings and the
  # super type parsed value
  materialized_super_type_in_context = super_type.materialize(super_type_materialization_args).type_vars(recursive: false)
  # Now we check if the parsed type is valid  provided the constraints of the super class
  super_type_generic_object = BasicObject::TypeRegistry.find_generic_type(super_type.ruby_type)
  materialized_super_type = super_type_generic_object.materialize(materialized_super_type_in_context)

  # materialized_super_type.type_vars = super_type.type_vars # ...
  materialized_super_type.as_object_type.find_function_type(message, num_args, block)
end

#parse_super_type_materialization_arg(super_type_var) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/typed/types/polymorphism/generic_object.rb', line 40

def parse_super_type_materialization_arg(super_type_var)
  return super_type_var if super_type_var.bound
  found_matching_var = type_vars.detect do |var|
    var_name = var.name.split(':').last
    super_type_var.name.index(var_name)
  end
  if found_matching_var
    base_matching_var = found_matching_var.dup
    base_matching_var.name = super_type_var.name
    base_matching_var.variable = super_type_var.variable
    base_matching_var
  else
    fail TypedRb::TypeCheckError,
         "Error materializing super type annotation for variable #{generic_singleton_object.ruby_type} '#{super_type_var.split(':').last}' not found in base class #{ruby_type}"
  end
end

#parse_super_type_materialization_args(super_type_vars) ⇒ Object



34
35
36
37
38
# File 'lib/typed/types/polymorphism/generic_object.rb', line 34

def parse_super_type_materialization_args(super_type_vars)
  super_type_vars.map do |super_type_var|
    parse_super_type_materialization_arg(super_type_var)
  end
end

#to_sObject



113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/typed/types/polymorphism/generic_object.rb', line 113

def to_s
  base_string = super
  var_types_strings = @type_vars.map do |var_type|
    if var_type.respond_to?(:bound) && var_type.bound
      # "[#{var_type.variable} <= #{var_type.bound}]"
      "[#{var_type.bound}]"
    else
      "[#{var_type}]"
    end
  end
  "#{base_string}#{var_types_strings.join}"
end