typed.rb 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/Rakefile +26 -0
 - data/bin/typed.rb +110 -0
 - data/lib/typed/language.rb +131 -0
 - data/lib/typed/model/tm_abs.rb +104 -0
 - data/lib/typed/model/tm_array_literal.rb +25 -0
 - data/lib/typed/model/tm_boolean.rb +15 -0
 - data/lib/typed/model/tm_boolean_operator.rb +34 -0
 - data/lib/typed/model/tm_break.rb +24 -0
 - data/lib/typed/model/tm_case_when.rb +38 -0
 - data/lib/typed/model/tm_class.rb +63 -0
 - data/lib/typed/model/tm_const.rb +29 -0
 - data/lib/typed/model/tm_defined.rb +19 -0
 - data/lib/typed/model/tm_error.rb +16 -0
 - data/lib/typed/model/tm_float.rb +15 -0
 - data/lib/typed/model/tm_for.rb +42 -0
 - data/lib/typed/model/tm_fun.rb +165 -0
 - data/lib/typed/model/tm_global_var.rb +22 -0
 - data/lib/typed/model/tm_global_var_assignment.rb +20 -0
 - data/lib/typed/model/tm_hash_literal.rb +32 -0
 - data/lib/typed/model/tm_if_else.rb +24 -0
 - data/lib/typed/model/tm_instance_var.rb +23 -0
 - data/lib/typed/model/tm_instance_var_assignment.rb +32 -0
 - data/lib/typed/model/tm_int.rb +15 -0
 - data/lib/typed/model/tm_local_var_asgn.rb +35 -0
 - data/lib/typed/model/tm_mass_asgn.rb +60 -0
 - data/lib/typed/model/tm_mlhs.rb +87 -0
 - data/lib/typed/model/tm_module.rb +51 -0
 - data/lib/typed/model/tm_next.rb +24 -0
 - data/lib/typed/model/tm_nil.rb +14 -0
 - data/lib/typed/model/tm_range_literal.rb +30 -0
 - data/lib/typed/model/tm_regexp.rb +27 -0
 - data/lib/typed/model/tm_rescue.rb +27 -0
 - data/lib/typed/model/tm_return.rb +24 -0
 - data/lib/typed/model/tm_s_class.rb +30 -0
 - data/lib/typed/model/tm_self.rb +22 -0
 - data/lib/typed/model/tm_send.rb +300 -0
 - data/lib/typed/model/tm_sequencing.rb +53 -0
 - data/lib/typed/model/tm_string.rb +15 -0
 - data/lib/typed/model/tm_string_interpolation.rb +21 -0
 - data/lib/typed/model/tm_super.rb +27 -0
 - data/lib/typed/model/tm_symbol.rb +15 -0
 - data/lib/typed/model/tm_symbol_interpolation.rb +21 -0
 - data/lib/typed/model/tm_try.rb +29 -0
 - data/lib/typed/model/tm_var.rb +28 -0
 - data/lib/typed/model/tm_while.rb +43 -0
 - data/lib/typed/model.rb +48 -0
 - data/lib/typed/prelude.rb +939 -0
 - data/lib/typed/prelude_existential_registry.bin +0 -0
 - data/lib/typed/prelude_generic_registry.bin +0 -0
 - data/lib/typed/prelude_registry.bin +0 -0
 - data/lib/typed/runtime/ast_parser.rb +589 -0
 - data/lib/typed/runtime/method_signature_processor.rb +72 -0
 - data/lib/typed/runtime/normalization/validations.rb +47 -0
 - data/lib/typed/runtime/normalization.rb +196 -0
 - data/lib/typed/runtime/parser_context.rb +36 -0
 - data/lib/typed/runtime/type_parser.rb +215 -0
 - data/lib/typed/runtime/type_registry.rb +170 -0
 - data/lib/typed/runtime/type_signature_processor.rb +34 -0
 - data/lib/typed/runtime.rb +33 -0
 - data/lib/typed/type_signature/parser.rb +240 -0
 - data/lib/typed/types/polymorphism/existential_type_variable.rb +13 -0
 - data/lib/typed/types/polymorphism/generic_comparisons.rb +134 -0
 - data/lib/typed/types/polymorphism/generic_variables.rb +24 -0
 - data/lib/typed/types/polymorphism/type_variable.rb +138 -0
 - data/lib/typed/types/polymorphism/type_variable_register.rb +298 -0
 - data/lib/typed/types/polymorphism/unification.rb +579 -0
 - data/lib/typed/types/ty_boolean.rb +15 -0
 - data/lib/typed/types/ty_dynamic.rb +39 -0
 - data/lib/typed/types/ty_either.rb +168 -0
 - data/lib/typed/types/ty_error.rb +18 -0
 - data/lib/typed/types/ty_existential_type.rb +22 -0
 - data/lib/typed/types/ty_function.rb +144 -0
 - data/lib/typed/types/ty_generic_function.rb +115 -0
 - data/lib/typed/types/ty_generic_object.rb +180 -0
 - data/lib/typed/types/ty_generic_singleton_object.rb +238 -0
 - data/lib/typed/types/ty_object.rb +256 -0
 - data/lib/typed/types/ty_singleton_object.rb +78 -0
 - data/lib/typed/types/ty_stack_jump.rb +44 -0
 - data/lib/typed/types/ty_top_level_object.rb +38 -0
 - data/lib/typed/types.rb +60 -0
 - data/lib/typed/typing_context.rb +206 -0
 - data/lib/typed/version.rb +3 -0
 - data/lib/typed.rb +161 -0
 - data/spec/lib/ast_parser_spec.rb +101 -0
 - data/spec/lib/examples/animals.rb +44 -0
 - data/spec/lib/examples/counter.rb +16 -0
 - data/spec/lib/examples/if.rb +31 -0
 - data/spec/lib/language_spec.rb +36 -0
 - data/spec/lib/model/tm_abs_spec.rb +66 -0
 - data/spec/lib/model/tm_array_literal_spec.rb +36 -0
 - data/spec/lib/model/tm_case_when_spec.rb +39 -0
 - data/spec/lib/model/tm_class_spec.rb +67 -0
 - data/spec/lib/model/tm_defined_spec.rb +10 -0
 - data/spec/lib/model/tm_for_spec.rb +150 -0
 - data/spec/lib/model/tm_fun_spec.rb +11 -0
 - data/spec/lib/model/tm_hash_literal_spec.rb +40 -0
 - data/spec/lib/model/tm_mass_asgn_spec.rb +104 -0
 - data/spec/lib/model/tm_module_spec.rb +42 -0
 - data/spec/lib/model/tm_regexp_spec.rb +9 -0
 - data/spec/lib/model/tm_return_spec.rb +47 -0
 - data/spec/lib/model/tm_s_class_spec.rb +27 -0
 - data/spec/lib/model/tm_self_spec.rb +19 -0
 - data/spec/lib/model/tm_string_interpolation_spec.rb +10 -0
 - data/spec/lib/model/tm_symbol_interpolation_spec.rb +10 -0
 - data/spec/lib/model/tm_symbol_spec.rb +9 -0
 - data/spec/lib/model/tm_while_spec.rb +141 -0
 - data/spec/lib/polymorphism/type_variable_spec.rb +14 -0
 - data/spec/lib/polymorphism/unification_spec.rb +328 -0
 - data/spec/lib/prelude/array_spec.rb +263 -0
 - data/spec/lib/prelude/class_spec.rb +12 -0
 - data/spec/lib/prelude/enumerable_spec.rb +278 -0
 - data/spec/lib/prelude/enumerator_spec.rb +101 -0
 - data/spec/lib/prelude/hash_spec.rb +361 -0
 - data/spec/lib/prelude/kernel_spec.rb +23 -0
 - data/spec/lib/prelude/object_spec.rb +22 -0
 - data/spec/lib/prelude/pair_spec.rb +16 -0
 - data/spec/lib/prelude/showable_spec.rb +31 -0
 - data/spec/lib/prelude/string_spec.rb +98 -0
 - data/spec/lib/runtime/normalization_spec.rb +29 -0
 - data/spec/lib/runtime/validations_spec.rb +56 -0
 - data/spec/lib/runtime_spec.rb +503 -0
 - data/spec/lib/type_signature/parser_spec.rb +239 -0
 - data/spec/lib/types/comparisons_spec.rb +35 -0
 - data/spec/lib/types/polymorphism/generic_comparisons_spec.rb +492 -0
 - data/spec/lib/types/polymorphism/type_variable_register_spec.rb +128 -0
 - data/spec/lib/types/ty_dynamic_spec.rb +103 -0
 - data/spec/lib/types/ty_either_spec.rb +288 -0
 - data/spec/lib/types/ty_error_spec.rb +18 -0
 - data/spec/lib/types/ty_generic_object_spec.rb +78 -0
 - data/spec/lib/types/ty_generic_singleton_object_spec.rb +288 -0
 - data/spec/lib/types/typing_context_spec.rb +86 -0
 - data/spec/lib/types_spec.rb +174 -0
 - data/spec/lib/typing/boolean_asgn_spec.rb +134 -0
 - data/spec/lib/typing/break_spec.rb +79 -0
 - data/spec/lib/typing/generics_spec.rb +191 -0
 - data/spec/lib/typing/instance_vars_spec.rb +103 -0
 - data/spec/lib/typing/next_spec.rb +29 -0
 - data/spec/lib/typing/op_asgn_spec.rb +104 -0
 - data/spec/lib/typing/overriden_methods_spec.rb +31 -0
 - data/spec/lib/typing/subtyping_spec.rb +112 -0
 - data/spec/lib/typing/tm_boolean_operator_spec.rb +100 -0
 - data/spec/lib/typing/tm_boolean_spec.rb +61 -0
 - data/spec/lib/typing/tm_const_spec.rb +28 -0
 - data/spec/lib/typing/tm_defined_spec.rb +12 -0
 - data/spec/lib/typing/tm_fun_spec.rb +347 -0
 - data/spec/lib/typing/tm_global_var_spec.rb +33 -0
 - data/spec/lib/typing/tm_if_else_spec.rb +104 -0
 - data/spec/lib/typing/tm_ignore_spec.rb +24 -0
 - data/spec/lib/typing/tm_instance_vars_spec.rb +117 -0
 - data/spec/lib/typing/tm_local_var_asgn_spec.rb +134 -0
 - data/spec/lib/typing/tm_mlhs_spec.rb +164 -0
 - data/spec/lib/typing/tm_module_spec.rb +89 -0
 - data/spec/lib/typing/tm_raise_spec.rb +31 -0
 - data/spec/lib/typing/tm_range_literal_spec.rb +25 -0
 - data/spec/lib/typing/tm_regexp_spec.rb +14 -0
 - data/spec/lib/typing/tm_return_spec.rb +45 -0
 - data/spec/lib/typing/tm_send_casting_spec.rb +26 -0
 - data/spec/lib/typing/tm_send_class_methods_spec.rb +42 -0
 - data/spec/lib/typing/tm_send_generic_apply_spec.rb +103 -0
 - data/spec/lib/typing/tm_send_generic_methods_spec.rb +77 -0
 - data/spec/lib/typing/tm_send_initialize_spec.rb +68 -0
 - data/spec/lib/typing/tm_send_lambda_spec.rb +135 -0
 - data/spec/lib/typing/tm_send_spec.rb +217 -0
 - data/spec/lib/typing/tm_send_yield_block_spec.rb +308 -0
 - data/spec/lib/typing/tm_sequencing_spec.rb +174 -0
 - data/spec/lib/typing/tm_string_interpolation_spec.rb +19 -0
 - data/spec/lib/typing/tm_super_spec.rb +63 -0
 - data/spec/lib/typing/tm_symbol_interpolation_spec.rb +19 -0
 - data/spec/lib/typing/tm_symbol_spec.rb +14 -0
 - data/spec/lib/typing/tm_try_spec.rb +73 -0
 - data/spec/spec_helper.rb +140 -0
 - metadata +216 -0
 
