Class: Rigor::Environment::RbsLoader
- Inherits:
-
Object
- Object
- Rigor::Environment::RbsLoader
- Defined in:
- lib/rigor/environment/rbs_loader.rb
Overview
Loads RBS class declarations and method definitions from disk and exposes them to the inference engine in a small, stable surface.
Slice 4 phase 1 only enabled the RBS core signatures shipped with the ‘rbs` gem (`Object`, `Integer`, `String`, `Array`, …). Phase 2a adds opt-in stdlib library loading (`pathname`, `json`, `tempfile`, …) and arbitrary-directory signature loading (typically the project’s local ‘sig/` tree). Both are off by default on `RbsLoader.default` so the core-only fast path stays cheap; project-aware loading is opted into through for_project or by constructing a custom loader.
The default instance is shared across the process: building the core RBS environment costs hundreds of milliseconds and the data is read-only. The shared instance is frozen, but holds a mutable state hash for lazy memoization of the heavy ‘RBS::Environment` and `RBS::DefinitionBuilder` – the user-visible API stays purely functional.
See docs/internal-spec/inference-engine.md for the binding contract. rubocop:disable Metrics/ClassLength
Instance Attribute Summary collapse
-
#libraries ⇒ Object
readonly
Returns the value of attribute libraries.
-
#signature_paths ⇒ Object
readonly
Returns the value of attribute signature_paths.
Class Method Summary collapse
- .default ⇒ Object
-
.reset_default! ⇒ Object
Used by tests to discard the cached default loader; production code MUST NOT call this.
Instance Method Summary collapse
-
#class_known?(name) ⇒ Boolean
Returns true when an RBS class or module declaration with the given name is loaded.
- #class_ordering(lhs, rhs) ⇒ Object
-
#class_type_param_names(class_name) ⇒ Object
Slice 4 phase 2d.
-
#constant_type(name) ⇒ Object
Slice A constant-value lookup.
-
#initialize(libraries: [], signature_paths: []) ⇒ RbsLoader
constructor
A new instance of RbsLoader.
-
#instance_definition(class_name) ⇒ RBS::Definition?
The resolved instance definition for ‘class_name`, or nil when the class is unknown or its definition cannot be built (RBS may raise on broken hierarchies; we fail-soft and return nil so the caller can fall back).
- #instance_method(class_name:, method_name:) ⇒ RBS::Definition::Method?
-
#singleton_definition(class_name) ⇒ RBS::Definition?
The resolved singleton (class object) definition for ‘class_name`.
-
#singleton_method(class_name:, method_name:) ⇒ RBS::Definition::Method?
The class method on ‘class_name`.
Constructor Details
#initialize(libraries: [], signature_paths: []) ⇒ RbsLoader
Returns a new instance of RbsLoader.
60 61 62 63 64 65 66 67 68 |
# File 'lib/rigor/environment/rbs_loader.rb', line 60 def initialize(libraries: [], signature_paths: []) @libraries = libraries.map(&:to_s).freeze @signature_paths = signature_paths.map { |p| Pathname(p) }.freeze @state = { env: nil, builder: nil } @instance_definition_cache = {} @singleton_definition_cache = {} @class_known_cache = {} @hierarchy = RbsHierarchy.new(self) end |
Instance Attribute Details
#libraries ⇒ Object (readonly)
Returns the value of attribute libraries.
47 48 49 |
# File 'lib/rigor/environment/rbs_loader.rb', line 47 def libraries @libraries end |
#signature_paths ⇒ Object (readonly)
Returns the value of attribute signature_paths.
47 48 49 |
# File 'lib/rigor/environment/rbs_loader.rb', line 47 def signature_paths @signature_paths end |
Class Method Details
.default ⇒ Object
34 35 36 |
# File 'lib/rigor/environment/rbs_loader.rb', line 34 def default @default ||= new.freeze end |
.reset_default! ⇒ Object
Used by tests to discard the cached default loader; production code MUST NOT call this. The shared loader holds a several-MB RBS::Environment, so dropping it during a normal run wastes the cost of rebuilding it.
42 43 44 |
# File 'lib/rigor/environment/rbs_loader.rb', line 42 def reset_default! @default = nil end |
Instance Method Details
#class_known?(name) ⇒ Boolean
Returns true when an RBS class or module declaration with the given name is loaded. Accepts unprefixed or top-level-prefixed names (“Integer” or “::Integer”). Memoized per-name (positive and negative results both cache).
74 75 76 77 78 79 |
# File 'lib/rigor/environment/rbs_loader.rb', line 74 def class_known?(name) key = name.to_s return @class_known_cache[key] if @class_known_cache.key?(key) @class_known_cache[key] = compute_class_known(name) end |
#class_ordering(lhs, rhs) ⇒ Object
143 144 145 |
# File 'lib/rigor/environment/rbs_loader.rb', line 143 def class_ordering(lhs, rhs) @hierarchy.class_ordering(lhs, rhs) end |
#class_type_param_names(class_name) ⇒ Object
Slice 4 phase 2d. Returns the class’s declared type-parameter names as Symbols (e.g., ‘[:Elem]` for `Array`, `[:K, :V]` for `Hash`). Used by the dispatcher to build the substitution map from receiver `type_args` into the method’s return type. The instance definition is the canonical source because singleton methods (e.g., ‘Array.new`) parameterize over the same `Elem` as instance methods.
Returns an empty array for non-generic classes and for unknown names (the loader stays fail-soft). NOTE: in the ‘rbs` gem, `RBS::Definition#type_params` returns `Array<Symbol>` directly, not the AST `TypeParam` object (those live on the AST level).
136 137 138 139 140 141 |
# File 'lib/rigor/environment/rbs_loader.rb', line 136 def class_type_param_names(class_name) definition = instance_definition(class_name) return [] unless definition definition.type_params.dup end |
#constant_type(name) ⇒ Object
Slice A constant-value lookup. Returns the translated ‘Rigor::Type` for a non-class constant declaration (`BUCKETS: Array`, `DEFAULT_PATH: String`, …) or `nil` when no constant entry exists for `name` in the loaded RBS environment. Callers MUST treat the return value as authoritative when present and as “unknown” when nil; the loader does NOT consult the class declarations here — class objects are still resolved through #class_known? and `Environment#singleton_for_name`.
156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/rigor/environment/rbs_loader.rb', line 156 def constant_type(name) rbs_name = parse_type_name(name) return nil unless rbs_name entry = env.constant_decls[rbs_name] return nil unless entry translated = Inference::RbsTypeTranslator.translate(entry.decl.type) translated unless translated.is_a?(Type::Bot) rescue StandardError nil end |
#instance_definition(class_name) ⇒ RBS::Definition?
Returns the resolved instance definition for ‘class_name`, or nil when the class is unknown or its definition cannot be built (RBS may raise on broken hierarchies; we fail-soft and return nil so the caller can fall back).
85 86 87 88 89 90 |
# File 'lib/rigor/environment/rbs_loader.rb', line 85 def instance_definition(class_name) key = class_name.to_s return @instance_definition_cache[key] if @instance_definition_cache.key?(key) @instance_definition_cache[key] = build_instance_definition(class_name) end |
#instance_method(class_name:, method_name:) ⇒ RBS::Definition::Method?
93 94 95 96 97 98 |
# File 'lib/rigor/environment/rbs_loader.rb', line 93 def instance_method(class_name:, method_name:) definition = instance_definition(class_name) return nil unless definition definition.methods[method_name.to_sym] end |
#singleton_definition(class_name) ⇒ RBS::Definition?
The resolved singleton (class object) definition for ‘class_name`. The methods on this definition are the *class methods* of `class_name`, including those inherited from `Class` and `Module` for class types. Returns nil for unknown names and on RBS build errors (fail-soft).
105 106 107 108 109 110 |
# File 'lib/rigor/environment/rbs_loader.rb', line 105 def singleton_definition(class_name) key = class_name.to_s return @singleton_definition_cache[key] if @singleton_definition_cache.key?(key) @singleton_definition_cache[key] = build_singleton_definition(class_name) end |
#singleton_method(class_name:, method_name:) ⇒ RBS::Definition::Method?
Returns the class method on ‘class_name`. For example, `singleton_method(class_name: “Integer”, method_name: :sqrt)` returns the definition for `Integer.sqrt`, while `singleton_method(class_name: “Foo”, method_name: :new)` returns Class#new for any class type.
117 118 119 120 121 122 |
# File 'lib/rigor/environment/rbs_loader.rb', line 117 def singleton_method(class_name:, method_name:) definition = singleton_definition(class_name) return nil unless definition definition.methods[method_name.to_sym] end |