Class: Rigor::TypeNode::Generic

Inherits:
Object
  • Object
show all
Defined in:
lib/rigor/type_node/generic.rb

Overview

A parameterised named-type reference (‘Pick<T, K>`, `non-empty-array`, `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”), Generic(“Union”, […])])` — actually the union spelling depends on the parser’s eventual convention (slice 3 pins it); for now the field set is the only public commitment.

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

Constructor Details

#initialize(head:, args:) ⇒ Generic

Returns a new instance of Generic.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/rigor/type_node/generic.rb', line 27

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