| 
         @@ -0,0 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- coding: utf-8 -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative '../model'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module TypedRb
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Model
         
     | 
| 
      
 6 
     | 
    
         
            +
                # range literals
         
     | 
| 
      
 7 
     | 
    
         
            +
                class TmRangeLiteral < Expr
         
     | 
| 
      
 8 
     | 
    
         
            +
                  attr_reader :start_range, :end_range
         
     | 
| 
      
 9 
     | 
    
         
            +
                  def initialize(start_range, end_range, node)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    super(node)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @start_range = start_range
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @end_range = end_range
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  def check_type(context)
         
     | 
| 
      
 16 
     | 
    
         
            +
                    start_range_type = start_range.check_type(context)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    end_range_type = end_range.check_type(context)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    max_type = [start_range_type, end_range_type].max
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                    type_var = Types::Polymorphism::TypeVariable.new('Range:T',
         
     | 
| 
      
 21 
     | 
    
         
            +
                                                                     :node => node,
         
     | 
| 
      
 22 
     | 
    
         
            +
                                                                     :gen_name => false,
         
     | 
| 
      
 23 
     | 
    
         
            +
                                                                     :upper_bound => max_type,
         
     | 
| 
      
 24 
     | 
    
         
            +
                                                                     :lower_bound => max_type)
         
     | 
| 
      
 25 
     | 
    
         
            +
                    type_var.bind(max_type)
         
     | 
| 
      
 26 
     | 
    
         
            +
                    Types::TyGenericObject.new(Range, [type_var], node)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- coding: utf-8 -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative '../model'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module TypedRb
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Model
         
     | 
| 
      
 6 
     | 
    
         
            +
                # Regular expresssion
         
     | 
| 
      
 7 
     | 
    
         
            +
                class TmRegexp < Expr
         
     | 
| 
      
 8 
     | 
    
         
            +
                  attr_reader :exp, :options
         
     | 
| 
      
 9 
     | 
    
         
            +
                  def initialize(exp, options, node)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    super(node)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @exp = exp
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @ptions = options
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  def check_type(context)
         
     | 
