rigortype 0.4.6 → 0.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +4 -2
- data/data/core_overlay/bigdecimal.rbs +33 -0
- data/data/core_overlay/resolv.rbs +30 -0
- data/data/gem_overlay/activesupport/core_ext.rbs +45 -13
- data/data/gem_overlay/addressable/addressable.rbs +40 -0
- data/data/vendored_gem_sigs/bundler/bundler.rbs +1 -1
- data/data/vendored_gem_sigs/rubygems/rubygems_extras.rbs +4 -3
- data/docs/handbook/01-getting-started.md +6 -3
- data/docs/handbook/11-sig-gen.md +85 -3
- data/docs/handbook/appendix-phpstan.md +4 -4
- data/docs/install.md +20 -0
- data/docs/manual/01-installation.md +67 -26
- data/docs/manual/02-cli-reference.md +455 -113
- data/docs/manual/03-configuration.md +76 -5
- data/docs/manual/04-diagnostics.md +5 -4
- data/docs/manual/06-baseline.md +6 -4
- data/docs/manual/08-skills.md +11 -0
- data/docs/manual/09-editor-integration.md +21 -2
- data/docs/manual/10-mcp-server.md +38 -2
- data/docs/manual/12-caching.md +4 -3
- data/docs/manual/14-rails-quickstart.md +1 -1
- data/docs/manual/19-effect-labels.md +3 -4
- data/docs/manual/plugins/rigor-actionpack.md +32 -15
- data/docs/manual/plugins/rigor-activesupport-core-ext.md +23 -1
- data/docs/manual/plugins/rigor-sorbet.md +17 -3
- data/lib/rigor/analysis/baseline.rb +24 -27
- data/lib/rigor/analysis/check_rules/always_raises_shield.rb +147 -0
- data/lib/rigor/analysis/check_rules/always_truthy_condition_collector.rb +5 -6
- data/lib/rigor/analysis/check_rules/call_facts.rb +58 -0
- data/lib/rigor/analysis/check_rules/dead_assignment_collector.rb +2 -2
- data/lib/rigor/analysis/check_rules/declaration_sourced_guard.rb +12 -4
- data/lib/rigor/analysis/check_rules/duplicate_hash_key_collector.rb +2 -2
- data/lib/rigor/analysis/check_rules/inferred_param_guard.rb +85 -13
- data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +16 -4
- data/lib/rigor/analysis/check_rules/lexical_method_sites.rb +6 -1
- data/lib/rigor/analysis/check_rules/main_pass_collector.rb +5 -8
- data/lib/rigor/analysis/check_rules/plugin_api_surface.rb +195 -0
- data/lib/rigor/analysis/check_rules/published_constant_guard.rb +41 -12
- data/lib/rigor/analysis/check_rules/rbs_receiver_surface.rb +27 -1
- data/lib/rigor/analysis/check_rules/rebinding_block_callees.rb +3 -3
- data/lib/rigor/analysis/check_rules/replaced_singleton_defs.rb +96 -0
- data/lib/rigor/analysis/check_rules/return_in_ensure_collector.rb +1 -2
- data/lib/rigor/analysis/check_rules/rule_ids.rb +9 -2
- data/lib/rigor/analysis/check_rules/rule_walk.rb +9 -7
- data/lib/rigor/analysis/check_rules/shadowed_rescue_collector.rb +3 -4
- data/lib/rigor/analysis/check_rules/special_global_setters.rb +3 -3
- data/lib/rigor/analysis/check_rules/unreachable_clause_collector.rb +2 -2
- data/lib/rigor/analysis/check_rules/void_value_use_collector.rb +2 -2
- data/lib/rigor/analysis/check_rules.rb +720 -141
- data/lib/rigor/analysis/crash_signature.rb +45 -3
- data/lib/rigor/analysis/dependency_recorder.rb +237 -80
- data/lib/rigor/analysis/dependency_source_inference/boundary_cross_reporter.rb +14 -3
- data/lib/rigor/analysis/dependency_source_inference/gem_resolver.rb +1 -1
- data/lib/rigor/analysis/dependency_source_inference/index.rb +6 -8
- data/lib/rigor/analysis/dependency_source_inference/walker.rb +4 -4
- data/lib/rigor/analysis/edit_replay.rb +93 -6
- data/lib/rigor/analysis/fact_store.rb +3 -3
- data/lib/rigor/analysis/incremental.rb +11 -1
- data/lib/rigor/analysis/incremental_run_slot/write_guard.rb +4 -3
- data/lib/rigor/analysis/incremental_run_slot.rb +2 -2
- data/lib/rigor/analysis/incremental_session.rb +306 -53
- data/lib/rigor/analysis/reachability/plugin_roots.rb +6 -3
- data/lib/rigor/analysis/rule_catalog.rb +39 -3
- data/lib/rigor/analysis/run_cache_key.rb +27 -3
- data/lib/rigor/analysis/run_disclosure_credit.rb +26 -6
- data/lib/rigor/analysis/run_stats.rb +2 -2
- data/lib/rigor/analysis/runner/buffer_pool_dispatcher.rb +6 -2
- data/lib/rigor/analysis/runner/declaration_position.rb +8 -8
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +264 -112
- data/lib/rigor/analysis/runner/effect_envelope_pass.rb +4 -9
- data/lib/rigor/analysis/runner/pool_coordinator.rb +173 -328
- data/lib/rigor/analysis/runner/project_pre_passes.rb +4 -37
- data/lib/rigor/analysis/runner/run_level_facts.rb +304 -0
- data/lib/rigor/analysis/runner/run_snapshots.rb +44 -54
- data/lib/rigor/analysis/runner/worker_payload.rb +36 -0
- data/lib/rigor/analysis/runner.rb +298 -109
- data/lib/rigor/analysis/self_call_resolution_recorder.rb +62 -23
- data/lib/rigor/analysis/template_unit_positions.rb +2 -3
- data/lib/rigor/analysis/template_units.rb +9 -1
- data/lib/rigor/analysis/worker_session.rb +65 -71
- data/lib/rigor/bleeding_edge.rb +22 -10
- data/lib/rigor/builtins/imported_refinements.rb +6 -8
- data/lib/rigor/builtins/predefined_constant_refinements.rb +1 -1
- data/lib/rigor/builtins/regex_refinement.rb +4 -6
- data/lib/rigor/cache/descriptor.rb +6 -5
- data/lib/rigor/cache/file_digest.rb +39 -31
- data/lib/rigor/cache/incremental_snapshot.rb +95 -17
- data/lib/rigor/cache/rbs_cache_producer.rb +2 -2
- data/lib/rigor/cache/rbs_class_ancestor_table.rb +1 -1
- data/lib/rigor/cache/rbs_class_type_param_names.rb +2 -2
- data/lib/rigor/cache/rbs_constant_table.rb +1 -1
- data/lib/rigor/cache/rbs_descriptor.rb +90 -4
- data/lib/rigor/cache/rbs_environment.rb +8 -1
- data/lib/rigor/cache/rbs_environment_marshal_patch.rb +2 -2
- data/lib/rigor/cache/rbs_known_class_names.rb +1 -1
- data/lib/rigor/cache/store.rb +11 -10
- data/lib/rigor/ci_detector.rb +1 -1
- data/lib/rigor/cli/annotate_command.rb +24 -19
- data/lib/rigor/cli/baseline_command.rb +160 -57
- data/lib/rigor/cli/catalogue.rb +256 -0
- data/lib/rigor/cli/check_command.rb +112 -104
- data/lib/rigor/cli/check_runner_factory.rb +2 -2
- data/lib/rigor/cli/command.rb +15 -1
- data/lib/rigor/cli/coverage_command.rb +21 -8
- data/lib/rigor/cli/coverage_mutation.rb +5 -7
- data/lib/rigor/cli/coverage_renderer.rb +2 -1
- data/lib/rigor/cli/coverage_scan.rb +3 -5
- data/lib/rigor/cli/diff_command.rb +25 -20
- data/lib/rigor/cli/docs_command.rb +1 -2
- data/lib/rigor/cli/doctor_command.rb +12 -12
- data/lib/rigor/cli/effects_command.rb +50 -40
- data/lib/rigor/cli/effects_diff_renderer.rb +18 -17
- data/lib/rigor/cli/effects_explain_renderer.rb +13 -12
- data/lib/rigor/cli/effects_renderer.rb +2 -1
- data/lib/rigor/cli/effects_snapshot_command.rb +26 -18
- data/lib/rigor/cli/explain_command.rb +18 -8
- data/lib/rigor/cli/fused_protection_renderer.rb +2 -1
- data/lib/rigor/cli/json_document.rb +41 -0
- data/lib/rigor/cli/lens_command.rb +29 -10
- data/lib/rigor/cli/lsp_command.rb +250 -23
- data/lib/rigor/cli/mcp_command.rb +12 -7
- data/lib/rigor/cli/mutation_fork_scan.rb +1 -1
- data/lib/rigor/cli/mutation_protection_renderer.rb +3 -2
- data/lib/rigor/cli/options.rb +40 -1
- data/lib/rigor/cli/plugin_command.rb +93 -46
- data/lib/rigor/cli/plugins_command.rb +17 -18
- data/lib/rigor/cli/plugins_renderer.rb +10 -6
- data/lib/rigor/cli/protection_fork_scan.rb +2 -2
- data/lib/rigor/cli/protection_renderer.rb +2 -1
- data/lib/rigor/cli/show_bleedingedge_command.rb +21 -15
- data/lib/rigor/cli/sig_gen_command.rb +92 -27
- data/lib/rigor/cli/skill_command.rb +32 -3
- data/lib/rigor/cli/skill_deep_probe.rb +1 -1
- data/lib/rigor/cli/skill_describe.rb +2 -1
- data/lib/rigor/cli/trace_command.rb +14 -9
- data/lib/rigor/cli/triage_command.rb +10 -11
- data/lib/rigor/cli/triage_renderer.rb +2 -1
- data/lib/rigor/cli/type_of_command.rb +16 -11
- data/lib/rigor/cli/type_of_project_scope.rb +1 -4
- data/lib/rigor/cli/type_of_renderer.rb +4 -1
- data/lib/rigor/cli/type_scan_command.rb +14 -9
- data/lib/rigor/cli/type_scan_renderer.rb +2 -1
- data/lib/rigor/cli/unused_command.rb +27 -17
- data/lib/rigor/cli/upgrade_command.rb +5 -0
- data/lib/rigor/cli.rb +214 -56
- data/lib/rigor/config_audit.rb +33 -19
- data/lib/rigor/configuration/severity_profile.rb +14 -5
- data/lib/rigor/configuration.rb +104 -35
- data/lib/rigor/effects/collector.rb +53 -21
- data/lib/rigor/effects/definition_context.rb +0 -2
- data/lib/rigor/effects/envelope.rb +1 -1
- data/lib/rigor/effects/framework_units.rb +1 -1
- data/lib/rigor/effects/mutation_classifier.rb +4 -7
- data/lib/rigor/effects/propagator.rb +1 -1
- data/lib/rigor/effects/registry.rb +2 -2
- data/lib/rigor/effects/snapshot.rb +1 -1
- data/lib/rigor/effects/taint_cause.rb +0 -2
- data/lib/rigor/effects/unit_scan.rb +9 -13
- data/lib/rigor/environment/bundle_sig_discovery.rb +64 -33
- data/lib/rigor/environment/class_registry.rb +3 -3
- data/lib/rigor/environment/constant_type_cache_holder.rb +5 -0
- data/lib/rigor/environment/core_root.rb +77 -0
- data/lib/rigor/environment/default_libraries.rb +18 -1
- data/lib/rigor/environment/deferred_signature_plan.rb +381 -0
- data/lib/rigor/environment/gated_signature_guard.rb +1 -1
- data/lib/rigor/environment/gated_signature_plan.rb +5 -2
- data/lib/rigor/environment/hkt_registry_holder.rb +6 -0
- data/lib/rigor/environment/lockfile_resolver.rb +28 -12
- data/lib/rigor/environment/member_consistency/comparator.rb +18 -1
- data/lib/rigor/environment/member_consistency.rb +56 -7
- data/lib/rigor/environment/missing_gem_constant_index.rb +3 -2
- data/lib/rigor/environment/project_path_gems.rb +124 -0
- data/lib/rigor/environment/rbs_collection_discovery.rb +123 -8
- data/lib/rigor/environment/rbs_coverage_report.rb +12 -11
- data/lib/rigor/environment/rbs_hierarchy.rb +12 -15
- data/lib/rigor/environment/rbs_loader.rb +772 -110
- data/lib/rigor/environment/reflection.rb +7 -7
- data/lib/rigor/environment/required_features.rb +0 -3
- data/lib/rigor/environment/ruby_library_roots.rb +1 -1
- data/lib/rigor/environment/vendored_signature_plan.rb +153 -0
- data/lib/rigor/environment.rb +169 -42
- data/lib/rigor/flow_contribution/merger.rb +4 -4
- data/lib/rigor/inference/acceptance.rb +136 -40
- data/lib/rigor/inference/alias_mutation_floor/foreign_locals.rb +117 -0
- data/lib/rigor/inference/alias_mutation_floor/memos.rb +85 -0
- data/lib/rigor/inference/alias_mutation_floor/reach.rb +119 -0
- data/lib/rigor/inference/alias_mutation_floor/site_collector.rb +252 -0
- data/lib/rigor/inference/alias_mutation_floor.rb +339 -0
- data/lib/rigor/inference/anonymous_meta_class.rb +18 -0
- data/lib/rigor/inference/block_auto_splat.rb +1 -1
- data/lib/rigor/inference/block_parameter_binder.rb +2 -3
- data/lib/rigor/inference/block_run_count.rb +185 -0
- data/lib/rigor/inference/budget_trace.rb +8 -2
- data/lib/rigor/inference/builtins/array_catalog.rb +2 -2
- data/lib/rigor/inference/builtins/exception_catalog.rb +2 -2
- data/lib/rigor/inference/builtins/numeric_catalog.rb +2 -5
- data/lib/rigor/inference/builtins/random_catalog.rb +2 -2
- data/lib/rigor/inference/callee_mutation_chain.rb +88 -77
- data/lib/rigor/inference/callee_write_census.rb +815 -0
- data/lib/rigor/inference/captured_locals.rb +2 -0
- data/lib/rigor/inference/census_foreign_block.rb +354 -0
- data/lib/rigor/inference/clause_widening.rb +1 -1
- data/lib/rigor/inference/closure_escape_analyzer.rb +11 -4
- data/lib/rigor/inference/construction_escape.rb +258 -0
- data/lib/rigor/inference/declaration_walk/traversal.rb +1 -1
- data/lib/rigor/inference/declaration_walk.rb +4 -0
- data/lib/rigor/inference/deep_erasure.rb +39 -7
- data/lib/rigor/inference/def_handle.rb +1 -1
- data/lib/rigor/inference/def_node_resolver.rb +33 -15
- data/lib/rigor/inference/def_return_typer.rb +47 -5
- data/lib/rigor/inference/definer_resolution.rb +19 -9
- data/lib/rigor/inference/definers_index.rb +162 -0
- data/lib/rigor/inference/direct_ivar_writes.rb +300 -0
- data/lib/rigor/inference/element_read_widening.rb +49 -3
- data/lib/rigor/inference/error_info.rb +16 -0
- data/lib/rigor/inference/expression_typer.rb +1559 -320
- data/lib/rigor/inference/external_ancestor_resolution.rb +3 -4
- data/lib/rigor/inference/flow_tracer.rb +31 -14
- data/lib/rigor/inference/fork_map.rb +3 -0
- data/lib/rigor/inference/fresh_frame_blocks.rb +52 -1
- data/lib/rigor/inference/global_write_census.rb +81 -5
- data/lib/rigor/inference/global_writer_reach.rb +260 -0
- data/lib/rigor/inference/hkt_body.rb +1 -2
- data/lib/rigor/inference/hkt_body_parser.rb +3 -5
- data/lib/rigor/inference/hkt_reducer.rb +2 -2
- data/lib/rigor/inference/hkt_registry.rb +3 -5
- data/lib/rigor/inference/in_effect_refinements.rb +7 -0
- data/lib/rigor/inference/indexed_narrowing.rb +61 -15
- data/lib/rigor/inference/intervening_ivar_reset.rb +26 -4
- data/lib/rigor/inference/ivar_writer_census.rb +154 -8
- data/lib/rigor/inference/key_presence_guard.rb +51 -24
- data/lib/rigor/inference/last_line/self_evidence.rb +30 -0
- data/lib/rigor/inference/last_line.rb +5 -2
- data/lib/rigor/inference/loop_value_record.rb +66 -14
- data/lib/rigor/inference/match_rebinding/frame.rb +57 -0
- data/lib/rigor/inference/match_rebinding/yielding_match.rb +101 -0
- data/lib/rigor/inference/match_rebinding.rb +28 -5
- data/lib/rigor/inference/method_dispatcher/alias_strict_nominals.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/argument_distribution.rb +40 -0
- data/lib/rigor/inference/method_dispatcher/block_folding.rb +44 -30
- data/lib/rigor/inference/method_dispatcher/class_keyed_block_params.rb +65 -0
- data/lib/rigor/inference/method_dispatcher/constant_folding.rb +3 -3
- data/lib/rigor/inference/method_dispatcher/contested_overloads.rb +89 -0
- data/lib/rigor/inference/method_dispatcher/core_enumerable_receiver.rb +44 -0
- data/lib/rigor/inference/method_dispatcher/declared_constructor.rb +151 -0
- data/lib/rigor/inference/method_dispatcher/facet_distribution.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/imprecise_argument.rb +2 -2
- data/lib/rigor/inference/method_dispatcher/interface_shape.rb +181 -0
- data/lib/rigor/inference/method_dispatcher/iterator_dispatch.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/kernel_dispatch.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/no_match_fallback.rb +54 -0
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +51 -27
- data/lib/rigor/inference/method_dispatcher/random_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +606 -78
- data/lib/rigor/inference/method_dispatcher/reduce_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/regexp_folding.rb +2 -2
- data/lib/rigor/inference/method_dispatcher/self_substitute.rb +3 -3
- data/lib/rigor/inference/method_dispatcher/set_folding.rb +9 -7
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +467 -84
- data/lib/rigor/inference/method_dispatcher/singleton_folding.rb +0 -1
- data/lib/rigor/inference/method_dispatcher/singleton_mixin_dispatch.rb +50 -17
- data/lib/rigor/inference/method_dispatcher/singleton_type_params.rb +104 -0
- data/lib/rigor/inference/method_dispatcher/struct_folding.rb +5 -5
- data/lib/rigor/inference/method_dispatcher/struct_materialization.rb +4 -6
- data/lib/rigor/inference/method_dispatcher/uri_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher.rb +123 -25
- data/lib/rigor/inference/method_parameter_binder.rb +136 -56
- data/lib/rigor/inference/module_function_state/spellings.rb +2 -2
- data/lib/rigor/inference/module_function_state.rb +24 -3
- data/lib/rigor/inference/multi_target_binder.rb +2 -2
- data/lib/rigor/inference/mutation_rejoin.rb +240 -4
- data/lib/rigor/inference/mutation_widening.rb +199 -29
- data/lib/rigor/inference/narrowing.rb +238 -50
- data/lib/rigor/inference/operand_effects.rb +43 -2
- data/lib/rigor/inference/optimistic_origin.rb +134 -9
- data/lib/rigor/inference/origin_lookup.rb +1 -1
- data/lib/rigor/inference/out_buffer_mutation.rb +72 -0
- data/lib/rigor/inference/parameter_inference_collector.rb +5 -6
- data/lib/rigor/inference/pre_eval_constants.rb +1 -1
- data/lib/rigor/inference/precision_scanner.rb +1 -1
- data/lib/rigor/inference/project_method_ownership.rb +30 -9
- data/lib/rigor/inference/project_patched_methods.rb +65 -13
- data/lib/rigor/inference/project_patched_scanner.rb +120 -25
- data/lib/rigor/inference/project_patched_visibility.rb +39 -3
- data/lib/rigor/inference/project_yielder.rb +11 -17
- data/lib/rigor/inference/rbs_type_translator.rb +68 -15
- data/lib/rigor/inference/receiver_alias.rb +20 -0
- data/lib/rigor/inference/receiver_writer_call.rb +67 -0
- data/lib/rigor/inference/recursion_rebinding.rb +157 -0
- data/lib/rigor/inference/refined_dispatch/constructed_class.rb +57 -17
- data/lib/rigor/inference/refined_dispatch/own_method.rb +51 -16
- data/lib/rigor/inference/refined_dispatch.rb +13 -0
- data/lib/rigor/inference/reflective_ivar_write.rb +19 -11
- data/lib/rigor/inference/remover_holder_scan.rb +287 -0
- data/lib/rigor/inference/remover_narrowing.rb +224 -0
- data/lib/rigor/inference/rewrite_mutation.rb +53 -2
- data/lib/rigor/inference/scope_indexer/certainty.rb +0 -1
- data/lib/rigor/inference/scope_indexer/class_cvars_collector.rb +13 -6
- data/lib/rigor/inference/scope_indexer/constant_ivar_value.rb +93 -0
- data/lib/rigor/inference/scope_indexer/declared_param_writes.rb +70 -26
- data/lib/rigor/inference/scope_indexer/derived_param_value.rb +112 -0
- data/lib/rigor/inference/scope_indexer/empty_seed.rb +99 -0
- data/lib/rigor/inference/scope_indexer/ivar_contributions.rb +295 -0
- data/lib/rigor/inference/scope_indexer/mixin_accumulator.rb +136 -9
- data/lib/rigor/inference/scope_indexer.rb +2213 -226
- data/lib/rigor/inference/self_call_ivar_writes.rb +103 -12
- data/lib/rigor/inference/self_preserving_block.rb +87 -0
- data/lib/rigor/inference/set_mutation.rb +189 -0
- data/lib/rigor/inference/singleton_hook_decline.rb +42 -8
- data/lib/rigor/inference/singleton_object_constant.rb +32 -2
- data/lib/rigor/inference/statement_evaluator.rb +3268 -358
- data/lib/rigor/inference/string_mutation.rb +14 -0
- data/lib/rigor/inference/struct_fold_safety.rb +4 -6
- data/lib/rigor/inference/synthetic_method_scanner.rb +40 -17
- data/lib/rigor/inference/toplevel_def_census.rb +67 -0
- data/lib/rigor/inference/unknown_store_widening.rb +103 -4
- data/lib/rigor/inference/unthreaded_rebinds.rb +2 -3
- data/lib/rigor/inference/untyped_rejoin.rb +1 -1
- data/lib/rigor/inference/void_tail_summary.rb +29 -9
- data/lib/rigor/language_server/buffer_table.rb +3 -3
- data/lib/rigor/language_server/completion_provider.rb +26 -20
- data/lib/rigor/language_server/config_warning_announcer.rb +28 -0
- data/lib/rigor/language_server/diagnostic_publisher.rb +8 -3
- data/lib/rigor/language_server/document_symbol_provider.rb +1 -1
- data/lib/rigor/language_server/folding_range_provider.rb +1 -2
- data/lib/rigor/language_server/hover_provider.rb +1 -7
- data/lib/rigor/language_server/hover_renderer.rb +6 -8
- data/lib/rigor/language_server/project_context.rb +39 -1
- data/lib/rigor/language_server/publish_batcher.rb +3 -4
- data/lib/rigor/language_server/selection_range_provider.rb +2 -4
- data/lib/rigor/language_server/server.rb +7 -3
- data/lib/rigor/language_server/signature_help_provider.rb +4 -4
- data/lib/rigor/lens/claims/comparison.rb +78 -0
- data/lib/rigor/lens/claims/request.rb +131 -0
- data/lib/rigor/lens/claims/type_reader.rb +216 -0
- data/lib/rigor/lens/claims.rb +208 -0
- data/lib/rigor/lens/contract_reader.rb +5 -0
- data/lib/rigor/lens/document.rb +1 -1
- data/lib/rigor/lens/file_reader.rb +21 -8
- data/lib/rigor/lens/plugins.rb +1 -1
- data/lib/rigor/lens/run.rb +8 -0
- data/lib/rigor/lens.rb +1 -1
- data/lib/rigor/library_probe.rb +68 -0
- data/lib/rigor/mcp/server.rb +73 -2
- data/lib/rigor/mcp.rb +1 -1
- data/lib/rigor/memo_audit.rb +282 -0
- data/lib/rigor/plugin/access_denied_error.rb +1 -2
- data/lib/rigor/plugin/base.rb +15 -2
- data/lib/rigor/plugin/bundled_catalog.rb +1 -12
- data/lib/rigor/plugin/io_boundary.rb +26 -4
- data/lib/rigor/plugin/loader.rb +25 -8
- data/lib/rigor/plugin/macro/heredoc_template.rb +7 -8
- data/lib/rigor/plugin/macro/trait_registry.rb +6 -9
- data/lib/rigor/plugin/manifest.rb +16 -16
- data/lib/rigor/plugin/registry.rb +16 -5
- data/lib/rigor/plugin/services.rb +2 -3
- data/lib/rigor/plugin/source_rbs_synthesis_reporter.rb +11 -0
- data/lib/rigor/plugin/trust_policy.rb +48 -2
- data/lib/rigor/plugin/type_node_resolver.rb +2 -4
- data/lib/rigor/plugin.rb +6 -8
- data/lib/rigor/plugin_gap_advisory.rb +5 -1
- data/lib/rigor/project_environment.rb +16 -2
- data/lib/rigor/protection/analysis_guard.rb +1 -1
- data/lib/rigor/protection/discovery_seed.rb +44 -5
- data/lib/rigor/protection/mutation_cache.rb +4 -1
- data/lib/rigor/protection/mutator.rb +1 -1
- data/lib/rigor/rbs_extended/envelope_scanner.rb +4 -6
- data/lib/rigor/rbs_extended/hkt_directives.rb +6 -10
- data/lib/rigor/rbs_extended/reporter.rb +27 -3
- data/lib/rigor/rbs_extended.rb +2 -3
- data/lib/rigor/reflection/constant_ancestors.rb +81 -22
- data/lib/rigor/reflection/declaration_collectors.rb +55 -0
- data/lib/rigor/reflection/declarations.rb +58 -0
- data/lib/rigor/reflection/project_method.rb +177 -0
- data/lib/rigor/reflection.rb +2 -0
- data/lib/rigor/rooted_glob.rb +32 -1
- data/lib/rigor/run_scoped_slots.rb +38 -0
- data/lib/rigor/runtime/jit.rb +1 -1
- data/lib/rigor/scope/discovery_index.rb +168 -8
- data/lib/rigor/scope/resolution_chain/relevance.rb +14 -1
- data/lib/rigor/scope/resolution_chain.rb +901 -54
- data/lib/rigor/scope.rb +644 -37
- data/lib/rigor/sig_gen/bot_proposal_guard.rb +306 -0
- data/lib/rigor/sig_gen/classification.rb +18 -1
- data/lib/rigor/sig_gen/effect_annotation.rb +3 -3
- data/lib/rigor/sig_gen/generator.rb +588 -66
- data/lib/rigor/sig_gen/generic_header_scan.rb +189 -0
- data/lib/rigor/sig_gen/inline_declarations.rb +2 -2
- data/lib/rigor/sig_gen/layout_index.rb +3 -3
- data/lib/rigor/sig_gen/method_candidate.rb +37 -4
- data/lib/rigor/sig_gen/observation_collector.rb +14 -7
- data/lib/rigor/sig_gen/observed_call.rb +1 -1
- data/lib/rigor/sig_gen/path_mapper.rb +6 -0
- data/lib/rigor/sig_gen/platform_guarded_files.rb +184 -0
- data/lib/rigor/sig_gen/renderer.rb +15 -9
- data/lib/rigor/sig_gen/skip_reason_catalog.rb +62 -2
- data/lib/rigor/sig_gen/type_name_qualification.rb +69 -0
- data/lib/rigor/sig_gen/write_reporter.rb +63 -14
- data/lib/rigor/sig_gen/write_result.rb +23 -12
- data/lib/rigor/sig_gen/writer.rb +238 -37
- data/lib/rigor/sig_gen.rb +1 -0
- data/lib/rigor/source/forwardable_delegators.rb +122 -0
- data/lib/rigor/source/node_children.rb +13 -0
- data/lib/rigor/type/acceptance_router.rb +2 -2
- data/lib/rigor/type/accepts_result.rb +1 -1
- data/lib/rigor/type/app.rb +4 -6
- data/lib/rigor/type/combinator.rb +173 -21
- data/lib/rigor/type/constant.rb +4 -5
- data/lib/rigor/type/hash_shape.rb +21 -40
- data/lib/rigor/type/interface.rb +60 -0
- data/lib/rigor/type/union.rb +1 -1
- data/lib/rigor/type.rb +1 -0
- data/lib/rigor/type_node/identifier.rb +1 -2
- data/lib/rigor/type_node/resolver_chain.rb +1 -1
- data/lib/rigor/type_node/string_literal.rb +1 -2
- data/lib/rigor/type_node/symbol_literal.rb +1 -2
- data/lib/rigor/type_node/union.rb +3 -6
- data/lib/rigor/type_of_memo/serving.rb +99 -0
- data/lib/rigor/type_of_memo/stats.rb +43 -0
- data/lib/rigor/type_of_memo.rb +337 -0
- data/lib/rigor/typing_state.rb +1094 -0
- data/lib/rigor/value_semantics.rb +1 -10
- data/lib/rigor/version.rb +1 -1
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_discoverer.rb +2 -2
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_index.rb +2 -3
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +1 -1
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_discoverer.rb +38 -36
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_index.rb +4 -2
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb +6 -4
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb +1 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_index.rb +1 -5
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_scan.rb +0 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/erb_compiler.rb +2 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/view_assigns.rb +3 -3
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +115 -36
- data/plugins/rigor-active-model-serializers/lib/rigor/plugin/active_model_serializers.rb +3 -6
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/analyzer.rb +25 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/effects.rb +1 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_discoverer.rb +16 -6
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_index.rb +4 -2
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +4 -3
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/analyzer.rb +2 -1
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/association_roots.rb +3 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/effects.rb +2 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +21 -31
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_index.rb +10 -16
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_parser.rb +132 -33
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_table.rb +20 -6
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/structure_sql_parser.rb +7 -4
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +54 -17
- data/plugins/rigor-activerecord/sig/active_record/relation.rbs +19 -5
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_discoverer.rb +3 -4
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_index.rb +1 -1
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +11 -14
- data/plugins/rigor-activestorage/lib/rigor-activestorage.rb +1 -1
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext/effects.rb +1 -1
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext/symbolize_keys.rb +102 -0
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb +30 -9
- data/plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs +55 -13
- data/plugins/rigor-alba/lib/rigor/plugin/alba/resource_collector.rb +15 -21
- data/plugins/rigor-alba/lib/rigor/plugin/alba/resource_discoverer.rb +1 -6
- data/plugins/rigor-alba/lib/rigor/plugin/alba/resource_index.rb +3 -3
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema/schema_scanner.rb +1 -3
- data/plugins/rigor-dry-struct/lib/rigor/plugin/dry_struct.rb +6 -6
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types/alias_scanner.rb +5 -6
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types.rb +1 -1
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation/params_shape.rb +2 -3
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation.rb +5 -8
- data/plugins/rigor-ethon/lib/rigor/plugin/ethon.rb +0 -1
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_discoverer.rb +1 -1
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot.rb +10 -18
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi/analyzer.rb +0 -1
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi/discoverer.rb +0 -2
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi.rb +8 -7
- data/plugins/rigor-grape/lib/rigor/plugin/grape.rb +0 -2
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql/type_scanner.rb +6 -7
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql.rb +12 -2
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami/action_checker.rb +2 -4
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami.rb +2 -5
- data/plugins/rigor-mangrove/lib/rigor/plugin/mangrove.rb +8 -2
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest/assertion_analyzer.rb +6 -6
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_discoverer.rb +2 -1
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/analyzer.rb +3 -8
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_index.rb +2 -3
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_loader.rb +5 -8
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/analyzer.rb +200 -4
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/devise_routes.rb +2 -3
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_discoverer.rb +1 -1
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/routes_parser.rb +4 -11
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +4 -3
- data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb +2 -1
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +5 -5
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec.rb +2 -2
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails.rb +3 -4
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers/analyzer.rb +6 -8
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb +3 -2
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/absurd_recognizer.rb +4 -5
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/assertion_recognizer.rb +6 -7
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog.rb +210 -3
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog_walker.rb +146 -7
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sig_parser.rb +2 -2
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/type_translator.rb +52 -34
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +97 -24
- data/plugins/rigor-statesman/lib/rigor/plugin/statesman.rb +2 -3
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer/serializer_collector.rb +16 -16
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer/serializer_discoverer.rb +4 -8
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer/serializer_index.rb +4 -4
- data/sig/rigor/analysis/baseline.rbs +0 -3
- data/sig/rigor/analysis/check_rules/rule_walk.rbs +6 -0
- data/sig/rigor/analysis/fact_store.rbs +2 -2
- data/sig/rigor/analysis/reachability/scan_cache.rbs +1 -1
- data/sig/rigor/cache/descriptor.rbs +14 -0
- data/sig/rigor/cli/diff_command.rbs +1 -1
- data/sig/rigor/cli/explain_command.rbs +1 -1
- data/sig/rigor/effects/registry.rbs +2 -2
- data/sig/rigor/environment.rbs +4 -1
- data/sig/rigor/inference.rbs +4 -1
- data/sig/rigor/plugin/additional_initializer.rbs +0 -5
- data/sig/rigor/plugin/base.rbs +53 -18
- data/sig/rigor/plugin/effect_attribution.rbs +3 -3
- data/sig/rigor/plugin/effect_edge.rbs +1 -1
- data/sig/rigor/plugin/effect_entry_points.rbs +3 -3
- data/sig/rigor/plugin/interfaces.rbs +51 -0
- data/sig/rigor/plugin/io_boundary.rbs +3 -3
- data/sig/rigor/plugin/manifest.rbs +9 -9
- data/sig/rigor/plugin/node_context.rbs +21 -0
- data/sig/rigor/plugin/protocol_contract.rbs +3 -7
- data/sig/rigor/reflection.rbs +37 -0
- data/sig/rigor/scope.rbs +43 -4
- data/sig/rigor/trinary.rbs +1 -0
- data/sig/rigor/type.rbs +9 -3
- data/sig/rigor.rbs +3 -2
- data/skills/rigor-ask/SKILL.md +1 -0
- data/skills/rigor-plugin-author/SKILL.md +4 -4
- data/skills/rigor-plugin-author/references/02-walker-and-types.md +5 -5
- data/skills/rigor-plugin-review/SKILL.md +3 -3
- data/skills/rigor-project-init/references/01-detect.md +1 -0
- data/skills/rigor-project-init/references/03-baseline-and-bugs.md +17 -2
- data/skills/rigor-project-init/references/06-agent-contract.md +4 -4
- data/skills/rigor-rbs-contract/SKILL.md +147 -0
- data/skills/rigor-rbs-contract/references/01-finding-candidates.md +212 -0
- data/skills/rigor-rbs-contract/references/02-contract-rules.md +157 -0
- data/skills/rigor-rbs-contract/references/03-target-own-code.md +90 -0
- data/skills/rigor-rbs-contract/references/04-target-gem-rbs-collection.md +210 -0
- data/skills/rigor-rbs-contract/references/05-declaration-mutants.md +182 -0
- data/skills/rigor-rbs-setup/SKILL.md +3 -1
- data/skills/rigor-type-oracle/SKILL.md +26 -1
- data/skills/rigor-type-oracle/references/02-agents-md-fragment.md +4 -3
- metadata +82 -3
|
@@ -11,7 +11,7 @@ module Rigor
|
|
|
11
11
|
# intent tracked by #2325, and only then does this row generate; coercion-facing: `to_s`), and `initialize`
|
|
12
12
|
# stores the result of the private `validate_receiver!` helper (#2312).
|
|
13
13
|
attr_reader receiver: String
|
|
14
|
-
# sig-gen gap: #
|
|
14
|
+
# sig-gen gap: #2325 — `method:` is `untyped` (input `untyped`, looks deliberate; a declared type is authoring
|
|
15
15
|
# intent tracked by #2325, and only then does this row generate; coercion-facing: `String | Symbol | nil`),
|
|
16
16
|
# stored as `method&.to_sym`.
|
|
17
17
|
attr_reader method: Symbol?
|
|
@@ -4,15 +4,15 @@ module Rigor
|
|
|
4
4
|
# framework entry points (ADR-103 WD6). Frozen value object; {#globs} are deduplicated and
|
|
5
5
|
# sorted in `initialize`.
|
|
6
6
|
class EffectEntryPoints
|
|
7
|
-
# sig-gen gap: #
|
|
7
|
+
# sig-gen gap: #2325 — `initialize` declares `name:` `untyped` (input `untyped`, looks deliberate; a declared
|
|
8
8
|
# type is authoring intent tracked by #2325, and only then does this row generate; coercion-facing: it takes
|
|
9
9
|
# anything that answers `to_s`), so no input type reaches the reader.
|
|
10
10
|
attr_reader name: String
|
|
11
|
-
# sig-gen gap: #
|
|
11
|
+
# sig-gen gap: #2325 — `globs:` is `untyped` (input `untyped`, looks deliberate; a declared type is authoring
|
|
12
12
|
# intent tracked by #2325, and only then does this row generate; coercion-facing: `Array(globs)`, each `to_s`),
|
|
13
13
|
# deduplicated and sorted in `initialize`.
|
|
14
14
|
attr_reader globs: Array[String]
|
|
15
|
-
# sig-gen gap: #
|
|
15
|
+
# sig-gen gap: #2325 — `why:` is `untyped` (input `untyped`, looks deliberate; a declared type is authoring
|
|
16
16
|
# intent tracked by #2325, and only then does this row generate; coercion-facing: `to_s`).
|
|
17
17
|
attr_reader why: String
|
|
18
18
|
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# ADR-128 — the plugin-facing structural interfaces: what a hook may call on the engine objects it receives.
|
|
2
|
+
#
|
|
3
|
+
# The criterion (ADR-128): a method is public plugin API only if it is declared on `Plugin::Base`, on one of the
|
|
4
|
+
# interfaces below, or in a namespace `docs/internal-spec/public-api.md` lists as public. Being reachable at
|
|
5
|
+
# runtime does not make a method public. `spec/rigor/plugin_boundary_spec.rb` gates the bundled plugins against
|
|
6
|
+
# these member lists, so adding a member here is an API promise, and `public_api_drift_spec.rb` pins the sets.
|
|
7
|
+
#
|
|
8
|
+
# Each interface is backed by a concrete engine class (the `BACKING` table in `spec/support/plugin_boundary.rb`).
|
|
9
|
+
# Engine signatures keep those concrete classes (ADR-128 WD5); an interface appears only at a plugin-facing
|
|
10
|
+
# position, in `base.rbs`.
|
|
11
|
+
module Rigor
|
|
12
|
+
module Plugin
|
|
13
|
+
# The scope a hook receives. Backed by `Rigor::Scope`, which has far more members (about 200); only these are
|
|
14
|
+
# promised. `environment` is non-nil, matching `Scope#environment`.
|
|
15
|
+
interface _Scope
|
|
16
|
+
def type_of: (::Prism::Node node) -> Rigor::Type::t
|
|
17
|
+
def self_type: () -> Rigor::Type::t?
|
|
18
|
+
def local: (String | Symbol name) -> Rigor::Type::t?
|
|
19
|
+
def source_path: () -> String?
|
|
20
|
+
def with_local: (String | Symbol name, Rigor::Type::t type) -> Rigor::Plugin::_Scope
|
|
21
|
+
def environment: () -> Rigor::Plugin::_Environment
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# The project's RBS and class-registry handle, backed by `Rigor::Environment`.
|
|
25
|
+
interface _Environment
|
|
26
|
+
def nominal_for_name: (String | Symbol name) -> Rigor::Type::Nominal?
|
|
27
|
+
def rbs_module?: (String | Symbol name) -> bool
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# The services container `Plugin::Base#init` / `#prepare` receive, backed by `Rigor::Plugin::Services`.
|
|
31
|
+
# `reflection` and `type` are public namespaces (`Rigor::Reflection`, `Rigor::Type::Combinator`) that a plugin
|
|
32
|
+
# also reaches by constant, so they are typed as those modules rather than narrowed to an interface.
|
|
33
|
+
interface _Services
|
|
34
|
+
def fact_store: () -> Rigor::Plugin::_FactStore
|
|
35
|
+
def configuration: () -> Rigor::Plugin::_Configuration
|
|
36
|
+
def reflection: () -> singleton(Rigor::Reflection)
|
|
37
|
+
def type: () -> singleton(Rigor::Type::Combinator)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# The per-run cross-plugin fact store, backed by `Rigor::Plugin::FactStore`.
|
|
41
|
+
interface _FactStore
|
|
42
|
+
def publish: (plugin_id: String | Symbol, name: Symbol, value: untyped) -> nil
|
|
43
|
+
def read: (plugin_id: String | Symbol, name: Symbol) -> untyped
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# The project configuration, backed by `Rigor::Configuration`.
|
|
47
|
+
interface _Configuration
|
|
48
|
+
def paths: () -> Array[String]
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -4,7 +4,7 @@ class Rigor::Plugin::IoBoundary
|
|
|
4
4
|
def file?: (untyped) -> bool
|
|
5
5
|
def directory?: (untyped) -> bool
|
|
6
6
|
def list_directory: (untyped) -> Array[String]
|
|
7
|
-
def list_directory_kinds: (untyped) -> Hash[String,
|
|
7
|
+
def list_directory_kinds: (untyped) -> Hash[String, Symbol]
|
|
8
8
|
# Records a `:names` glob row (membership only); a caller needing a match's content `read_file`s it. A `..`
|
|
9
9
|
# segment, a brace or a backslash in `pattern` raises `AccessDeniedError`.
|
|
10
10
|
def glob: (untyped root, untyped pattern) -> Array[String]
|
|
@@ -14,7 +14,7 @@ class Rigor::Plugin::IoBoundary
|
|
|
14
14
|
# whose parameter is undeclared.
|
|
15
15
|
def refusal_summary: () -> { count: Integer, first_path: String?, nearest_root: String? }?
|
|
16
16
|
def open_url: (untyped url) -> String
|
|
17
|
-
#
|
|
18
|
-
def cache_descriptor: () ->
|
|
17
|
+
# The returned descriptor is frozen.
|
|
18
|
+
def cache_descriptor: () -> Rigor::Cache::Descriptor
|
|
19
19
|
def replay: (untyped descriptor) -> nil
|
|
20
20
|
end
|
|
@@ -18,7 +18,7 @@ class Rigor::Plugin::Manifest
|
|
|
18
18
|
def config_schema: () -> untyped
|
|
19
19
|
def config_defaults: () -> Hash[String, untyped]
|
|
20
20
|
def target_gems: () -> Array[String]
|
|
21
|
-
# sig-gen gap: #
|
|
21
|
+
# sig-gen gap: #2418 — written by a private `assign_*` helper whose parameters are undeclared (`initialize` hands
|
|
22
22
|
# its fields to such helpers); each write is a derived expression (`dup.freeze`, `map`), so the helper's parameter
|
|
23
23
|
# types alone would not generate it.
|
|
24
24
|
def template_globs: () -> Array[String]
|
|
@@ -35,31 +35,31 @@ class Rigor::Plugin::Manifest
|
|
|
35
35
|
def hkt_registrations: () -> untyped
|
|
36
36
|
def hkt_definitions: () -> untyped
|
|
37
37
|
def signature_paths: () -> Array[String]
|
|
38
|
-
# sig-gen gap: #
|
|
38
|
+
# sig-gen gap: #2418 — same shape as `template_globs`: `validate_protocol_contracts!` requires every element
|
|
39
39
|
# `is_a?(ProtocolContract)`.
|
|
40
40
|
def protocol_contracts: () -> Array[Rigor::Plugin::ProtocolContract]
|
|
41
41
|
# ADR-32 WD6/WD12 — any object responding to `call`, and its result is a documented multi-shape
|
|
42
42
|
# outcome (`String` / nil / `[:error, msg]` / `[:ok, src, msgs]`), not `String?` — `untyped` is the
|
|
43
43
|
# honest claim until the outcome has a sig'd shape.
|
|
44
44
|
def source_rbs_synthesizer: () -> untyped
|
|
45
|
-
# sig-gen gap: #
|
|
45
|
+
# sig-gen gap: #2418 — same shape as `template_globs`: the validator (`validate_additional_initializers!`) requires
|
|
46
46
|
# every element `is_a?(AdditionalInitializer)`, so the element type is hand-written.
|
|
47
47
|
def additional_initializers: () -> Array[Rigor::Plugin::AdditionalInitializer]
|
|
48
48
|
|
|
49
|
-
# sig-gen gap: #
|
|
49
|
+
# sig-gen gap: #2418 — same shape as `template_globs`: `validate_effect_root!` bounds the spelling.
|
|
50
50
|
def effect_root: () -> String?
|
|
51
|
-
# sig-gen gap: #
|
|
51
|
+
# sig-gen gap: #2418 — same shape as `template_globs`: `validate_effect_labels!` requires non-empty `String`
|
|
52
52
|
# elements.
|
|
53
53
|
def effect_labels: () -> Array[String]
|
|
54
|
-
# sig-gen gap: #
|
|
54
|
+
# sig-gen gap: #2418 — same shape as `template_globs`: `validate_effect_attributions!` requires every element
|
|
55
55
|
# `is_a?(EffectAttribution)`.
|
|
56
56
|
def effect_attributions: () -> Array[Rigor::Plugin::EffectAttribution]
|
|
57
|
-
# sig-gen gap: #
|
|
57
|
+
# sig-gen gap: #2418 — same shape as `template_globs`: `validate_effect_edges!` requires `is_a?(EffectEdge)`.
|
|
58
58
|
def effect_edges: () -> Array[Rigor::Plugin::EffectEdge]
|
|
59
|
-
# sig-gen gap: #
|
|
59
|
+
# sig-gen gap: #2418 — same shape as `template_globs`: `validate_effect_entry_points!` requires
|
|
60
60
|
# `is_a?(EffectEntryPoints)`.
|
|
61
61
|
def effect_entry_points: () -> Array[Rigor::Plugin::EffectEntryPoints]
|
|
62
|
-
# sig-gen gap: #
|
|
62
|
+
# sig-gen gap: #2418 — same shape as `template_globs`: `validate_effect_ancestry!` requires `is_a?(EffectAncestry)`.
|
|
63
63
|
def effect_ancestry: () -> Array[Rigor::Plugin::EffectAncestry]
|
|
64
64
|
|
|
65
65
|
# The identity opening a root when this plugin's labels join the run's vocabulary: the
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Rigor
|
|
2
|
+
module Plugin
|
|
3
|
+
# ADR-37 slice 1d — the lexical context of a node, the fifth argument of a `node_rule` block.
|
|
4
|
+
class NodeContext
|
|
5
|
+
EMPTY: nil
|
|
6
|
+
|
|
7
|
+
attr_reader ancestors: Array[::Prism::Node]
|
|
8
|
+
|
|
9
|
+
def initialize: (Array[::Prism::Node] ancestors) -> void
|
|
10
|
+
# The three finders return the innermost ancestor of a given kind: a `DefNode`, a `ClassNode` or
|
|
11
|
+
# `ModuleNode`, and a `CallNode` respectively. `enclosing_def` is sig-gen's proposal (#2719, #2914); the other
|
|
12
|
+
# two blocks (`||`, `&&`) are not a single class test, so their bodies still infer `Prism::Node?`. A narrower
|
|
13
|
+
# declaration would be an unmarked sig-gen divergence (ADR-107).
|
|
14
|
+
# Known Steep 2.0.0 limitation (surfaced by `library "prism"`, #2718): it does not narrow `rfind` through an
|
|
15
|
+
# `is_a?` block, so it warns that the body is `Prism::Node?`; the declaration keeps the precise shape.
|
|
16
|
+
def enclosing_def: () -> (Prism::DefNode | nil)
|
|
17
|
+
def enclosing_module: () -> ::Prism::Node?
|
|
18
|
+
def enclosing_block: (Symbol method_name) -> ::Prism::Node?
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -23,11 +23,8 @@ module Rigor
|
|
|
23
23
|
def self.[]: (index: Integer, type_name: String) -> instance | (Integer index, String type_name) -> instance
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
# sig-gen gap: #2321 — `attr_reader` rows over ivars `initialize` assigns from expressions derived
|
|
27
|
-
# from its parameters (`dup.freeze`/`to_sym`), so the stored types are hand-written.
|
|
28
26
|
attr_reader path_glob: String
|
|
29
27
|
|
|
30
|
-
# sig-gen gap: #2321 — as above (`to_sym` normalizes the accepted Symbol|String).
|
|
31
28
|
attr_reader method_name: Symbol
|
|
32
29
|
|
|
33
30
|
# `singleton ? true : false` collapses any truthy input to bool — sig-gen already infers
|
|
@@ -38,12 +35,11 @@ module Rigor
|
|
|
38
35
|
# parameters are undeclared (it guarantees `Array[ParamType]`).
|
|
39
36
|
attr_reader param_types: Array[ParamType]
|
|
40
37
|
|
|
41
|
-
# sig-gen gap: #2321 — as above (nil or a non-empty `dup.freeze`d String).
|
|
42
38
|
attr_reader return_type_name: String?
|
|
43
39
|
|
|
44
|
-
#
|
|
45
|
-
#
|
|
46
|
-
#
|
|
40
|
+
# authored: the declared literal union is intent. `initialize` stores `severity.to_sym` after
|
|
41
|
+
# `validate_severity!` bounds it to `VALID_SEVERITIES`, so the value is one of the three literals, but sig-gen
|
|
42
|
+
# generates `Symbol` for it, not the union.
|
|
47
43
|
attr_reader severity: :error | :warning | :info
|
|
48
44
|
|
|
49
45
|
# `method_name`/`severity` accept String too (both are `to_sym`'d); `param_types` entries are
|
data/sig/rigor/reflection.rbs
CHANGED
|
@@ -19,5 +19,42 @@ module Rigor
|
|
|
19
19
|
def self?.class_type_param_names: (String | Symbol class_name, ?scope: Scope) -> Array[Symbol]
|
|
20
20
|
def self?.discovered_class?: (String | Symbol class_name, ?scope: Scope) -> bool
|
|
21
21
|
def self?.discovered_method?: (String | Symbol class_name, String | Symbol method_name, ?kind: Symbol, ?scope: Scope) -> bool
|
|
22
|
+
def self?.project_method_defined: (String | Symbol? class_name, String | Symbol method_name, kind: :instance | :singleton, source: :def | :discovered | :either, scope: Scope) -> Trinary
|
|
23
|
+
def self?.rbs_method_defined: (String | Symbol? class_name, String | Symbol method_name, kind: :instance | :singleton, scope: Scope) -> Trinary
|
|
24
|
+
def self?.ancestry_reaches: (String | Symbol? class_name, Array[String | Symbol] ancestor_names, kind: :instance | :singleton, scope: Scope) -> Trinary
|
|
25
|
+
# sig-gen gap: #2302 — the collector's `@classes = []` is grown by `<<`, so sig-gen reads the array as `Array[untyped]`.
|
|
26
|
+
def self?.class_declarations_in: (Prism::Node root) ?{ (DeclaredCall call) -> void } -> Array[ClassDeclaration]
|
|
27
|
+
|
|
28
|
+
# One `class` header of a parsed file, as `class_declarations_in` reports it.
|
|
29
|
+
class ClassDeclaration < Data
|
|
30
|
+
# sig-gen gap: #1150 — `Data.define` members carry no type, so sig-gen proposes `untyped`; the shape is hand-written.
|
|
31
|
+
attr_reader name: String
|
|
32
|
+
# sig-gen gap: #1150 — `Data.define` members carry no type, so sig-gen proposes `untyped`; the shape is hand-written.
|
|
33
|
+
attr_reader nesting: Array[String]
|
|
34
|
+
# sig-gen gap: #1150 — `Data.define` members carry no type, so sig-gen proposes `untyped`; the shape is hand-written.
|
|
35
|
+
attr_reader node: Prism::ClassNode
|
|
36
|
+
|
|
37
|
+
# sig-gen gap: #1150 — `Data.define` members carry no type, so the constructor's keywords are `untyped` in sig-gen.
|
|
38
|
+
def self.new: (name: String, nesting: Array[String], node: Prism::ClassNode) -> instance
|
|
39
|
+
| (String name, Array[String] nesting, Prism::ClassNode node) -> instance
|
|
40
|
+
# sig-gen gap: #1150 — `Data.define` members carry no type, so the constructor's keywords are `untyped` in sig-gen.
|
|
41
|
+
def self.[]: (name: String, nesting: Array[String], node: Prism::ClassNode) -> instance
|
|
42
|
+
| (String name, Array[String] nesting, Prism::ClassNode node) -> instance
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# One call `class_declarations_in` yields: the `Prism::CallNode` and the class or module it lexically sits in.
|
|
46
|
+
class DeclaredCall < Data
|
|
47
|
+
# sig-gen gap: #1150 — `Data.define` members carry no type, so sig-gen proposes `untyped`; the shape is hand-written.
|
|
48
|
+
attr_reader node: Prism::CallNode
|
|
49
|
+
# sig-gen gap: #1150 — `Data.define` members carry no type, so sig-gen proposes `untyped`; the shape is hand-written.
|
|
50
|
+
attr_reader owner: String?
|
|
51
|
+
|
|
52
|
+
# sig-gen gap: #1150 — `Data.define` members carry no type, so the constructor's keywords are `untyped` in sig-gen.
|
|
53
|
+
def self.new: (node: Prism::CallNode, owner: String?) -> instance
|
|
54
|
+
| (Prism::CallNode node, String? owner) -> instance
|
|
55
|
+
# sig-gen gap: #1150 — `Data.define` members carry no type, so the constructor's keywords are `untyped` in sig-gen.
|
|
56
|
+
def self.[]: (node: Prism::CallNode, owner: String?) -> instance
|
|
57
|
+
| (Prism::CallNode node, String? owner) -> instance
|
|
58
|
+
end
|
|
22
59
|
end
|
|
23
60
|
end
|
data/sig/rigor/scope.rbs
CHANGED
|
@@ -18,6 +18,7 @@ module Rigor
|
|
|
18
18
|
# its bare cause (issue #1302).
|
|
19
19
|
attr_reader optimistic_locals: Hash[Symbol, Symbol | Inference::OptimisticOrigin::BoundMark]
|
|
20
20
|
attr_reader optimistic_ivars: Hash[Symbol, Symbol | Inference::OptimisticOrigin::BoundMark]
|
|
21
|
+
attr_reader construction_facts: Hash[Symbol, Set[untyped]]
|
|
21
22
|
attr_reader repeated_or_writes: Hash[untyped, bool]
|
|
22
23
|
# sig-gen gap: #2323 — the same reader shape; `Inference::MatchRebinding::Frame` carries no signature.
|
|
23
24
|
attr_reader match_frame: untyped
|
|
@@ -29,7 +30,7 @@ module Rigor
|
|
|
29
30
|
attr_reader struct_fold_safe_locals: Set[Symbol]
|
|
30
31
|
attr_reader opaque_block_self: bool
|
|
31
32
|
# Issue #1759 — `:refinement` (REFINEMENT_BLOCK_SELF) directly in a `refine X do … end` block body.
|
|
32
|
-
attr_reader block_self_unknown: bool | :refinement
|
|
33
|
+
attr_reader block_self_unknown: bool | :refinement | :preserved
|
|
33
34
|
attr_reader singleton_class_body: bool
|
|
34
35
|
attr_reader lexical_nesting: Array[String]?
|
|
35
36
|
# Issue #1429 — a guard's narrowing of a constant reference, keyed by its spelling.
|
|
@@ -64,14 +65,24 @@ module Rigor
|
|
|
64
65
|
# authored: the list holds module names and the `InEffectRefinements::UNKNOWN` Symbol; sig-gen reads the delegated
|
|
65
66
|
# return through an unsigned class as untyped.
|
|
66
67
|
def in_effect_refinements: (untyped node, ?Array[String] declared) -> Array[String | Symbol]
|
|
68
|
+
# authored: the element is an `Array` led by its Symbol kind by contract (`[:defines, name]`, `[:ivar_set, name]`); a Set's element type stays `untyped` in sig-gen (#2177, #2317), so the generator
|
|
69
|
+
# would never propose it.
|
|
67
70
|
def discovered_global_write_census: () -> Set[Array[untyped]]
|
|
68
71
|
def discovered_includes: () -> Hash[String, Array[String]]
|
|
69
72
|
# Issue #1123 — the instance-ancestor-ORDER table beside the include one.
|
|
70
73
|
def discovered_prepends: () -> Hash[String, Array[String]]
|
|
71
74
|
def discovered_extends: () -> Hash[String, Array[String]]
|
|
75
|
+
# authored: the element is `String` (a source path) by contract; a Set's element type stays `untyped` in sig-gen (#2177, #2317), so the generator
|
|
76
|
+
# would never propose it.
|
|
72
77
|
def discovered_class_sources: () -> Hash[String, Set[String]]
|
|
78
|
+
# authored: the element is `String` (a source path) by contract; a Set's element type stays `untyped` in sig-gen (#2177, #2317), so the generator
|
|
79
|
+
# would never propose it.
|
|
73
80
|
def constant_sources: () -> Hash[String, Set[String]]
|
|
81
|
+
# authored: the element is `String` (a constant's last segment) by contract; a Set's element type stays `untyped` in sig-gen (#2177, #2317), so the generator
|
|
82
|
+
# would never propose it.
|
|
74
83
|
def published_constant_names: () -> Set[String]
|
|
84
|
+
# authored: the element is `String` (a constant name) by contract; a Set's element type stays `untyped` in sig-gen (#2177, #2317), so the generator
|
|
85
|
+
# would never propose it.
|
|
75
86
|
def local_constant_names: () -> Set[String]
|
|
76
87
|
# sig-gen gap: #1150 — the `Data.define` table it reads carries no type, so sig-gen skips the return; the shape is hand-written.
|
|
77
88
|
def bound_constant_names: (String name) -> Array[String]
|
|
@@ -89,6 +100,12 @@ module Rigor
|
|
|
89
100
|
def run_generation: () -> Object?
|
|
90
101
|
def record_dynamic_origin: (untyped node, Symbol cause) -> Scope
|
|
91
102
|
def record_optimistic_origin: (untyped node, Symbol cause) -> Scope
|
|
103
|
+
# sig-gen gap: #2840 — the reader returns through a sentinel `equal?` guard over `Hash#fetch`; sig-gen emits nothing.
|
|
104
|
+
def dynamic_origin: (untyped node) -> Symbol?
|
|
105
|
+
# sig-gen gap: #2840 — the reader returns through a sentinel `equal?` guard over `Hash#fetch`; sig-gen emits nothing.
|
|
106
|
+
def optimistic_origin: (untyped node) -> Symbol?
|
|
107
|
+
# sig-gen gap: #2840 — the reader returns through a sentinel `equal?` guard over `Hash#fetch`; sig-gen emits nothing.
|
|
108
|
+
def void_origin: (untyped node) -> Inference::VoidOrigin?
|
|
92
109
|
|
|
93
110
|
def record_void_origin: (untyped node, Inference::VoidOrigin origin) -> Scope
|
|
94
111
|
|
|
@@ -208,12 +225,16 @@ module Rigor
|
|
|
208
225
|
|
|
209
226
|
def self.empty: (?environment: Environment, ?source_path: String?) -> Scope
|
|
210
227
|
|
|
211
|
-
def initialize: (environment: Environment, locals: Hash[Symbol, Type::t], ?fact_store: Analysis::FactStore, ?self_type: Type::t?, ?ivars: Hash[Symbol, Type::t], ?cvars: Hash[Symbol, Type::t], ?globals: Hash[Symbol, Type::t], ?discovery: DiscoveryIndex, ?source_path: String?, ?opaque_block_self: bool, ?block_self_unknown: bool | :refinement, ?singleton_class_body: bool, ?dynamic_origins: Hash[untyped, Symbol], ?indexed_narrowings: Hash[IndexedKey, Type::t], ?method_chain_narrowings: Hash[ChainKey, Type::t], ?declaration_sourced: Set[[Symbol, Symbol] | [Symbol, Symbol, Symbol]], ?published_constant_sourced: Set[[Symbol, Symbol]], ?struct_fold_safe_locals: Set[Symbol], ?lexical_nesting: Array[String]?, ?local_origins: Hash[Symbol, Symbol], ?ivar_origins: Hash[Symbol, Symbol], ?void_origins: Hash[untyped, Inference::VoidOrigin], ?plugin_typed_calls: Hash[untyped, bool], ?optimistic_origins: Hash[untyped, Symbol], ?optimistic_locals: Hash[Symbol, Symbol | Inference::OptimisticOrigin::BoundMark], ?optimistic_ivars: Hash[Symbol, Symbol | Inference::OptimisticOrigin::BoundMark], ?repeated_or_writes: Hash[untyped, bool], ?match_frame: untyped, ?constant_narrowings: Hash[String, Type::t], ?guard_records: Hash[[Symbol, Symbol | String], Type::t], ?bot_guard_classes: Hash[[Symbol, Symbol | String], Array[String]], ?declared_refinements: Array[String | Symbol]) -> void
|
|
228
|
+
def initialize: (environment: Environment, locals: Hash[Symbol, Type::t], ?fact_store: Analysis::FactStore, ?self_type: Type::t?, ?ivars: Hash[Symbol, Type::t], ?cvars: Hash[Symbol, Type::t], ?globals: Hash[Symbol, Type::t], ?discovery: DiscoveryIndex, ?source_path: String?, ?opaque_block_self: bool, ?block_self_unknown: bool | :refinement | :preserved, ?singleton_class_body: bool, ?dynamic_origins: Hash[untyped, Symbol], ?indexed_narrowings: Hash[IndexedKey, Type::t], ?method_chain_narrowings: Hash[ChainKey, Type::t], ?declaration_sourced: Set[[Symbol, Symbol] | [Symbol, Symbol, Symbol]], ?published_constant_sourced: Set[[Symbol, Symbol]], ?struct_fold_safe_locals: Set[Symbol], ?lexical_nesting: Array[String]?, ?local_origins: Hash[Symbol, Symbol], ?ivar_origins: Hash[Symbol, Symbol], ?void_origins: Hash[untyped, Inference::VoidOrigin], ?plugin_typed_calls: Hash[untyped, bool], ?optimistic_origins: Hash[untyped, Symbol], ?optimistic_locals: Hash[Symbol, Symbol | Inference::OptimisticOrigin::BoundMark], ?optimistic_ivars: Hash[Symbol, Symbol | Inference::OptimisticOrigin::BoundMark], ?construction_facts: Hash[Symbol, Set[Symbol]], ?repeated_or_writes: Hash[untyped, bool], ?match_frame: untyped, ?constant_narrowings: Hash[String, Type::t], ?guard_records: Hash[[Symbol, Symbol | String], Type::t], ?bot_guard_classes: Hash[[Symbol, Symbol | String], Array[String]], ?declared_refinements: Array[String | Symbol]) -> void
|
|
212
229
|
def with_source_path: (String? path) -> Scope
|
|
213
230
|
def with_struct_fold_safe: (Set[Symbol] locals) -> Scope
|
|
214
231
|
def with_lexical_nesting: (Array[String]? chain) -> Scope
|
|
215
232
|
def struct_fold_safe?: (String | Symbol name) -> bool
|
|
233
|
+
def entering_block_without_gradual_marks: (Prism::Node block_node) -> Scope
|
|
216
234
|
def entering_opaque_block: () -> Scope
|
|
235
|
+
PRESERVED_BLOCK_SELF: :preserved
|
|
236
|
+
def entering_self_preserving_block: () -> Scope
|
|
237
|
+
def walked_block_self_unknown?: () -> bool
|
|
217
238
|
def block_self_unknown?: () -> bool
|
|
218
239
|
REFINEMENT_BLOCK_SELF: :refinement
|
|
219
240
|
def refinement_block_self?: () -> bool
|
|
@@ -229,10 +250,15 @@ module Rigor
|
|
|
229
250
|
def global: (String | Symbol name) -> Type::t?
|
|
230
251
|
def local_origin: (String | Symbol name) -> Symbol?
|
|
231
252
|
def ivar_origin: (String | Symbol name) -> Symbol?
|
|
253
|
+
# sig-gen gap: #2403 — the `Hash#[]` miss in `bound_cause` is lost across the call; sig-gen says `Symbol`.
|
|
232
254
|
def optimistic_local: (String | Symbol name) -> Symbol?
|
|
255
|
+
# sig-gen gap: #2403 — the `Hash#[]` miss in `bound_cause` is lost across the call; sig-gen says `Symbol`.
|
|
233
256
|
def optimistic_ivar: (String | Symbol name) -> Symbol?
|
|
234
257
|
def optimistic_local_miss: (String | Symbol name) -> Object?
|
|
235
258
|
def optimistic_ivar_miss: (String | Symbol name) -> Object?
|
|
259
|
+
def construction_fact?: (String | Symbol name, ?Symbol fact) -> bool
|
|
260
|
+
def project_method_name?: (untyped) -> (false | true)
|
|
261
|
+
def with_construction_fact: (untyped, untyped) -> Rigor::Scope
|
|
236
262
|
def with_local: (String | Symbol name, Type::t type) -> Scope
|
|
237
263
|
def with_rejoined_locals: (untyped) -> Rigor::Scope
|
|
238
264
|
def with_ivar: (String | Symbol name, Type::t type) -> Scope
|
|
@@ -271,8 +297,6 @@ module Rigor
|
|
|
271
297
|
def seed_declaration_sourced_global: (String | Symbol name, Type::t type) -> Scope
|
|
272
298
|
def with_global_copy_marks: (String | Symbol name, Array[String | Symbol] globals) -> Scope
|
|
273
299
|
def without_local_declaration_marks: (String | Symbol name) -> Scope
|
|
274
|
-
# sig-gen gap: #2322 — the records come out of `@declaration_sourced`, whose set now types; `ref[2]` reads as
|
|
275
|
-
# `Symbol?`, but the `filter_map` over it answers `Array[untyped]`.
|
|
276
300
|
def declaration_sourced_global_copies: (String | Symbol name) -> Array[Symbol]
|
|
277
301
|
def with_declaration_sourced_local: (String | Symbol name, Type::t type) -> Scope
|
|
278
302
|
def with_local_declaration_mark: (String | Symbol name) -> Scope
|
|
@@ -283,6 +307,9 @@ module Rigor
|
|
|
283
307
|
def with_inferred_param_mark: (String | Symbol name) -> Scope
|
|
284
308
|
def without_inferred_param_mark: (String | Symbol name) -> Scope
|
|
285
309
|
def inferred_param?: (String | Symbol name) -> bool
|
|
310
|
+
def with_gradual_narrowing_mark: (String | Symbol name) -> Scope
|
|
311
|
+
def gradual_narrowing?: (String | Symbol name) -> bool
|
|
312
|
+
def gradual_narrowing_names: () -> Array[Symbol]
|
|
286
313
|
def forget_match_globals: () -> Scope
|
|
287
314
|
def untyped_match_globals: () -> Scope
|
|
288
315
|
def match_globals_bound?: () -> bool
|
|
@@ -307,6 +334,13 @@ module Rigor
|
|
|
307
334
|
def def_node_slot: (untyped class_name, untyped method_name, ?Symbol kind) -> untyped
|
|
308
335
|
def user_def_for: (String | Symbol class_name, String | Symbol method_name) -> ::Prism::DefNode?
|
|
309
336
|
def user_def_through_ancestors: (String | Symbol class_name, String | Symbol method_name, ?name_memo: Hash[untyped, untyped]) -> ([::Prism::DefNode, String] | [nil, nil])
|
|
337
|
+
# Returns `[opaque_flag, recorder_keys]`. Steep 2.0.0 cannot verify a tuple through the
|
|
338
|
+
# `Array#freeze` on the returned literal and reports a MethodBodyTypeMismatch warning; the
|
|
339
|
+
# declaration keeps the precise shape because `rigor sig-gen` proves it.
|
|
340
|
+
def subclassing_opacity: () -> [false | true, Array[untyped]]
|
|
341
|
+
# authored: each owner is a frozen `[class_name, open_to_override]` pair. sig-gen types the lazily built
|
|
342
|
+
# `(owners ||= []) <<` array as `Array[untyped]`; the body keeps it to avoid `Hash#filter_map`'s per-entry pair.
|
|
343
|
+
def user_instance_def_owners: (untyped) -> Array[Array[untyped]]
|
|
310
344
|
def discovered_method_through_ancestors?: (String | Symbol? class_name, String | Symbol method_name, Symbol kind, ?name_memo: Hash[untyped, untyped]) -> bool
|
|
311
345
|
def external_ancestor_name_candidates: (String | Symbol class_name, ?name_memo: Hash[untyped, untyped]) -> Array[Array[String]]
|
|
312
346
|
def enqueue_ancestors: (String current, Array[String] queue, Hash[untyped, untyped] name_memo, ?mixins: bool) -> void
|
|
@@ -320,6 +354,7 @@ module Rigor
|
|
|
320
354
|
def known_user_class?: (String | Symbol name) -> bool
|
|
321
355
|
def singleton_def_for: (String | Symbol class_name, String | Symbol method_name) -> ::Prism::DefNode?
|
|
322
356
|
def module_function_def?: (untyped, untyped) -> (false | true)
|
|
357
|
+
def module_function_row_def?: (untyped, untyped) -> (false | true)
|
|
323
358
|
def singleton_def_through_ancestors: (String | Symbol class_name, String | Symbol method_name, ?name_memo: Hash[untyped, untyped]) -> ([::Prism::DefNode, String] | [nil, nil])
|
|
324
359
|
def user_def_site_for: (String | Symbol class_name, String | Symbol method_name) -> String?
|
|
325
360
|
def user_singleton_def_site_for: (String | Symbol class_name, String | Symbol method_name) -> String?
|
|
@@ -330,6 +365,9 @@ module Rigor
|
|
|
330
365
|
# sig-gen gap: #1167 — the instance-side twin: the same untyped `call_node`, the same untyped-return skip.
|
|
331
366
|
def instance_def_shadows_call?: (String | Symbol class_name, String | Symbol method_name, untyped call_node) -> bool
|
|
332
367
|
def top_level_def_for: (String | Symbol method_name) -> ::Prism::DefNode?
|
|
368
|
+
def ownerless_definition?: (untyped, ?top_level: untyped) -> (false | true)
|
|
369
|
+
def toplevel_def_ambiguity: (String | Symbol method_name) -> (:contested | :several | :main_singleton | :aliased | :anonymous | :object)?
|
|
370
|
+
def declared_class?: (String | Symbol class_name) -> bool
|
|
333
371
|
def bindable_top_level_def_for: (String | Symbol method_name) -> ::Prism::DefNode?
|
|
334
372
|
def toplevel?: () -> bool
|
|
335
373
|
def discovered_method_visibility: (String | Symbol class_name, String | Symbol method_name) -> Symbol?
|
|
@@ -337,6 +375,7 @@ module Rigor
|
|
|
337
375
|
def data_member_layout: (String | Symbol class_name) -> Array[Symbol]?
|
|
338
376
|
def struct_member_layout: (String | Symbol class_name) -> { members: Array[Symbol], keyword_init: bool }?
|
|
339
377
|
def includes_of: (String | Symbol class_name) -> Array[String]
|
|
378
|
+
def prepends_of: (String | Symbol class_name) -> Array[String]
|
|
340
379
|
# sig-gen gap: #2302 — `names = []` grown by `concat` reads `Array[untyped]`, so the element type is
|
|
341
380
|
# hand-written, matching {#includes_of}.
|
|
342
381
|
def singleton_extends_of: (String | Symbol class_name) -> Array[String]
|
data/sig/rigor/trinary.rbs
CHANGED
data/sig/rigor/type.rbs
CHANGED
|
@@ -56,8 +56,8 @@ module Rigor
|
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
class Dynamic
|
|
59
|
-
attr_reader static_facet: Type::t
|
|
60
|
-
def initialize: (Type::t static_facet) -> void
|
|
59
|
+
attr_reader static_facet: Type::t | Interface
|
|
60
|
+
def initialize: (Type::t | Interface static_facet) -> void
|
|
61
61
|
def describe: (?Symbol verbosity) -> String
|
|
62
62
|
def erase_to_rbs: () -> "untyped"
|
|
63
63
|
def top: () -> Trinary
|
|
@@ -169,6 +169,11 @@ module Rigor
|
|
|
169
169
|
def inspect: () -> String
|
|
170
170
|
end
|
|
171
171
|
|
|
172
|
+
# ADR-130 — a `Rigor::Plugin` interface, carried only as a `Dynamic`'s facet (`Dynamic[Rigor::Plugin::_Scope]`), so
|
|
173
|
+
# it is not a member of `Type::t`. Declared for that name only; its members are read from the source.
|
|
174
|
+
class Interface
|
|
175
|
+
end
|
|
176
|
+
|
|
172
177
|
class Union
|
|
173
178
|
attr_reader members: Array[Type::t]
|
|
174
179
|
def initialize: (Array[Type::t] members) -> void
|
|
@@ -446,7 +451,8 @@ module Rigor
|
|
|
446
451
|
def self?.top: () -> Top
|
|
447
452
|
def self?.bot: () -> Bot
|
|
448
453
|
def self?.untyped: () -> Dynamic
|
|
449
|
-
def self?.
|
|
454
|
+
def self?.untyped?: (Type::t? type) -> bool
|
|
455
|
+
def self?.dynamic: (Type::t | Interface static_facet) -> Dynamic
|
|
450
456
|
def self?.nominal_of: (Module | String class_name_or_object, ?type_args: Array[Type::t]) -> Nominal
|
|
451
457
|
def self?.singleton_of: (Module | String class_name_or_object) -> Singleton
|
|
452
458
|
def self?.constant_of: (untyped value) -> Constant
|
data/sig/rigor.rbs
CHANGED
|
@@ -165,8 +165,9 @@ module Rigor
|
|
|
165
165
|
# sig-gen gap: #1008 — `result` is populated by `collect_return_summaries` mutating it by
|
|
166
166
|
# reference from a sibling method; sig-gen folds only the `{}` seed and the empty-memo early
|
|
167
167
|
# return, so it proposes the seed shape instead of the honest, usually-non-empty contract.
|
|
168
|
-
# Keys are `[path, "Class#method"]` pairs; values are `{ keys:, returns:, effects: }` bundles
|
|
169
|
-
def
|
|
168
|
+
# Keys are `[path, "Class#method"]` pairs; values are `{ keys:, returns:, effects: }` bundles, or
|
|
169
|
+
# nil for a def whose keys the run cannot list. nil for a pool run, which harvests none (#3160).
|
|
170
|
+
def return_summaries: () -> Hash[[String, String], Hash[Symbol, untyped]?]?
|
|
170
171
|
# ADR-67 — `[class_name, method_name, kind] => { param_name => Type }`.
|
|
171
172
|
def param_inferred_types: () -> Hash[[String, Symbol, Symbol], Hash[Symbol, Type::t]]
|
|
172
173
|
def collect_param_inference_table: (untyped files) -> Hash[[String, Symbol, Symbol], Hash[Symbol, Type::t]]
|
data/skills/rigor-ask/SKILL.md
CHANGED
|
@@ -130,6 +130,7 @@ A good hand-off is two or three sentences of orientation plus the pointer:
|
|
|
130
130
|
- baseline reduction → **`rigor-baseline-reduce`** · coverage holes → **`rigor-protection-uplift`**
|
|
131
131
|
- a missing gem/DSL → **`rigor-plugin-author`** · monkey-patch clusters → **`rigor-monkeypatch-resolve`**
|
|
132
132
|
- about to *write* a type (RBS, `#:`, a Sorbet `sig`, a YARD tag, a doc sentence) → **`rigor-type-oracle`**
|
|
133
|
+
- auditing, fixing, or contributing RBS declarations (a gem's `sig/`, a gem_rbs_collection entry) → **`rigor-rbs-contract`**
|
|
133
134
|
|
|
134
135
|
When in doubt, give less and point — it respects the user's "three skills
|
|
135
136
|
to remember" promise and keeps each answer to the part only `rigor-ask`
|
|
@@ -68,10 +68,10 @@ install`), every plugin bundled in the toolchain is readable source.
|
|
|
68
68
|
Use it as a worked-example library throughout this skill:
|
|
69
69
|
|
|
70
70
|
```sh
|
|
71
|
-
rigor plugin
|
|
72
|
-
rigor plugin
|
|
73
|
-
rigor plugin path
|
|
74
|
-
rigor plugin root # gem root + public API (lib/rigor/plugin.rb)
|
|
71
|
+
rigor plugin # all bundled + example plugins, with paths
|
|
72
|
+
rigor plugin rigor-activesupport-core-ext # a plugin's main source, inline
|
|
73
|
+
rigor plugin --path rigor-units # the dir, to browse with your file tool
|
|
74
|
+
rigor plugin --root # gem root + public API (lib/rigor/plugin.rb)
|
|
75
75
|
```
|
|
76
76
|
|
|
77
77
|
`rigor plugin` (singular) browses the toolchain's plugins; `rigor
|
|
@@ -254,8 +254,8 @@ Two ways to wire the RBS, depending on how the plugin is packaged:
|
|
|
254
254
|
read one as a worked example:
|
|
255
255
|
|
|
256
256
|
```sh
|
|
257
|
-
rigor plugin
|
|
258
|
-
rigor plugin path
|
|
257
|
+
rigor plugin rigor-activesupport-core-ext # see manifest + sig/ layout
|
|
258
|
+
rigor plugin --path rigor-activesupport-core-ext # then browse its sig/ dir
|
|
259
259
|
```
|
|
260
260
|
|
|
261
261
|
2. **A project-private plugin** — the manifest field still works, but
|
|
@@ -280,9 +280,9 @@ They compose — many plugins ship both.
|
|
|
280
280
|
|
|
281
281
|
> **Browse a real plugin instead of guessing the API.** Because Rigor
|
|
282
282
|
> is installed on disk (`mise` / `gem install`), every bundled plugin's
|
|
283
|
-
> source is readable as a worked example. `rigor plugin
|
|
284
|
-
> them all with absolute paths; `rigor plugin
|
|
285
|
-
> plugin's main source; `rigor plugin root` points at the engine source
|
|
283
|
+
> source is readable as a worked example. `rigor plugin` shows
|
|
284
|
+
> them all with absolute paths; `rigor plugin <name>` inlines a
|
|
285
|
+
> plugin's main source; `rigor plugin --root` points at the engine source
|
|
286
286
|
> and the public `Rigor::Plugin::Base` API. When the prose here is
|
|
287
287
|
> thinner than you need, read a shipped plugin that does the same thing.
|
|
288
288
|
|
|
@@ -74,9 +74,9 @@ Rigor is installed on disk, so both the plugin under review and the
|
|
|
74
74
|
worked-example plugins are readable source:
|
|
75
75
|
|
|
76
76
|
```sh
|
|
77
|
-
rigor plugin
|
|
78
|
-
rigor plugin
|
|
79
|
-
rigor plugin path
|
|
77
|
+
rigor plugin # every bundled + example plugin, with paths
|
|
78
|
+
rigor plugin rigor-<id> # a plugin's main source, inline
|
|
79
|
+
rigor plugin --path rigor-<id> # its directory, to browse
|
|
80
80
|
```
|
|
81
81
|
|
|
82
82
|
The **authoritative** authoring surface — the one this review scores
|
|
@@ -56,6 +56,7 @@ bundle exec rbs collection install
|
|
|
56
56
|
Use `bundle exec` when `rbs` appears in `Gemfile` or `Gemfile.lock`
|
|
57
57
|
(the common case — Steep / rbs_rails workflows put it there). If `rbs`
|
|
58
58
|
is not in the Gemfile, use the bare `rbs collection install` instead.
|
|
59
|
+
If `bundle exec rbs` runs an `rbs` that `gem:rigortype` put on `PATH` instead of the project's, see the [install guide's note on `rbs` shadowing](https://github.com/rigortype/rigor/blob/master/docs/install.md#case-a--mise-is-available-recommended).
|
|
59
60
|
|
|
60
61
|
Ask the user for permission before running, since this installs files
|
|
61
62
|
into `.gem_rbs_collection/` (a generated directory that belongs in
|
|
@@ -170,6 +170,8 @@ bundle exec rbs collection install # if rbs is in Gemfile
|
|
|
170
170
|
# or: rbs collection install
|
|
171
171
|
```
|
|
172
172
|
|
|
173
|
+
If `bundle exec rbs` runs an `rbs` that `gem:rigortype` put on `PATH` instead of the project's, see the [install guide's note on `rbs` shadowing](https://github.com/rigortype/rigor/blob/master/docs/install.md#case-a--mise-is-available-recommended).
|
|
174
|
+
|
|
173
175
|
Re-run `rigor triage`. If the `gem-without-rbs` count drops, carry
|
|
174
176
|
the new, smaller count into Phase 7.
|
|
175
177
|
|
|
@@ -218,8 +220,19 @@ baseline is a ceiling, not a blanket. Reducing it later is the
|
|
|
218
220
|
Recommend committing `.rigor-baseline.yml` — it documents project
|
|
219
221
|
state; list it in the Final step's file inventory.
|
|
220
222
|
|
|
223
|
+
**Rule-less diagnostics cannot be baselined.** A file Prism cannot
|
|
224
|
+
parse (a parse error), a missing `paths:` entry or an internal error
|
|
225
|
+
yields a diagnostic with no rule, so it has no `(file, rule)` bucket.
|
|
226
|
+
The summary then prints a second line ("N diagnostic(s) have no rule
|
|
227
|
+
(parse, path or internal errors) in M file(s) and cannot be
|
|
228
|
+
baselined") and lists the files; the command still exits 0. Acknowledge
|
|
229
|
+
mode reaches a green `rigor check` only after those files are fixed or
|
|
230
|
+
added to `exclude:`, or the bad `paths:` entry is removed. Do that
|
|
231
|
+
before wiring `baseline:`, then re-run `rigor baseline regenerate`.
|
|
232
|
+
|
|
221
233
|
Print the suppression summary for the user: "N diagnostics recorded
|
|
222
|
-
as baseline; M will surface on subsequent runs."
|
|
234
|
+
as baseline; M will surface on subsequent runs." Take N from the
|
|
235
|
+
`covering N diagnostic(s)` count, and count the unbaselineable ones in M.
|
|
223
236
|
|
|
224
237
|
## Phase 8 — Surface real bugs & offer escalation
|
|
225
238
|
|
|
@@ -386,7 +399,9 @@ information and Rigor has no built-in coverage. In order:
|
|
|
386
399
|
|
|
387
400
|
1. `bundle exec rbs collection install` (bare `rbs collection install`
|
|
388
401
|
if `rbs` is not in the project's Gemfile) — pulls community RBS for
|
|
389
|
-
the gem if it exists. Re-run triage afterwards.
|
|
402
|
+
the gem if it exists. Re-run triage afterwards. If `bundle exec rbs`
|
|
403
|
+
runs a `gem:rigortype` `rbs` instead of the project's, see the
|
|
404
|
+
[install guide's note on `rbs` shadowing](https://github.com/rigortype/rigor/blob/master/docs/install.md#case-a--mise-is-available-recommended).
|
|
390
405
|
2. `dependencies.source_inference:` in `.rigor.dist.yml` — opt the
|
|
391
406
|
gem into Rigor inferring `Dynamic`-typed returns from its source.
|
|
392
407
|
3. If the gem is widely used and genuinely warrants first-class
|
|
@@ -28,13 +28,13 @@ rigor skill --full rigor-type-oracle
|
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
Its `references/02-agents-md-fragment.md` section carries the paragraph
|
|
31
|
-
and the
|
|
31
|
+
and the six bullets. Copy that block **verbatim** — including its
|
|
32
32
|
single-long-line shape, which is deliberate (some renderers turn a
|
|
33
33
|
newline inside a paragraph into a line break).
|
|
34
34
|
|
|
35
|
-
Do not paraphrase it from memory, and do not shorten it: the
|
|
35
|
+
Do not paraphrase it from memory, and do not shorten it: the six bullets
|
|
36
36
|
are the load-bearing part — expression, method signature, parameter,
|
|
37
|
-
the gap rule, and
|
|
37
|
+
the gap rule, provenance, and the declared-`void` contract.
|
|
38
38
|
|
|
39
39
|
## Where it goes
|
|
40
40
|
|
|
@@ -44,7 +44,7 @@ the gap rule, and provenance.
|
|
|
44
44
|
| Only `CLAUDE.md` exists | Append it there. |
|
|
45
45
|
| Both exist | Put it in `AGENTS.md`. Add `@AGENTS.md` to `CLAUDE.md` only if it is not already pulled in. |
|
|
46
46
|
| Neither exists | **Create `AGENTS.md`** with this as its first section. |
|
|
47
|
-
| A types / type-checking section already exists | Merge into it; keep the
|
|
47
|
+
| A types / type-checking section already exists | Merge into it; keep the six bullets intact. Never write a second, competing rule. |
|
|
48
48
|
|
|
49
49
|
Never overwrite unrelated content. If the project already states a rule
|
|
50
50
|
about type authorship that contradicts this one, stop and show the user
|