Class: Rigor::Plugin::Registry
- Inherits:
-
Object
- Object
- Rigor::Plugin::Registry
- Defined in:
- lib/rigor/plugin/registry.rb
Overview
Read-side query API over the plugins loaded for a single ‘Analysis::Runner.run`. Constructed by Loader.load and exposed downstream so the contribution merger (slice 3) and diagnostic provenance (slice 5) can iterate over loaded plugin instances in deterministic order.
The registry is read-only after construction; ordering is the order in which Loader resolved configuration entries, which is project-config order with plugin-id alphabetical as the tie-breaker.
ADR-15 Phase 3 — alongside the instantiated ‘plugins`, the registry carries `blueprints`: a frozen, Ractor-shareable `Array<Blueprint>` that records how to re-instantiate the same plugin set in a worker Ractor. The eventual Phase 4 pool ships `blueprints` across the boundary and calls Registry.materialize per-Ractor; the live `plugins` carriage on the coordinator registry stays unchanged.
Constant Summary collapse
- EMPTY =
new.freeze
Instance Attribute Summary collapse
-
#blueprints ⇒ Object
readonly
Returns the value of attribute blueprints.
-
#load_errors ⇒ Object
readonly
Returns the value of attribute load_errors.
-
#plugins ⇒ Object
readonly
Returns the value of attribute plugins.
Class Method Summary collapse
-
.materialize(blueprints:, services:) ⇒ Object
ADR-15 Phase 3 — build a fresh Registry from the supplied blueprint set by replaying Blueprint#materialize per entry against ‘services`.
Instance Method Summary collapse
- #any_load_errors? ⇒ Boolean
-
#contracts_for_path(path) ⇒ Object
ADR-28 — the subset of ‘protocol_contracts` whose `path_glob` matches `path`.
- #empty? ⇒ Boolean
- #find(id) ⇒ Object
-
#hkt_overlay_registry ⇒ Object
ADR-20 slice 6 — aggregate every loaded plugin’s manifest-declared HKT registrations + definitions into a single ‘Inference::HktRegistry` overlay that `Environment#hkt_registry` merges on top of the bundled `Builtins::HktBuiltins.registry`.
- #ids ⇒ Object
-
#initialize(plugins: [], load_errors: [], blueprints: []) ⇒ Registry
constructor
A new instance of Registry.
- #open_receiver?(class_name) ⇒ Boolean
-
#open_receivers ⇒ Object
ADR-26 — the aggregate set of “open” receiver class names declared across loaded plugins (manifest ‘open_receivers:`).
-
#protocol_contracts ⇒ Object
ADR-28 — flat, ordered list of every loaded plugin’s path-scoped method-protocol contracts, in plugin registration order.
-
#signature_paths ⇒ Object
ADR-25 — flat, ordered list of every loaded plugin’s resolved RBS signature directories (absolute paths), in plugin registration order.
-
#source_rbs_synthesizers ⇒ Object
ADR-32 WD4 + WD5 — flat ordered list of ‘[plugin, callable]` pairs for every loaded plugin that declares a `source_rbs_synthesizer:` in its manifest.
-
#type_node_resolvers ⇒ Object
ADR-13 slice 2 — flat ordered list of every loaded plugin’s manifest-declared TypeNodeResolver instances, in plugin registration order.
Constructor Details
#initialize(plugins: [], load_errors: [], blueprints: []) ⇒ Registry
Returns a new instance of Registry.
39 40 41 42 43 44 |
# File 'lib/rigor/plugin/registry.rb', line 39 def initialize(plugins: [], load_errors: [], blueprints: []) @plugins = plugins.dup.freeze @load_errors = load_errors.dup.freeze @blueprints = blueprints.dup.freeze freeze end |
Instance Attribute Details
#blueprints ⇒ Object (readonly)
Returns the value of attribute blueprints.
27 28 29 |
# File 'lib/rigor/plugin/registry.rb', line 27 def blueprints @blueprints end |
#load_errors ⇒ Object (readonly)
Returns the value of attribute load_errors.
27 28 29 |
# File 'lib/rigor/plugin/registry.rb', line 27 def load_errors @load_errors end |
#plugins ⇒ Object (readonly)
Returns the value of attribute plugins.
27 28 29 |
# File 'lib/rigor/plugin/registry.rb', line 27 def plugins @plugins end |
Class Method Details
.materialize(blueprints:, services:) ⇒ Object
ADR-15 Phase 3 — build a fresh Registry from the supplied blueprint set by replaying Blueprint#materialize per entry against ‘services`. The returned registry carries NEW plugin instances (mutable per-Ractor accumulators included) and the same blueprint set, so a worker can hand the materialised registry to Environment without losing the replay handle. `load_errors` is intentionally empty: load-time failures already surfaced in the coordinator registry and don’t repeat per worker.
55 56 57 58 |
# File 'lib/rigor/plugin/registry.rb', line 55 def self.materialize(blueprints:, services:) plugins = blueprints.map { |bp| bp.materialize(services: services) } new(plugins: plugins, blueprints: blueprints, load_errors: []) end |
Instance Method Details
#any_load_errors? ⇒ Boolean
73 74 75 |
# File 'lib/rigor/plugin/registry.rb', line 73 def any_load_errors? !load_errors.empty? end |
#contracts_for_path(path) ⇒ Object
ADR-28 — the subset of ‘protocol_contracts` whose `path_glob` matches `path`. Contract globs are authored project-root-relative (`lib/controller/*/.rb`); the analyzer may hand this method either a project-relative path (`rigor check` run from the project root) or an absolute one (run from elsewhere, or a spec tmpdir), so the glob is matched both directly and as a `**/`-prefixed path suffix. `File::FNM_PATHNAME` keeps `*` from crossing `/`; `File::FNM_EXTGLOB` enables `a,b` groups. Returns `[]` for a nil path so the binder can call this unconditionally.
156 157 158 159 160 161 |
# File 'lib/rigor/plugin/registry.rb', line 156 def contracts_for_path(path) return [] if path.nil? path_s = path.to_s protocol_contracts.select { |contract| path_matches_glob?(contract.path_glob, path_s) } end |
#empty? ⇒ Boolean
69 70 71 |
# File 'lib/rigor/plugin/registry.rb', line 69 def empty? plugins.empty? end |
#find(id) ⇒ Object
60 61 62 63 |
# File 'lib/rigor/plugin/registry.rb', line 60 def find(id) id_s = id.to_s plugins.find { |plugin| plugin.manifest.id == id_s } end |
#hkt_overlay_registry ⇒ Object
ADR-20 slice 6 — aggregate every loaded plugin’s manifest-declared HKT registrations + definitions into a single ‘Inference::HktRegistry` overlay that `Environment#hkt_registry` merges on top of the bundled `Builtins::HktBuiltins.registry`. Last plugin to register a URI wins (registration order determined by the user’s ‘plugins:` list); user `.rbs` overlays merge on top of this overlay last. Returns `Inference::HktRegistry::EMPTY` when no plugin contributes HKT entries so callers can skip the merge.
99 100 101 102 103 104 105 |
# File 'lib/rigor/plugin/registry.rb', line 99 def registrations = plugins.flat_map { |plugin| plugin.manifest.hkt_registrations } definitions = plugins.flat_map { |plugin| plugin.manifest.hkt_definitions } return Inference::HktRegistry::EMPTY if registrations.empty? && definitions.empty? Inference::HktRegistry.new(registrations: registrations, definitions: definitions) end |
#ids ⇒ Object
65 66 67 |
# File 'lib/rigor/plugin/registry.rb', line 65 def ids plugins.map { |plugin| plugin.manifest.id } end |
#open_receiver?(class_name) ⇒ Boolean
127 128 129 130 131 |
# File 'lib/rigor/plugin/registry.rb', line 127 def open_receiver?(class_name) return false if class_name.nil? open_receivers.include?(class_name.to_s) end |
#open_receivers ⇒ Object
ADR-26 — the aggregate set of “open” receiver class names declared across loaded plugins (manifest ‘open_receivers:`). A class is open when a plugin vouches that it responds beyond its RBS-declared method surface. `open_receiver?` is the membership predicate `Analysis::CheckRules` consults to skip the `call.undefined-method` rule for such a class.
123 124 125 |
# File 'lib/rigor/plugin/registry.rb', line 123 def open_receivers plugins.flat_map { |plugin| plugin.manifest.open_receivers } end |
#protocol_contracts ⇒ Object
ADR-28 — flat, ordered list of every loaded plugin’s path-scoped method-protocol contracts, in plugin registration order. Read from each plugin’s ‘#protocol_contracts` (which the manifest backs by default but a plugin MAY override to fold in per-project config). Consumed by `Inference::MethodParameterBinder` (the parameter-type provision) and by contributing plugins’ ‘#diagnostics_for_file` hooks (the presence + return-type check).
142 143 144 |
# File 'lib/rigor/plugin/registry.rb', line 142 def protocol_contracts plugins.flat_map(&:protocol_contracts) end |
#signature_paths ⇒ Object
ADR-25 — flat, ordered list of every loaded plugin’s resolved RBS signature directories (absolute paths), in plugin registration order. ‘Environment.for_project` merges these into the signature-path set fed to `RbsLoader`, alongside the configuration’s ‘signature_paths:` and the `bundler:` / `rbs_collection:` discovery output.
113 114 115 |
# File 'lib/rigor/plugin/registry.rb', line 113 def signature_paths plugins.flat_map(&:signature_paths) end |
#source_rbs_synthesizers ⇒ Object
ADR-32 WD4 + WD5 — flat ordered list of ‘[plugin, callable]` pairs for every loaded plugin that declares a `source_rbs_synthesizer:` in its manifest. The engine invokes each callable once per analysed Ruby source file at env-build time; non-nil return strings are merged into the RBS environment as virtual signature sources. The full plugin instance is carried alongside the callable so the engine’s cache layer (WD5) can compose ‘plugin.plugin_entry` into its per-file descriptor — a config change to the plugin (e.g. flipping `require_magic_comment:`) invalidates the dependent synthesizer cache without any plugin-side bookkeeping.
175 176 177 178 179 180 181 182 |
# File 'lib/rigor/plugin/registry.rb', line 175 def source_rbs_synthesizers plugins.filter_map do |plugin| synthesizer = plugin.manifest.source_rbs_synthesizer next nil if synthesizer.nil? [plugin, synthesizer] end end |
#type_node_resolvers ⇒ Object
ADR-13 slice 2 — flat ordered list of every loaded plugin’s manifest-declared TypeNodeResolver instances, in plugin registration order. Slice 3 wires this into the parser’s resolver chain; until then the method is a read-side aggregator only. The first non-nil ‘#resolve(node, scope)` return wins per ADR-13 WD3 / WD5 — registration order is the user’s lever.
84 85 86 |
# File 'lib/rigor/plugin/registry.rb', line 84 def type_node_resolvers plugins.flat_map { |plugin| plugin.manifest.type_node_resolvers } end |