| 
      
 16 
     | 
    
         
            +
                    options.check_type(context) if options
         
     | 
| 
      
 17 
     | 
    
         
            +
                    exp_type = exp.check_type(context)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    if exp_type.compatible?(Types::TyString.new(node), :lt)
         
     | 
| 
      
 19 
     | 
    
         
            +
                      Types::TyRegexp.new(node)
         
     | 
| 
      
 20 
     | 
    
         
            +
                    else
         
     | 
| 
      
 21 
     | 
    
         
            +
                      error_message = "Error type checking  Regexp: Expected String type for expression, found #{exp_type}"
         
     | 
| 
      
 22 
     | 
    
         
            +
                      fail Types::TypeCheckError.new(error_message, node)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    end
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative '../model'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module TypedRb
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Model
         
     | 
| 
      
 5 
     | 
    
         
            +
                class TmRescue < Expr
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                  attr_reader :exceptions, :catch_var, :rescue_body
         
     | 
| 
      
 8 
     | 
    
         
            +
                  def initialize(exceptions, catch_var, rescue_body)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    @exceptions = exceptions
         
     | 
| 
      
 10 
     | 
    
         
            +
                    @catch_var = catch_var
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @rescue_body = rescue_body
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def check_type(context)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    if catch_var
         
     | 
| 
      
 16 
     | 
    
         
            +
                      exception_type = exceptions.map{|e| e.check_type(context) }.max
         
     | 
| 
      
 17 
     | 
    
         
            +
                      context.add_binding!(catch_var, exception_type)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
                    if rescue_body
         
     | 
| 
      
 20 
     | 
    
         
            +
                      rescue_body.check_type(context)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    else
         
     | 
| 
      
 22 
     | 
    
         
            +
                      Types::TyUnit.new
         
     | 
| 
      
 23 
     | 
    
         
            +
                    end
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative '../model'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module TypedRb
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Model
         
     | 
| 
      
 5 
     | 
    
         
            +
                class TmReturn < Expr
         
     | 
| 
      
 6 
     | 
    
         
            +
                  attr_reader :elements
         
     | 
| 
      
 7 
     | 
    
         
            +
                  def initialize(elements, node)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    super(node)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    @elements = elements
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  def check_type(context)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    returned_type = if elements.size == 0
         
     | 
| 
      
 14 
     | 
    
         
            +
                                      Types::TyUnit.new(node)
         
     | 
| 
      
 15 
     | 
    
         
            +
                                    elsif elements.size == 1
         
     | 
| 
      
 16 
     | 
    
         
            +
                                      elements.first.check_type(context)
         
     | 
| 
      
 17 
     | 
    
         
            +
                                    else
         
     | 
| 
      
 18 
     | 
    
         
            +
                                      TmArrayLiteral.new(elements, node).check_type(context)
         
     | 
| 
      
 19 
     | 
    
         
            +
                                    end
         
     | 
| 
      
 20 
     | 
    
         
            +
                    Types::TyStackJump.return(returned_type, node)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- coding: utf-8 -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative '../model'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module TypedRb
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Model
         
     | 
| 
      
 6 
     | 
    
         
            +
                # Class expression
         
     | 
| 
      
 7 
     | 
    
         
            +
                class TmSClass < Expr
         
     | 
| 
      
 8 
     | 
    
         
            +
                  attr_reader :class_name, :super_class_name, :body
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def initialize(class_name, body, node)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    super(node)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @class_name = class_name
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @body = body
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  def check_type(context)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    if class_name != :self
         
     | 
| 
      
 18 
     | 
    
         
            +
                      class_ruby_type = Types::TypingContext.find_namespace(class_name)
         
     | 
| 
      
 19 
     | 
    
         
            +
                      class_type = Runtime::TypeParser.parse_singleton_object_type(class_ruby_type.name)
         
     | 
| 
      
 20 
     | 
    
         
            +
                      class_type.node = node
         
     | 
| 
      
 21 
     | 
    
         
            +
                      context = context.add_binding(:self, class_type)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    end
         
     | 
| 
      
 23 
     | 
    
         
            +
                    Types::TypingContext.push_context(:sclass)
         
     | 
| 
      
 24 
     | 
    
         
            +
                    res = body.check_type(context)
         
     | 
| 
      
 25 
     | 
    
         
            +
                    Types::TypingContext.pop_context
         
     | 
| 
      
 26 
     | 
    
         
            +
                    res
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- coding: utf-8 -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative '../model'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module TypedRb
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Model
         
     | 
| 
      
 6 
     | 
    
         
            +
                # booleans
         
     | 
| 
      
 7 
     | 
    
         
            +
                class TmSelf < Expr
         
     | 
| 
      
 8 
     | 
    
         
            +
                  def initialize(node)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    super(node)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  def check_type(context)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    self_type = context.get_type_for(:self)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    if self_type.nil?
         
     | 
| 
      
 15 
     | 
    
         
            +
                      fail TypeCheckError.new.new('Error type checking self reference: Cannot find self reference in typing context', node)
         
     | 
| 
      
 16 
     | 
    
         
            +
                    else
         
     | 
| 
      
 17 
     | 
    
         
            +
                      self_type
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,300 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- coding: utf-8 -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative '../model'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module TypedRb
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Model
         
     | 
| 
      
 6 
     | 
    
         
            +
                # message send
         
     | 
| 
      
 7 
     | 
    
         
            +
                class TmSend < Expr
         
     | 
| 
      
 8 
     | 
    
         
            +
                  attr_accessor :receiver, :message, :args, :block
         
     | 
| 
      
 9 
     | 
    
         
            +
                  def initialize(receiver, message, args, node)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    super(node)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @receiver = receiver
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @message = message
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @args = args
         
     | 
| 
      
 14 
     | 
    
         
            +
                    @block = nil
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  def with_block(block)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    @block = block
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  def check_type(context)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    @context = context
         
     | 
| 
      
 23 
     | 
    
         
            +
                    TypedRb.log(binding, :debug,  "Type checking message sent: #{message} at line #{node.loc.line}")
         
     | 
| 
      
 24 
     | 
    
         
            +
                    if receiver.nil? && message == :ts
         
     | 
| 
      
 25 
     | 
    
         
            +
                      # ignore, => type annotation
         
     | 
| 
      
 26 
     | 
    
         
            +
                      Types::TyUnit.new(node)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    elsif message == :new && !singleton_object_type(receiver, context).nil? # clean this!
         
     | 
| 
      
 28 
     | 
    
         
            +
                      check_instantiation(context)
         
     | 
| 
      
 29 
     | 
    
         
            +
                    elsif receiver == :self || receiver.nil?
         
     | 
| 
      
 30 
     | 
    
         
            +
                      # self.m(args), m(args), m
         
     | 
| 
      
 31 
     | 
    
         
            +
                      check_type_no_explicit_receiver(context)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    else
         
     | 
| 
      
 33 
     | 
    
         
            +
                      # x.m(args)
         
     | 
| 
      
 34 
     | 
    
         
            +
                      check_type_explicit_receiver(context)
         
     | 
