Class: Rigor::Plugin::AdditionalInitializer
- Inherits:
-
Object
- Object
- Rigor::Plugin::AdditionalInitializer
- Defined in:
- lib/rigor/plugin/additional_initializer.rb
Overview
ADR-38 declaration: “on ‘receiver_constraint` (and its subclasses), every method named in `methods` also establishes instance-variable state — treat it like `initialize` for the read-before-write nil soundness gate.”
Authored on a plugin manifest:
manifest(
id: "minitest",
version: "0.1.0",
additional_initializers: [
Rigor::Plugin::AdditionalInitializer.new(
receiver_constraint: "Minitest::Test",
methods: [:setup]
)
]
)
The Ruby analogue of PHPStan’s ‘AdditionalConstructorsExtension`. `Rigor::Inference::ScopeIndexer` consults the aggregated set at its single read-before-write gate: for a `def` whose name is in `methods` on a class that equals or inherits from `receiver_constraint` (matched via `Environment#class_ordering`, the same mechanism ADR-16 Tier A uses), the method’s ivar writes are folded into the class’s ‘init_writes` set, so a sibling method reading those ivars no longer gets a `Constant` widening.
The contribution can only ever suppress a nil widening — it never makes the analyzer stricter — so a missed or over-broad match is false-positive-safe by construction (ADR-38 § “Why this is FP-safe”).
## Fields
-
‘receiver_constraint` — fully-qualified class name (String). The entry applies to that class and its subclasses.
-
‘methods` — Array of Symbol method names treated as initializers on a matching class.
## Ractor-shareability
Both fields are frozen at construction (ADR-15 Phase 1); ‘Ractor.shareable?` returns true after `#initialize`, so the value object survives `Plugin::Registry.materialize` into a worker Ractor.
Instance Attribute Summary collapse
-
#methods ⇒ Object
readonly
Returns the value of attribute methods.
-
#receiver_constraint ⇒ Object
readonly
Returns the value of attribute receiver_constraint.
Instance Method Summary collapse
- #==(other) ⇒ Object (also: #eql?)
-
#covers_method?(method_name) ⇒ Boolean
True when ‘method_name` (a Symbol) is declared an initializer by this entry.
- #hash ⇒ Object
-
#initialize(receiver_constraint:, methods:) ⇒ AdditionalInitializer
constructor
A new instance of AdditionalInitializer.
- #to_h ⇒ Object
Constructor Details
#initialize(receiver_constraint:, methods:) ⇒ AdditionalInitializer
Returns a new instance of AdditionalInitializer.
54 55 56 57 58 59 60 61 |
# File 'lib/rigor/plugin/additional_initializer.rb', line 54 def initialize(receiver_constraint:, methods:) validate_receiver_constraint!(receiver_constraint) validate_methods!(methods) @receiver_constraint = receiver_constraint.dup.freeze @methods = methods.map(&:to_sym).freeze freeze end |
Instance Attribute Details
#methods ⇒ Object (readonly)
Returns the value of attribute methods.
52 53 54 |
# File 'lib/rigor/plugin/additional_initializer.rb', line 52 def methods @methods end |
#receiver_constraint ⇒ Object (readonly)
Returns the value of attribute receiver_constraint.
52 53 54 |
# File 'lib/rigor/plugin/additional_initializer.rb', line 52 def receiver_constraint @receiver_constraint end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
77 78 79 |
# File 'lib/rigor/plugin/additional_initializer.rb', line 77 def ==(other) other.is_a?(AdditionalInitializer) && to_h == other.to_h end |
#covers_method?(method_name) ⇒ Boolean
True when ‘method_name` (a Symbol) is declared an initializer by this entry. The class-constraint match is the caller’s responsibility (it needs the environment’s class graph).
66 67 68 |
# File 'lib/rigor/plugin/additional_initializer.rb', line 66 def covers_method?(method_name) methods.include?(method_name) end |
#hash ⇒ Object
82 83 84 |
# File 'lib/rigor/plugin/additional_initializer.rb', line 82 def hash to_h.hash end |
#to_h ⇒ Object
70 71 72 73 74 75 |
# File 'lib/rigor/plugin/additional_initializer.rb', line 70 def to_h { "receiver_constraint" => receiver_constraint, "methods" => methods.map(&:to_s) } end |