Class: Rigor::Inference::MethodParameterBinder

Inherits:
Object
  • Object
show all
Defined in:
lib/rigor/inference/method_parameter_binder.rb

Overview

Builds the entry scope of a method body by translating the method’s parameter list into a ‘name -> Rigor::Type` map.

Parameter types come from the surrounding class’s RBS signature when one is available; otherwise every parameter defaults to ‘Dynamic`. The default is the Slice 1 fail-soft answer for unknown values, so a method whose RBS signature is missing or whose parameters cannot be matched still binds every name into the scope (a method body whose `Local x` reads return `Dynamic` instead of falling through to the unbound-local `Dynamic` event is the same observable type, but the binding presence is what later slices need to attach narrowing facts to).

The class context (‘class_path:`) and `singleton:` flag are supplied by the caller (the StatementEvaluator) which threads them as the lexical class scope. The binder makes no assumption about how that context was computed; it only uses it to build the `(class_name, method_name)` lookup key for `Rigor::Environment::RbsLoader#instance_method` / `#singleton_method`.

See docs/internal-spec/inference-engine.md for the binding contract. rubocop:disable Metrics/ClassLength

Instance Method Summary collapse

Constructor Details

#initialize(environment:, class_path:, singleton:) ⇒ MethodParameterBinder

Returns a new instance of MethodParameterBinder.

Parameters:

  • environment (Rigor::Environment)
  • class_path (String, nil)

    the qualified name of the class the method is defined in (e.g., ‘“Foo::Bar”`), or `nil` for a top-level `def` outside any class. When `nil` (or when the class is unknown to RBS), every parameter falls back to `Dynamic`.

  • singleton (Boolean)

    ‘true` when the def is a singleton method (either `def self.foo` or a `def foo` inside `class << self`); routes the lookup through `RbsLoader#singleton_method`.



45
46
47
48
49
# File 'lib/rigor/inference/method_parameter_binder.rb', line 45

def initialize(environment:, class_path:, singleton:)
  @environment = environment
  @class_path = class_path
  @singleton = singleton
end

Instance Method Details

#bind(def_node) ⇒ Hash{Symbol => Rigor::Type}

Returns ordered map from parameter name to bound type. Anonymous parameters (‘*` and `**` without a name) are skipped.

Parameters:

  • def_node (Prism::DefNode)

Returns:

  • (Hash{Symbol => Rigor::Type})

    ordered map from parameter name to bound type. Anonymous parameters (‘*` and `**` without a name) are skipped.



55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/rigor/inference/method_parameter_binder.rb', line 55

def bind(def_node)
  slots = collect_slots(def_node.parameters)
  types = default_types_for(slots)

  rbs_method = lookup_rbs_method(def_node)
  return types unless rbs_method

  method_types = rbs_method.method_types
  return types if method_types.empty?

  apply_rbs_overloads(types, slots, method_types)
  types
end