| 
      
 35 
     | 
    
         
            +
                    end
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  def singleton_object_type(receiver, context)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    parsed_receiver_type = if receiver.nil? || receiver == :self
         
     | 
| 
      
 40 
     | 
    
         
            +
                                             context.get_type_for(:self)
         
     | 
| 
      
 41 
     | 
    
         
            +
                                           else
         
     | 
| 
      
 42 
     | 
    
         
            +
                                             receiver_type
         
     | 
| 
      
 43 
     | 
    
         
            +
                                           end
         
     | 
| 
      
 44 
     | 
    
         
            +
                    return parsed_receiver_type if parsed_receiver_type.is_a?(Types::TySingletonObject)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  # we received new, but we look for initialize in the class,
         
     | 
| 
      
 48 
     | 
    
         
            +
                  # not the singleton class.
         
     | 
| 
      
 49 
     | 
    
         
            +
                  # we then run the regular application,
         
     | 
| 
      
 50 
     | 
    
         
            +
                  # but we return the class type instead of the return type
         
     | 
| 
      
 51 
     | 
    
         
            +
                  # for the constructor application (should be unit/nil).
         
     | 
| 
      
 52 
     | 
    
         
            +
                  def check_instantiation(context)
         
     | 
| 
      
 53 
     | 
    
         
            +
                    self_type = singleton_object_type(receiver, context).as_object_type
         
     | 
| 
      
 54 
     | 
    
         
            +
                    function_klass_type, function_type = self_type.find_function_type(:initialize, args.size, @block)
         
     | 
| 
      
 55 
     | 
    
         
            +
                    # function application
         
     | 
| 
      
 56 
     | 
    
         
            +
                    @message = :initialize
         
     | 
| 
      
 57 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 58 
     | 
    
         
            +
                      check_application(self_type, function_type, context)
         
     | 
| 
      
 59 
     | 
    
         
            +
                    rescue TypeCheckError => error
         
     | 
| 
      
 60 
     | 
    
         
            +
                      raise error if function_klass_type == self_type.ruby_type
         
     | 
| 
      
 61 
     | 
    
         
            +
                    end
         
     | 
| 
      
 62 
     | 
    
         
            +
                    self_type
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  def check_type_no_explicit_receiver(context)
         
     | 
| 
      
 66 
     | 
    
         
            +
                    if message == :yield
         
     | 
| 
      
 67 
     | 
    
         
            +
                      check_yield_application(context)
         
     | 
| 
      
 68 
     | 
    
         
            +
                    else
         
     | 
| 
      
 69 
     | 
    
         
            +
                      @receiver_type = context.get_type_for(:self) # check message in self type -> application
         
     | 
| 
      
 70 
     | 
    
         
            +
                      check_type_explicit_receiver(context)
         
     | 
| 
      
 71 
     | 
    
         
            +
                    end
         
     | 
| 
      
 72 
     | 
    
         
            +
                  end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                  def check_yield_application(context)
         
     | 
| 
      
 75 
     | 
    
         
            +
                    yield_abs_type = context.get_type_for(:yield)
         
     | 
| 
      
 76 
     | 
    
         
            +
                    if yield_abs_type
         
     | 
| 
      
 77 
     | 
    
         
            +
                      check_lambda_application(yield_abs_type, context)
         
     | 
| 
      
 78 
     | 
    
         
            +
                    else
         
     | 
| 
      
 79 
     | 
    
         
            +
                      fail TypeCheckError.new("Error type checking message sent '#{message}': Cannot find yield function defined in typing context", node)
         
     | 
| 
      
 80 
     | 
    
         
            +
                    end
         
     | 
| 
      
 81 
     | 
    
         
            +
                  end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                  def check_type_explicit_receiver(context)
         
     | 
| 
      
 84 
     | 
    
         
            +
                    if receiver_type.is_a?(Types::Polymorphism::TypeVariable)
         
     | 
| 
      
 85 
     | 
    
         
            +
                      # Existential type (Module) if receiver_type is self
         
     | 
| 
      
 86 
     | 
    
         
            +
                      # TODO: what can we do if this is the inclusion of a module?
         
     | 
| 
      
 87 
     | 
    
         
            +
                      arg_types = args.map { |arg| arg.check_type(context) }
         
     | 
| 
      
 88 
     | 
    
         
            +
                      receiver_type.add_message_constraint(message, arg_types)
         
     | 
| 
      
 89 
     | 
    
         
            +
                    elsif receiver_type.is_a?(Types::TyGenericSingletonObject) && (message == :call)
         
     | 
| 
      
 90 
     | 
    
         
            +
                      # Application of types accept a type class or a string with a type description
         
     | 
| 
      
 91 
     | 
    
         
            +
                      arg_types = parse_type_application_arguments(args, context)
         
     | 
| 
      
 92 
     | 
    
         
            +
                      check_type_application_to_generic(receiver_type, arg_types)
         
     | 
| 
      
 93 
     | 
    
         
            +
                    elsif receiver_type.is_a?(Types::TyFunction) && (message == :[] || message == :call)
         
     | 
| 
      
 94 
     | 
    
         
            +
                      check_lambda_application(receiver_type, context)
         
     | 
| 
      
 95 
     | 
    
         
            +
                    else
         
     | 
| 
      
 96 
     | 
    
         
            +
                      function_klass_type, function_type = receiver_type.find_function_type(message, args.size, @block)
         
     | 
| 
      
 97 
     | 
    
         
            +
                      # begin
         
     | 
| 
      
 98 
     | 
    
         
            +
                      if function_type.nil?
         
     | 
| 
      
 99 
     | 
    
         
            +
                        error_message = "Error type checking message sent '#{message}': Type information for #{receiver_type}:#{message} not found."
         
     | 
| 
      
 100 
     | 
    
         
            +
                        fail TypeCheckError.new(error_message, node)
         
     | 
| 
      
 101 
     | 
    
         
            +
                      elsif cast?(function_klass_type)
         
     | 
| 
      
 102 
     | 
    
         
            +
                        check_casting(context)
         
     | 
| 
      
 103 
     | 
    
         
            +
                      elsif module_include_implementation?(function_klass_type)
         
     | 
| 
      
 104 
     | 
    
         
            +
                        check_module_inclusions(receiver_type, context)
         
     | 
| 
      
 105 
     | 
    
         
            +
                      else
         
     | 
| 
      
 106 
     | 
    
         
            +
                        # function application
         
     | 
| 
      
 107 
     | 
    
         
            +
                        check_application(receiver_type, function_type, context)
         
     | 
| 
      
 108 
     | 
    
         
            +
                      end
         
     | 
| 
      
 109 
     | 
    
         
            +
                      # rescue TypeCheckError => error
         
     | 
| 
      
 110 
     | 
    
         
            +
                      #  if function_klass_type != receiver_type.ruby_type
         
     | 
| 
      
 111 
     | 
    
         
            +
                      #    Types::TyDynamic.new(Object, node)
         
     | 
| 
      
 112 
     | 
    
         
            +
                      #  else
         
     | 
