rigortype 0.3.7 → 0.3.9
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 +1 -1
- data/data/capability_roles/capability_roles.rbs +36 -0
- data/data/gem_overlay/activesupport/core_ext.rbs +109 -13
- data/docs/handbook/02-everyday-types.md +17 -14
- data/docs/handbook/03-narrowing.md +37 -4
- data/docs/handbook/05-methods-and-blocks.md +1 -1
- data/docs/handbook/06-classes.md +2 -2
- data/docs/handbook/07-rbs-and-extended.md +14 -1
- data/docs/handbook/11-sig-gen.md +96 -15
- data/docs/handbook/README.md +1 -1
- data/docs/handbook/appendix-elixir.md +2 -2
- data/docs/handbook/appendix-go.md +2 -2
- data/docs/handbook/appendix-java-csharp.md +2 -2
- data/docs/handbook/appendix-mypy.md +2 -2
- data/docs/handbook/appendix-phpstan.md +1 -1
- data/docs/handbook/appendix-rust.md +1 -1
- data/docs/handbook/appendix-type-theory.md +4 -4
- data/docs/handbook/appendix-typescript.md +1 -1
- data/docs/llms.txt +2 -0
- data/docs/manual/02-cli-reference.md +39 -4
- data/docs/manual/03-configuration.md +11 -0
- data/docs/manual/04-diagnostics.md +12 -1
- data/docs/manual/07-plugins.md +15 -5
- data/docs/manual/08-skills.md +23 -2
- data/docs/manual/11-ci.md +9 -0
- data/docs/manual/15-type-protection-coverage.md +8 -0
- data/docs/manual/16-rbs-extended-annotations.md +6 -1
- data/docs/manual/18-removing-dead-code.md +10 -8
- data/docs/manual/plugins/rigor-actionpack.md +18 -0
- data/docs/manual/plugins/rigor-activerecord.md +28 -0
- data/docs/manual/plugins/rigor-activesupport-core-ext.md +32 -2
- data/docs/manual/plugins/rigor-rbs-inline.md +42 -1
- data/lib/rigor/analysis/baseline.rb +2 -2
- data/lib/rigor/analysis/check_rules/always_truthy_condition_collector.rb +1 -1
- data/lib/rigor/analysis/check_rules/dead_version_guard_arms.rb +1 -5
- data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +10 -2
- data/lib/rigor/analysis/check_rules/main_pass_collector.rb +1 -1
- data/lib/rigor/analysis/check_rules/published_constant_guard.rb +15 -6
- data/lib/rigor/analysis/check_rules/rule_ids.rb +1 -1
- data/lib/rigor/analysis/check_rules/rule_walk.rb +39 -4
- data/lib/rigor/analysis/check_rules/self_closedness_scanner.rb +1 -1
- data/lib/rigor/analysis/check_rules/shadowed_rescue_collector.rb +1 -1
- data/lib/rigor/analysis/check_rules/unreachable_clause_collector.rb +2 -2
- data/lib/rigor/analysis/check_rules/void_value_use_collector.rb +0 -1
- data/lib/rigor/analysis/check_rules.rb +200 -32
- data/lib/rigor/analysis/crash_signature.rb +69 -13
- data/lib/rigor/analysis/dependency_source_inference/boundary_cross_reporter.rb +1 -1
- data/lib/rigor/analysis/dependency_source_inference/builder.rb +0 -2
- data/lib/rigor/analysis/dependency_source_inference/gem_resolver.rb +0 -2
- data/lib/rigor/analysis/dependency_source_inference/index.rb +5 -5
- data/lib/rigor/analysis/dependency_source_inference/return_type_heuristic.rb +1 -2
- data/lib/rigor/analysis/dependency_source_inference/walker.rb +4 -4
- data/lib/rigor/analysis/effects_cache_probe.rb +3 -4
- data/lib/rigor/analysis/erb_template_detector.rb +1 -2
- data/lib/rigor/analysis/fact_store.rb +6 -1
- data/lib/rigor/analysis/incremental.rb +16 -0
- data/lib/rigor/analysis/incremental_session.rb +100 -29
- data/lib/rigor/analysis/plugin_fact_fingerprint.rb +0 -1
- data/lib/rigor/analysis/reachability/graph.rb +3 -5
- data/lib/rigor/analysis/reachability/plugin_roots.rb +6 -5
- data/lib/rigor/analysis/reachability/project_files.rb +2 -2
- data/lib/rigor/analysis/reachability/scan.rb +5 -5
- data/lib/rigor/analysis/reachability/scan_cache.rb +2 -2
- data/lib/rigor/analysis/reachability/signature_scan.rb +2 -2
- data/lib/rigor/analysis/result.rb +1 -3
- data/lib/rigor/analysis/rule_catalog.rb +4 -1
- data/lib/rigor/analysis/run_cache_key.rb +1 -1
- data/lib/rigor/analysis/run_cache_probe.rb +3 -5
- data/lib/rigor/analysis/runner/buffer_pool_dispatcher.rb +6 -8
- data/lib/rigor/analysis/runner/declaration_position.rb +1 -2
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +316 -40
- data/lib/rigor/analysis/runner/effect_annotation_residual_pass.rb +2 -3
- data/lib/rigor/analysis/runner/effect_envelope_pass.rb +9 -10
- data/lib/rigor/analysis/runner/pool_coordinator.rb +430 -77
- data/lib/rigor/analysis/runner/project_pre_passes.rb +12 -6
- data/lib/rigor/analysis/runner/run_snapshots.rb +13 -3
- data/lib/rigor/analysis/runner.rb +200 -43
- data/lib/rigor/analysis/worker_session.rb +36 -12
- data/lib/rigor/bleeding_edge.rb +12 -24
- data/lib/rigor/builtins/hkt_builtins.rb +2 -2
- data/lib/rigor/builtins/imported_refinements.rb +166 -30
- data/lib/rigor/builtins/predefined_constant_refinements.rb +5 -7
- data/lib/rigor/builtins/regex_refinement.rb +4 -4
- data/lib/rigor/builtins/static_return_refinements.rb +5 -6
- data/lib/rigor/cache/annotation_location.rb +70 -0
- data/lib/rigor/cache/descriptor.rb +58 -20
- data/lib/rigor/cache/engine_source.rb +4 -4
- data/lib/rigor/cache/file_digest.rb +9 -1
- data/lib/rigor/cache/incremental_snapshot.rb +40 -6
- data/lib/rigor/cache/rbs_class_ancestor_table.rb +0 -3
- data/lib/rigor/cache/rbs_class_type_param_names.rb +0 -3
- data/lib/rigor/cache/rbs_constant_table.rb +0 -3
- data/lib/rigor/cache/rbs_descriptor.rb +79 -11
- data/lib/rigor/cache/rbs_environment.rb +8 -4
- data/lib/rigor/cache/rbs_environment_marshal_patch.rb +39 -0
- data/lib/rigor/cache/rbs_known_class_names.rb +0 -3
- data/lib/rigor/cache/store.rb +85 -33
- data/lib/rigor/cli/annotate_command.rb +5 -6
- data/lib/rigor/cli/check_command.rb +57 -10
- data/lib/rigor/cli/check_invocation.rb +6 -11
- data/lib/rigor/cli/check_runner_factory.rb +1 -5
- data/lib/rigor/cli/coverage_command.rb +1 -1
- data/lib/rigor/cli/coverage_mutation.rb +12 -3
- data/lib/rigor/cli/coverage_scan.rb +1 -5
- data/lib/rigor/cli/diff_command.rb +1 -1
- data/lib/rigor/cli/doc_links.rb +3 -3
- data/lib/rigor/cli/docs_command.rb +2 -2
- data/lib/rigor/cli/doctor_command.rb +85 -38
- data/lib/rigor/cli/effects_command.rb +2 -2
- data/lib/rigor/cli/effects_diff_renderer.rb +3 -3
- data/lib/rigor/cli/effects_snapshot_command.rb +1 -1
- data/lib/rigor/cli/explain_command.rb +34 -1
- data/lib/rigor/cli/fused_protection_report.rb +7 -1
- data/lib/rigor/cli/lsp_command.rb +1 -1
- data/lib/rigor/cli/mcp_command.rb +1 -1
- data/lib/rigor/cli/measurement_integrity_warning.rb +4 -5
- data/lib/rigor/cli/mutation_fork_scan.rb +6 -6
- data/lib/rigor/cli/mutation_protection_report.rb +7 -1
- data/lib/rigor/cli/plugin_command.rb +1 -1
- data/lib/rigor/cli/plugins_command.rb +2 -1
- data/lib/rigor/cli/prism_colorizer.rb +2 -2
- data/lib/rigor/cli/protection_fork_scan.rb +6 -6
- data/lib/rigor/cli/show_bleedingedge_command.rb +1 -1
- data/lib/rigor/cli/sig_gen_command.rb +31 -2
- data/lib/rigor/cli/skill_command.rb +1 -1
- data/lib/rigor/cli/skill_deep_probe.rb +4 -4
- data/lib/rigor/cli/skill_describe.rb +36 -35
- data/lib/rigor/cli/trace_command.rb +4 -4
- data/lib/rigor/cli/trace_renderer.rb +5 -6
- data/lib/rigor/cli/triage_command.rb +1 -1
- data/lib/rigor/cli/type_of_command.rb +10 -6
- data/lib/rigor/cli/type_scan_command.rb +4 -4
- data/lib/rigor/cli/unused_command.rb +11 -3
- data/lib/rigor/cli/upgrade_command.rb +1 -1
- data/lib/rigor/cli.rb +68 -6
- data/lib/rigor/config_audit.rb +30 -5
- data/lib/rigor/configuration/severity_profile.rb +6 -6
- data/lib/rigor/configuration.rb +43 -4
- data/lib/rigor/effects/attribution.rb +1 -3
- data/lib/rigor/effects/config_envelopes.rb +6 -8
- data/lib/rigor/effects/definition_lines.rb +25 -6
- data/lib/rigor/effects/effect_table.rb +0 -1
- data/lib/rigor/effects/entry_points.rb +0 -2
- data/lib/rigor/effects/envelope_check.rb +8 -8
- data/lib/rigor/effects/envelope_index.rb +5 -8
- data/lib/rigor/effects/framework_units.rb +4 -6
- data/lib/rigor/effects/identity.rb +4 -6
- data/lib/rigor/effects/inline_anchor.rb +7 -7
- data/lib/rigor/effects/label_intent.rb +3 -4
- data/lib/rigor/effects/liskov_check.rb +8 -8
- data/lib/rigor/effects/method_key.rb +1 -1
- data/lib/rigor/effects/plugin_facts.rb +4 -6
- data/lib/rigor/effects/propagator.rb +2 -3
- data/lib/rigor/effects/scanner.rb +1 -1
- data/lib/rigor/effects/signature_sources.rb +3 -5
- data/lib/rigor/effects/snapshot.rb +10 -10
- data/lib/rigor/effects/snapshot_diff.rb +1 -1
- data/lib/rigor/effects/unit_scan.rb +10 -10
- data/lib/rigor/effects/unknown_label_check.rb +3 -8
- data/lib/rigor/effects/unknown_label_report.rb +3 -4
- data/lib/rigor/environment/bundle_sig_discovery.rb +6 -6
- data/lib/rigor/environment/class_registry.rb +3 -1
- data/lib/rigor/environment/failure_slot.rb +28 -0
- data/lib/rigor/environment/installed_gem_set.rb +85 -0
- data/lib/rigor/environment/lockfile_resolver.rb +51 -4
- data/lib/rigor/environment/missing_gem_constant_index.rb +4 -4
- data/lib/rigor/environment/rbs_collection_discovery.rb +5 -5
- data/lib/rigor/environment/rbs_coverage_report.rb +5 -5
- data/lib/rigor/environment/rbs_hierarchy.rb +3 -1
- data/lib/rigor/environment/rbs_loader.rb +613 -113
- data/lib/rigor/environment.rb +189 -27
- data/lib/rigor/flow_contribution/merger.rb +0 -2
- data/lib/rigor/flow_contribution.rb +11 -13
- data/lib/rigor/inference/acceptance.rb +153 -8
- data/lib/rigor/inference/block_parameter_binder.rb +2 -3
- data/lib/rigor/inference/body_fixpoint.rb +5 -5
- data/lib/rigor/inference/budget_trace.rb +1 -5
- data/lib/rigor/inference/captured_locals.rb +2 -3
- data/lib/rigor/inference/closure_escape_analyzer.rb +2 -4
- data/lib/rigor/inference/coverage_scanner.rb +4 -6
- data/lib/rigor/inference/dynamic_origin.rb +1 -1
- data/lib/rigor/inference/element_read_widening.rb +168 -0
- data/lib/rigor/inference/expression_typer.rb +763 -143
- data/lib/rigor/inference/fork_map.rb +5 -7
- data/lib/rigor/inference/hkt_reducer.rb +2 -3
- data/lib/rigor/inference/hkt_registry.rb +19 -10
- data/lib/rigor/inference/hkt_sugar_translator.rb +15 -21
- data/lib/rigor/inference/index_write_widening.rb +1 -5
- data/lib/rigor/inference/macro_block_self_type.rb +1 -4
- data/lib/rigor/inference/method_dispatcher/block_folding.rb +2 -9
- data/lib/rigor/inference/method_dispatcher/cgi_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/constant_folding.rb +305 -19
- data/lib/rigor/inference/method_dispatcher/data_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/file_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/iterator_dispatch.rb +2 -2
- data/lib/rigor/inference/method_dispatcher/json_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/kernel_dispatch.rb +7 -1
- data/lib/rigor/inference/method_dispatcher/math_folding.rb +41 -3
- data/lib/rigor/inference/method_dispatcher/method_folding.rb +2 -5
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +61 -47
- data/lib/rigor/inference/method_dispatcher/random_folding.rb +82 -0
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +165 -31
- data/lib/rigor/inference/method_dispatcher/receiver_affinity.rb +25 -4
- data/lib/rigor/inference/method_dispatcher/reduce_folding.rb +2 -8
- data/lib/rigor/inference/method_dispatcher/regexp_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/set_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/shellwords_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/singleton_mixin_dispatch.rb +1 -2
- data/lib/rigor/inference/method_dispatcher/struct_folding.rb +4 -5
- data/lib/rigor/inference/method_dispatcher/struct_materialization.rb +85 -4
- data/lib/rigor/inference/method_dispatcher/time_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/universal_object_dispatch.rb +1 -2
- data/lib/rigor/inference/method_dispatcher/uri_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher.rb +12 -13
- data/lib/rigor/inference/method_parameter_binder.rb +4 -6
- data/lib/rigor/inference/multi_target_binder.rb +1 -3
- data/lib/rigor/inference/mutation_rejoin.rb +168 -0
- data/lib/rigor/inference/mutation_widening.rb +100 -51
- data/lib/rigor/inference/narrowing.rb +299 -46
- data/lib/rigor/inference/optimistic_origin.rb +1 -7
- data/lib/rigor/inference/origin_lookup.rb +2 -3
- data/lib/rigor/inference/parameter_inference_collector.rb +5 -6
- data/lib/rigor/inference/pre_eval_constants.rb +6 -5
- data/lib/rigor/inference/precision_scanner.rb +3 -4
- data/lib/rigor/inference/project_patched_methods.rb +2 -2
- data/lib/rigor/inference/project_patched_scanner.rb +3 -3
- data/lib/rigor/inference/protection_scanner.rb +1 -2
- data/lib/rigor/inference/range_constant.rb +57 -0
- data/lib/rigor/inference/rbs_type_translator.rb +49 -11
- data/lib/rigor/inference/receiver_alias.rb +3 -3
- data/lib/rigor/inference/refinement_mutation.rb +72 -0
- data/lib/rigor/inference/scope_indexer.rb +688 -151
- data/lib/rigor/inference/statement_evaluator.rb +221 -50
- data/lib/rigor/inference/string_mutation.rb +60 -0
- data/lib/rigor/inference/struct_fold_safety.rb +6 -7
- data/lib/rigor/inference/synthetic_method_index.rb +1 -2
- data/lib/rigor/inference/synthetic_method_scanner.rb +4 -6
- data/lib/rigor/inference/version_guard.rb +28 -21
- data/lib/rigor/inference/void_origin.rb +3 -3
- data/lib/rigor/inference/void_tail_summary.rb +2 -4
- data/lib/rigor/language_server/buffer_table.rb +4 -4
- data/lib/rigor/language_server/completion_provider.rb +1 -1
- data/lib/rigor/language_server/debouncer.rb +1 -1
- data/lib/rigor/language_server/diagnostic_publisher.rb +4 -4
- data/lib/rigor/language_server/document_symbol_provider.rb +1 -1
- data/lib/rigor/language_server/folding_range_provider.rb +1 -1
- data/lib/rigor/language_server/hover_provider.rb +1 -1
- data/lib/rigor/language_server/hover_renderer.rb +2 -2
- data/lib/rigor/language_server/incremental_sync.rb +6 -6
- data/lib/rigor/language_server/project_context.rb +2 -5
- data/lib/rigor/language_server/publish_batcher.rb +2 -2
- data/lib/rigor/language_server/selection_range_provider.rb +2 -2
- data/lib/rigor/language_server/server.rb +9 -9
- data/lib/rigor/language_server/signature_help_provider.rb +1 -1
- data/lib/rigor/language_server/uri.rb +1 -1
- data/lib/rigor/plugin/base.rb +90 -21
- data/lib/rigor/plugin/bundled_catalog.rb +167 -0
- data/lib/rigor/plugin/effect_attribution.rb +7 -7
- data/lib/rigor/plugin/effect_entry_points.rb +3 -3
- data/lib/rigor/plugin/fact_store.rb +6 -6
- data/lib/rigor/plugin/io_boundary.rb +93 -8
- data/lib/rigor/plugin/isolation.rb +29 -6
- data/lib/rigor/plugin/loader.rb +31 -12
- data/lib/rigor/plugin/macro/heredoc_template.rb +1 -1
- data/lib/rigor/plugin/macro/trait_registry.rb +1 -1
- data/lib/rigor/plugin/manifest.rb +23 -1
- data/lib/rigor/plugin/registry.rb +67 -14
- data/lib/rigor/plugin/source_rbs_synthesis_reporter.rb +12 -1
- data/lib/rigor/plugin/trust_policy.rb +2 -4
- data/lib/rigor/plugin/type_node_resolver.rb +3 -3
- data/lib/rigor/plugin_gap_advisory.rb +96 -0
- data/lib/rigor/project_environment.rb +138 -0
- data/lib/rigor/protection/analysis_guard.rb +93 -14
- data/lib/rigor/protection/closure_kill_oracle.rb +67 -23
- data/lib/rigor/protection/dependency_closure.rb +5 -8
- data/lib/rigor/protection/diagnostic_oracle.rb +2 -2
- data/lib/rigor/protection/discovery_seed.rb +11 -11
- data/lib/rigor/protection/kill_signature.rb +2 -4
- data/lib/rigor/protection/measurement_integrity.rb +1 -3
- data/lib/rigor/protection/mutation_cache.rb +6 -9
- data/lib/rigor/protection/mutation_scanner.rb +12 -15
- data/lib/rigor/protection/mutator.rb +2 -1
- data/lib/rigor/protection/test_suite_oracle.rb +5 -5
- data/lib/rigor/rbs_extended/conformance_checker.rb +4 -3
- data/lib/rigor/rbs_extended/envelope_scanner.rb +12 -13
- data/lib/rigor/rbs_extended/hkt_directives.rb +16 -1
- data/lib/rigor/rbs_extended/reporter.rb +122 -16
- data/lib/rigor/rbs_extended.rb +67 -22
- data/lib/rigor/reflection/constant_path.rb +126 -0
- data/lib/rigor/reflection.rb +26 -10
- data/lib/rigor/runtime/jit.rb +6 -8
- data/lib/rigor/scope/discovery_index.rb +30 -0
- data/lib/rigor/scope.rb +203 -4
- data/lib/rigor/sig_gen/generator.rb +181 -102
- data/lib/rigor/sig_gen/layout_index.rb +3 -4
- data/lib/rigor/sig_gen/meta_class_shape.rb +3 -5
- data/lib/rigor/sig_gen/observation_collector.rb +17 -15
- data/lib/rigor/sig_gen/path_mapper.rb +4 -6
- data/lib/rigor/sig_gen/rbs_validity.rb +4 -4
- data/lib/rigor/sig_gen/renderer.rb +17 -11
- data/lib/rigor/sig_gen/skip_reason_catalog.rb +111 -0
- data/lib/rigor/sig_gen/superclass_spelling.rb +27 -0
- data/lib/rigor/sig_gen/type_elaborator.rb +1 -3
- data/lib/rigor/sig_gen/writer.rb +23 -6
- data/lib/rigor/signature_path_audit.rb +153 -6
- data/lib/rigor/source/literals.rb +0 -23
- data/lib/rigor/source/node_children.rb +0 -2
- data/lib/rigor/source/node_locator.rb +5 -11
- data/lib/rigor/source/node_walker.rb +2 -5
- data/lib/rigor/triage/catalogue.rb +1 -3
- data/lib/rigor/triage.rb +3 -5
- data/lib/rigor/type/accepts_result.rb +24 -6
- data/lib/rigor/type/combinator.rb +68 -5
- data/lib/rigor/type/data_class.rb +2 -2
- data/lib/rigor/type/data_instance.rb +4 -4
- data/lib/rigor/type/float_range.rb +128 -0
- data/lib/rigor/type/hash_shape.rb +5 -5
- data/lib/rigor/type/integer_range.rb +13 -8
- data/lib/rigor/type/nominal.rb +8 -2
- data/lib/rigor/type/refined.rb +3 -3
- data/lib/rigor/type/struct_class.rb +3 -3
- data/lib/rigor/type/struct_instance.rb +4 -4
- data/lib/rigor/type.rb +1 -0
- data/lib/rigor/type_node/generic.rb +1 -1
- data/lib/rigor/type_node/range_literal.rb +25 -0
- data/lib/rigor/type_node/resolver_chain.rb +1 -1
- data/lib/rigor/type_node.rb +1 -0
- data/lib/rigor/version.rb +1 -1
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/analyzer.rb +0 -4
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_discoverer.rb +0 -1
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_index.rb +0 -2
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +1 -0
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/analyzer.rb +0 -4
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_discoverer.rb +3 -5
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_index.rb +1 -4
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb +1 -0
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb +33 -30
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_discoverer.rb +0 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_index.rb +1 -3
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +28 -2
- data/plugins/rigor-actionpack/sig/action_controller.rbs +71 -0
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/analyzer.rb +0 -4
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/effects.rb +1 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_discoverer.rb +0 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_index.rb +0 -2
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/recurring_scan.rb +1 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +1 -0
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +3 -4
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_parser.rb +1 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/structure_sql_parser.rb +1 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +42 -7
- data/plugins/rigor-activerecord/sig/active_record/framework.rbs +123 -0
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +1 -0
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb +9 -2
- data/plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs +119 -14
- data/plugins/rigor-devise/lib/rigor/plugin/devise.rb +1 -0
- data/plugins/rigor-dry-monads/lib/rigor/plugin/dry_monads.rb +1 -0
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema/schema_scanner.rb +9 -7
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema.rb +7 -3
- data/plugins/rigor-dry-struct/lib/rigor/plugin/dry_struct.rb +1 -0
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types/alias_scanner.rb +8 -6
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types.rb +11 -7
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation/contract_scanner.rb +13 -11
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation.rb +9 -4
- data/plugins/rigor-ethon/lib/rigor/plugin/ethon.rb +1 -0
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/analyzer.rb +0 -5
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_discoverer.rb +0 -1
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_index.rb +0 -1
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot.rb +8 -1
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi.rb +36 -4
- data/plugins/rigor-ffi-rzmq/lib/rigor/plugin/ffi_rzmq.rb +1 -0
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql/type_scanner.rb +8 -6
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql.rb +6 -3
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami.rb +1 -0
- data/plugins/rigor-mangrove/lib/rigor/plugin/mangrove.rb +2 -1
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest/assertion_analyzer.rb +0 -3
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest.rb +1 -0
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/analyzer.rb +0 -5
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/authorization_scan.rb +2 -2
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_discoverer.rb +0 -1
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_index.rb +0 -1
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit.rb +1 -0
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/analyzer.rb +0 -12
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_index.rb +1 -3
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_loader.rb +0 -1
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n.rb +1 -0
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/acronyms.rb +5 -5
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/analyzer.rb +1 -10
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/devise_routes.rb +3 -3
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/doorkeeper_routes.rb +2 -2
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/grape_api_discoverer.rb +2 -2
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_discoverer.rb +2 -2
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_table.rb +9 -10
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/routes_parser.rb +2 -3
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +1 -0
- data/plugins/rigor-railties/lib/rigor/plugin/railties.rb +1 -0
- data/plugins/rigor-rbnacl/lib/rigor/plugin/rbnacl.rb +13 -1
- data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb +128 -3
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/analyzer.rb +0 -3
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_scope_index.rb +0 -3
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_type_resolver.rb +1 -5
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +2 -3
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec.rb +1 -0
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails/have_http_status_analyzer.rb +0 -3
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails.rb +1 -0
- data/plugins/rigor-sassc/lib/rigor/plugin/sassc.rb +1 -0
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers/analyzer.rb +1 -9
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers.rb +1 -0
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/analyzer.rb +0 -4
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/effects.rb +1 -1
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/schedule_scan.rb +1 -1
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_discoverer.rb +0 -1
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_index.rb +0 -2
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb +1 -0
- data/plugins/rigor-sinatra/lib/rigor/plugin/sinatra.rb +1 -0
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/absurd_recognizer.rb +2 -5
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/assertion_recognizer.rb +1 -4
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog.rb +3 -9
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog_walker.rb +4 -4
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sig_parser.rb +1 -2
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sigil_detector.rb +4 -5
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/type_translator.rb +7 -5
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +5 -5
- data/plugins/rigor-statesman/lib/rigor/plugin/statesman.rb +1 -0
- data/sig/rigor/analysis/reachability/scan_cache.rbs +12 -0
- data/sig/rigor/cache.rbs +2 -3
- data/sig/rigor/environment.rbs +11 -0
- data/sig/rigor/inference.rbs +3 -10
- data/sig/rigor/plugin/io_boundary.rbs +4 -0
- data/sig/rigor/plugin/manifest.rbs +2 -1
- data/sig/rigor/reflection.rbs +3 -1
- data/sig/rigor/scope.rbs +24 -3
- data/sig/rigor/sig_gen/skip_reason_catalog.rbs +14 -0
- data/sig/rigor/type.rbs +27 -1
- data/sig/rigor.rbs +1 -0
- data/skills/rigor-ask/SKILL.md +8 -6
- data/skills/rigor-plugin-author/references/02-walker-and-types.md +13 -2
- data/skills/rigor-project-init/SKILL.md +6 -3
- data/skills/rigor-project-init/references/02-configure.md +10 -6
- data/skills/rigor-project-init/references/06-agent-contract.md +67 -0
- data/skills/rigor-type-oracle/SKILL.md +228 -0
- data/skills/rigor-type-oracle/references/01-oracle-commands.md +261 -0
- data/skills/rigor-type-oracle/references/02-agents-md-fragment.md +52 -0
- data/skills/rigor-type-oracle/references/03-gap-protocol.md +128 -0
- data/skills/rigor-unused-adjudicate/SKILL.md +8 -5
- metadata +28 -3
- data/lib/rigor/cli/probe_environment.rb +0 -85
- data/sig/rigor/inference/builtins/numeric_catalog.rbs +0 -3
|
@@ -35,11 +35,9 @@ module Rigor
|
|
|
35
35
|
:pre_eval_diagnostics_from_scanner
|
|
36
36
|
)
|
|
37
37
|
|
|
38
|
-
# @param
|
|
39
|
-
#
|
|
40
|
-
# @param
|
|
41
|
-
# @param plugin_requirer [#call, nil]
|
|
42
|
-
# @param pool_mode [#call] reader returning the pool-mode flag.
|
|
38
|
+
# @param plugin_requirer — how a plugin gem is brought into the process, called with the gem name; nil
|
|
39
|
+
# lets `Plugin::Loader` apply its own default.
|
|
40
|
+
# @param pool_mode — reader returning the pool-mode flag.
|
|
43
41
|
def initialize(configuration:, cache_store:, buffer:, plugin_requirer:, pool_mode:)
|
|
44
42
|
@configuration = configuration
|
|
45
43
|
@cache_store = cache_store
|
|
@@ -56,7 +54,7 @@ module Rigor
|
|
|
56
54
|
:discovered_classes, :discovered_def_nodes, :discovered_def_nestings,
|
|
57
55
|
:discovered_singleton_def_nodes, :discovered_def_sources, :discovered_singleton_def_sources,
|
|
58
56
|
:discovered_superclasses, :discovered_header_nestings, :discovered_includes,
|
|
59
|
-
:discovered_class_sources, :constant_values, :constant_sources, :constant_writes,
|
|
57
|
+
:discovered_extends, :discovered_class_sources, :constant_values, :constant_sources, :constant_writes,
|
|
60
58
|
:discovered_method_visibilities, :discovered_methods, :data_member_layouts,
|
|
61
59
|
:struct_member_layouts
|
|
62
60
|
)
|
|
@@ -77,6 +75,11 @@ module Rigor
|
|
|
77
75
|
bundle_path: @configuration.bundler_bundle_path,
|
|
78
76
|
auto_detect: @configuration.bundler_auto_detect
|
|
79
77
|
)&.to_s
|
|
78
|
+
# ADR-39 slice 5 / #911 — hand the project's `plugins_isolation:` to the invocation layer before
|
|
79
|
+
# any plugin `#prepare` runs, for the same reason the bundle root is resolved above: `#prepare`
|
|
80
|
+
# already calls through {Plugin::Isolation}, so a later assignment would leave prepare-time
|
|
81
|
+
# calls on a different strategy than the rest of the run.
|
|
82
|
+
Plugin::Isolation.configured_strategy = @configuration.plugins_isolation
|
|
80
83
|
plugin_registry = load_plugins
|
|
81
84
|
dependency_source_index = DependencySourceInference::Builder.build(@configuration.dependencies)
|
|
82
85
|
# ADR-18 slice 3 — plugin prepare MUST run before the synthetic-method scanner so cross-plugin
|
|
@@ -161,6 +164,9 @@ module Rigor
|
|
|
161
164
|
# the cref Ruby resolves it in rather than by peeling the subclass's own qualified name.
|
|
162
165
|
discovered_header_nestings: def_index.fetch(:header_nestings),
|
|
163
166
|
discovered_includes: def_index.fetch(:includes),
|
|
167
|
+
# Issue #898 — the singleton-side mixin table, kept beside the instance-side one so a class
|
|
168
|
+
# object's `extend`s reach `Narrowing` from a sibling file the way its `include`s already do.
|
|
169
|
+
discovered_extends: def_index.fetch(:extends),
|
|
164
170
|
discovered_class_sources: def_index.fetch(:class_sources),
|
|
165
171
|
# Issue #644 — the cross-file value-constant publication table and its write attribution.
|
|
166
172
|
constant_values: def_index.fetch(:constant_values),
|
|
@@ -16,8 +16,9 @@ module Rigor
|
|
|
16
16
|
# back-reference cycle.
|
|
17
17
|
class RunSnapshots
|
|
18
18
|
attr_accessor :class_decl_paths, :signature_paths,
|
|
19
|
-
:synthesized_namespaces, :quarantined_signatures, :conformance_results,
|
|
20
|
-
:env_build_failure, :definition_build_failures, :
|
|
19
|
+
:synthesized_namespaces, :quarantined_signatures, :signature_standdowns, :conformance_results,
|
|
20
|
+
:env_build_failure, :definition_build_failures, :hkt_scan_failure,
|
|
21
|
+
:effect_annotation_carrier
|
|
21
22
|
|
|
22
23
|
# Constructor defaults match the {Runner} constructor: the pre-seed values `build_run_stats` /
|
|
23
24
|
# `pre_file_diagnostics` read before the first analysis path runs are frozen empties. The
|
|
@@ -25,15 +26,22 @@ module Rigor
|
|
|
25
26
|
# `[error_class, first_line, buffer_names]` tuple or nothing. Its per-class sibling
|
|
26
27
|
# `definition_build_failures` (#696) holds a LIST, because a collapsed universe fails many classes,
|
|
27
28
|
# and is accumulated ACROSS pool workers rather than assigned once — see
|
|
28
|
-
# {PoolCoordinator#merge_worker_reporters}.
|
|
29
|
+
# {PoolCoordinator#merge_worker_reporters}. `hkt_scan_failure` (#784) is nil-or-tuple like
|
|
30
|
+
# `env_build_failure`, not a list like `definition_build_failures`: the scan is ONE build over the
|
|
31
|
+
# whole `signature_paths:` overlay, not a per-class one, so it has exactly one outcome per run.
|
|
32
|
+
# `signature_standdowns` (#610) is the quarantine slot's twin for the plugin-contributed files that
|
|
33
|
+
# stood down against a colliding generic arity: a list, assigned once from the loader as
|
|
34
|
+
# `quarantined_signatures` is, and derived from the final env so a cache HIT carries it too.
|
|
29
35
|
def initialize
|
|
30
36
|
@class_decl_paths = {}.freeze
|
|
31
37
|
@signature_paths = [].freeze
|
|
32
38
|
@synthesized_namespaces = [].freeze
|
|
33
39
|
@quarantined_signatures = [].freeze
|
|
40
|
+
@signature_standdowns = [].freeze
|
|
34
41
|
@conformance_results = [].freeze
|
|
35
42
|
@env_build_failure = nil
|
|
36
43
|
@definition_build_failures = [].freeze
|
|
44
|
+
@hkt_scan_failure = nil
|
|
37
45
|
@effect_annotation_carrier = [].freeze
|
|
38
46
|
end
|
|
39
47
|
|
|
@@ -44,9 +52,11 @@ module Rigor
|
|
|
44
52
|
@signature_paths = []
|
|
45
53
|
@synthesized_namespaces = []
|
|
46
54
|
@quarantined_signatures = []
|
|
55
|
+
@signature_standdowns = []
|
|
47
56
|
@conformance_results = []
|
|
48
57
|
@env_build_failure = nil
|
|
49
58
|
@definition_build_failures = []
|
|
59
|
+
@hkt_scan_failure = nil
|
|
50
60
|
@effect_annotation_carrier = [].freeze
|
|
51
61
|
end
|
|
52
62
|
end
|
|
@@ -9,6 +9,7 @@ require_relative "../scope"
|
|
|
9
9
|
require_relative "../cache/store"
|
|
10
10
|
require_relative "../cache/rbs_descriptor"
|
|
11
11
|
require_relative "../cache/file_digest"
|
|
12
|
+
require_relative "../cache/incremental_snapshot"
|
|
12
13
|
require_relative "run_cache_key"
|
|
13
14
|
require_relative "path_expansion"
|
|
14
15
|
require_relative "../plugin"
|
|
@@ -29,6 +30,7 @@ require_relative "../inference/scope_indexer"
|
|
|
29
30
|
require_relative "../inference/synthetic_method_scanner"
|
|
30
31
|
require_relative "../inference/project_patched_scanner"
|
|
31
32
|
require_relative "../inference/method_dispatcher/file_folding"
|
|
33
|
+
require_relative "crash_signature"
|
|
32
34
|
require_relative "buffer_binding"
|
|
33
35
|
require_relative "check_rules"
|
|
34
36
|
require_relative "dependency_recorder"
|
|
@@ -64,7 +66,26 @@ module Rigor
|
|
|
64
66
|
|
|
65
67
|
attr_reader :cache_store, :plugin_registry, :dependency_source_index,
|
|
66
68
|
:rbs_extended_reporter, :boundary_cross_reporter,
|
|
67
|
-
:analyzed_files, :unresolved_self_calls, :seed_bundles
|
|
69
|
+
:analyzed_files, :unresolved_self_calls, :seed_bundles,
|
|
70
|
+
# #788 rounds 6–7 — the rows per-file analysis produced this run, severity-resolved exactly
|
|
71
|
+
# as the run's stream is and sliced to this run's targets (a pool backend folds `.rigor.yml`
|
|
72
|
+
# prepare / degraded rows into `analyze_files`'s return). `IncrementalSession` caches ONLY
|
|
73
|
+
# this and serves reused files from it without re-stamping: a run-level row is regenerated
|
|
74
|
+
# every run wherever it is positioned, and slicing the run's full stream by path cached the
|
|
75
|
+
# file-positioned ones (`effect.annotations-unchecked`, `source-rbs-*`).
|
|
76
|
+
:per_file_diagnostics
|
|
77
|
+
|
|
78
|
+
# Issues #796 / #794 — the two run-level rows a NARROWED run cannot re-derive from the files it
|
|
79
|
+
# analyses: the `definition-build-failed` set (whose producer is the analysis's own demand, and #696
|
|
80
|
+
# forbids Rigor demanding in its place) and the HKT-scan outcome (whose producer is an environment a
|
|
81
|
+
# nothing-changed recheck otherwise has no reason to build). {IncrementalSession} persists what a full
|
|
82
|
+
# run answers here and hands it back to the next narrowed run.
|
|
83
|
+
def run_level_rows
|
|
84
|
+
Cache::IncrementalSnapshot::RunLevelRows.new(
|
|
85
|
+
definition_build_failures: @snapshots.definition_build_failures,
|
|
86
|
+
hkt_scan_failure: @snapshots.hkt_scan_failure
|
|
87
|
+
)
|
|
88
|
+
end
|
|
68
89
|
|
|
69
90
|
# ADR-46 — the per-file cross-file read records this run captured (empty unless
|
|
70
91
|
# `record_dependencies: true`). Sequential analysis records into `@file_dependencies` via
|
|
@@ -206,41 +227,40 @@ module Rigor
|
|
|
206
227
|
end
|
|
207
228
|
end
|
|
208
229
|
|
|
209
|
-
# @param
|
|
210
|
-
# @param
|
|
211
|
-
# @param cache_store [Rigor::Cache::Store, nil] the persistent cache the runner exposes to producers
|
|
230
|
+
# @param explain — surface fail-soft fallback events as `:info` diagnostics.
|
|
231
|
+
# @param cache_store — the persistent cache the runner exposes to producers
|
|
212
232
|
# (`RbsConstantTable` and successors). Pass `nil` to disable caching for this run; the CLI's
|
|
213
233
|
# `--no-cache` flag wires `nil` through. v0.0.9 group A slice 1 introduces the surface; later
|
|
214
234
|
# slices route real producers through it.
|
|
215
|
-
# @param workers
|
|
235
|
+
# @param workers — ADR-15 Phase 4b — when greater than zero, per-file analysis dispatches
|
|
216
236
|
# across a pool of N workers. Default `0` keeps the sequential code path bit-for-bit unchanged.
|
|
217
237
|
# Controlled via the `RIGOR_RACTOR_WORKERS` env var or `.rigor.yml` `parallel.workers:` (Phase 4c,
|
|
218
238
|
# fully wired).
|
|
219
|
-
# @param collect_stats
|
|
239
|
+
# @param collect_stats — when true (default), `#run` builds a {RunStats} summary exposed via
|
|
220
240
|
# `result.stats` — this forces the RBS env build at end-of-run so the `class_decl_paths` snapshot
|
|
221
241
|
# has real source attribution. Set to false to skip the stats summary entirely; the CLI's
|
|
222
242
|
# `--no-stats` threads `false` through to keep trivial-fixture runs from warming `.rigor/cache`.
|
|
223
|
-
# @param prebuilt
|
|
243
|
+
# @param prebuilt — when supplied, the runner adopts the pre-built
|
|
224
244
|
# plugin registry / dependency-source index / scanner outputs from the snapshot and skips the
|
|
225
245
|
# per-call pre-passes that produce them. Used by long-lived integrations
|
|
226
246
|
# (`Rigor::LanguageServer::ProjectContext`) to keep per-buffer requests fast — scanners walk the
|
|
227
247
|
# project once per generation rather than once per request, and plugin `#prepare` runs once per
|
|
228
248
|
# generation rather than once per request. Watched-file invalidation is the owner's responsibility;
|
|
229
249
|
# the runner trusts the snapshot it was given.
|
|
230
|
-
# @param environment
|
|
250
|
+
# @param environment — opt-in Environment override. When supplied, sequential
|
|
231
251
|
# mode uses the provided env instance in `#analyze_files` instead of building a fresh one via
|
|
232
252
|
# `Environment.for_project`, and attaches the runner's per-run reporter pair onto the env's mutable
|
|
233
253
|
# `Reporters` slot via `Environment#attach_reporters!`. Long-lived consumers (LSP `ProjectContext`)
|
|
234
254
|
# pass a shared env so per-publish work doesn't repeat the `Environment.for_project` build (bundler
|
|
235
255
|
# / lockfile / collection discovery, RbsLoader construction). Pool mode ignores the override — each
|
|
236
256
|
# worker continues to build its own Environment.
|
|
237
|
-
# @param discovery_seed
|
|
257
|
+
# @param discovery_seed — issue #260 — opt-in cross-file discovery tables, keyed by
|
|
238
258
|
# {Scope::DiscoveryIndex} slot name, seeded onto every per-file scope through
|
|
239
259
|
# `project_scope_seed_tables`. The ONE deliberate exception to "a `prebuilt:` runner carries no
|
|
240
260
|
# discovery tables": {Protection::DiagnosticOracle} threads the table set Tier 2's site filter already
|
|
241
261
|
# judges anchors against, so a site admitted because a sibling-file class resolved is also a site the
|
|
242
262
|
# oracle can kill at. nil (the default) leaves the prebuilt/LSP contract byte-identical.
|
|
243
|
-
# @param no_tolerated_effects
|
|
263
|
+
# @param no_tolerated_effects — ADR-103 WD1 / #385 — `rigor check --no-tolerated-effects`.
|
|
244
264
|
# Judges effect envelopes as if `effects.tolerated:` were empty. A judgment-time switch only: the
|
|
245
265
|
# run, its collection and its cache identity are unchanged.
|
|
246
266
|
def initialize(configuration:, explain: false, # rubocop:disable Metrics/ParameterLists,Metrics/AbcSize,Metrics/MethodLength
|
|
@@ -249,8 +269,12 @@ module Rigor
|
|
|
249
269
|
buffer: nil, prebuilt: nil, environment: nil,
|
|
250
270
|
record_dependencies: false, record_self_calls: false, analyze_only: nil,
|
|
251
271
|
seed_bundles: nil, collect_seed_bundles: false, param_inferred_types: nil,
|
|
252
|
-
discovery_seed: nil, no_tolerated_effects: false
|
|
272
|
+
discovery_seed: nil, no_tolerated_effects: false,
|
|
273
|
+
restored_run_level_rows: nil)
|
|
253
274
|
@configuration = configuration
|
|
275
|
+
# Issues #796 / #794 — the previous full run's run-level rows, supplied only by
|
|
276
|
+
# {IncrementalSession} on a narrowed run; see {PoolCoordinator#replay_restored_run_level_rows}.
|
|
277
|
+
@restored_run_level_rows = restored_run_level_rows
|
|
254
278
|
@explain = explain
|
|
255
279
|
@cache_store = enforce_read_only_cache(cache_store, buffer)
|
|
256
280
|
@plugin_requirer = plugin_requirer
|
|
@@ -302,6 +326,7 @@ module Rigor
|
|
|
302
326
|
# See `self_undefined_rule_active?`.
|
|
303
327
|
@self_undefined_rule_active = nil
|
|
304
328
|
@analyzed_files = [].freeze
|
|
329
|
+
@per_file_diagnostics = [].freeze
|
|
305
330
|
# In-memory source map for `#run_source` — `{ logical_path => source String }`. When set,
|
|
306
331
|
# `parse_source` reads bytes from here instead of disk and `expand_paths` accepts the (possibly
|
|
307
332
|
# non-existent) logical path. nil on a normal disk-backed run.
|
|
@@ -353,6 +378,8 @@ module Rigor
|
|
|
353
378
|
# Issue #682 — the `Module.nesting` each class / module declaration HEADER is written in.
|
|
354
379
|
@project_discovered_header_nestings = {}.freeze
|
|
355
380
|
@project_discovered_includes = {}.freeze
|
|
381
|
+
# Issue #898 — the singleton-side twin of the include table (`extend M` / `extend self`).
|
|
382
|
+
@project_discovered_extends = {}.freeze
|
|
356
383
|
@project_discovered_class_sources = {}.freeze
|
|
357
384
|
# Issue #644 — the cross-file VALUE-constant publication table (`{qualified name => Type::Constant}`,
|
|
358
385
|
# literal writes only) and its per-name write attribution. The first seeds `in_source_constants` on
|
|
@@ -379,6 +406,9 @@ module Rigor
|
|
|
379
406
|
# (sequential + fork-worker) through `project_scope_seed_tables`. Empty unless the project lists
|
|
380
407
|
# `pre_eval:` files that declare publishable constants, so a project without one is byte-identical.
|
|
381
408
|
@project_pre_eval_constants = {}.freeze
|
|
409
|
+
# Issue #663 — the listed set {#publishable_pre_eval_constants} asks "is this writer one of ours?"
|
|
410
|
+
# against; a function of the configuration alone, so it outlives every discovery rebuild.
|
|
411
|
+
@pre_eval_path_set = nil
|
|
382
412
|
# ADR-84 WD2 — per-run identity token for the user-method return memo's bucket (see
|
|
383
413
|
# Scope::DiscoveryIndex#run_generation). Minted fresh in `run_analysis` so the memo never serves an
|
|
384
414
|
# entry across a run boundary (LSP re-check, ADR-62 warm loop); nil until the first run so
|
|
@@ -426,6 +456,9 @@ module Rigor
|
|
|
426
456
|
# Per-run reset of the environment the cacheable path resolves, reused by the envelope pass so a
|
|
427
457
|
# run never builds two.
|
|
428
458
|
@run_environment = nil
|
|
459
|
+
# #788 — the per-file reader is assigned only on the analysis (miss) path; reset it here so a run the
|
|
460
|
+
# ADR-45 result cache serves does not answer with the previous run's rows.
|
|
461
|
+
@per_file_diagnostics = [].freeze
|
|
429
462
|
# ADR-84 WD2 — roll the return-memo bucket: a fresh frozen token per run makes every per-file scope
|
|
430
463
|
# of THIS run share one memo bucket while entries from any earlier run in this process (stale after
|
|
431
464
|
# an edit) become unreachable.
|
|
@@ -467,9 +500,8 @@ module Rigor
|
|
|
467
500
|
# so the result matches a one-file disk run; only the cross-file project pre-pass is empty (there is
|
|
468
501
|
# one file, and the per-file indexer self-discovers its own classes / defs).
|
|
469
502
|
#
|
|
470
|
-
# @param source
|
|
471
|
-
# @param path
|
|
472
|
-
# @return [Result]
|
|
503
|
+
# @param source — Ruby source to analyze.
|
|
504
|
+
# @param path — logical path for diagnostic locations.
|
|
473
505
|
def run_source(source:, path: "(source).rb")
|
|
474
506
|
@in_memory_sources = { path => source }
|
|
475
507
|
run([path])
|
|
@@ -595,7 +627,7 @@ module Rigor
|
|
|
595
627
|
# arg-flooring surface). Only meaningful right after a run populated the memo (baseline / recheck),
|
|
596
628
|
# before the bucket rolls. Keys are held live here; the session Marshals them for the snapshot.
|
|
597
629
|
#
|
|
598
|
-
# @return
|
|
630
|
+
# @return `{ [path, "Class#method" | "Class.method"] => { keys:, returns:, effects: } }`.
|
|
599
631
|
def return_summaries
|
|
600
632
|
memo = Inference::ExpressionTyper.harvest_return_memo
|
|
601
633
|
return {} if memo.empty?
|
|
@@ -653,9 +685,9 @@ module Rigor
|
|
|
653
685
|
# store) exactly as a real run's setup does, then re-drives each spec's def through the ADR-84 return
|
|
654
686
|
# memo. Off any hot path — invoked only when declaration-stable changed pairs carry a persisted summary.
|
|
655
687
|
#
|
|
656
|
-
# @param paths
|
|
657
|
-
# @param specs
|
|
658
|
-
# @return
|
|
688
|
+
# @param paths — analysis roots (nil → the configuration's `paths:`).
|
|
689
|
+
# @param specs — each `{ class_name:, method_name:, singleton:, keys: [[receiver, args], …] }`.
|
|
690
|
+
# @return `{ [class_name, method_name, singleton] => [return_descriptor_or_nil, …] }`.
|
|
659
691
|
def evaluate_return_types(paths, specs)
|
|
660
692
|
return {} if specs.empty?
|
|
661
693
|
|
|
@@ -674,7 +706,14 @@ module Rigor
|
|
|
674
706
|
@run_generation = Object.new.freeze
|
|
675
707
|
run_project_pre_passes(expansion: expansion)
|
|
676
708
|
ensure_project_discovery(expansion)
|
|
677
|
-
|
|
709
|
+
# Issue #795 — `source_files:` is the WHOLE project's file list, never `target_files(expansion)`.
|
|
710
|
+
# `IncrementalSession#build_runner` threads its own `@buffer` into this Runner, so in editor-buffer
|
|
711
|
+
# mode `target_files` narrows to the buffer's single logical path; an environment built over just
|
|
712
|
+
# that path drops every OTHER file's plugin-synthesized virtual RBS, which can flip a re-evaluated
|
|
713
|
+
# return descriptor and wrongly declare a caller's return type unstable (or stable) relative to the
|
|
714
|
+
# full-project answer. This probe never analyzes a file, so it carries none of #788's per-file-cache
|
|
715
|
+
# duplication concern either.
|
|
716
|
+
environment = @pool_coordinator.resolve_sequential_environment(source_files: expansion.fetch(:files))
|
|
678
717
|
specs.to_h do |spec|
|
|
679
718
|
[[spec[:class_name], spec[:method_name], spec[:singleton]], evaluate_spec_returns(spec, environment)]
|
|
680
719
|
end
|
|
@@ -776,7 +815,7 @@ module Rigor
|
|
|
776
815
|
# fixpoint over them, which is the pre-split behaviour and the retry the fail-soft posture wants.
|
|
777
816
|
# Only when neither entry answers does the run re-analyse.
|
|
778
817
|
#
|
|
779
|
-
# @return
|
|
818
|
+
# @return whether this run was served.
|
|
780
819
|
def served_from_effect_entries?(descriptor)
|
|
781
820
|
summary = peek_effect_summary(descriptor)
|
|
782
821
|
if summary
|
|
@@ -927,9 +966,19 @@ module Rigor
|
|
|
927
966
|
).diagnostics
|
|
928
967
|
end
|
|
929
968
|
|
|
969
|
+
# Issue #795 — `source_files:` is the WHOLE project's file list (`expansion.fetch(:files)`), never
|
|
970
|
+
# `target_files(expansion)`. A subset or editor-buffer run's `target_files` narrows to the
|
|
971
|
+
# `analyze_only` closure or the buffer's single logical path; building the envelope walk's
|
|
972
|
+
# environment over that subset drops every plugin-synthesized virtual RBS from an excluded file, so
|
|
973
|
+
# an envelope declared only in that file's inline annotation is invisible to the walk — the same #793
|
|
974
|
+
# gap #788 closed for per-file analysis, left open here because #788's binding sentences scoped
|
|
975
|
+
# themselves to "the environments the per-file analysis builds". This path is exempt from #788's
|
|
976
|
+
# per-file-cache duplication concern: `effect.unknown-label` (and its envelope-pass siblings) are
|
|
977
|
+
# produced by this pass, never by `Runner#per_file_diagnostics`, so `IncrementalSession` never caches
|
|
978
|
+
# them and widening this source list cannot duplicate a row on recheck.
|
|
930
979
|
def envelope_rbs_loader(expansion)
|
|
931
980
|
environment = @run_environment ||
|
|
932
|
-
@pool_coordinator.resolve_sequential_environment(source_files:
|
|
981
|
+
@pool_coordinator.resolve_sequential_environment(source_files: expansion.fetch(:files))
|
|
933
982
|
environment&.rbs_loader
|
|
934
983
|
rescue StandardError
|
|
935
984
|
nil
|
|
@@ -985,24 +1034,71 @@ module Rigor
|
|
|
985
1034
|
# per-file cache, so it needs the full analyzed set to subtract the affected closure from.
|
|
986
1035
|
targets = target_files(expansion)
|
|
987
1036
|
@analyzed_files = targets
|
|
988
|
-
|
|
1037
|
+
# Issue #784 — the whole project's file list rides along so an EMPTY `targets` (a narrowed run whose
|
|
1038
|
+
# closure is empty) can still resolve the environment a full run would — same files, same
|
|
1039
|
+
# synthesized RBS — to demand the HKT registry once, while a project with no files resolves nothing.
|
|
1040
|
+
# #788 rounds 6–7 — the per-file stream is kept apart from the run-level streams appended below,
|
|
1041
|
+
# because `IncrementalSession` must cache ONLY what per-file analysis produced (#per_file_diagnostics),
|
|
1042
|
+
# and the reader is exposed SEVERITY-RESOLVED and sliced to this run's targets. The cache serves a
|
|
1043
|
+
# reused file without re-stamping, so a raw row would resurrect a rule the profile resolves to `:off`
|
|
1044
|
+
# (`static.value-use.void` ships off on the default profile) and serve the authored severity where an
|
|
1045
|
+
# override re-stamps it; and a pool backend folds `.rigor.yml`-positioned prepare / pool-degraded rows
|
|
1046
|
+
# into the same return, which the slice drops. The run's own stream is stamped once, at the end.
|
|
1047
|
+
diagnostics += analyze_targets(targets, environment: environment, project_files: expansion.fetch(:files))
|
|
989
1048
|
# ADR-103 WD12 — the effect fixpoint, in the post-pool aggregation slot beside the conformance
|
|
990
1049
|
# results. Graph-only over a finite lattice, so it is a plain worklist to a true fixpoint; it
|
|
991
1050
|
# contributes NO diagnostics and its result leaves through `#effect_table`, never through the
|
|
992
1051
|
# stream. Skipped entirely when collection did not run.
|
|
993
1052
|
close_effect_graph
|
|
994
|
-
diagnostics
|
|
1053
|
+
diagnostics + post_analysis_diagnostic_streams
|
|
1054
|
+
end
|
|
1055
|
+
|
|
1056
|
+
# The rbs-coverage build-failure ladder plus every remaining post-analysis stream
|
|
1057
|
+
# `#assemble_run_diagnostics` appends, in their fixed contract order (see the comments at each call
|
|
1058
|
+
# below and at the streams' own definitions). Split out of `#assemble_run_diagnostics` so that
|
|
1059
|
+
# method's `Metrics/AbcSize` stays under budget — every stream here is a plain `DiagnosticAggregator`
|
|
1060
|
+
# reader with no branching of its own, so the split changes nothing about WHEN or in WHAT order they
|
|
1061
|
+
# run.
|
|
1062
|
+
def post_analysis_diagnostic_streams
|
|
1063
|
+
diagnostics = @diagnostic_aggregator.rbs_quarantined_signature_diagnostics
|
|
995
1064
|
diagnostics += @diagnostic_aggregator.rbs_environment_build_failed_diagnostics
|
|
996
|
-
# Issue #696 — after its env-wide twin and before the synthesized-namespace notice: the
|
|
1065
|
+
# Issue #696 — after its env-wide twin and before the synthesized-namespace notice: the four
|
|
997
1066
|
# `rbs.coverage.*` build conditions surface widest-consequence first, and their relative order is
|
|
998
1067
|
# the diagnostic output contract.
|
|
999
1068
|
diagnostics += @diagnostic_aggregator.rbs_definition_build_failed_diagnostics
|
|
1000
|
-
|
|
1069
|
+
# Issue #784 — last of the four, deliberately: it loses only the IMPLICIT HKT registrations a
|
|
1070
|
+
# `type` alias would have contributed, never a class's own declared method surface, so it is the
|
|
1071
|
+
# narrowest-consequence rung on the same ladder.
|
|
1072
|
+
diagnostics += @diagnostic_aggregator.rbs_hkt_scan_failed_diagnostics
|
|
1073
|
+
# The synthesized-namespace notice, then (#610) the plugin-signature stand-down: the outcome that
|
|
1074
|
+
# AVOIDED a definition-build failure, so the quietest row on that ladder.
|
|
1075
|
+
diagnostics += @diagnostic_aggregator.rbs_coverage_notice_diagnostics
|
|
1001
1076
|
diagnostics += @diagnostic_aggregator.conforms_to_diagnostics
|
|
1002
1077
|
diagnostics += @diagnostic_aggregator.rbs_extended_reporter_diagnostics
|
|
1003
1078
|
diagnostics += @diagnostic_aggregator.boundary_cross_diagnostics
|
|
1004
|
-
diagnostics
|
|
1005
|
-
|
|
1079
|
+
diagnostics += @diagnostic_aggregator.source_rbs_synthesis_diagnostics
|
|
1080
|
+
# Issue #959 — read LAST (after `analyze_targets`, which already ran before this method is called),
|
|
1081
|
+
# so every per-file plugin call has had its chance to record a refusal on its (per-plugin-instance
|
|
1082
|
+
# memoised) `IoBoundary`, alongside the prepare-time refusals the same boundary instance may
|
|
1083
|
+
# already carry.
|
|
1084
|
+
diagnostics + @diagnostic_aggregator.plugin_trust_refusal_diagnostics
|
|
1085
|
+
end
|
|
1086
|
+
private :post_analysis_diagnostic_streams
|
|
1087
|
+
|
|
1088
|
+
# #788 round 7 — runs per-file analysis over `targets` and exposes what it produced as
|
|
1089
|
+
# `#per_file_diagnostics`: the `analyze_files` return, stamped with the same severity profile the run's
|
|
1090
|
+
# own stream gets (`SeverityStamp` drops `:off` rows and re-stamps overrides, and the per-file cache never
|
|
1091
|
+
# re-stamps), sliced to the rows positioned at the targets. Returns the RAW return for the run's stream,
|
|
1092
|
+
# which is stamped once, at the end of `#run_analysis`.
|
|
1093
|
+
def analyze_targets(targets, environment:, project_files:)
|
|
1094
|
+
raw = @pool_coordinator.analyze_files(targets, environment: environment, project_files: project_files)
|
|
1095
|
+
analysed = targets.to_set
|
|
1096
|
+
@per_file_diagnostics = @diagnostic_aggregator.apply_severity_profile(raw)
|
|
1097
|
+
.select { |diagnostic| analysed.include?(diagnostic.path) }
|
|
1098
|
+
.freeze
|
|
1099
|
+
raw
|
|
1100
|
+
end
|
|
1101
|
+
private :analyze_targets
|
|
1006
1102
|
|
|
1007
1103
|
# ADR-67 WD6a — the check-walk parameter-inference pre-pass. Populates `@project_param_inferred_types`
|
|
1008
1104
|
# (read by `project_scope_seed_tables`) with the call-site union of every undeclared parameter, running
|
|
@@ -1121,13 +1217,22 @@ module Rigor
|
|
|
1121
1217
|
def build_run_dependency_descriptor(expansion, rbs_descriptor)
|
|
1122
1218
|
entries = analyzed_file_entries(expansion) + discovery_file_entries(expansion) +
|
|
1123
1219
|
pre_eval_file_entries + rbs_descriptor.files
|
|
1124
|
-
|
|
1220
|
+
# #979 — the signature ROOTS' listings, one glob row each. `rbs_descriptor.files` covers only the
|
|
1221
|
+
# `.rbs` files that existed while the run read them, so without these a signature file written after
|
|
1222
|
+
# the run left the slot validating fresh and the warm run answered without it.
|
|
1223
|
+
globs = rbs_descriptor.globs.dup
|
|
1125
1224
|
@plugin_registry.plugins.each do |plugin|
|
|
1126
1225
|
# Read the boundary WITHOUT triggering its lazy `@io_boundary ||=` initializer: plugin instances
|
|
1127
1226
|
# are frozen after the run, and a plugin that never built a boundary read no files through it,
|
|
1128
1227
|
# so it contributes no dependencies.
|
|
1129
1228
|
boundary = plugin.instance_variable_get(:@io_boundary)
|
|
1130
|
-
|
|
1229
|
+
if boundary
|
|
1230
|
+
# #629 — a boundary carries GlobEntry listing rows too (`IoBoundary#list_directory`), and they
|
|
1231
|
+
# are the only edge back to a file the run decided was ABSENT from a directory it consulted.
|
|
1232
|
+
boundary_descriptor = boundary.cache_descriptor
|
|
1233
|
+
entries.concat(boundary_descriptor.files)
|
|
1234
|
+
globs.concat(boundary_descriptor.globs)
|
|
1235
|
+
end
|
|
1131
1236
|
plugin.class.producers.each_value do |prod|
|
|
1132
1237
|
globs.concat(plugin.send(:watch_glob_entries, prod[:watch])) if prod[:watch]
|
|
1133
1238
|
end
|
|
@@ -1248,6 +1353,7 @@ module Rigor
|
|
|
1248
1353
|
@project_discovered_superclasses = discovery.discovered_superclasses
|
|
1249
1354
|
@project_discovered_header_nestings = discovery.discovered_header_nestings
|
|
1250
1355
|
@project_discovered_includes = discovery.discovered_includes
|
|
1356
|
+
@project_discovered_extends = discovery.discovered_extends
|
|
1251
1357
|
@project_discovered_class_sources = discovery.discovered_class_sources
|
|
1252
1358
|
@project_constant_values = discovery.constant_values
|
|
1253
1359
|
@published_constant_name_set = nil
|
|
@@ -1341,7 +1447,7 @@ module Rigor
|
|
|
1341
1447
|
3.0.0 3.1.0 3.2.0 3.3.0 3.4.0 3.5.0 4.0.0 4.1.0 4.2.0
|
|
1342
1448
|
].freeze
|
|
1343
1449
|
|
|
1344
|
-
# @return
|
|
1450
|
+
# @return the lowest `target_ruby` this Prism build accepts, or nil if none of the
|
|
1345
1451
|
# ladder parses. Memoised per process (the value is constant for a given Prism).
|
|
1346
1452
|
def self.prism_supported_floor
|
|
1347
1453
|
@prism_supported_floor ||= PRISM_VERSION_LADDER.find do |candidate|
|
|
@@ -1427,7 +1533,7 @@ module Rigor
|
|
|
1427
1533
|
# indexes, prepare-diagnostic snapshot, and the four end-of-pass snapshots) is reached through reader
|
|
1428
1534
|
# procs so each collaborator observes the live ivar value at call time without a back-reference
|
|
1429
1535
|
# cycle. The reporter accumulators and the {RunSnapshots} sink are shared mutable instances.
|
|
1430
|
-
def build_collaborators # rubocop:disable Metrics/MethodLength
|
|
1536
|
+
def build_collaborators # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
1431
1537
|
@pre_passes = ProjectPrePasses.new(
|
|
1432
1538
|
configuration: @configuration, cache_store: @cache_store, buffer: @buffer,
|
|
1433
1539
|
plugin_requirer: @plugin_requirer, pool_mode: -> { pool_mode? }
|
|
@@ -1446,7 +1552,8 @@ module Rigor
|
|
|
1446
1552
|
synthetic_method_index: -> { @synthetic_method_index },
|
|
1447
1553
|
project_patched_methods: -> { @project_patched_methods },
|
|
1448
1554
|
project_scope_seed: -> { project_scope_seed_tables },
|
|
1449
|
-
analyze_file: ->(path, environment) { analyze_file(path, environment) }
|
|
1555
|
+
analyze_file: ->(path, environment) { analyze_file(path, environment) },
|
|
1556
|
+
restored_run_level_rows: @restored_run_level_rows
|
|
1450
1557
|
)
|
|
1451
1558
|
@diagnostic_aggregator = DiagnosticAggregator.new(
|
|
1452
1559
|
configuration: @configuration,
|
|
@@ -1460,8 +1567,10 @@ module Rigor
|
|
|
1460
1567
|
pre_eval_diagnostics_from_scanner: -> { @pre_eval_diagnostics_from_scanner },
|
|
1461
1568
|
synthesized_namespaces_snapshot: -> { @snapshots.synthesized_namespaces },
|
|
1462
1569
|
quarantined_signatures_snapshot: -> { @snapshots.quarantined_signatures },
|
|
1570
|
+
signature_standdowns_snapshot: -> { @snapshots.signature_standdowns },
|
|
1463
1571
|
env_build_failure_snapshot: -> { @snapshots.env_build_failure },
|
|
1464
1572
|
definition_build_failures_snapshot: -> { @snapshots.definition_build_failures },
|
|
1573
|
+
hkt_scan_failure_snapshot: -> { @snapshots.hkt_scan_failure },
|
|
1465
1574
|
conformance_results_snapshot: -> { @snapshots.conformance_results }
|
|
1466
1575
|
)
|
|
1467
1576
|
end
|
|
@@ -1693,7 +1802,7 @@ module Rigor
|
|
|
1693
1802
|
unless @project_discovered_header_nestings.empty?
|
|
1694
1803
|
tables[:discovered_header_nestings] = @project_discovered_header_nestings
|
|
1695
1804
|
end
|
|
1696
|
-
tables
|
|
1805
|
+
seed_mixin_tables(tables)
|
|
1697
1806
|
unless @project_discovered_method_visibilities.empty?
|
|
1698
1807
|
tables[:discovered_method_visibilities] = @project_discovered_method_visibilities
|
|
1699
1808
|
end
|
|
@@ -1704,6 +1813,14 @@ module Rigor
|
|
|
1704
1813
|
tables
|
|
1705
1814
|
end
|
|
1706
1815
|
|
|
1816
|
+
# The two mixin tables: the ADR-24 instance-side `include` / `prepend` map and its #898 singleton-side
|
|
1817
|
+
# `extend` twin. Paired here because they are read as one picture of a class's ancestry, and split out
|
|
1818
|
+
# of {#project_scope_seed_tables} to keep it under the complexity budget.
|
|
1819
|
+
def seed_mixin_tables(tables)
|
|
1820
|
+
tables[:discovered_includes] = @project_discovered_includes unless @project_discovered_includes.empty?
|
|
1821
|
+
tables[:discovered_extends] = @project_discovered_extends unless @project_discovered_extends.empty?
|
|
1822
|
+
end
|
|
1823
|
+
|
|
1707
1824
|
# ADR-46 slice 1 / issue #644 — the two SOURCE-ATTRIBUTION tables, read only by the recording accessors
|
|
1708
1825
|
# (`Scope#record_class_dependency` for the class-declaration map, `Scope#record_constant_dependency`
|
|
1709
1826
|
# for the constant-write map). A normal run carries neither. Extracted to keep
|
|
@@ -1743,12 +1860,6 @@ module Rigor
|
|
|
1743
1860
|
tables[:published_constant_names] = names unless names.empty?
|
|
1744
1861
|
end
|
|
1745
1862
|
|
|
1746
|
-
# Issue #644 — the seeded `in_source_constants` table, joining the two cross-file constant producers.
|
|
1747
|
-
# The whole-project literal table wins over a `pre_eval:` publication of the same name: both describe
|
|
1748
|
-
# the same assignment, the literal table pins the value the write actually carries while ADR-17's
|
|
1749
|
-
# widener erases it to the class, and listing a file under `pre_eval:` must never LOSE precision. The
|
|
1750
|
-
# per-file table still wins over both (`ScopeIndexer.index`'s merge) — same-file stays the most
|
|
1751
|
-
# specific authority.
|
|
1752
1863
|
# Issue #644 — the LAST SEGMENTS of the published table, the run-wide half of
|
|
1753
1864
|
# `Scope#published_constant?`. Seeded on EVERY run (unlike `constant_sources`, which only a recording
|
|
1754
1865
|
# run needs) because {CheckRules::PublishedConstantGuard} asks the question on every `if` / `unless`.
|
|
@@ -1757,11 +1868,57 @@ module Rigor
|
|
|
1757
1868
|
@project_constant_values.keys.to_set { |name| name.split("::").last }.freeze
|
|
1758
1869
|
end
|
|
1759
1870
|
|
|
1871
|
+
# Issue #644 — the seeded `in_source_constants` table, joining the two cross-file constant producers.
|
|
1872
|
+
# The whole-project literal table wins over a `pre_eval:` publication of the same name: both describe
|
|
1873
|
+
# the same assignment, the literal table pins the value the write actually carries while ADR-17's
|
|
1874
|
+
# widener erases it to the class, and listing a file under `pre_eval:` must never LOSE precision. The
|
|
1875
|
+
# per-file table still wins over both (`ScopeIndexer.index`'s merge) — same-file stays the most
|
|
1876
|
+
# specific authority.
|
|
1760
1877
|
def merged_seed_constants
|
|
1761
|
-
|
|
1762
|
-
return @
|
|
1878
|
+
pre_eval = publishable_pre_eval_constants
|
|
1879
|
+
return @project_constant_values if pre_eval.empty?
|
|
1880
|
+
return pre_eval if @project_constant_values.empty?
|
|
1881
|
+
|
|
1882
|
+
pre_eval.merge(@project_constant_values).freeze
|
|
1883
|
+
end
|
|
1884
|
+
|
|
1885
|
+
# Issue #663 — the `pre_eval:` publication with every name an UNLISTED file also assigns retracted.
|
|
1886
|
+
# Without this a listed `X = :a` answered `Symbol` at every reader while a sibling `X = "str"` decided
|
|
1887
|
+
# the runtime value half the time: a confident wrong type, not lost precision, and the one asymmetry
|
|
1888
|
+
# #644's precedence work left standing. The retraction costs the opt-in nothing where it earns its
|
|
1889
|
+
# keep — a name only listed files write is untouched, and where the literal table also publishes it
|
|
1890
|
+
# already won (above).
|
|
1891
|
+
#
|
|
1892
|
+
# Conflict is read off #644's write attribution, which censuses every assigning form, so a name the
|
|
1893
|
+
# listed file's own typed walk widened is retracted by an unlisted `X += 1` or `A, X = 1, 2` as
|
|
1894
|
+
# readily as by a plain reassignment. Among LISTED files the rule is unchanged: `PreEvalConstants`
|
|
1895
|
+
# widens first and drops only on disagreement, so two listed files writing `1` and `2` still publish
|
|
1896
|
+
# `Integer` rather than being retracted for being two.
|
|
1897
|
+
def publishable_pre_eval_constants
|
|
1898
|
+
return @project_pre_eval_constants if @project_pre_eval_constants.empty?
|
|
1899
|
+
|
|
1900
|
+
listed = pre_eval_path_set
|
|
1901
|
+
kept = @project_pre_eval_constants.reject { |name, _| unlisted_constant_writer?(name, listed) }
|
|
1902
|
+
kept.size == @project_pre_eval_constants.size ? @project_pre_eval_constants : kept.freeze
|
|
1903
|
+
end
|
|
1904
|
+
|
|
1905
|
+
# True when some file outside `listed` assigns `name`. The wildcard key is consulted alongside the
|
|
1906
|
+
# name's own attribution ([#668](https://github.com/rigortype/rigor/issues/668)): a `k::X = 7` names
|
|
1907
|
+
# no target, and a listed file kept out of `paths:` (ADR-17 WD5 permits it) contributes no censused
|
|
1908
|
+
# name of its own for the wildcard's paths to have been folded into.
|
|
1909
|
+
def unlisted_constant_writer?(name, listed)
|
|
1910
|
+
segment = name.split("::").last
|
|
1911
|
+
writers = @project_constant_sources[name]
|
|
1912
|
+
wildcard = @project_constant_sources["#{Inference::ScopeIndexer::DYNAMIC_TARGET_PREFIX}#{segment}"]
|
|
1913
|
+
[writers, wildcard].any? do |paths|
|
|
1914
|
+
paths&.any? { |path| !listed.include?(File.expand_path(path)) }
|
|
1915
|
+
end
|
|
1916
|
+
end
|
|
1763
1917
|
|
|
1764
|
-
|
|
1918
|
+
# The listed `pre_eval:` files, expanded so a census path and a configured one compare as the same
|
|
1919
|
+
# file whichever spelling each arrived in.
|
|
1920
|
+
def pre_eval_path_set
|
|
1921
|
+
@pre_eval_path_set ||= @configuration.pre_eval.to_set { |path| File.expand_path(path) }
|
|
1765
1922
|
end
|
|
1766
1923
|
|
|
1767
1924
|
# ADR-46 — seed the instance + singleton `"path:line"` def-source tables (each only when non-empty).
|
|
@@ -1876,7 +2033,7 @@ module Rigor
|
|
|
1876
2033
|
path: path,
|
|
1877
2034
|
line: 1,
|
|
1878
2035
|
column: 1,
|
|
1879
|
-
message:
|
|
2036
|
+
message: CrashSignature.check_rule_message(e),
|
|
1880
2037
|
severity: :error
|
|
1881
2038
|
)
|
|
1882
2039
|
]
|