Class: Rigor::TypeNode::Generic
- Inherits:
-
Object
- Object
- Rigor::TypeNode::Generic
- Defined in:
- lib/rigor/type_node/generic.rb
Overview
A parameterised named-type reference (Pick<T, K>,
non-empty-array[Integer], pick_of[T, "name" | "email"],
…) in an RBS::Extended payload. The head is the parser-
observed name (no bracket type); args is the ordered
sequence of type-argument nodes already produced by the
parser at one level of depth.
Args are themselves Identifier or Generic. Nested generics ride the same
shape: Pick<Address, "name" | "surname"> reaches the resolver as
Generic("Pick", [Identifier("Address"), Union([...])]).
The carrier is intentionally permissive about args.size. The grammar-level rule "no brackets ⇒
Identifier; brackets ⇒ Generic" lives on the parser side; nothing here forbids a zero-arg Generic
so plugins can synthesise nodes for diagnostic or testing purposes without the parser fighting back.
Instance Method Summary collapse
-
#initialize(head:, args:) ⇒ Generic
constructor
A new instance of Generic.
Constructor Details
#initialize(head:, args:) ⇒ Generic
Returns a new instance of Generic.
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/rigor/type_node/generic.rb', line 20 def initialize(head:, args:) unless head.is_a?(String) && !head.empty? raise ArgumentError, "TypeNode::Generic head must be a non-empty String, " \ "got #{head.inspect}" end unless args.is_a?(Array) && args.all? { |a| valid_arg?(a) } raise ArgumentError, "TypeNode::Generic args must be an Array of " \ "TypeNode::Identifier / TypeNode::Generic / " \ "TypeNode::IntegerLiteral, got #{args.inspect}" end # Freeze the String head + Array args so the Data object is `Ractor.shareable?`. Each `a` is # already a shareable TypeNode value object (checked above), so freezing the wrapping Array # is sufficient. frozen_head = head.frozen? ? head : head.dup.freeze frozen_args = args.frozen? ? args : args.dup.freeze super(head: frozen_head, args: frozen_args) end |