rigortype 0.3.8 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/data/capability_roles/capability_roles.rbs +36 -0
- data/data/core_overlay/enumerable.rbs +51 -0
- data/data/core_overlay/enumerator.rbs +84 -0
- data/data/core_overlay/hash_rbs3.rbs +41 -0
- data/data/core_overlay/process.rbs +40 -0
- data/data/core_overlay/string_io.rbs +33 -0
- data/data/effects/core.yml +3 -3
- data/data/gem_overlay/activesupport/core_ext.rbs +236 -17
- data/docs/handbook/02-everyday-types.md +17 -14
- data/docs/handbook/03-narrowing.md +132 -14
- data/docs/handbook/04-tuples-and-shapes.md +8 -6
- data/docs/handbook/05-methods-and-blocks.md +1 -1
- data/docs/handbook/06-classes.md +2 -2
- data/docs/handbook/07-rbs-and-extended.md +19 -1
- data/docs/handbook/10-sorbet.md +9 -10
- data/docs/handbook/11-sig-gen.md +525 -13
- data/docs/handbook/README.md +1 -1
- data/docs/handbook/appendix-elixir.md +2 -2
- data/docs/handbook/appendix-go.md +2 -2
- data/docs/handbook/appendix-java-csharp.md +2 -2
- data/docs/handbook/appendix-mypy.md +2 -2
- data/docs/handbook/appendix-phpstan.md +1 -1
- data/docs/handbook/appendix-rust.md +1 -1
- data/docs/handbook/appendix-type-theory.md +4 -4
- data/docs/handbook/appendix-typescript.md +1 -1
- data/docs/llms.txt +2 -0
- data/docs/manual/02-cli-reference.md +95 -6
- data/docs/manual/03-configuration.md +18 -0
- data/docs/manual/04-diagnostics.md +15 -0
- data/docs/manual/07-plugins.md +15 -5
- data/docs/manual/08-skills.md +23 -2
- data/docs/manual/10-mcp-server.md +3 -2
- data/docs/manual/11-ci.md +9 -0
- data/docs/manual/15-type-protection-coverage.md +8 -0
- data/docs/manual/16-rbs-extended-annotations.md +46 -8
- data/docs/manual/18-removing-dead-code.md +10 -8
- data/docs/manual/19-effect-labels.md +10 -0
- data/docs/manual/plugins/README.md +7 -0
- data/docs/manual/plugins/rigor-actioncable.md +8 -1
- data/docs/manual/plugins/rigor-actionmailer.md +7 -0
- data/docs/manual/plugins/rigor-actionpack.md +261 -0
- data/docs/manual/plugins/rigor-active-model-serializers.md +153 -0
- data/docs/manual/plugins/rigor-activejob.md +7 -0
- data/docs/manual/plugins/rigor-activerecord.md +138 -4
- data/docs/manual/plugins/rigor-activestorage.md +8 -1
- data/docs/manual/plugins/rigor-activesupport-core-ext.md +43 -7
- data/docs/manual/plugins/rigor-grape.md +106 -0
- data/docs/manual/plugins/rigor-graphql.md +23 -2
- data/docs/manual/plugins/rigor-pundit.md +8 -1
- data/docs/manual/plugins/rigor-rails-i18n.md +10 -5
- data/docs/manual/plugins/rigor-rails-routes.md +7 -0
- data/docs/manual/plugins/rigor-rbs-inline.md +229 -1
- data/docs/manual/plugins/rigor-sidekiq.md +8 -1
- data/docs/manual/plugins/rigor-sorbet.md +21 -5
- data/exe/rigor +19 -4
- data/lib/rigor/analysis/baseline.rb +3 -3
- data/lib/rigor/analysis/check_rules/always_truthy_condition_collector.rb +1 -1
- data/lib/rigor/analysis/check_rules/dead_version_guard_arms.rb +1 -5
- data/lib/rigor/analysis/check_rules/declaration_sourced_guard.rb +167 -2
- data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +10 -2
- data/lib/rigor/analysis/check_rules/lexical_method_sites.rb +189 -0
- data/lib/rigor/analysis/check_rules/main_pass_collector.rb +6 -4
- data/lib/rigor/analysis/check_rules/published_constant_guard.rb +15 -6
- data/lib/rigor/analysis/check_rules/rule_ids.rb +21 -6
- data/lib/rigor/analysis/check_rules/rule_walk.rb +41 -5
- data/lib/rigor/analysis/check_rules/self_closedness_scanner.rb +1 -1
- data/lib/rigor/analysis/check_rules/shadowed_rescue_collector.rb +1 -1
- data/lib/rigor/analysis/check_rules/source_arity.rb +323 -0
- data/lib/rigor/analysis/check_rules/special_global_setters.rb +146 -0
- data/lib/rigor/analysis/check_rules/unreachable_clause_collector.rb +38 -4
- data/lib/rigor/analysis/check_rules/void_value_use_collector.rb +0 -1
- data/lib/rigor/analysis/check_rules.rb +718 -79
- data/lib/rigor/analysis/crash_signature.rb +8 -24
- data/lib/rigor/analysis/dependency_recorder.rb +23 -0
- data/lib/rigor/analysis/dependency_source_inference/boundary_cross_reporter.rb +1 -1
- data/lib/rigor/analysis/dependency_source_inference/builder.rb +0 -2
- data/lib/rigor/analysis/dependency_source_inference/gem_resolver.rb +0 -2
- data/lib/rigor/analysis/dependency_source_inference/index.rb +5 -5
- data/lib/rigor/analysis/dependency_source_inference/return_type_heuristic.rb +1 -2
- data/lib/rigor/analysis/dependency_source_inference/walker.rb +4 -4
- data/lib/rigor/analysis/effects_cache_probe.rb +3 -4
- data/lib/rigor/analysis/erb_template_detector.rb +1 -2
- data/lib/rigor/analysis/fact_store.rb +15 -1
- data/lib/rigor/analysis/incremental.rb +42 -0
- data/lib/rigor/analysis/incremental_session.rb +117 -26
- data/lib/rigor/analysis/plugin_fact_fingerprint.rb +0 -1
- data/lib/rigor/analysis/project_scan.rb +11 -1
- data/lib/rigor/analysis/reachability/graph.rb +3 -5
- data/lib/rigor/analysis/reachability/plugin_roots.rb +5 -5
- data/lib/rigor/analysis/reachability/project_files.rb +2 -2
- data/lib/rigor/analysis/reachability/scan.rb +5 -5
- data/lib/rigor/analysis/reachability/scan_cache.rb +3 -2
- data/lib/rigor/analysis/reachability/signature_scan.rb +2 -2
- data/lib/rigor/analysis/result.rb +1 -3
- data/lib/rigor/analysis/rule_catalog.rb +131 -1
- data/lib/rigor/analysis/run_cache_key.rb +21 -12
- data/lib/rigor/analysis/run_cache_probe.rb +3 -5
- data/lib/rigor/analysis/runner/buffer_pool_dispatcher.rb +6 -8
- data/lib/rigor/analysis/runner/declaration_position.rb +1 -2
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +340 -33
- data/lib/rigor/analysis/runner/effect_annotation_residual_pass.rb +2 -3
- data/lib/rigor/analysis/runner/effect_envelope_pass.rb +18 -14
- data/lib/rigor/analysis/runner/pool_coordinator.rb +357 -97
- data/lib/rigor/analysis/runner/project_pre_passes.rb +38 -13
- data/lib/rigor/analysis/runner/run_snapshots.rb +6 -1
- data/lib/rigor/analysis/runner.rb +407 -51
- data/lib/rigor/analysis/template_unit_collector.rb +303 -0
- data/lib/rigor/analysis/template_unit_paths.rb +91 -0
- data/lib/rigor/analysis/template_unit_positions.rb +293 -0
- data/lib/rigor/analysis/template_units.rb +399 -0
- data/lib/rigor/analysis/worker_session.rb +62 -20
- data/lib/rigor/bleeding_edge.rb +10 -24
- data/lib/rigor/builtins/hkt_builtins.rb +3 -2
- data/lib/rigor/builtins/imported_refinements.rb +159 -21
- data/lib/rigor/builtins/predefined_constant_refinements.rb +5 -7
- data/lib/rigor/builtins/regex_refinement.rb +21 -13
- data/lib/rigor/builtins/static_return_refinements.rb +7 -6
- data/lib/rigor/cache/annotation_location.rb +2 -4
- data/lib/rigor/cache/descriptor.rb +63 -20
- data/lib/rigor/cache/engine_source.rb +33 -5
- data/lib/rigor/cache/file_digest.rb +9 -1
- data/lib/rigor/cache/incremental_snapshot.rb +72 -6
- data/lib/rigor/cache/rbs_cache_producer.rb +4 -0
- data/lib/rigor/cache/rbs_class_ancestor_table.rb +0 -3
- data/lib/rigor/cache/rbs_class_type_param_names.rb +0 -3
- data/lib/rigor/cache/rbs_constant_table.rb +0 -3
- data/lib/rigor/cache/rbs_descriptor.rb +112 -14
- data/lib/rigor/cache/rbs_environment.rb +8 -4
- data/lib/rigor/cache/rbs_known_class_names.rb +0 -3
- data/lib/rigor/cache/store.rb +76 -32
- data/lib/rigor/ci_detector.rb +1 -0
- data/lib/rigor/cli/annotate_command.rb +5 -6
- data/lib/rigor/cli/check_command.rb +57 -10
- data/lib/rigor/cli/check_invocation.rb +6 -11
- data/lib/rigor/cli/check_runner_factory.rb +1 -5
- data/lib/rigor/cli/coverage_command.rb +1 -1
- data/lib/rigor/cli/coverage_mutation.rb +12 -3
- data/lib/rigor/cli/coverage_scan.rb +1 -5
- data/lib/rigor/cli/diff_command.rb +1 -1
- data/lib/rigor/cli/doc_links.rb +4 -4
- data/lib/rigor/cli/docs_command.rb +6 -6
- data/lib/rigor/cli/doctor_command.rb +85 -38
- data/lib/rigor/cli/effects_command.rb +2 -2
- data/lib/rigor/cli/effects_diff_renderer.rb +3 -3
- data/lib/rigor/cli/effects_snapshot_command.rb +1 -1
- data/lib/rigor/cli/explain_command.rb +34 -1
- data/lib/rigor/cli/fused_protection_report.rb +7 -1
- data/lib/rigor/cli/lsp_command.rb +1 -1
- data/lib/rigor/cli/mcp_command.rb +1 -1
- data/lib/rigor/cli/measurement_integrity_warning.rb +4 -5
- data/lib/rigor/cli/mutation_fork_scan.rb +6 -6
- data/lib/rigor/cli/mutation_protection_report.rb +7 -1
- data/lib/rigor/cli/plugin_command.rb +4 -4
- data/lib/rigor/cli/plugins_command.rb +2 -1
- data/lib/rigor/cli/prism_colorizer.rb +1 -2
- data/lib/rigor/cli/protection_fork_scan.rb +6 -6
- data/lib/rigor/cli/show_bleedingedge_command.rb +1 -1
- data/lib/rigor/cli/sig_gen_command.rb +212 -31
- data/lib/rigor/cli/skill_command.rb +2 -2
- data/lib/rigor/cli/skill_deep_probe.rb +4 -4
- data/lib/rigor/cli/skill_describe.rb +35 -35
- data/lib/rigor/cli/trace_command.rb +4 -4
- data/lib/rigor/cli/trace_renderer.rb +5 -6
- data/lib/rigor/cli/triage_command.rb +1 -1
- data/lib/rigor/cli/type_of_command.rb +29 -11
- data/lib/rigor/cli/type_of_renderer.rb +20 -9
- data/lib/rigor/cli/type_of_template_probe.rb +189 -0
- data/lib/rigor/cli/type_scan_command.rb +4 -4
- data/lib/rigor/cli/unused_command.rb +11 -3
- data/lib/rigor/cli/upgrade_command.rb +1 -1
- data/lib/rigor/cli.rb +89 -9
- data/lib/rigor/config_audit.rb +30 -5
- data/lib/rigor/configuration/severity_profile.rb +25 -9
- data/lib/rigor/configuration.rb +109 -7
- data/lib/rigor/effects/ancestry_recorder.rb +191 -0
- data/lib/rigor/effects/attribution.rb +12 -5
- data/lib/rigor/effects/callee_rule.rb +368 -0
- data/lib/rigor/effects/catalog.rb +7 -4
- data/lib/rigor/effects/collector.rb +11 -5
- data/lib/rigor/effects/config_envelopes.rb +15 -10
- data/lib/rigor/effects/definition_context.rb +179 -0
- data/lib/rigor/effects/definition_lines.rb +25 -6
- data/lib/rigor/effects/effect_table.rb +11 -4
- data/lib/rigor/effects/entry_points.rb +0 -2
- data/lib/rigor/effects/envelope_check.rb +9 -9
- data/lib/rigor/effects/envelope_index.rb +20 -8
- data/lib/rigor/effects/file_collection.rb +59 -5
- data/lib/rigor/effects/framework_units.rb +5 -7
- data/lib/rigor/effects/identity.rb +20 -6
- data/lib/rigor/effects/inline_anchor.rb +7 -7
- data/lib/rigor/effects/label_intent.rb +3 -4
- data/lib/rigor/effects/liskov_check.rb +8 -8
- data/lib/rigor/effects/local_ownership.rb +38 -12
- data/lib/rigor/effects/method_key.rb +22 -1
- data/lib/rigor/effects/mutation_classifier.rb +23 -12
- data/lib/rigor/effects/plugin_facts.rb +47 -37
- data/lib/rigor/effects/propagator.rb +297 -19
- data/lib/rigor/effects/registry.rb +1 -1
- data/lib/rigor/effects/scanner.rb +122 -73
- data/lib/rigor/effects/signature_sources.rb +4 -6
- data/lib/rigor/effects/snapshot.rb +12 -11
- data/lib/rigor/effects/snapshot_diff.rb +1 -1
- data/lib/rigor/effects/summary.rb +27 -4
- data/lib/rigor/effects/unit_scan.rb +393 -38
- data/lib/rigor/effects/unknown_label_check.rb +3 -8
- data/lib/rigor/effects/unknown_label_report.rb +3 -4
- data/lib/rigor/effects/visibility.rb +101 -0
- data/lib/rigor/environment/bundle_sig_discovery.rb +6 -6
- data/lib/rigor/environment/class_registry.rb +3 -1
- data/lib/rigor/environment/failure_slot.rb +2 -2
- data/lib/rigor/environment/installed_gem_set.rb +85 -0
- data/lib/rigor/environment/lockfile_resolver.rb +68 -4
- data/lib/rigor/environment/member_consistency/comparator.rb +708 -0
- data/lib/rigor/environment/member_consistency.rb +298 -0
- data/lib/rigor/environment/missing_gem_constant_index.rb +4 -4
- data/lib/rigor/environment/rbs_collection_discovery.rb +5 -5
- data/lib/rigor/environment/rbs_coverage_report.rb +5 -5
- data/lib/rigor/environment/rbs_hierarchy.rb +3 -1
- data/lib/rigor/environment/rbs_loader.rb +674 -79
- data/lib/rigor/environment.rb +174 -24
- data/lib/rigor/flow_contribution/merger.rb +0 -2
- data/lib/rigor/flow_contribution.rb +11 -13
- data/lib/rigor/hashing/xxh3.rb +264 -0
- data/lib/rigor/inference/acceptance.rb +292 -17
- data/lib/rigor/inference/block_auto_splat.rb +216 -0
- data/lib/rigor/inference/block_call_timing.rb +338 -0
- data/lib/rigor/inference/block_parameter_binder.rb +75 -30
- data/lib/rigor/inference/block_repetition.rb +71 -0
- data/lib/rigor/inference/body_fixpoint.rb +7 -6
- data/lib/rigor/inference/budget_trace.rb +3 -6
- data/lib/rigor/inference/builtins/method_catalog.rb +2 -1
- data/lib/rigor/inference/builtins/string_catalog.rb +1 -1
- data/lib/rigor/inference/captured_locals.rb +389 -18
- data/lib/rigor/inference/closure_escape_analyzer.rb +159 -17
- data/lib/rigor/inference/content_join.rb +200 -27
- data/lib/rigor/inference/coverage_scanner.rb +4 -6
- data/lib/rigor/inference/def_return_typer.rb +11 -7
- data/lib/rigor/inference/define_method_block_self.rb +64 -0
- data/lib/rigor/inference/dynamic_origin.rb +1 -1
- data/lib/rigor/inference/element_read_widening.rb +180 -0
- data/lib/rigor/inference/error_info.rb +196 -0
- data/lib/rigor/inference/expression_typer.rb +2124 -468
- data/lib/rigor/inference/external_ancestor_resolution.rb +267 -0
- data/lib/rigor/inference/fork_map.rb +5 -7
- data/lib/rigor/inference/fresh_frame_blocks.rb +127 -0
- data/lib/rigor/inference/global_write_census.rb +239 -0
- data/lib/rigor/inference/guard_rebinding.rb +447 -0
- data/lib/rigor/inference/hash_lookup_mutation.rb +88 -0
- data/lib/rigor/inference/hkt_reducer.rb +2 -3
- data/lib/rigor/inference/hkt_registry.rb +4 -7
- data/lib/rigor/inference/index_write_widening.rb +16 -7
- data/lib/rigor/inference/indexed_narrowing.rb +61 -9
- data/lib/rigor/inference/jump_targets.rb +82 -0
- data/lib/rigor/inference/last_line/implicit_self.rb +210 -0
- data/lib/rigor/inference/last_line/self_evidence.rb +329 -0
- data/lib/rigor/inference/last_line.rb +340 -0
- data/lib/rigor/inference/last_status.rb +144 -0
- data/lib/rigor/inference/macro_block_self_type.rb +168 -21
- data/lib/rigor/inference/match_rebinding/calls.rb +281 -0
- data/lib/rigor/inference/match_rebinding/frame.rb +148 -0
- data/lib/rigor/inference/match_rebinding/operands.rb +236 -0
- data/lib/rigor/inference/match_rebinding/self_calls.rb +83 -0
- data/lib/rigor/inference/match_rebinding.rb +392 -0
- data/lib/rigor/inference/method_dispatcher/alias_strict_nominals.rb +36 -0
- data/lib/rigor/inference/method_dispatcher/block_folding.rb +87 -33
- data/lib/rigor/inference/method_dispatcher/cgi_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/constant_folding.rb +305 -19
- data/lib/rigor/inference/method_dispatcher/data_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/facet_distribution.rb +147 -0
- data/lib/rigor/inference/method_dispatcher/file_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/hash_transform_keys_folding.rb +191 -0
- data/lib/rigor/inference/method_dispatcher/iterator_dispatch.rb +6 -2
- data/lib/rigor/inference/method_dispatcher/json_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/kernel_dispatch.rb +7 -1
- data/lib/rigor/inference/method_dispatcher/match_data_folding.rb +159 -0
- data/lib/rigor/inference/method_dispatcher/math_folding.rb +41 -3
- data/lib/rigor/inference/method_dispatcher/method_folding.rb +2 -5
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +165 -111
- data/lib/rigor/inference/method_dispatcher/process_folding.rb +56 -0
- data/lib/rigor/inference/method_dispatcher/proven_overload.rb +72 -0
- data/lib/rigor/inference/method_dispatcher/random_folding.rb +82 -0
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +1046 -69
- data/lib/rigor/inference/method_dispatcher/receiver_affinity.rb +25 -4
- data/lib/rigor/inference/method_dispatcher/reduce_folding.rb +2 -8
- data/lib/rigor/inference/method_dispatcher/regexp_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/self_substitute.rb +142 -0
- data/lib/rigor/inference/method_dispatcher/set_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +129 -54
- data/lib/rigor/inference/method_dispatcher/shellwords_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/singleton_mixin_dispatch.rb +1 -2
- data/lib/rigor/inference/method_dispatcher/struct_folding.rb +5 -6
- data/lib/rigor/inference/method_dispatcher/struct_materialization.rb +85 -4
- data/lib/rigor/inference/method_dispatcher/time_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/universal_object_dispatch.rb +1 -2
- data/lib/rigor/inference/method_dispatcher/uri_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher.rb +225 -25
- data/lib/rigor/inference/method_parameter_binder.rb +12 -9
- data/lib/rigor/inference/multi_target_binder.rb +341 -55
- data/lib/rigor/inference/mutation_rejoin.rb +171 -0
- data/lib/rigor/inference/mutation_widening.rb +156 -85
- data/lib/rigor/inference/narrowing.rb +835 -162
- data/lib/rigor/inference/operand_effects.rb +167 -0
- data/lib/rigor/inference/operand_walk.rb +88 -0
- data/lib/rigor/inference/optimistic_origin.rb +153 -16
- data/lib/rigor/inference/origin_lookup.rb +2 -3
- data/lib/rigor/inference/parameter_inference_collector.rb +7 -7
- data/lib/rigor/inference/pre_eval_constants.rb +6 -5
- data/lib/rigor/inference/precision_scanner.rb +3 -4
- data/lib/rigor/inference/project_method_ownership.rb +136 -0
- data/lib/rigor/inference/project_patched_methods.rb +9 -4
- data/lib/rigor/inference/project_patched_scanner.rb +10 -6
- data/lib/rigor/inference/protection_scanner.rb +1 -2
- data/lib/rigor/inference/range_constant.rb +57 -0
- data/lib/rigor/inference/rbs_type_translator.rb +49 -11
- data/lib/rigor/inference/receiver_alias.rb +93 -4
- data/lib/rigor/inference/receiver_blind_block.rb +219 -0
- data/lib/rigor/inference/refinement_mutation.rb +76 -0
- data/lib/rigor/inference/repeated_or_writes.rb +463 -0
- data/lib/rigor/inference/return_barrier.rb +54 -0
- data/lib/rigor/inference/rewrite_mutation.rb +120 -0
- data/lib/rigor/inference/scope_indexer.rb +5228 -627
- data/lib/rigor/inference/statement_evaluator.rb +3452 -595
- data/lib/rigor/inference/stored_block_call.rb +54 -0
- data/lib/rigor/inference/string_mutation.rb +97 -0
- data/lib/rigor/inference/struct_fold_safety.rb +6 -7
- data/lib/rigor/inference/synthetic_method_index.rb +1 -2
- data/lib/rigor/inference/synthetic_method_scanner.rb +4 -6
- data/lib/rigor/inference/unknown_store_widening.rb +200 -0
- data/lib/rigor/inference/unthreaded_rebinds.rb +282 -0
- data/lib/rigor/inference/version_guard.rb +28 -21
- data/lib/rigor/inference/void_origin.rb +3 -3
- data/lib/rigor/inference/void_tail_summary.rb +2 -4
- data/lib/rigor/language_server/buffer_table.rb +4 -4
- data/lib/rigor/language_server/completion_provider.rb +1 -1
- data/lib/rigor/language_server/debouncer.rb +0 -1
- data/lib/rigor/language_server/diagnostic_publisher.rb +7 -6
- data/lib/rigor/language_server/document_symbol_provider.rb +1 -1
- data/lib/rigor/language_server/folding_range_provider.rb +1 -1
- data/lib/rigor/language_server/hover_provider.rb +1 -1
- data/lib/rigor/language_server/hover_renderer.rb +4 -4
- data/lib/rigor/language_server/incremental_sync.rb +6 -6
- data/lib/rigor/language_server/project_context.rb +7 -8
- data/lib/rigor/language_server/publish_batcher.rb +2 -2
- data/lib/rigor/language_server/selection_range_provider.rb +2 -2
- data/lib/rigor/language_server/server.rb +9 -9
- data/lib/rigor/language_server/signature_help_provider.rb +1 -1
- data/lib/rigor/language_server/uri.rb +1 -1
- data/lib/rigor/mcp/server.rb +2 -1
- data/lib/rigor/plugin/base.rb +258 -26
- data/lib/rigor/plugin/box_probe.rb +91 -0
- data/lib/rigor/plugin/bundled_catalog.rb +167 -0
- data/lib/rigor/plugin/effect_attribution.rb +65 -11
- data/lib/rigor/plugin/effect_entry_points.rb +3 -3
- data/lib/rigor/plugin/fact_store.rb +6 -6
- data/lib/rigor/plugin/io_boundary.rb +93 -8
- data/lib/rigor/plugin/isolation.rb +29 -6
- data/lib/rigor/plugin/loader.rb +33 -13
- data/lib/rigor/plugin/macro/block_as_method.rb +45 -6
- data/lib/rigor/plugin/macro/heredoc_template.rb +1 -1
- data/lib/rigor/plugin/macro/trait_registry.rb +1 -1
- data/lib/rigor/plugin/manifest.rb +94 -11
- data/lib/rigor/plugin/registry.rb +76 -12
- data/lib/rigor/plugin/source_rbs_synthesis_reporter.rb +21 -4
- data/lib/rigor/plugin/template_unit.rb +196 -0
- data/lib/rigor/plugin/trust_policy.rb +2 -4
- data/lib/rigor/plugin/type_node_resolver.rb +3 -3
- data/lib/rigor/plugin.rb +1 -0
- data/lib/rigor/plugin_gap_advisory.rb +96 -0
- data/lib/rigor/project_environment.rb +138 -0
- data/lib/rigor/protection/analysis_guard.rb +93 -14
- data/lib/rigor/protection/closure_kill_oracle.rb +67 -23
- data/lib/rigor/protection/dependency_closure.rb +5 -8
- data/lib/rigor/protection/diagnostic_oracle.rb +2 -2
- data/lib/rigor/protection/discovery_seed.rb +14 -12
- data/lib/rigor/protection/kill_signature.rb +1 -4
- data/lib/rigor/protection/measurement_integrity.rb +1 -3
- data/lib/rigor/protection/mutation_cache.rb +7 -11
- data/lib/rigor/protection/mutation_scanner.rb +12 -15
- data/lib/rigor/protection/mutator.rb +2 -1
- data/lib/rigor/protection/test_suite_oracle.rb +5 -5
- data/lib/rigor/rbs_extended/conformance_checker.rb +4 -3
- data/lib/rigor/rbs_extended/envelope_scanner.rb +4 -6
- data/lib/rigor/rbs_extended/reporter.rb +36 -10
- data/lib/rigor/rbs_extended.rb +88 -21
- data/lib/rigor/reflection/constant_ancestors.rb +97 -0
- data/lib/rigor/reflection/constant_path.rb +139 -0
- data/lib/rigor/reflection.rb +93 -110
- data/lib/rigor/runtime/jit.rb +6 -8
- data/lib/rigor/scope/discovery_index.rb +165 -2
- data/lib/rigor/scope.rb +1041 -32
- data/lib/rigor/sig_gen/alias_index.rb +289 -0
- data/lib/rigor/sig_gen/classification.rb +22 -5
- data/lib/rigor/sig_gen/declaration_equivalence.rb +127 -0
- data/lib/rigor/sig_gen/effect_annotation.rb +202 -0
- data/lib/rigor/sig_gen/generator.rb +673 -53
- data/lib/rigor/sig_gen/inline_declarations.rb +184 -0
- data/lib/rigor/sig_gen/layout_index.rb +3 -4
- data/lib/rigor/sig_gen/meta_class_shape.rb +3 -5
- data/lib/rigor/sig_gen/method_candidate.rb +47 -3
- data/lib/rigor/sig_gen/observation_collector.rb +18 -16
- data/lib/rigor/sig_gen/path_mapper.rb +4 -6
- data/lib/rigor/sig_gen/rbs_validity.rb +4 -4
- data/lib/rigor/sig_gen/renderer.rb +128 -14
- data/lib/rigor/sig_gen/skip_reason_catalog.rb +154 -0
- data/lib/rigor/sig_gen/superclass_spelling.rb +27 -0
- data/lib/rigor/sig_gen/type_elaborator.rb +1 -3
- data/lib/rigor/sig_gen/write_result.rb +19 -3
- data/lib/rigor/sig_gen/writer.rb +189 -41
- data/lib/rigor/sig_gen.rb +3 -0
- data/lib/rigor/signature_path_audit.rb +153 -6
- data/lib/rigor/source/literals.rb +0 -23
- data/lib/rigor/source/node_children.rb +0 -2
- data/lib/rigor/source/node_locator.rb +5 -11
- data/lib/rigor/source/node_walker.rb +0 -6
- data/lib/rigor/source/parameter_envelope.rb +72 -0
- data/lib/rigor/source.rb +1 -0
- data/lib/rigor/triage/catalogue.rb +1 -3
- data/lib/rigor/triage.rb +3 -5
- data/lib/rigor/type/accepts_result.rb +24 -6
- data/lib/rigor/type/combinator.rb +144 -5
- data/lib/rigor/type/data_class.rb +2 -2
- data/lib/rigor/type/data_instance.rb +4 -4
- data/lib/rigor/type/difference.rb +1 -0
- data/lib/rigor/type/float_range.rb +128 -0
- data/lib/rigor/type/hash_shape.rb +6 -6
- data/lib/rigor/type/integer_range.rb +13 -8
- data/lib/rigor/type/nominal.rb +8 -2
- data/lib/rigor/type/refined.rb +4 -3
- data/lib/rigor/type/struct_class.rb +3 -3
- data/lib/rigor/type/struct_instance.rb +4 -4
- data/lib/rigor/type.rb +1 -0
- data/lib/rigor/type_node/generic.rb +1 -1
- data/lib/rigor/type_node/range_literal.rb +25 -0
- data/lib/rigor/type_node/resolver_chain.rb +1 -1
- data/lib/rigor/type_node.rb +1 -0
- data/lib/rigor/version.rb +1 -1
- data/lib/rigor.rb +1 -0
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/analyzer.rb +0 -4
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_discoverer.rb +0 -1
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_index.rb +0 -2
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/effects.rb +1 -0
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +10 -5
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/analyzer.rb +0 -4
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_discoverer.rb +3 -5
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_index.rb +1 -4
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb +14 -4
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb +32 -30
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_discoverer.rb +0 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_index.rb +1 -3
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_scan.rb +96 -0
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/effects.rb +65 -8
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/erb_compiler.rb +270 -0
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/render_locals.rb +402 -0
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/view_assigns.rb +370 -0
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/view_units.rb +132 -0
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +264 -3
- data/plugins/rigor-actionpack/sig/action_controller.rbs +71 -0
- data/plugins/rigor-actionpack/sig/action_view.rbs +43 -0
- data/plugins/rigor-active-model-serializers/lib/rigor/plugin/active_model_serializers/serializer_discoverer.rb +220 -0
- data/plugins/rigor-active-model-serializers/lib/rigor/plugin/active_model_serializers/serializer_index.rb +56 -0
- data/plugins/rigor-active-model-serializers/lib/rigor/plugin/active_model_serializers.rb +263 -0
- data/plugins/rigor-active-model-serializers/lib/rigor-active-model-serializers.rb +7 -0
- data/plugins/rigor-active-model-serializers/sig/active_model_serializers.rbs +45 -0
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/analyzer.rb +0 -4
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/effects.rb +2 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_discoverer.rb +0 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_index.rb +0 -2
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/recurring_scan.rb +1 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +10 -5
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/analyzer.rb +35 -3
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/effects.rb +72 -12
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +383 -7
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_index.rb +14 -6
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_parser.rb +1 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/structure_sql_parser.rb +1 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +322 -41
- data/plugins/rigor-activerecord/sig/active_record/framework.rbs +123 -0
- data/plugins/rigor-activerecord/sig/active_record/relation.rbs +206 -31
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +26 -14
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext/effects.rb +9 -2
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb +9 -2
- data/plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs +290 -19
- data/plugins/rigor-devise/lib/rigor/plugin/devise.rb +1 -0
- data/plugins/rigor-dry-monads/lib/rigor/plugin/dry_monads.rb +3 -0
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema/schema_scanner.rb +9 -7
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema.rb +7 -3
- data/plugins/rigor-dry-struct/lib/rigor/plugin/dry_struct.rb +1 -0
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types/alias_scanner.rb +8 -6
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types.rb +11 -7
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation/contract_scanner.rb +13 -11
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation.rb +9 -4
- data/plugins/rigor-ethon/lib/rigor/plugin/ethon.rb +2 -0
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/analyzer.rb +0 -5
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_discoverer.rb +0 -1
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_index.rb +0 -1
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot.rb +8 -1
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi/types.rb +1 -1
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi.rb +36 -4
- data/plugins/rigor-ffi-rzmq/lib/rigor/plugin/ffi_rzmq.rb +1 -0
- data/plugins/rigor-grape/lib/rigor/plugin/grape.rb +141 -0
- data/plugins/rigor-grape/lib/rigor-grape.rb +6 -0
- data/plugins/rigor-grape/sig/grape.rbs +263 -0
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql/type_scanner.rb +8 -6
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql.rb +78 -5
- data/plugins/rigor-graphql/sig/graphql.rbs +485 -0
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami.rb +1 -0
- data/plugins/rigor-mangrove/lib/rigor/plugin/mangrove.rb +2 -1
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest/assertion_analyzer.rb +2 -3
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest.rb +1 -0
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/analyzer.rb +0 -5
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/authorization_scan.rb +2 -2
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_discoverer.rb +0 -1
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_index.rb +0 -1
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit.rb +12 -7
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/analyzer.rb +0 -12
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_index.rb +1 -3
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_loader.rb +0 -1
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n.rb +36 -37
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/acronyms.rb +5 -5
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/analyzer.rb +0 -10
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/devise_routes.rb +5 -3
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/doorkeeper_routes.rb +3 -2
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/grape_api_discoverer.rb +2 -2
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_discoverer.rb +2 -2
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_table.rb +9 -10
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/routes_parser.rb +2 -3
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +10 -17
- data/plugins/rigor-railties/lib/rigor/plugin/railties.rb +1 -0
- data/plugins/rigor-rbnacl/lib/rigor/plugin/rbnacl.rb +13 -1
- data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline/same_line_annotations.rb +149 -0
- data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb +324 -18
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/analyzer.rb +0 -3
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_scope_index.rb +0 -3
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_type_resolver.rb +1 -5
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +2 -3
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec.rb +1 -0
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails/have_http_status_analyzer.rb +0 -3
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails.rb +1 -0
- data/plugins/rigor-sassc/lib/rigor/plugin/sassc.rb +1 -0
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers/analyzer.rb +1 -9
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers.rb +1 -0
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/analyzer.rb +0 -4
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/effects.rb +1 -1
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/schedule_scan.rb +2 -1
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_discoverer.rb +0 -1
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_index.rb +0 -2
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb +10 -5
- data/plugins/rigor-sinatra/lib/rigor/plugin/sinatra.rb +1 -0
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/absurd_recognizer.rb +2 -5
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/assertion_recognizer.rb +1 -4
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog.rb +3 -9
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog_walker.rb +4 -4
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sig_parser.rb +1 -2
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sigil_detector.rb +3 -5
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/type_translator.rb +7 -5
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +51 -6
- data/plugins/rigor-sorbet/sig/sorbet.rbs +277 -0
- data/plugins/rigor-statesman/lib/rigor/plugin/statesman.rb +1 -0
- data/sig/rigor/analysis/baseline.rbs +69 -7
- data/sig/rigor/analysis/fact_store.rbs +1 -1
- data/sig/rigor/analysis/project_scan.rbs +74 -0
- data/sig/rigor/analysis/reachability/scan_cache.rbs +12 -0
- data/sig/rigor/cache.rbs +2 -3
- data/sig/rigor/effects/config_envelopes.rbs +100 -0
- data/sig/rigor/effects/effect_table.rbs +60 -0
- data/sig/rigor/effects/envelope.rbs +97 -0
- data/sig/rigor/effects/envelope_index.rbs +33 -0
- data/sig/rigor/effects/file_collection.rbs +81 -0
- data/sig/rigor/effects/label.rbs +26 -0
- data/sig/rigor/effects/label_set.rbs +46 -0
- data/sig/rigor/effects/method_key.rbs +24 -0
- data/sig/rigor/effects/origin.rbs +50 -0
- data/sig/rigor/effects/plugin_facts.rbs +141 -0
- data/sig/rigor/effects/registry.rbs +68 -0
- data/sig/rigor/effects/summary.rbs +50 -0
- data/sig/rigor/effects/taint_cause.rbs +12 -0
- data/sig/rigor/environment.rbs +17 -10
- data/sig/rigor/inference/optimistic_origin.rbs +10 -0
- data/sig/rigor/inference.rbs +9 -14
- data/sig/rigor/plugin/additional_initializer.rbs +36 -0
- data/sig/rigor/plugin/base.rbs +30 -7
- data/sig/rigor/plugin/effect_ancestry.rbs +27 -0
- data/sig/rigor/plugin/effect_attribution.rbs +66 -0
- data/sig/rigor/plugin/effect_edge.rbs +33 -0
- data/sig/rigor/plugin/effect_entry_points.rbs +25 -0
- data/sig/rigor/plugin/io_boundary.rbs +4 -0
- data/sig/rigor/plugin/loader.rbs +3 -3
- data/sig/rigor/plugin/manifest.rbs +51 -11
- data/sig/rigor/plugin/protocol_contract.rbs +68 -0
- data/sig/rigor/plugin/registry.rbs +62 -1
- data/sig/rigor/plugin.rbs +1 -1
- data/sig/rigor/rbs_extended.rbs +1 -1
- data/sig/rigor/reflection.rbs +9 -6
- data/sig/rigor/scope.rbs +148 -12
- data/sig/rigor/sig_gen/skip_reason_catalog.rbs +21 -0
- data/sig/rigor/source.rbs +4 -4
- data/sig/rigor/testing.rbs +10 -4
- data/sig/rigor/type.rbs +33 -1
- data/sig/rigor.rbs +39 -20
- data/skills/rigor-ask/SKILL.md +16 -11
- data/skills/rigor-baseline-reduce/SKILL.md +4 -6
- data/skills/rigor-ci-setup/SKILL.md +17 -21
- data/skills/rigor-doctor/SKILL.md +24 -22
- data/skills/rigor-doctor/references/01-checks.md +97 -33
- data/skills/rigor-editor-setup/SKILL.md +6 -4
- data/skills/rigor-mcp-setup/SKILL.md +5 -4
- data/skills/rigor-monkeypatch-resolve/SKILL.md +5 -3
- data/skills/rigor-next-steps/SKILL.md +4 -2
- data/skills/rigor-plugin-author/SKILL.md +19 -23
- data/skills/rigor-plugin-author/references/01-plan-and-scaffold.md +9 -8
- data/skills/rigor-plugin-author/references/02-walker-and-types.md +25 -27
- data/skills/rigor-plugin-author/references/03-test-and-ship.md +6 -8
- data/skills/rigor-plugin-review/SKILL.md +6 -4
- data/skills/rigor-plugin-review/references/01-best-practices-checklist.md +2 -1
- data/skills/rigor-plugin-tune/SKILL.md +4 -2
- data/skills/rigor-project-init/SKILL.md +15 -10
- data/skills/rigor-project-init/references/01-detect.md +13 -9
- data/skills/rigor-project-init/references/02-configure.md +43 -14
- data/skills/rigor-project-init/references/03-baseline-and-bugs.md +14 -14
- data/skills/rigor-project-init/references/04-sig-uplift.md +27 -14
- data/skills/rigor-project-init/references/06-agent-contract.md +67 -0
- data/skills/rigor-protection-uplift/SKILL.md +4 -6
- data/skills/rigor-rbs-setup/SKILL.md +4 -2
- data/skills/rigor-type-oracle/SKILL.md +226 -0
- data/skills/rigor-type-oracle/references/01-oracle-commands.md +265 -0
- data/skills/rigor-type-oracle/references/02-agents-md-fragment.md +52 -0
- data/skills/rigor-type-oracle/references/03-gap-protocol.md +125 -0
- data/skills/rigor-unused-adjudicate/SKILL.md +12 -7
- data/skills/rigor-upgrade/SKILL.md +13 -8
- metadata +133 -3
- data/lib/rigor/cli/probe_environment.rb +0 -85
- data/sig/rigor/inference/builtins/numeric_catalog.rbs +0 -3
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
require "tmpdir"
|
|
4
4
|
|
|
5
5
|
require_relative "../../environment"
|
|
6
|
+
require_relative "../../project_environment"
|
|
6
7
|
require_relative "../diagnostic"
|
|
7
8
|
require_relative "../worker_session"
|
|
8
9
|
require_relative "../run_stats"
|
|
9
10
|
require_relative "../../effects/signature_sources"
|
|
10
11
|
require_relative "../../rbs_extended/conformance_checker"
|
|
11
12
|
require_relative "../../runtime/jit"
|
|
13
|
+
require_relative "../../cache/engine_source"
|
|
12
14
|
|
|
13
15
|
module Rigor
|
|
14
16
|
module Analysis
|
|
@@ -29,30 +31,21 @@ module Rigor
|
|
|
29
31
|
# delegated back through an injected `analyze_file` callable so the CheckRules / recorder /
|
|
30
32
|
# plugin-emission machinery stays on the {Runner}.
|
|
31
33
|
class PoolCoordinator # rubocop:disable Metrics/ClassLength
|
|
32
|
-
# @param
|
|
33
|
-
# @param
|
|
34
|
-
# @param
|
|
35
|
-
# @param
|
|
36
|
-
# @param
|
|
37
|
-
# @param
|
|
38
|
-
# @param environment_override [Rigor::Environment, nil]
|
|
39
|
-
# @param rbs_extended_reporter [RbsExtended::Reporter]
|
|
40
|
-
# @param boundary_cross_reporter [DependencySourceInference::BoundaryCrossReporter]
|
|
41
|
-
# @param source_rbs_synthesis_reporter [Plugin::SourceRbsSynthesisReporter]
|
|
42
|
-
# @param snapshots [RunSnapshots] shared end-of-pass snapshot sink.
|
|
43
|
-
# @param plugin_registry [#call] reader for the current registry.
|
|
44
|
-
# @param dependency_source_index [#call] reader.
|
|
45
|
-
# @param synthetic_method_index [#call] reader.
|
|
46
|
-
# @param project_patched_methods [#call] reader.
|
|
47
|
-
# @param project_scope_seed [#call] reader for the cross-file pre-pass seed tables
|
|
34
|
+
# @param snapshots — shared end-of-pass snapshot sink.
|
|
35
|
+
# @param plugin_registry — reader for the current registry.
|
|
36
|
+
# @param dependency_source_index — reader.
|
|
37
|
+
# @param synthetic_method_index — reader.
|
|
38
|
+
# @param project_patched_methods — reader.
|
|
39
|
+
# @param project_scope_seed — reader for the cross-file pre-pass seed tables
|
|
48
40
|
# (`Runner#project_scope_seed_tables`).
|
|
49
|
-
# @param analyze_file
|
|
41
|
+
# @param analyze_file — `(path, environment) -> diagnostics`.
|
|
50
42
|
def initialize(configuration:, cache_store:, explain:, workers:, collect_stats:, # rubocop:disable Metrics/ParameterLists
|
|
51
43
|
buffer:, environment_override:, rbs_extended_reporter:,
|
|
52
44
|
boundary_cross_reporter:, source_rbs_synthesis_reporter:,
|
|
53
45
|
snapshots:, plugin_registry:, dependency_source_index:,
|
|
54
46
|
synthetic_method_index:, project_patched_methods:,
|
|
55
|
-
analyze_file:, project_scope_seed: -> { {} }, record_dependencies: false
|
|
47
|
+
analyze_file:, project_scope_seed: -> { {} }, record_dependencies: false,
|
|
48
|
+
restored_run_level_rows: nil, template_units: -> { TemplateUnits.empty })
|
|
56
49
|
@configuration = configuration
|
|
57
50
|
@cache_store = cache_store
|
|
58
51
|
@explain = explain
|
|
@@ -67,6 +60,11 @@ module Rigor
|
|
|
67
60
|
# `#collected_effects`, so a pooled run's effect graph is the sequential run's graph.
|
|
68
61
|
@record_effects = configuration.effects_enabled?
|
|
69
62
|
@collected_effects = {}
|
|
63
|
+
# Issue #1051 — run-scoped plugin disclosures ({Plugin::Base#disclose_once}), keyed
|
|
64
|
+
# `[plugin id, key]` so the FIRST worker to register a pair wins and every later copy is dropped.
|
|
65
|
+
# The de-duplication has to happen here, on the parent, because each fork worker owns its own
|
|
66
|
+
# plugin instances and therefore its own `@run_disclosures` table.
|
|
67
|
+
@collected_run_disclosures = {}
|
|
70
68
|
@collect_stats = collect_stats
|
|
71
69
|
@buffer = buffer
|
|
72
70
|
@environment_override = environment_override
|
|
@@ -79,7 +77,15 @@ module Rigor
|
|
|
79
77
|
@synthetic_method_index_reader = synthetic_method_index
|
|
80
78
|
@project_patched_methods_reader = project_patched_methods
|
|
81
79
|
@project_scope_seed_reader = project_scope_seed
|
|
80
|
+
# #392 — read through a proc, like every other runner-owned table here: the units are synthesised
|
|
81
|
+
# on the parent during the run and handed to the ONE pre-fork {WorkerSession}, so every child
|
|
82
|
+
# inherits the same compiled bytes.
|
|
83
|
+
@template_units_reader = template_units
|
|
82
84
|
@analyze_file = analyze_file
|
|
85
|
+
# Issues #796 / #794 — the previous full run's run-level rows, handed down by
|
|
86
|
+
# {Analysis::IncrementalSession} on a NARROWED run only (a recheck's closure, a
|
|
87
|
+
# `--verify-incremental` partition). A full run leaves this nil and derives everything itself.
|
|
88
|
+
@restored_run_level_rows = restored_run_level_rows
|
|
83
89
|
end
|
|
84
90
|
|
|
85
91
|
# ADR-46 — the per-file cross-file read records the fork pool captured this run (empty unless
|
|
@@ -92,6 +98,25 @@ module Rigor
|
|
|
92
98
|
# these with its own sequential records before the post-pool fixpoint.
|
|
93
99
|
attr_reader :collected_effects
|
|
94
100
|
|
|
101
|
+
# Issue #1051 — the run-scoped disclosures a pool run collected, de-duplicated by `[plugin id, key]`
|
|
102
|
+
# and in first-registration order. Empty on a sequential run: there the runner's own plugin
|
|
103
|
+
# registry is the one that registered them, and {Runner} reads it directly.
|
|
104
|
+
def collected_run_disclosures
|
|
105
|
+
@collected_run_disclosures.values
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Issue #1051 — folds one session's / one worker payload's disclosures in, keeping the first
|
|
109
|
+
# registration of each `[plugin id, key]` pair. Nothing here inspects the message: two workers that
|
|
110
|
+
# disclose the same key with differently interpolated text still collapse to one row, which is the
|
|
111
|
+
# point — the key is the identity a plugin author controls, and an author who interpolates
|
|
112
|
+
# worker-varying text into a message has authored one disclosure, not N.
|
|
113
|
+
def merge_run_disclosures(records)
|
|
114
|
+
Array(records).each do |record|
|
|
115
|
+
identity = [record[:plugin_id], record[:key]].freeze
|
|
116
|
+
@collected_run_disclosures[identity] ||= record
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
95
120
|
# ADR-15 Phase 4b — pool mode is enabled when `@workers > 0`. Editor mode (`buffer:` non-nil)
|
|
96
121
|
# silently overrides pool mode to sequential: per design § "Ractor pool mode", the pool's warm-up
|
|
97
122
|
# cost dominates one-file wall time, so the pool gains nothing on a per-buffer invocation. The
|
|
@@ -115,47 +140,12 @@ module Rigor
|
|
|
115
140
|
# sources. The env stays a LOCAL variable (not an ivar) so it goes GC-eligible when the method
|
|
116
141
|
# returns — holding it as long-lived state added memory pressure that surfaced as a Bus Error
|
|
117
142
|
# during the spec suite under Ruby 4.0 + rbs 4.0.2.
|
|
118
|
-
# @param project_files
|
|
119
|
-
# (`expansion.fetch(:files)`), independent of any `analyze_only` narrowing of `files
|
|
120
|
-
#
|
|
143
|
+
# @param project_files — issue #784 — the WHOLE project's analyzed file set
|
|
144
|
+
# (`expansion.fetch(:files)`), independent of any `analyze_only` narrowing of `files`; see
|
|
145
|
+
# {#serve_empty_closure} for what an empty `files` does with it.
|
|
121
146
|
def analyze_files(files, environment: nil, project_files: nil)
|
|
122
147
|
if files.empty?
|
|
123
|
-
|
|
124
|
-
# holds it (`IncrementalSession` caches only `Runner#per_file_diagnostics`, so every run-level row
|
|
125
|
-
# is regenerated every run), so returning here without recording flips a red project green — and
|
|
126
|
-
# the shipping `--incremental` path reaches this branch with NO environment in hand on every
|
|
127
|
-
# warm recheck that changed nothing (`CheckCommand#run_incremental_check` builds its session
|
|
128
|
-
# without one). So: an environment already in hand is consulted; otherwise one is resolved over
|
|
129
|
-
# the project's OWN file list — not `[]`, which would drop every plugin-synthesized virtual RBS
|
|
130
|
-
# (`Environment.collect_virtual_rbs` short-circuits on an empty list) and scan a different type
|
|
131
|
-
# universe from the one a full run analyses — and only when the project HAS files: with none,
|
|
132
|
-
# nobody could have demanded a registry, and an empty project keeps paying no env build. Keyed
|
|
133
|
-
# on the project's files rather than on `analyze_only`, because a recheck over an EMPTY project
|
|
134
|
-
# narrows to `Set[]`, which is non-nil.
|
|
135
|
-
env = environment || @environment_override
|
|
136
|
-
if project_files && !project_files.empty?
|
|
137
|
-
env ||= resolve_sequential_environment(source_files: project_files)
|
|
138
|
-
end
|
|
139
|
-
# #788 rounds 6 and 9 — everything the run owes from its environment that no per-file analysis
|
|
140
|
-
# produces is taken here, the way `analyze_files_sequentially` takes it: the project-signature
|
|
141
|
-
# state (`synthesized-namespace`, `quarantined-signature`, `environment-build-failed`, the
|
|
142
|
-
# conformance results), the effect-annotation carrier the residual pass reads, and the HKT-scan
|
|
143
|
-
# outcome. Now that run-level rows are never served from the per-file cache, this branch is the
|
|
144
|
-
# only producer on a warm recheck that changed nothing — leaving any of them out turned a red
|
|
145
|
-
# project green on its second `--incremental` run (the inline-only `effect.annotations-unchecked`
|
|
146
|
-
# went 1 → 0; a quarantined `signature_paths:` file went 1 → 0; a `conforms-to` class whose
|
|
147
|
-
# definition build fails went 1 → 0). Same ORDER as the sequential path, because the order is
|
|
148
|
-
# the contract: the conformance scan inside the signature-state snapshot demands the definition
|
|
149
|
-
# of every `rigor:v1:conforms-to` class — a user-authored, invocation-independent demand that
|
|
150
|
-
# #696 counts — so the definition-build failures are read AFTER it and BEFORE the HKT demand,
|
|
151
|
-
# exactly where `analyze_files_sequentially` reads them relative to its own. What this branch
|
|
152
|
-
# cannot regenerate is the part of that set the per-file ANALYSIS demanded (#796). This also
|
|
153
|
-
# retires the #441 "`.rbs` lane only when the run analyses nothing" boundary: its cost premise
|
|
154
|
-
# (no environment on this path) stopped holding the moment the branch above resolved one.
|
|
155
|
-
snapshot_project_signature_state(env)
|
|
156
|
-
snapshot_effect_annotation_carrier(env&.rbs_loader)
|
|
157
|
-
record_definition_build_failures(env&.rbs_loader&.definition_build_failures)
|
|
158
|
-
record_hkt_scan_failure(hkt_scan_outcome(env))
|
|
148
|
+
serve_empty_closure(environment, project_files)
|
|
159
149
|
return []
|
|
160
150
|
end
|
|
161
151
|
# Issue #784 / #793 — `files` is what this run ANALYSES; `source_files` is what its environment
|
|
@@ -166,11 +156,152 @@ module Rigor
|
|
|
166
156
|
# whose trigger lived in an excluded file's synthesized RBS fired on the full run and vanished on
|
|
167
157
|
# the subset. Every environment and worker this run builds now takes the whole project.
|
|
168
158
|
source_files = project_files || files
|
|
169
|
-
|
|
159
|
+
result =
|
|
160
|
+
if pool_mode?
|
|
161
|
+
dispatch_pool(files, source_files: source_files)
|
|
162
|
+
else
|
|
163
|
+
analyze_files_sequentially(
|
|
164
|
+
files, environment || resolve_sequential_environment(source_files: source_files)
|
|
165
|
+
)
|
|
166
|
+
end
|
|
167
|
+
# Issues #796 / #794 — a narrowed run's own demand set is a SUBSET of the full run's, so the two
|
|
168
|
+
# rows below are folded in after it, whichever backend produced the per-file stream.
|
|
169
|
+
replayed_restored_run_level_rows?(closure: files)
|
|
170
|
+
result
|
|
171
|
+
end
|
|
170
172
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
+
# Issue #784 — an EMPTY analyze set still owes the run its run-level rows: the per-file cache never
|
|
174
|
+
# holds them (`IncrementalSession` caches only `Runner#per_file_diagnostics`), so returning here
|
|
175
|
+
# without recording flips a red project green — and the shipping `--incremental` path reaches this
|
|
176
|
+
# branch with NO environment in hand on every warm recheck that changed nothing
|
|
177
|
+
# (`CheckCommand#run_incremental_check` builds its session without one).
|
|
178
|
+
#
|
|
179
|
+
# #788 rounds 6 and 9 — everything the run owes from its environment that no per-file analysis
|
|
180
|
+
# produces is taken here, the way `analyze_files_sequentially` takes it: the project-signature state
|
|
181
|
+
# (`synthesized-namespace`, `quarantined-signature`, `environment-build-failed`, the conformance
|
|
182
|
+
# results), the effect-annotation carrier the residual pass reads, and the HKT-scan outcome. Leaving
|
|
183
|
+
# any of them out turned a red project green on its second `--incremental` run. Same ORDER as the
|
|
184
|
+
# sequential path, because the order is the contract: the conformance scan inside the
|
|
185
|
+
# signature-state snapshot demands the definition of every `rigor:v1:conforms-to` class — a
|
|
186
|
+
# user-authored, invocation-independent demand that #696 counts — so the definition-build failures
|
|
187
|
+
# are read AFTER it and BEFORE the HKT outcome.
|
|
188
|
+
#
|
|
189
|
+
# Issue #794 — the environment is resolved LAZILY, by the two snapshots that need one and only when
|
|
190
|
+
# their own gates say so: a project with no `signature_paths:`, no plugin-deferred signatures and no
|
|
191
|
+
# source-RBS synthesizer now reaches the end of this branch without building an environment at all,
|
|
192
|
+
# where #788 built one unconditionally to make the HKT demand. Issue #796 — what this branch cannot
|
|
193
|
+
# derive is the part of the definition-build set the per-file ANALYSIS demanded, and #696 forbids a
|
|
194
|
+
# Rigor-owned demand from standing in for it; the previous full run's set is replayed instead.
|
|
195
|
+
# @param project_files — issue #784 — the WHOLE project's analyzed file set
|
|
196
|
+
# (`expansion.fetch(:files)`), independent of any `analyze_only` narrowing. Read here to decide
|
|
197
|
+
# whether anyone could have demanded anything at all: with no files, nobody could have, and an
|
|
198
|
+
# empty project keeps paying no env build. Keyed on the project's files rather than on
|
|
199
|
+
# `analyze_only`, because a recheck over an EMPTY project narrows to `Set[]`, which is non-nil.
|
|
200
|
+
def serve_empty_closure(environment, project_files)
|
|
201
|
+
env = environment || @environment_override
|
|
202
|
+
# Resolved over the project's OWN file list — not `[]`, which would drop every plugin-synthesized
|
|
203
|
+
# virtual RBS (`Environment.collect_virtual_rbs` short-circuits on an empty list) and scan a
|
|
204
|
+
# different type universe from the one a full run analyses.
|
|
205
|
+
resolve = lambda do
|
|
206
|
+
next env if env
|
|
207
|
+
next nil if project_files.nil? || project_files.empty?
|
|
208
|
+
|
|
209
|
+
env = resolve_sequential_environment(source_files: project_files)
|
|
210
|
+
end
|
|
211
|
+
snapshot_project_signature_state(signature_state_environment(resolve))
|
|
212
|
+
snapshot_effect_annotation_carrier(
|
|
213
|
+
annotation_carrier_environment(resolve, in_hand: !env.nil?)&.rbs_loader
|
|
173
214
|
)
|
|
215
|
+
# `env` rather than `resolve.call`: read the demand the snapshots above just made when they built
|
|
216
|
+
# an environment, and force nothing when they did not.
|
|
217
|
+
record_definition_build_failures(env&.rbs_loader&.definition_build_failures)
|
|
218
|
+
return if replayed_restored_run_level_rows?
|
|
219
|
+
|
|
220
|
+
record_hkt_scan_failure(hkt_scan_outcome(resolve.call))
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# Issue #794 — the signature-state snapshot's own gates, asked BEFORE an environment exists. Both
|
|
224
|
+
# answers are loader-free (the configuration and the plugin registry), and with neither gate open
|
|
225
|
+
# {#snapshot_project_signature_state} writes the same empty state a nil environment gives it.
|
|
226
|
+
def signature_state_environment(resolve)
|
|
227
|
+
plugin_signature_paths? || project_signature_paths? ? resolve.call : nil
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# Issue #794 — the same, for the #441 carrier. The carrier is a filter over the loader's
|
|
231
|
+
# `virtual_rbs`, and an environment whose loader can hold none of it answers the same empty carrier
|
|
232
|
+
# a nil environment does. Two ways it can hold some: a plugin registry that declares a synthesizer
|
|
233
|
+
# (`Environment.collect_virtual_rbs` short-circuits to `[]` without one — and ADR-93 auto-wires
|
|
234
|
+
# `rigor-rbs-inline`, so this is the shape almost every project is in), or an environment ALREADY in
|
|
235
|
+
# hand, whose loader is free to read and may carry virtual buffers from a route this coordinator
|
|
236
|
+
# never saw (a restored env cache, a caller-supplied override). Only the third shape — no
|
|
237
|
+
# synthesizer AND no environment yet — declines, which is the #794 saving: nothing is built to
|
|
238
|
+
# discover an emptiness the registry already proves.
|
|
239
|
+
def annotation_carrier_environment(resolve, in_hand: false)
|
|
240
|
+
return nil if @record_effects
|
|
241
|
+
return resolve.call if in_hand
|
|
242
|
+
|
|
243
|
+
registry = plugin_registry
|
|
244
|
+
return nil unless registry.respond_to?(:source_rbs_synthesizers)
|
|
245
|
+
return nil if registry.source_rbs_synthesizers.empty?
|
|
246
|
+
|
|
247
|
+
resolve.call
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# Issues #796 / #794 — fold the previous full run's run-level rows into this narrowed run's
|
|
251
|
+
# snapshots. The definition-build set is UNIONed (`#record_definition_build_failures` dedupes by
|
|
252
|
+
# class), so a class this run demanded for itself and the replayed set agree; the HKT outcome is a
|
|
253
|
+
# single tuple whoever demanded it, so `||=` keeps this run's own answer when it has one. Returns
|
|
254
|
+
# true when a replay was available, which is what tells {#serve_empty_closure} it owes no HKT demand
|
|
255
|
+
# of its own — and so no environment.
|
|
256
|
+
#
|
|
257
|
+
# @param closure — the files this run analyses; see {#stale_replayed_failure?}.
|
|
258
|
+
def replayed_restored_run_level_rows?(closure: nil)
|
|
259
|
+
rows = @restored_run_level_rows
|
|
260
|
+
return false if rows.nil?
|
|
261
|
+
|
|
262
|
+
replayable = Array(rows.definition_build_failures).reject do |failure|
|
|
263
|
+
stale_replayed_failure?(failure, closure)
|
|
264
|
+
end
|
|
265
|
+
record_definition_build_failures(replayable)
|
|
266
|
+
record_hkt_scan_failure(rows.hkt_scan_failure)
|
|
267
|
+
true
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# A replayed definition-build failure the snapshot's own fingerprint cannot vouch for. The
|
|
271
|
+
# fingerprint digests the three signature sources it can read WITHOUT an environment — `sig:`,
|
|
272
|
+
# `Gemfile.lock` / `rbs_collection.lock.yaml`, and the configuration — but NOT the virtual RBS a
|
|
273
|
+
# source-RBS synthesizer derives from `.rb` files (under ADR-93's auto-wired `rigor-rbs-inline`,
|
|
274
|
+
# every `#:` annotation). So a duplicate declaration can be REMOVED from a `.rb` file without moving
|
|
275
|
+
# the fingerprint, and the replayed row would outlive its own cause: the edited file enters the
|
|
276
|
+
# closure, its analysis demands nothing that would re-derive the row, and the run reports a
|
|
277
|
+
# collision between files that no longer collide.
|
|
278
|
+
#
|
|
279
|
+
# The narrowed run cannot re-derive the row either (#696 forbids Rigor demanding a definition the
|
|
280
|
+
# analysis did not), so the honest answer is to DROP it and under-report rather than assert a
|
|
281
|
+
# diagnostic on a program that may now be correct — false positives outrank worst-case reading. The
|
|
282
|
+
# cost is bounded to the row's own conflicting buffers: a collision between two files neither of
|
|
283
|
+
# which this run touches still replays.
|
|
284
|
+
def stale_replayed_failure?(failure, closure)
|
|
285
|
+
return false if closure.nil?
|
|
286
|
+
|
|
287
|
+
buffers = failure.is_a?(Array) ? failure[3] : nil
|
|
288
|
+
return false if buffers.nil?
|
|
289
|
+
|
|
290
|
+
closure_paths = closure.to_set { |path| File.expand_path(path.to_s) }
|
|
291
|
+
Array(buffers).any? do |name|
|
|
292
|
+
path = virtual_buffer_path(name)
|
|
293
|
+
!path.nil? && closure_paths.include?(File.expand_path(path))
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
# The source file behind a `virtual:<plugin id>:<path>` buffer name
|
|
298
|
+
# (`Environment.collect_virtual_rbs`), or nil for any other buffer — a `sig:` file, a bundled `.rbs`
|
|
299
|
+
# — which the fingerprint does cover and which therefore never goes stale under a replay.
|
|
300
|
+
def virtual_buffer_path(name)
|
|
301
|
+
parts = name.to_s.split(":", 3)
|
|
302
|
+
return nil unless parts.length == 3 && parts.first == "virtual"
|
|
303
|
+
|
|
304
|
+
parts.last
|
|
174
305
|
end
|
|
175
306
|
|
|
176
307
|
def analyze_files_sequentially(files, environment)
|
|
@@ -206,6 +337,13 @@ module Rigor
|
|
|
206
337
|
# `.rigor/cache` on a bare `--no-stats` run. The loader has already memoised each answer, so reading
|
|
207
338
|
# them here is free.
|
|
208
339
|
def snapshot_project_signature_state(environment)
|
|
340
|
+
# Issue #610 — NOT behind the `signature_paths:` gate below: the source a bundled plugin's `sig/`
|
|
341
|
+
# stands down against is typically an `rbs collection install` the configuration never lists
|
|
342
|
+
# there. Gated instead on a loaded plugin contributing signatures at all — the registry answers
|
|
343
|
+
# that without touching the env, and it is exactly the set the loader defers — so a project with
|
|
344
|
+
# no such plugin reads nothing off its loader here, as before.
|
|
345
|
+
@snapshots.signature_standdowns =
|
|
346
|
+
plugin_signature_paths? ? signature_standdowns_for(environment&.rbs_loader) : []
|
|
209
347
|
unless project_signature_paths?
|
|
210
348
|
@snapshots.synthesized_namespaces = []
|
|
211
349
|
@snapshots.quarantined_signatures = []
|
|
@@ -279,7 +417,7 @@ module Rigor
|
|
|
279
417
|
# An effects run (ADR-103 WD13) is pinned for exactly the same reason — the Ractor messages carry
|
|
280
418
|
# no side-table channel — and degrades the same way. The degrade is sound rather than merely safe:
|
|
281
419
|
# the sequential fallback still collects, so the effect graph is complete either way.
|
|
282
|
-
# @param source_files
|
|
420
|
+
# @param source_files — the file list every worker's / the fallback's environment is
|
|
283
421
|
# built over — the whole project (issue #793), defaulting to `files` for direct callers.
|
|
284
422
|
def dispatch_pool(files, source_files: files)
|
|
285
423
|
if @record_dependencies || @record_effects
|
|
@@ -318,11 +456,7 @@ module Rigor
|
|
|
318
456
|
rbs_extended_reporter: @rbs_extended_reporter,
|
|
319
457
|
boundary_cross_reporter: @boundary_cross_reporter,
|
|
320
458
|
source_rbs_synthesis_reporter: @source_rbs_synthesis_reporter,
|
|
321
|
-
|
|
322
|
-
bundler_auto_detect: @configuration.bundler_auto_detect,
|
|
323
|
-
bundler_lockfile: @configuration.bundler_lockfile,
|
|
324
|
-
rbs_collection_lockfile: @configuration.rbs_collection_lockfile,
|
|
325
|
-
rbs_collection_auto_detect: @configuration.rbs_collection_auto_detect,
|
|
459
|
+
**ProjectEnvironment.dependency_discovery_options(@configuration),
|
|
326
460
|
synthetic_method_index: synthetic_method_index,
|
|
327
461
|
project_patched_methods: project_patched_methods,
|
|
328
462
|
source_files: source_files
|
|
@@ -369,6 +503,20 @@ module Rigor
|
|
|
369
503
|
# (shareable) registry into the class-ivar cache before any worker reads.
|
|
370
504
|
Environment::ClassRegistry.default
|
|
371
505
|
|
|
506
|
+
# #1055 — the same treatment for the engine-source digest. Every worker's `Environment.for_project`
|
|
507
|
+
# reaches `Cache::EngineSource.key_config_entries` whenever a source-RBS synthesizer is wired (the
|
|
508
|
+
# ADR-93 `rigor-rbs-inline` auto-wire, on by default and off throughout the spec suite), and the
|
|
509
|
+
# memo behind it is a 90 ms tree walk that cannot be eager-loaded at require time. Warming it here
|
|
510
|
+
# is what makes the worker's access a READ of a frozen String rather than a forbidden class-ivar
|
|
511
|
+
# write. `Unavailable` is left to the worker: it raises rather than assigning, so it costs the pool
|
|
512
|
+
# no more than it costs a sequential run, and swallowing it here would hide a tree the engine
|
|
513
|
+
# cannot identify.
|
|
514
|
+
begin
|
|
515
|
+
Cache::EngineSource.process_identity
|
|
516
|
+
rescue Cache::EngineSource::Unavailable
|
|
517
|
+
nil
|
|
518
|
+
end
|
|
519
|
+
|
|
372
520
|
# ADR-15 Phase 4b.x — pre-warm the RBS cache so workers serve every reflection query from the
|
|
373
521
|
# Marshal blob on disk. Without this, the first cache MISS inside a worker falls through to
|
|
374
522
|
# `RBS::EnvironmentLoader.new`, which reads a chain of non-`Ractor.shareable?` RubyGems / RBS
|
|
@@ -389,15 +537,33 @@ module Rigor
|
|
|
389
537
|
# finds. `#prewarm_rbs_cache_for_pool` already builds and fully loads exactly this
|
|
390
538
|
# coordinator-side environment (to warm the cache before any worker spawns); it now hands it
|
|
391
539
|
# back so its RBS state can be read the same way the fork pool reads its pre-fork session
|
|
392
|
-
# environment. The
|
|
393
|
-
# `
|
|
394
|
-
#
|
|
395
|
-
#
|
|
396
|
-
#
|
|
397
|
-
#
|
|
398
|
-
#
|
|
399
|
-
|
|
540
|
+
# environment. The effect-annotation carrier (#441 — the inline stratum of
|
|
541
|
+
# `effect.annotations-unchecked`, read by the residual pass after this environment is gone) is
|
|
542
|
+
# taken off the same environment, in the same ORDER as the fork pool and the sequential path
|
|
543
|
+
# take theirs: it had no producer here either, so an annotation living only in an rbs-inline
|
|
544
|
+
# comment lost its row under this backend alone. That read is only as good as the environment's
|
|
545
|
+
# virtual RBS, which is why the prewarm is built the way the workers build theirs (see
|
|
546
|
+
# {#prewarm_rbs_cache_for_pool}). The conformance scan inside the signature-state snapshot
|
|
547
|
+
# demands the definition of every `rigor:v1:conforms-to` class — a demand no Ractor worker
|
|
548
|
+
# shares memory with — so a resulting definition-build failure is recorded explicitly right
|
|
549
|
+
# after, exactly as the empty-closure branch reads its own environment's demand (#788). No
|
|
550
|
+
# matching explicit call for the HKT-scan outcome: every worker already demands it from its OWN
|
|
551
|
+
# environment in `#drain_reporters`, and the scan has one outcome whoever demands it, so a
|
|
552
|
+
# worker's report already says what the coordinator's own demand would.
|
|
553
|
+
# #1064 — the lockfile is resolved HERE, once, and travels to every worker as frozen data the way
|
|
554
|
+
# `source_files` does: Bundler's parser reads RubyGems module state a non-main Ractor may not touch,
|
|
555
|
+
# so a worker resolving its own raised `Ractor::IsolationError`, printed a "malformed Gemfile.lock"
|
|
556
|
+
# warning per worker, and analysed with the project's gem signatures silently missing.
|
|
557
|
+
locked_gems = Ractor.make_shareable(
|
|
558
|
+
Environment::LockfileResolver.locked_gems(
|
|
559
|
+
lockfile_path: @configuration.bundler_lockfile,
|
|
560
|
+
project_root: Dir.pwd,
|
|
561
|
+
auto_detect: @configuration.bundler_auto_detect
|
|
562
|
+
)
|
|
563
|
+
)
|
|
564
|
+
warm_env = prewarm_rbs_cache_for_pool(source_files: source_files, locked_gems: locked_gems)
|
|
400
565
|
snapshot_project_signature_state(warm_env)
|
|
566
|
+
snapshot_effect_annotation_carrier(warm_env&.rbs_loader)
|
|
401
567
|
record_definition_build_failures(warm_env&.rbs_loader&.definition_build_failures)
|
|
402
568
|
|
|
403
569
|
configuration = @configuration
|
|
@@ -411,14 +577,15 @@ module Rigor
|
|
|
411
577
|
shareable_source_files = source_files.map { |path| path.to_s.dup.freeze }.freeze
|
|
412
578
|
|
|
413
579
|
pool = Array.new(@workers) do
|
|
414
|
-
Ractor.new(configuration, cache_root, blueprints, explain, shareable_source_files) do |configuration, cache_root, blueprints, explain, shareable_source_files| # rubocop:disable Layout/LineLength
|
|
580
|
+
Ractor.new(configuration, cache_root, blueprints, explain, shareable_source_files, locked_gems) do |configuration, cache_root, blueprints, explain, shareable_source_files, locked_gems| # rubocop:disable Layout/LineLength
|
|
415
581
|
cache_store = cache_root ? Rigor::Cache::Store.new(root: cache_root) : nil
|
|
416
582
|
session = Rigor::Analysis::WorkerSession.new(
|
|
417
583
|
configuration: configuration,
|
|
418
584
|
cache_store: cache_store,
|
|
419
585
|
plugin_blueprints: blueprints,
|
|
420
586
|
explain: explain,
|
|
421
|
-
source_files: shareable_source_files
|
|
587
|
+
source_files: shareable_source_files,
|
|
588
|
+
locked_gems: locked_gems
|
|
422
589
|
)
|
|
423
590
|
main = Ractor.main
|
|
424
591
|
main.send([:prepare, session.prepare_diagnostics])
|
|
@@ -430,7 +597,10 @@ module Rigor
|
|
|
430
597
|
main.send([:file, msg, session.analyze(msg)])
|
|
431
598
|
end
|
|
432
599
|
|
|
433
|
-
|
|
600
|
+
# Issue #1051 — sent with `:done`, not with `:prepare`: this backend builds no parent session,
|
|
601
|
+
# so the worker's own table is the only place a disclosure exists, and it is complete only
|
|
602
|
+
# once the worker has finished its files.
|
|
603
|
+
main.send([:done, session.drain_reporters, session.drain_run_disclosures])
|
|
434
604
|
end
|
|
435
605
|
end
|
|
436
606
|
|
|
@@ -464,7 +634,8 @@ module Rigor
|
|
|
464
634
|
when :file
|
|
465
635
|
results_by_path[message[1]] = message[2]
|
|
466
636
|
when :done
|
|
467
|
-
merge_worker_reporters(message
|
|
637
|
+
merge_worker_reporters(message[1])
|
|
638
|
+
merge_run_disclosures(message[2])
|
|
468
639
|
end
|
|
469
640
|
end
|
|
470
641
|
|
|
@@ -492,6 +663,18 @@ module Rigor
|
|
|
492
663
|
# definition-build failures the re-analysis demanded (#696) and the HKT-scan outcome, demanded
|
|
493
664
|
# once more by the run itself (#784 — a rescued scan failure otherwise vanished with the worker).
|
|
494
665
|
# The fork backend needs none of this: it re-analyses on the parent {WorkerSession} and drains it.
|
|
666
|
+
#
|
|
667
|
+
# Issue #1051, known exception: run-scoped disclosures a plugin registered from `#prepare` are NOT
|
|
668
|
+
# recovered here — nor, since #1060, a positioned `#emit_once` batch registered there, which rides
|
|
669
|
+
# the same table. There is no session to drain — this backend builds none on the coordinator — and
|
|
670
|
+
# `#prepare` deliberately does not run on the coordinator-side registry under pool mode, so a
|
|
671
|
+
# prepare-time disclosure lives only inside the Ractor that died with it. A disclosure registered
|
|
672
|
+
# from `#diagnostics_for_file` IS recovered, because the re-analysis below runs the coordinator-side
|
|
673
|
+
# plugin instances that {DiagnosticAggregator#plugin_run_disclosure_diagnostics} reads directly.
|
|
674
|
+
# Left as is: recovering the rest means running `#prepare` on the coordinator registry, which would
|
|
675
|
+
# re-publish every cross-plugin fact for a degrade, and this backend is off by default. Since #1055
|
|
676
|
+
# the path is also rare rather than universal — it used to be taken on every run, because every
|
|
677
|
+
# worker died in its constructor on a class-ivar memo.
|
|
495
678
|
def reanalyze_degraded_in_process(degraded, results_by_path, source_files:)
|
|
496
679
|
return if degraded.empty?
|
|
497
680
|
|
|
@@ -529,7 +712,8 @@ module Rigor
|
|
|
529
712
|
project_patched_methods: project_patched_methods,
|
|
530
713
|
project_scope_seed: project_scope_seed,
|
|
531
714
|
source_files: source_files,
|
|
532
|
-
record_dependencies: @record_dependencies
|
|
715
|
+
record_dependencies: @record_dependencies,
|
|
716
|
+
template_units: template_units
|
|
533
717
|
)
|
|
534
718
|
# Force the full RBS load on the parent so children copy-on-write inherit a warm Environment
|
|
535
719
|
# rather than each rebuilding it after the fork.
|
|
@@ -550,6 +734,14 @@ module Rigor
|
|
|
550
734
|
# same project).
|
|
551
735
|
snapshot_project_signature_state(session.environment)
|
|
552
736
|
snapshot_effect_annotation_carrier(session.environment.rbs_loader)
|
|
737
|
+
# Issue #1051 — taken BEFORE the fork, for the same reason and with the same effect as the two
|
|
738
|
+
# snapshots above: `#prepare` ran on the parent when the session was built, so every disclosure a
|
|
739
|
+
# plugin registers there (the normal case — a disclosure is a fact about the project's inputs,
|
|
740
|
+
# known before a file is read) is already in this table, in the same order the sequential path
|
|
741
|
+
# would produce. Each child inherits the identical table and re-offers it in its payload, where
|
|
742
|
+
# `merge_run_disclosures` drops it as a duplicate; only a disclosure a worker registers while
|
|
743
|
+
# analysing its own slice adds anything.
|
|
744
|
+
merge_run_disclosures(session.drain_run_disclosures)
|
|
553
745
|
snapshot_fork_pool_stats(session) if @collect_stats
|
|
554
746
|
|
|
555
747
|
worker_count = [@workers, files.size].min
|
|
@@ -568,6 +760,8 @@ module Rigor
|
|
|
568
760
|
unless degraded.empty?
|
|
569
761
|
degraded.each { |path| results_by_path[path] = session.analyze(path) }
|
|
570
762
|
merge_worker_reporters(session.drain_reporters)
|
|
763
|
+
# The degraded slice ran on the parent session, so a disclosure it registered lives there.
|
|
764
|
+
merge_run_disclosures(session.drain_run_disclosures)
|
|
571
765
|
# The degraded slice was re-analysed on the parent session, so its dependency records live there,
|
|
572
766
|
# not in a child payload — fold them in alongside the successful children's.
|
|
573
767
|
@collected_dependencies.merge!(session.drain_dependencies) if @record_dependencies
|
|
@@ -592,7 +786,8 @@ module Rigor
|
|
|
592
786
|
Runtime::Jit.rearm_after_fork
|
|
593
787
|
results = slice.to_h { |path| [path, session.analyze(path)] }
|
|
594
788
|
payload = { results: results, reporters: session.drain_reporters,
|
|
595
|
-
dependencies: session.drain_dependencies
|
|
789
|
+
dependencies: session.drain_dependencies,
|
|
790
|
+
disclosures: session.drain_run_disclosures }
|
|
596
791
|
# ADR-103 WD13 — the effects slot exists only on a collecting run, so a normal `--workers N` run
|
|
597
792
|
# marshals exactly the payload it marshalled before the feature existed.
|
|
598
793
|
payload[:effects] = session.drain_effects if @record_effects
|
|
@@ -624,6 +819,7 @@ module Rigor
|
|
|
624
819
|
if payload
|
|
625
820
|
results_by_path.merge!(payload.fetch(:results))
|
|
626
821
|
merge_worker_reporters(payload.fetch(:reporters))
|
|
822
|
+
merge_run_disclosures(payload.fetch(:disclosures, []))
|
|
627
823
|
@collected_dependencies.merge!(payload.fetch(:dependencies, {})) if @record_dependencies
|
|
628
824
|
@collected_effects.merge!(payload.fetch(:effects, {})) if @record_effects
|
|
629
825
|
else
|
|
@@ -633,7 +829,7 @@ module Rigor
|
|
|
633
829
|
degraded
|
|
634
830
|
end
|
|
635
831
|
|
|
636
|
-
# @return
|
|
832
|
+
# @return the child's `{results:, reporters:}` payload, or nil when the child exited
|
|
637
833
|
# abnormally or wrote no readable payload. `Marshal.load` is safe here: the blob was written by
|
|
638
834
|
# our own forked child to a temp file we created.
|
|
639
835
|
def fork_worker_payload(status, out_path)
|
|
@@ -658,19 +854,43 @@ module Rigor
|
|
|
658
854
|
# ADR-15 Phase 4b.x — drives every cached RBS producer on the main Ractor so each worker can serve
|
|
659
855
|
# all reflection queries from disk (Marshal-load only). Builds a single coordinator-side
|
|
660
856
|
# {Environment} for this purpose and returns it fully loaded — issue #798: the caller also reads
|
|
661
|
-
# the project-signature state off it, since it is the only
|
|
662
|
-
# ever holds. Workers still build their OWN
|
|
663
|
-
# then routes through `cached_env` instead
|
|
664
|
-
|
|
857
|
+
# the project-signature state and the effect-annotation carrier off it, since it is the only
|
|
858
|
+
# environment this backend's coordinator ever holds. Workers still build their OWN
|
|
859
|
+
# `Environment.for_project` inside the Ractor body, which then routes through `cached_env` instead
|
|
860
|
+
# of `RBS::EnvironmentLoader.new`.
|
|
861
|
+
#
|
|
862
|
+
# Built with the loaded plugin registry over the project's WHOLE file list (#793's rule), exactly
|
|
863
|
+
# as each worker builds its own. `Environment.for_project` collects plugin-synthesized virtual RBS
|
|
864
|
+
# only when handed BOTH (`collect_virtual_rbs` short-circuits on a nil registry and on an empty
|
|
865
|
+
# list), and this used to pass neither: its loader's `virtual_rbs` read empty on every project, so
|
|
866
|
+
# a carrier snapshotted off it would have been `[]` whatever the rbs-inline comments said — the
|
|
867
|
+
# method called, the row still missing. Two more things follow from building the environment the
|
|
868
|
+
# workers build: the env-cache descriptor digests the same signature roots (a plugin's
|
|
869
|
+
# `signature_paths:`) and the same virtual set, so the slot this warms is the slot the workers
|
|
870
|
+
# read; and each synthesizer runs once here and is memoised through the cache store (ADR-32 WD5)
|
|
871
|
+
# instead of once per worker.
|
|
872
|
+
#
|
|
873
|
+
# Deliberately NOT {#build_runner_environment}: that hands the environment the run's own reporter
|
|
874
|
+
# accumulators, and an environment BUILD writes to one of them — `collect_virtual_rbs` records a
|
|
875
|
+
# synthesizer's parse failures and unhonoured annotations on the `source_rbs_synthesis` reporter.
|
|
876
|
+
# Every Ractor worker builds this same environment with reporters of its own and drains them back
|
|
877
|
+
# through {#merge_worker_reporters}, whose replay of that stream appends without dedup, so a
|
|
878
|
+
# coordinator-side reporter here would count each entry once more than the drains already do. The
|
|
879
|
+
# other two are written only by demands this environment never receives (the HKT scan, per-file
|
|
880
|
+
# dispatch); all three are withheld together so the no-double-count holds by construction rather
|
|
881
|
+
# than by which reads happen to be made. The dispatch-only per-run state (the dependency-source
|
|
882
|
+
# index, the synthetic-method / project-patched indexes) is withheld for the same reason: nothing
|
|
883
|
+
# here dispatches.
|
|
884
|
+
# @param source_files — the WHOLE project's file list, never the analyzed subset.
|
|
885
|
+
def prewarm_rbs_cache_for_pool(source_files:, locked_gems: nil)
|
|
665
886
|
warm_env = Environment.for_project(
|
|
666
887
|
libraries: @configuration.libraries,
|
|
667
888
|
signature_paths: @configuration.signature_paths,
|
|
668
889
|
cache_store: @cache_store,
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
rbs_collection_auto_detect: @configuration.rbs_collection_auto_detect
|
|
890
|
+
plugin_registry: plugin_registry,
|
|
891
|
+
source_files: source_files,
|
|
892
|
+
locked_gems: locked_gems,
|
|
893
|
+
**ProjectEnvironment.dependency_discovery_options(@configuration)
|
|
674
894
|
)
|
|
675
895
|
warm_env.rbs_loader&.prewarm
|
|
676
896
|
warm_env
|
|
@@ -680,11 +900,16 @@ module Rigor
|
|
|
680
900
|
# (currently: `--no-cache` would force workers through `EnvironmentLoader.new`), degrade to
|
|
681
901
|
# sequential analysis with a `:warning` `pool-degraded` diagnostic at run start. The actual
|
|
682
902
|
# per-file analysis runs on the coordinator, identical to the default sequential path.
|
|
683
|
-
# @param source_files
|
|
903
|
+
# @param source_files — issue #793 — the whole project, so this path's environment
|
|
684
904
|
# carries the same plugin-synthesized RBS the pool workers' would. It used to build over `[]`,
|
|
685
905
|
# i.e. with no synthesized RBS at all, even on a full run.
|
|
686
906
|
def analyze_files_sequentially_fallback(files, reason:, source_files: files)
|
|
687
907
|
environment = build_runner_environment(source_files: source_files)
|
|
908
|
+
# Same set, same ORDER as `#analyze_files_sequentially`. The signature state used to be hand-copied
|
|
909
|
+
# here slot by slot, which dropped `synthesized-namespace` and every conformance row. The conformance
|
|
910
|
+
# scan inside it demands the definition of every `rigor:v1:conforms-to` class, so it has to run
|
|
911
|
+
# BEFORE the definition-build failures are read below, or a failure only that scan reaches is lost.
|
|
912
|
+
snapshot_project_signature_state(environment)
|
|
688
913
|
snapshot_effect_annotation_carrier(environment.rbs_loader)
|
|
689
914
|
diagnostics = files.flat_map { |path| @analyze_file.call(path, environment) }
|
|
690
915
|
loader = environment.rbs_loader
|
|
@@ -699,9 +924,6 @@ module Rigor
|
|
|
699
924
|
record_hkt_scan_failure(hkt_scan_outcome(environment))
|
|
700
925
|
@snapshots.class_decl_paths = loader&.class_decl_paths || {}.freeze
|
|
701
926
|
@snapshots.signature_paths = loader&.signature_paths || [].freeze
|
|
702
|
-
@snapshots.quarantined_signatures =
|
|
703
|
-
project_signature_paths? ? (loader&.quarantined_signatures || []) : []
|
|
704
|
-
@snapshots.env_build_failure = project_signature_paths? ? loader&.env_build_failure : nil
|
|
705
927
|
diagnostics.unshift(
|
|
706
928
|
Diagnostic.new(
|
|
707
929
|
path: ".rigor.yml", line: 1, column: 1,
|
|
@@ -723,9 +945,17 @@ module Rigor
|
|
|
723
945
|
end
|
|
724
946
|
# ADR-32 WD6 — merge per-worker synthesizer failures back into the coordinator's reporter. Fetched
|
|
725
947
|
# with a default empty array so older drains (pre-slice-2) remain compatible.
|
|
948
|
+
#
|
|
949
|
+
# `kind:` rides along (issue #824): without it every drained entry replayed as WD6's default
|
|
950
|
+
# `:failed`, so under `--workers N` a WD12 "parsed but not honoured" row came back as
|
|
951
|
+
# `source-rbs-synthesis-failed` — a different id, and a message telling the user the file
|
|
952
|
+
# contributed nothing when all but one of its annotations bound. Every worker reads the same
|
|
953
|
+
# sources and so hands over the same entries; the reporter's own dedup collapses them. `line:` rides
|
|
954
|
+
# along for the same reason (#1075): a consistency error is positioned at its `.rbs` member.
|
|
726
955
|
Array(drained[:source_rbs_synthesis]).each do |entry|
|
|
727
956
|
@source_rbs_synthesis_reporter.record(
|
|
728
|
-
plugin_id: entry.plugin_id, path: entry.path, message: entry.message
|
|
957
|
+
plugin_id: entry.plugin_id, path: entry.path, message: entry.message, kind: entry.kind,
|
|
958
|
+
line: entry.line
|
|
729
959
|
)
|
|
730
960
|
end
|
|
731
961
|
# Issue #696. Fetched with a default so an older drain stays compatible, exactly as the line above.
|
|
@@ -764,6 +994,18 @@ module Rigor
|
|
|
764
994
|
message: entry.message, path: entry.path, line: entry.line, column: entry.column
|
|
765
995
|
)
|
|
766
996
|
end
|
|
997
|
+
replay_deprecated_forms(rbs)
|
|
998
|
+
end
|
|
999
|
+
|
|
1000
|
+
# ADR-109 WD3 — the fourth stream, read with the nil default like the hkt one so an older drain
|
|
1001
|
+
# shape records nothing.
|
|
1002
|
+
def replay_deprecated_forms(rbs)
|
|
1003
|
+
Array(rbs[:deprecated_forms]).each do |entry|
|
|
1004
|
+
@rbs_extended_reporter.record_deprecated_form(
|
|
1005
|
+
payload: entry.payload, replacement: entry.replacement,
|
|
1006
|
+
path: entry.path, line: entry.line, column: entry.column
|
|
1007
|
+
)
|
|
1008
|
+
end
|
|
767
1009
|
end
|
|
768
1010
|
|
|
769
1011
|
# Issue #696 — accumulate the per-class `RBS::DefinitionBuilder` failures this run observed, deduped
|
|
@@ -822,8 +1064,7 @@ module Rigor
|
|
|
822
1064
|
# build on a project with no files (see {#analyze_files}). Memoised, so on a reused Environment
|
|
823
1065
|
# this is a hash read.
|
|
824
1066
|
#
|
|
825
|
-
# @
|
|
826
|
-
# @return [Array, nil] the recorded tuple, or nil (no environment, or the scan built)
|
|
1067
|
+
# @return the recorded tuple, or nil (no environment, or the scan built)
|
|
827
1068
|
def hkt_scan_outcome(environment)
|
|
828
1069
|
return nil if environment.nil?
|
|
829
1070
|
|
|
@@ -838,6 +1079,21 @@ module Rigor
|
|
|
838
1079
|
!(paths.nil? || paths.empty?)
|
|
839
1080
|
end
|
|
840
1081
|
|
|
1082
|
+
# Issue #610 — see {#snapshot_project_signature_state}. The registry's `signature_paths` is what
|
|
1083
|
+
# `Environment.for_project` defers, so this is the loader-free form of "is anything deferred?".
|
|
1084
|
+
def plugin_signature_paths?
|
|
1085
|
+
registry = plugin_registry
|
|
1086
|
+
registry.respond_to?(:signature_paths) && !registry.signature_paths.empty?
|
|
1087
|
+
end
|
|
1088
|
+
|
|
1089
|
+
# Empty for a loader with nothing deferred, without touching its env.
|
|
1090
|
+
def signature_standdowns_for(loader)
|
|
1091
|
+
return [] if loader.nil? || !loader.respond_to?(:deferred_signature_paths)
|
|
1092
|
+
return [] if loader.deferred_signature_paths.empty?
|
|
1093
|
+
|
|
1094
|
+
loader.signature_standdowns
|
|
1095
|
+
end
|
|
1096
|
+
|
|
841
1097
|
def plugin_registry
|
|
842
1098
|
@plugin_registry_reader.call
|
|
843
1099
|
end
|
|
@@ -854,6 +1110,10 @@ module Rigor
|
|
|
854
1110
|
@project_patched_methods_reader.call
|
|
855
1111
|
end
|
|
856
1112
|
|
|
1113
|
+
def template_units
|
|
1114
|
+
@template_units_reader.call
|
|
1115
|
+
end
|
|
1116
|
+
|
|
857
1117
|
def project_scope_seed
|
|
858
1118
|
@project_scope_seed_reader.call
|
|
859
1119
|
end
|