| 
      
 113 
     | 
    
         
            +
                      #    raise error
         
     | 
| 
      
 114 
     | 
    
         
            +
                      #  end
         
     | 
| 
      
 115 
     | 
    
         
            +
                      # end
         
     | 
| 
      
 116 
     | 
    
         
            +
                    end
         
     | 
| 
      
 117 
     | 
    
         
            +
                  end
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
                  def parse_type_application_arguments(arguments, context)
         
     | 
| 
      
 120 
     | 
    
         
            +
                    arguments.map do |argument|
         
     | 
| 
      
 121 
     | 
    
         
            +
                      if argument.is_a?(Model::TmString)
         
     | 
| 
      
 122 
     | 
    
         
            +
                        type_var_signature = argument.node.children.first
         
     | 
| 
      
 123 
     | 
    
         
            +
                        maybe_generic_method_var = Types::TypingContext.vars_info(:method)[type_var_signature]
         
     | 
| 
      
 124 
     | 
    
         
            +
                        maybe_generic_class_var = Types::TypingContext.vars_info(:class)[type_var_signature]
         
     | 
| 
      
 125 
     | 
    
         
            +
                        if maybe_generic_method_var || maybe_generic_class_var
         
     | 
| 
      
 126 
     | 
    
         
            +
                          maybe_generic_method_var || maybe_generic_class_var
         
     | 
| 
      
 127 
     | 
    
         
            +
                        else
         
     | 
| 
      
 128 
     | 
    
         
            +
                          parsed_types = TypeSignature::Parser.parse(type_var_signature)
         
     | 
| 
      
 129 
     | 
    
         
            +
                          if parsed_types.is_a?(Array)
         
     | 
| 
      
 130 
     | 
    
         
            +
                            parsed_types.map { |parsed_type| parse_type_application_argument(parsed_type) }
         
     | 
| 
      
 131 
     | 
    
         
            +
                          else
         
     | 
| 
      
 132 
     | 
    
         
            +
                            parse_type_application_argument(parsed_types)
         
     | 
| 
      
 133 
     | 
    
         
            +
                          end
         
     | 
| 
      
 134 
     | 
    
         
            +
                        end
         
     | 
| 
      
 135 
     | 
    
         
            +
                      else
         
     | 
| 
      
 136 
     | 
    
         
            +
                        argument.check_type(context)
         
     | 
| 
      
 137 
     | 
    
         
            +
                      end
         
     | 
| 
      
 138 
     | 
    
         
            +
                    end.flatten
         
     | 
| 
      
 139 
     | 
    
         
            +
                  end
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
                  def parse_type_application_argument(type)
         
     | 
| 
      
 142 
     | 
    
         
            +
                    # TODO: do this recursively in the case of nested generic type
         
     | 
| 
      
 143 
     | 
    
         
            +
                    # TODO: do we need it at all?
         
     | 
| 
      
 144 
     | 
    
         
            +
                    klass = if type.is_a?(Hash) && type[:kind] == :generic_type
         
     | 
| 
      
 145 
     | 
    
         
            +
                              Class.for_name(type[:type])
         
     | 
| 
      
 146 
     | 
    
         
            +
                            end
         
     | 
| 
      
 147 
     | 
    
         
            +
                    Runtime::TypeParser.parse(type, klass)
         
     | 
| 
      
 148 
     | 
    
         
            +
                  end
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
                  def type_application_counter
         
     | 
| 
      
 151 
     | 
    
         
            +
                    @type_application_counter ||= 0
         
     | 
| 
      
 152 
     | 
    
         
            +
                    @type_application_counter += 1
         
     | 
| 
      
 153 
     | 
    
         
            +
                  end
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
                  def check_type_application_to_generic(generic_type, args)
         
     | 
| 
      
 156 
     | 
    
         
            +
                    generic_type.materialize(args)
         
     | 
| 
      
 157 
     | 
    
         
            +
                  end
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
                  def check_application(receiver_type, function_type, context)
         
     | 
| 
      
 160 
     | 
    
         
            +
                    if function_type.is_a?(Types::TyDynamicFunction)
         
     | 
| 
      
 161 
     | 
    
         
            +
                      function_type.to
         
     | 
| 
      
 162 
     | 
    
         
            +
                    else
         
     | 
| 
      
 163 
     | 
    
         
            +
                      if function_type.generic?
         
     | 
| 
      
 164 
     | 
    
         
            +
                        function_type.local_typing_context.parent = Types::TypingContext.type_variables_register
         
     | 
| 
      
 165 
     | 
    
         
            +
                        return_type = function_type.materialize do |materialized_function|
         
     | 
| 
      
 166 
     | 
    
         
            +
                          check_application(receiver_type, materialized_function, context)
         
     | 
| 
      
 167 
     | 
    
         
            +
                        end.to
         
     | 
| 
      
 168 
     | 
    
         
            +
                        return_type.respond_to?(:as_object_type) ? return_type.as_object_type : return_type
         
     | 
| 
      
 169 
     | 
    
         
            +
                      else
         
     | 
| 
      
 170 
     | 
    
         
            +
                        formal_parameters = function_type.from
         
     | 
| 
      
 171 
     | 
    
         
            +
                        parameters_info = function_type.parameters_info
         
     | 
| 
      
 172 
     | 
    
         
            +
                        TypedRb.log(binding, :debug, "Checking function application #{receiver_type}::#{message}( #{parameters_info} )")
         
     | 
| 
      
 173 
     | 
    
         
            +
                        check_args_application(parameters_info, formal_parameters, args, context)
         
     | 
| 
      
 174 
     | 
    
         
            +
                        if @block
         
     | 
| 
      
 175 
     | 
    
         
            +
                          block_type = @block.check_type(context)
         
     | 
| 
      
 176 
     | 
    
         
            +
                          # TODO:
         
     | 
| 
      
 177 
     | 
    
         
            +
                          # Unification is run here
         
     | 
| 
      
 178 
     | 
    
         
            +
                          # Algorithm is failing:
         
     | 
| 
      
 179 
     | 
    
         
            +
                          # G > String,
         
     | 
| 
      
 180 
     | 
    
         
            +
                          # G < E
         
     | 
| 
      
 181 
     | 
    
         
            +
                          # ========
         
     | 
| 
      
 182 
     | 
    
         
            +
                          # G = [String, ?]
         
     | 
| 
      
 183 
     | 
    
         
            +
                          # -----
         
     | 
| 
      
 184 
     | 
    
         
            +
                          # G = [String, E]
         
     | 
| 
      
 185 
     | 
    
         
            +
                          # E = [String, ?]
         
     | 
| 
      
 186 
     | 
    
         
            +
                          block_return_type = if function_type.block_type
         
     | 
| 
      
 187 
     | 
    
         
            +
                                                # materialization and unification will happen in this invocation
         
     | 
| 
      
 188 
     | 
    
         
            +
                                                block_type.compatible?(function_type.block_type, :lt)
         
     | 
| 
      
 189 
     | 
    
         
            +
                                              else
         
     | 
| 
      
 190 
     | 
    
         
            +
                                                block_type.to
         
     | 
