rigortype 0.4.6 → 0.4.8
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 +4 -2
- data/data/core_overlay/bigdecimal.rbs +33 -0
- data/data/core_overlay/resolv.rbs +30 -0
- data/data/gem_overlay/activesupport/core_ext.rbs +45 -13
- data/data/gem_overlay/addressable/addressable.rbs +40 -0
- 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 +6 -3
- data/docs/handbook/11-sig-gen.md +85 -3
- data/docs/handbook/appendix-phpstan.md +4 -4
- data/docs/install.md +20 -0
- data/docs/manual/01-installation.md +67 -26
- data/docs/manual/02-cli-reference.md +455 -113
- data/docs/manual/03-configuration.md +76 -5
- data/docs/manual/04-diagnostics.md +5 -4
- data/docs/manual/06-baseline.md +6 -4
- data/docs/manual/08-skills.md +11 -0
- data/docs/manual/09-editor-integration.md +21 -2
- data/docs/manual/10-mcp-server.md +38 -2
- data/docs/manual/12-caching.md +4 -3
- data/docs/manual/14-rails-quickstart.md +1 -1
- data/docs/manual/19-effect-labels.md +3 -4
- data/docs/manual/plugins/rigor-actionpack.md +32 -15
- data/docs/manual/plugins/rigor-activesupport-core-ext.md +23 -1
- data/docs/manual/plugins/rigor-sorbet.md +17 -3
- data/lib/rigor/analysis/baseline.rb +24 -27
- data/lib/rigor/analysis/check_rules/always_raises_shield.rb +147 -0
- data/lib/rigor/analysis/check_rules/always_truthy_condition_collector.rb +5 -6
- data/lib/rigor/analysis/check_rules/call_facts.rb +58 -0
- data/lib/rigor/analysis/check_rules/dead_assignment_collector.rb +2 -2
- data/lib/rigor/analysis/check_rules/declaration_sourced_guard.rb +12 -4
- data/lib/rigor/analysis/check_rules/duplicate_hash_key_collector.rb +2 -2
- data/lib/rigor/analysis/check_rules/inferred_param_guard.rb +85 -13
- data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +16 -4
- data/lib/rigor/analysis/check_rules/lexical_method_sites.rb +6 -1
- data/lib/rigor/analysis/check_rules/main_pass_collector.rb +5 -8
- data/lib/rigor/analysis/check_rules/plugin_api_surface.rb +195 -0
- data/lib/rigor/analysis/check_rules/published_constant_guard.rb +41 -12
- data/lib/rigor/analysis/check_rules/rbs_receiver_surface.rb +27 -1
- data/lib/rigor/analysis/check_rules/rebinding_block_callees.rb +3 -3
- data/lib/rigor/analysis/check_rules/replaced_singleton_defs.rb +96 -0
- data/lib/rigor/analysis/check_rules/return_in_ensure_collector.rb +1 -2
- data/lib/rigor/analysis/check_rules/rule_ids.rb +9 -2
- 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 +2 -2
- data/lib/rigor/analysis/check_rules/void_value_use_collector.rb +2 -2
- data/lib/rigor/analysis/check_rules.rb +720 -141
- data/lib/rigor/analysis/crash_signature.rb +45 -3
- data/lib/rigor/analysis/dependency_recorder.rb +237 -80
- 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 +93 -6
- data/lib/rigor/analysis/fact_store.rb +3 -3
- data/lib/rigor/analysis/incremental.rb +11 -1
- data/lib/rigor/analysis/incremental_run_slot/write_guard.rb +4 -3
- data/lib/rigor/analysis/incremental_run_slot.rb +2 -2
- data/lib/rigor/analysis/incremental_session.rb +306 -53
- data/lib/rigor/analysis/reachability/plugin_roots.rb +6 -3
- data/lib/rigor/analysis/rule_catalog.rb +39 -3
- data/lib/rigor/analysis/run_cache_key.rb +27 -3
- data/lib/rigor/analysis/run_disclosure_credit.rb +26 -6
- data/lib/rigor/analysis/run_stats.rb +2 -2
- data/lib/rigor/analysis/runner/buffer_pool_dispatcher.rb +6 -2
- data/lib/rigor/analysis/runner/declaration_position.rb +8 -8
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +264 -112
- data/lib/rigor/analysis/runner/effect_envelope_pass.rb +4 -9
- data/lib/rigor/analysis/runner/pool_coordinator.rb +173 -328
- data/lib/rigor/analysis/runner/project_pre_passes.rb +4 -37
- 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/worker_payload.rb +36 -0
- data/lib/rigor/analysis/runner.rb +298 -109
- data/lib/rigor/analysis/self_call_resolution_recorder.rb +62 -23
- 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 +65 -71
- data/lib/rigor/bleeding_edge.rb +22 -10
- 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/file_digest.rb +39 -31
- data/lib/rigor/cache/incremental_snapshot.rb +95 -17
- 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 +90 -4
- data/lib/rigor/cache/rbs_environment.rb +8 -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 +160 -57
- data/lib/rigor/cli/catalogue.rb +256 -0
- data/lib/rigor/cli/check_command.rb +112 -104
- 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 +25 -20
- 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 +26 -18
- 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 +29 -10
- data/lib/rigor/cli/lsp_command.rb +250 -23
- data/lib/rigor/cli/mcp_command.rb +12 -7
- 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 +40 -1
- data/lib/rigor/cli/plugin_command.rb +93 -46
- data/lib/rigor/cli/plugins_command.rb +17 -18
- data/lib/rigor/cli/plugins_renderer.rb +10 -6
- 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 +21 -15
- data/lib/rigor/cli/sig_gen_command.rb +92 -27
- 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 +2 -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 +16 -11
- data/lib/rigor/cli/type_of_project_scope.rb +1 -4
- 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 +214 -56
- data/lib/rigor/config_audit.rb +33 -19
- data/lib/rigor/configuration/severity_profile.rb +14 -5
- data/lib/rigor/configuration.rb +104 -35
- data/lib/rigor/effects/collector.rb +53 -21
- 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 +64 -33
- data/lib/rigor/environment/class_registry.rb +3 -3
- data/lib/rigor/environment/constant_type_cache_holder.rb +5 -0
- data/lib/rigor/environment/core_root.rb +77 -0
- data/lib/rigor/environment/default_libraries.rb +18 -1
- data/lib/rigor/environment/deferred_signature_plan.rb +381 -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/hkt_registry_holder.rb +6 -0
- 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_collection_discovery.rb +123 -8
- data/lib/rigor/environment/rbs_coverage_report.rb +12 -11
- data/lib/rigor/environment/rbs_hierarchy.rb +12 -15
- data/lib/rigor/environment/rbs_loader.rb +772 -110
- data/lib/rigor/environment/reflection.rb +7 -7
- data/lib/rigor/environment/required_features.rb +0 -3
- data/lib/rigor/environment/ruby_library_roots.rb +1 -1
- data/lib/rigor/environment/vendored_signature_plan.rb +153 -0
- data/lib/rigor/environment.rb +169 -42
- data/lib/rigor/flow_contribution/merger.rb +4 -4
- data/lib/rigor/inference/acceptance.rb +136 -40
- data/lib/rigor/inference/alias_mutation_floor/foreign_locals.rb +117 -0
- data/lib/rigor/inference/alias_mutation_floor/memos.rb +85 -0
- data/lib/rigor/inference/alias_mutation_floor/reach.rb +119 -0
- data/lib/rigor/inference/alias_mutation_floor/site_collector.rb +252 -0
- data/lib/rigor/inference/alias_mutation_floor.rb +339 -0
- data/lib/rigor/inference/anonymous_meta_class.rb +18 -0
- data/lib/rigor/inference/block_auto_splat.rb +1 -1
- data/lib/rigor/inference/block_parameter_binder.rb +2 -3
- data/lib/rigor/inference/block_run_count.rb +185 -0
- data/lib/rigor/inference/budget_trace.rb +8 -2
- data/lib/rigor/inference/builtins/array_catalog.rb +2 -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 +88 -77
- data/lib/rigor/inference/callee_write_census.rb +815 -0
- data/lib/rigor/inference/captured_locals.rb +2 -0
- data/lib/rigor/inference/census_foreign_block.rb +354 -0
- data/lib/rigor/inference/clause_widening.rb +1 -1
- data/lib/rigor/inference/closure_escape_analyzer.rb +11 -4
- data/lib/rigor/inference/construction_escape.rb +258 -0
- data/lib/rigor/inference/declaration_walk/traversal.rb +1 -1
- data/lib/rigor/inference/declaration_walk.rb +4 -0
- data/lib/rigor/inference/deep_erasure.rb +39 -7
- data/lib/rigor/inference/def_handle.rb +1 -1
- data/lib/rigor/inference/def_node_resolver.rb +33 -15
- data/lib/rigor/inference/def_return_typer.rb +47 -5
- data/lib/rigor/inference/definer_resolution.rb +19 -9
- data/lib/rigor/inference/definers_index.rb +162 -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 +16 -0
- data/lib/rigor/inference/expression_typer.rb +1559 -320
- data/lib/rigor/inference/external_ancestor_resolution.rb +3 -4
- data/lib/rigor/inference/flow_tracer.rb +31 -14
- data/lib/rigor/inference/fork_map.rb +3 -0
- data/lib/rigor/inference/fresh_frame_blocks.rb +52 -1
- data/lib/rigor/inference/global_write_census.rb +81 -5
- 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/in_effect_refinements.rb +7 -0
- data/lib/rigor/inference/indexed_narrowing.rb +61 -15
- data/lib/rigor/inference/intervening_ivar_reset.rb +26 -4
- data/lib/rigor/inference/ivar_writer_census.rb +154 -8
- data/lib/rigor/inference/key_presence_guard.rb +51 -24
- data/lib/rigor/inference/last_line/self_evidence.rb +30 -0
- data/lib/rigor/inference/last_line.rb +5 -2
- data/lib/rigor/inference/loop_value_record.rb +66 -14
- data/lib/rigor/inference/match_rebinding/frame.rb +57 -0
- data/lib/rigor/inference/match_rebinding/yielding_match.rb +101 -0
- data/lib/rigor/inference/match_rebinding.rb +28 -5
- 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 +44 -30
- data/lib/rigor/inference/method_dispatcher/class_keyed_block_params.rb +65 -0
- data/lib/rigor/inference/method_dispatcher/constant_folding.rb +3 -3
- data/lib/rigor/inference/method_dispatcher/contested_overloads.rb +89 -0
- data/lib/rigor/inference/method_dispatcher/core_enumerable_receiver.rb +44 -0
- data/lib/rigor/inference/method_dispatcher/declared_constructor.rb +151 -0
- data/lib/rigor/inference/method_dispatcher/facet_distribution.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/imprecise_argument.rb +2 -2
- data/lib/rigor/inference/method_dispatcher/interface_shape.rb +181 -0
- data/lib/rigor/inference/method_dispatcher/iterator_dispatch.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/kernel_dispatch.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/no_match_fallback.rb +54 -0
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +51 -27
- data/lib/rigor/inference/method_dispatcher/random_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +606 -78
- 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 +3 -3
- data/lib/rigor/inference/method_dispatcher/set_folding.rb +9 -7
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +467 -84
- 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/singleton_type_params.rb +104 -0
- 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 +123 -25
- data/lib/rigor/inference/method_parameter_binder.rb +136 -56
- data/lib/rigor/inference/module_function_state/spellings.rb +2 -2
- data/lib/rigor/inference/module_function_state.rb +24 -3
- data/lib/rigor/inference/multi_target_binder.rb +2 -2
- data/lib/rigor/inference/mutation_rejoin.rb +240 -4
- data/lib/rigor/inference/mutation_widening.rb +199 -29
- data/lib/rigor/inference/narrowing.rb +238 -50
- data/lib/rigor/inference/operand_effects.rb +43 -2
- data/lib/rigor/inference/optimistic_origin.rb +134 -9
- data/lib/rigor/inference/origin_lookup.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/precision_scanner.rb +1 -1
- data/lib/rigor/inference/project_method_ownership.rb +30 -9
- data/lib/rigor/inference/project_patched_methods.rb +65 -13
- data/lib/rigor/inference/project_patched_scanner.rb +120 -25
- data/lib/rigor/inference/project_patched_visibility.rb +39 -3
- data/lib/rigor/inference/project_yielder.rb +11 -17
- data/lib/rigor/inference/rbs_type_translator.rb +68 -15
- data/lib/rigor/inference/receiver_alias.rb +20 -0
- data/lib/rigor/inference/receiver_writer_call.rb +67 -0
- data/lib/rigor/inference/recursion_rebinding.rb +157 -0
- data/lib/rigor/inference/refined_dispatch/constructed_class.rb +57 -17
- data/lib/rigor/inference/refined_dispatch/own_method.rb +51 -16
- data/lib/rigor/inference/refined_dispatch.rb +13 -0
- data/lib/rigor/inference/reflective_ivar_write.rb +19 -11
- data/lib/rigor/inference/remover_holder_scan.rb +287 -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 +0 -1
- data/lib/rigor/inference/scope_indexer/class_cvars_collector.rb +13 -6
- data/lib/rigor/inference/scope_indexer/constant_ivar_value.rb +93 -0
- data/lib/rigor/inference/scope_indexer/declared_param_writes.rb +70 -26
- 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 +295 -0
- data/lib/rigor/inference/scope_indexer/mixin_accumulator.rb +136 -9
- data/lib/rigor/inference/scope_indexer.rb +2213 -226
- data/lib/rigor/inference/self_call_ivar_writes.rb +103 -12
- data/lib/rigor/inference/self_preserving_block.rb +87 -0
- data/lib/rigor/inference/set_mutation.rb +189 -0
- data/lib/rigor/inference/singleton_hook_decline.rb +42 -8
- data/lib/rigor/inference/singleton_object_constant.rb +32 -2
- data/lib/rigor/inference/statement_evaluator.rb +3268 -358
- data/lib/rigor/inference/string_mutation.rb +14 -0
- data/lib/rigor/inference/struct_fold_safety.rb +4 -6
- data/lib/rigor/inference/synthetic_method_scanner.rb +40 -17
- data/lib/rigor/inference/toplevel_def_census.rb +67 -0
- data/lib/rigor/inference/unknown_store_widening.rb +103 -4
- data/lib/rigor/inference/unthreaded_rebinds.rb +2 -3
- data/lib/rigor/inference/untyped_rejoin.rb +1 -1
- data/lib/rigor/inference/void_tail_summary.rb +29 -9
- data/lib/rigor/language_server/buffer_table.rb +3 -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 +8 -3
- 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 +39 -1
- 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 +7 -3
- data/lib/rigor/language_server/signature_help_provider.rb +4 -4
- data/lib/rigor/lens/claims/comparison.rb +78 -0
- data/lib/rigor/lens/claims/request.rb +131 -0
- data/lib/rigor/lens/claims/type_reader.rb +216 -0
- data/lib/rigor/lens/claims.rb +208 -0
- data/lib/rigor/lens/contract_reader.rb +5 -0
- data/lib/rigor/lens/document.rb +1 -1
- data/lib/rigor/lens/file_reader.rb +21 -8
- data/lib/rigor/lens/plugins.rb +1 -1
- data/lib/rigor/lens/run.rb +8 -0
- data/lib/rigor/lens.rb +1 -1
- data/lib/rigor/library_probe.rb +68 -0
- data/lib/rigor/mcp/server.rb +73 -2
- data/lib/rigor/mcp.rb +1 -1
- data/lib/rigor/memo_audit.rb +282 -0
- data/lib/rigor/plugin/access_denied_error.rb +1 -2
- data/lib/rigor/plugin/base.rb +15 -2
- data/lib/rigor/plugin/bundled_catalog.rb +1 -12
- data/lib/rigor/plugin/io_boundary.rb +26 -4
- 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 +16 -16
- data/lib/rigor/plugin/registry.rb +16 -5
- 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 +48 -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 +44 -5
- data/lib/rigor/protection/mutation_cache.rb +4 -1
- 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 +81 -22
- data/lib/rigor/reflection/declaration_collectors.rb +55 -0
- data/lib/rigor/reflection/declarations.rb +58 -0
- data/lib/rigor/reflection/project_method.rb +177 -0
- data/lib/rigor/reflection.rb +2 -0
- data/lib/rigor/rooted_glob.rb +32 -1
- data/lib/rigor/run_scoped_slots.rb +38 -0
- data/lib/rigor/runtime/jit.rb +1 -1
- data/lib/rigor/scope/discovery_index.rb +168 -8
- data/lib/rigor/scope/resolution_chain/relevance.rb +14 -1
- data/lib/rigor/scope/resolution_chain.rb +901 -54
- data/lib/rigor/scope.rb +644 -37
- data/lib/rigor/sig_gen/bot_proposal_guard.rb +306 -0
- data/lib/rigor/sig_gen/classification.rb +18 -1
- data/lib/rigor/sig_gen/effect_annotation.rb +3 -3
- data/lib/rigor/sig_gen/generator.rb +588 -66
- 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 +37 -4
- data/lib/rigor/sig_gen/observation_collector.rb +14 -7
- 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/platform_guarded_files.rb +184 -0
- data/lib/rigor/sig_gen/renderer.rb +15 -9
- data/lib/rigor/sig_gen/skip_reason_catalog.rb +62 -2
- 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 +238 -37
- data/lib/rigor/sig_gen.rb +1 -0
- data/lib/rigor/source/forwardable_delegators.rb +122 -0
- data/lib/rigor/source/node_children.rb +13 -0
- 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 +173 -21
- data/lib/rigor/type/constant.rb +4 -5
- data/lib/rigor/type/hash_shape.rb +21 -40
- data/lib/rigor/type/interface.rb +60 -0
- data/lib/rigor/type/union.rb +1 -1
- data/lib/rigor/type.rb +1 -0
- 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/type_of_memo/serving.rb +99 -0
- data/lib/rigor/type_of_memo/stats.rb +43 -0
- data/lib/rigor/type_of_memo.rb +337 -0
- data/lib/rigor/typing_state.rb +1094 -0
- 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 +38 -36
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_index.rb +4 -2
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb +6 -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 +3 -3
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +115 -36
- data/plugins/rigor-active-model-serializers/lib/rigor/plugin/active_model_serializers.rb +3 -6
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/analyzer.rb +25 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/effects.rb +1 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_discoverer.rb +16 -6
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_index.rb +4 -2
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +4 -3
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/analyzer.rb +2 -1
- 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 +132 -33
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_table.rb +20 -6
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/structure_sql_parser.rb +7 -4
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +54 -17
- data/plugins/rigor-activerecord/sig/active_record/relation.rbs +19 -5
- 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 +11 -14
- 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 +30 -9
- data/plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs +55 -13
- data/plugins/rigor-alba/lib/rigor/plugin/alba/resource_collector.rb +15 -21
- data/plugins/rigor-alba/lib/rigor/plugin/alba/resource_discoverer.rb +1 -6
- data/plugins/rigor-alba/lib/rigor/plugin/alba/resource_index.rb +3 -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 +1 -1
- 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 +8 -7
- 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-graphql/lib/rigor/plugin/graphql.rb +12 -2
- 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 +8 -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 +200 -4
- 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 +4 -3
- data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb +2 -1
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +5 -5
- 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 +3 -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 +210 -3
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog_walker.rb +146 -7
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sig_parser.rb +2 -2
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/type_translator.rb +52 -34
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +97 -24
- data/plugins/rigor-statesman/lib/rigor/plugin/statesman.rb +2 -3
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer/serializer_collector.rb +16 -16
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer/serializer_discoverer.rb +4 -8
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer/serializer_index.rb +4 -4
- data/sig/rigor/analysis/baseline.rbs +0 -3
- data/sig/rigor/analysis/check_rules/rule_walk.rbs +6 -0
- data/sig/rigor/analysis/fact_store.rbs +2 -2
- data/sig/rigor/analysis/reachability/scan_cache.rbs +1 -1
- data/sig/rigor/cache/descriptor.rbs +14 -0
- data/sig/rigor/cli/diff_command.rbs +1 -1
- data/sig/rigor/cli/explain_command.rbs +1 -1
- data/sig/rigor/effects/registry.rbs +2 -2
- data/sig/rigor/environment.rbs +4 -1
- data/sig/rigor/inference.rbs +4 -1
- data/sig/rigor/plugin/additional_initializer.rbs +0 -5
- data/sig/rigor/plugin/base.rbs +53 -18
- data/sig/rigor/plugin/effect_attribution.rbs +3 -3
- data/sig/rigor/plugin/effect_edge.rbs +1 -1
- data/sig/rigor/plugin/effect_entry_points.rbs +3 -3
- data/sig/rigor/plugin/interfaces.rbs +51 -0
- data/sig/rigor/plugin/io_boundary.rbs +3 -3
- data/sig/rigor/plugin/manifest.rbs +9 -9
- data/sig/rigor/plugin/node_context.rbs +21 -0
- data/sig/rigor/plugin/protocol_contract.rbs +3 -7
- data/sig/rigor/reflection.rbs +37 -0
- data/sig/rigor/scope.rbs +43 -4
- data/sig/rigor/trinary.rbs +1 -0
- data/sig/rigor/type.rbs +9 -3
- data/sig/rigor.rbs +3 -2
- data/skills/rigor-ask/SKILL.md +1 -0
- 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/01-detect.md +1 -0
- data/skills/rigor-project-init/references/03-baseline-and-bugs.md +17 -2
- data/skills/rigor-project-init/references/06-agent-contract.md +4 -4
- data/skills/rigor-rbs-contract/SKILL.md +147 -0
- data/skills/rigor-rbs-contract/references/01-finding-candidates.md +212 -0
- data/skills/rigor-rbs-contract/references/02-contract-rules.md +157 -0
- data/skills/rigor-rbs-contract/references/03-target-own-code.md +90 -0
- data/skills/rigor-rbs-contract/references/04-target-gem-rbs-collection.md +210 -0
- data/skills/rigor-rbs-contract/references/05-declaration-mutants.md +182 -0
- data/skills/rigor-rbs-setup/SKILL.md +3 -1
- data/skills/rigor-type-oracle/SKILL.md +26 -1
- data/skills/rigor-type-oracle/references/02-agents-md-fragment.md +4 -3
- metadata +82 -3
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require_relative "../check_rules/rule_ids"
|
|
4
4
|
require_relative "../crash_signature"
|
|
5
5
|
require_relative "../diagnostic"
|
|
6
|
+
require_relative "../run_cache_key"
|
|
6
7
|
require_relative "../severity_stamp"
|
|
7
8
|
|
|
8
9
|
module Rigor
|
|
@@ -29,35 +30,24 @@ module Rigor
|
|
|
29
30
|
# @param pool_mode — reader returning the pool-mode flag.
|
|
30
31
|
# @param cached_plugin_prepare_diagnostics — reader returning the prepare-diagnostic snapshot.
|
|
31
32
|
# @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.
|
|
33
|
+
# @param snapshots — the run's {RunSnapshots} store (ADR-116 WD3), read at row-build time. Its slots'
|
|
34
|
+
# shapes, as the rows below read them:
|
|
35
|
+
# - `quarantined_signatures` — the `signature_paths:` files skipped because they do not parse
|
|
36
|
+
# (`[path, first_error_line]` pairs);
|
|
37
|
+
# - `signature_standdowns` (#610) — `[path, class_name, existing_arity, incoming_arity,
|
|
38
|
+
# existing_file]` tuples, then (#2422) `[path, declaration, nil, nil, cause_file, :member]` ones;
|
|
39
|
+
# - `vendored_standdowns` (#1713) — `Environment::RbsLoader#vendored_standdowns`;
|
|
40
|
+
# - `env_build_failure` — `[error_class, first_error_line, conflicting_buffer_names]`, or nil;
|
|
41
|
+
# - `definition_build_failures` (#696) — `[class_name, error_class, member,
|
|
42
|
+
# conflicting_buffer_names, unresolved_type_name_detail, mixin_count]` tuples (#997 added the fifth
|
|
43
|
+
# element — `[token, location, refinement_hint]`, `nil` unless `error_class` is
|
|
44
|
+
# `RBS::NoTypeFoundError`; #2440 the sixth, {Environment::RbsLoader#variable_mixin_count});
|
|
45
|
+
# - `hkt_scan_failure` (#784) — `[error_class_name, first_message_line, raw_frame_or_nil, stage]`,
|
|
46
|
+
# or nil; `stage` is `:scan` or `:overlay` (#791) and picks the row's wording.
|
|
53
47
|
def initialize(configuration:, rbs_extended_reporter:, boundary_cross_reporter:, # rubocop:disable Metrics/ParameterLists
|
|
54
48
|
source_rbs_synthesis_reporter:, plugin_registry:, dependency_source_index:,
|
|
55
49
|
pool_mode:, cached_plugin_prepare_diagnostics:,
|
|
56
|
-
pre_eval_diagnostics_from_scanner:,
|
|
57
|
-
quarantined_signatures_snapshot:, env_build_failure_snapshot:,
|
|
58
|
-
definition_build_failures_snapshot:, hkt_scan_failure_snapshot:,
|
|
59
|
-
conformance_results_snapshot:, signature_standdowns_snapshot: -> { [] },
|
|
60
|
-
vendored_standdowns_snapshot: -> { [] }, pooled_run_disclosures: -> { [] },
|
|
50
|
+
pre_eval_diagnostics_from_scanner:, snapshots:, pooled_run_disclosures: -> { [] },
|
|
61
51
|
served_run_disclosures: -> { [] }, pooled_trust_refusals: -> { [] })
|
|
62
52
|
@configuration = configuration
|
|
63
53
|
@rbs_extended_reporter = rbs_extended_reporter
|
|
@@ -68,14 +58,7 @@ module Rigor
|
|
|
68
58
|
@pool_mode_reader = pool_mode
|
|
69
59
|
@cached_plugin_prepare_diagnostics_reader = cached_plugin_prepare_diagnostics
|
|
70
60
|
@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
|
|
61
|
+
@snapshots = snapshots
|
|
79
62
|
# Issue #1051 — reader for the pool coordinator's de-duplicated run-scoped disclosure table.
|
|
80
63
|
# Empty on a sequential run, where `plugin_registry`'s own instances are the ones that registered.
|
|
81
64
|
@pooled_run_disclosures_reader = pooled_run_disclosures
|
|
@@ -86,6 +69,14 @@ module Rigor
|
|
|
86
69
|
@pooled_trust_refusals_reader = pooled_trust_refusals
|
|
87
70
|
end
|
|
88
71
|
|
|
72
|
+
# ADR-116 WD3 — every post-analysis run-level row, in the contract order {RunLevelFacts.row_builders}
|
|
73
|
+
# declares: the `rbs.coverage.*` build-failure ladder widest consequence first, its `:info` notices,
|
|
74
|
+
# the conformance rows, the reporter streams, then the plugin run disclosures and the trust-refusal
|
|
75
|
+
# envelope, read last so every per-file plugin call has recorded its refusals.
|
|
76
|
+
def run_level_diagnostics
|
|
77
|
+
RunLevelFacts.row_builders.flat_map { |builder| public_send(builder) }
|
|
78
|
+
end
|
|
79
|
+
|
|
89
80
|
# Pre-file diagnostic streams that fire once per run rather than per analyzed file: plugin load /
|
|
90
81
|
# prepare envelopes, the ADR-10 dependency-source resolution surface, and the `expand_paths` errors
|
|
91
82
|
# for `paths:` entries that don't exist or aren't `.rb`. Aggregated here so `#run` stays under the
|
|
@@ -94,9 +85,9 @@ module Rigor
|
|
|
94
85
|
# ADR-15 Phase 4b — `plugin_prepare_diagnostics` runs on the coordinator's plugin registry under
|
|
95
86
|
# sequential mode; under pool mode each worker re-runs `prepare` against its own plugin instances,
|
|
96
87
|
# so the pool path drains the first worker's prepare-diagnostic snapshot into the aggregated
|
|
97
|
-
# diagnostic stream instead (see {#analyze_files_in_pool}). Skipping the coordinator
|
|
98
|
-
# mode avoids double-running `#prepare` against the coordinator-side plugin instances
|
|
99
|
-
# pool path never consults for per-file analysis).
|
|
88
|
+
# diagnostic stream instead (see {PoolCoordinator#analyze_files_in_pool}). Skipping the coordinator
|
|
89
|
+
# prepare in pool mode avoids double-running `#prepare` against the coordinator-side plugin instances
|
|
90
|
+
# (which the pool path never consults for per-file analysis).
|
|
100
91
|
def pre_file_diagnostics(expansion)
|
|
101
92
|
# ADR-18 slice 3 — prepare diagnostics are captured earlier in #run (before the synthetic-method
|
|
102
93
|
# scanner) so cross-plugin facts are available to the scanner. We re-surface the captured
|
|
@@ -109,6 +100,7 @@ module Rigor
|
|
|
109
100
|
dependency_source_budget_diagnostics +
|
|
110
101
|
dependency_source_config_conflict_diagnostics +
|
|
111
102
|
rbs_coverage_diagnostics +
|
|
103
|
+
rbs_collection_setup_hint_diagnostics +
|
|
112
104
|
rbs_inline_annotation_hint_diagnostics(expansion) +
|
|
113
105
|
expansion.fetch(:errors)
|
|
114
106
|
end
|
|
@@ -125,7 +117,7 @@ module Rigor
|
|
|
125
117
|
next if File.file?(path)
|
|
126
118
|
|
|
127
119
|
Diagnostic.new(
|
|
128
|
-
path:
|
|
120
|
+
path: @configuration.config_display_path, line: 1, column: 1,
|
|
129
121
|
message: "pre_eval entry not found: #{path.inspect}. " \
|
|
130
122
|
"Pre-evaluation requires the file to exist on disk; remove the entry " \
|
|
131
123
|
"or create the file before re-running analysis.",
|
|
@@ -173,7 +165,7 @@ module Rigor
|
|
|
173
165
|
def plugin_load_diagnostics
|
|
174
166
|
plugin_registry.load_errors.map do |error|
|
|
175
167
|
Diagnostic.new(
|
|
176
|
-
path:
|
|
168
|
+
path: @configuration.config_display_path,
|
|
177
169
|
line: 1,
|
|
178
170
|
column: 1,
|
|
179
171
|
message: plugin_load_error_message(error),
|
|
@@ -202,7 +194,7 @@ module Rigor
|
|
|
202
194
|
def dependency_source_diagnostics
|
|
203
195
|
dependency_source_index.unresolvable.map do |entry|
|
|
204
196
|
Diagnostic.new(
|
|
205
|
-
path:
|
|
197
|
+
path: @configuration.config_display_path,
|
|
206
198
|
line: 1,
|
|
207
199
|
column: 1,
|
|
208
200
|
message: "dependencies.source_inference[].gem #{entry.gem_name.inspect} could not be " \
|
|
@@ -227,7 +219,7 @@ module Rigor
|
|
|
227
219
|
def dependency_source_config_conflict_diagnostics
|
|
228
220
|
@configuration.dependencies.warnings.map do |message|
|
|
229
221
|
Diagnostic.new(
|
|
230
|
-
path:
|
|
222
|
+
path: @configuration.config_display_path,
|
|
231
223
|
line: 1,
|
|
232
224
|
column: 1,
|
|
233
225
|
message: message,
|
|
@@ -242,7 +234,7 @@ module Rigor
|
|
|
242
234
|
budget = @configuration.dependencies.budget_per_gem
|
|
243
235
|
dependency_source_index.budget_exceeded.map do |gem_name|
|
|
244
236
|
Diagnostic.new(
|
|
245
|
-
path:
|
|
237
|
+
path: @configuration.config_display_path,
|
|
246
238
|
line: 1,
|
|
247
239
|
column: 1,
|
|
248
240
|
message: "dependencies.source_inference[].gem #{gem_name.inspect} exceeded the per-gem " \
|
|
@@ -258,7 +250,8 @@ module Rigor
|
|
|
258
250
|
|
|
259
251
|
# O4 Layer 3 slice 3 — graceful-degradation coverage report. When the project has a `Gemfile.lock`
|
|
260
252
|
# (slice 1) and one or more locked gems are not covered by ANY of the four RBS resolution paths
|
|
261
|
-
# (`DEFAULT_LIBRARIES
|
|
253
|
+
# (the resolved library list — `DEFAULT_LIBRARIES` + `libraries:` + the collection lockfile's stdlib
|
|
254
|
+
# entries, `data/vendored_gem_sigs/`, slice-1 bundle-shipped `sig/`, slice-2
|
|
262
255
|
# `rbs_collection.lock.yaml`), emit a single `:info` diagnostic summarising the uncovered set so the
|
|
263
256
|
# user can act on it (run `rbs collection install`, opt the gem into `dependencies.source_inference:`,
|
|
264
257
|
# or accept the `Dynamic[T]` fallback).
|
|
@@ -271,6 +264,9 @@ module Rigor
|
|
|
271
264
|
project_root: Dir.pwd,
|
|
272
265
|
auto_detect: @configuration.bundler_auto_detect
|
|
273
266
|
)
|
|
267
|
+
# Issue #2441 — the project's own path gems are not dependencies missing RBS; the environment skips
|
|
268
|
+
# their collection copy, so the same set leaves the report here.
|
|
269
|
+
locked = locked.except(*project_own_gem_names(locked))
|
|
274
270
|
return [] if locked.empty?
|
|
275
271
|
|
|
276
272
|
bundle_sig_paths = Environment::BundleSigDiscovery.discover(
|
|
@@ -286,7 +282,7 @@ module Rigor
|
|
|
286
282
|
)
|
|
287
283
|
rows = Environment::RbsCoverageReport.classify(
|
|
288
284
|
locked_gems: locked,
|
|
289
|
-
default_libraries:
|
|
285
|
+
default_libraries: resolved_default_libraries,
|
|
290
286
|
bundle_sig_paths: bundle_sig_paths,
|
|
291
287
|
rbs_collection_paths: collection_paths
|
|
292
288
|
)
|
|
@@ -296,6 +292,65 @@ module Rigor
|
|
|
296
292
|
[build_rbs_coverage_missing_diagnostic(missing)]
|
|
297
293
|
end
|
|
298
294
|
|
|
295
|
+
# Issue #3030 — one `:info` when the run found no `rbs_collection.lock.yaml` but the directory looks set up for
|
|
296
|
+
# one ({Environment::RbsCollectionDiscovery.missing_lockfile_hint}): the dependency RBS a collection would
|
|
297
|
+
# load is absent, and Rigor does not resolve it from `manifest.yaml` or a gemspec itself.
|
|
298
|
+
def rbs_collection_setup_hint_diagnostics
|
|
299
|
+
# The run-result key and the `--incremental` fingerprint carry the same answer ({RunCacheKey}).
|
|
300
|
+
hint = RunCacheKey.collection_setup_hint(@configuration)
|
|
301
|
+
return [] if hint.nil?
|
|
302
|
+
|
|
303
|
+
[build_rbs_collection_setup_hint_diagnostic(hint)]
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
RBS_COLLECTION_SETUP_STEPS = {
|
|
307
|
+
collection_test_dir: "This looks like a gem_rbs_collection test directory: run the collection's " \
|
|
308
|
+
"`bin/test` setup for this gem first (it writes the lockfile and " \
|
|
309
|
+
"`.gem_rbs_collection/`), then run Rigor here again.",
|
|
310
|
+
collection_config: "An `rbs_collection.yaml` is here: run `rbs collection install` to write the " \
|
|
311
|
+
"lockfile, then run Rigor again."
|
|
312
|
+
}.freeze
|
|
313
|
+
private_constant :RBS_COLLECTION_SETUP_STEPS
|
|
314
|
+
|
|
315
|
+
def build_rbs_collection_setup_hint_diagnostic(hint)
|
|
316
|
+
Diagnostic.new(
|
|
317
|
+
path: @configuration.config_display_path,
|
|
318
|
+
line: 1,
|
|
319
|
+
column: 1,
|
|
320
|
+
message: "No `rbs_collection.lock.yaml` was found, so no `rbs collection` RBS was loaded: the signatures " \
|
|
321
|
+
"of this directory's gem dependencies are absent and calls into them read `Dynamic[top]`. " \
|
|
322
|
+
"#{RBS_COLLECTION_SETUP_STEPS.fetch(hint)}",
|
|
323
|
+
severity: :info,
|
|
324
|
+
rule: "rbs.coverage.collection-not-installed",
|
|
325
|
+
source_family: :builtin
|
|
326
|
+
)
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
# Issue #2962 — the library list is {Environment::BaseLibraries.resolve}'s, the same merge
|
|
330
|
+
# `Environment.for_project` loads, so a gem covered through `libraries:` or a lockfile stdlib
|
|
331
|
+
# entry is not reported missing. Only the names the environment loads count ({LibraryProbe.loadable}): a
|
|
332
|
+
# locked gem named there that RBS has no library for is still missing.
|
|
333
|
+
def resolved_default_libraries
|
|
334
|
+
resolved = Environment::BaseLibraries.resolve(
|
|
335
|
+
@configuration.libraries,
|
|
336
|
+
rbs_collection_lockfile: @configuration.rbs_collection_lockfile,
|
|
337
|
+
rbs_collection_auto_detect: @configuration.rbs_collection_auto_detect,
|
|
338
|
+
root: Dir.pwd
|
|
339
|
+
)
|
|
340
|
+
LibraryProbe.loadable(resolved)
|
|
341
|
+
end
|
|
342
|
+
private :resolved_default_libraries
|
|
343
|
+
|
|
344
|
+
# Issue #2441 — the same project-own set `Environment.for_project` skips the collection copy of.
|
|
345
|
+
def project_own_gem_names(locked)
|
|
346
|
+
Environment::ProjectPathGems.names(
|
|
347
|
+
locked,
|
|
348
|
+
paths: @configuration.paths, root: Dir.pwd,
|
|
349
|
+
exclude_patterns: @configuration.exclude_patterns, exclude_base: @configuration.exclude_base
|
|
350
|
+
)
|
|
351
|
+
end
|
|
352
|
+
private :project_own_gem_names
|
|
353
|
+
|
|
299
354
|
# ADR-93 WD3 — the standalone residual. A bare `gem install rigortype` has no `rbs-inline` library,
|
|
300
355
|
# so the spec's "annotations are official type sources whenever present" cannot be satisfied: the
|
|
301
356
|
# annotated code reads `Dynamic[top]`. When the library is absent AND the project actually carries
|
|
@@ -342,7 +397,7 @@ module Rigor
|
|
|
342
397
|
|
|
343
398
|
def build_rbs_inline_unsynthesized_diagnostic(sample_path)
|
|
344
399
|
Diagnostic.new(
|
|
345
|
-
path:
|
|
400
|
+
path: @configuration.config_display_path,
|
|
346
401
|
line: 1,
|
|
347
402
|
column: 1,
|
|
348
403
|
message: "Inline rbs-inline annotations (`# @rbs …`, `#: <type>`) are present in your project " \
|
|
@@ -379,7 +434,7 @@ module Rigor
|
|
|
379
434
|
# the `reject-unparseable-signatures` feature promotes this rule to `:error` for anyone who opts in
|
|
380
435
|
# (and by default at the next major).
|
|
381
436
|
def rbs_quarantined_signature_diagnostics
|
|
382
|
-
quarantined =
|
|
437
|
+
quarantined = @snapshots[:quarantined_signatures]
|
|
383
438
|
return [] if quarantined.empty?
|
|
384
439
|
|
|
385
440
|
[build_rbs_quarantined_signature_diagnostic(quarantined)]
|
|
@@ -400,7 +455,7 @@ module Rigor
|
|
|
400
455
|
# `reject-unparseable-signatures` bleeding-edge feature promotes it to `:error` for anyone who opts in
|
|
401
456
|
# (and by default at the next major).
|
|
402
457
|
def rbs_environment_build_failed_diagnostics
|
|
403
|
-
failure =
|
|
458
|
+
failure = @snapshots[:env_build_failure]
|
|
404
459
|
return [] if failure.nil?
|
|
405
460
|
|
|
406
461
|
[build_rbs_environment_build_failed_diagnostic(failure)]
|
|
@@ -426,7 +481,7 @@ module Rigor
|
|
|
426
481
|
# a Rigor release turn a green build red with no user change (ADR-5 / AGENTS.md § FP discipline).
|
|
427
482
|
# The `reject-unparseable-signatures` bleeding-edge feature promotes it to `:error`.
|
|
428
483
|
def rbs_definition_build_failed_diagnostics
|
|
429
|
-
failures =
|
|
484
|
+
failures = @snapshots[:definition_build_failures]
|
|
430
485
|
return [] if failures.nil? || failures.empty?
|
|
431
486
|
|
|
432
487
|
[build_rbs_definition_build_failed_diagnostic(failures)]
|
|
@@ -445,14 +500,14 @@ module Rigor
|
|
|
445
500
|
# surface, no signature file is skipped, the environment builds. That is why this sits LAST on the
|
|
446
501
|
# ladder, after its two `rbs.coverage.*` siblings above.
|
|
447
502
|
def rbs_hkt_scan_failed_diagnostics
|
|
448
|
-
failure =
|
|
503
|
+
failure = @snapshots[:hkt_scan_failure]
|
|
449
504
|
return [] if failure.nil?
|
|
450
505
|
|
|
451
506
|
[build_rbs_hkt_scan_failed_diagnostic(failure)]
|
|
452
507
|
end
|
|
453
508
|
|
|
454
509
|
def rbs_synthesized_namespace_diagnostics
|
|
455
|
-
synthesized =
|
|
510
|
+
synthesized = @snapshots[:synthesized_namespaces]
|
|
456
511
|
return [] if synthesized.nil? || synthesized.empty?
|
|
457
512
|
|
|
458
513
|
[build_rbs_synthesized_namespace_diagnostic(synthesized)]
|
|
@@ -465,10 +520,12 @@ module Rigor
|
|
|
465
520
|
# typing they are not getting and why, and — unlike the quarantine row this file used to be
|
|
466
521
|
# misreported as — is not sent to remove a declaration the plugin owns.
|
|
467
522
|
def rbs_plugin_signature_stood_down_diagnostics
|
|
468
|
-
standdowns =
|
|
523
|
+
standdowns = @snapshots[:signature_standdowns]
|
|
469
524
|
return [] if standdowns.nil? || standdowns.empty?
|
|
470
525
|
|
|
471
|
-
standdowns.
|
|
526
|
+
members, files = standdowns.partition { |entry| entry[5] == :member }
|
|
527
|
+
files.map { |entry| build_rbs_plugin_signature_stood_down_diagnostic(entry) } +
|
|
528
|
+
members.group_by(&:first).map { |path, rows| build_rbs_plugin_member_stood_down_diagnostic(path, rows) }
|
|
472
529
|
end
|
|
473
530
|
|
|
474
531
|
# Issue #1713 — the other outcome that avoided a definition-build failure: a required-feature-gated
|
|
@@ -476,7 +533,7 @@ module Rigor
|
|
|
476
533
|
# declares — a member, a whole type, or, when nothing narrower built, the directory. One `:info` per
|
|
477
534
|
# directory, naming the declarations that stood down and the files that displaced them.
|
|
478
535
|
def rbs_vendored_signature_stood_down_diagnostics
|
|
479
|
-
standdowns =
|
|
536
|
+
standdowns = @snapshots[:vendored_standdowns]
|
|
480
537
|
return [] if standdowns.nil? || standdowns.empty?
|
|
481
538
|
|
|
482
539
|
standdowns.map { |entry| build_rbs_vendored_signature_stood_down_diagnostic(entry) }
|
|
@@ -498,7 +555,7 @@ module Rigor
|
|
|
498
555
|
# conformance; every analysis path, pooled or degraded, takes the snapshot `synthesized_namespaces`
|
|
499
556
|
# comes from.
|
|
500
557
|
def conforms_to_diagnostics
|
|
501
|
-
results =
|
|
558
|
+
results = @snapshots[:conformance_results]
|
|
502
559
|
return [] if results.nil? || results.empty?
|
|
503
560
|
|
|
504
561
|
results.map { |record| build_conformance_diagnostic(record) }
|
|
@@ -570,7 +627,7 @@ module Rigor
|
|
|
570
627
|
sample = quarantined.first(sample_size).map { |path, _first_line| relative_signature_path(path) }
|
|
571
628
|
suffix = quarantined.size > sample_size ? ", and #{quarantined.size - sample_size} more" : ""
|
|
572
629
|
Diagnostic.new(
|
|
573
|
-
path:
|
|
630
|
+
path: @configuration.config_display_path,
|
|
574
631
|
line: 1,
|
|
575
632
|
column: 1,
|
|
576
633
|
message: "#{quarantined.size} RBS file(s) under `signature_paths:` were SKIPPED " \
|
|
@@ -593,7 +650,7 @@ module Rigor
|
|
|
593
650
|
suffix = files.size > sample_size ? ", and #{files.size - sample_size} more" : ""
|
|
594
651
|
conflicts = sample.empty? ? "" : " Conflicting signature file(s): #{sample.join(', ')}#{suffix}."
|
|
595
652
|
Diagnostic.new(
|
|
596
|
-
path:
|
|
653
|
+
path: @configuration.config_display_path,
|
|
597
654
|
line: 1,
|
|
598
655
|
column: 1,
|
|
599
656
|
message: "The RBS environment failed to build (#{error_class}): #{first_line}.#{conflicts} " \
|
|
@@ -630,9 +687,9 @@ module Rigor
|
|
|
630
687
|
failures = failures.sort_by { |failure| failure.first.to_s }
|
|
631
688
|
sample_size = 5
|
|
632
689
|
files = failures.flat_map { |failure| Array(failure[3]) }
|
|
633
|
-
.map { |name|
|
|
690
|
+
.map { |name| signature_source_label(name.to_s) }.uniq.sort
|
|
634
691
|
Diagnostic.new(
|
|
635
|
-
path:
|
|
692
|
+
path: @configuration.config_display_path,
|
|
636
693
|
line: 1,
|
|
637
694
|
column: 1,
|
|
638
695
|
message: "#{failures.size} RBS class definition(s) failed to build: " \
|
|
@@ -641,32 +698,120 @@ module Rigor
|
|
|
641
698
|
"Rigor still treats each class as KNOWN, so calls into it — real methods and typos " \
|
|
642
699
|
"alike — silently read `Dynamic[top]` instead of resolving, and this run is quieter " \
|
|
643
700
|
"than it should be rather than cleaner. #{definition_build_advice(failures.first)}",
|
|
644
|
-
severity: :warning,
|
|
701
|
+
severity: selected_core_failure?(failures) ? :error : :warning,
|
|
645
702
|
rule: "rbs.coverage.definition-build-failed",
|
|
646
703
|
source_family: :builtin
|
|
647
704
|
)
|
|
648
705
|
end
|
|
649
706
|
|
|
707
|
+
# Issue #2517 — a class that does not build from the selected `core_root:` alone is that explicit choice
|
|
708
|
+
# failing, not a Rigor release disagreeing with the user's `sig/`, so it is an error. A failure that also
|
|
709
|
+
# names a file outside the core (a project `sig/` collision) keeps the warning it has without one.
|
|
710
|
+
def selected_core_failure?(failures)
|
|
711
|
+
core_root = @configuration.core_root
|
|
712
|
+
return false if core_root.nil?
|
|
713
|
+
|
|
714
|
+
prefix = File.join(core_root, "")
|
|
715
|
+
failures.any? do |failure|
|
|
716
|
+
buffers = Array(failure[3]).map(&:to_s)
|
|
717
|
+
!buffers.empty? && buffers.all? { |name| name.start_with?(prefix) }
|
|
718
|
+
end
|
|
719
|
+
end
|
|
720
|
+
|
|
650
721
|
# The closing advice follows the FIRST failure's error class: `GenericParameterMismatchError` is two
|
|
651
722
|
# declarations of one CLASS at different generic arity (#610); `NoTypeFoundError` (issue #997) is
|
|
652
723
|
# ONE declaration naming a type that does not exist, which "remove the duplicate declaration" sends
|
|
653
724
|
# its reader after a duplicate that is not there — the fifth tuple element
|
|
654
|
-
# ({RbsLoader#unresolved_type_name_detail}) is non-nil for exactly that case.
|
|
655
|
-
#
|
|
656
|
-
#
|
|
725
|
+
# ({RbsLoader#unresolved_type_name_detail}) is non-nil for exactly that case. Issue #2440 — a
|
|
726
|
+
# duplicated instance variable, a superclass mismatch, a missing superclass and a type applied to
|
|
727
|
+
# the wrong arguments each get their own sentence, and when a `virtual:` (inline RBS) buffer is
|
|
728
|
+
# among the colliding sources the advice never tells the reader to remove it as if it were a file.
|
|
729
|
+
# Every other error class (the two duplicated-definition errors, `RecursiveAncestorError`, …) keeps
|
|
730
|
+
# the duplicate-declaration wording, which is accurate for them.
|
|
657
731
|
def definition_build_advice(failure)
|
|
658
|
-
_, error_class,
|
|
659
|
-
|
|
732
|
+
_, error_class, member, buffers, unresolved = failure
|
|
733
|
+
inline = Array(buffers).any? { |name| name.to_s.start_with?("virtual:") }
|
|
734
|
+
case error_class.to_s.split("::").last
|
|
735
|
+
when "GenericParameterMismatchError"
|
|
660
736
|
"Two signature sources declare the class with a different number of type parameters; make " \
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
737
|
+
"the declarations agree (`rbs validate`) to restore type coverage."
|
|
738
|
+
when "InstanceVariableDuplicationError" then variable_duplication_advice("instance variable", failure)
|
|
739
|
+
when "ClassInstanceVariableDuplicationError"
|
|
740
|
+
variable_duplication_advice("class instance variable", failure)
|
|
741
|
+
when "SuperclassMismatchError" then superclass_mismatch_advice(inline)
|
|
742
|
+
when "NoSuperclassFoundError" then no_superclass_advice(member)
|
|
743
|
+
when "InvalidTypeApplicationError" then invalid_type_application_advice(member)
|
|
664
744
|
else
|
|
745
|
+
return unresolved_type_name_advice(unresolved) if unresolved
|
|
746
|
+
|
|
665
747
|
"Two signature sources declare the same member; remove the duplicate declaration " \
|
|
666
748
|
"(`rbs validate`) to restore type coverage."
|
|
667
749
|
end
|
|
668
750
|
end
|
|
669
751
|
|
|
752
|
+
# The sixth tuple slot ({RbsLoader#variable_mixin_count}) is set only when the failing class mixes in
|
|
753
|
+
# the variable's owner at least twice and the owner declares it once: rbs counts the variable once per
|
|
754
|
+
# mixin. Otherwise — a variable duplicated in the owner itself, inherited or not — the wording follows
|
|
755
|
+
# which sources collide: inline only, inline and a file, two files, or one file declaring it twice.
|
|
756
|
+
def variable_duplication_advice(noun, failure)
|
|
757
|
+
class_name, _, member, buffers, _, mixins = failure
|
|
758
|
+
if mixins.is_a?(Integer) && mixins >= 2
|
|
759
|
+
return mixin_variable_duplication_advice(noun, class_name.to_s.delete_prefix("::"),
|
|
760
|
+
member.to_s.delete_prefix("::"))
|
|
761
|
+
end
|
|
762
|
+
|
|
763
|
+
names = Array(buffers).map(&:to_s)
|
|
764
|
+
inline = names.count { |name| name.start_with?("virtual:") }
|
|
765
|
+
if inline >= 2 && inline == names.size
|
|
766
|
+
"Two inline `# @rbs` annotations declare the same #{noun} in one class, and RBS rejects the " \
|
|
767
|
+
"pair even when the types agree; keep one of them to restore type coverage."
|
|
768
|
+
elsif inline.positive?
|
|
769
|
+
"The same #{noun} is declared twice in one class, at least once by an inline `# @rbs` " \
|
|
770
|
+
"annotation, and RBS rejects the pair even when the types agree. Keep one declaration: " \
|
|
771
|
+
"regenerate the committed `.rbs` (`rbs-inline --output`) or remove its copy of the " \
|
|
772
|
+
"variable, or drop the annotation from the `.rb` file, to restore type coverage."
|
|
773
|
+
elsif names.size >= 2
|
|
774
|
+
"Two signature files declare the same #{noun} in one class, and RBS rejects the pair even " \
|
|
775
|
+
"when the types agree; keep one declaration (`rbs validate`) to restore type coverage."
|
|
776
|
+
else
|
|
777
|
+
"The same #{noun} is declared twice in one class, and RBS rejects the pair even when the " \
|
|
778
|
+
"types agree; keep one declaration (`rbs validate`) to restore type coverage."
|
|
779
|
+
end
|
|
780
|
+
end
|
|
781
|
+
|
|
782
|
+
def mixin_variable_duplication_advice(noun, klass, owner)
|
|
783
|
+
"`#{klass}` mixes in `#{owner}` (`include`, `extend` or `prepend`) more than once, in one " \
|
|
784
|
+
"declaration or across several, and RBS counts each #{noun} `#{owner}` declares once per mixin. " \
|
|
785
|
+
"Keep a single mixin of `#{owner}` in `#{klass}` (a committed `rbs-inline --output` file and the " \
|
|
786
|
+
"`.rb` file it came from count as two declarations) to restore type coverage."
|
|
787
|
+
end
|
|
788
|
+
|
|
789
|
+
def superclass_mismatch_advice(inline)
|
|
790
|
+
advice = "Two declarations of the class name different superclasses; make them name the same " \
|
|
791
|
+
"one, or leave the superclass off every declaration but one (a reopening needs none), " \
|
|
792
|
+
"to restore type coverage."
|
|
793
|
+
return advice unless inline
|
|
794
|
+
|
|
795
|
+
"#{advice} Where one side is an inline annotation, fix the annotation and regenerate the " \
|
|
796
|
+
"committed `.rbs` (`rbs-inline --output`), or remove the committed copy."
|
|
797
|
+
end
|
|
798
|
+
|
|
799
|
+
def no_superclass_advice(member)
|
|
800
|
+
name = member.to_s.delete_prefix("::")
|
|
801
|
+
subject = name.empty? ? "A superclass" : "`#{name}`"
|
|
802
|
+
"#{subject} is named as a superclass, but no loaded signature declares it; declare it in your " \
|
|
803
|
+
"`sig/` (or load the library that does through `libraries:`), or re-run `rigor sig-gen` if " \
|
|
804
|
+
"the signature was generated, to restore type coverage."
|
|
805
|
+
end
|
|
806
|
+
|
|
807
|
+
def invalid_type_application_advice(member)
|
|
808
|
+
name = member.to_s.delete_prefix("::")
|
|
809
|
+
subject = name.empty? ? "a type" : "`#{name}`"
|
|
810
|
+
"A signature applies #{subject} with the wrong number of type arguments, or applies them to the " \
|
|
811
|
+
"wrong class; match the arguments to the type parameters the class declares (`rbs validate`) " \
|
|
812
|
+
"to restore type coverage."
|
|
813
|
+
end
|
|
814
|
+
|
|
670
815
|
# Issue #997 — `unresolved` is {RbsLoader#unresolved_type_name_detail}'s `[token, location,
|
|
671
816
|
# refinement_hint]`. `refinement_hint` turns the message into a fix: the token is not a typo to
|
|
672
817
|
# chase down but the start of a Rigor refinement name that is not valid in an RBS type position, and
|
|
@@ -741,7 +886,7 @@ module Rigor
|
|
|
741
886
|
frame_clause = relative_frame ? " at #{relative_frame}" : ""
|
|
742
887
|
raised = "(#{error_class}): #{first_line}#{frame_clause}."
|
|
743
888
|
Diagnostic.new(
|
|
744
|
-
path:
|
|
889
|
+
path: @configuration.config_display_path,
|
|
745
890
|
line: 1,
|
|
746
891
|
column: 1,
|
|
747
892
|
message: stage == :overlay ? hkt_overlay_failed_message(raised) : hkt_scan_failed_message(raised),
|
|
@@ -777,6 +922,15 @@ module Rigor
|
|
|
777
922
|
end
|
|
778
923
|
|
|
779
924
|
# The absolute path is what the loader records; the user thinks in project-relative terms.
|
|
925
|
+
# Issue #2440 — a `virtual:<plugin>:<path>` buffer is named by the `.rb` file it was synthesized
|
|
926
|
+
# from, which is the file the user can open; the plugin id says how it became RBS.
|
|
927
|
+
def signature_source_label(name)
|
|
928
|
+
prefix, plugin_id, path = name.split(":", 3)
|
|
929
|
+
return relative_signature_path(name) unless prefix == "virtual" && plugin_id && path && !path.empty?
|
|
930
|
+
|
|
931
|
+
"#{relative_signature_path(path)} (inline RBS via #{plugin_id})"
|
|
932
|
+
end
|
|
933
|
+
|
|
780
934
|
def relative_signature_path(path)
|
|
781
935
|
root = "#{Dir.pwd}#{File::SEPARATOR}"
|
|
782
936
|
path.start_with?(root) ? path.delete_prefix(root) : path
|
|
@@ -787,7 +941,7 @@ module Rigor
|
|
|
787
941
|
sample = synthesized.first(sample_size)
|
|
788
942
|
suffix = synthesized.size > sample_size ? ", and #{synthesized.size - sample_size} more" : ""
|
|
789
943
|
Diagnostic.new(
|
|
790
|
-
path:
|
|
944
|
+
path: @configuration.config_display_path,
|
|
791
945
|
line: 1,
|
|
792
946
|
column: 1,
|
|
793
947
|
message: "#{synthesized.size} RBS namespace(s) under `signature_paths:` are " \
|
|
@@ -806,7 +960,7 @@ module Rigor
|
|
|
806
960
|
path, class_name, existing_arity, incoming_arity, existing_file = entry
|
|
807
961
|
displaced_by = displacing_source_phrase(existing_file)
|
|
808
962
|
Diagnostic.new(
|
|
809
|
-
path:
|
|
963
|
+
path: @configuration.config_display_path,
|
|
810
964
|
line: 1,
|
|
811
965
|
column: 1,
|
|
812
966
|
message: "`#{relative_signature_path(path.to_s)}` (a signature file a plugin contributes) declares " \
|
|
@@ -824,10 +978,37 @@ module Rigor
|
|
|
824
978
|
)
|
|
825
979
|
end
|
|
826
980
|
|
|
981
|
+
# Issue #2422 — one plugin signature file that loaded without the declarations another source also makes,
|
|
982
|
+
# naming each (sampled) with the file whose declaration was used instead. One row per file, not per
|
|
983
|
+
# declaration: an `rbs collection install` of a gem can overlap the plugin for it on hundreds. A method
|
|
984
|
+
# that composed with the other source's as an overload is not here; the plugin's overloads still bind.
|
|
985
|
+
# The wording covers a superclass a plugin's class header gave up (#2439) as well as a member.
|
|
986
|
+
def build_rbs_plugin_member_stood_down_diagnostic(path, rows)
|
|
987
|
+
labels = rows.map do |_path, declaration, _, _, cause_file|
|
|
988
|
+
cause = cause_file.nil? || cause_file.empty? ? "" : " (#{relative_signature_path(cause_file.to_s)})"
|
|
989
|
+
"`#{declaration}`#{cause}"
|
|
990
|
+
end
|
|
991
|
+
Diagnostic.new(
|
|
992
|
+
path: @configuration.config_display_path,
|
|
993
|
+
line: 1,
|
|
994
|
+
column: 1,
|
|
995
|
+
message: "`#{relative_signature_path(path.to_s)}` (a signature file a plugin contributes) loaded without " \
|
|
996
|
+
"#{rows.size} declaration(s) another signature source already makes: #{sampled(labels, 10)}. " \
|
|
997
|
+
"Conflicting declarations (two of one method or constant, or two different superclasses " \
|
|
998
|
+
"of one class) fail the build, so the plugin's stood down and the other source's, named in " \
|
|
999
|
+
"parentheses, is used; the rest of the plugin's file still " \
|
|
1000
|
+
"loads. Nothing to fix unless you want the plugin's typing back, which needs that source to " \
|
|
1001
|
+
"stop declaring it.",
|
|
1002
|
+
severity: :info,
|
|
1003
|
+
rule: "rbs.coverage.plugin-signature-stood-down",
|
|
1004
|
+
source_family: :builtin
|
|
1005
|
+
)
|
|
1006
|
+
end
|
|
1007
|
+
|
|
827
1008
|
def build_rbs_vendored_signature_stood_down_diagnostic(entry)
|
|
828
1009
|
dir, declarations, whole = entry
|
|
829
1010
|
Diagnostic.new(
|
|
830
|
-
path:
|
|
1011
|
+
path: @configuration.config_display_path,
|
|
831
1012
|
line: 1,
|
|
832
1013
|
column: 1,
|
|
833
1014
|
message: vendored_standdown_message(dir, declarations, whole),
|
|
@@ -906,7 +1087,7 @@ module Rigor
|
|
|
906
1087
|
sample = missing.first(sample_size).map(&:gem_name)
|
|
907
1088
|
suffix = missing.size > sample_size ? ", and #{missing.size - sample_size} more" : ""
|
|
908
1089
|
Diagnostic.new(
|
|
909
|
-
path:
|
|
1090
|
+
path: @configuration.config_display_path,
|
|
910
1091
|
line: 1,
|
|
911
1092
|
column: 1,
|
|
912
1093
|
message: "#{missing.size} gem(s) in Gemfile.lock have no RBS available: " \
|
|
@@ -936,9 +1117,12 @@ module Rigor
|
|
|
936
1117
|
# all three cross the pool drain channel (see {RbsExtended::Reporter}); an entry with no position
|
|
937
1118
|
# falls back to `.rigor.yml`-style file-level attribution.
|
|
938
1119
|
def rbs_extended_reporter_diagnostics
|
|
939
|
-
|
|
1120
|
+
unresolved_payload_diagnostics + lossy_projection_diagnostics + hkt_directive_diagnostics +
|
|
1121
|
+
deprecated_form_diagnostics
|
|
1122
|
+
end
|
|
940
1123
|
|
|
941
|
-
|
|
1124
|
+
def unresolved_payload_diagnostics
|
|
1125
|
+
@rbs_extended_reporter.unresolved_payloads.map do |entry|
|
|
942
1126
|
build_positioned_reporter_diagnostic(
|
|
943
1127
|
entry,
|
|
944
1128
|
rule: "dynamic.rbs-extended.unresolved",
|
|
@@ -947,8 +1131,10 @@ module Rigor
|
|
|
947
1131
|
"that contributes the referenced type vocabulary."
|
|
948
1132
|
)
|
|
949
1133
|
end
|
|
1134
|
+
end
|
|
950
1135
|
|
|
951
|
-
|
|
1136
|
+
def lossy_projection_diagnostics
|
|
1137
|
+
@rbs_extended_reporter.lossy_projections.map do |entry|
|
|
952
1138
|
build_positioned_reporter_diagnostic(
|
|
953
1139
|
entry,
|
|
954
1140
|
rule: "dynamic.shape.lossy-projection",
|
|
@@ -957,8 +1143,6 @@ module Rigor
|
|
|
957
1143
|
"a `HashShape` / `Tuple` carrier or accept the unchanged result."
|
|
958
1144
|
)
|
|
959
1145
|
end
|
|
960
|
-
|
|
961
|
-
unresolved + lossy + hkt_directive_diagnostics + deprecated_form_diagnostics
|
|
962
1146
|
end
|
|
963
1147
|
|
|
964
1148
|
# ADR-109 WD3 — one row per annotation still written in a spelling the grammar accepts but no
|
|
@@ -1069,7 +1253,7 @@ module Rigor
|
|
|
1069
1253
|
|
|
1070
1254
|
@boundary_cross_reporter.entries.map do |entry|
|
|
1071
1255
|
Diagnostic.new(
|
|
1072
|
-
path:
|
|
1256
|
+
path: @configuration.config_display_path, line: 1, column: 1,
|
|
1073
1257
|
message: "`#{entry.class_name}##{entry.method_name}` is contributed by both " \
|
|
1074
1258
|
"RBS (#{entry.rbs_display}) and the `mode: :full` opt-in gem " \
|
|
1075
1259
|
"`#{entry.gem_name}`. RBS wins on dispatch; verify the gem source " \
|
|
@@ -1196,7 +1380,7 @@ module Rigor
|
|
|
1196
1380
|
|
|
1197
1381
|
def run_disclosure_diagnostic(record)
|
|
1198
1382
|
Diagnostic.new(
|
|
1199
|
-
path:
|
|
1383
|
+
path: @configuration.config_display_path, line: 1, column: 1,
|
|
1200
1384
|
message: record.fetch(:message),
|
|
1201
1385
|
severity: record.fetch(:severity),
|
|
1202
1386
|
rule: record.fetch(:rule),
|
|
@@ -1239,7 +1423,7 @@ module Rigor
|
|
|
1239
1423
|
def plugin_trust_refusal_diagnostic(plugin, summary)
|
|
1240
1424
|
plugin_id = plugin.manifest.id
|
|
1241
1425
|
Diagnostic.new(
|
|
1242
|
-
path:
|
|
1426
|
+
path: @configuration.config_display_path, line: 1, column: 1,
|
|
1243
1427
|
message: "plugin #{plugin_id.inspect} had #{summary[:count]} read(s) refused by the trust " \
|
|
1244
1428
|
"policy; first refused path: #{summary[:first_path].inspect}, outside read root " \
|
|
1245
1429
|
"#{summary[:nearest_root].inspect}. Spell the path the way that read root spells it " \
|
|
@@ -1330,38 +1514,6 @@ module Rigor
|
|
|
1330
1514
|
def pre_eval_diagnostics_from_scanner
|
|
1331
1515
|
@pre_eval_diagnostics_from_scanner_reader.call
|
|
1332
1516
|
end
|
|
1333
|
-
|
|
1334
|
-
def synthesized_namespaces_snapshot
|
|
1335
|
-
@synthesized_namespaces_snapshot_reader.call
|
|
1336
|
-
end
|
|
1337
|
-
|
|
1338
|
-
def quarantined_signatures_snapshot
|
|
1339
|
-
@quarantined_signatures_snapshot_reader.call
|
|
1340
|
-
end
|
|
1341
|
-
|
|
1342
|
-
def signature_standdowns_snapshot
|
|
1343
|
-
@signature_standdowns_snapshot_reader.call
|
|
1344
|
-
end
|
|
1345
|
-
|
|
1346
|
-
def vendored_standdowns_snapshot
|
|
1347
|
-
@vendored_standdowns_snapshot_reader.call
|
|
1348
|
-
end
|
|
1349
|
-
|
|
1350
|
-
def env_build_failure_snapshot
|
|
1351
|
-
@env_build_failure_snapshot_reader.call
|
|
1352
|
-
end
|
|
1353
|
-
|
|
1354
|
-
def definition_build_failures_snapshot
|
|
1355
|
-
@definition_build_failures_snapshot_reader.call
|
|
1356
|
-
end
|
|
1357
|
-
|
|
1358
|
-
def hkt_scan_failure_snapshot
|
|
1359
|
-
@hkt_scan_failure_snapshot_reader.call
|
|
1360
|
-
end
|
|
1361
|
-
|
|
1362
|
-
def conformance_results_snapshot
|
|
1363
|
-
@conformance_results_snapshot_reader.call
|
|
1364
|
-
end
|
|
1365
1517
|
end
|
|
1366
1518
|
end
|
|
1367
1519
|
end
|