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
|
@@ -36,9 +36,14 @@ module Rigor
|
|
|
36
36
|
# - `method_names` — Array of Symbol method names. A call shape `<receiver_subclass>.get('/path') { ... }`
|
|
37
37
|
# matches when `:get` is in this list. (Named `verbs:` before ADR-60 WD2 normalised the macro
|
|
38
38
|
# value-object vocabulary.)
|
|
39
|
-
# - `self_type` —
|
|
40
|
-
#
|
|
41
|
-
#
|
|
39
|
+
# - `self_type` — the `self`-binding the substrate applies inside the block. `:receiver_instance`
|
|
40
|
+
# (the default) types `self` as an instance of the receiver class — the Sinatra contract. A String
|
|
41
|
+
# binds `self` to a *named* class instead of the receiver: `"Grape::Endpoint"` binds
|
|
42
|
+
# `Nominal[Grape::Endpoint]` (the block is `instance_eval`'d on an instance of that class, e.g. a
|
|
43
|
+
# route body on `Grape::Endpoint`), and `"singleton(Grape::API::Instance)"` binds
|
|
44
|
+
# `Singleton[Grape::API::Instance]` (the block is `instance_eval`'d on that *class object*, e.g.
|
|
45
|
+
# a `namespace` body on `Grape::API::Instance`). Reserved Symbol names (`:receiver_singleton`,
|
|
46
|
+
# `:dsl_recorder`) remain unaccepted.
|
|
42
47
|
#
|
|
43
48
|
# ## Ractor-shareability
|
|
44
49
|
#
|
|
@@ -48,6 +53,13 @@ module Rigor
|
|
|
48
53
|
SELF_TYPE_RECEIVER_INSTANCE = :receiver_instance
|
|
49
54
|
VALID_SELF_TYPES = [SELF_TYPE_RECEIVER_INSTANCE].freeze
|
|
50
55
|
|
|
56
|
+
CLASS_NAME_PATTERN = /[A-Z]\w*(?:::[A-Z]\w*)*/
|
|
57
|
+
# `self_type: "Foo::Bar"` — the block is `instance_eval`'d on an instance of `Foo::Bar`.
|
|
58
|
+
NAMED_SELF_TYPE_PATTERN = /\A#{CLASS_NAME_PATTERN}\z/
|
|
59
|
+
# `self_type: "singleton(Foo::Bar)"` — the block is `instance_eval`'d on the `Foo::Bar` class
|
|
60
|
+
# object itself (Grape's `namespace`/`route_param` bodies run on `Grape::API::Instance`).
|
|
61
|
+
SINGLETON_SELF_TYPE_PATTERN = /\Asingleton\((#{CLASS_NAME_PATTERN})\)\z/
|
|
62
|
+
|
|
51
63
|
attr_reader :receiver_constraint, :method_names, :self_type
|
|
52
64
|
|
|
53
65
|
def initialize(receiver_constraint:, method_names:, self_type: SELF_TYPE_RECEIVER_INSTANCE)
|
|
@@ -57,7 +69,7 @@ module Rigor
|
|
|
57
69
|
|
|
58
70
|
@receiver_constraint = receiver_constraint.dup.freeze
|
|
59
71
|
@method_names = method_names.map(&:to_sym).freeze
|
|
60
|
-
@self_type = self_type
|
|
72
|
+
@self_type = self_type.is_a?(String) ? self_type.dup.freeze : self_type
|
|
61
73
|
freeze
|
|
62
74
|
end
|
|
63
75
|
|
|
@@ -81,6 +93,31 @@ module Rigor
|
|
|
81
93
|
[receiver_constraint, method_names, self_type].hash
|
|
82
94
|
end
|
|
83
95
|
|
|
96
|
+
# The class name a String `self_type` binds `self` to — `"Foo::Bar"` for both the plain and the
|
|
97
|
+
# `singleton(Foo::Bar)` form — or `nil` for `:receiver_instance`.
|
|
98
|
+
def self_type_name
|
|
99
|
+
return nil unless self_type.is_a?(String)
|
|
100
|
+
|
|
101
|
+
self_type[SINGLETON_SELF_TYPE_PATTERN, 1] || self_type
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Whether a String `self_type` binds the *class object* (`"singleton(Foo::Bar)"`) rather than an
|
|
105
|
+
# instance (`"Foo::Bar"`). Nominal-receiver call sites only match instance-binding entries —
|
|
106
|
+
# a `singleton(...)` binding exists solely for `instance_eval`-on-class contracts, which always
|
|
107
|
+
# surface as `Singleton[X]` receivers.
|
|
108
|
+
def singleton_binding?
|
|
109
|
+
self_type.is_a?(String) && self_type.match?(SINGLETON_SELF_TYPE_PATTERN)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Whether `self_type` names a class whose *instance* the block is `instance_eval`'d on
|
|
113
|
+
# (`"Foo::Bar"`). These entries are the only ones that also match `Nominal[Y]` receivers: inside
|
|
114
|
+
# an already-narrowed `instance_eval` body (`self : Nominal[ParamsScope]`), a nested call on
|
|
115
|
+
# `self` re-enters the same context. `:receiver_instance` keeps its original Singleton-only
|
|
116
|
+
# contract — a nominal receiver calling a class-level verb is a different (unmodelled) shape.
|
|
117
|
+
def named_instance_binding?
|
|
118
|
+
self_type.is_a?(String) && !singleton_binding?
|
|
119
|
+
end
|
|
120
|
+
|
|
84
121
|
private
|
|
85
122
|
|
|
86
123
|
def validate_receiver_constraint!(value)
|
|
@@ -108,10 +145,12 @@ module Rigor
|
|
|
108
145
|
|
|
109
146
|
def validate_self_type!(self_type)
|
|
110
147
|
return if VALID_SELF_TYPES.include?(self_type)
|
|
148
|
+
return if self_type.is_a?(String) &&
|
|
149
|
+
(self_type.match?(NAMED_SELF_TYPE_PATTERN) || self_type.match?(SINGLETON_SELF_TYPE_PATTERN))
|
|
111
150
|
|
|
112
151
|
raise ArgumentError,
|
|
113
|
-
"Plugin::Macro::BlockAsMethod#self_type must be one of #{VALID_SELF_TYPES.inspect}
|
|
114
|
-
"got #{self_type.inspect}"
|
|
152
|
+
"Plugin::Macro::BlockAsMethod#self_type must be one of #{VALID_SELF_TYPES.inspect} " \
|
|
153
|
+
"or a class-name String ('Foo::Bar' / 'singleton(Foo::Bar)'), got #{self_type.inspect}"
|
|
115
154
|
end
|
|
116
155
|
end
|
|
117
156
|
end
|
|
@@ -152,7 +152,7 @@ module Rigor
|
|
|
152
152
|
class ReturnsFromArg
|
|
153
153
|
attr_reader :position, :plugin_id, :fact
|
|
154
154
|
|
|
155
|
-
# @return
|
|
155
|
+
# @return coerced value class for a Hash / nil / ReturnsFromArg input. Raises
|
|
156
156
|
# on any other shape so manifest authoring failures surface at construction time.
|
|
157
157
|
def self.coerce(value)
|
|
158
158
|
return nil if value.nil?
|
|
@@ -105,7 +105,7 @@ module Rigor
|
|
|
105
105
|
to_h.hash
|
|
106
106
|
end
|
|
107
107
|
|
|
108
|
-
# @return
|
|
108
|
+
# @return fully-qualified module name for the given trait symbol, or nil when the
|
|
109
109
|
# registry doesn't know the symbol (caller emits a tier_b.unknown-trait provenance marker and falls
|
|
110
110
|
# through).
|
|
111
111
|
def module_for(symbol)
|
|
@@ -42,31 +42,49 @@ module Rigor
|
|
|
42
42
|
# {Rigor::Effects::Label} accepts as a root.
|
|
43
43
|
VALID_EFFECT_ROOT = /\A[a-z][a-z0-9_]*\z/
|
|
44
44
|
|
|
45
|
+
# ADR-96 WD1 — the gems a plugin models, spelled exactly as `Gemfile.lock` names them. Not derivable
|
|
46
|
+
# from the plugin id (`rigor-factorybot` models `factory_bot`, `rigor-rspec` models `rspec-core`), which
|
|
47
|
+
# is what makes it a declared field; an empty list is the meaningful answer for a plugin that models no
|
|
48
|
+
# gem at all.
|
|
49
|
+
attr_reader :target_gems
|
|
50
|
+
|
|
45
51
|
attr_reader :id, :version, :description, :config_schema, :config_defaults, :produces, :consumes,
|
|
46
|
-
:owns_receivers, :open_receivers, :
|
|
52
|
+
:owns_receivers, :open_receivers, :rbs_complete_ancestors, :rbs_complete_extends,
|
|
53
|
+
:type_node_resolvers,
|
|
54
|
+
:block_as_methods,
|
|
47
55
|
:heredoc_templates, :nested_class_templates, :trait_registries,
|
|
48
56
|
:hkt_registrations, :hkt_definitions, :signature_paths, :protocol_contracts,
|
|
49
57
|
:source_rbs_synthesizer, :additional_initializers,
|
|
50
58
|
:effect_root, :effect_labels, :effect_attributions, :effect_edges, :effect_entry_points,
|
|
51
59
|
:effect_ancestry
|
|
52
60
|
|
|
53
|
-
|
|
61
|
+
# #392 — the project-relative globs whose files this plugin compiles into {TemplateUnit}s. Purely a
|
|
62
|
+
# CLAIM: the engine globs these, reads each match's bytes and offers them to
|
|
63
|
+
# {Base#template_units_for_file}, which is where the transform itself lives. A plugin declaring none
|
|
64
|
+
# is never asked, and a run whose plugins declare none does no extra globbing at all.
|
|
65
|
+
attr_reader :template_globs
|
|
66
|
+
|
|
67
|
+
def initialize( # rubocop:disable Metrics/ParameterLists, Metrics/MethodLength
|
|
54
68
|
id:, version:,
|
|
55
|
-
description: nil, config_schema: {},
|
|
56
|
-
produces: [], consumes: [], owns_receivers: [], open_receivers: [],
|
|
69
|
+
description: nil, config_schema: {}, target_gems: [],
|
|
70
|
+
produces: [], consumes: [], owns_receivers: [], open_receivers: [], rbs_complete_ancestors: [],
|
|
71
|
+
rbs_complete_extends: [], type_node_resolvers: [],
|
|
57
72
|
block_as_methods: [], heredoc_templates: [], nested_class_templates: [],
|
|
58
73
|
trait_registries: [],
|
|
59
74
|
hkt_registrations: [], hkt_definitions: [], signature_paths: [], protocol_contracts: [],
|
|
60
75
|
source_rbs_synthesizer: nil, additional_initializers: [],
|
|
61
76
|
effect_root: nil, effect_labels: [], effect_attributions: [], effect_edges: [],
|
|
62
|
-
effect_entry_points: [], effect_ancestry: []
|
|
77
|
+
effect_entry_points: [], effect_ancestry: [], template_globs: []
|
|
63
78
|
)
|
|
64
79
|
validate_id!(id)
|
|
65
80
|
validate_version!(version)
|
|
66
81
|
validate_config_schema!(config_schema)
|
|
67
82
|
validate_produces!(produces)
|
|
83
|
+
validate_target_gems!(target_gems)
|
|
68
84
|
validate_owns_receivers!(owns_receivers)
|
|
69
85
|
validate_open_receivers!(open_receivers)
|
|
86
|
+
validate_rbs_complete_ancestors!(rbs_complete_ancestors)
|
|
87
|
+
validate_rbs_complete_extends!(rbs_complete_extends)
|
|
70
88
|
validate_type_node_resolvers!(type_node_resolvers)
|
|
71
89
|
validate_block_as_methods!(block_as_methods)
|
|
72
90
|
validate_heredoc_templates!(heredoc_templates)
|
|
@@ -85,10 +103,12 @@ module Rigor
|
|
|
85
103
|
open_receivers, type_node_resolvers, block_as_methods, heredoc_templates, trait_registries,
|
|
86
104
|
hkt_registrations, hkt_definitions, signature_paths, protocol_contracts,
|
|
87
105
|
source_rbs_synthesizer)
|
|
106
|
+
assign_target_gems(target_gems)
|
|
107
|
+
assign_rbs_complete_ancestors(rbs_complete_ancestors, rbs_complete_extends)
|
|
88
108
|
assign_nested_class_templates(nested_class_templates)
|
|
89
109
|
assign_additional_initializers(additional_initializers)
|
|
90
110
|
assign_effect_fields(effect_root, effect_labels, effect_attributions, effect_edges,
|
|
91
|
-
effect_entry_points, effect_ancestry)
|
|
111
|
+
effect_entry_points, effect_ancestry, template_globs)
|
|
92
112
|
freeze
|
|
93
113
|
end
|
|
94
114
|
|
|
@@ -119,6 +139,19 @@ module Rigor
|
|
|
119
139
|
@source_rbs_synthesizer = source_rbs_synthesizer
|
|
120
140
|
end
|
|
121
141
|
|
|
142
|
+
# ADR-96 WD1 — assigned outside assign_fields, which already carries the maximum positional arity.
|
|
143
|
+
def assign_target_gems(target_gems)
|
|
144
|
+
@target_gems = target_gems.map { |g| g.to_s.dup.freeze }.uniq.freeze
|
|
145
|
+
end
|
|
146
|
+
private :assign_target_gems
|
|
147
|
+
|
|
148
|
+
# ADR-43 WD4 — assigned outside assign_fields (which already carries the maximum positional arity).
|
|
149
|
+
def assign_rbs_complete_ancestors(rbs_complete_ancestors, rbs_complete_extends)
|
|
150
|
+
@rbs_complete_ancestors = rbs_complete_ancestors.map { |c| c.to_s.dup.freeze }.freeze
|
|
151
|
+
@rbs_complete_extends = rbs_complete_extends.map { |c| c.to_s.dup.freeze }.freeze
|
|
152
|
+
end
|
|
153
|
+
private :assign_rbs_complete_ancestors
|
|
154
|
+
|
|
122
155
|
# Assigned outside assign_fields (which already carries the maximum positional arity) — set in
|
|
123
156
|
# `initialize` before the final freeze. ADR-36 nested-class emission tier.
|
|
124
157
|
def assign_nested_class_templates(nested_class_templates)
|
|
@@ -148,15 +181,27 @@ module Rigor
|
|
|
148
181
|
private :validate_effect_fields!
|
|
149
182
|
|
|
150
183
|
def assign_effect_fields(effect_root, effect_labels, effect_attributions, effect_edges,
|
|
151
|
-
effect_entry_points, effect_ancestry)
|
|
184
|
+
effect_entry_points, effect_ancestry, template_globs)
|
|
152
185
|
@effect_root = effect_root.nil? ? nil : effect_root.to_s.dup.freeze
|
|
153
186
|
@effect_labels = effect_labels.map { |label| label.to_s.dup.freeze }.uniq.sort.freeze
|
|
154
187
|
@effect_attributions = effect_attributions.dup.freeze
|
|
155
188
|
@effect_edges = effect_edges.dup.freeze
|
|
156
189
|
@effect_entry_points = effect_entry_points.dup.freeze
|
|
157
190
|
@effect_ancestry = effect_ancestry.dup.freeze
|
|
191
|
+
assign_template_globs(template_globs)
|
|
158
192
|
end
|
|
159
193
|
private :assign_effect_fields
|
|
194
|
+
|
|
195
|
+
# #392 — a glob is a String, and an absolute one is refused: a template unit is a project file, and
|
|
196
|
+
# a plugin reaching outside the project root is the trust boundary ADR-2 § "Plugin Trust and I/O
|
|
197
|
+
# Policy" draws. Validated and assigned in one call, because `#initialize` is at its line budget.
|
|
198
|
+
def assign_template_globs(globs)
|
|
199
|
+
validate_array_of!("template_globs", globs, "non-empty relative glob Strings") do |glob|
|
|
200
|
+
glob.is_a?(String) && !glob.empty? && !glob.start_with?("/") && !glob.include?("..")
|
|
201
|
+
end
|
|
202
|
+
@template_globs = globs.map { |glob| glob.to_s.dup.freeze }.uniq.freeze
|
|
203
|
+
end
|
|
204
|
+
private :assign_template_globs
|
|
160
205
|
# rubocop:enable Metrics/ParameterLists, Metrics/AbcSize
|
|
161
206
|
|
|
162
207
|
public
|
|
@@ -182,17 +227,20 @@ module Rigor
|
|
|
182
227
|
errors
|
|
183
228
|
end
|
|
184
229
|
|
|
185
|
-
def to_h # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
230
|
+
def to_h # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
|
|
186
231
|
{
|
|
187
232
|
"id" => id,
|
|
188
233
|
"version" => version,
|
|
189
234
|
"description" => description,
|
|
190
235
|
"config_schema" => config_schema.to_h { |k, v| [k, v.to_s] },
|
|
191
236
|
"config_defaults" => config_defaults,
|
|
237
|
+
"target_gems" => target_gems,
|
|
192
238
|
"produces" => produces.map(&:to_s),
|
|
193
239
|
"consumes" => consumes.map { |c| consumption_hash(c) },
|
|
194
240
|
"owns_receivers" => owns_receivers,
|
|
195
241
|
"open_receivers" => open_receivers,
|
|
242
|
+
"rbs_complete_ancestors" => rbs_complete_ancestors,
|
|
243
|
+
"rbs_complete_extends" => rbs_complete_extends,
|
|
196
244
|
"type_node_resolvers" => type_node_resolvers.map { |r| r.class.name },
|
|
197
245
|
"block_as_methods" => block_as_methods.map(&:to_h),
|
|
198
246
|
"heredoc_templates" => heredoc_templates.map(&:to_h),
|
|
@@ -209,7 +257,8 @@ module Rigor
|
|
|
209
257
|
"effect_attributions" => effect_attributions.map(&:to_h),
|
|
210
258
|
"effect_edges" => effect_edges.map(&:to_h),
|
|
211
259
|
"effect_entry_points" => effect_entry_points.map(&:to_h),
|
|
212
|
-
"effect_ancestry" => effect_ancestry.map(&:to_h)
|
|
260
|
+
"effect_ancestry" => effect_ancestry.map(&:to_h),
|
|
261
|
+
"template_globs" => template_globs
|
|
213
262
|
}
|
|
214
263
|
end
|
|
215
264
|
|
|
@@ -218,10 +267,11 @@ module Rigor
|
|
|
218
267
|
# otherwise. A third-party plugin's `effect_root:` is ignored here (and warned about by the registry),
|
|
219
268
|
# so it opens only the root named after itself.
|
|
220
269
|
def effect_owner
|
|
221
|
-
|
|
270
|
+
root = effect_root
|
|
271
|
+
return id if root.nil?
|
|
222
272
|
return id unless FirstParty.bundled?(id)
|
|
223
273
|
|
|
224
|
-
|
|
274
|
+
root
|
|
225
275
|
end
|
|
226
276
|
|
|
227
277
|
# Whether this plugin's `effect_attributions:` may carry `discharge: true` (ADR-103 WD6).
|
|
@@ -344,6 +394,13 @@ module Rigor
|
|
|
344
394
|
raise ArgumentError, "plugin manifest #{field} must be an Array of #{label}, got #{value.inspect}"
|
|
345
395
|
end
|
|
346
396
|
|
|
397
|
+
# ADR-96 WD1 — every entry is a gem name as `Gemfile.lock` spells it. The uniform Array-of-String check
|
|
398
|
+
# is all the manifest can do: whether the named gem exists is a fact about RubyGems, not about the
|
|
399
|
+
# manifest, and a typo surfaces as an advisory that never fires rather than as a load failure.
|
|
400
|
+
def validate_target_gems!(target_gems)
|
|
401
|
+
validate_array_of!("target_gems", target_gems, "non-empty String") { |g| g.is_a?(String) && !g.empty? }
|
|
402
|
+
end
|
|
403
|
+
|
|
347
404
|
def validate_produces!(produces)
|
|
348
405
|
validate_array_of!("produces", produces, "Symbol/String") { |p| p.is_a?(Symbol) || p.is_a?(String) }
|
|
349
406
|
end
|
|
@@ -366,6 +423,32 @@ module Rigor
|
|
|
366
423
|
validate_array_of!("open_receivers", open_receivers, "non-empty String") { |c| c.is_a?(String) && !c.empty? }
|
|
367
424
|
end
|
|
368
425
|
|
|
426
|
+
# ADR-43 WD4 — `rbs_complete_ancestors:` declares the class names this plugin's bundled RBS covers
|
|
427
|
+
# COMPLETELY: a method call the signature does not declare is genuinely absent at runtime. A
|
|
428
|
+
# Ruby-source subclass of a listed class may then bridge inherited calls to the ancestor's RBS
|
|
429
|
+
# (the ADR-43 allow-list's manifest-declared half). The dual of `open_receivers:` — that field
|
|
430
|
+
# marks a class open to suppress diagnostics on an unbounded surface; this one marks a class
|
|
431
|
+
# closed to ENABLE them on subclasses. Listing a class whose signature is partial would turn
|
|
432
|
+
# every omitted inherited method into a `call.undefined-method` false positive on subclass
|
|
433
|
+
# receivers, so only classes the plugin's `signature_paths:` declares exhaustively belong here.
|
|
434
|
+
def validate_rbs_complete_ancestors!(rbs_complete_ancestors)
|
|
435
|
+
validate_array_of!("rbs_complete_ancestors", rbs_complete_ancestors, "non-empty String") do |c|
|
|
436
|
+
c.is_a?(String) && !c.empty?
|
|
437
|
+
end
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
# `rbs_complete_extends:` is the extend-edge twin of `rbs_complete_ancestors:` (ADR-43 WD4): it names
|
|
441
|
+
# the MODULES whose bundled RBS instance surface is complete, so a project `extend M` in a class or
|
|
442
|
+
# module body lets singleton-side calls on that class resolve M's declared instance methods
|
|
443
|
+
# (`class F; extend T::Sig; sig { ... }; end` reaching `T::Sig#sig`). Same completeness rule: a
|
|
444
|
+
# module whose declared surface is partial does not belong here — the extend edge would misreport
|
|
445
|
+
# real calls as `call.undefined-method`.
|
|
446
|
+
def validate_rbs_complete_extends!(rbs_complete_extends)
|
|
447
|
+
validate_array_of!("rbs_complete_extends", rbs_complete_extends, "non-empty String") do |c|
|
|
448
|
+
c.is_a?(String) && !c.empty?
|
|
449
|
+
end
|
|
450
|
+
end
|
|
451
|
+
|
|
369
452
|
# ADR-13 slice 2 — `type_node_resolvers:` declares the plugin-supplied `TypeNodeResolver` instances the
|
|
370
453
|
# parser consults (in slice 3) when an RBS::Extended payload's named- or generic-type head misses the
|
|
371
454
|
# built-in registry. Slice 2 carries the declarations on the manifest and the registry exposes them in
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative "blueprint"
|
|
4
|
+
# Issue #806 — {Registry#guarded_manifest} constructs one. `Rigor::Plugin::LoadError` MUST be defined by
|
|
5
|
+
# then: an unresolved bare `LoadError` in this lexical scope silently falls back to Ruby's own ::LoadError.
|
|
6
|
+
require_relative "load_error"
|
|
4
7
|
|
|
5
8
|
module Rigor
|
|
6
9
|
module Plugin
|
|
@@ -217,23 +220,26 @@ module Rigor
|
|
|
217
220
|
class Registry
|
|
218
221
|
attr_reader :plugins, :load_errors, :blueprints, :contribution_index, :resolved_gem_paths
|
|
219
222
|
|
|
220
|
-
# @param plugins
|
|
221
|
-
# @param load_errors
|
|
223
|
+
# @param plugins — instantiated plugin instances in deterministic order.
|
|
224
|
+
# @param load_errors — failures surfaced during loading. Each error is
|
|
222
225
|
# also turned into a diagnostic by the runner.
|
|
223
|
-
# @param blueprints
|
|
226
|
+
# @param blueprints — frozen, Ractor-shareable replay descriptors
|
|
224
227
|
# aligned 1:1 with `plugins`. The loader fills this in; callers that construct Registry manually MAY
|
|
225
228
|
# pass `[]` and accept that {.materialize} cannot replay the set.
|
|
226
|
-
# @param resolved_gem_paths
|
|
229
|
+
# @param resolved_gem_paths — #194 slice 1 — `gem name => resolved file path`
|
|
227
230
|
# for each successfully required plugin gem, so `rigor plugins` can print where a loaded (and
|
|
228
231
|
# possibly frozen) plugin actually loaded from. Defaults to empty; a worker registry built by
|
|
229
232
|
# {.materialize} carries none (the provenance surface runs only on the coordinator).
|
|
230
233
|
def initialize(plugins: [], load_errors: [], blueprints: [], resolved_gem_paths: {})
|
|
231
234
|
@plugins = plugins.dup.freeze
|
|
232
|
-
@load_errors = load_errors.dup.freeze
|
|
233
235
|
@blueprints = blueprints.dup.freeze
|
|
234
236
|
@resolved_gem_paths = resolved_gem_paths.dup.freeze
|
|
235
237
|
@contribution_index = ContributionIndex.new(@plugins)
|
|
236
|
-
|
|
238
|
+
# Issue #806 — every manifest the construction-time aggregates need is read ONCE here, behind a
|
|
239
|
+
# per-plugin rescue, and a plugin that raises joins `load_errors` instead of taking the run down.
|
|
240
|
+
manifest_errors = []
|
|
241
|
+
compile_aggregates(@plugins.map { |plugin| guarded_manifest(plugin, manifest_errors) })
|
|
242
|
+
@load_errors = (load_errors + manifest_errors).freeze
|
|
237
243
|
# ADR-52 WD4 — the single engine-owned node-rule walk, compiled once per run from the node-rule
|
|
238
244
|
# plugin subset (registry order). The runner reuses it for every file; it builds fresh per-file
|
|
239
245
|
# state internally, so it is safe to freeze and share.
|
|
@@ -306,9 +312,14 @@ module Rigor
|
|
|
306
312
|
# in plugin registration order. `Environment#build_name_scope` builds a `TypeNode::ResolverChain` from
|
|
307
313
|
# this list (environment.rb). The first non-nil `#resolve(node, scope)` return wins per ADR-13 WD3 /
|
|
308
314
|
# WD5 — registration order is the user's lever.
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
315
|
+
#
|
|
316
|
+
# Issue #806 — compiled at construction alongside its `compile_aggregates` siblings, and for a second
|
|
317
|
+
# reason beyond theirs: `Environment#build_name_scope` demands it during Environment CONSTRUCTION, so
|
|
318
|
+
# the previous per-call `plugin.manifest` read had no rescue above it anywhere — a plugin raising here
|
|
319
|
+
# aborted every `Environment.for_project`, i.e. the whole run, before any seam could record it. The
|
|
320
|
+
# guard has to sit at registry construction because that is the last point at which a failure can still
|
|
321
|
+
# join `load_errors` (the registry freezes immediately after).
|
|
322
|
+
attr_reader :type_node_resolvers
|
|
312
323
|
|
|
313
324
|
# ADR-20 slice 6 — aggregate every loaded plugin's manifest-declared HKT registrations + definitions
|
|
314
325
|
# into a single `Inference::HktRegistry` overlay that `Environment#hkt_registry` merges on top of the
|
|
@@ -362,6 +373,30 @@ module Rigor
|
|
|
362
373
|
@open_receivers_set.include?(class_name.to_s)
|
|
363
374
|
end
|
|
364
375
|
|
|
376
|
+
# ADR-43 WD4 — the aggregate set of "RBS-complete ancestor" class names declared across loaded
|
|
377
|
+
# plugins (manifest `rbs_complete_ancestors:`). `RbsDispatch`'s inherited-call bridge consults it
|
|
378
|
+
# alongside the engine's own allow-list: a Ruby-source subclass of a listed class resolves
|
|
379
|
+
# inherited calls against the ancestor's RBS, and the signature-reading rules apply to them.
|
|
380
|
+
attr_reader :rbs_complete_ancestors
|
|
381
|
+
|
|
382
|
+
def rbs_complete_ancestor?(class_name)
|
|
383
|
+
return false if class_name.nil?
|
|
384
|
+
|
|
385
|
+
@rbs_complete_ancestors_set.include?(class_name.to_s)
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
# The extend-edge twin of `rbs_complete_ancestors` — the aggregate set of module names declared via
|
|
389
|
+
# manifest `rbs_complete_extends:`. `RbsDispatch`'s singleton bridge consults it for `extend M`
|
|
390
|
+
# edges in project source: `class F; extend T::Sig; sig { ... }; end` resolves `sig` through
|
|
391
|
+
# `T::Sig`'s bundled RBS instance surface.
|
|
392
|
+
attr_reader :rbs_complete_extends
|
|
393
|
+
|
|
394
|
+
def rbs_complete_extends?(class_name)
|
|
395
|
+
return false if class_name.nil?
|
|
396
|
+
|
|
397
|
+
@rbs_complete_extends_set.include?(class_name.to_s)
|
|
398
|
+
end
|
|
399
|
+
|
|
365
400
|
# ADR-28 — flat, ordered list of every loaded plugin's path-scoped method-protocol contracts, in
|
|
366
401
|
# plugin registration order. Read from each plugin's `#protocol_contracts` (which the manifest backs
|
|
367
402
|
# by default but a plugin MAY override to fold in per-project config). Consumed by
|
|
@@ -419,15 +454,29 @@ module Rigor
|
|
|
419
454
|
# compiled once at construction (the registry is frozen, so the flat_map-on-every-call versions
|
|
420
455
|
# re-derived an invariant). `@contracts_by_path` is a mutable per-path memo inside the frozen registry
|
|
421
456
|
# — safe because the contract set and the glob semantics are fixed for the lifetime of the run.
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
457
|
+
#
|
|
458
|
+
# @param manifests — one entry per plugin, positionally aligned with `@plugins`;
|
|
459
|
+
# nil where {#guarded_manifest} caught a raising manifest read.
|
|
460
|
+
def compile_aggregates(manifests)
|
|
461
|
+
@additional_initializers = manifests.flat_map { |m| m&.additional_initializers || [] }.freeze
|
|
462
|
+
@open_receivers = aggregate_class_names(manifests, :open_receivers)
|
|
425
463
|
@open_receivers_set = @open_receivers.to_set.freeze
|
|
464
|
+
@rbs_complete_ancestors = aggregate_class_names(manifests, :rbs_complete_ancestors)
|
|
465
|
+
@rbs_complete_ancestors_set = @rbs_complete_ancestors.to_set.freeze
|
|
466
|
+
@rbs_complete_extends = aggregate_class_names(manifests, :rbs_complete_extends)
|
|
467
|
+
@rbs_complete_extends_set = @rbs_complete_extends.to_set.freeze
|
|
468
|
+
@type_node_resolvers = manifests.flat_map { |m| m&.type_node_resolvers || [] }.freeze
|
|
426
469
|
@protocol_contracts = @plugins.flat_map { |p| safe_protocol_contracts(p) }.freeze
|
|
427
470
|
@contracts_by_path = {}
|
|
428
471
|
@effect_memo = {}
|
|
429
472
|
end
|
|
430
473
|
|
|
474
|
+
# The shared shape of `open_receivers:` / `rbs_complete_ancestors:` — a flat uniq'd class-name list
|
|
475
|
+
# aggregated across manifests, each entry normalised to String.
|
|
476
|
+
def aggregate_class_names(manifests, field)
|
|
477
|
+
manifests.flat_map { |m| (m&.public_send(field) || []).map(&:to_s) }.uniq.freeze
|
|
478
|
+
end
|
|
479
|
+
|
|
431
480
|
# Fail-soft per plugin: a plugin whose `effect_attributions:` override raises (a missing
|
|
432
481
|
# `config/application.rb`, an unreadable path) contributes nothing rather than taking the run down.
|
|
433
482
|
# An effect contribution is an enrichment; ADR-2 isolates plugin failures at the analyzer boundary
|
|
@@ -466,6 +515,21 @@ module Rigor
|
|
|
466
515
|
nil
|
|
467
516
|
end
|
|
468
517
|
|
|
518
|
+
# Issue #806 — {#safe_manifest} with a receipt. The construction-time aggregates degraded silently
|
|
519
|
+
# when a manifest read raised, so a plugin that contributed nothing looked identical to a plugin that
|
|
520
|
+
# was never asked; the load-error channel is where "a plugin could not be loaded" already lives, and
|
|
521
|
+
# `Analysis::Runner` turns each entry into one `plugin_loader.load-error` row naming the plugin. The
|
|
522
|
+
# plugin ref is the CLASS, not `manifest.id`: the manifest is the surface that just failed.
|
|
523
|
+
def guarded_manifest(plugin, errors)
|
|
524
|
+
plugin.manifest
|
|
525
|
+
rescue StandardError => e
|
|
526
|
+
errors << LoadError.new(
|
|
527
|
+
"plugin #{plugin.class} raised while reading its manifest: #{e.class}: #{e.message}",
|
|
528
|
+
plugin_ref: plugin.class.to_s, cause: e
|
|
529
|
+
)
|
|
530
|
+
nil
|
|
531
|
+
end
|
|
532
|
+
|
|
469
533
|
def safe_protocol_contracts(plugin)
|
|
470
534
|
plugin.protocol_contracts || []
|
|
471
535
|
rescue StandardError
|
|
@@ -21,19 +21,36 @@ module Rigor
|
|
|
21
21
|
# dropping an annotation it parsed. They are not the same news — the first says the file contributed
|
|
22
22
|
# nothing, the second that it contributed all but one thing — so they carry distinct diagnostic ids.
|
|
23
23
|
# Defaults to `:failed`, the pre-WD12 meaning, so an older caller records what it always did.
|
|
24
|
-
|
|
24
|
+
#
|
|
25
|
+
# `:contradiction` (ADR-112 WD5, issue #1075) is the consistency rule's error: a member two sources
|
|
26
|
+
# declare in ways that contradict, or a refinement outside its own declared type. It is the one kind
|
|
27
|
+
# positioned at a real line (`line`, nil for every other kind), because it usually sits in a `.rbs`
|
|
28
|
+
# file whose positions are exact; the others are file-level rows at line 1.
|
|
29
|
+
Entry = Data.define(:plugin_id, :path, :message, :kind, :line)
|
|
25
30
|
|
|
26
31
|
def initialize
|
|
27
32
|
@entries = []
|
|
33
|
+
@seen = {}
|
|
28
34
|
end
|
|
29
35
|
|
|
30
|
-
|
|
31
|
-
|
|
36
|
+
# Identical entries are collapsed. Each becomes one `:info` row, and two rows saying the same thing
|
|
37
|
+
# about the same file carry nothing the first does not: the synthesizer's own per-file notices are
|
|
38
|
+
# already `uniq`, but a worker pool re-runs the whole env build in EVERY worker over the same project
|
|
39
|
+
# file list and then drains each worker's stream into this one reporter, so without the dedup a
|
|
40
|
+
# `--workers N` run printed N copies of a row a `--workers=0` run printed once. The same collapse the
|
|
41
|
+
# {RbsExtended::Reporter} drain documents, for the same reason.
|
|
42
|
+
def record(plugin_id:, path:, message:, kind: :failed, line: nil)
|
|
43
|
+
entry = Entry.new(
|
|
32
44
|
plugin_id: plugin_id.to_s.dup.freeze,
|
|
33
45
|
path: path.to_s.dup.freeze,
|
|
34
46
|
message: message.to_s.dup.freeze,
|
|
35
|
-
kind: kind
|
|
47
|
+
kind: kind,
|
|
48
|
+
line: line
|
|
36
49
|
)
|
|
50
|
+
return nil if @seen.key?(entry)
|
|
51
|
+
|
|
52
|
+
@seen[entry] = true
|
|
53
|
+
@entries << entry
|
|
37
54
|
nil
|
|
38
55
|
end
|
|
39
56
|
|