rigortype 0.3.8 → 0.4.0
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/capability_roles/capability_roles.rbs +36 -0
- data/data/core_overlay/enumerable.rbs +51 -0
- data/data/core_overlay/enumerator.rbs +84 -0
- data/data/core_overlay/hash_rbs3.rbs +41 -0
- data/data/core_overlay/process.rbs +40 -0
- data/data/core_overlay/string_io.rbs +33 -0
- data/data/effects/core.yml +3 -3
- data/data/gem_overlay/activesupport/core_ext.rbs +236 -17
- data/docs/handbook/02-everyday-types.md +17 -14
- data/docs/handbook/03-narrowing.md +132 -14
- data/docs/handbook/04-tuples-and-shapes.md +8 -6
- data/docs/handbook/05-methods-and-blocks.md +1 -1
- data/docs/handbook/06-classes.md +2 -2
- data/docs/handbook/07-rbs-and-extended.md +19 -1
- data/docs/handbook/10-sorbet.md +9 -10
- data/docs/handbook/11-sig-gen.md +525 -13
- data/docs/handbook/README.md +1 -1
- data/docs/handbook/appendix-elixir.md +2 -2
- data/docs/handbook/appendix-go.md +2 -2
- data/docs/handbook/appendix-java-csharp.md +2 -2
- data/docs/handbook/appendix-mypy.md +2 -2
- data/docs/handbook/appendix-phpstan.md +1 -1
- data/docs/handbook/appendix-rust.md +1 -1
- data/docs/handbook/appendix-type-theory.md +4 -4
- data/docs/handbook/appendix-typescript.md +1 -1
- data/docs/llms.txt +2 -0
- data/docs/manual/02-cli-reference.md +95 -6
- data/docs/manual/03-configuration.md +18 -0
- data/docs/manual/04-diagnostics.md +15 -0
- data/docs/manual/07-plugins.md +15 -5
- data/docs/manual/08-skills.md +23 -2
- data/docs/manual/10-mcp-server.md +3 -2
- data/docs/manual/11-ci.md +9 -0
- data/docs/manual/15-type-protection-coverage.md +8 -0
- data/docs/manual/16-rbs-extended-annotations.md +46 -8
- data/docs/manual/18-removing-dead-code.md +10 -8
- data/docs/manual/19-effect-labels.md +10 -0
- data/docs/manual/plugins/README.md +7 -0
- data/docs/manual/plugins/rigor-actioncable.md +8 -1
- data/docs/manual/plugins/rigor-actionmailer.md +7 -0
- data/docs/manual/plugins/rigor-actionpack.md +261 -0
- data/docs/manual/plugins/rigor-active-model-serializers.md +153 -0
- data/docs/manual/plugins/rigor-activejob.md +7 -0
- data/docs/manual/plugins/rigor-activerecord.md +138 -4
- data/docs/manual/plugins/rigor-activestorage.md +8 -1
- data/docs/manual/plugins/rigor-activesupport-core-ext.md +43 -7
- data/docs/manual/plugins/rigor-grape.md +106 -0
- data/docs/manual/plugins/rigor-graphql.md +23 -2
- data/docs/manual/plugins/rigor-pundit.md +8 -1
- data/docs/manual/plugins/rigor-rails-i18n.md +10 -5
- data/docs/manual/plugins/rigor-rails-routes.md +7 -0
- data/docs/manual/plugins/rigor-rbs-inline.md +229 -1
- data/docs/manual/plugins/rigor-sidekiq.md +8 -1
- data/docs/manual/plugins/rigor-sorbet.md +21 -5
- data/exe/rigor +19 -4
- data/lib/rigor/analysis/baseline.rb +3 -3
- data/lib/rigor/analysis/check_rules/always_truthy_condition_collector.rb +1 -1
- data/lib/rigor/analysis/check_rules/dead_version_guard_arms.rb +1 -5
- data/lib/rigor/analysis/check_rules/declaration_sourced_guard.rb +167 -2
- data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +10 -2
- data/lib/rigor/analysis/check_rules/lexical_method_sites.rb +189 -0
- data/lib/rigor/analysis/check_rules/main_pass_collector.rb +6 -4
- data/lib/rigor/analysis/check_rules/published_constant_guard.rb +15 -6
- data/lib/rigor/analysis/check_rules/rule_ids.rb +21 -6
- data/lib/rigor/analysis/check_rules/rule_walk.rb +41 -5
- data/lib/rigor/analysis/check_rules/self_closedness_scanner.rb +1 -1
- data/lib/rigor/analysis/check_rules/shadowed_rescue_collector.rb +1 -1
- data/lib/rigor/analysis/check_rules/source_arity.rb +323 -0
- data/lib/rigor/analysis/check_rules/special_global_setters.rb +146 -0
- data/lib/rigor/analysis/check_rules/unreachable_clause_collector.rb +38 -4
- data/lib/rigor/analysis/check_rules/void_value_use_collector.rb +0 -1
- data/lib/rigor/analysis/check_rules.rb +718 -79
- data/lib/rigor/analysis/crash_signature.rb +8 -24
- data/lib/rigor/analysis/dependency_recorder.rb +23 -0
- data/lib/rigor/analysis/dependency_source_inference/boundary_cross_reporter.rb +1 -1
- data/lib/rigor/analysis/dependency_source_inference/builder.rb +0 -2
- data/lib/rigor/analysis/dependency_source_inference/gem_resolver.rb +0 -2
- data/lib/rigor/analysis/dependency_source_inference/index.rb +5 -5
- data/lib/rigor/analysis/dependency_source_inference/return_type_heuristic.rb +1 -2
- data/lib/rigor/analysis/dependency_source_inference/walker.rb +4 -4
- data/lib/rigor/analysis/effects_cache_probe.rb +3 -4
- data/lib/rigor/analysis/erb_template_detector.rb +1 -2
- data/lib/rigor/analysis/fact_store.rb +15 -1
- data/lib/rigor/analysis/incremental.rb +42 -0
- data/lib/rigor/analysis/incremental_session.rb +117 -26
- data/lib/rigor/analysis/plugin_fact_fingerprint.rb +0 -1
- data/lib/rigor/analysis/project_scan.rb +11 -1
- data/lib/rigor/analysis/reachability/graph.rb +3 -5
- data/lib/rigor/analysis/reachability/plugin_roots.rb +5 -5
- data/lib/rigor/analysis/reachability/project_files.rb +2 -2
- data/lib/rigor/analysis/reachability/scan.rb +5 -5
- data/lib/rigor/analysis/reachability/scan_cache.rb +3 -2
- data/lib/rigor/analysis/reachability/signature_scan.rb +2 -2
- data/lib/rigor/analysis/result.rb +1 -3
- data/lib/rigor/analysis/rule_catalog.rb +131 -1
- data/lib/rigor/analysis/run_cache_key.rb +21 -12
- data/lib/rigor/analysis/run_cache_probe.rb +3 -5
- data/lib/rigor/analysis/runner/buffer_pool_dispatcher.rb +6 -8
- data/lib/rigor/analysis/runner/declaration_position.rb +1 -2
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +340 -33
- data/lib/rigor/analysis/runner/effect_annotation_residual_pass.rb +2 -3
- data/lib/rigor/analysis/runner/effect_envelope_pass.rb +18 -14
- data/lib/rigor/analysis/runner/pool_coordinator.rb +357 -97
- data/lib/rigor/analysis/runner/project_pre_passes.rb +38 -13
- data/lib/rigor/analysis/runner/run_snapshots.rb +6 -1
- data/lib/rigor/analysis/runner.rb +407 -51
- data/lib/rigor/analysis/template_unit_collector.rb +303 -0
- data/lib/rigor/analysis/template_unit_paths.rb +91 -0
- data/lib/rigor/analysis/template_unit_positions.rb +293 -0
- data/lib/rigor/analysis/template_units.rb +399 -0
- data/lib/rigor/analysis/worker_session.rb +62 -20
- data/lib/rigor/bleeding_edge.rb +10 -24
- data/lib/rigor/builtins/hkt_builtins.rb +3 -2
- data/lib/rigor/builtins/imported_refinements.rb +159 -21
- data/lib/rigor/builtins/predefined_constant_refinements.rb +5 -7
- data/lib/rigor/builtins/regex_refinement.rb +21 -13
- data/lib/rigor/builtins/static_return_refinements.rb +7 -6
- data/lib/rigor/cache/annotation_location.rb +2 -4
- data/lib/rigor/cache/descriptor.rb +63 -20
- data/lib/rigor/cache/engine_source.rb +33 -5
- data/lib/rigor/cache/file_digest.rb +9 -1
- data/lib/rigor/cache/incremental_snapshot.rb +72 -6
- data/lib/rigor/cache/rbs_cache_producer.rb +4 -0
- data/lib/rigor/cache/rbs_class_ancestor_table.rb +0 -3
- data/lib/rigor/cache/rbs_class_type_param_names.rb +0 -3
- data/lib/rigor/cache/rbs_constant_table.rb +0 -3
- data/lib/rigor/cache/rbs_descriptor.rb +112 -14
- data/lib/rigor/cache/rbs_environment.rb +8 -4
- data/lib/rigor/cache/rbs_known_class_names.rb +0 -3
- data/lib/rigor/cache/store.rb +76 -32
- data/lib/rigor/ci_detector.rb +1 -0
- data/lib/rigor/cli/annotate_command.rb +5 -6
- data/lib/rigor/cli/check_command.rb +57 -10
- data/lib/rigor/cli/check_invocation.rb +6 -11
- data/lib/rigor/cli/check_runner_factory.rb +1 -5
- data/lib/rigor/cli/coverage_command.rb +1 -1
- data/lib/rigor/cli/coverage_mutation.rb +12 -3
- data/lib/rigor/cli/coverage_scan.rb +1 -5
- data/lib/rigor/cli/diff_command.rb +1 -1
- data/lib/rigor/cli/doc_links.rb +4 -4
- data/lib/rigor/cli/docs_command.rb +6 -6
- data/lib/rigor/cli/doctor_command.rb +85 -38
- data/lib/rigor/cli/effects_command.rb +2 -2
- data/lib/rigor/cli/effects_diff_renderer.rb +3 -3
- data/lib/rigor/cli/effects_snapshot_command.rb +1 -1
- data/lib/rigor/cli/explain_command.rb +34 -1
- data/lib/rigor/cli/fused_protection_report.rb +7 -1
- data/lib/rigor/cli/lsp_command.rb +1 -1
- data/lib/rigor/cli/mcp_command.rb +1 -1
- data/lib/rigor/cli/measurement_integrity_warning.rb +4 -5
- data/lib/rigor/cli/mutation_fork_scan.rb +6 -6
- data/lib/rigor/cli/mutation_protection_report.rb +7 -1
- data/lib/rigor/cli/plugin_command.rb +4 -4
- data/lib/rigor/cli/plugins_command.rb +2 -1
- data/lib/rigor/cli/prism_colorizer.rb +1 -2
- data/lib/rigor/cli/protection_fork_scan.rb +6 -6
- data/lib/rigor/cli/show_bleedingedge_command.rb +1 -1
- data/lib/rigor/cli/sig_gen_command.rb +212 -31
- data/lib/rigor/cli/skill_command.rb +2 -2
- data/lib/rigor/cli/skill_deep_probe.rb +4 -4
- data/lib/rigor/cli/skill_describe.rb +35 -35
- data/lib/rigor/cli/trace_command.rb +4 -4
- data/lib/rigor/cli/trace_renderer.rb +5 -6
- data/lib/rigor/cli/triage_command.rb +1 -1
- data/lib/rigor/cli/type_of_command.rb +29 -11
- data/lib/rigor/cli/type_of_renderer.rb +20 -9
- data/lib/rigor/cli/type_of_template_probe.rb +189 -0
- data/lib/rigor/cli/type_scan_command.rb +4 -4
- data/lib/rigor/cli/unused_command.rb +11 -3
- data/lib/rigor/cli/upgrade_command.rb +1 -1
- data/lib/rigor/cli.rb +89 -9
- data/lib/rigor/config_audit.rb +30 -5
- data/lib/rigor/configuration/severity_profile.rb +25 -9
- data/lib/rigor/configuration.rb +109 -7
- data/lib/rigor/effects/ancestry_recorder.rb +191 -0
- data/lib/rigor/effects/attribution.rb +12 -5
- data/lib/rigor/effects/callee_rule.rb +368 -0
- data/lib/rigor/effects/catalog.rb +7 -4
- data/lib/rigor/effects/collector.rb +11 -5
- data/lib/rigor/effects/config_envelopes.rb +15 -10
- data/lib/rigor/effects/definition_context.rb +179 -0
- data/lib/rigor/effects/definition_lines.rb +25 -6
- data/lib/rigor/effects/effect_table.rb +11 -4
- data/lib/rigor/effects/entry_points.rb +0 -2
- data/lib/rigor/effects/envelope_check.rb +9 -9
- data/lib/rigor/effects/envelope_index.rb +20 -8
- data/lib/rigor/effects/file_collection.rb +59 -5
- data/lib/rigor/effects/framework_units.rb +5 -7
- data/lib/rigor/effects/identity.rb +20 -6
- data/lib/rigor/effects/inline_anchor.rb +7 -7
- data/lib/rigor/effects/label_intent.rb +3 -4
- data/lib/rigor/effects/liskov_check.rb +8 -8
- data/lib/rigor/effects/local_ownership.rb +38 -12
- data/lib/rigor/effects/method_key.rb +22 -1
- data/lib/rigor/effects/mutation_classifier.rb +23 -12
- data/lib/rigor/effects/plugin_facts.rb +47 -37
- data/lib/rigor/effects/propagator.rb +297 -19
- data/lib/rigor/effects/registry.rb +1 -1
- data/lib/rigor/effects/scanner.rb +122 -73
- data/lib/rigor/effects/signature_sources.rb +4 -6
- data/lib/rigor/effects/snapshot.rb +12 -11
- data/lib/rigor/effects/snapshot_diff.rb +1 -1
- data/lib/rigor/effects/summary.rb +27 -4
- data/lib/rigor/effects/unit_scan.rb +393 -38
- data/lib/rigor/effects/unknown_label_check.rb +3 -8
- data/lib/rigor/effects/unknown_label_report.rb +3 -4
- data/lib/rigor/effects/visibility.rb +101 -0
- data/lib/rigor/environment/bundle_sig_discovery.rb +6 -6
- data/lib/rigor/environment/class_registry.rb +3 -1
- data/lib/rigor/environment/failure_slot.rb +2 -2
- data/lib/rigor/environment/installed_gem_set.rb +85 -0
- data/lib/rigor/environment/lockfile_resolver.rb +68 -4
- data/lib/rigor/environment/member_consistency/comparator.rb +708 -0
- data/lib/rigor/environment/member_consistency.rb +298 -0
- data/lib/rigor/environment/missing_gem_constant_index.rb +4 -4
- data/lib/rigor/environment/rbs_collection_discovery.rb +5 -5
- data/lib/rigor/environment/rbs_coverage_report.rb +5 -5
- data/lib/rigor/environment/rbs_hierarchy.rb +3 -1
- data/lib/rigor/environment/rbs_loader.rb +674 -79
- data/lib/rigor/environment.rb +174 -24
- data/lib/rigor/flow_contribution/merger.rb +0 -2
- data/lib/rigor/flow_contribution.rb +11 -13
- data/lib/rigor/hashing/xxh3.rb +264 -0
- data/lib/rigor/inference/acceptance.rb +292 -17
- data/lib/rigor/inference/block_auto_splat.rb +216 -0
- data/lib/rigor/inference/block_call_timing.rb +338 -0
- data/lib/rigor/inference/block_parameter_binder.rb +75 -30
- data/lib/rigor/inference/block_repetition.rb +71 -0
- data/lib/rigor/inference/body_fixpoint.rb +7 -6
- data/lib/rigor/inference/budget_trace.rb +3 -6
- data/lib/rigor/inference/builtins/method_catalog.rb +2 -1
- data/lib/rigor/inference/builtins/string_catalog.rb +1 -1
- data/lib/rigor/inference/captured_locals.rb +389 -18
- data/lib/rigor/inference/closure_escape_analyzer.rb +159 -17
- data/lib/rigor/inference/content_join.rb +200 -27
- data/lib/rigor/inference/coverage_scanner.rb +4 -6
- data/lib/rigor/inference/def_return_typer.rb +11 -7
- data/lib/rigor/inference/define_method_block_self.rb +64 -0
- data/lib/rigor/inference/dynamic_origin.rb +1 -1
- data/lib/rigor/inference/element_read_widening.rb +180 -0
- data/lib/rigor/inference/error_info.rb +196 -0
- data/lib/rigor/inference/expression_typer.rb +2124 -468
- data/lib/rigor/inference/external_ancestor_resolution.rb +267 -0
- data/lib/rigor/inference/fork_map.rb +5 -7
- data/lib/rigor/inference/fresh_frame_blocks.rb +127 -0
- data/lib/rigor/inference/global_write_census.rb +239 -0
- data/lib/rigor/inference/guard_rebinding.rb +447 -0
- data/lib/rigor/inference/hash_lookup_mutation.rb +88 -0
- data/lib/rigor/inference/hkt_reducer.rb +2 -3
- data/lib/rigor/inference/hkt_registry.rb +4 -7
- data/lib/rigor/inference/index_write_widening.rb +16 -7
- data/lib/rigor/inference/indexed_narrowing.rb +61 -9
- data/lib/rigor/inference/jump_targets.rb +82 -0
- data/lib/rigor/inference/last_line/implicit_self.rb +210 -0
- data/lib/rigor/inference/last_line/self_evidence.rb +329 -0
- data/lib/rigor/inference/last_line.rb +340 -0
- data/lib/rigor/inference/last_status.rb +144 -0
- data/lib/rigor/inference/macro_block_self_type.rb +168 -21
- data/lib/rigor/inference/match_rebinding/calls.rb +281 -0
- data/lib/rigor/inference/match_rebinding/frame.rb +148 -0
- data/lib/rigor/inference/match_rebinding/operands.rb +236 -0
- data/lib/rigor/inference/match_rebinding/self_calls.rb +83 -0
- data/lib/rigor/inference/match_rebinding.rb +392 -0
- data/lib/rigor/inference/method_dispatcher/alias_strict_nominals.rb +36 -0
- data/lib/rigor/inference/method_dispatcher/block_folding.rb +87 -33
- data/lib/rigor/inference/method_dispatcher/cgi_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/constant_folding.rb +305 -19
- data/lib/rigor/inference/method_dispatcher/data_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/facet_distribution.rb +147 -0
- data/lib/rigor/inference/method_dispatcher/file_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/hash_transform_keys_folding.rb +191 -0
- data/lib/rigor/inference/method_dispatcher/iterator_dispatch.rb +6 -2
- data/lib/rigor/inference/method_dispatcher/json_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/kernel_dispatch.rb +7 -1
- data/lib/rigor/inference/method_dispatcher/match_data_folding.rb +159 -0
- data/lib/rigor/inference/method_dispatcher/math_folding.rb +41 -3
- data/lib/rigor/inference/method_dispatcher/method_folding.rb +2 -5
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +165 -111
- data/lib/rigor/inference/method_dispatcher/process_folding.rb +56 -0
- data/lib/rigor/inference/method_dispatcher/proven_overload.rb +72 -0
- data/lib/rigor/inference/method_dispatcher/random_folding.rb +82 -0
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +1046 -69
- data/lib/rigor/inference/method_dispatcher/receiver_affinity.rb +25 -4
- data/lib/rigor/inference/method_dispatcher/reduce_folding.rb +2 -8
- data/lib/rigor/inference/method_dispatcher/regexp_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/self_substitute.rb +142 -0
- data/lib/rigor/inference/method_dispatcher/set_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +129 -54
- data/lib/rigor/inference/method_dispatcher/shellwords_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/singleton_mixin_dispatch.rb +1 -2
- data/lib/rigor/inference/method_dispatcher/struct_folding.rb +5 -6
- data/lib/rigor/inference/method_dispatcher/struct_materialization.rb +85 -4
- data/lib/rigor/inference/method_dispatcher/time_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/universal_object_dispatch.rb +1 -2
- data/lib/rigor/inference/method_dispatcher/uri_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher.rb +225 -25
- data/lib/rigor/inference/method_parameter_binder.rb +12 -9
- data/lib/rigor/inference/multi_target_binder.rb +341 -55
- data/lib/rigor/inference/mutation_rejoin.rb +171 -0
- data/lib/rigor/inference/mutation_widening.rb +156 -85
- data/lib/rigor/inference/narrowing.rb +835 -162
- data/lib/rigor/inference/operand_effects.rb +167 -0
- data/lib/rigor/inference/operand_walk.rb +88 -0
- data/lib/rigor/inference/optimistic_origin.rb +153 -16
- data/lib/rigor/inference/origin_lookup.rb +2 -3
- data/lib/rigor/inference/parameter_inference_collector.rb +7 -7
- data/lib/rigor/inference/pre_eval_constants.rb +6 -5
- data/lib/rigor/inference/precision_scanner.rb +3 -4
- data/lib/rigor/inference/project_method_ownership.rb +136 -0
- data/lib/rigor/inference/project_patched_methods.rb +9 -4
- data/lib/rigor/inference/project_patched_scanner.rb +10 -6
- data/lib/rigor/inference/protection_scanner.rb +1 -2
- data/lib/rigor/inference/range_constant.rb +57 -0
- data/lib/rigor/inference/rbs_type_translator.rb +49 -11
- data/lib/rigor/inference/receiver_alias.rb +93 -4
- data/lib/rigor/inference/receiver_blind_block.rb +219 -0
- data/lib/rigor/inference/refinement_mutation.rb +76 -0
- data/lib/rigor/inference/repeated_or_writes.rb +463 -0
- data/lib/rigor/inference/return_barrier.rb +54 -0
- data/lib/rigor/inference/rewrite_mutation.rb +120 -0
- data/lib/rigor/inference/scope_indexer.rb +5228 -627
- data/lib/rigor/inference/statement_evaluator.rb +3452 -595
- data/lib/rigor/inference/stored_block_call.rb +54 -0
- data/lib/rigor/inference/string_mutation.rb +97 -0
- data/lib/rigor/inference/struct_fold_safety.rb +6 -7
- data/lib/rigor/inference/synthetic_method_index.rb +1 -2
- data/lib/rigor/inference/synthetic_method_scanner.rb +4 -6
- data/lib/rigor/inference/unknown_store_widening.rb +200 -0
- data/lib/rigor/inference/unthreaded_rebinds.rb +282 -0
- data/lib/rigor/inference/version_guard.rb +28 -21
- data/lib/rigor/inference/void_origin.rb +3 -3
- data/lib/rigor/inference/void_tail_summary.rb +2 -4
- data/lib/rigor/language_server/buffer_table.rb +4 -4
- data/lib/rigor/language_server/completion_provider.rb +1 -1
- data/lib/rigor/language_server/debouncer.rb +0 -1
- data/lib/rigor/language_server/diagnostic_publisher.rb +7 -6
- data/lib/rigor/language_server/document_symbol_provider.rb +1 -1
- data/lib/rigor/language_server/folding_range_provider.rb +1 -1
- data/lib/rigor/language_server/hover_provider.rb +1 -1
- data/lib/rigor/language_server/hover_renderer.rb +4 -4
- data/lib/rigor/language_server/incremental_sync.rb +6 -6
- data/lib/rigor/language_server/project_context.rb +7 -8
- data/lib/rigor/language_server/publish_batcher.rb +2 -2
- data/lib/rigor/language_server/selection_range_provider.rb +2 -2
- data/lib/rigor/language_server/server.rb +9 -9
- data/lib/rigor/language_server/signature_help_provider.rb +1 -1
- data/lib/rigor/language_server/uri.rb +1 -1
- data/lib/rigor/mcp/server.rb +2 -1
- data/lib/rigor/plugin/base.rb +258 -26
- data/lib/rigor/plugin/box_probe.rb +91 -0
- data/lib/rigor/plugin/bundled_catalog.rb +167 -0
- data/lib/rigor/plugin/effect_attribution.rb +65 -11
- data/lib/rigor/plugin/effect_entry_points.rb +3 -3
- data/lib/rigor/plugin/fact_store.rb +6 -6
- data/lib/rigor/plugin/io_boundary.rb +93 -8
- data/lib/rigor/plugin/isolation.rb +29 -6
- data/lib/rigor/plugin/loader.rb +33 -13
- data/lib/rigor/plugin/macro/block_as_method.rb +45 -6
- data/lib/rigor/plugin/macro/heredoc_template.rb +1 -1
- data/lib/rigor/plugin/macro/trait_registry.rb +1 -1
- data/lib/rigor/plugin/manifest.rb +94 -11
- data/lib/rigor/plugin/registry.rb +76 -12
- data/lib/rigor/plugin/source_rbs_synthesis_reporter.rb +21 -4
- data/lib/rigor/plugin/template_unit.rb +196 -0
- data/lib/rigor/plugin/trust_policy.rb +2 -4
- data/lib/rigor/plugin/type_node_resolver.rb +3 -3
- data/lib/rigor/plugin.rb +1 -0
- data/lib/rigor/plugin_gap_advisory.rb +96 -0
- data/lib/rigor/project_environment.rb +138 -0
- data/lib/rigor/protection/analysis_guard.rb +93 -14
- data/lib/rigor/protection/closure_kill_oracle.rb +67 -23
- data/lib/rigor/protection/dependency_closure.rb +5 -8
- data/lib/rigor/protection/diagnostic_oracle.rb +2 -2
- data/lib/rigor/protection/discovery_seed.rb +14 -12
- data/lib/rigor/protection/kill_signature.rb +1 -4
- data/lib/rigor/protection/measurement_integrity.rb +1 -3
- data/lib/rigor/protection/mutation_cache.rb +7 -11
- data/lib/rigor/protection/mutation_scanner.rb +12 -15
- data/lib/rigor/protection/mutator.rb +2 -1
- data/lib/rigor/protection/test_suite_oracle.rb +5 -5
- data/lib/rigor/rbs_extended/conformance_checker.rb +4 -3
- data/lib/rigor/rbs_extended/envelope_scanner.rb +4 -6
- data/lib/rigor/rbs_extended/reporter.rb +36 -10
- data/lib/rigor/rbs_extended.rb +88 -21
- data/lib/rigor/reflection/constant_ancestors.rb +97 -0
- data/lib/rigor/reflection/constant_path.rb +139 -0
- data/lib/rigor/reflection.rb +93 -110
- data/lib/rigor/runtime/jit.rb +6 -8
- data/lib/rigor/scope/discovery_index.rb +165 -2
- data/lib/rigor/scope.rb +1041 -32
- data/lib/rigor/sig_gen/alias_index.rb +289 -0
- data/lib/rigor/sig_gen/classification.rb +22 -5
- data/lib/rigor/sig_gen/declaration_equivalence.rb +127 -0
- data/lib/rigor/sig_gen/effect_annotation.rb +202 -0
- data/lib/rigor/sig_gen/generator.rb +673 -53
- data/lib/rigor/sig_gen/inline_declarations.rb +184 -0
- data/lib/rigor/sig_gen/layout_index.rb +3 -4
- data/lib/rigor/sig_gen/meta_class_shape.rb +3 -5
- data/lib/rigor/sig_gen/method_candidate.rb +47 -3
- data/lib/rigor/sig_gen/observation_collector.rb +18 -16
- data/lib/rigor/sig_gen/path_mapper.rb +4 -6
- data/lib/rigor/sig_gen/rbs_validity.rb +4 -4
- data/lib/rigor/sig_gen/renderer.rb +128 -14
- data/lib/rigor/sig_gen/skip_reason_catalog.rb +154 -0
- data/lib/rigor/sig_gen/superclass_spelling.rb +27 -0
- data/lib/rigor/sig_gen/type_elaborator.rb +1 -3
- data/lib/rigor/sig_gen/write_result.rb +19 -3
- data/lib/rigor/sig_gen/writer.rb +189 -41
- data/lib/rigor/sig_gen.rb +3 -0
- data/lib/rigor/signature_path_audit.rb +153 -6
- data/lib/rigor/source/literals.rb +0 -23
- data/lib/rigor/source/node_children.rb +0 -2
- data/lib/rigor/source/node_locator.rb +5 -11
- data/lib/rigor/source/node_walker.rb +0 -6
- data/lib/rigor/source/parameter_envelope.rb +72 -0
- data/lib/rigor/source.rb +1 -0
- data/lib/rigor/triage/catalogue.rb +1 -3
- data/lib/rigor/triage.rb +3 -5
- data/lib/rigor/type/accepts_result.rb +24 -6
- data/lib/rigor/type/combinator.rb +144 -5
- data/lib/rigor/type/data_class.rb +2 -2
- data/lib/rigor/type/data_instance.rb +4 -4
- data/lib/rigor/type/difference.rb +1 -0
- data/lib/rigor/type/float_range.rb +128 -0
- data/lib/rigor/type/hash_shape.rb +6 -6
- data/lib/rigor/type/integer_range.rb +13 -8
- data/lib/rigor/type/nominal.rb +8 -2
- data/lib/rigor/type/refined.rb +4 -3
- data/lib/rigor/type/struct_class.rb +3 -3
- data/lib/rigor/type/struct_instance.rb +4 -4
- data/lib/rigor/type.rb +1 -0
- data/lib/rigor/type_node/generic.rb +1 -1
- data/lib/rigor/type_node/range_literal.rb +25 -0
- data/lib/rigor/type_node/resolver_chain.rb +1 -1
- data/lib/rigor/type_node.rb +1 -0
- data/lib/rigor/version.rb +1 -1
- data/lib/rigor.rb +1 -0
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/analyzer.rb +0 -4
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_discoverer.rb +0 -1
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_index.rb +0 -2
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/effects.rb +1 -0
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +10 -5
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/analyzer.rb +0 -4
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_discoverer.rb +3 -5
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_index.rb +1 -4
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb +14 -4
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb +32 -30
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_discoverer.rb +0 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_index.rb +1 -3
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_scan.rb +96 -0
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/effects.rb +65 -8
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/erb_compiler.rb +270 -0
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/render_locals.rb +402 -0
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/view_assigns.rb +370 -0
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/view_units.rb +132 -0
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +264 -3
- data/plugins/rigor-actionpack/sig/action_controller.rbs +71 -0
- data/plugins/rigor-actionpack/sig/action_view.rbs +43 -0
- data/plugins/rigor-active-model-serializers/lib/rigor/plugin/active_model_serializers/serializer_discoverer.rb +220 -0
- data/plugins/rigor-active-model-serializers/lib/rigor/plugin/active_model_serializers/serializer_index.rb +56 -0
- data/plugins/rigor-active-model-serializers/lib/rigor/plugin/active_model_serializers.rb +263 -0
- data/plugins/rigor-active-model-serializers/lib/rigor-active-model-serializers.rb +7 -0
- data/plugins/rigor-active-model-serializers/sig/active_model_serializers.rbs +45 -0
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/analyzer.rb +0 -4
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/effects.rb +2 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_discoverer.rb +0 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_index.rb +0 -2
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/recurring_scan.rb +1 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +10 -5
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/analyzer.rb +35 -3
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/effects.rb +72 -12
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +383 -7
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_index.rb +14 -6
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_parser.rb +1 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/structure_sql_parser.rb +1 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +322 -41
- data/plugins/rigor-activerecord/sig/active_record/framework.rbs +123 -0
- data/plugins/rigor-activerecord/sig/active_record/relation.rbs +206 -31
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +26 -14
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext/effects.rb +9 -2
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb +9 -2
- data/plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs +290 -19
- data/plugins/rigor-devise/lib/rigor/plugin/devise.rb +1 -0
- data/plugins/rigor-dry-monads/lib/rigor/plugin/dry_monads.rb +3 -0
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema/schema_scanner.rb +9 -7
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema.rb +7 -3
- data/plugins/rigor-dry-struct/lib/rigor/plugin/dry_struct.rb +1 -0
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types/alias_scanner.rb +8 -6
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types.rb +11 -7
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation/contract_scanner.rb +13 -11
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation.rb +9 -4
- data/plugins/rigor-ethon/lib/rigor/plugin/ethon.rb +2 -0
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/analyzer.rb +0 -5
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_discoverer.rb +0 -1
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_index.rb +0 -1
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot.rb +8 -1
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi/types.rb +1 -1
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi.rb +36 -4
- data/plugins/rigor-ffi-rzmq/lib/rigor/plugin/ffi_rzmq.rb +1 -0
- data/plugins/rigor-grape/lib/rigor/plugin/grape.rb +141 -0
- data/plugins/rigor-grape/lib/rigor-grape.rb +6 -0
- data/plugins/rigor-grape/sig/grape.rbs +263 -0
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql/type_scanner.rb +8 -6
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql.rb +78 -5
- data/plugins/rigor-graphql/sig/graphql.rbs +485 -0
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami.rb +1 -0
- data/plugins/rigor-mangrove/lib/rigor/plugin/mangrove.rb +2 -1
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest/assertion_analyzer.rb +2 -3
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest.rb +1 -0
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/analyzer.rb +0 -5
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/authorization_scan.rb +2 -2
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_discoverer.rb +0 -1
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_index.rb +0 -1
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit.rb +12 -7
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/analyzer.rb +0 -12
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_index.rb +1 -3
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_loader.rb +0 -1
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n.rb +36 -37
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/acronyms.rb +5 -5
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/analyzer.rb +0 -10
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/devise_routes.rb +5 -3
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/doorkeeper_routes.rb +3 -2
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/grape_api_discoverer.rb +2 -2
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_discoverer.rb +2 -2
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_table.rb +9 -10
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/routes_parser.rb +2 -3
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +10 -17
- data/plugins/rigor-railties/lib/rigor/plugin/railties.rb +1 -0
- data/plugins/rigor-rbnacl/lib/rigor/plugin/rbnacl.rb +13 -1
- data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline/same_line_annotations.rb +149 -0
- data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb +324 -18
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/analyzer.rb +0 -3
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_scope_index.rb +0 -3
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_type_resolver.rb +1 -5
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +2 -3
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec.rb +1 -0
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails/have_http_status_analyzer.rb +0 -3
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails.rb +1 -0
- data/plugins/rigor-sassc/lib/rigor/plugin/sassc.rb +1 -0
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers/analyzer.rb +1 -9
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers.rb +1 -0
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/analyzer.rb +0 -4
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/effects.rb +1 -1
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/schedule_scan.rb +2 -1
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_discoverer.rb +0 -1
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_index.rb +0 -2
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb +10 -5
- data/plugins/rigor-sinatra/lib/rigor/plugin/sinatra.rb +1 -0
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/absurd_recognizer.rb +2 -5
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/assertion_recognizer.rb +1 -4
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog.rb +3 -9
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog_walker.rb +4 -4
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sig_parser.rb +1 -2
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sigil_detector.rb +3 -5
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/type_translator.rb +7 -5
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +51 -6
- data/plugins/rigor-sorbet/sig/sorbet.rbs +277 -0
- data/plugins/rigor-statesman/lib/rigor/plugin/statesman.rb +1 -0
- data/sig/rigor/analysis/baseline.rbs +69 -7
- data/sig/rigor/analysis/fact_store.rbs +1 -1
- data/sig/rigor/analysis/project_scan.rbs +74 -0
- data/sig/rigor/analysis/reachability/scan_cache.rbs +12 -0
- data/sig/rigor/cache.rbs +2 -3
- data/sig/rigor/effects/config_envelopes.rbs +100 -0
- data/sig/rigor/effects/effect_table.rbs +60 -0
- data/sig/rigor/effects/envelope.rbs +97 -0
- data/sig/rigor/effects/envelope_index.rbs +33 -0
- data/sig/rigor/effects/file_collection.rbs +81 -0
- data/sig/rigor/effects/label.rbs +26 -0
- data/sig/rigor/effects/label_set.rbs +46 -0
- data/sig/rigor/effects/method_key.rbs +24 -0
- data/sig/rigor/effects/origin.rbs +50 -0
- data/sig/rigor/effects/plugin_facts.rbs +141 -0
- data/sig/rigor/effects/registry.rbs +68 -0
- data/sig/rigor/effects/summary.rbs +50 -0
- data/sig/rigor/effects/taint_cause.rbs +12 -0
- data/sig/rigor/environment.rbs +17 -10
- data/sig/rigor/inference/optimistic_origin.rbs +10 -0
- data/sig/rigor/inference.rbs +9 -14
- data/sig/rigor/plugin/additional_initializer.rbs +36 -0
- data/sig/rigor/plugin/base.rbs +30 -7
- data/sig/rigor/plugin/effect_ancestry.rbs +27 -0
- data/sig/rigor/plugin/effect_attribution.rbs +66 -0
- data/sig/rigor/plugin/effect_edge.rbs +33 -0
- data/sig/rigor/plugin/effect_entry_points.rbs +25 -0
- data/sig/rigor/plugin/io_boundary.rbs +4 -0
- data/sig/rigor/plugin/loader.rbs +3 -3
- data/sig/rigor/plugin/manifest.rbs +51 -11
- data/sig/rigor/plugin/protocol_contract.rbs +68 -0
- data/sig/rigor/plugin/registry.rbs +62 -1
- data/sig/rigor/plugin.rbs +1 -1
- data/sig/rigor/rbs_extended.rbs +1 -1
- data/sig/rigor/reflection.rbs +9 -6
- data/sig/rigor/scope.rbs +148 -12
- data/sig/rigor/sig_gen/skip_reason_catalog.rbs +21 -0
- data/sig/rigor/source.rbs +4 -4
- data/sig/rigor/testing.rbs +10 -4
- data/sig/rigor/type.rbs +33 -1
- data/sig/rigor.rbs +39 -20
- data/skills/rigor-ask/SKILL.md +16 -11
- data/skills/rigor-baseline-reduce/SKILL.md +4 -6
- data/skills/rigor-ci-setup/SKILL.md +17 -21
- data/skills/rigor-doctor/SKILL.md +24 -22
- data/skills/rigor-doctor/references/01-checks.md +97 -33
- data/skills/rigor-editor-setup/SKILL.md +6 -4
- data/skills/rigor-mcp-setup/SKILL.md +5 -4
- data/skills/rigor-monkeypatch-resolve/SKILL.md +5 -3
- data/skills/rigor-next-steps/SKILL.md +4 -2
- data/skills/rigor-plugin-author/SKILL.md +19 -23
- data/skills/rigor-plugin-author/references/01-plan-and-scaffold.md +9 -8
- data/skills/rigor-plugin-author/references/02-walker-and-types.md +25 -27
- data/skills/rigor-plugin-author/references/03-test-and-ship.md +6 -8
- data/skills/rigor-plugin-review/SKILL.md +6 -4
- data/skills/rigor-plugin-review/references/01-best-practices-checklist.md +2 -1
- data/skills/rigor-plugin-tune/SKILL.md +4 -2
- data/skills/rigor-project-init/SKILL.md +15 -10
- data/skills/rigor-project-init/references/01-detect.md +13 -9
- data/skills/rigor-project-init/references/02-configure.md +43 -14
- data/skills/rigor-project-init/references/03-baseline-and-bugs.md +14 -14
- data/skills/rigor-project-init/references/04-sig-uplift.md +27 -14
- data/skills/rigor-project-init/references/06-agent-contract.md +67 -0
- data/skills/rigor-protection-uplift/SKILL.md +4 -6
- data/skills/rigor-rbs-setup/SKILL.md +4 -2
- data/skills/rigor-type-oracle/SKILL.md +226 -0
- data/skills/rigor-type-oracle/references/01-oracle-commands.md +265 -0
- data/skills/rigor-type-oracle/references/02-agents-md-fragment.md +52 -0
- data/skills/rigor-type-oracle/references/03-gap-protocol.md +125 -0
- data/skills/rigor-unused-adjudicate/SKILL.md +12 -7
- data/skills/rigor-upgrade/SKILL.md +13 -8
- metadata +133 -3
- data/lib/rigor/cli/probe_environment.rb +0 -85
- data/sig/rigor/inference/builtins/numeric_catalog.rbs +0 -3
|
@@ -37,8 +37,7 @@ module Rigor
|
|
|
37
37
|
# run, so the same Prism node object is seen in both the `dynamic_return` rule and
|
|
38
38
|
# `diagnostics_for_file`.
|
|
39
39
|
module AbsurdRecognizer
|
|
40
|
-
# @
|
|
41
|
-
# @return [Boolean] true when `call_node` is `T.absurd(x)`.
|
|
40
|
+
# @return true when `call_node` is `T.absurd(x)`.
|
|
42
41
|
def self.absurd_call?(call_node)
|
|
43
42
|
return false unless call_node.is_a?(Prism::CallNode)
|
|
44
43
|
return false unless call_node.name == :absurd
|
|
@@ -50,9 +49,7 @@ module Rigor
|
|
|
50
49
|
arguments&.size == 1
|
|
51
50
|
end
|
|
52
51
|
|
|
53
|
-
# @
|
|
54
|
-
# @param scope [Rigor::Scope, nil]
|
|
55
|
-
# @return [Boolean] true when the discriminant has been narrowed to `bot` (the branch is
|
|
52
|
+
# @return true when the discriminant has been narrowed to `bot` (the branch is
|
|
56
53
|
# unreachable, so `T.absurd` is correct). The caller suppresses the `absurd-reachable` diagnostic
|
|
57
54
|
# in this case.
|
|
58
55
|
def self.exhaustive?(call_node, scope)
|
|
@@ -53,10 +53,7 @@ module Rigor
|
|
|
53
53
|
|
|
54
54
|
module_function
|
|
55
55
|
|
|
56
|
-
# @param
|
|
57
|
-
# @param scope [Rigor::Scope]
|
|
58
|
-
# @param plugin_id [String] used for the contribution's `provenance.source_family`.
|
|
59
|
-
# @return [Rigor::FlowContribution, nil]
|
|
56
|
+
# @param plugin_id — used for the contribution's `provenance.source_family`.
|
|
60
57
|
def recognize(call_node:, scope:, plugin_id:)
|
|
61
58
|
return nil unless TypeTranslator.sorbet_t_namespaced?(call_node.receiver)
|
|
62
59
|
return nil unless SORBET_ASSERTIONS.include?(call_node.name)
|
|
@@ -23,7 +23,6 @@ module Rigor
|
|
|
23
23
|
@frozen_after_build = false
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
# @param signature [MethodSignature]
|
|
27
26
|
def record(signature)
|
|
28
27
|
raise "Catalog already finalised" if @frozen_after_build
|
|
29
28
|
|
|
@@ -31,10 +30,9 @@ module Rigor
|
|
|
31
30
|
@entries[key] = signature
|
|
32
31
|
end
|
|
33
32
|
|
|
34
|
-
# @param class_name
|
|
33
|
+
# @param class_name — the class / module that carries the mixin (`class Post; include Foo;
|
|
35
34
|
# end` records under `"Post"`).
|
|
36
|
-
# @param
|
|
37
|
-
# @param module_name [String] the textual name of the mixed-in module as it appeared at the
|
|
35
|
+
# @param module_name — the textual name of the mixed-in module as it appeared at the
|
|
38
36
|
# include / extend site (`"Foo"`, `"Foo::Bar"`, `"::Foo"`).
|
|
39
37
|
def record_mixin(class_name:, kind:, module_name:)
|
|
40
38
|
raise "Catalog already finalised" if @frozen_after_build
|
|
@@ -55,13 +53,11 @@ module Rigor
|
|
|
55
53
|
freeze
|
|
56
54
|
end
|
|
57
55
|
|
|
58
|
-
# @return [MethodSignature, nil]
|
|
59
56
|
def lookup(class_name:, method_name:, kind:)
|
|
60
57
|
@entries[key_for(class_name, method_name, kind)]
|
|
61
58
|
end
|
|
62
59
|
|
|
63
|
-
# @
|
|
64
|
-
# @return [Hash{Symbol => Array<String>}] frozen mapping `{ include: [...], extend: [...] }`.
|
|
60
|
+
# @return frozen mapping `{ include: [...], extend: [...] }`.
|
|
65
61
|
# Returns {EMPTY_MIXINS} when no mixins were recorded.
|
|
66
62
|
def mixins_for(class_name)
|
|
67
63
|
@mixins[class_name] || EMPTY_MIXINS
|
|
@@ -77,8 +73,6 @@ module Rigor
|
|
|
77
73
|
# static assertion vocabulary), and the precise `(class, kind)` lookup stays in the rule block.
|
|
78
74
|
# Computed fresh per call — the plugin memoises the resolved set, and `freeze!` freezes the
|
|
79
75
|
# catalog itself so a lazy memo ivar here would raise.
|
|
80
|
-
#
|
|
81
|
-
# @return [Array<Symbol>]
|
|
82
76
|
def method_names
|
|
83
77
|
@entries.keys.map { |key| key[1] }.uniq
|
|
84
78
|
end
|
|
@@ -26,10 +26,10 @@ module Rigor
|
|
|
26
26
|
|
|
27
27
|
module_function
|
|
28
28
|
|
|
29
|
-
# @param root
|
|
30
|
-
# @param catalog
|
|
31
|
-
# @param path
|
|
32
|
-
# @return
|
|
29
|
+
# @param root — the file's program node.
|
|
30
|
+
# @param catalog — mutable; signatures are recorded into it.
|
|
31
|
+
# @param path — file path used for diagnostic provenance.
|
|
32
|
+
# @return errors observed during the walk; empty when the file is sig-clean.
|
|
33
33
|
def walk(root:, catalog:, path:)
|
|
34
34
|
state = State.new(catalog: catalog, path: path)
|
|
35
35
|
walk_node(root, state, lexical_path: [], in_singleton_class: false)
|
|
@@ -44,8 +44,7 @@ module Rigor
|
|
|
44
44
|
|
|
45
45
|
module_function
|
|
46
46
|
|
|
47
|
-
# @param sig_call
|
|
48
|
-
# @return [ParseResult, ParseError]
|
|
47
|
+
# @param sig_call — the `sig { ... }` / `sig do ... end` call.
|
|
49
48
|
def parse(sig_call)
|
|
50
49
|
return ParseError.new(reason: :no_block, node: sig_call) if sig_call.block.nil?
|
|
51
50
|
|
|
@@ -30,8 +30,7 @@ module Rigor
|
|
|
30
30
|
|
|
31
31
|
module_function
|
|
32
32
|
|
|
33
|
-
# @
|
|
34
|
-
# @return [Symbol] one of {VALID_LEVELS}; defaults to {DEFAULT_LEVEL} for sigil-less or
|
|
33
|
+
# @return one of {VALID_LEVELS}; defaults to {DEFAULT_LEVEL} for sigil-less or
|
|
35
34
|
# malformed-sigil files.
|
|
36
35
|
def detect(contents)
|
|
37
36
|
return DEFAULT_LEVEL if contents.nil? || contents.empty?
|
|
@@ -52,14 +51,13 @@ module Rigor
|
|
|
52
51
|
DEFAULT_LEVEL
|
|
53
52
|
end
|
|
54
53
|
|
|
55
|
-
# @
|
|
56
|
-
# @return [Boolean] true when `# typed: ignore`. The harvest pipeline calls this to short-circuit
|
|
54
|
+
# @return true when `# typed: ignore`. The harvest pipeline calls this to short-circuit
|
|
57
55
|
# walking the file's AST.
|
|
58
56
|
def ignored?(level)
|
|
59
57
|
level == :ignore
|
|
60
58
|
end
|
|
61
59
|
|
|
62
|
-
# @return
|
|
60
|
+
# @return true when `level` is at or above the `# typed: true` mark. Used by the
|
|
63
61
|
# `enforce_sigil` config gate (default `true`): with the gate on, only files marked `:true` /
|
|
64
62
|
# `:strict` / `:strong` contribute their sigs to the catalog. The `:false` (and sigil-less)
|
|
65
63
|
# levels still get walked (so RBI files outside the project can be loaded regardless), but their
|
|
@@ -52,8 +52,7 @@ module Rigor
|
|
|
52
52
|
|
|
53
53
|
module_function
|
|
54
54
|
|
|
55
|
-
# @
|
|
56
|
-
# @return [Rigor::Type] never `nil`; unrecognised forms degrade to `Type::Combinator.untyped`.
|
|
55
|
+
# @return never `nil`; unrecognised forms degrade to `Type::Combinator.untyped`.
|
|
57
56
|
def translate(node)
|
|
58
57
|
return Rigor::Type::Combinator.untyped if node.nil?
|
|
59
58
|
|
|
@@ -67,7 +66,6 @@ module Rigor
|
|
|
67
66
|
end
|
|
68
67
|
end
|
|
69
68
|
|
|
70
|
-
# @param node [Prism::ConstantReadNode]
|
|
71
69
|
def translate_constant_read(node)
|
|
72
70
|
name = node.name.to_s
|
|
73
71
|
return Rigor::Type::Combinator.untyped if name.empty?
|
|
@@ -75,7 +73,6 @@ module Rigor
|
|
|
75
73
|
Rigor::Type::Combinator.nominal_of(name)
|
|
76
74
|
end
|
|
77
75
|
|
|
78
|
-
# @param node [Prism::ConstantPathNode]
|
|
79
76
|
def translate_constant_path(node)
|
|
80
77
|
name = constant_path_name(node)
|
|
81
78
|
return degraded if name.nil?
|
|
@@ -233,7 +230,12 @@ module Rigor
|
|
|
233
230
|
|
|
234
231
|
pairs << [element.key.unescaped.to_sym, translate(element.value)]
|
|
235
232
|
end
|
|
236
|
-
|
|
233
|
+
# `.to_h`: `hash_shape_of` validates its argument is a Hash and raises `ArgumentError` on the
|
|
234
|
+
# array-of-pairs form, so `sig { returns({name: String}) }` degraded to `Dynamic[top]` through
|
|
235
|
+
# the plugin's rescue instead of producing a shape. Found by #673, when relaxing
|
|
236
|
+
# `call.argument-type-mismatch` to check the positional arguments of keyword-bearing
|
|
237
|
+
# signatures made the call site visible.
|
|
238
|
+
Rigor::Type::Combinator.hash_shape_of(pairs.to_h)
|
|
237
239
|
end
|
|
238
240
|
|
|
239
241
|
# Renders a constant-path node (`Foo::Bar`, `::Foo::Bar`) as a `::`-joined String. Mirrors the
|
|
@@ -29,6 +29,14 @@ module Rigor
|
|
|
29
29
|
# The {TypeTranslator} table documents coverage. Most of Sorbet's vocabulary translates; remaining
|
|
30
30
|
# gaps (`T.proc`, `T::Struct` subclasses, `T.attached_class`, etc.) degrade silently to `Dynamic[top]`.
|
|
31
31
|
#
|
|
32
|
+
# Issue #1097 — the plugin also ships `sig/sorbet.rbs`, a bundled declaration of the annotation DSL
|
|
33
|
+
# surface itself: `T`'s type-expression functions, the `T::X[...]` constructors, `T::Sig`'s `sig`
|
|
34
|
+
# verb (reached via the manifest `rbs_complete_extends:` bridge over `extend T::Sig`), the
|
|
35
|
+
# `DeclBuilder` the sig block `instance_eval`s on (via `block_as_methods:`), and the
|
|
36
|
+
# `T::Struct` / `T::Enum` family (via `rbs_complete_ancestors:`). The value-side assertions
|
|
37
|
+
# (`T.let`/`T.cast`/`T.must`/…) stay recogniser-owned — RBS cannot express "return the asserted
|
|
38
|
+
# type" — and `T`'s declared surface is intentionally partial behind `open_receivers:`.
|
|
39
|
+
#
|
|
32
40
|
# Architecture: per-run `Catalog` is built lazily on first access by walking every configured `paths:`
|
|
33
41
|
# entry's `.rb` files plus every `rbi_paths:` entry's `.rbi` files (slice 4) via the plugin's
|
|
34
42
|
# `IoBoundary`. The catalog is frozen after the first build and consulted by the `dynamic_return` rule
|
|
@@ -57,6 +65,7 @@ module Rigor
|
|
|
57
65
|
class Sorbet < Rigor::Plugin::Base
|
|
58
66
|
manifest(
|
|
59
67
|
id: "sorbet",
|
|
68
|
+
target_gems: ["sorbet-runtime"],
|
|
60
69
|
version: "0.1.0",
|
|
61
70
|
description: "Ingests Sorbet `sig` blocks as method-signature contributions.",
|
|
62
71
|
config_schema: {
|
|
@@ -69,7 +78,43 @@ module Rigor
|
|
|
69
78
|
# effect of recursing into the parent root.
|
|
70
79
|
"rbi_paths" => { kind: :array, default: ["sorbet/rbi"] },
|
|
71
80
|
"enforce_sigil" => { kind: :boolean, default: true }
|
|
72
|
-
}
|
|
81
|
+
},
|
|
82
|
+
# #1097 — bundled sorbet-runtime DSL surface (`sig/sorbet.rbs`). `sig` itself reaches the
|
|
83
|
+
# class object through `extend T::Sig` (or the `< T::ImmutableStruct` / `< T::Enum`
|
|
84
|
+
# family, which carry the edge themselves), which is
|
|
85
|
+
# why `rbs_complete_extends:` — the extend-edge allow-list — carries `T::Sig` /
|
|
86
|
+
# `T::Helpers` / `T::Generic`, and `rbs_complete_ancestors:` carries the Struct/Enum family
|
|
87
|
+
# for the subclass bridge.
|
|
88
|
+
signature_paths: ["sig"],
|
|
89
|
+
rbs_complete_extends: %w[T::Sig T::Helpers T::Generic],
|
|
90
|
+
rbs_complete_ancestors: %w[T::Struct T::InexactStruct T::ImmutableStruct T::Enum],
|
|
91
|
+
# `sig { ... }` bodies are `instance_eval`'d on a `DeclBuilder`
|
|
92
|
+
# (`T::Private::Methods._run_builder`), so `params` / `returns` / `void` resolve on the
|
|
93
|
+
# builder, not the enclosing class. `T::Sig::WithoutRuntime.sig` is the direct-call twin —
|
|
94
|
+
# a singleton method on the module, matching by name equality.
|
|
95
|
+
block_as_methods: [
|
|
96
|
+
Rigor::Plugin::Macro::BlockAsMethod.new(
|
|
97
|
+
receiver_constraint: "T::Sig",
|
|
98
|
+
method_names: %i[sig],
|
|
99
|
+
self_type: "T::Private::Methods::DeclBuilder"
|
|
100
|
+
),
|
|
101
|
+
Rigor::Plugin::Macro::BlockAsMethod.new(
|
|
102
|
+
receiver_constraint: "T::Sig::WithoutRuntime",
|
|
103
|
+
method_names: %i[sig],
|
|
104
|
+
self_type: "T::Private::Methods::DeclBuilder"
|
|
105
|
+
)
|
|
106
|
+
],
|
|
107
|
+
# The declared surface is deliberately partial — `T` is an open module whose runtime
|
|
108
|
+
# surface is much larger than the DSL (version-dependent internals, `T::Private::*`,
|
|
109
|
+
# `T::Configuration`, `T::Utils`). Open receivers keep an unmodelled `T.something` opaque
|
|
110
|
+
# rather than a `call.undefined-method` false positive. `DeclBuilder` is NOT open —
|
|
111
|
+
# `sig { typo }` is a real bug and stays a diagnostic.
|
|
112
|
+
open_receivers: %w[T T::Sig T::Sig::WithoutRuntime T::Helpers T::Generic
|
|
113
|
+
T::Utils T::Configuration T::Private T::Private::Methods
|
|
114
|
+
T::Props T::Props::ClassMethods T::Props::CustomType
|
|
115
|
+
T::Types T::Types::Base T::Array T::Hash T::Set
|
|
116
|
+
T::Enumerable T::Enumerator T::Range T::Class
|
|
117
|
+
T::InexactStruct T::Struct T::ImmutableStruct T::Enum]
|
|
73
118
|
)
|
|
74
119
|
|
|
75
120
|
def init(services)
|
|
@@ -440,13 +485,13 @@ module Rigor
|
|
|
440
485
|
# Frozen empty bundle used when the `:catalog` producer failed (e.g. a project I/O error) so downstream
|
|
441
486
|
# reads see a well-formed shape rather than nil.
|
|
442
487
|
EMPTY_CATALOG_BUNDLE = { catalog: Catalog.new.freeze!, sigil_by_path: {}, parse_errors_by_path: {} }.freeze
|
|
488
|
+
Ractor.make_shareable(EMPTY_CATALOG_BUNDLE)
|
|
443
489
|
private_constant :EMPTY_CATALOG_BUNDLE
|
|
444
490
|
|
|
445
|
-
# @param root
|
|
446
|
-
# @param
|
|
447
|
-
# @param
|
|
448
|
-
# @param
|
|
449
|
-
# @param extensions [Array<String>] file extensions to accept (e.g. `[".rb"]` for project source,
|
|
491
|
+
# @param root — directory or single file.
|
|
492
|
+
# @param sigil_by_path — accumulator: harvested file → detected sigil level.
|
|
493
|
+
# @param parse_errors_by_path — accumulator: file → `{kind:,line:,column:}` tuples.
|
|
494
|
+
# @param extensions — file extensions to accept (e.g. `[".rb"]` for project source,
|
|
450
495
|
# `[".rbi"]` for Sorbet RBI tree).
|
|
451
496
|
def harvest_path(root, catalog, sigil_by_path, parse_errors_by_path, extensions)
|
|
452
497
|
absolute = canonicalize(root)
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
# Bundled RBS for the sorbet-runtime annotation DSL (issue #1097).
|
|
2
|
+
#
|
|
3
|
+
# sorbet-runtime ships RBI, not RBS, so none of the annotation surface (`T`, `T::Sig`, the
|
|
4
|
+
# `DeclBuilder` behind `sig { ... }`, the `T::Array[...]` constructors, the `T::Helpers` /
|
|
5
|
+
# `T::Generic` class macros) resolves for the analyzer. This file declares that surface so the
|
|
6
|
+
# DSL *expressions themselves* type; the plugin's `AssertionRecognizer` continues to own the
|
|
7
|
+
# value-sensitive calls (`T.let` / `T.cast` / `T.must` / `T.bind` / `T.assert_type!` /
|
|
8
|
+
# `T.reveal_type` / `T.unsafe`) ahead of this RBS — the signatures here deliberately agree with
|
|
9
|
+
# it (`T.unsafe` stays `untyped`, `T.bind` returns `nil`) for the cases the recognizer declines.
|
|
10
|
+
#
|
|
11
|
+
# Provenance (docs/agents/type-authoring.md): `rigor sig-gen` cannot produce this file — the DSL
|
|
12
|
+
# methods are installed by `Module#extend` hooks and `instance_eval` in sorbet-runtime's source
|
|
13
|
+
# (sorbet-runtime 0.5.11766, `lib/types/{sig,_types,generic,helpers,struct,enum}.rb` and
|
|
14
|
+
# `lib/types/private/methods/decl_builder.rb`), so every entry was hand-derived by reading that
|
|
15
|
+
# source. Members that do not exist at that version's runtime location are deliberately absent.
|
|
16
|
+
#
|
|
17
|
+
# Two Rigor-side mechanisms complete the picture (manifest fields):
|
|
18
|
+
#
|
|
19
|
+
# - `rbs_complete_extends:` — `extend T::Sig` in a class/module body is what puts `sig` on the
|
|
20
|
+
# class object's singleton; the dispatch bridge resolves those calls through the module's
|
|
21
|
+
# instance surface declared here.
|
|
22
|
+
# - `block_as_methods:` — `sig`'s block is `instance_eval`'d on a `DeclBuilder`
|
|
23
|
+
# (`T::Private::Methods.declare_sig` → `DeclBuilder#instance_eval`), so `sig` bodies bind
|
|
24
|
+
# `self` to `T::Private::Methods::DeclBuilder`, NOT to the enclosing class.
|
|
25
|
+
|
|
26
|
+
module T
|
|
27
|
+
# `T::Boolean` is a runtime constant (`T.any(TrueClass, FalseClass)` → a `T::Types::Union`
|
|
28
|
+
# instance), not a module — it appears in `params`/`returns` argument position as a const read.
|
|
29
|
+
Boolean: ::T::Types::Union
|
|
30
|
+
|
|
31
|
+
# The type-ASSERTION functions (`T.let`, `T.cast`, `T.assert_type!`, `T.bind`, `T.must`,
|
|
32
|
+
# `T.must_because`, `T.reveal_type`, `T.absurd`, `T.unsafe`) are deliberately NOT declared here.
|
|
33
|
+
# Their static return is the *asserted* type (the second argument, translated) or the nil-stripped
|
|
34
|
+
# inner type — semantics RBS cannot express — so the plugin's `AssertionRecognizer` /
|
|
35
|
+
# `AbsurdRecognizer` owns them ahead of dispatch, and a declined call degrades through `T`'s
|
|
36
|
+
# `open_receivers:` entry to opaque rather than a wrong `X` reading.
|
|
37
|
+
|
|
38
|
+
# Type-expression constructors — used in `params`/`returns` argument position.
|
|
39
|
+
def self.nilable: (untyped type) -> ::T::Types::Base
|
|
40
|
+
def self.untyped: () -> ::T::Types::Base
|
|
41
|
+
def self.noreturn: () -> ::T::Types::Base
|
|
42
|
+
def self.anything: () -> ::T::Types::Base
|
|
43
|
+
def self.all: (untyped type_a, untyped type_b, *untyped types) -> ::T::Types::Base
|
|
44
|
+
def self.any: (untyped type_a, untyped type_b, *untyped types) -> ::T::Types::Base
|
|
45
|
+
def self.class_of: (untyped arg) -> ::T::Types::Base
|
|
46
|
+
def self.self_type: () -> ::T::Types::Base
|
|
47
|
+
def self.attached_class: () -> ::T::Types::Base
|
|
48
|
+
def self.type_parameter: (::Symbol name) -> ::T::Types::TypeParameter
|
|
49
|
+
# `type=nil, &blk` — the positional form is a kept-for-migration legacy path (`_types.rb`);
|
|
50
|
+
# the block form wraps in `T::Private::Types::TypeAlias`.
|
|
51
|
+
def self.type_alias: (?untyped type) ?{ () -> untyped } -> ::T::Types::Base
|
|
52
|
+
|
|
53
|
+
# `T.proc` returns a DeclBuilder in `Modes.proc` (`T::Private::Methods.start_proc`), so the
|
|
54
|
+
# `T.proc.params(x: Integer).returns(String)` chain resolves through the same builder surface.
|
|
55
|
+
def self.proc: () -> ::T::Private::Methods::DeclBuilder
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# `T::Sig` is a mixin a class EXTENDS (`extend T::Sig`) to gain the class-level `sig` verb —
|
|
59
|
+
# sorbet-runtime does not patch `Module`. `sig` itself returns nil at runtime
|
|
60
|
+
# (`declare_sig` stores the DeclarationBlock and returns nil).
|
|
61
|
+
module T::Sig
|
|
62
|
+
def sig: (?untyped arg0) ?{ () -> untyped } -> nil
|
|
63
|
+
|
|
64
|
+
# `T::Sig::WithoutRuntime.sig { ... }` is a no-op shim for contexts where the runtime wrapper
|
|
65
|
+
# cannot be installed; it is called ON the module, so `sig` here is a module-singleton method.
|
|
66
|
+
# `extend T::Sig::WithoutRuntime` installs nothing at runtime, so no instance `sig` is declared.
|
|
67
|
+
module WithoutRuntime
|
|
68
|
+
def self.sig: (?untyped arg0) ?{ () -> untyped } -> nil
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# The builder `sig`'s block is `instance_eval`'d on (`DeclBuilder#instance_eval(&blk)` via
|
|
73
|
+
# `T::Private::Methods._run_builder`). Every DSL method returns `self` so the
|
|
74
|
+
# `params(...).returns(...).checked(:always)` chain keeps typing.
|
|
75
|
+
class T::Private::Methods::DeclBuilder
|
|
76
|
+
def params: (*untyped unused_positional_params, **untyped params) -> self
|
|
77
|
+
def returns: (untyped type) -> self
|
|
78
|
+
def void: () -> self
|
|
79
|
+
def bind: (untyped type) -> self
|
|
80
|
+
def checked: (untyped level) -> self
|
|
81
|
+
def on_failure: (*untyped args) -> self
|
|
82
|
+
def abstract: () -> self
|
|
83
|
+
def final: () -> self
|
|
84
|
+
def override: (?allow_incompatible: bool | Symbol) -> self
|
|
85
|
+
def overridable: () -> self
|
|
86
|
+
def type_parameters: (*untyped names) -> self
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# The `T::X[...]` type constructors are modules with a singleton `[]` (`_types.rb`), returning the
|
|
90
|
+
# corresponding `T::Types::TypedX` instance. The carriers below exist so the constructor's return
|
|
91
|
+
# reads as a real nominal rather than `Dynamic[top]`.
|
|
92
|
+
module T::Array
|
|
93
|
+
def self.[]: (untyped type) -> ::T::Types::TypedArray
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
module T::Hash
|
|
97
|
+
def self.[]: (untyped keys, untyped values) -> ::T::Types::TypedHash
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
module T::Set
|
|
101
|
+
def self.[]: (untyped type) -> ::T::Types::TypedSet
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
module T::Enumerable
|
|
105
|
+
def self.[]: (untyped type) -> ::T::Types::TypedEnumerable
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
module T::Enumerator
|
|
109
|
+
def self.[]: (untyped type) -> ::T::Types::TypedEnumerator
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
module T::Range
|
|
113
|
+
def self.[]: (untyped type) -> ::T::Types::TypedRange
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
module T::Class
|
|
117
|
+
def self.[]: (untyped type) -> ::T::Types::TypedClass
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Carrier classes for the `T::X[...]` constructors and the `T.*` type-expression functions. The
|
|
121
|
+
# internal `T::Types::*` class names are the runtime classes (`types/types/*.rb`).
|
|
122
|
+
module T::Types
|
|
123
|
+
class Base
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
class TypedArray < Base
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
class TypedHash < Base
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
class TypedSet < Base
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
class TypedEnumerable < Base
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
class TypedEnumerator < Base
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
class TypedRange < Base
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
class TypedClass < Base
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
class Union < Base
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
class Intersection < Base
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
class TypeParameter < Base
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
class TypeMember < Base
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
class TypeTemplate < Base
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
class Proc < Base
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# `extend T::Helpers` installs the class/module declaration macros (`abstract!`, `interface!`,
|
|
167
|
+
# `final!`, `sealed!`, `requires_ancestor`, `mixes_in_class_methods`). All return void-ish values
|
|
168
|
+
# from `T::Private::{Abstract,Final,Sealed}` bookkeeping (`helpers.rb`).
|
|
169
|
+
module T::Helpers
|
|
170
|
+
def abstract!: () -> void
|
|
171
|
+
def interface!: () -> void
|
|
172
|
+
def final!: () -> void
|
|
173
|
+
def sealed!: () -> void
|
|
174
|
+
def mixes_in_class_methods: (::Module mod, *::Module mods) -> void
|
|
175
|
+
def requires_ancestor: () { () -> untyped } -> void
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# `extend T::Generic` installs the type-member macros — `Elem = type_member` is the common shape
|
|
179
|
+
# (`generic.rb`). `[]` is the generic-application stub (`def [](*types); self; end`).
|
|
180
|
+
module T::Generic
|
|
181
|
+
# `generic.rb` — `extend T::Generic` alone also installs the helper macros: the module
|
|
182
|
+
# `include`s `T::Helpers` (and `Kernel`), so its instance surface carries `abstract!` et al.
|
|
183
|
+
include T::Helpers
|
|
184
|
+
|
|
185
|
+
def []: (*untyped types) -> self
|
|
186
|
+
def type_member: (?untyped variance) ?{ () -> untyped } -> ::T::Types::TypeMember
|
|
187
|
+
def type_template: (?untyped variance) ?{ () -> untyped } -> ::T::Types::TypeTemplate
|
|
188
|
+
def has_attached_class!: (?untyped variance) ?{ () -> untyped } -> void
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# `T::Props` is the property mixin; its `included` hook `extend`s the includer with
|
|
192
|
+
# `ClassMethods` (`mixes_in_class_methods`), which is where `prop` / `const` live. The hook itself
|
|
193
|
+
# is not modelled — `include T::Props` alone does not put `prop` on the class in this
|
|
194
|
+
# declaration either — but the `T::Struct` family below declares the same `extend` edges directly,
|
|
195
|
+
# matching the runtime outcome for `< T::Struct` subclasses.
|
|
196
|
+
module T::Props
|
|
197
|
+
module ClassMethods
|
|
198
|
+
def prop: (::Symbol name, untyped cls, **untyped rules) -> void
|
|
199
|
+
def const: (::Symbol name, untyped cls_or_args, **untyped args) -> void
|
|
200
|
+
def props: () -> ::Hash[untyped, untyped]
|
|
201
|
+
def plugins: () -> ::Array[untyped]
|
|
202
|
+
def decorator: () -> ::T::Props::Decorator
|
|
203
|
+
def decorator_class: () -> ::Class
|
|
204
|
+
def validate_prop_value: (untyped prop, untyped val) -> void
|
|
205
|
+
def plugin: (untyped mod) -> void
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
class Decorator
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
module CustomType
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
module Serializable
|
|
215
|
+
# `serializable.rb` — lifted onto includers via `mixes_in_class_methods`.
|
|
216
|
+
module ClassMethods
|
|
217
|
+
def prop_by_serialized_forms: () -> ::Hash[untyped, untyped]
|
|
218
|
+
def from_hash: (untyped hash, ?bool strict) -> untyped
|
|
219
|
+
def from_hash!: (untyped hash) -> untyped
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
module Plugin
|
|
224
|
+
# `plugin.rb` — `mixes_in_class_methods(ClassMethods)`; `included` re-registers the plugin
|
|
225
|
+
# (`child.plugin(self)`), which is what extends `plugin::ClassMethods` onto the target.
|
|
226
|
+
module ClassMethods
|
|
227
|
+
def included: (untyped child) -> void
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# The `T::Struct` family. `struct.rb` has `T::InexactStruct` `include T::Props` (+Serializable,
|
|
233
|
+
# +Constructor); the `mixes_in_class_methods` hooks extend `T::Props::ClassMethods` (then the
|
|
234
|
+
# registered `T::Props::Plugin::ClassMethods`) and `T::Props::Serializable::ClassMethods` onto the
|
|
235
|
+
# class — verified against the runtime singleton ancestry. Neither `T::Sig` nor `T::Helpers` is
|
|
236
|
+
# extended here: `sig` inside a `class Doc < T::Struct` body raises at runtime unless the subclass
|
|
237
|
+
# adds `extend T::Sig` itself (dependabot's `TokenBucket` does exactly that). Only
|
|
238
|
+
# `T::ImmutableStruct` extends `T::Sig` (`struct.rb` — it annotates its own `initialize`). The
|
|
239
|
+
# edges are declared directly so subclasses resolve `prop` / `const` / `from_hash` through the
|
|
240
|
+
# `rbs_complete_ancestors` superclass bridge.
|
|
241
|
+
class T::InexactStruct
|
|
242
|
+
extend T::Props::ClassMethods
|
|
243
|
+
extend T::Props::Plugin::ClassMethods
|
|
244
|
+
extend T::Props::Serializable::ClassMethods
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
class T::Struct < T::InexactStruct
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
class T::ImmutableStruct < T::InexactStruct
|
|
251
|
+
extend T::Sig
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
# `T::Enum` — `enum.rb` `extend`s `T::Sig` and `T::Props::CustomType`; `enums` `yield`s its block
|
|
255
|
+
# so `X = new` inside keeps the subclass's class-object self.
|
|
256
|
+
class T::Enum
|
|
257
|
+
extend T::Sig
|
|
258
|
+
extend T::Props::CustomType
|
|
259
|
+
|
|
260
|
+
def self.enums: () { () -> untyped } -> void
|
|
261
|
+
def serialize: () -> ::String
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
# Namespace-only declarations so bare const reads (`T::Utils`, `T::Configuration`,
|
|
265
|
+
# `T::Private::Methods`) type as `Singleton[...]` instead of `Dynamic[top]`. Their singleton
|
|
266
|
+
# surface is intentionally NOT modelled — they are covered by `open_receivers:` so calls on them
|
|
267
|
+
# degrade to opaque rather than firing `call.undefined-method` on an unmodelled private API.
|
|
268
|
+
module T::Utils
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
module T::Configuration
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
module T::Private
|
|
275
|
+
module Methods
|
|
276
|
+
end
|
|
277
|
+
end
|
|
@@ -6,26 +6,88 @@ module Rigor
|
|
|
6
6
|
class LoadError < ::StandardError
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
+
# Tuple-shaped bucket key so rule-ID rows and message-pattern rows coexist: `message_regex` is
|
|
10
|
+
# `nil` for rule-ID rows and a `Regexp` for message-pattern rows; `rule` and `file` are always
|
|
11
|
+
# present (parse_row raises without them; the generator's group key carries both). `count`
|
|
12
|
+
# intentionally shadows `Struct#count` — PHPStan-compatible field name.
|
|
13
|
+
class Bucket < ::Struct[untyped]
|
|
14
|
+
# sig-gen gap: #1183 — Struct member types are not inferred from construction sites; every
|
|
15
|
+
# member row in this class (and the keyword ctor below) is hand-written.
|
|
16
|
+
def file: () -> String
|
|
17
|
+
# sig-gen gap: #1183 — as above.
|
|
18
|
+
def rule: () -> String
|
|
19
|
+
# sig-gen gap: #1183 — as above.
|
|
20
|
+
def message_regex: () -> Regexp?
|
|
21
|
+
# sig-gen gap: #1183 — as above.
|
|
22
|
+
def count: () -> Integer
|
|
23
|
+
# sig-gen gap: #1183 — as above.
|
|
24
|
+
def file=: (String) -> String
|
|
25
|
+
# sig-gen gap: #1183 — as above.
|
|
26
|
+
def rule=: (String) -> String
|
|
27
|
+
# sig-gen gap: #1183 — as above.
|
|
28
|
+
def message_regex=: (Regexp?) -> Regexp?
|
|
29
|
+
# sig-gen gap: #1183 — as above.
|
|
30
|
+
def count=: (Integer) -> Integer
|
|
31
|
+
# sig-gen gap: #1183 — as above.
|
|
32
|
+
def self.new: (?file: String, ?rule: String, ?message_regex: Regexp?, ?count: Integer) -> instance
|
|
33
|
+
# sig-gen gap: #1183 — as above.
|
|
34
|
+
def self.[]: (?file: String, ?rule: String, ?message_regex: Regexp?, ?count: Integer) -> instance
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# One bucket's drift state for `audit`. `status` is the four-way verdict `status_for` returns;
|
|
38
|
+
# `delta` is `actual_count - bucket.count` (positive = over threshold).
|
|
39
|
+
class DriftRow < ::Struct[untyped]
|
|
40
|
+
# sig-gen gap: #1183 — Struct member types are not inferred from construction sites; as above.
|
|
41
|
+
def bucket: () -> Bucket
|
|
42
|
+
# sig-gen gap: #1183 — as above.
|
|
43
|
+
def actual_count: () -> Integer
|
|
44
|
+
# sig-gen gap: #1183 — as above.
|
|
45
|
+
def status: () -> (:within | :over | :cleared | :reducible)
|
|
46
|
+
def delta: () -> Integer
|
|
47
|
+
# sig-gen gap: #1183 — as above.
|
|
48
|
+
def bucket=: (Bucket) -> Bucket
|
|
49
|
+
# sig-gen gap: #1183 — as above.
|
|
50
|
+
def actual_count=: (Integer) -> Integer
|
|
51
|
+
# sig-gen gap: #1183 — as above.
|
|
52
|
+
def status=: (:within | :over | :cleared | :reducible) -> (:within | :over | :cleared | :reducible)
|
|
53
|
+
# sig-gen gap: #1183 — as above.
|
|
54
|
+
def self.new: (?bucket: Bucket, ?actual_count: Integer, ?status: :within | :over | :cleared | :reducible) -> instance
|
|
55
|
+
# sig-gen gap: #1183 — as above.
|
|
56
|
+
def self.[]: (?bucket: Bucket, ?actual_count: Integer, ?status: :within | :over | :cleared | :reducible) -> instance
|
|
57
|
+
end
|
|
58
|
+
|
|
9
59
|
# Load a baseline file from disk.
|
|
10
60
|
# Returns `nil` when `path` is nil (no baseline configured).
|
|
11
61
|
# Raises {LoadError} on malformed or unsupported content.
|
|
12
62
|
def self.load: (::String? path, ?project_root: ::String) -> Baseline?
|
|
13
63
|
|
|
14
64
|
# Build a baseline from a current run's diagnostic stream.
|
|
15
|
-
def self.from_diagnostics: (untyped diagnostics, ?match_mode: :rule | :message) -> Baseline
|
|
65
|
+
def self.from_diagnostics: (untyped diagnostics, ?match_mode: :rule | :message, ?project_root: ::String | ::Pathname) -> Baseline
|
|
16
66
|
|
|
17
|
-
|
|
67
|
+
# Always an Array of Bucket — `initialize` freezes what it is given and every caller hands it
|
|
68
|
+
# Bucket instances (parse_row rows, from_diagnostics groups, `without`'s reject, or `[]`).
|
|
69
|
+
# sig-gen gap: #1154 — an `attr_reader` over an ivar assigned in `initialize` from a parameter
|
|
70
|
+
# is skipped (untyped return); the element type is hand-written.
|
|
71
|
+
attr_reader buckets: Array[Bucket]
|
|
18
72
|
|
|
19
|
-
|
|
73
|
+
# `project_root` is `Pathname.new`'d, so a `Pathname` is accepted as well as a `String`
|
|
74
|
+
# (`without` re-passes the stored Pathname).
|
|
75
|
+
def initialize: (Array[Bucket] buckets, ?project_root: ::String | ::Pathname) -> void
|
|
20
76
|
|
|
21
77
|
# Apply the baseline filter. Returns [surfaced_diagnostics, silenced_count].
|
|
22
|
-
|
|
78
|
+
# `diagnostics` stays `untyped`: `Analysis::Diagnostic`'s sig is partial (no `qualified_rule`),
|
|
79
|
+
# so a tighter param would put `diag.qualified_rule` behind an unsigned member. The declared
|
|
80
|
+
# `[Array[untyped], Integer]` diverges from sig-gen's inference
|
|
81
|
+
# (`[Array[untyped], untyped] | [untyped, 0]` — the literal seed and the accumulated local are
|
|
82
|
+
# unproven); the `Integer` count is the author's intent.
|
|
83
|
+
def filter: (untyped diagnostics) -> [Array[untyped], ::Integer]
|
|
23
84
|
|
|
24
|
-
# Report bucket-level drift for each recorded baseline bucket
|
|
25
|
-
|
|
85
|
+
# Report bucket-level drift for each recorded baseline bucket — one DriftRow per bucket, in
|
|
86
|
+
# baseline-file order.
|
|
87
|
+
def audit: (untyped diagnostics) -> Array[DriftRow]
|
|
26
88
|
|
|
27
89
|
# Return a new Baseline with the given buckets removed.
|
|
28
|
-
def without: (
|
|
90
|
+
def without: (Array[Bucket] buckets_to_drop) -> Baseline
|
|
29
91
|
|
|
30
92
|
# Serialise to a YAML string.
|
|
31
93
|
def to_yaml: () -> ::String
|
|
@@ -2,7 +2,7 @@ module Rigor
|
|
|
2
2
|
module Analysis
|
|
3
3
|
module CheckRules
|
|
4
4
|
def self?.diagnose: (path: String, root: untyped, scope_index: Hash[untyped, Scope]) -> Array[Diagnostic]
|
|
5
|
-
def self?.build_node_collectors: (String path, untyped scope_index) -> Hash[Symbol, untyped]
|
|
5
|
+
def self?.build_node_collectors: (String path, untyped scope_index, ?untyped root) -> Hash[Symbol, untyped]
|
|
6
6
|
def self?.node_collector_driver: (Hash[Symbol, untyped] collectors) -> untyped
|
|
7
7
|
def self?.shadow_verify_converged_collectors: (String path, untyped root, untyped scope_index, Hash[Symbol, untyped]? collectors) -> void
|
|
8
8
|
def self?.filter_suppressed: (Array[Diagnostic] diagnostics, comments: untyped, disabled_rules: Array[String]) -> Array[Diagnostic]
|