rigortype 0.4.6 → 0.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/data/gem_overlay/activesupport/core_ext.rbs +16 -13
- data/data/vendored_gem_sigs/bundler/bundler.rbs +1 -1
- data/data/vendored_gem_sigs/rubygems/rubygems_extras.rbs +4 -3
- data/docs/handbook/01-getting-started.md +5 -2
- data/docs/handbook/11-sig-gen.md +50 -3
- data/docs/handbook/appendix-phpstan.md +4 -4
- data/docs/manual/02-cli-reference.md +152 -26
- data/docs/manual/03-configuration.md +36 -3
- data/docs/manual/06-baseline.md +6 -4
- data/docs/manual/09-editor-integration.md +13 -2
- data/docs/manual/10-mcp-server.md +38 -2
- data/docs/manual/12-caching.md +4 -3
- data/docs/manual/plugins/rigor-actionpack.md +19 -11
- data/docs/manual/plugins/rigor-activesupport-core-ext.md +20 -1
- data/lib/rigor/analysis/baseline.rb +24 -27
- data/lib/rigor/analysis/check_rules/always_truthy_condition_collector.rb +5 -6
- data/lib/rigor/analysis/check_rules/dead_assignment_collector.rb +2 -2
- data/lib/rigor/analysis/check_rules/declaration_sourced_guard.rb +4 -4
- data/lib/rigor/analysis/check_rules/duplicate_hash_key_collector.rb +2 -2
- data/lib/rigor/analysis/check_rules/inferred_param_guard.rb +85 -13
- data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +3 -2
- data/lib/rigor/analysis/check_rules/lexical_method_sites.rb +0 -1
- data/lib/rigor/analysis/check_rules/main_pass_collector.rb +5 -8
- data/lib/rigor/analysis/check_rules/published_constant_guard.rb +1 -1
- data/lib/rigor/analysis/check_rules/rebinding_block_callees.rb +3 -3
- data/lib/rigor/analysis/check_rules/return_in_ensure_collector.rb +1 -2
- data/lib/rigor/analysis/check_rules/rule_ids.rb +1 -1
- data/lib/rigor/analysis/check_rules/rule_walk.rb +9 -7
- data/lib/rigor/analysis/check_rules/shadowed_rescue_collector.rb +3 -4
- data/lib/rigor/analysis/check_rules/special_global_setters.rb +3 -3
- data/lib/rigor/analysis/check_rules/unreachable_clause_collector.rb +2 -2
- data/lib/rigor/analysis/check_rules/void_value_use_collector.rb +1 -1
- data/lib/rigor/analysis/check_rules.rb +124 -44
- data/lib/rigor/analysis/crash_signature.rb +2 -2
- data/lib/rigor/analysis/dependency_recorder.rb +4 -4
- data/lib/rigor/analysis/dependency_source_inference/boundary_cross_reporter.rb +14 -3
- data/lib/rigor/analysis/dependency_source_inference/gem_resolver.rb +1 -1
- data/lib/rigor/analysis/dependency_source_inference/index.rb +6 -8
- data/lib/rigor/analysis/dependency_source_inference/walker.rb +4 -4
- data/lib/rigor/analysis/edit_replay.rb +93 -6
- data/lib/rigor/analysis/fact_store.rb +3 -3
- data/lib/rigor/analysis/incremental_run_slot/write_guard.rb +2 -2
- data/lib/rigor/analysis/incremental_run_slot.rb +2 -2
- data/lib/rigor/analysis/incremental_session.rb +27 -16
- data/lib/rigor/analysis/rule_catalog.rb +2 -2
- data/lib/rigor/analysis/run_stats.rb +2 -2
- data/lib/rigor/analysis/runner/buffer_pool_dispatcher.rb +2 -2
- data/lib/rigor/analysis/runner/declaration_position.rb +1 -1
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +193 -93
- data/lib/rigor/analysis/runner/effect_envelope_pass.rb +1 -1
- data/lib/rigor/analysis/runner/pool_coordinator.rb +147 -323
- data/lib/rigor/analysis/runner/project_pre_passes.rb +3 -3
- 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 +77 -71
- data/lib/rigor/analysis/self_call_resolution_recorder.rb +1 -1
- data/lib/rigor/analysis/template_unit_positions.rb +2 -3
- data/lib/rigor/analysis/template_units.rb +9 -1
- data/lib/rigor/analysis/worker_session.rb +24 -31
- data/lib/rigor/bleeding_edge.rb +3 -6
- data/lib/rigor/builtins/imported_refinements.rb +6 -8
- data/lib/rigor/builtins/predefined_constant_refinements.rb +1 -1
- data/lib/rigor/builtins/regex_refinement.rb +4 -6
- data/lib/rigor/cache/descriptor.rb +6 -5
- data/lib/rigor/cache/incremental_snapshot.rb +31 -12
- data/lib/rigor/cache/rbs_cache_producer.rb +2 -2
- data/lib/rigor/cache/rbs_class_ancestor_table.rb +1 -1
- data/lib/rigor/cache/rbs_class_type_param_names.rb +2 -2
- data/lib/rigor/cache/rbs_constant_table.rb +1 -1
- data/lib/rigor/cache/rbs_descriptor.rb +54 -3
- data/lib/rigor/cache/rbs_environment.rb +4 -1
- data/lib/rigor/cache/rbs_environment_marshal_patch.rb +2 -2
- data/lib/rigor/cache/rbs_known_class_names.rb +1 -1
- data/lib/rigor/cache/store.rb +11 -10
- data/lib/rigor/ci_detector.rb +1 -1
- data/lib/rigor/cli/annotate_command.rb +24 -19
- data/lib/rigor/cli/baseline_command.rb +145 -55
- data/lib/rigor/cli/catalogue.rb +256 -0
- data/lib/rigor/cli/check_command.rb +108 -102
- 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 +18 -17
- data/lib/rigor/cli/explain_command.rb +18 -8
- data/lib/rigor/cli/fused_protection_renderer.rb +2 -1
- data/lib/rigor/cli/json_document.rb +41 -0
- data/lib/rigor/cli/lens_command.rb +12 -8
- 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 +84 -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 +1 -1
- data/lib/rigor/cli/trace_command.rb +14 -9
- data/lib/rigor/cli/triage_command.rb +10 -11
- data/lib/rigor/cli/triage_renderer.rb +2 -1
- data/lib/rigor/cli/type_of_command.rb +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 +209 -54
- data/lib/rigor/config_audit.rb +1 -1
- data/lib/rigor/configuration/severity_profile.rb +5 -5
- data/lib/rigor/configuration.rb +72 -30
- data/lib/rigor/effects/definition_context.rb +0 -2
- data/lib/rigor/effects/envelope.rb +1 -1
- data/lib/rigor/effects/framework_units.rb +1 -1
- data/lib/rigor/effects/mutation_classifier.rb +4 -7
- data/lib/rigor/effects/propagator.rb +1 -1
- data/lib/rigor/effects/registry.rb +2 -2
- data/lib/rigor/effects/snapshot.rb +1 -1
- data/lib/rigor/effects/taint_cause.rb +0 -2
- data/lib/rigor/effects/unit_scan.rb +9 -13
- data/lib/rigor/environment/bundle_sig_discovery.rb +5 -9
- data/lib/rigor/environment/class_registry.rb +3 -3
- data/lib/rigor/environment/core_root.rb +77 -0
- data/lib/rigor/environment/default_libraries.rb +1 -1
- data/lib/rigor/environment/deferred_signature_plan.rb +283 -0
- data/lib/rigor/environment/gated_signature_guard.rb +1 -1
- data/lib/rigor/environment/gated_signature_plan.rb +5 -2
- data/lib/rigor/environment/lockfile_resolver.rb +28 -12
- data/lib/rigor/environment/member_consistency/comparator.rb +18 -1
- data/lib/rigor/environment/member_consistency.rb +56 -7
- data/lib/rigor/environment/missing_gem_constant_index.rb +3 -2
- data/lib/rigor/environment/project_path_gems.rb +124 -0
- data/lib/rigor/environment/rbs_hierarchy.rb +6 -15
- data/lib/rigor/environment/rbs_loader.rb +480 -67
- 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 +41 -10
- data/lib/rigor/flow_contribution/merger.rb +4 -4
- data/lib/rigor/inference/acceptance.rb +93 -32
- data/lib/rigor/inference/block_parameter_binder.rb +2 -3
- data/lib/rigor/inference/block_run_count.rb +178 -0
- data/lib/rigor/inference/budget_trace.rb +8 -2
- data/lib/rigor/inference/builtins/exception_catalog.rb +2 -2
- data/lib/rigor/inference/builtins/numeric_catalog.rb +2 -5
- data/lib/rigor/inference/builtins/random_catalog.rb +2 -2
- data/lib/rigor/inference/callee_mutation_chain.rb +88 -77
- data/lib/rigor/inference/callee_write_census.rb +815 -0
- data/lib/rigor/inference/construction_escape.rb +217 -0
- data/lib/rigor/inference/declaration_walk/traversal.rb +1 -1
- data/lib/rigor/inference/deep_erasure.rb +39 -7
- data/lib/rigor/inference/def_handle.rb +1 -1
- data/lib/rigor/inference/def_node_resolver.rb +1 -1
- data/lib/rigor/inference/def_return_typer.rb +46 -4
- data/lib/rigor/inference/definer_resolution.rb +4 -2
- data/lib/rigor/inference/definers_index.rb +106 -0
- data/lib/rigor/inference/direct_ivar_writes.rb +300 -0
- data/lib/rigor/inference/element_read_widening.rb +49 -3
- data/lib/rigor/inference/expression_typer.rb +116 -49
- data/lib/rigor/inference/external_ancestor_resolution.rb +3 -4
- data/lib/rigor/inference/global_write_census.rb +76 -2
- data/lib/rigor/inference/global_writer_reach.rb +260 -0
- data/lib/rigor/inference/hkt_body.rb +1 -2
- data/lib/rigor/inference/hkt_body_parser.rb +3 -5
- data/lib/rigor/inference/hkt_reducer.rb +2 -2
- data/lib/rigor/inference/hkt_registry.rb +3 -5
- data/lib/rigor/inference/indexed_narrowing.rb +4 -7
- data/lib/rigor/inference/intervening_ivar_reset.rb +26 -4
- data/lib/rigor/inference/ivar_writer_census.rb +51 -0
- data/lib/rigor/inference/key_presence_guard.rb +2 -1
- data/lib/rigor/inference/loop_value_record.rb +8 -4
- data/lib/rigor/inference/match_rebinding/frame.rb +46 -0
- data/lib/rigor/inference/match_rebinding/yielding_match.rb +45 -0
- data/lib/rigor/inference/match_rebinding.rb +11 -1
- data/lib/rigor/inference/memo_audit.rb +55 -0
- data/lib/rigor/inference/method_dispatcher/alias_strict_nominals.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/argument_distribution.rb +40 -0
- data/lib/rigor/inference/method_dispatcher/block_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/constant_folding.rb +3 -3
- data/lib/rigor/inference/method_dispatcher/contested_overloads.rb +89 -0
- data/lib/rigor/inference/method_dispatcher/iterator_dispatch.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/kernel_dispatch.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/no_match_fallback.rb +54 -0
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +39 -27
- data/lib/rigor/inference/method_dispatcher/random_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +203 -17
- data/lib/rigor/inference/method_dispatcher/reduce_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/regexp_folding.rb +2 -2
- data/lib/rigor/inference/method_dispatcher/self_substitute.rb +2 -2
- data/lib/rigor/inference/method_dispatcher/set_folding.rb +9 -7
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +83 -20
- data/lib/rigor/inference/method_dispatcher/singleton_folding.rb +0 -1
- data/lib/rigor/inference/method_dispatcher/singleton_mixin_dispatch.rb +50 -17
- data/lib/rigor/inference/method_dispatcher/struct_folding.rb +5 -5
- data/lib/rigor/inference/method_dispatcher/struct_materialization.rb +4 -6
- data/lib/rigor/inference/method_dispatcher/uri_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher.rb +64 -14
- data/lib/rigor/inference/module_function_state.rb +11 -1
- data/lib/rigor/inference/multi_target_binder.rb +1 -1
- data/lib/rigor/inference/mutation_rejoin.rb +240 -4
- data/lib/rigor/inference/mutation_widening.rb +157 -27
- data/lib/rigor/inference/narrowing.rb +47 -33
- data/lib/rigor/inference/optimistic_origin.rb +1 -1
- data/lib/rigor/inference/out_buffer_mutation.rb +72 -0
- data/lib/rigor/inference/parameter_inference_collector.rb +5 -6
- data/lib/rigor/inference/pre_eval_constants.rb +1 -1
- data/lib/rigor/inference/project_method_ownership.rb +6 -3
- data/lib/rigor/inference/project_yielder.rb +11 -17
- data/lib/rigor/inference/receiver_alias.rb +20 -0
- data/lib/rigor/inference/refined_dispatch/constructed_class.rb +3 -1
- data/lib/rigor/inference/refined_dispatch/own_method.rb +2 -1
- data/lib/rigor/inference/remover_holder_scan.rb +233 -0
- data/lib/rigor/inference/remover_narrowing.rb +224 -0
- data/lib/rigor/inference/rewrite_mutation.rb +53 -2
- data/lib/rigor/inference/scope_indexer/certainty.rb +0 -1
- data/lib/rigor/inference/scope_indexer/constant_ivar_value.rb +93 -0
- data/lib/rigor/inference/scope_indexer/declared_param_writes.rb +58 -15
- data/lib/rigor/inference/scope_indexer/derived_param_value.rb +112 -0
- data/lib/rigor/inference/scope_indexer/empty_seed.rb +99 -0
- data/lib/rigor/inference/scope_indexer/ivar_contributions.rb +135 -0
- data/lib/rigor/inference/scope_indexer.rb +137 -46
- data/lib/rigor/inference/self_call_ivar_writes.rb +84 -12
- data/lib/rigor/inference/set_mutation.rb +189 -0
- data/lib/rigor/inference/singleton_hook_decline.rb +1 -2
- data/lib/rigor/inference/statement_evaluator.rb +2328 -138
- data/lib/rigor/inference/struct_fold_safety.rb +4 -6
- data/lib/rigor/inference/synthetic_method_scanner.rb +5 -6
- data/lib/rigor/inference/toplevel_def_census.rb +59 -0
- data/lib/rigor/inference/unknown_store_widening.rb +103 -4
- data/lib/rigor/inference/unthreaded_rebinds.rb +2 -3
- data/lib/rigor/inference/void_tail_summary.rb +2 -1
- data/lib/rigor/language_server/buffer_table.rb +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/plugins.rb +1 -1
- data/lib/rigor/mcp/server.rb +73 -2
- data/lib/rigor/mcp.rb +1 -1
- data/lib/rigor/plugin/access_denied_error.rb +1 -2
- data/lib/rigor/plugin/bundled_catalog.rb +1 -12
- data/lib/rigor/plugin/io_boundary.rb +1 -1
- data/lib/rigor/plugin/loader.rb +25 -8
- data/lib/rigor/plugin/macro/heredoc_template.rb +7 -8
- data/lib/rigor/plugin/macro/trait_registry.rb +6 -9
- data/lib/rigor/plugin/manifest.rb +9 -13
- data/lib/rigor/plugin/registry.rb +3 -3
- data/lib/rigor/plugin/services.rb +2 -3
- data/lib/rigor/plugin/source_rbs_synthesis_reporter.rb +11 -0
- data/lib/rigor/plugin/trust_policy.rb +2 -2
- data/lib/rigor/plugin/type_node_resolver.rb +2 -4
- data/lib/rigor/plugin.rb +6 -8
- data/lib/rigor/plugin_gap_advisory.rb +5 -1
- data/lib/rigor/project_environment.rb +16 -2
- data/lib/rigor/protection/analysis_guard.rb +1 -1
- data/lib/rigor/protection/discovery_seed.rb +44 -5
- data/lib/rigor/protection/mutator.rb +1 -1
- data/lib/rigor/rbs_extended/envelope_scanner.rb +4 -6
- data/lib/rigor/rbs_extended/hkt_directives.rb +6 -10
- data/lib/rigor/rbs_extended/reporter.rb +27 -3
- data/lib/rigor/rbs_extended.rb +2 -3
- data/lib/rigor/reflection/constant_ancestors.rb +5 -3
- data/lib/rigor/rooted_glob.rb +15 -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 +19 -6
- data/lib/rigor/scope/resolution_chain.rb +3 -1
- data/lib/rigor/scope.rb +365 -31
- data/lib/rigor/sig_gen/classification.rb +4 -0
- data/lib/rigor/sig_gen/effect_annotation.rb +3 -3
- data/lib/rigor/sig_gen/generator.rb +371 -58
- data/lib/rigor/sig_gen/generic_header_scan.rb +189 -0
- data/lib/rigor/sig_gen/inline_declarations.rb +2 -2
- data/lib/rigor/sig_gen/layout_index.rb +3 -3
- data/lib/rigor/sig_gen/method_candidate.rb +23 -4
- data/lib/rigor/sig_gen/observation_collector.rb +3 -5
- 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/renderer.rb +15 -9
- data/lib/rigor/sig_gen/skip_reason_catalog.rb +15 -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 +217 -37
- data/lib/rigor/type/acceptance_router.rb +2 -2
- data/lib/rigor/type/accepts_result.rb +1 -1
- data/lib/rigor/type/app.rb +4 -6
- data/lib/rigor/type/combinator.rb +9 -13
- data/lib/rigor/type/constant.rb +4 -5
- data/lib/rigor/type/hash_shape.rb +21 -40
- data/lib/rigor/type/union.rb +1 -1
- data/lib/rigor/type_node/identifier.rb +1 -2
- data/lib/rigor/type_node/resolver_chain.rb +1 -1
- data/lib/rigor/type_node/string_literal.rb +1 -2
- data/lib/rigor/type_node/symbol_literal.rb +1 -2
- data/lib/rigor/type_node/union.rb +3 -6
- data/lib/rigor/value_semantics.rb +1 -10
- data/lib/rigor/version.rb +1 -1
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_discoverer.rb +2 -2
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_index.rb +2 -3
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +1 -1
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_discoverer.rb +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 +1 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +66 -19
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/effects.rb +1 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +4 -3
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/association_roots.rb +3 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/effects.rb +2 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +21 -31
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_index.rb +10 -16
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_parser.rb +2 -3
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_table.rb +0 -1
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +5 -4
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_discoverer.rb +3 -4
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_index.rb +1 -1
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +7 -12
- data/plugins/rigor-activestorage/lib/rigor-activestorage.rb +1 -1
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext/effects.rb +1 -1
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext/symbolize_keys.rb +102 -0
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb +19 -6
- data/plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs +26 -13
- data/plugins/rigor-alba/lib/rigor/plugin/alba/resource_index.rb +3 -3
- data/plugins/rigor-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 +4 -5
- data/plugins/rigor-grape/lib/rigor/plugin/grape.rb +0 -2
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql/type_scanner.rb +6 -7
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami/action_checker.rb +2 -4
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami.rb +2 -5
- data/plugins/rigor-mangrove/lib/rigor/plugin/mangrove.rb +2 -2
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest/assertion_analyzer.rb +6 -6
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_discoverer.rb +2 -1
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/analyzer.rb +3 -8
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_index.rb +2 -3
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_loader.rb +5 -8
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/analyzer.rb +1 -3
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/devise_routes.rb +2 -3
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_discoverer.rb +1 -1
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/routes_parser.rb +4 -11
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +1 -1
- data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb +2 -1
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +1 -1
- 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 +1 -1
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sig_parser.rb +2 -2
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +17 -21
- data/plugins/rigor-statesman/lib/rigor/plugin/statesman.rb +2 -3
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer/serializer_discoverer.rb +3 -2
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer/serializer_index.rb +4 -4
- data/sig/rigor/analysis/baseline.rbs +0 -3
- data/sig/rigor/analysis/fact_store.rbs +1 -0
- data/sig/rigor/analysis/reachability/scan_cache.rbs +1 -1
- data/sig/rigor/cli/diff_command.rbs +1 -1
- data/sig/rigor/cli/explain_command.rbs +1 -1
- data/sig/rigor/effects/registry.rbs +2 -2
- data/sig/rigor/inference.rbs +4 -1
- data/sig/rigor/plugin/additional_initializer.rbs +0 -5
- data/sig/rigor/plugin/base.rbs +1 -0
- 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/io_boundary.rbs +2 -1
- data/sig/rigor/plugin/manifest.rbs +9 -9
- data/sig/rigor/plugin/protocol_contract.rbs +3 -7
- data/sig/rigor/scope.rbs +23 -3
- data/skills/rigor-plugin-author/SKILL.md +4 -4
- data/skills/rigor-plugin-author/references/02-walker-and-types.md +5 -5
- data/skills/rigor-plugin-review/SKILL.md +3 -3
- data/skills/rigor-project-init/references/03-baseline-and-bugs.md +12 -1
- metadata +36 -3
|
@@ -8,6 +8,7 @@ require_relative "engine_source"
|
|
|
8
8
|
require_relative "store"
|
|
9
9
|
require_relative "../analysis/shadow_harness"
|
|
10
10
|
require_relative "../analysis/run_cache_key"
|
|
11
|
+
require_relative "../analysis/runner/run_level_facts"
|
|
11
12
|
require_relative "../environment"
|
|
12
13
|
require_relative "../analysis/path_expansion"
|
|
13
14
|
require_relative "../rooted_glob"
|
|
@@ -195,20 +196,26 @@ module Rigor
|
|
|
195
196
|
# 45: issue #1154 — each seed bundle's `global_write_census` also records the ivar writers the declared-parameter
|
|
196
197
|
# credit reads (`[:ivar_set, name]`, `[:ivar_set_class, class]`, `[:own_write, class, name, path]`), which a
|
|
197
198
|
# pre-45 bundle carries none of, so a warm run would credit an ivar write a cold run declines.
|
|
198
|
-
|
|
199
|
+
# 46: issue #2314 — each seed bundle's `global_write_census` also records the global writers
|
|
200
|
+
# (`[:global_writer, name, method]`) the statement walk reads past a call; a pre-46 bundle carries none, so a
|
|
201
|
+
# warm run would keep a global's binding a cold run forgets.
|
|
202
|
+
# 47: issues #2079 / #2170 — each seed bundle's `global_write_census` also records each instance-side ivar
|
|
203
|
+
# write's coarse value (`[:own_write_type, class, name, value, path]`), which the class-ivar census joins across
|
|
204
|
+
# files and along the chain; a pre-47 bundle carries none, so a warm run would keep a seed a cold run widens.
|
|
205
|
+
SCHEMA = 47
|
|
199
206
|
|
|
200
207
|
# The persisted per-file state.
|
|
201
208
|
# `cache` maps an analyzed file to its diagnostics.
|
|
202
|
-
# `sources` maps a consumer to the
|
|
209
|
+
# `sources` maps a consumer to the source files it read from.
|
|
203
210
|
# `digests` maps a file to its content digest at analysis time.
|
|
204
211
|
# `analyzed` is the ordered analyzed-file list.
|
|
205
212
|
# ADR-46 slice 4:
|
|
206
|
-
# `symbol_sources` maps a consumer to { source_path →
|
|
207
|
-
# `ancestry_sources` maps a consumer to
|
|
213
|
+
# `symbol_sources` maps a consumer to { source_path → the "ClassName#method" names it read }.
|
|
214
|
+
# `ancestry_sources` maps a consumer to the source paths it read for class ancestry.
|
|
208
215
|
# `symbol_fingerprints` maps a path to { "ClassName#method" => sha256_hex }.
|
|
209
216
|
# ADR-46 slice 3:
|
|
210
|
-
# `missing` maps a consumer to
|
|
211
|
-
# `class_decls` maps a path to
|
|
217
|
+
# `missing` maps a consumer to the "kind:name" keys it looked up and missed.
|
|
218
|
+
# `class_decls` maps a path to the qualified class names it declares.
|
|
212
219
|
# Issue #644:
|
|
213
220
|
# `constant_decls` maps a path to that file's constant PUBLICATION CENSUS,
|
|
214
221
|
# `{qualified name => [literal] | :unpublishable}`. The descriptor is what the recheck diffs: a name's
|
|
@@ -279,12 +286,14 @@ module Rigor
|
|
|
279
286
|
end
|
|
280
287
|
end
|
|
281
288
|
|
|
282
|
-
# Issues #796 / #794 — the
|
|
283
|
-
#
|
|
284
|
-
#
|
|
285
|
-
#
|
|
286
|
-
#
|
|
287
|
-
|
|
289
|
+
# Issues #796 / #794 — the run-level rows the snapshot carries: one member per run-level fact declared
|
|
290
|
+
# `replay` ({Analysis::Runner::RunLevelFacts}, ADR-116 WD3). Today that is `definition_build_failures`,
|
|
291
|
+
# the reported per-class detail list ({Environment::RbsLoader#definition_build_failures}), and
|
|
292
|
+
# `hkt_scan_failure`, the `[error_class, first_line, frame, stage]` tuple
|
|
293
|
+
# ({Rigor::Environment#hkt_scan_failure}), nil when the scan succeeded — which is why the presence of
|
|
294
|
+
# this object, not the tuple, is what says a replay is available. Declaring another fact `replay`
|
|
295
|
+
# changes this shape, so it bumps {SCHEMA}.
|
|
296
|
+
RunLevelRows = Data.define(*Analysis::Runner::RunLevelFacts.replayable_names)
|
|
288
297
|
|
|
289
298
|
# The global fingerprint that gates a snapshot load: a digest of the inputs whose change requires a full
|
|
290
299
|
# rebuild — the engine version + schema, the engine's own SOURCE when the version does not pin it, the
|
|
@@ -324,6 +333,7 @@ module Rigor
|
|
|
324
333
|
"sig:#{digest_signature_paths(project_sig_roots(configuration))}",
|
|
325
334
|
"pre_eval:#{digest_pre_eval(configuration.pre_eval)}"
|
|
326
335
|
]
|
|
336
|
+
parts.concat(core_root_parts(configuration))
|
|
327
337
|
parts.concat(dependency_source_parts(configuration))
|
|
328
338
|
identity = EngineSource.process_identity
|
|
329
339
|
parts << "engine-source:#{identity}" if identity
|
|
@@ -347,6 +357,15 @@ module Rigor
|
|
|
347
357
|
nil
|
|
348
358
|
end
|
|
349
359
|
|
|
360
|
+
# Issue #2517 — a selected core is read like the project's own `sig/`, so an edit in place to one of its files
|
|
361
|
+
# must drop the snapshot (and the language server's session, which keys on this fingerprint). No part for the
|
|
362
|
+
# default core, so every other project's fingerprint is as it was.
|
|
363
|
+
def self.core_root_parts(configuration)
|
|
364
|
+
core_root = configuration.core_root
|
|
365
|
+
core_root.nil? ? [] : ["core:#{digest_signature_paths([core_root])}"]
|
|
366
|
+
end
|
|
367
|
+
private_class_method :core_root_parts
|
|
368
|
+
|
|
350
369
|
def self.required_features(configuration, roots)
|
|
351
370
|
files = Analysis::PathExpansion.ruby_files(roots, configuration.exclude_patterns,
|
|
352
371
|
base: configuration.exclude_base)
|
|
@@ -6,8 +6,8 @@ module Rigor
|
|
|
6
6
|
module Cache
|
|
7
7
|
# Base for the RBS-derived cache producers.
|
|
8
8
|
#
|
|
9
|
-
# Every producer (`RbsKnownClassNames`, `RbsConstantTable`, `RbsEnvironment`, the ancestor / type-param
|
|
10
|
-
#
|
|
9
|
+
# Every producer (`RbsKnownClassNames`, `RbsConstantTable`, `RbsEnvironment`, the ancestor / type-param
|
|
10
|
+
# tables, …) repeated the identical `fetch` wiring: build the RBS descriptor, then
|
|
11
11
|
# `store.fetch_or_compute` under the producer's id, yielding to the producer's `compute`. Only the
|
|
12
12
|
# `PRODUCER_ID` constant and the `compute(loader)` body actually differ between producers.
|
|
13
13
|
#
|
|
@@ -6,7 +6,7 @@ require_relative "rbs_cache_producer"
|
|
|
6
6
|
module Rigor
|
|
7
7
|
module Cache
|
|
8
8
|
# Cache producer that materialises the RBS-declared ancestor chain of every loaded class / module into a
|
|
9
|
-
# Marshal-clean
|
|
9
|
+
# Marshal-clean table. Ancestor names are top-level-stripped (e.g. `"Integer"` not
|
|
10
10
|
# `"::Integer"`) to match `Environment::RbsHierarchy#normalize_name`.
|
|
11
11
|
#
|
|
12
12
|
# The hierarchy is the substrate behind every `class_ordering` query, which is itself a hot path on the
|
|
@@ -6,8 +6,8 @@ require_relative "rbs_cache_producer"
|
|
|
6
6
|
module Rigor
|
|
7
7
|
module Cache
|
|
8
8
|
# Cache producer that materialises every loaded class's RBS-declared type-parameter names as a
|
|
9
|
-
# Marshal-clean
|
|
10
|
-
# `[:Elem]`, `"Hash"` → `[:K, :V]`).
|
|
9
|
+
# Marshal-clean table keyed by top-level-stripped class name (e.g. `"Array"` →
|
|
10
|
+
# `[:Elem]`, `"Hash"` → `[:K, :V]`).
|
|
11
11
|
#
|
|
12
12
|
# The dispatcher reads type-parameter names every time it builds a substitution map from a receiver's
|
|
13
13
|
# `type_args` into a method's return type — it is one of the hottest reflection lookups during analysis.
|
|
@@ -6,7 +6,7 @@ require_relative "rbs_cache_producer"
|
|
|
6
6
|
module Rigor
|
|
7
7
|
module Cache
|
|
8
8
|
# Cache producer that materialises every RBS-declared constant to its translated `Rigor::Type` form and
|
|
9
|
-
# stores the result as a
|
|
9
|
+
# stores the result as a table keyed by canonical constant name. This is the v0.0.8
|
|
10
10
|
# first cached producer per ADR-6 § 7; it caches a post-translation artefact so the cache value is
|
|
11
11
|
# `Marshal`-clean (RBS-native objects carry `RBS::Location`, which lacks `_dump_data`).
|
|
12
12
|
#
|
|
@@ -77,9 +77,57 @@ module Rigor
|
|
|
77
77
|
# reconstructs {.config_entries} without loading a plugin, so an entry there that it cannot rebuild
|
|
78
78
|
# would turn the warm fast lane into a permanent miss on every project that enables a bundled plugin.
|
|
79
79
|
def self.env_only_config_entries(loader)
|
|
80
|
-
[deferred_signature_paths_entry(loader)].compact
|
|
80
|
+
[deferred_signature_paths_entry(loader), project_signature_paths_entry(loader), core_root_entry(loader)].compact
|
|
81
81
|
end
|
|
82
82
|
|
|
83
|
+
# Issue #2517 — which directory the env loaded core from. The selected core's files are digested by
|
|
84
|
+
# {.file_entries} too, so this row is the identity of the choice and those rows its contents: switching
|
|
85
|
+
# between two roots with byte-identical files still re-keys. Absent for the default core, whose identity
|
|
86
|
+
# is the `rbs` gem row, so every project without the setting keeps its key.
|
|
87
|
+
def self.core_root_entry(loader)
|
|
88
|
+
core_root = selected_core_root(loader)
|
|
89
|
+
return nil if core_root.nil?
|
|
90
|
+
|
|
91
|
+
Descriptor::ConfigEntry.new(key: "rbs.core_root", value_hash: Digest::SHA256.hexdigest(core_root.to_s))
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
private_class_method :core_root_entry
|
|
95
|
+
|
|
96
|
+
# The loader's issue #2517 core root as a Pathname, or nil for the default core.
|
|
97
|
+
def self.selected_core_root(loader)
|
|
98
|
+
core_root = loader.respond_to?(:core_root) ? loader.core_root : nil
|
|
99
|
+
core_root.nil? ? nil : Pathname(core_root)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
private_class_method :selected_core_root
|
|
103
|
+
|
|
104
|
+
# {.selected_core_root} as the signature roots it adds: none for the default core.
|
|
105
|
+
def self.core_root_dirs(loader)
|
|
106
|
+
core_root = selected_core_root(loader)
|
|
107
|
+
core_root.nil? ? [] : [core_root]
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
private_class_method :core_root_dirs
|
|
111
|
+
|
|
112
|
+
# Issue #2422 — which of the loader's `signature_paths:` are the project's own changes the env built from
|
|
113
|
+
# byte-identical files: a bundled plugin's method composes with another source's as an overload, but stands
|
|
114
|
+
# down to the project's own. Only read when a plugin defers signatures, so a project without one keeps its
|
|
115
|
+
# key.
|
|
116
|
+
def self.project_signature_paths_entry(loader)
|
|
117
|
+
return nil unless loader.respond_to?(:project_signature_paths) && loader.respond_to?(:deferred_signature_paths)
|
|
118
|
+
return nil if Array(loader.deferred_signature_paths).empty?
|
|
119
|
+
|
|
120
|
+
own = Array(loader.project_signature_paths).map(&:to_s).sort
|
|
121
|
+
return nil if own.empty?
|
|
122
|
+
|
|
123
|
+
Descriptor::ConfigEntry.new(
|
|
124
|
+
key: "rbs.project_signature_paths",
|
|
125
|
+
value_hash: Digest::SHA256.hexdigest(own.join("\n"))
|
|
126
|
+
)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
private_class_method :project_signature_paths_entry
|
|
130
|
+
|
|
83
131
|
def self.deferred_signature_paths_entry(loader)
|
|
84
132
|
return nil unless loader.respond_to?(:deferred_signature_paths)
|
|
85
133
|
|
|
@@ -104,7 +152,9 @@ module Rigor
|
|
|
104
152
|
# value must be deterministic; `:stat` (ADR-87 WD1) for the validation-only run-dependency descriptor
|
|
105
153
|
# ({RunDescriptor#files}), where the stat tier short-circuits the SHA-256 on an unmoved file.
|
|
106
154
|
def self.file_entries(loader, comparator: :digest)
|
|
107
|
-
|
|
155
|
+
# Issue #2517 — a selected core is project input like `signature_paths:`, not the engine-versioned `rbs`
|
|
156
|
+
# gem tree, so an edit in place must move the key.
|
|
157
|
+
roots = core_root_dirs(loader) + loader.signature_paths +
|
|
108
158
|
Rigor::Environment::RbsLoader.vendored_gem_sig_paths +
|
|
109
159
|
Rigor::Environment::RbsLoader.core_overlay_sig_paths +
|
|
110
160
|
Rigor::Environment::RbsLoader.capability_role_sig_paths
|
|
@@ -149,7 +199,8 @@ module Rigor
|
|
|
149
199
|
def self.glob_entries(loader)
|
|
150
200
|
# Deduplicated by path: a root reachable twice (an explicit `signature_paths:` entry that is also a
|
|
151
201
|
# bundled plugin's `sig/`, #610) would otherwise contribute two rows whose stat signatures race.
|
|
152
|
-
|
|
202
|
+
# Issue #2517 — and the selected core's root, where a file appearing is as much a new input.
|
|
203
|
+
(core_root_dirs(loader) + loader.signature_paths).uniq(&:to_s).filter_map do |root|
|
|
153
204
|
next unless root.directory?
|
|
154
205
|
|
|
155
206
|
Descriptor::GlobEntry.compute(root: root.to_s, pattern: File.join("**", "*.rbs"), mode: :names)
|
|
@@ -33,7 +33,10 @@ module Rigor
|
|
|
33
33
|
signature_paths: loader.signature_paths,
|
|
34
34
|
virtual_rbs: loader.respond_to?(:virtual_rbs) ? loader.virtual_rbs : [],
|
|
35
35
|
deferred_signature_paths:
|
|
36
|
-
loader.respond_to?(:deferred_signature_paths) ? loader.deferred_signature_paths : []
|
|
36
|
+
loader.respond_to?(:deferred_signature_paths) ? loader.deferred_signature_paths : [],
|
|
37
|
+
project_signature_paths:
|
|
38
|
+
loader.respond_to?(:project_signature_paths) ? loader.project_signature_paths : [],
|
|
39
|
+
core_root: loader.respond_to?(:core_root) ? loader.core_root : nil
|
|
37
40
|
)
|
|
38
41
|
end
|
|
39
42
|
|
|
@@ -53,8 +53,8 @@ require_relative "annotation_location"
|
|
|
53
53
|
# differently, and only the latter reaches `marshal_load`), so without the bump a stale blob would keep
|
|
54
54
|
# reporting the moved position indefinitely.
|
|
55
55
|
#
|
|
56
|
-
# Idempotent:
|
|
57
|
-
# rbs that adds Marshal hooks itself) is a no-op.
|
|
56
|
+
# Idempotent: each hook is defined only when `method_defined?` reports it missing, so requiring this file twice
|
|
57
|
+
# (or against an upstream rbs that adds Marshal hooks itself) is a no-op.
|
|
58
58
|
#
|
|
59
59
|
# `RBS::TypeName` / `RBS::Namespace` carry a second, subtler Marshal hazard, introduced by rbs 4.1's
|
|
60
60
|
# flyweight interning (ruby/rbs#2957): both memoise their `#hash` into an `@hash` ivar, and that value is
|
|
@@ -7,7 +7,7 @@ module Rigor
|
|
|
7
7
|
module Cache
|
|
8
8
|
# Cache producer that materialises the set of every RBS-declared class / module / alias name (top-level
|
|
9
9
|
# prefixed, e.g. `"::Math"`) currently loaded into the environment. Marshal-clean — the cache value is a
|
|
10
|
-
#
|
|
10
|
+
# Set of names.
|
|
11
11
|
#
|
|
12
12
|
# The set lets `RbsLoader#class_known?` answer point lookups in O(1) without re-parsing the name on each
|
|
13
13
|
# call, and lets a warm process skip the env walk entirely (the env still has to be built to enumerate
|
data/lib/rigor/cache/store.rb
CHANGED
|
@@ -135,14 +135,6 @@ module Rigor
|
|
|
135
135
|
end
|
|
136
136
|
end
|
|
137
137
|
|
|
138
|
-
# Walks the on-disk cache rooted at `root` and reports a producer-level inventory. Used by
|
|
139
|
-
# `rigor check --cache-stats` to surface cache size and per-producer entry counts without depending on
|
|
140
|
-
# in-process counters (which only reflect the current run).
|
|
141
|
-
#
|
|
142
|
-
# @return `{ root:, schema_version:, total_entries:, total_bytes:, producers: [{ id:, entries:,
|
|
143
|
-
# bytes: }, ...] }`. When the root does not exist or has no schema-version marker, `schema_version` is
|
|
144
|
-
# nil and the producer list is empty.
|
|
145
|
-
#
|
|
146
138
|
# The `schema_version.txt` marker content. Covers BOTH invalidation axes: the descriptor schema and the
|
|
147
139
|
# on-disk byte layout ({FORMAT_VERSION}, ADR-54). A format bump leaves the old entries permanently
|
|
148
140
|
# unreadable (header mismatch → miss) but, alone, would never reclaim their bytes — they can sit below
|
|
@@ -152,6 +144,13 @@ module Rigor
|
|
|
152
144
|
"#{PAYLOAD_ABI_VERSION}.#{Descriptor::SCHEMA_VERSION}.#{FORMAT_VERSION}"
|
|
153
145
|
end
|
|
154
146
|
|
|
147
|
+
# Walks the on-disk cache rooted at `root` and reports a producer-level inventory. Used by
|
|
148
|
+
# `rigor check --cache-stats` to surface cache size and per-producer entry counts without depending on
|
|
149
|
+
# in-process counters (which only reflect the current run).
|
|
150
|
+
#
|
|
151
|
+
# @return `{ root:, schema_version:, total_entries:, total_bytes:, producers: [{ id:, entries:,
|
|
152
|
+
# bytes: }, ...] }`. When the root does not exist or has no schema-version marker, `schema_version` is
|
|
153
|
+
# nil and the producer list is empty.
|
|
155
154
|
def self.disk_inventory(root:)
|
|
156
155
|
root_s = root.to_s
|
|
157
156
|
marker = File.join(root_s, "schema_version.txt")
|
|
@@ -360,7 +359,8 @@ module Rigor
|
|
|
360
359
|
# size-based LRU pass below stays gated on `max_bytes:` being configured: it walks all remaining
|
|
361
360
|
# `.entry` files, sorts by mtime ascending (oldest = least recently used), and unlinks from the oldest
|
|
362
361
|
# until the total is at or below the cap. Touch-on-disk-read ({read_entry}) is the cross-process LRU
|
|
363
|
-
# signal:
|
|
362
|
+
# signal: a disk hit (not an in-process-memo hit) updates the mtime when `max_bytes:` is set, so
|
|
363
|
+
# recently-read entries survive
|
|
364
364
|
# the eviction pass. Any FS error is swallowed — eviction must never break a run.
|
|
365
365
|
def evict!
|
|
366
366
|
return if @read_only
|
|
@@ -591,7 +591,8 @@ module Rigor
|
|
|
591
591
|
# — one check per Store is enough; a benign double-check under a thread race would just repeat
|
|
592
592
|
# idempotent work.
|
|
593
593
|
#
|
|
594
|
-
# A writable store clears the cache root and rewrites the marker on a stale
|
|
594
|
+
# A writable store clears the cache root and rewrites the marker on a stale marker (a missing or empty
|
|
595
|
+
# one is rewritten without clearing), then reports
|
|
595
596
|
# available. A read-only store never touches the root — no mkdir, no marker write, no destructive clear
|
|
596
597
|
# — so it reports available ONLY when the on-disk marker already matches current exactly; a stale or
|
|
597
598
|
# missing marker (e.g. a Rigor upgrade with no writable run yet, as in LSP / editor mode) reports
|
data/lib/rigor/ci_detector.rb
CHANGED
|
@@ -20,7 +20,7 @@ module Rigor
|
|
|
20
20
|
# non-CLI consumers exist: {Configuration#cache_validation_strict?} resolves the `auto` cache-validation default
|
|
21
21
|
# through it (a fresh CI checkout regenerates every stat tuple, so ADR-87's stat tier cannot work there).
|
|
22
22
|
# Detection is fully testable; callers pass `ENV`.
|
|
23
|
-
# `RIGOR_CI_DETECT=0` (or `false`/`no`) disables it globally — the seam the spec suite uses for determinism.
|
|
23
|
+
# `RIGOR_CI_DETECT=0` (or `false`/`no`/`off`) disables it globally — the seam the spec suite uses for determinism.
|
|
24
24
|
module CiDetector
|
|
25
25
|
Platform = Struct.new(:id, :name, :format, :tier, keyword_init: true) do
|
|
26
26
|
def native_stdout? = tier == :native_stdout
|
|
@@ -16,6 +16,7 @@ require_relative "../inference/statement_evaluator"
|
|
|
16
16
|
require_relative "prism_colorizer"
|
|
17
17
|
require_relative "command"
|
|
18
18
|
require_relative "../project_environment"
|
|
19
|
+
require_relative "json_document"
|
|
19
20
|
|
|
20
21
|
module Rigor
|
|
21
22
|
class CLI
|
|
@@ -32,10 +33,12 @@ module Rigor
|
|
|
32
33
|
class AnnotateCommand < Command
|
|
33
34
|
USAGE = "Usage: rigor annotate [options] FILE"
|
|
34
35
|
|
|
35
|
-
# Trailing `#=> …` annotation comment
|
|
36
|
-
#
|
|
37
|
-
#
|
|
38
|
-
#
|
|
36
|
+
# Trailing `#=> …` annotation comment, matched and stripped before re-annotating so re-running is idempotent.
|
|
37
|
+
# Follows xmpfilter's convention of owning the `#=>` marker, and also absorbs the older `#=> dump_type: <type>`
|
|
38
|
+
# spelling.
|
|
39
|
+
# Strips the first `#=>` that is preceded by whitespace and followed by whitespace or the end of the line,
|
|
40
|
+
# together with that preceding whitespace, through the end of the line. A string literal is not special-cased,
|
|
41
|
+
# since the pattern does not parse Ruby; `a#=>b` and `x #=>y` are left alone.
|
|
39
42
|
ANNOTATION_PATTERN = /\s+#=>(?:\s.*)?\z/
|
|
40
43
|
|
|
41
44
|
# Arguments for highlighting through `bat`: the annotated text arrives on stdin, so the language must be explicit;
|
|
@@ -59,19 +62,13 @@ module Rigor
|
|
|
59
62
|
execute(file, options)
|
|
60
63
|
end
|
|
61
64
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def
|
|
65
|
-
|
|
66
|
-
options = { config: nil, color: @out.tty? && !no_color_env?, bat: nil, format: :text }
|
|
67
|
-
|
|
68
|
-
parser = OptionParser.new do |opts|
|
|
65
|
+
# The parser this command parses with, built without parsing anything: the catalogue reads the
|
|
66
|
+
# flags and formats from it (ADR-126 WD3). `options` is only written by the switches' blocks.
|
|
67
|
+
def option_parser(options = {})
|
|
68
|
+
OptionParser.new do |opts|
|
|
69
69
|
opts.banner = USAGE
|
|
70
70
|
Options.add_config(opts, options)
|
|
71
|
-
|
|
72
|
-
"Output format: text (default) or json (a { line => type } map)") do |value|
|
|
73
|
-
options[:format] = value.to_sym
|
|
74
|
-
end
|
|
71
|
+
Options.add_format(opts, options, "Output format: text (default) or json (a { line => type } map)")
|
|
75
72
|
opts.on("--[no-]color",
|
|
76
73
|
"Force or disable ANSI colour (default: auto-detect a tty; honours NO_COLOR)") do |value|
|
|
77
74
|
options[:color] = value
|
|
@@ -81,7 +78,15 @@ module Rigor
|
|
|
81
78
|
options[:bat] = value
|
|
82
79
|
end
|
|
83
80
|
end
|
|
84
|
-
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
private
|
|
84
|
+
|
|
85
|
+
def parse_options
|
|
86
|
+
# Default: colour a tty, unless `NO_COLOR` opts out. An explicit `--color` / `--no-color` overrides both.
|
|
87
|
+
options = { config: nil, color: @out.tty? && !no_color_env?, bat: nil, format: "text" }
|
|
88
|
+
|
|
89
|
+
option_parser(options).parse!(@argv)
|
|
85
90
|
|
|
86
91
|
options
|
|
87
92
|
end
|
|
@@ -118,7 +123,7 @@ module Rigor
|
|
|
118
123
|
line_types = LineTypeCollector.new(scope_index).collect(parse_result.value)
|
|
119
124
|
|
|
120
125
|
case options.fetch(:format)
|
|
121
|
-
when
|
|
126
|
+
when "json"
|
|
122
127
|
emit_json(line_types)
|
|
123
128
|
else
|
|
124
129
|
@out.puts(render(annotate(source, line_types), color: options.fetch(:color), bat: options.fetch(:bat)))
|
|
@@ -132,7 +137,7 @@ module Rigor
|
|
|
132
137
|
# object keys).
|
|
133
138
|
def emit_json(line_types)
|
|
134
139
|
annotations = line_types.keys.sort.to_h { |line| [line.to_s, line_types[line].describe(:short)] }
|
|
135
|
-
@out.puts(JSON.generate({ "annotations" => annotations }))
|
|
140
|
+
@out.puts(JSON.generate(JsonDocument.stamp({ "annotations" => annotations })))
|
|
136
141
|
end
|
|
137
142
|
|
|
138
143
|
# The plugin-aware environment for the annotated file, so a `#=> <type>` matches what `rigor check`
|
|
@@ -225,7 +230,7 @@ module Rigor
|
|
|
225
230
|
@scope_index = scope_index
|
|
226
231
|
end
|
|
227
232
|
|
|
228
|
-
# @return 1-indexed line
|
|
233
|
+
# @return map of 1-indexed line number to type.
|
|
229
234
|
def collect(program)
|
|
230
235
|
by_line = {}
|
|
231
236
|
each_statement(program) do |statement|
|