| 
      
 191 
     | 
    
         
            +
                                              end
         
     | 
| 
      
 192 
     | 
    
         
            +
                          if block_return_type.to.stack_jump?
         
     | 
| 
      
 193 
     | 
    
         
            +
                            break_type = block_return_type.to.wrapped_type.check_type(context)
         
     | 
| 
      
 194 
     | 
    
         
            +
                            unless break_type.compatible?(function_type.to, :lt)
         
     | 
| 
      
 195 
     | 
    
         
            +
                              error_message = "Incompatible 'break' type, expected #{function_type.to}, found #{break_type}"
         
     | 
| 
      
 196 
     | 
    
         
            +
                              fail error_message, block_return_type.to.node
         
     | 
| 
      
 197 
     | 
    
         
            +
                            end
         
     | 
| 
      
 198 
     | 
    
         
            +
                          elsif block_return_type.to.either?
         
     | 
| 
      
 199 
     | 
    
         
            +
                            max_type = block_return_type.check_type(context, [:return, :break, :normal])
         
     | 
| 
      
 200 
     | 
    
         
            +
                            unless max_type.compatible?(function_type.to, :lt)
         
     | 
| 
      
 201 
     | 
    
         
            +
                              error_message = "Incompatible either max type, expected #{function_type.to}, found #{max_type}"
         
     | 
| 
      
 202 
     | 
    
         
            +
                              fail error_message, block_return_type.to.node
         
     | 
| 
      
 203 
     | 
    
         
            +
                            end
         
     | 
| 
      
 204 
     | 
    
         
            +
                          end
         
     | 
| 
      
 205 
     | 
    
         
            +
                        end
         
     | 
| 
      
 206 
     | 
    
         
            +
                        return_type = function_type.to
         
     | 
| 
      
 207 
     | 
    
         
            +
                        return_type.respond_to?(:as_object_type) ? return_type.as_object_type : return_type
         
     | 
| 
      
 208 
     | 
    
         
            +
                      end
         
     | 
| 
      
 209 
     | 
    
         
            +
                    end
         
     | 
| 
      
 210 
     | 
    
         
            +
                  end
         
     | 
| 
      
 211 
     | 
    
         
            +
             
     | 
| 
      
 212 
     | 
    
         
            +
                  def check_lambda_application(lambda_type, context)
         
     | 
| 
      
 213 
     | 
    
         
            +
                    lambda_type.check_args_application(args, context).to
         
     | 
| 
      
 214 
     | 
    
         
            +
                  end
         
     | 
| 
      
 215 
     | 
    
         
            +
             
     | 
| 
      
 216 
     | 
    
         
            +
                  def check_args_application(parameters_info, formal_parameters, actual_arguments, context)
         
     | 
| 
      
 217 
     | 
    
         
            +
                    #binding.pry if actual_arguments.size == 1 && actual_arguments.first.class == TypedRb::Model::TmVar && actual_arguments.first.val == "klass" && actual_arguments.first.col == 36
         
     | 
| 
      
 218 
     | 
    
         
            +
                    parameters_info.each_with_index do |(require_info, arg_name), index|
         
     | 
| 
      
 219 
     | 
    
         
            +
                      actual_argument = actual_arguments[index]
         
     | 
| 
      
 220 
     | 
    
         
            +
                      formal_parameter_type = formal_parameters[index]
         
     | 
| 
      
 221 
     | 
    
         
            +
                      if formal_parameter_type.nil? && !require_info == :block
         
     | 
| 
      
 222 
     | 
    
         
            +
                        fail TypeCheckError.new("Error type checking message sent '#{message}': Missing information about argument #{arg_name} in #{receiver}##{message}", node)
         
     | 
| 
      
 223 
     | 
    
         
            +
                      end
         
     | 
| 
      
 224 
     | 
    
         
            +
                      if actual_argument.nil? && require_info != :opt && require_info != :rest && require_info != :block
         
     | 
| 
      
 225 
     | 
    
         
            +
                        fail TypeCheckError.new("Error type checking message sent '#{message}': Missing mandatory argument #{arg_name} in #{receiver}##{message}", node)
         
     | 
| 
      
 226 
     | 
    
         
            +
                      else
         
     | 
| 
      
 227 
     | 
    
         
            +
                        if require_info == :rest
         
     | 
| 
      
 228 
     | 
    
         
            +
                          break if actual_argument.nil? # invocation without any of the optional arguments
         
     | 
| 
      
 229 
     | 
    
         
            +
                          rest_type = formal_parameter_type.type_vars.first
         
     | 
| 
      
 230 
     | 
    
         
            +
                          formal_parameter_type = if rest_type.respond_to?(:bound)
         
     | 
| 
      
 231 
     | 
    
         
            +
                                                    rest_type.bound
         
     | 
| 
      
 232 
     | 
    
         
            +
                                                  else
         
     | 
| 
      
 233 
     | 
    
         
            +
                                                    rest_type
         
     | 
| 
      
 234 
     | 
    
         
            +
                                                  end
         
     | 
| 
      
 235 
     | 
    
         
            +
                          actual_arguments[index..-1].each do |actual_argument|
         
     | 
| 
      
 236 
     | 
    
         
            +
                            unless actual_argument.check_type(context).compatible?(formal_parameter_type, :lt)
         
     | 
| 
      
 237 
     | 
    
         
            +
                              error_message = "Error type checking message sent '#{message}': #{formal_parameter_type} expected, #{actual_argument_type} found"
         
     | 
| 
      
 238 
     | 
    
         
            +
                              fail TypeCheckError.new(error_message, node)
         
     | 
| 
      
 239 
     | 
    
         
            +
                            end
         
     | 
| 
      
 240 
     | 
    
         
            +
                          end
         
     | 
| 
      
 241 
     | 
    
         
            +
                          break
         
     | 
| 
      
 242 
     | 
    
         
            +
                        else
         
     | 
| 
      
 243 
     | 
    
         
            +
                          unless actual_argument.nil? # opt or block if this is nil
         
     | 
| 
      
 244 
     | 
    
         
            +
                            actual_argument_type = actual_argument.check_type(context)
         
     | 
| 
      
 245 
     | 
    
         
            +
                            fail TypeCheckError.new("Error type checking message sent '#{message}': Missing type information for argument '#{arg_name}'", node) if formal_parameter_type.nil?
         
     | 
| 
      
 246 
     | 
    
         
            +
                            begin
         
     | 
| 
      
 247 
     | 
    
         
            +
                              unless actual_argument_type.compatible?(formal_parameter_type, :lt)
         
     | 
| 
      
 248 
     | 
    
         
            +
                                error_message = "Error type checking message sent '#{message}': #{formal_parameter_type} expected, #{actual_argument_type} found"
         
     | 
| 
      
 249 
     | 
    
         
            +
                                fail TypeCheckError.new(error_message, node)
         
     | 
| 
      
 250 
     | 
    
         
            +
                              end
         
     | 
| 
      
 251 
     | 
    
         
            +
                            rescue Types::UncomparableTypes, ArgumentError
         
     | 
