Class: Rigor::Environment::ClassRegistry

Inherits:
Object
  • Object
show all
Defined in:
lib/rigor/environment/class_registry.rb

Overview

Resolves Ruby Class/Module objects to Rigor::Type::Nominal instances. The hardcoded list spans the core classes the literal typer (Slice 1) and the constant-resolution path (Slice 2 strengthening) need. Slice 4 will extend the registry by reading RBS Definitions through Rigor::Environment::RbsLoader.

See docs/internal-spec/inference-engine.md for the binding contract (every entry below MUST always be recognised).

Constant Summary collapse

SLICE_1_BUILT_INS =
[
  Integer,
  Float,
  String,
  Symbol,
  NilClass,
  TrueClass,
  FalseClass,
  Object,
  BasicObject
].freeze
SLICE_2_BUILT_INS =

Common Ruby core classes that user code routinely names by constant reference. Adding them to the registry lets ‘nominal_for_name` resolve `Array`, `Hash`, etc. without each call site re-listing them; Slice 4’s RBS loader will subsume these once it lands.

[
  Array,
  Hash,
  Range,
  Regexp,
  Proc,
  Method,
  Module,
  Class,
  Numeric,
  Comparable,
  Enumerable,
  Exception,
  StandardError,
  RuntimeError,
  ArgumentError,
  TypeError,
  NameError,
  NoMethodError,
  KeyError,
  IndexError,
  RangeError,
  ZeroDivisionError,
  IO,
  File,
  Dir,
  Encoding
].freeze
CORE_BUILT_INS =
(SLICE_1_BUILT_INS + SLICE_2_BUILT_INS).freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeClassRegistry

Returns a new instance of ClassRegistry.



77
78
79
80
# File 'lib/rigor/environment/class_registry.rb', line 77

def initialize
  @nominals = {}
  @class_objects = {}
end

Class Method Details

.defaultObject



64
65
66
# File 'lib/rigor/environment/class_registry.rb', line 64

def default
  @default ||= build_default
end

Instance Method Details

#class_ordering(lhs, rhs) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/rigor/environment/class_registry.rb', line 116

def class_ordering(lhs, rhs)
  lhs = normalize_name(lhs)
  rhs = normalize_name(rhs)
  return :equal if lhs == rhs

  lhs_class = @class_objects[lhs]
  rhs_class = @class_objects[rhs]
  return :unknown if lhs_class.nil? || rhs_class.nil?

  if lhs_class <= rhs_class
    :subclass
  elsif rhs_class <= lhs_class
    :superclass
  else
    :disjoint
  end
end

#nominal_for(class_object) ⇒ Object



97
98
99
100
101
102
103
# File 'lib/rigor/environment/class_registry.rb', line 97

def nominal_for(class_object)
  unless registered?(class_object)
    raise KeyError, "Rigor::Environment::ClassRegistry has no entry for #{class_object.inspect}"
  end

  @nominals.fetch(class_object.name)
end

#nominal_for_name(name) ⇒ Object

Nil-safe lookup by class name. Accepts Symbol or String. Returns the registered Rigor::Type::Nominal, or nil when the name is unknown. Used by ExpressionTyper to resolve Prism::ConstantReadNode and Prism::ConstantPathNode under the fail-soft policy: unknown names MUST NOT raise and MUST flow through the engine’s tracer.



110
111
112
113
114
# File 'lib/rigor/environment/class_registry.rb', line 110

def nominal_for_name(name)
  return nil if name.nil?

  @nominals[name.to_s]
end

#register(class_object) ⇒ Object

Raises:

  • (ArgumentError)


82
83
84
85
86
87
88
89
# File 'lib/rigor/environment/class_registry.rb', line 82

def register(class_object)
  raise ArgumentError, "expected Class or Module, got #{class_object.class}" unless class_object.is_a?(Module)
  raise ArgumentError, "anonymous class has no name" if class_object.name.nil?

  @nominals[class_object.name] ||= Type::Combinator.nominal_of(class_object)
  @class_objects[class_object.name] ||= class_object
  self
end

#registered?(class_object) ⇒ Boolean

Returns:

  • (Boolean)


91
92
93
94
95
# File 'lib/rigor/environment/class_registry.rb', line 91

def registered?(class_object)
  return false unless class_object.is_a?(Module) && class_object.name

  @nominals.key?(class_object.name)
end