rigortype 0.4.5 → 0.4.7
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/gem_overlay/activesupport/core_ext.rbs +16 -13
- data/data/vendored_gem_sigs/bundler/bundler.rbs +1 -1
- data/data/vendored_gem_sigs/rubygems/rubygems_extras.rbs +4 -3
- data/docs/handbook/01-getting-started.md +5 -2
- data/docs/handbook/11-sig-gen.md +61 -5
- data/docs/handbook/appendix-phpstan.md +4 -4
- data/docs/manual/02-cli-reference.md +192 -27
- data/docs/manual/03-configuration.md +38 -4
- data/docs/manual/04-diagnostics.md +1 -1
- data/docs/manual/06-baseline.md +6 -4
- data/docs/manual/09-editor-integration.md +13 -2
- data/docs/manual/10-mcp-server.md +47 -3
- data/docs/manual/12-caching.md +9 -1
- data/docs/manual/plugins/rigor-actionmailer.md +30 -0
- data/docs/manual/plugins/rigor-actionpack.md +49 -11
- data/docs/manual/plugins/rigor-activesupport-core-ext.md +20 -1
- data/docs/manual/plugins/rigor-devise.md +15 -0
- data/docs/manual/plugins/rigor-rspec.md +2 -1
- data/lib/rigor/analysis/baseline.rb +24 -27
- data/lib/rigor/analysis/buffer_binding.rb +14 -0
- data/lib/rigor/analysis/check_rules/always_truthy_condition_collector.rb +5 -6
- data/lib/rigor/analysis/check_rules/dead_assignment_collector.rb +2 -2
- data/lib/rigor/analysis/check_rules/declaration_sourced_guard.rb +4 -4
- data/lib/rigor/analysis/check_rules/duplicate_hash_key_collector.rb +2 -2
- data/lib/rigor/analysis/check_rules/inferred_param_guard.rb +105 -12
- data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +143 -15
- data/lib/rigor/analysis/check_rules/lexical_method_sites.rb +4 -1
- data/lib/rigor/analysis/check_rules/main_pass_collector.rb +5 -8
- data/lib/rigor/analysis/check_rules/published_constant_guard.rb +1 -1
- data/lib/rigor/analysis/check_rules/rbs_receiver_surface.rb +66 -3
- data/lib/rigor/analysis/check_rules/rebinding_block_callees/dispatch.rb +112 -0
- data/lib/rigor/analysis/check_rules/rebinding_block_callees.rb +394 -0
- data/lib/rigor/analysis/check_rules/return_in_ensure_collector.rb +1 -2
- data/lib/rigor/analysis/check_rules/ruby_deprecations.rb +7 -0
- data/lib/rigor/analysis/check_rules/rule_ids.rb +1 -1
- data/lib/rigor/analysis/check_rules/rule_walk.rb +9 -7
- data/lib/rigor/analysis/check_rules/shadowed_rescue_collector.rb +3 -4
- data/lib/rigor/analysis/check_rules/special_global_setters.rb +3 -3
- data/lib/rigor/analysis/check_rules/unreachable_clause_collector.rb +53 -2
- data/lib/rigor/analysis/check_rules/void_value_use_collector.rb +1 -1
- data/lib/rigor/analysis/check_rules.rb +217 -52
- data/lib/rigor/analysis/crash_signature.rb +2 -2
- data/lib/rigor/analysis/dependency_recorder.rb +15 -4
- data/lib/rigor/analysis/dependency_source_inference/boundary_cross_reporter.rb +14 -3
- data/lib/rigor/analysis/dependency_source_inference/gem_resolver.rb +1 -1
- data/lib/rigor/analysis/dependency_source_inference/index.rb +6 -8
- data/lib/rigor/analysis/dependency_source_inference/walker.rb +4 -4
- data/lib/rigor/analysis/edit_replay.rb +154 -0
- data/lib/rigor/analysis/fact_store.rb +3 -3
- data/lib/rigor/analysis/incremental.rb +37 -0
- data/lib/rigor/analysis/incremental_run_slot/write_guard.rb +2 -2
- data/lib/rigor/analysis/incremental_run_slot.rb +2 -2
- data/lib/rigor/analysis/incremental_session.rb +202 -43
- data/lib/rigor/analysis/path_expansion.rb +41 -0
- data/lib/rigor/analysis/require_relative_closure.rb +100 -0
- data/lib/rigor/analysis/rule_catalog.rb +7 -3
- data/lib/rigor/analysis/run_disclosure_credit.rb +80 -0
- data/lib/rigor/analysis/run_disclosure_ledger.rb +155 -0
- data/lib/rigor/analysis/run_stats.rb +2 -2
- data/lib/rigor/analysis/runner/buffer_pool_dispatcher.rb +8 -4
- data/lib/rigor/analysis/runner/declaration_position.rb +1 -1
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +204 -96
- data/lib/rigor/analysis/runner/effect_envelope_pass.rb +1 -1
- data/lib/rigor/analysis/runner/pool_coordinator.rb +157 -320
- data/lib/rigor/analysis/runner/project_pre_passes.rb +48 -6
- data/lib/rigor/analysis/runner/run_level_facts.rb +304 -0
- data/lib/rigor/analysis/runner/run_snapshots.rb +44 -54
- data/lib/rigor/analysis/runner/scan_environment.rb +51 -0
- data/lib/rigor/analysis/runner/worker_payload.rb +36 -0
- data/lib/rigor/analysis/runner.rb +233 -120
- data/lib/rigor/analysis/self_call_resolution_recorder.rb +1 -1
- data/lib/rigor/analysis/template_unit_positions.rb +2 -3
- data/lib/rigor/analysis/template_units.rb +9 -1
- data/lib/rigor/analysis/worker_session.rb +38 -33
- data/lib/rigor/bleeding_edge.rb +3 -6
- data/lib/rigor/builtins/imported_refinements.rb +6 -8
- data/lib/rigor/builtins/predefined_constant_refinements.rb +1 -1
- data/lib/rigor/builtins/regex_refinement.rb +4 -6
- data/lib/rigor/cache/descriptor.rb +6 -5
- data/lib/rigor/cache/incremental_snapshot.rb +60 -18
- data/lib/rigor/cache/rbs_cache_producer.rb +2 -2
- data/lib/rigor/cache/rbs_class_ancestor_table.rb +1 -1
- data/lib/rigor/cache/rbs_class_type_param_names.rb +2 -2
- data/lib/rigor/cache/rbs_constant_table.rb +1 -1
- data/lib/rigor/cache/rbs_descriptor.rb +54 -3
- data/lib/rigor/cache/rbs_environment.rb +4 -1
- data/lib/rigor/cache/rbs_environment_marshal_patch.rb +2 -2
- data/lib/rigor/cache/rbs_known_class_names.rb +1 -1
- data/lib/rigor/cache/store.rb +11 -10
- data/lib/rigor/ci_detector.rb +1 -1
- data/lib/rigor/cli/annotate_command.rb +24 -19
- data/lib/rigor/cli/baseline_command.rb +145 -55
- data/lib/rigor/cli/catalogue.rb +256 -0
- data/lib/rigor/cli/check_command.rb +188 -93
- data/lib/rigor/cli/check_runner_factory.rb +2 -2
- data/lib/rigor/cli/command.rb +15 -1
- data/lib/rigor/cli/coverage_command.rb +21 -8
- data/lib/rigor/cli/coverage_mutation.rb +5 -7
- data/lib/rigor/cli/coverage_renderer.rb +2 -1
- data/lib/rigor/cli/coverage_scan.rb +3 -5
- data/lib/rigor/cli/diff_command.rb +27 -21
- data/lib/rigor/cli/docs_command.rb +1 -2
- data/lib/rigor/cli/doctor_command.rb +12 -12
- data/lib/rigor/cli/effects_command.rb +50 -40
- data/lib/rigor/cli/effects_diff_renderer.rb +18 -17
- data/lib/rigor/cli/effects_explain_renderer.rb +13 -12
- data/lib/rigor/cli/effects_renderer.rb +2 -1
- data/lib/rigor/cli/effects_snapshot_command.rb +18 -17
- data/lib/rigor/cli/explain_command.rb +18 -8
- data/lib/rigor/cli/fused_protection_renderer.rb +2 -1
- data/lib/rigor/cli/json_document.rb +41 -0
- data/lib/rigor/cli/lens_command.rb +17 -13
- data/lib/rigor/cli/lsp_command.rb +250 -23
- data/lib/rigor/cli/mcp_command.rb +14 -8
- data/lib/rigor/cli/mutation_fork_scan.rb +1 -1
- data/lib/rigor/cli/mutation_protection_renderer.rb +3 -2
- data/lib/rigor/cli/options.rb +60 -4
- data/lib/rigor/cli/plugin_command.rb +93 -46
- data/lib/rigor/cli/plugins_command.rb +22 -18
- data/lib/rigor/cli/plugins_renderer.rb +34 -8
- data/lib/rigor/cli/protection_fork_scan.rb +2 -2
- data/lib/rigor/cli/protection_renderer.rb +2 -1
- data/lib/rigor/cli/show_bleedingedge_command.rb +23 -16
- data/lib/rigor/cli/sig_gen_command.rb +130 -34
- data/lib/rigor/cli/skill_command.rb +32 -3
- data/lib/rigor/cli/skill_deep_probe.rb +1 -1
- data/lib/rigor/cli/skill_describe.rb +1 -1
- data/lib/rigor/cli/trace_command.rb +14 -9
- data/lib/rigor/cli/triage_command.rb +10 -11
- data/lib/rigor/cli/triage_renderer.rb +2 -1
- data/lib/rigor/cli/type_of_command.rb +18 -12
- data/lib/rigor/cli/type_of_project_scope.rb +24 -0
- data/lib/rigor/cli/type_of_renderer.rb +4 -1
- data/lib/rigor/cli/type_scan_command.rb +14 -9
- data/lib/rigor/cli/type_scan_renderer.rb +2 -1
- data/lib/rigor/cli/unused_command.rb +27 -17
- data/lib/rigor/cli/upgrade_command.rb +5 -0
- data/lib/rigor/cli.rb +209 -54
- data/lib/rigor/config_audit.rb +17 -6
- data/lib/rigor/configuration/severity_profile.rb +5 -5
- data/lib/rigor/configuration.rb +86 -34
- data/lib/rigor/effects/definition_context.rb +0 -2
- data/lib/rigor/effects/envelope.rb +1 -1
- data/lib/rigor/effects/framework_units.rb +1 -1
- data/lib/rigor/effects/mutation_classifier.rb +4 -7
- data/lib/rigor/effects/propagator.rb +1 -1
- data/lib/rigor/effects/registry.rb +2 -2
- data/lib/rigor/effects/snapshot.rb +1 -1
- data/lib/rigor/effects/taint_cause.rb +0 -2
- data/lib/rigor/effects/unit_scan.rb +9 -13
- data/lib/rigor/environment/bundle_sig_discovery.rb +5 -9
- data/lib/rigor/environment/class_registry.rb +3 -3
- data/lib/rigor/environment/core_root.rb +77 -0
- data/lib/rigor/environment/default_libraries.rb +1 -1
- data/lib/rigor/environment/deferred_signature_plan.rb +283 -0
- data/lib/rigor/environment/gated_signature_guard.rb +1 -1
- data/lib/rigor/environment/gated_signature_plan.rb +5 -2
- data/lib/rigor/environment/lockfile_resolver.rb +28 -12
- data/lib/rigor/environment/member_consistency/comparator.rb +18 -1
- data/lib/rigor/environment/member_consistency.rb +56 -7
- data/lib/rigor/environment/missing_gem_constant_index.rb +3 -2
- data/lib/rigor/environment/project_path_gems.rb +124 -0
- data/lib/rigor/environment/rbs_hierarchy.rb +6 -15
- data/lib/rigor/environment/rbs_loader.rb +592 -70
- data/lib/rigor/environment/reflection.rb +7 -7
- data/lib/rigor/environment/required_features.rb +136 -32
- data/lib/rigor/environment/ruby_library_roots.rb +122 -0
- data/lib/rigor/environment/vendored_signature_plan.rb +153 -0
- data/lib/rigor/environment.rb +44 -11
- data/lib/rigor/flow_contribution/merger.rb +4 -4
- data/lib/rigor/inference/acceptance.rb +93 -32
- data/lib/rigor/inference/block_parameter_binder.rb +2 -3
- data/lib/rigor/inference/block_run_count.rb +178 -0
- data/lib/rigor/inference/budget_trace.rb +8 -2
- data/lib/rigor/inference/builtins/exception_catalog.rb +2 -2
- data/lib/rigor/inference/builtins/numeric_catalog.rb +2 -5
- data/lib/rigor/inference/builtins/random_catalog.rb +2 -2
- data/lib/rigor/inference/callee_mutation_chain.rb +126 -0
- data/lib/rigor/inference/callee_write_census.rb +815 -0
- data/lib/rigor/inference/construction_escape.rb +217 -0
- data/lib/rigor/inference/declaration_walk/traversal.rb +1 -1
- data/lib/rigor/inference/deep_erasure.rb +170 -0
- data/lib/rigor/inference/def_handle.rb +1 -1
- data/lib/rigor/inference/def_node_resolver.rb +1 -1
- data/lib/rigor/inference/def_return_typer.rb +204 -12
- data/lib/rigor/inference/definer_resolution.rb +21 -5
- data/lib/rigor/inference/definers_index.rb +106 -0
- data/lib/rigor/inference/direct_ivar_writes.rb +300 -0
- data/lib/rigor/inference/element_read_widening.rb +49 -3
- data/lib/rigor/inference/error_info.rb +17 -3
- data/lib/rigor/inference/expression_typer.rb +173 -57
- data/lib/rigor/inference/external_ancestor_resolution.rb +3 -4
- data/lib/rigor/inference/global_write_census.rb +110 -1
- data/lib/rigor/inference/global_writer_reach.rb +260 -0
- data/lib/rigor/inference/hkt_body.rb +1 -2
- data/lib/rigor/inference/hkt_body_parser.rb +3 -5
- data/lib/rigor/inference/hkt_reducer.rb +2 -2
- data/lib/rigor/inference/hkt_registry.rb +3 -5
- data/lib/rigor/inference/indexed_narrowing.rb +4 -7
- data/lib/rigor/inference/intervening_ivar_reset.rb +26 -4
- data/lib/rigor/inference/ivar_writer_census.rb +246 -0
- data/lib/rigor/inference/key_presence_guard.rb +2 -1
- data/lib/rigor/inference/loop_value_record.rb +57 -0
- data/lib/rigor/inference/match_rebinding/frame.rb +65 -0
- data/lib/rigor/inference/match_rebinding/yielding_match.rb +45 -0
- data/lib/rigor/inference/match_rebinding.rb +11 -1
- data/lib/rigor/inference/memo_audit.rb +55 -0
- data/lib/rigor/inference/method_dispatcher/alias_strict_nominals.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/argument_distribution.rb +40 -0
- data/lib/rigor/inference/method_dispatcher/block_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/constant_folding.rb +113 -12
- data/lib/rigor/inference/method_dispatcher/contested_overloads.rb +89 -0
- data/lib/rigor/inference/method_dispatcher/iterator_dispatch.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/kernel_dispatch.rb +7 -3
- data/lib/rigor/inference/method_dispatcher/no_match_fallback.rb +54 -0
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +39 -27
- data/lib/rigor/inference/method_dispatcher/random_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +203 -17
- data/lib/rigor/inference/method_dispatcher/reduce_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/regexp_folding.rb +2 -2
- data/lib/rigor/inference/method_dispatcher/self_substitute.rb +2 -2
- data/lib/rigor/inference/method_dispatcher/set_folding.rb +59 -24
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +83 -20
- data/lib/rigor/inference/method_dispatcher/singleton_folding.rb +0 -1
- data/lib/rigor/inference/method_dispatcher/singleton_mixin_dispatch.rb +50 -17
- data/lib/rigor/inference/method_dispatcher/struct_folding.rb +5 -5
- data/lib/rigor/inference/method_dispatcher/struct_materialization.rb +4 -6
- data/lib/rigor/inference/method_dispatcher/uri_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher.rb +109 -29
- data/lib/rigor/inference/module_function_state/spellings.rb +64 -0
- data/lib/rigor/inference/module_function_state.rb +23 -1
- data/lib/rigor/inference/multi_target_binder.rb +1 -1
- data/lib/rigor/inference/mutation_rejoin.rb +240 -4
- data/lib/rigor/inference/mutation_widening.rb +162 -29
- data/lib/rigor/inference/narrowing.rb +113 -38
- data/lib/rigor/inference/object_mixins.rb +13 -1
- data/lib/rigor/inference/optimistic_origin.rb +1 -1
- data/lib/rigor/inference/out_buffer_mutation.rb +72 -0
- data/lib/rigor/inference/parameter_inference_collector.rb +5 -6
- data/lib/rigor/inference/pre_eval_constants.rb +1 -1
- data/lib/rigor/inference/project_method_ownership.rb +6 -3
- data/lib/rigor/inference/project_seed_tables.rb +2 -1
- data/lib/rigor/inference/project_yielder.rb +122 -0
- data/lib/rigor/inference/receiver_alias.rb +20 -0
- data/lib/rigor/inference/refined_dispatch/constructed_class.rb +3 -1
- data/lib/rigor/inference/refined_dispatch/own_method.rb +2 -1
- data/lib/rigor/inference/remover_holder_scan.rb +233 -0
- data/lib/rigor/inference/remover_narrowing.rb +224 -0
- data/lib/rigor/inference/rewrite_mutation.rb +53 -2
- data/lib/rigor/inference/scope_indexer/certainty.rb +9 -1
- data/lib/rigor/inference/scope_indexer/constant_ivar_value.rb +93 -0
- data/lib/rigor/inference/scope_indexer/declared_ivar_types.rb +64 -0
- data/lib/rigor/inference/scope_indexer/declared_param_writes.rb +205 -0
- data/lib/rigor/inference/scope_indexer/derived_param_value.rb +112 -0
- data/lib/rigor/inference/scope_indexer/empty_seed.rb +99 -0
- data/lib/rigor/inference/scope_indexer/ivar_contributions.rb +135 -0
- data/lib/rigor/inference/scope_indexer/unseen_ivar_writers.rb +133 -0
- data/lib/rigor/inference/scope_indexer.rb +614 -146
- data/lib/rigor/inference/self_call_ivar_writes.rb +101 -17
- data/lib/rigor/inference/set_mutation.rb +189 -0
- data/lib/rigor/inference/singleton_hook_decline.rb +1 -2
- data/lib/rigor/inference/statement_evaluator.rb +3036 -278
- data/lib/rigor/inference/struct_fold_safety.rb +4 -6
- data/lib/rigor/inference/synthetic_method_index.rb +23 -0
- data/lib/rigor/inference/synthetic_method_scanner/project_members.rb +130 -0
- data/lib/rigor/inference/synthetic_method_scanner.rb +73 -14
- data/lib/rigor/inference/toplevel_def_census.rb +59 -0
- data/lib/rigor/inference/unknown_store_widening.rb +103 -4
- data/lib/rigor/inference/unthreaded_rebinds.rb +2 -3
- data/lib/rigor/inference/void_tail_summary.rb +2 -1
- data/lib/rigor/language_server/buffer_table.rb +9 -3
- data/lib/rigor/language_server/completion_provider.rb +26 -20
- data/lib/rigor/language_server/config_warning_announcer.rb +28 -0
- data/lib/rigor/language_server/diagnostic_publisher.rb +28 -9
- data/lib/rigor/language_server/document_symbol_provider.rb +1 -1
- data/lib/rigor/language_server/folding_range_provider.rb +1 -2
- data/lib/rigor/language_server/hover_provider.rb +1 -7
- data/lib/rigor/language_server/hover_renderer.rb +6 -8
- data/lib/rigor/language_server/project_context.rb +98 -4
- data/lib/rigor/language_server/publish_batcher.rb +3 -4
- data/lib/rigor/language_server/selection_range_provider.rb +2 -4
- data/lib/rigor/language_server/server.rb +12 -6
- data/lib/rigor/language_server/signature_help_provider.rb +4 -4
- data/lib/rigor/lens/plugins.rb +1 -1
- data/lib/rigor/mcp/server.rb +82 -3
- data/lib/rigor/mcp.rb +1 -1
- data/lib/rigor/plugin/access_denied_error.rb +1 -2
- data/lib/rigor/plugin/base.rb +26 -11
- data/lib/rigor/plugin/bundled_catalog.rb +1 -12
- data/lib/rigor/plugin/io_boundary.rb +1 -1
- data/lib/rigor/plugin/loader.rb +25 -8
- data/lib/rigor/plugin/macro/heredoc_template.rb +7 -8
- data/lib/rigor/plugin/macro/trait_registry.rb +6 -9
- data/lib/rigor/plugin/manifest.rb +38 -16
- data/lib/rigor/plugin/registry.rb +41 -3
- data/lib/rigor/plugin/services.rb +2 -3
- data/lib/rigor/plugin/source_rbs_synthesis_reporter.rb +11 -0
- data/lib/rigor/plugin/trust_policy.rb +2 -2
- data/lib/rigor/plugin/type_node_resolver.rb +2 -4
- data/lib/rigor/plugin.rb +6 -8
- data/lib/rigor/plugin_gap_advisory.rb +5 -1
- data/lib/rigor/project_environment.rb +16 -2
- data/lib/rigor/protection/analysis_guard.rb +1 -1
- data/lib/rigor/protection/discovery_seed.rb +96 -2
- data/lib/rigor/protection/mutator.rb +1 -1
- data/lib/rigor/rbs_extended/envelope_scanner.rb +4 -6
- data/lib/rigor/rbs_extended/hkt_directives.rb +6 -10
- data/lib/rigor/rbs_extended/reporter.rb +27 -3
- data/lib/rigor/rbs_extended.rb +2 -3
- data/lib/rigor/reflection/constant_ancestors.rb +5 -3
- data/lib/rigor/rooted_glob.rb +25 -2
- data/lib/rigor/run_scoped_slots.rb +38 -0
- data/lib/rigor/runtime/jit.rb +1 -1
- data/lib/rigor/scope/discovery_index.rb +19 -6
- data/lib/rigor/scope/resolution_chain.rb +3 -1
- data/lib/rigor/scope.rb +379 -36
- data/lib/rigor/sig_gen/classification.rb +4 -0
- data/lib/rigor/sig_gen/effect_annotation.rb +3 -3
- data/lib/rigor/sig_gen/generator.rb +668 -84
- data/lib/rigor/sig_gen/generic_header_scan.rb +189 -0
- data/lib/rigor/sig_gen/inline_declarations.rb +2 -2
- data/lib/rigor/sig_gen/layout_index.rb +3 -3
- data/lib/rigor/sig_gen/method_candidate.rb +23 -4
- data/lib/rigor/sig_gen/observation_collector.rb +7 -6
- data/lib/rigor/sig_gen/observed_call.rb +1 -1
- data/lib/rigor/sig_gen/path_mapper.rb +6 -0
- data/lib/rigor/sig_gen/rbs_validity.rb +1 -1
- data/lib/rigor/sig_gen/renderer.rb +21 -12
- data/lib/rigor/sig_gen/skip_reason_catalog.rb +15 -2
- data/lib/rigor/sig_gen/type_elaborator.rb +21 -5
- data/lib/rigor/sig_gen/type_name_qualification.rb +69 -0
- data/lib/rigor/sig_gen/write_reporter.rb +63 -14
- data/lib/rigor/sig_gen/write_result.rb +23 -12
- data/lib/rigor/sig_gen/writer.rb +217 -37
- data/lib/rigor/type/acceptance_router.rb +2 -2
- data/lib/rigor/type/accepts_result.rb +1 -1
- data/lib/rigor/type/app.rb +4 -6
- data/lib/rigor/type/combinator.rb +13 -16
- data/lib/rigor/type/constant.rb +48 -7
- data/lib/rigor/type/hash_shape.rb +26 -40
- data/lib/rigor/type/struct_instance.rb +3 -2
- data/lib/rigor/type/union.rb +1 -1
- data/lib/rigor/type_node/identifier.rb +1 -2
- data/lib/rigor/type_node/resolver_chain.rb +1 -1
- data/lib/rigor/type_node/string_literal.rb +1 -2
- data/lib/rigor/type_node/symbol_literal.rb +1 -2
- data/lib/rigor/type_node/union.rb +3 -6
- data/lib/rigor/value_semantics.rb +1 -10
- data/lib/rigor/version.rb +1 -1
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_discoverer.rb +2 -2
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_index.rb +2 -3
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +1 -1
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_discoverer.rb +89 -70
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_index.rb +4 -2
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb +25 -4
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb +1 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_index.rb +1 -5
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_scan.rb +0 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/erb_compiler.rb +2 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/view_assigns.rb +1 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +79 -19
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/effects.rb +1 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +6 -3
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/association_roots.rb +3 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/effects.rb +2 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +21 -31
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_index.rb +10 -16
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_parser.rb +2 -3
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_table.rb +0 -1
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +5 -4
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_discoverer.rb +3 -4
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_index.rb +1 -1
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +7 -12
- data/plugins/rigor-activestorage/lib/rigor-activestorage.rb +1 -1
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext/effects.rb +1 -1
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext/symbolize_keys.rb +102 -0
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb +19 -6
- data/plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs +26 -13
- data/plugins/rigor-alba/lib/rigor/plugin/alba/resource_index.rb +3 -3
- data/plugins/rigor-devise/lib/rigor/plugin/devise.rb +5 -3
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema/schema_scanner.rb +1 -3
- data/plugins/rigor-dry-struct/lib/rigor/plugin/dry_struct.rb +6 -6
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types/alias_scanner.rb +5 -6
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types.rb +7 -6
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation/params_shape.rb +2 -3
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation.rb +5 -8
- data/plugins/rigor-ethon/lib/rigor/plugin/ethon.rb +0 -1
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_discoverer.rb +1 -1
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot.rb +10 -18
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi/analyzer.rb +0 -1
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi/discoverer.rb +0 -2
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi.rb +4 -5
- data/plugins/rigor-grape/lib/rigor/plugin/grape.rb +0 -2
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql/type_scanner.rb +6 -7
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami/action_checker.rb +2 -4
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami.rb +2 -5
- data/plugins/rigor-mangrove/lib/rigor/plugin/mangrove.rb +2 -2
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest/assertion_analyzer.rb +6 -6
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_discoverer.rb +2 -1
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/analyzer.rb +3 -8
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_index.rb +2 -3
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_loader.rb +5 -8
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/analyzer.rb +1 -3
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/devise_routes.rb +2 -3
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_discoverer.rb +1 -1
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/routes_parser.rb +4 -11
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +1 -1
- data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb +2 -1
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +102 -11
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec.rb +2 -2
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails.rb +3 -4
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers/analyzer.rb +6 -8
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb +5 -2
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/absurd_recognizer.rb +4 -5
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/assertion_recognizer.rb +6 -7
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog.rb +1 -1
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sig_parser.rb +2 -2
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +17 -21
- data/plugins/rigor-statesman/lib/rigor/plugin/statesman.rb +2 -3
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer/serializer_discoverer.rb +3 -2
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer/serializer_index.rb +4 -4
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer.rb +1 -1
- data/sig/rigor/analysis/baseline.rbs +0 -2
- data/sig/rigor/analysis/fact_store.rbs +1 -0
- data/sig/rigor/analysis/reachability/scan_cache.rbs +1 -1
- data/sig/rigor/cli/diff_command.rbs +1 -1
- data/sig/rigor/cli/explain_command.rbs +1 -1
- data/sig/rigor/effects/file_collection.rbs +5 -6
- data/sig/rigor/effects/registry.rbs +8 -6
- data/sig/rigor/effects/summary.rbs +6 -5
- data/sig/rigor/environment.rbs +5 -3
- data/sig/rigor/inference/optimistic_origin.rbs +11 -0
- data/sig/rigor/inference.rbs +10 -1
- data/sig/rigor/plugin/additional_initializer.rbs +0 -5
- data/sig/rigor/plugin/base.rbs +1 -0
- data/sig/rigor/plugin/effect_ancestry.rbs +6 -4
- data/sig/rigor/plugin/effect_attribution.rbs +25 -10
- data/sig/rigor/plugin/effect_edge.rbs +12 -5
- data/sig/rigor/plugin/effect_entry_points.rbs +8 -3
- data/sig/rigor/plugin/io_boundary.rbs +6 -5
- data/sig/rigor/plugin/manifest.rbs +16 -18
- data/sig/rigor/plugin/protocol_contract.rbs +6 -9
- data/sig/rigor/plugin/registry.rbs +1 -1
- data/sig/rigor/scope.rbs +51 -50
- data/sig/rigor/type.rbs +0 -6
- data/skills/rigor-plugin-author/SKILL.md +4 -4
- data/skills/rigor-plugin-author/references/02-walker-and-types.md +5 -5
- data/skills/rigor-plugin-review/SKILL.md +3 -3
- data/skills/rigor-project-init/references/03-baseline-and-bugs.md +12 -1
- metadata +55 -3
|
@@ -29,36 +29,25 @@ module Rigor
|
|
|
29
29
|
# @param pool_mode — reader returning the pool-mode flag.
|
|
30
30
|
# @param cached_plugin_prepare_diagnostics — reader returning the prepare-diagnostic snapshot.
|
|
31
31
|
# @param pre_eval_diagnostics_from_scanner — reader returning the pre-eval scanner diagnostics.
|
|
32
|
-
# @param
|
|
33
|
-
#
|
|
34
|
-
# because they do not parse
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
#
|
|
44
|
-
# `
|
|
45
|
-
#
|
|
46
|
-
# element — `[token, location, refinement_hint]`, `nil` unless `error_class` is
|
|
47
|
-
# `RBS::NoTypeFoundError`). Empty for a healthy sig set.
|
|
48
|
-
# @param hkt_scan_failure_snapshot — issue #784 — reader returning the `[error_class_name,
|
|
49
|
-
# first_message_line, raw_frame_or_nil, stage]` tuple whichever stage of the HKT-registry build
|
|
50
|
-
# raised, or nil when both built (or were never demanded). `stage` is `:scan` (the RBS `type`-alias
|
|
51
|
-
# scan) or `:overlay` (the plugin-manifest aggregation, #791), and picks the row's wording.
|
|
52
|
-
# @param conformance_results_snapshot — reader.
|
|
32
|
+
# @param snapshots — the run's {RunSnapshots} store (ADR-116 WD3), read at row-build time. Its slots'
|
|
33
|
+
# shapes, as the rows below read them:
|
|
34
|
+
# - `quarantined_signatures` — the `signature_paths:` files skipped because they do not parse
|
|
35
|
+
# (`[path, first_error_line]` pairs);
|
|
36
|
+
# - `signature_standdowns` (#610) — `[path, class_name, existing_arity, incoming_arity,
|
|
37
|
+
# existing_file]` tuples, then (#2422) `[path, declaration, nil, nil, cause_file, :member]` ones;
|
|
38
|
+
# - `vendored_standdowns` (#1713) — `Environment::RbsLoader#vendored_standdowns`;
|
|
39
|
+
# - `env_build_failure` — `[error_class, first_error_line, conflicting_buffer_names]`, or nil;
|
|
40
|
+
# - `definition_build_failures` (#696) — `[class_name, error_class, member,
|
|
41
|
+
# conflicting_buffer_names, unresolved_type_name_detail, mixin_count]` tuples (#997 added the fifth
|
|
42
|
+
# element — `[token, location, refinement_hint]`, `nil` unless `error_class` is
|
|
43
|
+
# `RBS::NoTypeFoundError`; #2440 the sixth, {Environment::RbsLoader#variable_mixin_count});
|
|
44
|
+
# - `hkt_scan_failure` (#784) — `[error_class_name, first_message_line, raw_frame_or_nil, stage]`,
|
|
45
|
+
# or nil; `stage` is `:scan` or `:overlay` (#791) and picks the row's wording.
|
|
53
46
|
def initialize(configuration:, rbs_extended_reporter:, boundary_cross_reporter:, # rubocop:disable Metrics/ParameterLists
|
|
54
47
|
source_rbs_synthesis_reporter:, plugin_registry:, dependency_source_index:,
|
|
55
48
|
pool_mode:, cached_plugin_prepare_diagnostics:,
|
|
56
|
-
pre_eval_diagnostics_from_scanner:,
|
|
57
|
-
|
|
58
|
-
definition_build_failures_snapshot:, hkt_scan_failure_snapshot:,
|
|
59
|
-
conformance_results_snapshot:, signature_standdowns_snapshot: -> { [] },
|
|
60
|
-
vendored_standdowns_snapshot: -> { [] }, pooled_run_disclosures: -> { [] },
|
|
61
|
-
pooled_trust_refusals: -> { [] })
|
|
49
|
+
pre_eval_diagnostics_from_scanner:, snapshots:, pooled_run_disclosures: -> { [] },
|
|
50
|
+
served_run_disclosures: -> { [] }, pooled_trust_refusals: -> { [] })
|
|
62
51
|
@configuration = configuration
|
|
63
52
|
@rbs_extended_reporter = rbs_extended_reporter
|
|
64
53
|
@boundary_cross_reporter = boundary_cross_reporter
|
|
@@ -68,22 +57,25 @@ module Rigor
|
|
|
68
57
|
@pool_mode_reader = pool_mode
|
|
69
58
|
@cached_plugin_prepare_diagnostics_reader = cached_plugin_prepare_diagnostics
|
|
70
59
|
@pre_eval_diagnostics_from_scanner_reader = pre_eval_diagnostics_from_scanner
|
|
71
|
-
@
|
|
72
|
-
@quarantined_signatures_snapshot_reader = quarantined_signatures_snapshot
|
|
73
|
-
@signature_standdowns_snapshot_reader = signature_standdowns_snapshot
|
|
74
|
-
@vendored_standdowns_snapshot_reader = vendored_standdowns_snapshot
|
|
75
|
-
@env_build_failure_snapshot_reader = env_build_failure_snapshot
|
|
76
|
-
@definition_build_failures_snapshot_reader = definition_build_failures_snapshot
|
|
77
|
-
@hkt_scan_failure_snapshot_reader = hkt_scan_failure_snapshot
|
|
78
|
-
@conformance_results_snapshot_reader = conformance_results_snapshot
|
|
60
|
+
@snapshots = snapshots
|
|
79
61
|
# Issue #1051 — reader for the pool coordinator's de-duplicated run-scoped disclosure table.
|
|
80
62
|
# Empty on a sequential run, where `plugin_registry`'s own instances are the ones that registered.
|
|
81
63
|
@pooled_run_disclosures_reader = pooled_run_disclosures
|
|
64
|
+
# Issue #2020 — reader for the rows an incremental recheck replays for the files it served unanalysed.
|
|
65
|
+
@served_run_disclosures_reader = served_run_disclosures
|
|
82
66
|
# Issue #1900 — reader for the pool coordinator's summed trust-refusal table. Empty on a
|
|
83
67
|
# sequential run, where `plugin_registry`'s own boundaries made every read.
|
|
84
68
|
@pooled_trust_refusals_reader = pooled_trust_refusals
|
|
85
69
|
end
|
|
86
70
|
|
|
71
|
+
# ADR-116 WD3 — every post-analysis run-level row, in the contract order {RunLevelFacts.row_builders}
|
|
72
|
+
# declares: the `rbs.coverage.*` build-failure ladder widest consequence first, its `:info` notices,
|
|
73
|
+
# the conformance rows, the reporter streams, then the plugin run disclosures and the trust-refusal
|
|
74
|
+
# envelope, read last so every per-file plugin call has recorded its refusals.
|
|
75
|
+
def run_level_diagnostics
|
|
76
|
+
RunLevelFacts.row_builders.flat_map { |builder| public_send(builder) }
|
|
77
|
+
end
|
|
78
|
+
|
|
87
79
|
# Pre-file diagnostic streams that fire once per run rather than per analyzed file: plugin load /
|
|
88
80
|
# prepare envelopes, the ADR-10 dependency-source resolution surface, and the `expand_paths` errors
|
|
89
81
|
# for `paths:` entries that don't exist or aren't `.rb`. Aggregated here so `#run` stays under the
|
|
@@ -92,9 +84,9 @@ module Rigor
|
|
|
92
84
|
# ADR-15 Phase 4b — `plugin_prepare_diagnostics` runs on the coordinator's plugin registry under
|
|
93
85
|
# sequential mode; under pool mode each worker re-runs `prepare` against its own plugin instances,
|
|
94
86
|
# so the pool path drains the first worker's prepare-diagnostic snapshot into the aggregated
|
|
95
|
-
# diagnostic stream instead (see {#analyze_files_in_pool}). Skipping the coordinator
|
|
96
|
-
# mode avoids double-running `#prepare` against the coordinator-side plugin instances
|
|
97
|
-
# pool path never consults for per-file analysis).
|
|
87
|
+
# diagnostic stream instead (see {PoolCoordinator#analyze_files_in_pool}). Skipping the coordinator
|
|
88
|
+
# prepare in pool mode avoids double-running `#prepare` against the coordinator-side plugin instances
|
|
89
|
+
# (which the pool path never consults for per-file analysis).
|
|
98
90
|
def pre_file_diagnostics(expansion)
|
|
99
91
|
# ADR-18 slice 3 — prepare diagnostics are captured earlier in #run (before the synthetic-method
|
|
100
92
|
# scanner) so cross-plugin facts are available to the scanner. We re-surface the captured
|
|
@@ -269,6 +261,9 @@ module Rigor
|
|
|
269
261
|
project_root: Dir.pwd,
|
|
270
262
|
auto_detect: @configuration.bundler_auto_detect
|
|
271
263
|
)
|
|
264
|
+
# Issue #2441 — the project's own path gems are not dependencies missing RBS; the environment skips
|
|
265
|
+
# their collection copy, so the same set leaves the report here.
|
|
266
|
+
locked = locked.except(*project_own_gem_names(locked))
|
|
272
267
|
return [] if locked.empty?
|
|
273
268
|
|
|
274
269
|
bundle_sig_paths = Environment::BundleSigDiscovery.discover(
|
|
@@ -294,6 +289,16 @@ module Rigor
|
|
|
294
289
|
[build_rbs_coverage_missing_diagnostic(missing)]
|
|
295
290
|
end
|
|
296
291
|
|
|
292
|
+
# Issue #2441 — the same project-own set `Environment.for_project` skips the collection copy of.
|
|
293
|
+
def project_own_gem_names(locked)
|
|
294
|
+
Environment::ProjectPathGems.names(
|
|
295
|
+
locked,
|
|
296
|
+
paths: @configuration.paths, root: Dir.pwd,
|
|
297
|
+
exclude_patterns: @configuration.exclude_patterns, exclude_base: @configuration.exclude_base
|
|
298
|
+
)
|
|
299
|
+
end
|
|
300
|
+
private :project_own_gem_names
|
|
301
|
+
|
|
297
302
|
# ADR-93 WD3 — the standalone residual. A bare `gem install rigortype` has no `rbs-inline` library,
|
|
298
303
|
# so the spec's "annotations are official type sources whenever present" cannot be satisfied: the
|
|
299
304
|
# annotated code reads `Dynamic[top]`. When the library is absent AND the project actually carries
|
|
@@ -377,7 +382,7 @@ module Rigor
|
|
|
377
382
|
# the `reject-unparseable-signatures` feature promotes this rule to `:error` for anyone who opts in
|
|
378
383
|
# (and by default at the next major).
|
|
379
384
|
def rbs_quarantined_signature_diagnostics
|
|
380
|
-
quarantined =
|
|
385
|
+
quarantined = @snapshots[:quarantined_signatures]
|
|
381
386
|
return [] if quarantined.empty?
|
|
382
387
|
|
|
383
388
|
[build_rbs_quarantined_signature_diagnostic(quarantined)]
|
|
@@ -398,7 +403,7 @@ module Rigor
|
|
|
398
403
|
# `reject-unparseable-signatures` bleeding-edge feature promotes it to `:error` for anyone who opts in
|
|
399
404
|
# (and by default at the next major).
|
|
400
405
|
def rbs_environment_build_failed_diagnostics
|
|
401
|
-
failure =
|
|
406
|
+
failure = @snapshots[:env_build_failure]
|
|
402
407
|
return [] if failure.nil?
|
|
403
408
|
|
|
404
409
|
[build_rbs_environment_build_failed_diagnostic(failure)]
|
|
@@ -424,7 +429,7 @@ module Rigor
|
|
|
424
429
|
# a Rigor release turn a green build red with no user change (ADR-5 / AGENTS.md § FP discipline).
|
|
425
430
|
# The `reject-unparseable-signatures` bleeding-edge feature promotes it to `:error`.
|
|
426
431
|
def rbs_definition_build_failed_diagnostics
|
|
427
|
-
failures =
|
|
432
|
+
failures = @snapshots[:definition_build_failures]
|
|
428
433
|
return [] if failures.nil? || failures.empty?
|
|
429
434
|
|
|
430
435
|
[build_rbs_definition_build_failed_diagnostic(failures)]
|
|
@@ -443,14 +448,14 @@ module Rigor
|
|
|
443
448
|
# surface, no signature file is skipped, the environment builds. That is why this sits LAST on the
|
|
444
449
|
# ladder, after its two `rbs.coverage.*` siblings above.
|
|
445
450
|
def rbs_hkt_scan_failed_diagnostics
|
|
446
|
-
failure =
|
|
451
|
+
failure = @snapshots[:hkt_scan_failure]
|
|
447
452
|
return [] if failure.nil?
|
|
448
453
|
|
|
449
454
|
[build_rbs_hkt_scan_failed_diagnostic(failure)]
|
|
450
455
|
end
|
|
451
456
|
|
|
452
457
|
def rbs_synthesized_namespace_diagnostics
|
|
453
|
-
synthesized =
|
|
458
|
+
synthesized = @snapshots[:synthesized_namespaces]
|
|
454
459
|
return [] if synthesized.nil? || synthesized.empty?
|
|
455
460
|
|
|
456
461
|
[build_rbs_synthesized_namespace_diagnostic(synthesized)]
|
|
@@ -463,10 +468,12 @@ module Rigor
|
|
|
463
468
|
# typing they are not getting and why, and — unlike the quarantine row this file used to be
|
|
464
469
|
# misreported as — is not sent to remove a declaration the plugin owns.
|
|
465
470
|
def rbs_plugin_signature_stood_down_diagnostics
|
|
466
|
-
standdowns =
|
|
471
|
+
standdowns = @snapshots[:signature_standdowns]
|
|
467
472
|
return [] if standdowns.nil? || standdowns.empty?
|
|
468
473
|
|
|
469
|
-
standdowns.
|
|
474
|
+
members, files = standdowns.partition { |entry| entry[5] == :member }
|
|
475
|
+
files.map { |entry| build_rbs_plugin_signature_stood_down_diagnostic(entry) } +
|
|
476
|
+
members.group_by(&:first).map { |path, rows| build_rbs_plugin_member_stood_down_diagnostic(path, rows) }
|
|
470
477
|
end
|
|
471
478
|
|
|
472
479
|
# Issue #1713 — the other outcome that avoided a definition-build failure: a required-feature-gated
|
|
@@ -474,7 +481,7 @@ module Rigor
|
|
|
474
481
|
# declares — a member, a whole type, or, when nothing narrower built, the directory. One `:info` per
|
|
475
482
|
# directory, naming the declarations that stood down and the files that displaced them.
|
|
476
483
|
def rbs_vendored_signature_stood_down_diagnostics
|
|
477
|
-
standdowns =
|
|
484
|
+
standdowns = @snapshots[:vendored_standdowns]
|
|
478
485
|
return [] if standdowns.nil? || standdowns.empty?
|
|
479
486
|
|
|
480
487
|
standdowns.map { |entry| build_rbs_vendored_signature_stood_down_diagnostic(entry) }
|
|
@@ -496,7 +503,7 @@ module Rigor
|
|
|
496
503
|
# conformance; every analysis path, pooled or degraded, takes the snapshot `synthesized_namespaces`
|
|
497
504
|
# comes from.
|
|
498
505
|
def conforms_to_diagnostics
|
|
499
|
-
results =
|
|
506
|
+
results = @snapshots[:conformance_results]
|
|
500
507
|
return [] if results.nil? || results.empty?
|
|
501
508
|
|
|
502
509
|
results.map { |record| build_conformance_diagnostic(record) }
|
|
@@ -628,7 +635,7 @@ module Rigor
|
|
|
628
635
|
failures = failures.sort_by { |failure| failure.first.to_s }
|
|
629
636
|
sample_size = 5
|
|
630
637
|
files = failures.flat_map { |failure| Array(failure[3]) }
|
|
631
|
-
.map { |name|
|
|
638
|
+
.map { |name| signature_source_label(name.to_s) }.uniq.sort
|
|
632
639
|
Diagnostic.new(
|
|
633
640
|
path: ".rigor.yml",
|
|
634
641
|
line: 1,
|
|
@@ -639,32 +646,120 @@ module Rigor
|
|
|
639
646
|
"Rigor still treats each class as KNOWN, so calls into it — real methods and typos " \
|
|
640
647
|
"alike — silently read `Dynamic[top]` instead of resolving, and this run is quieter " \
|
|
641
648
|
"than it should be rather than cleaner. #{definition_build_advice(failures.first)}",
|
|
642
|
-
severity: :warning,
|
|
649
|
+
severity: selected_core_failure?(failures) ? :error : :warning,
|
|
643
650
|
rule: "rbs.coverage.definition-build-failed",
|
|
644
651
|
source_family: :builtin
|
|
645
652
|
)
|
|
646
653
|
end
|
|
647
654
|
|
|
655
|
+
# Issue #2517 — a class that does not build from the selected `core_root:` alone is that explicit choice
|
|
656
|
+
# failing, not a Rigor release disagreeing with the user's `sig/`, so it is an error. A failure that also
|
|
657
|
+
# names a file outside the core (a project `sig/` collision) keeps the warning it has without one.
|
|
658
|
+
def selected_core_failure?(failures)
|
|
659
|
+
core_root = @configuration.core_root
|
|
660
|
+
return false if core_root.nil?
|
|
661
|
+
|
|
662
|
+
prefix = File.join(core_root, "")
|
|
663
|
+
failures.any? do |failure|
|
|
664
|
+
buffers = Array(failure[3]).map(&:to_s)
|
|
665
|
+
!buffers.empty? && buffers.all? { |name| name.start_with?(prefix) }
|
|
666
|
+
end
|
|
667
|
+
end
|
|
668
|
+
|
|
648
669
|
# The closing advice follows the FIRST failure's error class: `GenericParameterMismatchError` is two
|
|
649
670
|
# declarations of one CLASS at different generic arity (#610); `NoTypeFoundError` (issue #997) is
|
|
650
671
|
# ONE declaration naming a type that does not exist, which "remove the duplicate declaration" sends
|
|
651
672
|
# its reader after a duplicate that is not there — the fifth tuple element
|
|
652
|
-
# ({RbsLoader#unresolved_type_name_detail}) is non-nil for exactly that case.
|
|
653
|
-
#
|
|
654
|
-
#
|
|
673
|
+
# ({RbsLoader#unresolved_type_name_detail}) is non-nil for exactly that case. Issue #2440 — a
|
|
674
|
+
# duplicated instance variable, a superclass mismatch, a missing superclass and a type applied to
|
|
675
|
+
# the wrong arguments each get their own sentence, and when a `virtual:` (inline RBS) buffer is
|
|
676
|
+
# among the colliding sources the advice never tells the reader to remove it as if it were a file.
|
|
677
|
+
# Every other error class (the two duplicated-definition errors, `RecursiveAncestorError`, …) keeps
|
|
678
|
+
# the duplicate-declaration wording, which is accurate for them.
|
|
655
679
|
def definition_build_advice(failure)
|
|
656
|
-
_, error_class,
|
|
657
|
-
|
|
680
|
+
_, error_class, member, buffers, unresolved = failure
|
|
681
|
+
inline = Array(buffers).any? { |name| name.to_s.start_with?("virtual:") }
|
|
682
|
+
case error_class.to_s.split("::").last
|
|
683
|
+
when "GenericParameterMismatchError"
|
|
658
684
|
"Two signature sources declare the class with a different number of type parameters; make " \
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
685
|
+
"the declarations agree (`rbs validate`) to restore type coverage."
|
|
686
|
+
when "InstanceVariableDuplicationError" then variable_duplication_advice("instance variable", failure)
|
|
687
|
+
when "ClassInstanceVariableDuplicationError"
|
|
688
|
+
variable_duplication_advice("class instance variable", failure)
|
|
689
|
+
when "SuperclassMismatchError" then superclass_mismatch_advice(inline)
|
|
690
|
+
when "NoSuperclassFoundError" then no_superclass_advice(member)
|
|
691
|
+
when "InvalidTypeApplicationError" then invalid_type_application_advice(member)
|
|
662
692
|
else
|
|
693
|
+
return unresolved_type_name_advice(unresolved) if unresolved
|
|
694
|
+
|
|
663
695
|
"Two signature sources declare the same member; remove the duplicate declaration " \
|
|
664
696
|
"(`rbs validate`) to restore type coverage."
|
|
665
697
|
end
|
|
666
698
|
end
|
|
667
699
|
|
|
700
|
+
# The sixth tuple slot ({RbsLoader#variable_mixin_count}) is set only when the failing class mixes in
|
|
701
|
+
# the variable's owner at least twice and the owner declares it once: rbs counts the variable once per
|
|
702
|
+
# mixin. Otherwise — a variable duplicated in the owner itself, inherited or not — the wording follows
|
|
703
|
+
# which sources collide: inline only, inline and a file, two files, or one file declaring it twice.
|
|
704
|
+
def variable_duplication_advice(noun, failure)
|
|
705
|
+
class_name, _, member, buffers, _, mixins = failure
|
|
706
|
+
if mixins.is_a?(Integer) && mixins >= 2
|
|
707
|
+
return mixin_variable_duplication_advice(noun, class_name.to_s.delete_prefix("::"),
|
|
708
|
+
member.to_s.delete_prefix("::"))
|
|
709
|
+
end
|
|
710
|
+
|
|
711
|
+
names = Array(buffers).map(&:to_s)
|
|
712
|
+
inline = names.count { |name| name.start_with?("virtual:") }
|
|
713
|
+
if inline >= 2 && inline == names.size
|
|
714
|
+
"Two inline `# @rbs` annotations declare the same #{noun} in one class, and RBS rejects the " \
|
|
715
|
+
"pair even when the types agree; keep one of them to restore type coverage."
|
|
716
|
+
elsif inline.positive?
|
|
717
|
+
"The same #{noun} is declared twice in one class, at least once by an inline `# @rbs` " \
|
|
718
|
+
"annotation, and RBS rejects the pair even when the types agree. Keep one declaration: " \
|
|
719
|
+
"regenerate the committed `.rbs` (`rbs-inline --output`) or remove its copy of the " \
|
|
720
|
+
"variable, or drop the annotation from the `.rb` file, to restore type coverage."
|
|
721
|
+
elsif names.size >= 2
|
|
722
|
+
"Two signature files declare the same #{noun} in one class, and RBS rejects the pair even " \
|
|
723
|
+
"when the types agree; keep one declaration (`rbs validate`) to restore type coverage."
|
|
724
|
+
else
|
|
725
|
+
"The same #{noun} is declared twice in one class, and RBS rejects the pair even when the " \
|
|
726
|
+
"types agree; keep one declaration (`rbs validate`) to restore type coverage."
|
|
727
|
+
end
|
|
728
|
+
end
|
|
729
|
+
|
|
730
|
+
def mixin_variable_duplication_advice(noun, klass, owner)
|
|
731
|
+
"`#{klass}` mixes in `#{owner}` (`include`, `extend` or `prepend`) more than once, in one " \
|
|
732
|
+
"declaration or across several, and RBS counts each #{noun} `#{owner}` declares once per mixin. " \
|
|
733
|
+
"Keep a single mixin of `#{owner}` in `#{klass}` (a committed `rbs-inline --output` file and the " \
|
|
734
|
+
"`.rb` file it came from count as two declarations) to restore type coverage."
|
|
735
|
+
end
|
|
736
|
+
|
|
737
|
+
def superclass_mismatch_advice(inline)
|
|
738
|
+
advice = "Two declarations of the class name different superclasses; make them name the same " \
|
|
739
|
+
"one, or leave the superclass off every declaration but one (a reopening needs none), " \
|
|
740
|
+
"to restore type coverage."
|
|
741
|
+
return advice unless inline
|
|
742
|
+
|
|
743
|
+
"#{advice} Where one side is an inline annotation, fix the annotation and regenerate the " \
|
|
744
|
+
"committed `.rbs` (`rbs-inline --output`), or remove the committed copy."
|
|
745
|
+
end
|
|
746
|
+
|
|
747
|
+
def no_superclass_advice(member)
|
|
748
|
+
name = member.to_s.delete_prefix("::")
|
|
749
|
+
subject = name.empty? ? "A superclass" : "`#{name}`"
|
|
750
|
+
"#{subject} is named as a superclass, but no loaded signature declares it; declare it in your " \
|
|
751
|
+
"`sig/` (or load the library that does through `libraries:`), or re-run `rigor sig-gen` if " \
|
|
752
|
+
"the signature was generated, to restore type coverage."
|
|
753
|
+
end
|
|
754
|
+
|
|
755
|
+
def invalid_type_application_advice(member)
|
|
756
|
+
name = member.to_s.delete_prefix("::")
|
|
757
|
+
subject = name.empty? ? "a type" : "`#{name}`"
|
|
758
|
+
"A signature applies #{subject} with the wrong number of type arguments, or applies them to the " \
|
|
759
|
+
"wrong class; match the arguments to the type parameters the class declares (`rbs validate`) " \
|
|
760
|
+
"to restore type coverage."
|
|
761
|
+
end
|
|
762
|
+
|
|
668
763
|
# Issue #997 — `unresolved` is {RbsLoader#unresolved_type_name_detail}'s `[token, location,
|
|
669
764
|
# refinement_hint]`. `refinement_hint` turns the message into a fix: the token is not a typo to
|
|
670
765
|
# chase down but the start of a Rigor refinement name that is not valid in an RBS type position, and
|
|
@@ -775,6 +870,15 @@ module Rigor
|
|
|
775
870
|
end
|
|
776
871
|
|
|
777
872
|
# The absolute path is what the loader records; the user thinks in project-relative terms.
|
|
873
|
+
# Issue #2440 — a `virtual:<plugin>:<path>` buffer is named by the `.rb` file it was synthesized
|
|
874
|
+
# from, which is the file the user can open; the plugin id says how it became RBS.
|
|
875
|
+
def signature_source_label(name)
|
|
876
|
+
prefix, plugin_id, path = name.split(":", 3)
|
|
877
|
+
return relative_signature_path(name) unless prefix == "virtual" && plugin_id && path && !path.empty?
|
|
878
|
+
|
|
879
|
+
"#{relative_signature_path(path)} (inline RBS via #{plugin_id})"
|
|
880
|
+
end
|
|
881
|
+
|
|
778
882
|
def relative_signature_path(path)
|
|
779
883
|
root = "#{Dir.pwd}#{File::SEPARATOR}"
|
|
780
884
|
path.start_with?(root) ? path.delete_prefix(root) : path
|
|
@@ -822,6 +926,33 @@ module Rigor
|
|
|
822
926
|
)
|
|
823
927
|
end
|
|
824
928
|
|
|
929
|
+
# Issue #2422 — one plugin signature file that loaded without the declarations another source also makes,
|
|
930
|
+
# naming each (sampled) with the file whose declaration was used instead. One row per file, not per
|
|
931
|
+
# declaration: an `rbs collection install` of a gem can overlap the plugin for it on hundreds. A method
|
|
932
|
+
# that composed with the other source's as an overload is not here; the plugin's overloads still bind.
|
|
933
|
+
# The wording covers a superclass a plugin's class header gave up (#2439) as well as a member.
|
|
934
|
+
def build_rbs_plugin_member_stood_down_diagnostic(path, rows)
|
|
935
|
+
labels = rows.map do |_path, declaration, _, _, cause_file|
|
|
936
|
+
cause = cause_file.nil? || cause_file.empty? ? "" : " (#{relative_signature_path(cause_file.to_s)})"
|
|
937
|
+
"`#{declaration}`#{cause}"
|
|
938
|
+
end
|
|
939
|
+
Diagnostic.new(
|
|
940
|
+
path: ".rigor.yml",
|
|
941
|
+
line: 1,
|
|
942
|
+
column: 1,
|
|
943
|
+
message: "`#{relative_signature_path(path.to_s)}` (a signature file a plugin contributes) loaded without " \
|
|
944
|
+
"#{rows.size} declaration(s) another signature source already makes: #{sampled(labels, 10)}. " \
|
|
945
|
+
"Conflicting declarations (two of one method or constant, or two different superclasses " \
|
|
946
|
+
"of one class) fail the build, so the plugin's stood down and the other source's, named in " \
|
|
947
|
+
"parentheses, is used; the rest of the plugin's file still " \
|
|
948
|
+
"loads. Nothing to fix unless you want the plugin's typing back, which needs that source to " \
|
|
949
|
+
"stop declaring it.",
|
|
950
|
+
severity: :info,
|
|
951
|
+
rule: "rbs.coverage.plugin-signature-stood-down",
|
|
952
|
+
source_family: :builtin
|
|
953
|
+
)
|
|
954
|
+
end
|
|
955
|
+
|
|
825
956
|
def build_rbs_vendored_signature_stood_down_diagnostic(entry)
|
|
826
957
|
dir, declarations, whole = entry
|
|
827
958
|
Diagnostic.new(
|
|
@@ -934,9 +1065,12 @@ module Rigor
|
|
|
934
1065
|
# all three cross the pool drain channel (see {RbsExtended::Reporter}); an entry with no position
|
|
935
1066
|
# falls back to `.rigor.yml`-style file-level attribution.
|
|
936
1067
|
def rbs_extended_reporter_diagnostics
|
|
937
|
-
|
|
1068
|
+
unresolved_payload_diagnostics + lossy_projection_diagnostics + hkt_directive_diagnostics +
|
|
1069
|
+
deprecated_form_diagnostics
|
|
1070
|
+
end
|
|
938
1071
|
|
|
939
|
-
|
|
1072
|
+
def unresolved_payload_diagnostics
|
|
1073
|
+
@rbs_extended_reporter.unresolved_payloads.map do |entry|
|
|
940
1074
|
build_positioned_reporter_diagnostic(
|
|
941
1075
|
entry,
|
|
942
1076
|
rule: "dynamic.rbs-extended.unresolved",
|
|
@@ -945,8 +1079,10 @@ module Rigor
|
|
|
945
1079
|
"that contributes the referenced type vocabulary."
|
|
946
1080
|
)
|
|
947
1081
|
end
|
|
1082
|
+
end
|
|
948
1083
|
|
|
949
|
-
|
|
1084
|
+
def lossy_projection_diagnostics
|
|
1085
|
+
@rbs_extended_reporter.lossy_projections.map do |entry|
|
|
950
1086
|
build_positioned_reporter_diagnostic(
|
|
951
1087
|
entry,
|
|
952
1088
|
rule: "dynamic.shape.lossy-projection",
|
|
@@ -955,8 +1091,6 @@ module Rigor
|
|
|
955
1091
|
"a `HashShape` / `Tuple` carrier or accept the unchanged result."
|
|
956
1092
|
)
|
|
957
1093
|
end
|
|
958
|
-
|
|
959
|
-
unresolved + lossy + hkt_directive_diagnostics + deprecated_form_diagnostics
|
|
960
1094
|
end
|
|
961
1095
|
|
|
962
1096
|
# ADR-109 WD3 — one row per annotation still written in a spelling the grammar accepts but no
|
|
@@ -1116,12 +1250,14 @@ module Rigor
|
|
|
1116
1250
|
end
|
|
1117
1251
|
|
|
1118
1252
|
# Issue #1051 — the run-scoped plugin disclosures ({Plugin::Base#disclose_once}), the run's
|
|
1119
|
-
# project-global notices about its own inputs.
|
|
1253
|
+
# project-global notices about its own inputs. Three sources feed one table:
|
|
1120
1254
|
#
|
|
1121
1255
|
# - the coordinator-side registry, which is where a SEQUENTIAL run's `#prepare` and per-file hooks
|
|
1122
1256
|
# ran; and
|
|
1123
1257
|
# - `pooled_run_disclosures`, the pool coordinator's already-de-duplicated collection from the
|
|
1124
|
-
# pre-fork parent session and every worker payload
|
|
1258
|
+
# pre-fork parent session and every worker payload; and
|
|
1259
|
+
# - `served_run_disclosures` (#2020), the rows an incremental recheck replays for the files it served
|
|
1260
|
+
# from cache, since their per-file hooks did not run.
|
|
1125
1261
|
#
|
|
1126
1262
|
# Both are keyed `[plugin id, key]` and the first registration of a pair wins, so a run emits one
|
|
1127
1263
|
# row per pair no matter how many plugin instances (workers) reached it — the #1051 bug, where a
|
|
@@ -1183,6 +1319,10 @@ module Rigor
|
|
|
1183
1319
|
rescue StandardError
|
|
1184
1320
|
next
|
|
1185
1321
|
end
|
|
1322
|
+
# Issue #2020 — last, so a row this run registered afresh wins over the replay of the same key.
|
|
1323
|
+
Array(@served_run_disclosures_reader.call).each do |record|
|
|
1324
|
+
records[[record[:plugin_id], record[:key]]] ||= record
|
|
1325
|
+
end
|
|
1186
1326
|
records.values
|
|
1187
1327
|
end
|
|
1188
1328
|
|
|
@@ -1322,38 +1462,6 @@ module Rigor
|
|
|
1322
1462
|
def pre_eval_diagnostics_from_scanner
|
|
1323
1463
|
@pre_eval_diagnostics_from_scanner_reader.call
|
|
1324
1464
|
end
|
|
1325
|
-
|
|
1326
|
-
def synthesized_namespaces_snapshot
|
|
1327
|
-
@synthesized_namespaces_snapshot_reader.call
|
|
1328
|
-
end
|
|
1329
|
-
|
|
1330
|
-
def quarantined_signatures_snapshot
|
|
1331
|
-
@quarantined_signatures_snapshot_reader.call
|
|
1332
|
-
end
|
|
1333
|
-
|
|
1334
|
-
def signature_standdowns_snapshot
|
|
1335
|
-
@signature_standdowns_snapshot_reader.call
|
|
1336
|
-
end
|
|
1337
|
-
|
|
1338
|
-
def vendored_standdowns_snapshot
|
|
1339
|
-
@vendored_standdowns_snapshot_reader.call
|
|
1340
|
-
end
|
|
1341
|
-
|
|
1342
|
-
def env_build_failure_snapshot
|
|
1343
|
-
@env_build_failure_snapshot_reader.call
|
|
1344
|
-
end
|
|
1345
|
-
|
|
1346
|
-
def definition_build_failures_snapshot
|
|
1347
|
-
@definition_build_failures_snapshot_reader.call
|
|
1348
|
-
end
|
|
1349
|
-
|
|
1350
|
-
def hkt_scan_failure_snapshot
|
|
1351
|
-
@hkt_scan_failure_snapshot_reader.call
|
|
1352
|
-
end
|
|
1353
|
-
|
|
1354
|
-
def conformance_results_snapshot
|
|
1355
|
-
@conformance_results_snapshot_reader.call
|
|
1356
|
-
end
|
|
1357
1465
|
end
|
|
1358
1466
|
end
|
|
1359
1467
|
end
|
|
@@ -78,7 +78,7 @@ module Rigor
|
|
|
78
78
|
LABELS_CONSEQUENCE = "the label is not registered"
|
|
79
79
|
private_constant :LABELS_CONSEQUENCE
|
|
80
80
|
|
|
81
|
-
# @param rbs_loader — the run's loader; nil
|
|
81
|
+
# @param rbs_loader — the run's loader; nil skips the RBS walk, not the configured envelopes.
|
|
82
82
|
# @param effect_table — the propagated graph.
|
|
83
83
|
# @param discovery — forces and returns the cross-file discovery tables as
|
|
84
84
|
# `[def_sources, singleton_def_sources, class_sources]`. Called only when a finding needs a
|