| 
      
 252 
     | 
    
         
            +
                              raise Types::UncomparableTypes.new(actual_argument_type, formal_parameter_type, node)
         
     | 
| 
      
 253 
     | 
    
         
            +
                            end
         
     | 
| 
      
 254 
     | 
    
         
            +
                          end
         
     | 
| 
      
 255 
     | 
    
         
            +
                        end
         
     | 
| 
      
 256 
     | 
    
         
            +
                      end
         
     | 
| 
      
 257 
     | 
    
         
            +
                    end
         
     | 
| 
      
 258 
     | 
    
         
            +
                  end
         
     | 
| 
      
 259 
     | 
    
         
            +
             
     | 
| 
      
 260 
     | 
    
         
            +
                  def cast?(function_klass_type)
         
     | 
| 
      
 261 
     | 
    
         
            +
                    function_klass_type == BasicObject && message == :cast
         
     | 
| 
      
 262 
     | 
    
         
            +
                  end
         
     | 
| 
      
 263 
     | 
    
         
            +
             
     | 
| 
      
 264 
     | 
    
         
            +
                  def check_casting(context)
         
     | 
| 
      
 265 
     | 
    
         
            +
                    from_type = args[0].check_type(context)
         
     | 
| 
      
 266 
     | 
    
         
            +
                    to = parse_type_application_arguments([args[1]], context).first
         
     | 
| 
      
 267 
     | 
    
         
            +
                    to_type = to.is_a?(Types::TyObject) ? to.as_object_type : to
         
     | 
| 
      
 268 
     | 
    
         
            +
                    TypedRb.log(binding, :info, "Casting #{from_type} into #{to_type}")
         
     | 
| 
      
 269 
     | 
    
         
            +
                    to_type
         
     | 
| 
      
 270 
     | 
    
         
            +
                  end
         
     | 
| 
      
 271 
     | 
    
         
            +
             
     | 
| 
      
 272 
     | 
    
         
            +
                  def module_include_implementation?(function_klass_type)
         
     | 
| 
      
 273 
     | 
    
         
            +
                    function_klass_type == Module && message == :include
         
     | 
| 
      
 274 
     | 
    
         
            +
                  end
         
     | 
| 
      
 275 
     | 
    
         
            +
             
     | 
| 
      
 276 
     | 
    
         
            +
                  def check_module_inclusions(self_type, context)
         
     | 
| 
      
 277 
     | 
    
         
            +
                    args.map do |arg|
         
     | 
| 
      
 278 
     | 
    
         
            +
                      arg.check_type(context)
         
     | 
| 
      
 279 
     | 
    
         
            +
                    end.each do |module_type|
         
     | 
| 
      
 280 
     | 
    
         
            +
                      if module_type.is_a?(Types::TyExistentialType)
         
     | 
| 
      
 281 
     | 
    
         
            +
                        if module_type.local_typing_context
         
     | 
| 
      
 282 
     | 
    
         
            +
                          module_type.check_inclusion(self_type)
         
     | 
| 
      
 283 
     | 
    
         
            +
                        else
         
     | 
| 
      
 284 
     | 
    
         
            +
                          # TODO: report warning about missing module information
         
     | 
| 
      
 285 
     | 
    
         
            +
                          TypedRb.log(binding, :debug,  "Not type checking module #{module_type.ruby_type} inclusion due to lack of module information")
         
     | 
| 
      
 286 
     | 
    
         
            +
                        end
         
     | 
| 
      
 287 
     | 
    
         
            +
                      else
         
     | 
| 
      
 288 
     | 
    
         
            +
                        error_message = "Error type checking message sent '#{message}': Module type expected for inclusion in #{self_type}, #{module_type} found"
         
     | 
| 
      
 289 
     | 
    
         
            +
                        fail TypeCheckError.new(error_message, node)
         
     | 
| 
      
 290 
     | 
    
         
            +
                      end
         
     | 
| 
      
 291 
     | 
    
         
            +
                    end
         
     | 
| 
      
 292 
     | 
    
         
            +
                    self_type
         
     | 
| 
      
 293 
     | 
    
         
            +
                  end
         
     | 
| 
      
 294 
     | 
    
         
            +
             
     | 
| 
      
 295 
     | 
    
         
            +
                  def receiver_type
         
     | 
| 
      
 296 
     | 
    
         
            +
                    @receiver_type ||= receiver.check_type(@context)
         
     | 
| 
      
 297 
     | 
    
         
            +
                  end
         
     | 
| 
      
 298 
     | 
    
         
            +
                end
         
     | 
| 
      
 299 
     | 
    
         
            +
              end
         
     | 
| 
      
 300 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,53 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- coding: utf-8 -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative '../model'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module TypedRb
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Model
         
     | 
| 
      
 6 
     | 
    
         
            +
                class TmSequencing < Expr
         
     | 
| 
      
 7 
     | 
    
         
            +
                  attr_accessor :terms
         
     | 
| 
      
 8 
     | 
    
         
            +
                  def initialize(terms, node)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    super(node)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    @terms = terms.reject(&:nil?)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  def check_type(context)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    process_terms_before_return(@terms, context)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  private
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  def process_terms_before_return(terms, context, processed_terms=[], potential_return=nil)
         
     | 
| 
      
 20 
     | 
    
         
            +
                    if terms.empty?
         
     | 
| 
      
 21 
     | 
    
         
            +
                      make_final_return(processed_terms.last, potential_return)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    else
         
     | 
| 
      
 23 
     | 
    
         
            +
                      term_type = terms.first.check_type(context)
         
     | 
| 
      
 24 
     | 
    
         
            +
                      if term_type.stack_jump?
         
     | 
| 
      
 25 
     | 
    
         
            +
                        process_terms_after_return(terms.drop(1), context)
         
     | 
| 
      
 26 
     | 
    
         
            +
                        make_final_return(term_type, potential_return)
         
     | 
| 
      
 27 
     | 
    
         
            +
                      elsif term_type.either?
         
     | 
| 
      
 28 
     | 
    
         
            +
                        process_terms_before_return(terms.drop(1), context, processed_terms << nil, make_final_return(term_type, potential_return))
         
     | 
| 
      
 29 
     | 
    
         
            +
                      else
         
     | 
| 
      
 30 
     | 
    
         
            +
                        process_terms_before_return(terms.drop(1), context, processed_terms << term_type, potential_return)
         
     | 
| 
      
 31 
     | 
    
         
            +
                      end
         
     | 
| 
      
 32 
     | 
    
         
            +
                    end
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  def process_terms_after_return(terms, context)
         
     | 
| 
      
 36 
     | 
    
         
            +
                    terms.each { |term| term.check_type(context) }
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  def make_final_return(type_a, type_b)
         
     | 
| 
      
 41 
     | 
    
         
            +
                    return (type_a || type_b) if type_a.nil? || type_b.nil?
         
     | 
| 
      
 42 
     | 
    
         
            +
                    either_types = [type_a, type_b].map{ |type| Types::TyEither.wrap(type) }
         
     | 
