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
|
@@ -9,65 +9,51 @@ module Rigor
|
|
|
9
9
|
module MethodDispatcher
|
|
10
10
|
# Symbol-form `reduce` / `inject` return-type tier.
|
|
11
11
|
#
|
|
12
|
-
# `IteratorDispatch.inject_block_params` deliberately declines the
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
# the call falls to `Enumerable#reduce`'s RBS overload
|
|
18
|
-
# `(untyped, Symbol) -> untyped`, so the whole fold widens to
|
|
19
|
-
# `Dynamic[top]`.
|
|
12
|
+
# `IteratorDispatch.inject_block_params` deliberately declines the Symbol-call shapes
|
|
13
|
+
# (`(1..n).reduce(1, :*)`, `[1,2,3].reduce(:+)`) because they carry no block to bind parameters for —
|
|
14
|
+
# the decline of *block-param typing* is correct. What that decline leaves on the floor is the
|
|
15
|
+
# *return type*: with no block and no precise tier, the call falls to `Enumerable#reduce`'s RBS
|
|
16
|
+
# overload `(untyped, Symbol) -> untyped`, so the whole fold widens to `Dynamic[top]`.
|
|
20
17
|
#
|
|
21
|
-
# This tier recovers a precise return type for the Symbol-operand
|
|
22
|
-
#
|
|
18
|
+
# This tier recovers a precise return type for the Symbol-operand forms by dispatching the named
|
|
19
|
+
# operator on the accumulated type:
|
|
23
20
|
#
|
|
24
|
-
# - `(seed, :op)` (2-arg) — operand starts at the seed type `S`;
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
# `
|
|
32
|
-
#
|
|
33
|
-
# with the declared type and Rigor's false-positive discipline
|
|
34
|
-
# (the empty-collection `nil` runtime case is not modelled by RBS
|
|
35
|
-
# and adding it here would only pressure callers into defensive
|
|
36
|
-
# nil-handling for code that works).
|
|
21
|
+
# - `(seed, :op)` (2-arg) — operand starts at the seed type `S`; the result type is
|
|
22
|
+
# `dispatch(:op, widen(S) ∪ widen(E), widen(E))` joined with the seed (the seed is returned
|
|
23
|
+
# unchanged when the collection is empty). `E` is the receiver's element type.
|
|
24
|
+
# - `(:op)` (1-arg) — no seed: the first element seeds the memo, so the operand type is `E` and the
|
|
25
|
+
# result is `dispatch(:op, widen(E), widen(E))`. RBS models this overload as
|
|
26
|
+
# `() { (E, E) -> E } -> E` (no nil), so the tier returns the operator result without manufacturing
|
|
27
|
+
# a nil — staying consistent with the declared type and Rigor's false-positive discipline (the
|
|
28
|
+
# empty-collection `nil` runtime case is not modelled by RBS and adding it here would only pressure
|
|
29
|
+
# callers into defensive nil-handling for code that works).
|
|
37
30
|
#
|
|
38
|
-
# The tier is precision-additive: it declines (returns nil, today's
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
# Symbol operand, or an operator the engine cannot dispatch on the
|
|
42
|
-
# widened operand types.
|
|
31
|
+
# The tier is precision-additive: it declines (returns nil, today's `Dynamic[top]` behaviour) for
|
|
32
|
+
# every shape it cannot prove — unknown element type, Dynamic / Top receiver, a non-`Constant` Symbol
|
|
33
|
+
# operand, or an operator the engine cannot dispatch on the widened operand types.
|
|
43
34
|
#
|
|
44
|
-
# `widen_value_pinned` (ADR-55/56) collapses `Constant`/`IntegerRange`
|
|
45
|
-
#
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
# scope, the precision target is the carrier (`Integer`), not the value.
|
|
35
|
+
# `widen_value_pinned` (ADR-55/56) collapses `Constant`/`IntegerRange` operands to their nominal base
|
|
36
|
+
# before dispatch so the result is the operator's nominal return (`Integer`) rather than a
|
|
37
|
+
# constant-folded `Constant[120]` — full constant folding of the reduction is out of scope, the
|
|
38
|
+
# precision target is the carrier (`Integer`), not the value.
|
|
49
39
|
module ReduceFolding
|
|
50
40
|
module_function
|
|
51
41
|
|
|
52
42
|
REDUCE_METHODS = %i[reduce inject].freeze
|
|
53
43
|
private_constant :REDUCE_METHODS
|
|
54
44
|
|
|
55
|
-
# Allow-listed pure, side-effect-free fold operators. Each is
|
|
56
|
-
#
|
|
57
|
-
#
|
|
58
|
-
#
|
|
59
|
-
#
|
|
60
|
-
# (`acc.public_send(:gcd, elem)`); `:min` / `:max` are *not* (no
|
|
61
|
-
# `Integer#min`/`#max` — they would raise and decline), so they
|
|
62
|
-
# are deliberately omitted.
|
|
45
|
+
# Allow-listed pure, side-effect-free fold operators. Each is safe on the foldable constant operand
|
|
46
|
+
# classes (Integer / Float / Rational); division / modulo by zero is caught by the rescue harness
|
|
47
|
+
# in `execute_constant_reduce` and declines to the nominal fold. `:gcd` / `:lcm` are valid binary
|
|
48
|
+
# Integer methods (`acc.public_send(:gcd, elem)`); `:min` / `:max` are *not* (no
|
|
49
|
+
# `Integer#min`/`#max` — they would raise and decline), so they are deliberately omitted.
|
|
63
50
|
CONSTANT_FOLD_OPERATORS = %i[+ * - / % & | ^ gcd lcm].freeze
|
|
64
51
|
private_constant :CONSTANT_FOLD_OPERATORS
|
|
65
52
|
|
|
66
|
-
# Hard caps (ADR-41 WD4 style). The element count is checked
|
|
67
|
-
#
|
|
68
|
-
#
|
|
69
|
-
#
|
|
70
|
-
# folded value can never become an analyzer-heavy bignum.
|
|
53
|
+
# Hard caps (ADR-41 WD4 style). The element count is checked BEFORE the receiver is enumerated, so
|
|
54
|
+
# a `(1..1_000_000)` range never materialises. The bit-length cap rejects factorial-style blow-up
|
|
55
|
+
# (`(1..64).reduce(:*)` is a ~296-bit Integer) so the folded value can never become an
|
|
56
|
+
# analyzer-heavy bignum.
|
|
71
57
|
CONSTANT_FOLD_ELEMENT_CAP = 64
|
|
72
58
|
CONSTANT_FOLD_BIT_CAP = 256
|
|
73
59
|
private_constant :CONSTANT_FOLD_ELEMENT_CAP, :CONSTANT_FOLD_BIT_CAP
|
|
@@ -81,14 +67,11 @@ module Rigor
|
|
|
81
67
|
operator, seed = operator_and_seed(args)
|
|
82
68
|
return nil if operator.nil?
|
|
83
69
|
|
|
84
|
-
# Precision pre-check: when the receiver is a fully-constant
|
|
85
|
-
#
|
|
86
|
-
#
|
|
87
|
-
#
|
|
88
|
-
#
|
|
89
|
-
# cap, non-constant member, magnitude, exception) falls through
|
|
90
|
-
# to the carrier-precise nominal fold below — byte-identical to
|
|
91
|
-
# pre-fold behaviour.
|
|
70
|
+
# Precision pre-check: when the receiver is a fully-constant collection (a `Constant[Range]` with
|
|
71
|
+
# foldable endpoints or a `Tuple` of `Constant` elements) and the operator is an allow-listed pure
|
|
72
|
+
# op, treat the reduction as a pure function and execute it on the real values, capped. Any
|
|
73
|
+
# decline (size cap, non-constant member, magnitude, exception) falls through to the
|
|
74
|
+
# carrier-precise nominal fold below — byte-identical to pre-fold behaviour.
|
|
92
75
|
folded = try_constant_reduce(context.receiver, operator, seed)
|
|
93
76
|
return folded if folded
|
|
94
77
|
|
|
@@ -98,12 +81,11 @@ module Rigor
|
|
|
98
81
|
fold_result(operator, seed, element, context.environment)
|
|
99
82
|
end
|
|
100
83
|
|
|
101
|
-
# Executes the reduction on real constant values, or returns nil
|
|
102
|
-
#
|
|
103
|
-
# nil return, so every guard here is precision-additive only.
|
|
84
|
+
# Executes the reduction on real constant values, or returns nil to decline. The caller falls
|
|
85
|
+
# through to the nominal fold on a nil return, so every guard here is precision-additive only.
|
|
104
86
|
#
|
|
105
|
-
# @param seed [Rigor::Type, nil] the optional seed type; only a
|
|
106
|
-
#
|
|
87
|
+
# @param seed [Rigor::Type, nil] the optional seed type; only a foldable `Constant` seed is
|
|
88
|
+
# honoured, any other seed declines.
|
|
107
89
|
# @return [Rigor::Type::Constant, nil]
|
|
108
90
|
def try_constant_reduce(receiver, operator, seed)
|
|
109
91
|
return nil unless CONSTANT_FOLD_OPERATORS.include?(operator)
|
|
@@ -117,9 +99,8 @@ module Rigor
|
|
|
117
99
|
execute_constant_reduce(members, operator, seed_value, seed_present)
|
|
118
100
|
end
|
|
119
101
|
|
|
120
|
-
# Extracts the receiver's elements as a Ruby Array of foldable
|
|
121
|
-
#
|
|
122
|
-
# enumerating so an unbounded / huge `Constant[Range]` (e.g.
|
|
102
|
+
# Extracts the receiver's elements as a Ruby Array of foldable constant values, or nil to decline.
|
|
103
|
+
# Checks the size cap BEFORE enumerating so an unbounded / huge `Constant[Range]` (e.g.
|
|
123
104
|
# `(1..1_000_000)`) never calls `to_a`.
|
|
124
105
|
#
|
|
125
106
|
# @return [Array, nil]
|
|
@@ -141,8 +122,8 @@ module Rigor
|
|
|
141
122
|
# Reject endless / beginless ranges (`(1..)`, `(..5)`).
|
|
142
123
|
return nil if first.nil? || last.nil?
|
|
143
124
|
|
|
144
|
-
# Size BEFORE enumeration — `Range#size` is O(1) for numeric
|
|
145
|
-
#
|
|
125
|
+
# Size BEFORE enumeration — `Range#size` is O(1) for numeric ranges and never materialises the
|
|
126
|
+
# elements.
|
|
146
127
|
size = value.size
|
|
147
128
|
return nil unless size.is_a?(Integer)
|
|
148
129
|
return nil if size > CONSTANT_FOLD_ELEMENT_CAP
|
|
@@ -159,9 +140,8 @@ module Rigor
|
|
|
159
140
|
elements.map(&:value)
|
|
160
141
|
end
|
|
161
142
|
|
|
162
|
-
# @return [Array(Object, Boolean)] `[seed_value, present?]`. A nil
|
|
163
|
-
# seed
|
|
164
|
-
# `Constant` seed yields `[value, true]`. Any other seed yields
|
|
143
|
+
# @return [Array(Object, Boolean)] `[seed_value, present?]`. A nil seed type yields `[nil, false]`
|
|
144
|
+
# (no-seed form). A foldable `Constant` seed yields `[value, true]`. Any other seed yields
|
|
165
145
|
# `[nil, false]` so the caller can decline.
|
|
166
146
|
def constant_seed(seed)
|
|
167
147
|
return [nil, false] if seed.nil?
|
|
@@ -170,11 +150,9 @@ module Rigor
|
|
|
170
150
|
[seed.value, true]
|
|
171
151
|
end
|
|
172
152
|
|
|
173
|
-
# Runs the actual reduction, guarded by the rescue harness and
|
|
174
|
-
#
|
|
175
|
-
#
|
|
176
|
-
# (no-seed form → declines so the nominal fold's no-nil contract
|
|
177
|
-
# stands; see `fold_result`).
|
|
153
|
+
# Runs the actual reduction, guarded by the rescue harness and the magnitude cap. Empty-collection
|
|
154
|
+
# semantics match Ruby: `[].reduce(s, :op) == s` (seed form) and `[].reduce(:op) == nil` (no-seed
|
|
155
|
+
# form → declines so the nominal fold's no-nil contract stands; see `fold_result`).
|
|
178
156
|
#
|
|
179
157
|
# @return [Rigor::Type::Constant, nil]
|
|
180
158
|
def execute_constant_reduce(members, operator, seed_value, seed_present)
|
|
@@ -182,9 +160,8 @@ module Rigor
|
|
|
182
160
|
if seed_present
|
|
183
161
|
members.reduce(seed_value) { |acc, e| acc.public_send(operator, e) }
|
|
184
162
|
else
|
|
185
|
-
# No-seed empty collection reduces to nil; decline so the
|
|
186
|
-
#
|
|
187
|
-
# to `Constant[nil]`.
|
|
163
|
+
# No-seed empty collection reduces to nil; decline so the nominal no-nil contract is preserved
|
|
164
|
+
# rather than folding to `Constant[nil]`.
|
|
188
165
|
return nil if members.empty?
|
|
189
166
|
|
|
190
167
|
members.reduce { |acc, e| acc.public_send(operator, e) }
|
|
@@ -206,17 +183,15 @@ module Rigor
|
|
|
206
183
|
FOLDABLE_FOLD_CLASSES.any? { |klass| value.is_a?(klass) }
|
|
207
184
|
end
|
|
208
185
|
|
|
209
|
-
# Rejects bignum blow-up. A folded Integer wider than the bit cap
|
|
210
|
-
#
|
|
211
|
-
#
|
|
212
|
-
# type graph. Float / Rational carry no comparable blow-up risk.
|
|
186
|
+
# Rejects bignum blow-up. A folded Integer wider than the bit cap (factorial, repeated
|
|
187
|
+
# multiplication) declines to the nominal `Integer` carrier rather than parking a heavy literal in
|
|
188
|
+
# the type graph. Float / Rational carry no comparable blow-up risk.
|
|
213
189
|
def magnitude_too_large?(result)
|
|
214
190
|
result.is_a?(Integer) && result.bit_length > CONSTANT_FOLD_BIT_CAP
|
|
215
191
|
end
|
|
216
192
|
|
|
217
|
-
# Splits the call's positional arguments into the operator Symbol
|
|
218
|
-
#
|
|
219
|
-
# operand shape so `try_dispatch` declines.
|
|
193
|
+
# Splits the call's positional arguments into the operator Symbol and the optional seed. Returns
|
|
194
|
+
# `[nil, nil]` for any non-Symbol-operand shape so `try_dispatch` declines.
|
|
220
195
|
#
|
|
221
196
|
# - `[:op]` -> operator `:op`, no seed
|
|
222
197
|
# - `[seed, :op]` -> operator `:op`, seed `seed`
|
|
@@ -239,11 +214,9 @@ module Rigor
|
|
|
239
214
|
type.value.is_a?(Symbol) ? type.value : nil
|
|
240
215
|
end
|
|
241
216
|
|
|
242
|
-
# Dispatches the operator on the widened operand types. With a
|
|
243
|
-
#
|
|
244
|
-
#
|
|
245
|
-
# operator result); without a seed the memo and operand are both
|
|
246
|
-
# the element type.
|
|
217
|
+
# Dispatches the operator on the widened operand types. With a seed the memo type spans
|
|
218
|
+
# `seed | element` (the first iteration's memo is the seed, every later iteration's memo is a
|
|
219
|
+
# previous operator result); without a seed the memo and operand are both the element type.
|
|
247
220
|
def fold_result(operator, seed, element, environment)
|
|
248
221
|
widened_element = Type::Combinator.widen_value_pinned(element)
|
|
249
222
|
memo = if seed.nil?
|
|
@@ -257,12 +230,10 @@ module Rigor
|
|
|
257
230
|
result = dispatch_operator(memo, operator, widened_element, environment)
|
|
258
231
|
return nil if result.nil?
|
|
259
232
|
|
|
260
|
-
# The seed itself is the result when the collection is empty
|
|
261
|
-
#
|
|
262
|
-
# the
|
|
263
|
-
# (`
|
|
264
|
-
# the precision target rather than leaking a value-pinned member
|
|
265
|
-
# (`0 | Integer`) — full constant folding of the fold is out of
|
|
233
|
+
# The seed itself is the result when the collection is empty (`[].reduce(s, :op) == s`), so a
|
|
234
|
+
# 2-arg fold's static type is the operator result joined with the seed. The seed is widened
|
|
235
|
+
# (`Constant[0]` -> `Integer`) for the join so the carrier stays the precision target rather than
|
|
236
|
+
# leaking a value-pinned member (`0 | Integer`) — full constant folding of the fold is out of
|
|
266
237
|
# scope.
|
|
267
238
|
return result if seed.nil?
|
|
268
239
|
|
|
@@ -10,13 +10,10 @@ module Rigor
|
|
|
10
10
|
#
|
|
11
11
|
# === Supported methods
|
|
12
12
|
#
|
|
13
|
-
# * `escape(str)` / `quote(str)` — escapes regexp meta-characters.
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
# second argument may be a `Constant[Integer]` (flag bits), a
|
|
18
|
-
# `Constant[true/false]` (IGNORECASE shorthand), or absent.
|
|
19
|
-
# Returns `Constant[Regexp]`.
|
|
13
|
+
# * `escape(str)` / `quote(str)` — escapes regexp meta-characters. Returns `Constant[String]`.
|
|
14
|
+
# * `new(str)` / `new(str, opts)` — constructs a Regexp at fold time when the pattern argument is a
|
|
15
|
+
# `Constant[String]`. The optional second argument may be a `Constant[Integer]` (flag bits), a
|
|
16
|
+
# `Constant[true/false]` (IGNORECASE shorthand), or absent. Returns `Constant[Regexp]`.
|
|
20
17
|
#
|
|
21
18
|
# === Non-constant / unsupported cases
|
|
22
19
|
#
|
|
@@ -43,37 +40,29 @@ module Rigor
|
|
|
43
40
|
nil
|
|
44
41
|
end
|
|
45
42
|
|
|
46
|
-
# `Regexp.last_match` reads the same match-data slot the perlish
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
# `
|
|
53
|
-
#
|
|
54
|
-
# return even where the surrounding flow has *proven* the match
|
|
55
|
-
# succeeded — re-introducing the `possible nil receiver` the `$~`
|
|
56
|
-
# narrowing exists to remove the moment the code reaches for the
|
|
57
|
-
# match through the method rather than the global.
|
|
43
|
+
# `Regexp.last_match` reads the same match-data slot the perlish `$~` global tracks. On a
|
|
44
|
+
# proven-match edge — the truthy branch of `if str =~ /re/`, the surviving path of `unless /re/ =~
|
|
45
|
+
# s; raise; end`, a `case`/`when` regex arm — the flow engine has already narrowed `$~` to a
|
|
46
|
+
# non-nil `MatchData` (see `Narrowing#regex_match_predicate_scopes`). Upstream RBS types
|
|
47
|
+
# `Regexp.last_match` as `() -> MatchData?` / `(int) -> String?`, so without this consult the call
|
|
48
|
+
# drops back to the nilable return even where the surrounding flow has *proven* the match
|
|
49
|
+
# succeeded — re-introducing the `possible nil receiver` the `$~` narrowing exists to remove the
|
|
50
|
+
# moment the code reaches for the match through the method rather than the global.
|
|
58
51
|
#
|
|
59
|
-
# Mirrors the global's narrowing exactly, so it rides the same
|
|
60
|
-
#
|
|
61
|
-
# that can re-run a match clears `$~`, and this consult clears
|
|
52
|
+
# Mirrors the global's narrowing exactly, so it rides the same `Scope#forget_match_globals`
|
|
53
|
+
# invalidation (an intervening call that can re-run a match clears `$~`, and this consult clears
|
|
62
54
|
# with it):
|
|
63
55
|
#
|
|
64
56
|
# * 0-arg -> `MatchData` (the narrowed `$~`)
|
|
65
|
-
# * `(N)` -> `String` when capture group N is unconditional on
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
# alternation-reachable group is nil at runtime even
|
|
69
|
-
# on a successful match).
|
|
57
|
+
# * `(N)` -> `String` when capture group N is unconditional on every successful match (the same
|
|
58
|
+
# set the `$N` globals narrow), else `String?` (an optional / alternation-reachable
|
|
59
|
+
# group is nil at runtime even on a successful match).
|
|
70
60
|
# * `(:name)` / `(0)` and other forms defer to RBS.
|
|
71
61
|
#
|
|
72
|
-
# Declines (returns nil -> RBS) whenever `$~` is NOT proven
|
|
73
|
-
#
|
|
74
|
-
#
|
|
75
|
-
#
|
|
76
|
-
# exactly as today — this never invents a match.
|
|
62
|
+
# Declines (returns nil -> RBS) whenever `$~` is NOT proven non-nil: no match edge established it,
|
|
63
|
+
# or a falsey edge bound it to `Constant[nil]`. Narrowing only on the proven edge keeps the bare
|
|
64
|
+
# `m = Regexp.last_match; m[...]` (no preceding match) firing exactly as today — this never invents
|
|
65
|
+
# a match.
|
|
77
66
|
def fold_last_match(context)
|
|
78
67
|
scope = context.scope
|
|
79
68
|
return nil if scope.nil?
|
|
@@ -88,18 +77,16 @@ module Rigor
|
|
|
88
77
|
fold_last_match_group(args.first, scope)
|
|
89
78
|
end
|
|
90
79
|
|
|
91
|
-
# Narrowed `$~` is a non-nil `Nominal[MatchData]`. A bare
|
|
92
|
-
#
|
|
80
|
+
# Narrowed `$~` is a non-nil `Nominal[MatchData]`. A bare `MatchData?` / `nil` / Dynamic binding is
|
|
81
|
+
# NOT a proven match.
|
|
93
82
|
def proven_match?(match_data)
|
|
94
83
|
match_data.is_a?(Type::Nominal) && match_data.class_name == "MatchData"
|
|
95
84
|
end
|
|
96
85
|
|
|
97
|
-
# `Regexp.last_match(N)` for a value-pinned positive Integer N.
|
|
98
|
-
#
|
|
99
|
-
#
|
|
100
|
-
#
|
|
101
|
-
# runtime on a success), so we surface `String?`. A non-constant
|
|
102
|
-
# or non-positive index defers to RBS.
|
|
86
|
+
# `Regexp.last_match(N)` for a value-pinned positive Integer N. Track the matching `$N` global the
|
|
87
|
+
# predicate edge already narrowed: present (`String`) means the group is unconditional, absent
|
|
88
|
+
# means it is optional / alternation-reachable (nil at runtime on a success), so we surface
|
|
89
|
+
# `String?`. A non-constant or non-positive index defers to RBS.
|
|
103
90
|
def fold_last_match_group(arg, scope)
|
|
104
91
|
return nil unless arg.is_a?(Type::Constant)
|
|
105
92
|
|
|
@@ -123,11 +110,10 @@ module Rigor
|
|
|
123
110
|
Type::Combinator.constant_of(Regexp.escape(str))
|
|
124
111
|
end
|
|
125
112
|
|
|
126
|
-
# `Regexp.new(pattern)` / `Regexp.new(pattern, opts)` — constructs
|
|
127
|
-
#
|
|
128
|
-
#
|
|
129
|
-
#
|
|
130
|
-
# invalid arguments decline through to the RBS tier.
|
|
113
|
+
# `Regexp.new(pattern)` / `Regexp.new(pattern, opts)` — constructs the pattern at inference time.
|
|
114
|
+
# Delegates to Ruby's real `Regexp.new` so all option forms (Integer flags, `true`/`false`, option
|
|
115
|
+
# strings) are handled without case-analysis; non-constant or invalid arguments decline through to
|
|
116
|
+
# the RBS tier.
|
|
131
117
|
def fold_new(args)
|
|
132
118
|
return nil if args.empty? || args.size > 2
|
|
133
119
|
|
|
@@ -6,20 +6,17 @@ require_relative "singleton_folding"
|
|
|
6
6
|
module Rigor
|
|
7
7
|
module Inference
|
|
8
8
|
module MethodDispatcher
|
|
9
|
-
# Folds `Set` constructor calls into `Constant[Set]` when all
|
|
10
|
-
# arguments are statically known.
|
|
9
|
+
# Folds `Set` constructor calls into `Constant[Set]` when all arguments are statically known.
|
|
11
10
|
#
|
|
12
|
-
# Ruby 3.2+ implements Set in C (`set.c`). The constructor is
|
|
13
|
-
#
|
|
14
|
-
# to global state.
|
|
11
|
+
# Ruby 3.2+ implements Set in C (`set.c`). The constructor is deterministic — it reads only its
|
|
12
|
+
# arguments and writes nothing to global state.
|
|
15
13
|
#
|
|
16
14
|
# === Supported methods
|
|
17
15
|
#
|
|
18
|
-
# * `Set[]` — variadic constructor; each argument must be a
|
|
19
|
-
# `Constant[T]`. Returns `Constant[Set]`.
|
|
16
|
+
# * `Set[]` — variadic constructor; each argument must be a `Constant[T]`. Returns `Constant[Set]`.
|
|
20
17
|
# * `Set.new` — zero-argument form; returns `Constant[Set.new]`.
|
|
21
|
-
# * `Set.new(tuple)` — the argument must be a `Tuple` whose
|
|
22
|
-
#
|
|
18
|
+
# * `Set.new(tuple)` — the argument must be a `Tuple` whose every element is a `Constant[T]`. Returns
|
|
19
|
+
# `Constant[Set]`.
|
|
23
20
|
#
|
|
24
21
|
# === Non-constant / unsupported cases
|
|
25
22
|
#
|