Module: Rigor::Inference::Destructure
- 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. Leaf-name extraction for a destructured positional parameter (‘Prism::MultiTargetNode`). Stateless; lifted out of MethodParameterBinder so the binder’s class length stays in budget.
Class Method Summary collapse
- .names_for_entry(entry) ⇒ Object
-
.target_names(multi_target) ⇒ Object
Collect every leaf local name a ‘MultiTargetNode` binds, recursing through nested destructures (`((a, b), c)`) and the splat slot (`(a, *rest)`).
Class Method Details
.names_for_entry(entry) ⇒ Object
52 53 54 55 56 57 58 59 60 61 |
# File 'lib/rigor/inference/method_parameter_binder.rb', line 52 def names_for_entry(entry) # A splat sub-target (`*rest` inside the destructure) wraps its # real target in a `SplatNode#expression`; unwrap it. entry = entry.expression if entry.is_a?(Prism::SplatNode) && entry.expression return [] if entry.nil? return target_names(entry) if entry.is_a?(Prism::MultiTargetNode) return [entry.name] if entry.respond_to?(:name) && entry.name [] end |
.target_names(multi_target) ⇒ Object
Collect every leaf local name a ‘MultiTargetNode` binds, recursing through nested destructures (`((a, b), c)`) and the splat slot (`(a, *rest)`). Targets without a `#name` (an index/call write target, vanishingly rare in a parameter position) are skipped — there is no local to bind.
47 48 49 50 |
# File 'lib/rigor/inference/method_parameter_binder.rb', line 47 def target_names(multi_target) entries = multi_target.lefts + [multi_target.rest, *multi_target.rights].compact entries.flat_map { |entry| names_for_entry(entry) } end |