| 
      
 43 
     | 
    
         
            +
                    reduced_final_type = either_types.reduce { |a,b| a.compatible_either?(b) }.unwrap
         
     | 
| 
      
 44 
     | 
    
         
            +
                    if type_a.stack_jump? || type_b.stack_jump?
         
     | 
| 
      
 45 
     | 
    
         
            +
                      jump_kind = [type_a, type_b].detect {|type| type.stack_jump? }.jump_kind
         
     | 
| 
      
 46 
     | 
    
         
            +
                      reduced_final_type[jump_kind]
         
     | 
| 
      
 47 
     | 
    
         
            +
                    else
         
     | 
| 
      
 48 
     | 
    
         
            +
                      reduced_final_type
         
     | 
| 
      
 49 
     | 
    
         
            +
                    end
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- coding: utf-8 -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative '../model'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module TypedRb
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Model
         
     | 
| 
      
 6 
     | 
    
         
            +
                # strings
         
     | 
| 
      
 7 
     | 
    
         
            +
                class TmString < Expr
         
     | 
| 
      
 8 
     | 
    
         
            +
                  attr_accessor :val
         
     | 
| 
      
 9 
     | 
    
         
            +
                  def initialize(node)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    super(node, Types::TyString.new(node))
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @val = node.children.first
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative '../model'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module TypedRb
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Model
         
     | 
| 
      
 5 
     | 
    
         
            +
                # String interpolation
         
     | 
| 
      
 6 
     | 
    
         
            +
                class TmStringInterpolation < Expr
         
     | 
| 
      
 7 
     | 
    
         
            +
                  attr_reader :units
         
     | 
| 
      
 8 
     | 
    
         
            +
                  def initialize(units, node)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    super(node)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    @units = units
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  def check_type(context)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    units.each do |unit|
         
     | 
| 
      
 15 
     | 
    
         
            +
                      unit.check_type(context)
         
     | 
| 
      
 16 
     | 
    
         
            +
                    end
         
     | 
| 
      
 17 
     | 
    
         
            +
                    Types::TyString.new(node)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- coding: utf-8 -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative '../model'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module TypedRb
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Model
         
     | 
| 
      
 6 
     | 
    
         
            +
                # super keyword invocations
         
     | 
| 
      
 7 
     | 
    
         
            +
                class TmSuper < Expr
         
     | 
| 
      
 8 
     | 
    
         
            +
                  attr_reader :args
         
     | 
| 
      
 9 
     | 
    
         
            +
                  def initialize(args, node)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    super(node)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @args = args
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def check_type(context)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    if Types::TypingContext.function_context
         
     | 
| 
      
 16 
     | 
    
         
            +
                      self_type, message, args = Types::TypingContext.function_context
         
     | 
| 
      
 17 
     | 
    
         
            +
                      parent_self_type = Types::TyObject.new(self_type.hierarchy.first, node)
         
     | 
| 
      
 18 
     | 
    
         
            +
                      args = @args || args
         
     | 
| 
      
 19 
     | 
    
         
            +
                      args = args.map { |arg| arg.check_type(context) }
         
     | 
| 
      
 20 
     | 
    
         
            +
                      TmSend.new(parent_self_type, message, args, node).check_type(context)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    else
         
     | 
| 
      
 22 
     | 
    
         
            +
                      fail TypeCheckError.new("Error type checking 'super' invocation without function context.", node)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    end
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- coding: utf-8 -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative '../model'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module TypedRb
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Model
         
     | 
| 
      
 6 
     | 
    
         
            +
                # floats
         
     | 
| 
      
 7 
     | 
    
         
            +
                class TmSymbol < Expr
         
     | 
| 
      
 8 
     | 
    
         
            +
                  attr_accessor :val
         
     | 
| 
      
 9 
     | 
    
         
            +
                  def initialize(node)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    super(node, Types::TySymbol.new(node))
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @val = node.children.first
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative '../model'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module TypedRb
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Model
         
     | 
| 
      
 5 
     | 
    
         
            +
                # Symbol interpolation
         
     | 
| 
      
 6 
     | 
    
         
            +
                class TmSymbolInterpolation < Expr
         
     | 
| 
      
 7 
     | 
    
         
            +
                  attr_reader :units
         
     | 
| 
      
 8 
     | 
    
         
            +
                  def initialize(units, node)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    super(node)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    @units = units
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  def check_type(context)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    units.each do |unit|
         
     | 
| 
      
 15 
     | 
    
         
            +
                      unit.check_type(context)
         
     | 
| 
      
 16 
     | 
    
         
            +
                    end
         
     | 
| 
      
 17 
     | 
    
         
            +
                    Types::TySymbol.new(node)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,29 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- coding: utf-8 -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative '../model'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module TypedRb
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Model
         
     | 
| 
      
 6 
     | 
    
         
            +
                class TmTry < Expr
         
     | 
| 
      
 7 
     | 
    
         
            +
                  def initialize(try_term, rescue_terms, node)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    super(node)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    @try_term = try_term
         
     | 
| 
      
 10 
     | 
    
         
            +
                    @rescue_terms = rescue_terms
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  def check_type(context)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    try_term_type = @try_term.check_type(context)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    rescue_term_types = @rescue_terms.map do |term|
         
     | 
| 
      
 16 
     | 
    
         
            +
                      term.check_type(context)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    end.reject do |type|
         
     | 
| 
      
 18 
     | 
    
         
            +
                      type.is_a?(Types::TyUnit)
         
     | 
| 
      
 19 
     | 
    
         
            +
                    end
         
     | 
| 
      
 20 
     | 
    
         
            +
                    incompatible_type = rescue_term_types.detect { |term_type| !try_term_type.compatible?(term_type) }
         
     | 
| 
      
 21 
     | 
    
         
            +
                    if incompatible_type
         
     | 
| 
      
 22 
     | 
    
         
            +
                      fail TypeCheckError.new("Type error checking try statement: Error in rescue clause, expected type #{try_term_type} got #{incompatible_type}", node)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    else
         
     | 
| 
      
 24 
     | 
    
         
            +
                      try_term_type
         
     | 
| 
      
 25 
     | 
    
         
            +
                    end
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- coding: utf-8 -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative '../model'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module TypedRb
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Model
         
     | 
| 
      
 6 
     | 
    
         
            +
                # variable
         
     | 
| 
      
 7 
     | 
    
         
            +
                class TmVar < Expr
         
     | 
| 
      
 8 
     | 
    
         
            +
                  attr_accessor :val
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def initialize(val, node)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    super(node)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @val = val.to_s
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  def to_s
         
     | 
| 
      
 16 
     | 
    
         
            +
                    "#{GenSym.resolve(@val)}"
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  def check_type(context)
         
     | 
| 
      
 20 
     | 
    
         
            +
                    type = context.get_type_for(@val)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    if type.nil?
         
     | 
| 
      
 22 
     | 
    
         
            +
                      fail TypeCheckError.new("Type error checking local var #{@val}: Cannot find binding local var in the typing context", node)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    end
         
     | 
| 
      
 24 
     | 
    
         
            +
                    type
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     |