Class: Rigor::Environment
- Inherits:
-
Object
- Object
- Rigor::Environment
- Defined in:
- lib/rigor/environment.rb,
lib/rigor/environment/reporters.rb,
lib/rigor/environment/rbs_loader.rb,
lib/rigor/environment/reflection.rb,
lib/rigor/environment/rbs_hierarchy.rb,
lib/rigor/environment/class_registry.rb,
lib/rigor/environment/lockfile_resolver.rb,
lib/rigor/environment/hkt_registry_holder.rb,
lib/rigor/environment/rbs_coverage_report.rb,
lib/rigor/environment/bundle_sig_discovery.rb,
lib/rigor/environment/rbs_collection_discovery.rb,
lib/rigor/environment/constant_type_cache_holder.rb,
lib/rigor/environment/missing_gem_constant_index.rb,
sig/rigor/environment.rbs
Overview
The engine's view of the type universe outside the current scope. Slice 1 exposed only the class registry; Slice 4 added the RBS loader, which threads through ExpressionTyper and MethodDispatcher to type constant references and method calls that the literal-typer and constant-folding tiers cannot answer.
See docs/internal-spec/inference-engine.md for the binding contract.
Defined Under Namespace
Modules: BundleSigDiscovery, LockfileResolver, MissingGemConstantIndex, RbsCollectionDiscovery, RbsCoverageReport Classes: ClassRegistry, ConstantTypeCacheHolder, HktRegistryHolder, RbsHierarchy, RbsLoader, Reflection, Reporters
Constant Summary collapse
- DEFAULT_LIBRARIES =
Slice A stdlib expansion. Stdlib libraries that
Environment.for_projectloads on top of RBS core unless the caller passes an explicitlibraries:array. Each entry MUST be a stdlib library name accepted byRBS::EnvironmentLoader#has_library?; unknown libraries MUST fail-soft (RbsLoader#build_envalready filters throughhas_library?). The default set covers the common stdlib surface a Ruby program is likely to import (pathname,optparse,json,yaml,fileutils,tempfile,uri,logger,date) plus the analyzer-adjacent gems shipping their own RBS in this bundle (prism,rbs). On hosts where one of these libraries is not installed, the loader silently drops it.Callers MAY add to the default by passing
libraries: %w[csv ...]; the explicit list is appended toDEFAULT_LIBRARIESand de-duplicated. Callers that need a strictly RBS-core view MUST construct anRbsLoaderdirectly instead of going throughfor_project. %w[ pathname optparse json yaml fileutils tempfile tmpdir stringio forwardable digest securerandom uri logger date pp delegate observable abbrev find tsort singleton shellwords benchmark base64 did_you_mean monitor mutex_m timeout open3 erb etc ipaddr bigdecimal bigdecimal-math prettyprint random-formatter time open-uri resolv csv pstore objspace io-console cgi cgi-escape strscan prism rbs ].freeze
- GEM_OVERLAY_PLUGIN_IDS =
ADR-72 — a Gemfile.lock gem name mapped to the opt-in plugin id that ships the SAME core-ext RBS. When that plugin is loaded the auto-overlay for the gem stands down, so the two never both declare the methods (which would raise a duplicate-declaration error). Keyed on the gem name
RbsCoverageReportreports. { "activesupport" => "activesupport-core-ext" }.freeze
Instance Attribute Summary collapse
-
#class_registry ⇒ ClassRegistry
readonly
Returns the value of attribute class_registry.
-
#dependency_source_index ⇒ Object?
readonly
Returns the value of attribute dependency_source_index.
-
#hkt_registry ⇒ Object?
readonly
ADR-20 slices 2e + 6 — lazy HKT registry getter.
-
#name_scope ⇒ Object?
readonly
Returns the value of attribute name_scope.
-
#plugin_registry ⇒ Object?
readonly
Returns the value of attribute plugin_registry.
-
#project_patched_methods ⇒ Object?
readonly
Returns the value of attribute project_patched_methods.
-
#rbs_loader ⇒ RbsLoader?
readonly
Returns the value of attribute rbs_loader.
-
#reporters ⇒ Object
readonly
Returns the value of attribute reporters.
-
#synthetic_method_index ⇒ Object?
readonly
Returns the value of attribute synthetic_method_index.
Class Method Summary collapse
- .default ⇒ Environment
-
.for_project(root: Dir.pwd, libraries: [], signature_paths: nil, cache_store: nil, plugin_registry: nil, dependency_source_index: nil, rbs_extended_reporter: nil, boundary_cross_reporter: nil, source_rbs_synthesis_reporter: nil, bundler_bundle_path: nil, bundler_auto_detect: false, bundler_lockfile: nil, rbs_collection_lockfile: nil, rbs_collection_auto_detect: false, synthetic_method_index: nil, project_patched_methods: nil, source_files: []) ⇒ Rigor::Environment
Builds an Environment that consults the project's local signatures and any opt-in stdlib libraries on top of RBS core.
Instance Method Summary collapse
-
#attach_reporters!(rbs_extended_reporter:, boundary_cross_reporter:) ⇒ nil
Replaces the env's per-run reporter slots.
- #boundary_cross_reporter ⇒ Object?
-
#class_known?(name) ⇒ Boolean
Returns true when the constant name is known to either the static registry or the RBS loader.
-
#class_ordering(lhs, rhs) ⇒ ordering
Compares two class/module names using analyzer-owned class data.
-
#constant_for_name(name) ⇒ Type::t?
Slice A constant-value lookup.
-
#initialize(class_registry: ClassRegistry.default, rbs_loader: nil, plugin_registry: nil, dependency_source_index: nil, rbs_extended_reporter: nil, boundary_cross_reporter: nil, source_rbs_synthesis_reporter: nil, synthetic_method_index: nil, project_patched_methods: nil, hkt_registry: nil, missing_rbs_gems: [], missing_rbs_bundle_path: nil) ⇒ Environment
constructor
A new instance of Environment.
-
#missing_rbs_gem_owner(root_constant_name) ⇒ String?
ADR-82 WD9 — the gem name owning
root_constant_name, when that gem is locked in the project's Gemfile.lock, ships no resolvable RBS, and its entry file declares the constant at top level. -
#nominal_for_name(name) ⇒ Type::Nominal?
Resolves a constant name to a Rigor::Type::Nominal (the instance type carrier).
-
#rbs_extended_reporter ⇒ Object?
Backwards-compatible reporter accessors — every existing consumer (rbs_extended, method_dispatcher) calls these.
-
#rbs_module?(name) ⇒ Boolean
Returns true when the RBS environment carries the named declaration as a Module (not a Class).
-
#reflection ⇒ Object?
ADR-15 Phase 2b — returns the loader's read-only,
Ractor.shareable?query surface as a frozen Reflection. -
#singleton_for_name(name) ⇒ Type::Singleton?
Resolves a constant name to a Rigor::Type::Singleton (the class object carrier).
-
#source_rbs_synthesis_reporter ⇒ Object?
ADR-32 WD6 — the per-run accumulator for synthesizer failure events.
Constructor Details
#initialize(class_registry: ClassRegistry.default, rbs_loader: nil, plugin_registry: nil, dependency_source_index: nil, rbs_extended_reporter: nil, boundary_cross_reporter: nil, source_rbs_synthesis_reporter: nil, synthetic_method_index: nil, project_patched_methods: nil, hkt_registry: nil, missing_rbs_gems: [], missing_rbs_bundle_path: nil) ⇒ Environment
Returns a new instance of Environment.
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/rigor/environment.rb', line 83 def initialize(class_registry: ClassRegistry.default, rbs_loader: nil, # rubocop:disable Metrics/ParameterLists plugin_registry: nil, dependency_source_index: nil, rbs_extended_reporter: nil, boundary_cross_reporter: nil, source_rbs_synthesis_reporter: nil, synthetic_method_index: nil, project_patched_methods: nil, hkt_registry: nil, missing_rbs_gems: [], missing_rbs_bundle_path: nil) @class_registry = class_registry @rbs_loader = rbs_loader @plugin_registry = plugin_registry @dependency_source_index = dependency_source_index # ADR-pending — reporters live in a mutable container so long-lived integrations (LSP `ProjectContext`) # can swap them per `Runner.run` without rebuilding the env. The existing `#rbs_extended_reporter` / # `#boundary_cross_reporter` accessors below preserve the public lookup shape. @reporters = Reporters.new( rbs_extended: rbs_extended_reporter, boundary_cross: boundary_cross_reporter, source_rbs_synthesis: source_rbs_synthesis_reporter ) @synthetic_method_index = synthetic_method_index || Inference::SyntheticMethodIndex::EMPTY @project_patched_methods = project_patched_methods || Inference::ProjectPatchedMethods::EMPTY # ADR-20 slice 2c + 2e — the per-env HKT registry consulted by the reducer when resolving `Type::App` # carriers. Defaults to {Inference::HktRegistry::EMPTY}; the {.default} / {.for_project} class methods # seed it with the bundled builtins (`json::value`, …) plus any `%a{rigor:v1:hkt_register / # hkt_define}` annotations the RBS loader exposes. The hkt_registry getter (defined below) MEMOIZES # the result of merging the base with the RBS scan so the scan is paid at most once per Environment # lifetime — and only when first consulted, leaving fast paths like `rigor check --cache-stats # --no-stats` from doing the RBS env build at all. @hkt_registry_base = hkt_registry || Inference::HktRegistry::EMPTY @hkt_registry_holder = HktRegistryHolder.new @constant_type_cache = ConstantTypeCacheHolder.new # ADR-82 WD9 — `[gem_name, version]` pairs for the locked gems with no resolvable RBS. The # root-constant ownership index over them is built lazily (first unresolved constant read) so runs # whose constants all resolve never pay the entry-file scan. @missing_rbs_gems = missing_rbs_gems.freeze @missing_rbs_bundle_path = missing_rbs_bundle_path @missing_rbs_gem_constants_holder = HktRegistryHolder.new @name_scope = build_name_scope freeze end |
Instance Attribute Details
#class_registry ⇒ ClassRegistry (readonly)
Returns the value of attribute class_registry.
67 68 69 |
# File 'lib/rigor/environment.rb', line 67 def class_registry @class_registry end |
#dependency_source_index ⇒ Object? (readonly)
Returns the value of attribute dependency_source_index.
67 68 69 |
# File 'lib/rigor/environment.rb', line 67 def dependency_source_index @dependency_source_index end |
#hkt_registry ⇒ Object? (readonly)
ADR-20 slices 2e + 6 — lazy HKT registry getter. Merge order on first call: builtins (base) ← plugin
manifest aggregation ← RBS env scan. Last-write-wins on URI collisions so user-authored .rbs overlays
beat plugin entries, which beat the bundled JSON_VALUE. Memoised; single-threaded use only (under the
Ractor pool path each worker has its own Environment so cross-worker mutation is impossible; the LSP
single-publish-at-a-time invariant serialises here).
128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/rigor/environment.rb', line 128 def hkt_registry @hkt_registry_holder.fetch do = if @plugin_registry.respond_to?(:hkt_overlay_registry) @hkt_registry_base.merge(@plugin_registry.) else @hkt_registry_base end Inference::HktRegistry.scan_rbs_loader( @rbs_loader, base: , reporter: rbs_extended_reporter ) end end |
#name_scope ⇒ Object? (readonly)
Returns the value of attribute name_scope.
67 68 69 |
# File 'lib/rigor/environment.rb', line 67 def name_scope @name_scope end |
#plugin_registry ⇒ Object? (readonly)
Returns the value of attribute plugin_registry.
67 68 69 |
# File 'lib/rigor/environment.rb', line 67 def plugin_registry @plugin_registry end |
#project_patched_methods ⇒ Object? (readonly)
Returns the value of attribute project_patched_methods.
67 68 69 |
# File 'lib/rigor/environment.rb', line 67 def project_patched_methods @project_patched_methods end |
#rbs_loader ⇒ RbsLoader? (readonly)
Returns the value of attribute rbs_loader.
67 68 69 |
# File 'lib/rigor/environment.rb', line 67 def rbs_loader @rbs_loader end |
#reporters ⇒ Object (readonly)
Returns the value of attribute reporters.
67 68 69 |
# File 'lib/rigor/environment.rb', line 67 def reporters @reporters end |
#synthetic_method_index ⇒ Object? (readonly)
Returns the value of attribute synthetic_method_index.
67 68 69 |
# File 'lib/rigor/environment.rb', line 67 def synthetic_method_index @synthetic_method_index end |
Class Method Details
.default ⇒ Environment
192 193 194 195 196 197 |
# File 'lib/rigor/environment.rb', line 192 def default @default ||= new( rbs_loader: RbsLoader.default, hkt_registry: Builtins::HktBuiltins.registry ).freeze end |
.for_project(root: Dir.pwd, libraries: [], signature_paths: nil, cache_store: nil, plugin_registry: nil, dependency_source_index: nil, rbs_extended_reporter: nil, boundary_cross_reporter: nil, source_rbs_synthesis_reporter: nil, bundler_bundle_path: nil, bundler_auto_detect: false, bundler_lockfile: nil, rbs_collection_lockfile: nil, rbs_collection_auto_detect: false, synthetic_method_index: nil, project_patched_methods: nil, source_files: []) ⇒ Rigor::Environment
Builds an Environment that consults the project's local signatures and any opt-in stdlib libraries on top of RBS core.
rubocop:disable Metrics/MethodLength, Metrics/ParameterLists
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 |
# File 'lib/rigor/environment.rb', line 215 def for_project(root: Dir.pwd, libraries: [], signature_paths: nil, cache_store: nil, plugin_registry: nil, dependency_source_index: nil, rbs_extended_reporter: nil, boundary_cross_reporter: nil, source_rbs_synthesis_reporter: nil, bundler_bundle_path: nil, bundler_auto_detect: false, bundler_lockfile: nil, rbs_collection_lockfile: nil, rbs_collection_auto_detect: false, synthetic_method_index: nil, project_patched_methods: nil, source_files: []) resolved_paths = signature_paths || default_signature_paths(root) # O4 MVP — append per-gem `sig/` directories discovered under the target project's bundler install # root. Empty array when neither an explicit path nor auto-detection finds a bundle. Order: user # `signature_paths:` win first (semantic precedence inside `RbsLoader.build_env_for`); gem-shipped # sigs append last so user overrides stay authoritative. # # O4 Layer 3 — when a Gemfile.lock is available (explicit `bundler_lockfile:` or auto-detected next # to the project root), use the locked gem set to filter the discovered `sig/` directories. Stale # gems in the bundle install tree (out-of-band installs, version drift after a `bundle update`) are # silently dropped so only gems the project actually declares contribute RBS. locked = LockfileResolver.locked_gems( lockfile_path: bundler_lockfile, project_root: root, auto_detect: bundler_auto_detect ) gem_sig_paths = BundleSigDiscovery.discover( bundle_path: bundler_bundle_path, project_root: root, auto_detect: bundler_auto_detect, locked_gems: locked.empty? ? nil : locked ).map(&:to_s) # ADR-82 WD9 — the resolved bundle root, so the missing-gem constant index reads each RBS-less gem's # entry file from the TARGET's bundle (not rigor's own — see `MissingGemConstantIndex`). Resolved # once here; passed through to the lazy index build. bundle_root = BundleSigDiscovery.resolve_bundle_path( bundle_path: bundler_bundle_path, project_root: root, auto_detect: bundler_auto_detect )&.to_s # O4 Layer 3 slice 2 — when `rbs collection install` has been run for the target project, parse the # resulting `rbs_collection.lock.yaml` and feed each gem's `<collection_path>/<name>/<version>/` # directory into `signature_paths:`. Stdlib-typed entries are skipped (already covered by # `DEFAULT_LIBRARIES`), as are gems whose RBS rigor already loads from another source — # stdlib-extracted default gems (`cgi`, `logger`, …, shipped by the collection under a `git` source) # and the `data/vendored_gem_sigs/` bundle (`redis`, `nokogiri`, `pg`, …). `skip_gem_names:` passes # both sets so the collection copy doesn't double-declare against rigor's bundled RBS (the # `RBS::DuplicatedDeclarationError` hazard). merged_libraries = (DEFAULT_LIBRARIES + libraries.map(&:to_s)).uniq skip_gem_names = merged_libraries + RbsLoader.vendored_gem_names collection_paths = RbsCollectionDiscovery.discover( lockfile_path: rbs_collection_lockfile, project_root: root, auto_detect: rbs_collection_auto_detect, skip_gem_names: skip_gem_names ).map(&:to_s) # ADR-25 — RBS signature directories contributed by loaded plugins via their manifest # `signature_paths:`. Resolved to absolute dirs by `Plugin::Base#signature_paths`; additive, ranked # below the user's explicit `signature_paths:` and above the opportunistic bundle / collection # discovery. A duplicate-declaration conflict degrades through the same O7 failure-memo path. plugin_sig_paths = plugin_registry ? plugin_registry.signature_paths.map(&:to_s) : [] # ADR-72 — Gemfile.lock-gated bundled RBS overlays. For each locked gem that ships no RBS through any # resolution path (`:missing`) and has a Rigor-bundled overlay, load that overlay so its core-class # extensions resolve (e.g. `Integer#minutes` on a Rails project) — turning a systematic false # `call.undefined-method` into a no-op while a project WITHOUT the gem still sees the genuine # diagnostic. Appended last so any RBS the project already supplies wins, and skipped for a gem whose # opt-in plugin twin is loaded (no duplicate declaration). The paths ride in # `loader_signature_paths`, so the env cache descriptor digests them for free. missing_gems, = ( locked: locked, default_libraries: merged_libraries, bundle_sig_paths: gem_sig_paths, rbs_collection_paths: collection_paths, plugin_registry: plugin_registry ) loader_signature_paths = resolved_paths + plugin_sig_paths + gem_sig_paths + collection_paths + # ADR-32 WD4 + WD5 — invoke each loaded plugin's `source_rbs_synthesizer` once per project source # file and collect non-nil `[filename, rbs_source]` pairs. The synthesizer-emitting plugin (currently # only `rigor-rbs-inline`) is responsible for its own fail-soft on parse errors per WD6; this loop # only filters `nil` returns. # # When a `cache_store` is supplied, each synthesizer invocation is memoised per `(file path + content # SHA, plugin id + version + config_hash)` — WD5's cache key — so a second run with unchanged source # skips the rbs-inline parse cost. The empty string is the sentinel for "no contribution" so the # Store (which treats `nil` as cache miss) can persist the no-contribution decision too. virtual_rbs = collect_virtual_rbs(plugin_registry, source_files, cache_store, source_rbs_synthesis_reporter) loader = RbsLoader.new( libraries: merged_libraries, signature_paths: loader_signature_paths, cache_store: cache_store, virtual_rbs: virtual_rbs ) # ADR-20 slice 2c + 2e — seed hkt_registry with the bundled builtins. The Environment's # `#hkt_registry` getter then LAZILY merges in the RBS env scan on first call so fast paths that # don't consult HKT (e.g. `rigor check --cache-stats --no-stats`) don't pay the eager env-build cost # up front. URI collisions let the user-authored overlay win over the bundled builtin # (last-write-wins per ADR-20 OQ3 tentative). new( rbs_loader: loader, plugin_registry: plugin_registry, dependency_source_index: dependency_source_index, rbs_extended_reporter: rbs_extended_reporter, boundary_cross_reporter: boundary_cross_reporter, source_rbs_synthesis_reporter: source_rbs_synthesis_reporter, synthetic_method_index: synthetic_method_index, project_patched_methods: project_patched_methods, hkt_registry: Builtins::HktBuiltins.registry, missing_rbs_gems: missing_gems, missing_rbs_bundle_path: bundle_root ) end |
Instance Method Details
#attach_reporters!(rbs_extended_reporter:, boundary_cross_reporter:) ⇒ nil
Replaces the env's per-run reporter slots. Intended for long-lived integrations (LSP ProjectContext)
that share one Environment instance across many Runner.run calls: each call attaches its own fresh
reporter pair so per-call diagnostic events stay scoped to that call rather than accumulating across
publishes.
Single-threaded use only. Concurrent publishes against one Environment must serialise — the LSP
Server debouncer + synchronized writer already enforces this for the editor path. The Ractor pool
path builds a per-worker Environment and does not reach this surface.
185 186 187 188 189 |
# File 'lib/rigor/environment.rb', line 185 def attach_reporters!(rbs_extended_reporter:, boundary_cross_reporter:) @reporters.rbs_extended = rbs_extended_reporter @reporters.boundary_cross = boundary_cross_reporter nil end |
#boundary_cross_reporter ⇒ Object?
165 166 167 |
# File 'lib/rigor/environment.rb', line 165 def boundary_cross_reporter @reporters.boundary_cross end |
#class_known?(name) ⇒ Boolean
Returns true when the constant name is known to either the static registry or the RBS loader. Useful for callers that only need a presence check without materialising a type carrier.
505 506 507 508 509 510 511 512 513 |
# File 'lib/rigor/environment.rb', line 505 def class_known?(name) return true if class_registry.nominal_for_name(name) return true if class_known_in_rbs?(name) # ADR-36 nested-class emission — a variant subclass the substrate synthesised (e.g. `Shape::Circle` # from a `variants do variant Circle, Float end` block) is a real class for resolution purposes even # though no RBS / source declares it. @synthetic_method_index&.knows_class?(name) || false end |
#class_ordering(lhs, rhs) ⇒ ordering
Compares two class/module names using analyzer-owned class data. Returns :equal, :subclass,
:superclass, :disjoint, or :unknown. The static registry handles built-ins cheaply; the RBS
loader handles project/stdlib classes without relying on host Ruby constants being loaded.
536 537 538 539 540 541 542 543 544 545 546 547 |
# File 'lib/rigor/environment.rb', line 536 def class_ordering(lhs, rhs) lhs = normalize_class_name(lhs) rhs = normalize_class_name(rhs) return :equal if lhs == rhs registry_result = class_registry.class_ordering(lhs, rhs) return registry_result unless registry_result == :unknown return :unknown unless rbs_loader rbs_loader.class_ordering(lhs, rhs) end |
#constant_for_name(name) ⇒ Type::t?
Slice A constant-value lookup. Returns the translated Rigor::Type for an RBS-declared non-class
constant (Rigor::Analysis::FactStore::BUCKETS: Array[Symbol], Rigor::Configuration::DEFAULT_PATH: String, ...) or nil when no RBS constant declaration covers name. This is the value-bearing
counterpart of #singleton_for_name, which only resolves names that name a class or module. Callers
that need to type a Prism::ConstantReadNode/ Prism::ConstantPathNode MUST consult
#singleton_for_name first and fall through to this query when the constant is not a class.
491 492 493 494 495 496 497 498 499 500 501 |
# File 'lib/rigor/environment.rb', line 491 def constant_for_name(name) return nil if rbs_loader.nil? # Pure function of `name` for this Environment's lifetime — the refinement table and the RBS constant # table are both fixed — so memoise across the lexical-candidate ladder's heavy name reuse. key = name.to_s @constant_type_cache.fetch(key) do Builtins::PredefinedConstantRefinements.lookup(key) || rbs_loader.constant_type(key) end end |
#missing_rbs_gem_owner(root_constant_name) ⇒ String?
ADR-82 WD9 — the gem name owning root_constant_name, when that gem is locked in the project's
Gemfile.lock, ships no resolvable RBS, and its entry file declares the constant at top level. Nil for
everything else — the caller then keeps the generic provenance cause. The index is built once, lazily,
from RubyGems metadata + a Prism parse of each gem's entry file; no gem code runs (see
MissingGemConstantIndex). Under the fork pool a worker that never meets an unresolved constant never
builds it.
149 150 151 152 153 154 155 156 |
# File 'lib/rigor/environment.rb', line 149 def missing_rbs_gem_owner(root_constant_name) return nil if @missing_rbs_gems.empty? index = @missing_rbs_gem_constants_holder.fetch do MissingGemConstantIndex.build(@missing_rbs_gems, bundle_path: @missing_rbs_bundle_path) end index[root_constant_name.to_s] end |
#nominal_for_name(name) ⇒ Type::Nominal?
Resolves a constant name to a Rigor::Type::Nominal (the instance type carrier). Consults the static class registry first (cheap, hardcoded), then falls back to the RBS loader. Returns nil when the name is unknown to both.
NOTE: This is the construction helper for "an instance of class Foo". For "the class object Foo
itself" (the value of the constant), use #singleton_for_name instead.
466 467 468 469 470 471 |
# File 'lib/rigor/environment.rb', line 466 def nominal_for_name(name) registered = class_registry.nominal_for_name(name) return registered if registered class_known_in_rbs?(name) ? Type::Combinator.nominal_of(name.to_s) : nil end |
#rbs_extended_reporter ⇒ Object?
Backwards-compatible reporter accessors — every existing consumer (rbs_extended, method_dispatcher)
calls these. The frozen @reporters container is mutable for slot reassignment via
#attach_reporters! below.
161 162 163 |
# File 'lib/rigor/environment.rb', line 161 def rbs_extended_reporter @reporters.rbs_extended end |
#rbs_module?(name) ⇒ Boolean
Returns true when the RBS environment carries the named declaration as a Module (not a Class). Used by
the user_class_fallback_receiver tier to detect a module-mixin receiver (e.g. PP::ObjectMixin) so
the dispatcher can route unresolved method calls through the Nominal[Object] fallback — every
concrete includer of M honours Kernel / Object instance methods through its own ancestor chain.
527 528 529 530 531 |
# File 'lib/rigor/environment.rb', line 527 def rbs_module?(name) return false unless rbs_loader rbs_loader.rbs_module?(name) end |
#reflection ⇒ Object?
ADR-15 Phase 2b — returns the loader's read-only, Ractor.shareable? query surface as a frozen
Reflection. Built lazily on first access; subsequent calls return the same instance.
Returns nil when the environment carries no RBS loader (test-only Environment.new without
rbs_loader:).
519 520 521 |
# File 'lib/rigor/environment.rb', line 519 def reflection @rbs_loader&.reflection end |
#singleton_for_name(name) ⇒ Type::Singleton?
Resolves a constant name to a Rigor::Type::Singleton (the class object carrier). The expression Foo
evaluates to the class object, whose RBS type is singleton(Foo) -- this method is the corresponding
Rigor construction helper.
The lookup uses the same registry/RBS chain as #nominal_for_name so a class is either known to both queries or to neither.
479 480 481 482 483 |
# File 'lib/rigor/environment.rb', line 479 def singleton_for_name(name) return nil unless class_known?(name) Type::Combinator.singleton_of(name.to_s) end |
#source_rbs_synthesis_reporter ⇒ Object?
ADR-32 WD6 — the per-run accumulator for synthesizer failure events. Environment.for_project records
[:error, message] returns from a plugin's source_rbs_synthesizer here so the Runner can emit
source-rbs-synthesis-failed :info diagnostics after analysis completes. Nil when no plugin
contributes a synthesizer.
173 174 175 |
# File 'lib/rigor/environment.rb', line 173 def source_rbs_synthesis_reporter @reporters.source_rbs_synthesis end |