rigortype 0.2.7 → 0.2.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 +1 -1
- data/docs/manual/04-diagnostics.md +7 -4
- data/docs/manual/06-baseline.md +5 -2
- data/docs/manual/15-type-protection-coverage.md +6 -4
- data/lib/rigor/analysis/baseline.rb +56 -96
- data/lib/rigor/analysis/buffer_binding.rb +13 -20
- data/lib/rigor/analysis/check_rules/always_truthy_condition_collector.rb +29 -48
- data/lib/rigor/analysis/check_rules/dead_assignment_collector.rb +35 -54
- data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +23 -37
- data/lib/rigor/analysis/check_rules/main_pass_collector.rb +16 -23
- data/lib/rigor/analysis/check_rules/rule_walk.rb +48 -71
- data/lib/rigor/analysis/check_rules/self_closedness_scanner.rb +19 -28
- data/lib/rigor/analysis/check_rules/unreachable_clause_collector.rb +48 -67
- data/lib/rigor/analysis/check_rules.rb +174 -274
- data/lib/rigor/analysis/dependency_recorder.rb +26 -38
- data/lib/rigor/analysis/dependency_source_inference/boundary_cross_reporter.rb +13 -25
- data/lib/rigor/analysis/dependency_source_inference/builder.rb +17 -30
- data/lib/rigor/analysis/dependency_source_inference/gem_resolver.rb +15 -26
- data/lib/rigor/analysis/dependency_source_inference/index.rb +45 -76
- data/lib/rigor/analysis/dependency_source_inference/return_type_heuristic.rb +23 -40
- data/lib/rigor/analysis/dependency_source_inference/walker.rb +50 -83
- data/lib/rigor/analysis/dependency_source_inference.rb +6 -10
- data/lib/rigor/analysis/diagnostic.rb +48 -75
- data/lib/rigor/analysis/erb_template_detector.rb +13 -18
- data/lib/rigor/analysis/fact_store.rb +12 -22
- data/lib/rigor/analysis/incremental.rb +47 -63
- data/lib/rigor/analysis/incremental_session.rb +74 -100
- data/lib/rigor/analysis/project_scan.rb +12 -23
- data/lib/rigor/analysis/result.rb +3 -5
- data/lib/rigor/analysis/rule_catalog.rb +67 -95
- data/lib/rigor/analysis/run_stats.rb +38 -61
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +101 -160
- data/lib/rigor/analysis/runner/pool_coordinator.rb +121 -188
- data/lib/rigor/analysis/runner/project_pre_passes.rb +62 -96
- data/lib/rigor/analysis/runner/run_snapshots.rb +12 -18
- data/lib/rigor/analysis/runner.rb +220 -333
- data/lib/rigor/analysis/self_call_resolution_recorder.rb +30 -43
- data/lib/rigor/analysis/worker_session.rb +64 -102
- data/lib/rigor/ast/type_node.rb +6 -8
- data/lib/rigor/ast.rb +6 -10
- data/lib/rigor/bleeding_edge.rb +27 -35
- data/lib/rigor/builtins/hkt_builtins.rb +7 -14
- data/lib/rigor/builtins/imported_refinements.rb +106 -149
- data/lib/rigor/builtins/predefined_constant_refinements.rb +51 -65
- data/lib/rigor/builtins/regex_refinement.rb +32 -43
- data/lib/rigor/builtins/static_return_refinements.rb +57 -81
- data/lib/rigor/cache/descriptor.rb +58 -94
- data/lib/rigor/cache/incremental_snapshot.rb +32 -48
- data/lib/rigor/cache/rbs_cache_producer.rb +10 -15
- data/lib/rigor/cache/rbs_class_ancestor_table.rb +10 -16
- data/lib/rigor/cache/rbs_class_type_param_names.rb +10 -16
- data/lib/rigor/cache/rbs_constant_table.rb +8 -13
- data/lib/rigor/cache/rbs_descriptor.rb +8 -13
- data/lib/rigor/cache/rbs_environment.rb +11 -19
- data/lib/rigor/cache/rbs_environment_marshal_patch.rb +11 -19
- data/lib/rigor/cache/rbs_known_class_names.rb +8 -12
- data/lib/rigor/cache/store.rb +96 -151
- data/lib/rigor/cli/annotate_command.rb +51 -88
- data/lib/rigor/cli/baseline_command.rb +10 -17
- data/lib/rigor/cli/check_command.rb +121 -199
- data/lib/rigor/cli/check_runner_factory.rb +8 -14
- data/lib/rigor/cli/ci_detector.rb +9 -14
- data/lib/rigor/cli/command.rb +8 -14
- data/lib/rigor/cli/coverage_command.rb +19 -26
- data/lib/rigor/cli/coverage_mutation.rb +14 -19
- data/lib/rigor/cli/coverage_report.rb +0 -2
- data/lib/rigor/cli/coverage_scan.rb +7 -11
- data/lib/rigor/cli/diagnostic_formats.rb +43 -62
- data/lib/rigor/cli/diff_command.rb +10 -20
- data/lib/rigor/cli/docs_command.rb +26 -40
- data/lib/rigor/cli/doctor_command.rb +8 -9
- data/lib/rigor/cli/explain_command.rb +4 -7
- data/lib/rigor/cli/fused_protection_renderer.rb +4 -5
- data/lib/rigor/cli/fused_protection_report.rb +6 -8
- data/lib/rigor/cli/lsp_command.rb +11 -19
- data/lib/rigor/cli/mcp_command.rb +4 -6
- data/lib/rigor/cli/mutation_protection_renderer.rb +3 -4
- data/lib/rigor/cli/mutation_protection_report.rb +6 -9
- data/lib/rigor/cli/options.rb +11 -19
- data/lib/rigor/cli/plugin_command.rb +18 -30
- data/lib/rigor/cli/plugins_command.rb +29 -51
- data/lib/rigor/cli/plugins_renderer.rb +12 -20
- data/lib/rigor/cli/prism_colorizer.rb +13 -19
- data/lib/rigor/cli/protection_renderer.rb +5 -7
- data/lib/rigor/cli/protection_report.rb +27 -17
- data/lib/rigor/cli/renderable.rb +4 -6
- data/lib/rigor/cli/show_bleedingedge_command.rb +5 -8
- data/lib/rigor/cli/sig_gen_command.rb +14 -26
- data/lib/rigor/cli/skill_command.rb +30 -47
- data/lib/rigor/cli/skill_describe.rb +40 -64
- data/lib/rigor/cli/trace_command.rb +9 -16
- data/lib/rigor/cli/trace_renderer.rb +35 -51
- data/lib/rigor/cli/triage_command.rb +6 -10
- data/lib/rigor/cli/triage_renderer.rb +1 -2
- data/lib/rigor/cli/type_of_command.rb +14 -23
- data/lib/rigor/cli/type_of_renderer.rb +3 -5
- data/lib/rigor/cli/type_scan_command.rb +6 -10
- data/lib/rigor/cli/type_scan_renderer.rb +3 -5
- data/lib/rigor/cli/type_scan_report.rb +2 -3
- data/lib/rigor/cli/upgrade_command.rb +2 -3
- data/lib/rigor/cli.rb +16 -28
- data/lib/rigor/config_audit.rb +35 -44
- data/lib/rigor/configuration/dependencies.rb +41 -70
- data/lib/rigor/configuration/severity_profile.rb +28 -42
- data/lib/rigor/configuration.rb +150 -241
- data/lib/rigor/environment/bundle_sig_discovery.rb +74 -118
- data/lib/rigor/environment/class_registry.rb +19 -26
- data/lib/rigor/environment/constant_type_cache_holder.rb +14 -21
- data/lib/rigor/environment/hkt_registry_holder.rb +6 -12
- data/lib/rigor/environment/lockfile_resolver.rb +31 -47
- data/lib/rigor/environment/rbs_collection_discovery.rb +39 -63
- data/lib/rigor/environment/rbs_coverage_report.rb +24 -42
- data/lib/rigor/environment/rbs_loader.rb +420 -518
- data/lib/rigor/environment/reflection.rb +28 -53
- data/lib/rigor/environment/reporters.rb +13 -24
- data/lib/rigor/environment.rb +176 -291
- data/lib/rigor/flow_contribution/conflict.rb +16 -27
- data/lib/rigor/flow_contribution/element.rb +7 -12
- data/lib/rigor/flow_contribution/fact.rb +33 -57
- data/lib/rigor/flow_contribution/merge_result.rb +6 -9
- data/lib/rigor/flow_contribution/merger.rb +32 -47
- data/lib/rigor/flow_contribution.rb +37 -55
- data/lib/rigor/inference/acceptance.rb +133 -219
- data/lib/rigor/inference/block_parameter_binder.rb +52 -82
- data/lib/rigor/inference/body_fixpoint.rb +22 -30
- data/lib/rigor/inference/budget_trace.rb +43 -63
- data/lib/rigor/inference/builtins/array_catalog.rb +4 -6
- data/lib/rigor/inference/builtins/comparable_catalog.rb +4 -6
- data/lib/rigor/inference/builtins/complex_catalog.rb +13 -19
- data/lib/rigor/inference/builtins/date_catalog.rb +38 -67
- data/lib/rigor/inference/builtins/encoding_catalog.rb +22 -36
- data/lib/rigor/inference/builtins/enumerable_catalog.rb +4 -6
- data/lib/rigor/inference/builtins/exception_catalog.rb +38 -57
- data/lib/rigor/inference/builtins/hash_catalog.rb +9 -14
- data/lib/rigor/inference/builtins/method_catalog.rb +29 -48
- data/lib/rigor/inference/builtins/numeric_catalog.rb +13 -18
- data/lib/rigor/inference/builtins/pathname_catalog.rb +8 -13
- data/lib/rigor/inference/builtins/proc_catalog.rb +38 -62
- data/lib/rigor/inference/builtins/random_catalog.rb +21 -32
- data/lib/rigor/inference/builtins/range_catalog.rb +12 -21
- data/lib/rigor/inference/builtins/rational_catalog.rb +9 -15
- data/lib/rigor/inference/builtins/re_catalog.rb +29 -48
- data/lib/rigor/inference/builtins/set_catalog.rb +18 -27
- data/lib/rigor/inference/builtins/string_catalog.rb +12 -19
- data/lib/rigor/inference/builtins/struct_catalog.rb +18 -30
- data/lib/rigor/inference/builtins/time_catalog.rb +28 -44
- data/lib/rigor/inference/closure_escape_analyzer.rb +44 -67
- data/lib/rigor/inference/coverage_scanner.rb +13 -18
- data/lib/rigor/inference/def_return_typer.rb +8 -14
- data/lib/rigor/inference/dynamic_origin.rb +23 -20
- data/lib/rigor/inference/expression_typer.rb +774 -1152
- data/lib/rigor/inference/fallback.rb +8 -12
- data/lib/rigor/inference/fallback_tracer.rb +4 -10
- data/lib/rigor/inference/flow_tracer.rb +25 -36
- data/lib/rigor/inference/hkt_body.rb +45 -68
- data/lib/rigor/inference/hkt_body_parser.rb +33 -52
- data/lib/rigor/inference/hkt_reducer.rb +38 -59
- data/lib/rigor/inference/hkt_registry.rb +50 -76
- data/lib/rigor/inference/indexed_narrowing.rb +55 -81
- data/lib/rigor/inference/macro_block_self_type.rb +21 -34
- data/lib/rigor/inference/method_dispatcher/array_to_h_folding.rb +11 -18
- data/lib/rigor/inference/method_dispatcher/block_folding.rb +49 -83
- data/lib/rigor/inference/method_dispatcher/call_context.rb +16 -23
- data/lib/rigor/inference/method_dispatcher/cgi_folding.rb +13 -22
- data/lib/rigor/inference/method_dispatcher/constant_folding.rb +307 -454
- data/lib/rigor/inference/method_dispatcher/data_folding.rb +24 -34
- data/lib/rigor/inference/method_dispatcher/file_folding.rb +22 -37
- data/lib/rigor/inference/method_dispatcher/iterator_dispatch.rb +52 -81
- data/lib/rigor/inference/method_dispatcher/kernel_dispatch.rb +51 -78
- data/lib/rigor/inference/method_dispatcher/literal_string_folding.rb +60 -97
- data/lib/rigor/inference/method_dispatcher/math_folding.rb +23 -34
- data/lib/rigor/inference/method_dispatcher/member_shape_projection.rb +18 -26
- data/lib/rigor/inference/method_dispatcher/method_folding.rb +37 -71
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +114 -182
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +122 -193
- data/lib/rigor/inference/method_dispatcher/receiver_affinity.rb +15 -24
- data/lib/rigor/inference/method_dispatcher/reduce_folding.rb +64 -93
- data/lib/rigor/inference/method_dispatcher/regexp_folding.rb +31 -45
- data/lib/rigor/inference/method_dispatcher/set_folding.rb +6 -9
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +356 -511
- data/lib/rigor/inference/method_dispatcher/shellwords_folding.rb +22 -32
- data/lib/rigor/inference/method_dispatcher/singleton_folding.rb +15 -21
- data/lib/rigor/inference/method_dispatcher/struct_folding.rb +66 -82
- data/lib/rigor/inference/method_dispatcher/time_folding.rb +10 -15
- data/lib/rigor/inference/method_dispatcher/uri_folding.rb +9 -13
- data/lib/rigor/inference/method_dispatcher.rb +378 -524
- data/lib/rigor/inference/method_parameter_binder.rb +81 -114
- data/lib/rigor/inference/multi_target_binder.rb +51 -68
- data/lib/rigor/inference/mutation_widening.rb +115 -158
- data/lib/rigor/inference/narrowing.rb +509 -727
- data/lib/rigor/inference/origin_lookup.rb +38 -0
- data/lib/rigor/inference/parameter_inference_collector.rb +100 -100
- data/lib/rigor/inference/precision_scanner.rb +26 -35
- data/lib/rigor/inference/project_patched_methods.rb +20 -32
- data/lib/rigor/inference/project_patched_scanner.rb +23 -37
- data/lib/rigor/inference/protection_scanner.rb +16 -18
- data/lib/rigor/inference/rbs_type_translator.rb +49 -66
- data/lib/rigor/inference/scope_indexer.rb +473 -817
- data/lib/rigor/inference/statement_evaluator.rb +706 -1111
- data/lib/rigor/inference/struct_fold_safety.rb +34 -48
- data/lib/rigor/inference/synthetic_method.rb +9 -16
- data/lib/rigor/inference/synthetic_method_index.rb +20 -35
- data/lib/rigor/inference/synthetic_method_scanner.rb +63 -103
- data/lib/rigor/language_server/buffer_resolution.rb +6 -9
- data/lib/rigor/language_server/buffer_table.rb +11 -18
- data/lib/rigor/language_server/completion_provider.rb +69 -116
- data/lib/rigor/language_server/debouncer.rb +16 -25
- data/lib/rigor/language_server/diagnostic_publisher.rb +26 -40
- data/lib/rigor/language_server/document_symbol_provider.rb +14 -19
- data/lib/rigor/language_server/folding_range_provider.rb +11 -19
- data/lib/rigor/language_server/hover_provider.rb +8 -11
- data/lib/rigor/language_server/hover_renderer.rb +56 -93
- data/lib/rigor/language_server/loop.rb +14 -19
- data/lib/rigor/language_server/project_context.rb +46 -74
- data/lib/rigor/language_server/selection_range_provider.rb +9 -12
- data/lib/rigor/language_server/server.rb +55 -83
- data/lib/rigor/language_server/signature_help_provider.rb +29 -46
- data/lib/rigor/language_server/synchronized_writer.rb +4 -7
- data/lib/rigor/language_server/uri.rb +8 -13
- data/lib/rigor/language_server.rb +4 -6
- data/lib/rigor/mcp/loop.rb +2 -3
- data/lib/rigor/mcp/server.rb +4 -7
- data/lib/rigor/mcp.rb +3 -6
- data/lib/rigor/plugin/access_denied_error.rb +5 -8
- data/lib/rigor/plugin/additional_initializer.rb +21 -31
- data/lib/rigor/plugin/base.rb +335 -518
- data/lib/rigor/plugin/blueprint.rb +14 -23
- data/lib/rigor/plugin/box.rb +18 -29
- data/lib/rigor/plugin/fact_store.rb +16 -26
- data/lib/rigor/plugin/inflector.rb +37 -53
- data/lib/rigor/plugin/io_boundary.rb +33 -56
- data/lib/rigor/plugin/isolation.rb +42 -55
- data/lib/rigor/plugin/load_error.rb +10 -15
- data/lib/rigor/plugin/loader.rb +30 -49
- data/lib/rigor/plugin/macro/block_as_method.rb +20 -32
- data/lib/rigor/plugin/macro/heredoc_template.rb +35 -58
- data/lib/rigor/plugin/macro/nested_class_template.rb +22 -36
- data/lib/rigor/plugin/macro/trait_registry.rb +34 -51
- data/lib/rigor/plugin/macro.rb +10 -15
- data/lib/rigor/plugin/manifest.rb +85 -144
- data/lib/rigor/plugin/node_context.rb +14 -22
- data/lib/rigor/plugin/node_rule_walk.rb +49 -74
- data/lib/rigor/plugin/protocol_contract.rb +25 -39
- data/lib/rigor/plugin/registry.rb +132 -205
- data/lib/rigor/plugin/services.rb +21 -33
- data/lib/rigor/plugin/source_rbs_synthesis_reporter.rb +11 -19
- data/lib/rigor/plugin/trust_policy.rb +24 -38
- data/lib/rigor/plugin/type_node_resolver.rb +15 -24
- data/lib/rigor/protection/diagnostic_oracle.rb +11 -13
- data/lib/rigor/protection/mutation_scanner.rb +27 -35
- data/lib/rigor/protection/mutator.rb +50 -70
- data/lib/rigor/protection/test_suite_oracle.rb +20 -27
- data/lib/rigor/rbs_extended/conformance_checker.rb +48 -68
- data/lib/rigor/rbs_extended/hkt_directives.rb +28 -54
- data/lib/rigor/rbs_extended/reporter.rb +24 -40
- data/lib/rigor/rbs_extended.rb +107 -197
- data/lib/rigor/reflection.rb +68 -86
- data/lib/rigor/scope/discovery_index.rb +14 -19
- data/lib/rigor/scope.rb +255 -310
- data/lib/rigor/sig_gen/classification.rb +6 -10
- data/lib/rigor/sig_gen/generator.rb +197 -323
- data/lib/rigor/sig_gen/layout_index.rb +12 -20
- data/lib/rigor/sig_gen/method_candidate.rb +12 -17
- data/lib/rigor/sig_gen/observation_collector.rb +38 -70
- data/lib/rigor/sig_gen/observed_call.rb +13 -23
- data/lib/rigor/sig_gen/path_mapper.rb +17 -29
- data/lib/rigor/sig_gen/renderer.rb +7 -13
- data/lib/rigor/sig_gen/type_elaborator.rb +15 -28
- data/lib/rigor/sig_gen/write_result.rb +8 -16
- data/lib/rigor/sig_gen/writer.rb +95 -174
- data/lib/rigor/sig_gen.rb +3 -6
- data/lib/rigor/signature_path_audit.rb +24 -30
- data/lib/rigor/source/constant_path.rb +10 -14
- data/lib/rigor/source/literals.rb +31 -45
- data/lib/rigor/source/node_locator.rb +9 -11
- data/lib/rigor/source/node_walker.rb +9 -13
- data/lib/rigor/source.rb +3 -4
- data/lib/rigor/testing.rb +16 -20
- data/lib/rigor/triage/catalogue.rb +38 -62
- data/lib/rigor/triage.rb +31 -52
- data/lib/rigor/trinary.rb +9 -13
- data/lib/rigor/type/acceptance_router.rb +4 -6
- data/lib/rigor/type/accepts_result.rb +10 -14
- data/lib/rigor/type/app.rb +19 -27
- data/lib/rigor/type/bot.rb +4 -6
- data/lib/rigor/type/bound_method.rb +10 -15
- data/lib/rigor/type/combinator.rb +165 -257
- data/lib/rigor/type/constant.rb +23 -34
- data/lib/rigor/type/data_class.rb +10 -15
- data/lib/rigor/type/data_instance.rb +14 -20
- data/lib/rigor/type/difference.rb +21 -32
- data/lib/rigor/type/dynamic.rb +3 -5
- data/lib/rigor/type/hash_shape.rb +32 -18
- data/lib/rigor/type/integer_range.rb +11 -16
- data/lib/rigor/type/intersection.rb +27 -42
- data/lib/rigor/type/nominal.rb +10 -15
- data/lib/rigor/type/plain_lattice.rb +9 -13
- data/lib/rigor/type/refined.rb +67 -114
- data/lib/rigor/type/singleton.rb +4 -6
- data/lib/rigor/type/struct_class.rb +11 -16
- data/lib/rigor/type/struct_instance.rb +15 -21
- data/lib/rigor/type/tuple.rb +14 -19
- data/lib/rigor/type/union.rb +30 -42
- data/lib/rigor/type_node/generic.rb +14 -26
- data/lib/rigor/type_node/identifier.rb +12 -19
- data/lib/rigor/type_node.rb +3 -12
- data/lib/rigor/value_semantics.rb +16 -21
- data/lib/rigor/version.rb +1 -1
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/analyzer.rb +18 -30
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_discoverer.rb +16 -29
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_index.rb +12 -23
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +22 -39
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/analyzer.rb +26 -46
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_discoverer.rb +51 -87
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_index.rb +10 -17
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb +26 -39
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb +118 -176
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_discoverer.rb +30 -51
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_index.rb +57 -92
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +71 -108
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/analyzer.rb +13 -22
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_discoverer.rb +15 -25
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_index.rb +8 -13
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +16 -24
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/analyzer.rb +30 -47
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +79 -129
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_index.rb +36 -57
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_parser.rb +27 -41
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_table.rb +16 -24
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +148 -235
- data/plugins/rigor-activerecord/lib/rigor-activerecord.rb +3 -5
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/analyzer.rb +8 -14
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_discoverer.rb +9 -15
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_index.rb +4 -7
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +23 -41
- data/plugins/rigor-activestorage/lib/rigor-activestorage.rb +3 -5
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb +6 -10
- data/plugins/rigor-activesupport-core-ext/lib/rigor-activesupport-core-ext.rb +8 -11
- data/plugins/rigor-devise/lib/rigor/plugin/devise.rb +30 -45
- data/plugins/rigor-devise/lib/rigor-devise.rb +3 -5
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema/schema_scanner.rb +43 -69
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema.rb +26 -35
- data/plugins/rigor-dry-schema/lib/rigor-dry-schema.rb +3 -5
- data/plugins/rigor-dry-struct/lib/rigor/plugin/dry_struct.rb +30 -47
- data/plugins/rigor-dry-struct/lib/rigor-dry-struct.rb +3 -5
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types/alias_scanner.rb +67 -113
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types.rb +29 -46
- data/plugins/rigor-dry-types/lib/rigor-dry-types.rb +3 -5
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation/contract_scanner.rb +13 -20
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation.rb +14 -23
- data/plugins/rigor-dry-validation/lib/rigor-dry-validation.rb +2 -3
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/analyzer.rb +22 -37
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_discoverer.rb +28 -46
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_index.rb +13 -17
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot.rb +30 -47
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql/type_scanner.rb +52 -80
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql.rb +21 -31
- data/plugins/rigor-graphql/lib/rigor-graphql.rb +3 -5
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami/action_checker.rb +11 -17
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami.rb +20 -34
- data/plugins/rigor-mangrove/lib/rigor/plugin/mangrove.rb +45 -75
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest/assertion_analyzer.rb +22 -36
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest.rb +22 -41
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/analyzer.rb +17 -32
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_discoverer.rb +6 -12
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_index.rb +4 -8
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit.rb +17 -32
- data/plugins/rigor-rails/lib/rigor-rails.rb +11 -18
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/analyzer.rb +58 -92
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_index.rb +20 -34
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_loader.rb +20 -31
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n.rb +49 -82
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/analyzer.rb +55 -92
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/devise_routes.rb +51 -90
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/doorkeeper_routes.rb +17 -30
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_discoverer.rb +38 -70
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_table.rb +42 -74
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/routes_parser.rb +280 -497
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +54 -89
- data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb +32 -54
- data/plugins/rigor-rbs-inline/lib/rigor-rbs-inline.rb +8 -13
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/analyzer.rb +9 -16
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_scope_index.rb +24 -39
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_type_resolver.rb +13 -22
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +34 -56
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/scope_walker.rb +22 -42
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec.rb +43 -75
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails/have_http_status_analyzer.rb +27 -39
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails/http_status_codes.rb +14 -19
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails.rb +20 -34
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers/analyzer.rb +28 -47
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers.rb +21 -37
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/analyzer.rb +13 -22
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_discoverer.rb +18 -31
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_index.rb +6 -10
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb +14 -29
- data/plugins/rigor-sinatra/lib/rigor/plugin/sinatra.rb +23 -41
- data/plugins/rigor-sinatra/lib/rigor-sinatra.rb +3 -5
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/absurd_recognizer.rb +23 -38
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/assertion_recognizer.rb +57 -96
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog.rb +22 -35
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog_walker.rb +41 -69
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/method_signature.rb +6 -10
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sig_parser.rb +24 -41
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sigil_detector.rb +29 -50
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/type_translator.rb +55 -88
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +159 -262
- data/plugins/rigor-statesman/lib/rigor/plugin/statesman.rb +21 -29
- data/plugins/rigor-statesman/lib/rigor-statesman.rb +3 -5
- data/plugins/rigor-typescript-utility-types/lib/rigor/plugin/typescript_utility_types.rb +23 -37
- data/plugins/rigor-typescript-utility-types/lib/rigor-typescript-utility-types.rb +4 -6
- data/sig/rigor/scope.rbs +6 -0
- metadata +2 -1
|
@@ -8,66 +8,46 @@ require_relative "receiver_affinity"
|
|
|
8
8
|
module Rigor
|
|
9
9
|
module Inference
|
|
10
10
|
module MethodDispatcher
|
|
11
|
-
# Picks the RBS overload that should answer a call given the
|
|
12
|
-
#
|
|
13
|
-
# the v0.1.2 interface-strictness preference layered on top):
|
|
11
|
+
# Picks the RBS overload that should answer a call given the caller's actual argument types. Slice 4
|
|
12
|
+
# phase 2c shape (with the v0.1.2 interface-strictness preference layered on top):
|
|
14
13
|
#
|
|
15
|
-
# 1. Filter overloads by positional arity (required, optional and
|
|
16
|
-
#
|
|
17
|
-
# overload because we do not yet thread keyword args through
|
|
14
|
+
# 1. Filter overloads by positional arity (required, optional and rest_positionals are honored;
|
|
15
|
+
# required_keywords disqualify the overload because we do not yet thread keyword args through
|
|
18
16
|
# `call_arg_types`).
|
|
19
|
-
# 2. **Pass 1 — strict matches first.** Among the arity-matching
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
# `
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
# argument
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
# that admit only specific values). Those overloads carry
|
|
37
|
-
# value-precise returns (`Kernel#Array: (nil) -> []`,
|
|
38
|
-
# `Regexp#=~: (nil) -> nil`) that would otherwise win purely
|
|
39
|
-
# by list position and inject false constants into the flow;
|
|
40
|
-
# they remain selectable when the argument PROVES the value
|
|
41
|
-
# (strict pass) or when no other overload matches (step 4's
|
|
42
|
-
# fallback picks the first overload regardless).
|
|
43
|
-
# 4. If no overload matches at all, fall back to
|
|
44
|
-
# `method_types.first` so existing call sites keep their
|
|
45
|
-
# phase 1 / 2b behavior. This preserves the fail-soft
|
|
46
|
-
# invariant of the dispatcher.
|
|
17
|
+
# 2. **Pass 1 — strict matches first.** Among the arity-matching overloads, prefer the first one
|
|
18
|
+
# whose every (param, arg) pair returns a `yes` or `maybe` answer AND whose param types do NOT
|
|
19
|
+
# translate through `RBS::Types::Alias` / `Interface` / `Intersection`. The translator demotes
|
|
20
|
+
# those to `Dynamic[Top]`, which gradually accepts any argument — so without this preference, an
|
|
21
|
+
# alias-typed overload like `Array#[](::int) -> Elem` would beat the strict
|
|
22
|
+
# `Array#[](Range) -> Array[Elem]?` overload for a Range argument.
|
|
23
|
+
# 3. **Pass 2 — gradual fall-back.** If no fully strict overload matches, accept the first
|
|
24
|
+
# arity-and-gradual-accept match (the v0.1.1 behaviour). Alias / Interface / Intersection params
|
|
25
|
+
# still reach this pass, so call sites whose only candidate IS an alias-typed overload keep
|
|
26
|
+
# working. One exclusion: an `untyped` argument does NOT gradually match a value-pinning param
|
|
27
|
+
# (`nil` / literal types — carriers that admit only specific values). Those overloads carry
|
|
28
|
+
# value-precise returns (`Kernel#Array: (nil) -> []`, `Regexp#=~: (nil) -> nil`) that would
|
|
29
|
+
# otherwise win purely by list position and inject false constants into the flow; they remain
|
|
30
|
+
# selectable when the argument PROVES the value (strict pass) or when no other overload matches
|
|
31
|
+
# (step 4's fallback picks the first overload regardless).
|
|
32
|
+
# 4. If no overload matches at all, fall back to `method_types.first` so existing call sites keep
|
|
33
|
+
# their phase 1 / 2b behavior. This preserves the fail-soft invariant of the dispatcher.
|
|
47
34
|
#
|
|
48
|
-
# The selector is intentionally agnostic about the dispatch kind
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
# the caller fetched.
|
|
35
|
+
# The selector is intentionally agnostic about the dispatch kind (instance vs singleton). Both kinds
|
|
36
|
+
# share the same arity and acceptance shape; the difference is only in which `Definition` the caller
|
|
37
|
+
# fetched.
|
|
52
38
|
module OverloadSelector
|
|
53
39
|
module_function
|
|
54
40
|
|
|
55
|
-
# Canonical RBS-core aliases shipped by `core/builtin.rbs`
|
|
56
|
-
#
|
|
57
|
-
#
|
|
58
|
-
#
|
|
59
|
-
#
|
|
60
|
-
#
|
|
61
|
-
# to `Dynamic[Top]` (interfaces are not structurally
|
|
62
|
-
# matched yet), so a dedicated pass 1.5 between strict
|
|
63
|
-
# and gradual consults this map to pick the alias whose
|
|
64
|
-
# strict arm matches.
|
|
41
|
+
# Canonical RBS-core aliases shipped by `core/builtin.rbs` whose body is `<Nominal> | _DuckType`.
|
|
42
|
+
# Matching an overload against an Integer literal should pick the `(int) -> Array[Elem]` body over
|
|
43
|
+
# the `(string) -> String` body because Integer satisfies `int`'s strict arm and not `string`'s.
|
|
44
|
+
# The translator collapses both aliases to `Dynamic[Top]` (interfaces are not structurally matched
|
|
45
|
+
# yet), so a dedicated pass 1.5 between strict and gradual consults this map to pick the alias
|
|
46
|
+
# whose strict arm matches.
|
|
65
47
|
#
|
|
66
|
-
# Symbol keys are the alias names as they appear under
|
|
67
|
-
# `
|
|
68
|
-
#
|
|
69
|
-
# Values are an Array of class names whose Nominal[..]
|
|
70
|
-
# form is the alias's strict-arm matcher.
|
|
48
|
+
# Symbol keys are the alias names as they appear under `RBS::Types::Alias#name.to_s` (the `name` is
|
|
49
|
+
# a `TypeName` whose `to_s` includes the `::` prefix). Values are an Array of class names whose
|
|
50
|
+
# Nominal[..] form is the alias's strict-arm matcher.
|
|
71
51
|
ALIAS_STRICT_NOMINALS = {
|
|
72
52
|
"::int" => ["Integer"],
|
|
73
53
|
"::string" => ["String"],
|
|
@@ -80,46 +60,35 @@ module Rigor
|
|
|
80
60
|
private_constant :ALIAS_STRICT_NOMINALS
|
|
81
61
|
|
|
82
62
|
# @param method_definition [RBS::Definition::Method]
|
|
83
|
-
# @param arg_types [Array<Rigor::Type>] caller-provided types in
|
|
84
|
-
#
|
|
63
|
+
# @param arg_types [Array<Rigor::Type>] caller-provided types in positional order. Empty when
|
|
64
|
+
# there are no arguments.
|
|
85
65
|
# @param self_type [Rigor::Type] substitute for `Bases::Self`.
|
|
86
66
|
# @param instance_type [Rigor::Type] substitute for `Bases::Instance`.
|
|
87
|
-
# @param type_vars [Hash{Symbol => Rigor::Type}] substitution map
|
|
88
|
-
#
|
|
89
|
-
#
|
|
90
|
-
#
|
|
91
|
-
#
|
|
92
|
-
#
|
|
93
|
-
#
|
|
94
|
-
#
|
|
95
|
-
#
|
|
96
|
-
#
|
|
97
|
-
#
|
|
98
|
-
# before: `find` over arity-compatible overloads, falling
|
|
99
|
-
# back to the first declaration.
|
|
100
|
-
# @return [RBS::MethodType, nil] the chosen overload, or nil
|
|
101
|
-
# when the definition has no method types at all.
|
|
67
|
+
# @param type_vars [Hash{Symbol => Rigor::Type}] substitution map for class-level type variables
|
|
68
|
+
# (Slice 4 phase 2d). The selector threads it through to {RbsTypeTranslator} so parameter types
|
|
69
|
+
# like `::Array[Elem]` substitute Elem before the accepts check, instead of degrading the param
|
|
70
|
+
# to `Array[Dynamic[Top]]`.
|
|
71
|
+
# @param block_required [Boolean] when `true`, only overloads that declare a block clause are
|
|
72
|
+
# considered (Slice 6 phase C sub-phase 1). The fallback also prefers a block-bearing overload
|
|
73
|
+
# over `method_types.first`. When `false` (the Slice 4 phase 2c default) the selector behaves
|
|
74
|
+
# exactly as before: `find` over arity-compatible overloads, falling back to the first
|
|
75
|
+
# declaration.
|
|
76
|
+
# @return [RBS::MethodType, nil] the chosen overload, or nil when the definition has no method
|
|
77
|
+
# types at all.
|
|
102
78
|
def select(method_definition, arg_types:, self_type:, instance_type:, type_vars: {}, block_required: false,
|
|
103
79
|
environment: nil)
|
|
104
80
|
overloads = method_definition.method_types
|
|
105
81
|
return nil if overloads.empty?
|
|
106
82
|
|
|
107
|
-
# `rigor:v1:param: <name> <refinement>` annotations on
|
|
108
|
-
#
|
|
109
|
-
#
|
|
110
|
-
# `accepts_param?` so overload selection sees the
|
|
111
|
-
# tighter type when filtering candidates by argument
|
|
112
|
-
# compatibility.
|
|
83
|
+
# `rigor:v1:param: <name> <refinement>` annotations on this method override the RBS-declared
|
|
84
|
+
# parameter type at the matching name. The map is consumed inside `accepts_param?` so overload
|
|
85
|
+
# selection sees the tighter type when filtering candidates by argument compatibility.
|
|
113
86
|
param_overrides = RbsExtended.param_type_override_map(method_definition, environment: environment)
|
|
114
87
|
|
|
115
|
-
# Pre-sort: demote overloads whose param class is a
|
|
116
|
-
#
|
|
117
|
-
#
|
|
118
|
-
#
|
|
119
|
-
# convention so `5 + ?` for unknown `?` resolves to
|
|
120
|
-
# the receiver-class-preserving arm rather than an
|
|
121
|
-
# arbitrary sibling-class arm that only wins by
|
|
122
|
-
# overload-list position.
|
|
88
|
+
# Pre-sort: demote overloads whose param class is a disjoint sibling of the receiver class (e.g.
|
|
89
|
+
# `Integer#+(BigDecimal) -> BigDecimal` from the `bigdecimal` RBS reopen). Honors the coerce
|
|
90
|
+
# convention so `5 + ?` for unknown `?` resolves to the receiver-class-preserving arm rather than
|
|
91
|
+
# an arbitrary sibling-class arm that only wins by overload-list position.
|
|
123
92
|
overloads = ReceiverAffinity.reorder(overloads, self_type: self_type, environment: environment)
|
|
124
93
|
|
|
125
94
|
passes = lambda do |require_block|
|
|
@@ -132,28 +101,21 @@ module Rigor
|
|
|
132
101
|
match = passes.call(block_required)
|
|
133
102
|
return match if match
|
|
134
103
|
|
|
135
|
-
# A block at the call site that no block-declaring overload
|
|
136
|
-
#
|
|
137
|
-
#
|
|
138
|
-
#
|
|
139
|
-
#
|
|
140
|
-
# `define_command(:x) do … end` against
|
|
141
|
-
# `def define_command: (Symbol) -> Symbol`) degraded to
|
|
142
|
-
# `Dynamic[Top]` — and on a self-send suppressed the whole
|
|
143
|
-
# method's return type.
|
|
104
|
+
# A block at the call site that no block-declaring overload matched: Ruby ignores a block handed
|
|
105
|
+
# to a method that never yields it, so retry treating the block as ignorable rather than failing
|
|
106
|
+
# the dispatch. Without this, a block-bearing call to a method whose RBS declares no block (e.g.
|
|
107
|
+
# `define_command(:x) do … end` against `def define_command: (Symbol) -> Symbol`) degraded to
|
|
108
|
+
# `Dynamic[Top]` — and on a self-send suppressed the whole method's return type.
|
|
144
109
|
if block_required
|
|
145
110
|
match = passes.call(false)
|
|
146
111
|
return match if match
|
|
147
112
|
end
|
|
148
113
|
|
|
149
|
-
# No (usable) block at the call site: prefer an overload that does
|
|
150
|
-
#
|
|
151
|
-
# `
|
|
152
|
-
#
|
|
153
|
-
# the
|
|
154
|
-
# Without this, a no-block `[1, 2].filter` would adopt the
|
|
155
|
-
# block overload's `Array[Elem]` return when the call
|
|
156
|
-
# actually yields an `Enumerator`.
|
|
114
|
+
# No (usable) block at the call site: prefer an overload that does not REQUIRE a block over
|
|
115
|
+
# `overloads.first`. Methods like `Array#filter` / `Enumerable#map` declare the block-bearing
|
|
116
|
+
# overload first (`() { ... } -> Array[Elem]`) and the bare-call overload second
|
|
117
|
+
# (`() -> Enumerator[...]`). Without this, a no-block `[1, 2].filter` would adopt the block
|
|
118
|
+
# overload's `Array[Elem]` return when the call actually yields an `Enumerator`.
|
|
157
119
|
overloads.find { |mt| !overload_requires_block?(mt) } || overloads.first
|
|
158
120
|
end
|
|
159
121
|
|
|
@@ -161,10 +123,9 @@ module Rigor
|
|
|
161
123
|
method_type.respond_to?(:block) && method_type.block
|
|
162
124
|
end
|
|
163
125
|
|
|
164
|
-
# True when the overload declares a block that the caller
|
|
165
|
-
#
|
|
166
|
-
#
|
|
167
|
-
# match for a block-less call.
|
|
126
|
+
# True when the overload declares a block that the caller MUST supply (`{ ... }` in RBS). An
|
|
127
|
+
# optional block (`?{ ... }`) does NOT count — that overload is a valid match for a block-less
|
|
128
|
+
# call.
|
|
168
129
|
def overload_requires_block?(method_type)
|
|
169
130
|
block = overload_has_block?(method_type)
|
|
170
131
|
!!block && block.required
|
|
@@ -174,18 +135,13 @@ module Rigor
|
|
|
174
135
|
private
|
|
175
136
|
|
|
176
137
|
# Three-pass overload search:
|
|
177
|
-
# - Pass 1 (strict): skipped when any arg is
|
|
178
|
-
#
|
|
179
|
-
#
|
|
180
|
-
#
|
|
181
|
-
#
|
|
182
|
-
#
|
|
183
|
-
#
|
|
184
|
-
# strict arm so e.g. `Array#*(int)` wins over the
|
|
185
|
-
# `Array#*(string) -> String` overload for Integer args.
|
|
186
|
-
# - Pass 2 (gradual): the original gradual matcher so
|
|
187
|
-
# overloads that legitimately rely on duck-typed
|
|
188
|
-
# params still resolve when nothing stricter applies.
|
|
138
|
+
# - Pass 1 (strict): skipped when any arg is `Dynamic[Top]`, because gradual acceptance against
|
|
139
|
+
# an untyped arg accepts every param indiscriminately and would let pass 1 lock in an arbitrary
|
|
140
|
+
# strict overload (e.g. `Regexp#=~(nil) -> nil` over the `(::interned?) -> Integer?` overload).
|
|
141
|
+
# - Pass 1.5 (alias-resolved): consults each `RBS::Types::Alias`'s strict arm so e.g.
|
|
142
|
+
# `Array#*(int)` wins over the `Array#*(string) -> String` overload for Integer args.
|
|
143
|
+
# - Pass 2 (gradual): the original gradual matcher so overloads that legitimately rely on
|
|
144
|
+
# duck-typed params still resolve when nothing stricter applies.
|
|
189
145
|
def run_selection_passes(overloads, arg_types:, self_type:, instance_type:, type_vars:, block_required:,
|
|
190
146
|
param_overrides:)
|
|
191
147
|
shared = {
|
|
@@ -219,25 +175,19 @@ module Rigor
|
|
|
219
175
|
end
|
|
220
176
|
# rubocop:enable Metrics/ParameterLists
|
|
221
177
|
|
|
222
|
-
# Treats the literal `untyped` carrier (`Dynamic[Top]`)
|
|
223
|
-
#
|
|
224
|
-
#
|
|
225
|
-
# carry enough information to pick a sensible overload.
|
|
178
|
+
# Treats the literal `untyped` carrier (`Dynamic[Top]`) as too imprecise to drive a strict-pass
|
|
179
|
+
# match. Other `Dynamic`-wrapped types with a concrete static facet carry enough information to
|
|
180
|
+
# pick a sensible overload.
|
|
226
181
|
def untyped_arg?(type)
|
|
227
182
|
type.is_a?(Type::Dynamic) && type.static_facet.is_a?(Type::Top)
|
|
228
183
|
end
|
|
229
184
|
|
|
230
|
-
# Pass 1.5: for arity-compatible overloads whose every
|
|
231
|
-
#
|
|
232
|
-
#
|
|
233
|
-
#
|
|
234
|
-
#
|
|
235
|
-
#
|
|
236
|
-
# `Array#*(string) -> String` overload — even though
|
|
237
|
-
# both translate to `Dynamic[Top]` at the param level.
|
|
238
|
-
# Only fires when EVERY positional param has a known
|
|
239
|
-
# alias-or-strict shape; otherwise gradual matching
|
|
240
|
-
# takes over.
|
|
185
|
+
# Pass 1.5: for arity-compatible overloads whose every positional param is either a strict
|
|
186
|
+
# nominal OR a well-known core alias (`int` / `string` / `interned` / etc.), check the arg
|
|
187
|
+
# against the alias's STRICT arm. An Integer literal arg matches `int` here but not `string`, so
|
|
188
|
+
# `Array#*(int)` wins over the `Array#*(string) -> String` overload — even though both translate
|
|
189
|
+
# to `Dynamic[Top]` at the param level. Only fires when EVERY positional param has a known
|
|
190
|
+
# alias-or-strict shape; otherwise gradual matching takes over.
|
|
241
191
|
def find_matching_overload_via_aliases(overloads, arg_types:, block_required:)
|
|
242
192
|
overloads.find do |method_type|
|
|
243
193
|
next false if block_required && !OverloadSelector.overload_has_block?(method_type)
|
|
@@ -253,11 +203,9 @@ module Rigor
|
|
|
253
203
|
end
|
|
254
204
|
end
|
|
255
205
|
|
|
256
|
-
# Checks the param's RBS type against an arg using
|
|
257
|
-
# alias
|
|
258
|
-
#
|
|
259
|
-
# (the canonical core aliases all have non-alias
|
|
260
|
-
# strict arms).
|
|
206
|
+
# Checks the param's RBS type against an arg using alias-strict-arm matching. Optional / Union
|
|
207
|
+
# wrappers are flattened; alias resolution is one level deep (the canonical core aliases all have
|
|
208
|
+
# non-alias strict arms).
|
|
261
209
|
def alias_param_accepts?(rbs_type, arg)
|
|
262
210
|
nominal_names = strict_nominal_names_for(rbs_type)
|
|
263
211
|
return false if nominal_names.nil? || nominal_names.empty?
|
|
@@ -268,10 +216,9 @@ module Rigor
|
|
|
268
216
|
end
|
|
269
217
|
end
|
|
270
218
|
|
|
271
|
-
# Returns the candidate class names a param's RBS type
|
|
272
|
-
#
|
|
273
|
-
#
|
|
274
|
-
# nominals (e.g. an Interface or an unrecognised alias).
|
|
219
|
+
# Returns the candidate class names a param's RBS type accepts under alias-resolved strict
|
|
220
|
+
# matching, or nil when the shape cannot be reduced to a closed set of nominals (e.g. an
|
|
221
|
+
# Interface or an unrecognised alias).
|
|
275
222
|
def strict_nominal_names_for(rbs_type)
|
|
276
223
|
case rbs_type
|
|
277
224
|
when RBS::Types::ClassInstance
|
|
@@ -288,13 +235,10 @@ module Rigor
|
|
|
288
235
|
end
|
|
289
236
|
end
|
|
290
237
|
|
|
291
|
-
# Returns true when every positional param the call
|
|
292
|
-
#
|
|
293
|
-
#
|
|
294
|
-
#
|
|
295
|
-
# current shape — those gradually accept any arg, so
|
|
296
|
-
# an overload that includes one would beat strictly-
|
|
297
|
-
# typed alternatives in pass 2 of the selector.
|
|
238
|
+
# Returns true when every positional param the call site engages translates to a non-`Dynamic[Top]`
|
|
239
|
+
# carrier. Alias / Interface / Intersection RBS types all degrade to `Dynamic[Top]` per the
|
|
240
|
+
# translator's current shape — those gradually accept any arg, so an overload that includes one
|
|
241
|
+
# would beat strictly-typed alternatives in pass 2 of the selector.
|
|
298
242
|
def strictly_typed_params?(method_type, actual_count)
|
|
299
243
|
fun = method_type.type
|
|
300
244
|
return false unless arity_compatible?(fun, actual_count)
|
|
@@ -303,20 +247,15 @@ module Rigor
|
|
|
303
247
|
params.all? { |param| !alias_or_interface_param?(param.type) }
|
|
304
248
|
end
|
|
305
249
|
|
|
306
|
-
# Recursive: an Optional / Union wrapper is strict iff
|
|
307
|
-
#
|
|
308
|
-
#
|
|
309
|
-
#
|
|
310
|
-
# element type, which is checked separately when the
|
|
311
|
-
# element is actually accessed.
|
|
250
|
+
# Recursive: an Optional / Union wrapper is strict iff every member is strict. Type args of a
|
|
251
|
+
# ClassInstance are NOT walked — `Range[::int]` is a Range carrier at the param level; the alias
|
|
252
|
+
# only colours the element type, which is checked separately when the element is actually
|
|
253
|
+
# accessed.
|
|
312
254
|
#
|
|
313
|
-
# `RBS::Types::Bases::Any` (the explicit `untyped`
|
|
314
|
-
#
|
|
315
|
-
#
|
|
316
|
-
#
|
|
317
|
-
# catch-all overload that comes after the strictly-
|
|
318
|
-
# typed ones must lose pass 1 so the typed overloads
|
|
319
|
-
# win when their param actually fits the arg.
|
|
255
|
+
# `RBS::Types::Bases::Any` (the explicit `untyped` keyword) is treated like Alias / Interface /
|
|
256
|
+
# Intersection — both translate to `Dynamic[Top]`, both gradually accept anything. A
|
|
257
|
+
# `(untyped) -> T` catch-all overload that comes after the strictly-typed ones must lose pass 1
|
|
258
|
+
# so the typed overloads win when their param actually fits the arg.
|
|
320
259
|
def alias_or_interface_param?(rbs_type)
|
|
321
260
|
case rbs_type
|
|
322
261
|
when RBS::Types::Alias, RBS::Types::Interface,
|
|
@@ -350,9 +289,8 @@ module Rigor
|
|
|
350
289
|
end
|
|
351
290
|
end
|
|
352
291
|
|
|
353
|
-
# Slice 4 phase 2c does not pass keyword arguments through the
|
|
354
|
-
#
|
|
355
|
-
# overload that requires keywords is therefore not a viable
|
|
292
|
+
# Slice 4 phase 2c does not pass keyword arguments through the call site (caller passes only
|
|
293
|
+
# positional `arg_types`). An overload that requires keywords is therefore not a viable
|
|
356
294
|
# candidate; we skip it instead of forcing a fallback.
|
|
357
295
|
def rejects_keyword_required?(method_type)
|
|
358
296
|
fun = method_type.type
|
|
@@ -371,11 +309,10 @@ module Rigor
|
|
|
371
309
|
actual_count <= max_arity
|
|
372
310
|
end
|
|
373
311
|
|
|
374
|
-
# Builds the list of formal parameter declarations to compare
|
|
375
|
-
#
|
|
376
|
-
#
|
|
377
|
-
#
|
|
378
|
-
# repeat its single declaration for each absorbed argument.
|
|
312
|
+
# Builds the list of formal parameter declarations to compare against the actual arguments, in
|
|
313
|
+
# positional order: required first, then as many optionals as needed, then trailing required.
|
|
314
|
+
# Rest_positionals consumes the remainder; we repeat its single declaration for each absorbed
|
|
315
|
+
# argument.
|
|
379
316
|
def positional_params_for(fun, actual_count)
|
|
380
317
|
required = fun.required_positionals
|
|
381
318
|
optional = fun.optional_positionals
|
|
@@ -400,25 +337,20 @@ module Rigor
|
|
|
400
337
|
instance_type: instance_type,
|
|
401
338
|
type_vars: type_vars
|
|
402
339
|
)
|
|
403
|
-
# An `untyped` arg gradually accepts against every param,
|
|
404
|
-
#
|
|
405
|
-
#
|
|
406
|
-
#
|
|
407
|
-
#
|
|
408
|
-
# proves the value) or the final first-overload fallback
|
|
409
|
-
# may select such an overload. (Pass 1 already skips
|
|
410
|
-
# untyped args entirely, so this only engages pass 2.)
|
|
340
|
+
# An `untyped` arg gradually accepts against every param, so a value-pinning param would be
|
|
341
|
+
# "matched" with zero evidence and its value-precise return (`(nil) -> []`) would beat broader
|
|
342
|
+
# overloads purely by list position. Decline the pair; only the strict pass (where the arg
|
|
343
|
+
# proves the value) or the final first-overload fallback may select such an overload. (Pass 1
|
|
344
|
+
# already skips untyped args entirely, so this only engages pass 2.)
|
|
411
345
|
return false if untyped_arg?(arg) && value_pinning?(param_type)
|
|
412
346
|
|
|
413
347
|
result = param_type.accepts(arg, mode: :gradual)
|
|
414
348
|
result.yes? || result.maybe?
|
|
415
349
|
end
|
|
416
350
|
|
|
417
|
-
# A type that admits only specific VALUES rather than a
|
|
418
|
-
#
|
|
419
|
-
#
|
|
420
|
-
# entirely of them (`true | false`, `1 | 2`, `nil?`-style
|
|
421
|
-
# optionals of literals).
|
|
351
|
+
# A type that admits only specific VALUES rather than a class of values: a `Constant` carrier
|
|
352
|
+
# (RBS `nil` and literal types both translate to one) or a union made up entirely of them
|
|
353
|
+
# (`true | false`, `1 | 2`, `nil?`-style optionals of literals).
|
|
422
354
|
def value_pinning?(type)
|
|
423
355
|
case type
|
|
424
356
|
when Type::Constant then true
|