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
|
@@ -4,29 +4,22 @@ require "rbs"
|
|
|
4
4
|
|
|
5
5
|
module Rigor
|
|
6
6
|
module SigGen
|
|
7
|
-
# Pre-scans every `.rbs` file under the configured
|
|
8
|
-
# `signature_paths` to build a `qualified_class_name →
|
|
7
|
+
# Pre-scans every `.rbs` file under the configured `signature_paths` to build a `qualified_class_name →
|
|
9
8
|
# sig_file_path` map.
|
|
10
9
|
#
|
|
11
|
-
# ADR-14 path-mapper limitation surfaced repeatedly during
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
# `sig/rigor.rbs` declares `CLI::TypeOfCommand` and
|
|
16
|
-
# `CLI::TypeScanCommand`). The naive 1:1 mapper writes new
|
|
17
|
-
# files alongside the existing consolidated ones, producing
|
|
10
|
+
# ADR-14 path-mapper limitation surfaced repeatedly during the self-dogfood: the existing rigor `sig/`
|
|
11
|
+
# consolidates multiple `.rb` sources into one `.rbs` file (e.g. `sig/rigor/type.rbs` declares all 14
|
|
12
|
+
# `Type::*` classes, `sig/rigor.rbs` declares `CLI::TypeOfCommand` and `CLI::TypeScanCommand`). The naive
|
|
13
|
+
# 1:1 mapper writes new files alongside the existing consolidated ones, producing
|
|
18
14
|
# `RBS::DuplicatedMethodDefinition` errors at lookup time.
|
|
19
15
|
#
|
|
20
|
-
# The index lets {PathMapper} route a candidate to the
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
# class has no existing declaration anywhere under the
|
|
24
|
-
# signature tree.
|
|
16
|
+
# The index lets {PathMapper} route a candidate to the consolidated sig file when the class is already
|
|
17
|
+
# declared there, falling back to the 1:1 mirror only when the class has no existing declaration anywhere
|
|
18
|
+
# under the signature tree.
|
|
25
19
|
#
|
|
26
|
-
# First-found wins on duplicate declarations across files;
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
# the writer only needs one canonical target per class.
|
|
20
|
+
# First-found wins on duplicate declarations across files; RBS itself allows the same class to be declared
|
|
21
|
+
# in multiple files for additive member contributions, but the writer only needs one canonical target per
|
|
22
|
+
# class.
|
|
30
23
|
class LayoutIndex
|
|
31
24
|
# @param signature_paths [Array<String, Pathname>, nil]
|
|
32
25
|
# the `.rigor.yml`-configured signature directories.
|
|
@@ -84,8 +77,7 @@ module Rigor
|
|
|
84
77
|
_, _, decls = RBS::Parser.parse_signature(source)
|
|
85
78
|
record_decls(decls, [], rbs_path, accumulator)
|
|
86
79
|
rescue StandardError
|
|
87
|
-
# Bad RBS file — skip silently; the user's `rigor
|
|
88
|
-
# check` run will surface the real parse error
|
|
80
|
+
# Bad RBS file — skip silently; the user's `rigor check` run will surface the real parse error
|
|
89
81
|
# elsewhere.
|
|
90
82
|
end
|
|
91
83
|
|
|
@@ -4,24 +4,20 @@ module Rigor
|
|
|
4
4
|
module SigGen
|
|
5
5
|
# Per-method record produced by the generator.
|
|
6
6
|
#
|
|
7
|
-
# `classification` is one of the {Classification} constants;
|
|
8
|
-
#
|
|
9
|
-
# to that classification.
|
|
7
|
+
# `classification` is one of the {Classification} constants; the remaining fields are populated only when
|
|
8
|
+
# applicable to that classification.
|
|
10
9
|
#
|
|
11
10
|
# - `path` — the source `.rb` file the def came from.
|
|
12
|
-
# - `class_name` — qualified receiver class name (e.g.
|
|
13
|
-
# `"Foo::Bar"`). `nil` for top-level / DSL-block defs
|
|
11
|
+
# - `class_name` — qualified receiver class name (e.g. `"Foo::Bar"`). `nil` for top-level / DSL-block defs
|
|
14
12
|
# the MVP skips.
|
|
15
13
|
# - `method_name` — the def's `Symbol` name.
|
|
16
14
|
# - `kind` — `:instance` or `:singleton`.
|
|
17
|
-
# - `inferred_return` — `Rigor::Type` instance (or `nil`
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
# - `
|
|
22
|
-
#
|
|
23
|
-
# - `skip_reason` — one of {Classification::SKIP_DIAGNOSTIC_IDS}
|
|
24
|
-
# keys when classification is `:skipped`, else `nil`.
|
|
15
|
+
# - `inferred_return` — `Rigor::Type` instance (or `nil` when the inference pass disqualified the def).
|
|
16
|
+
# - `declared_return_rbs` — the existing RBS-declared return spelling, or `nil` when no RBS declares the
|
|
17
|
+
# method.
|
|
18
|
+
# - `rbs` — the rendered RBS one-liner the generator would emit (`nil` for skipped / equivalent rows).
|
|
19
|
+
# - `skip_reason` — one of {Classification::SKIP_DIAGNOSTIC_IDS} keys when classification is `:skipped`,
|
|
20
|
+
# else `nil`.
|
|
25
21
|
class MethodCandidate
|
|
26
22
|
attr_reader :path, :class_name, :method_name, :kind, :classification,
|
|
27
23
|
:inferred_return, :declared_return_rbs, :rbs, :skip_reason,
|
|
@@ -41,10 +37,9 @@ module Rigor
|
|
|
41
37
|
@skip_reason = skip_reason
|
|
42
38
|
@namespace_kinds = namespace_kinds.freeze
|
|
43
39
|
@class_shells = class_shells.freeze
|
|
44
|
-
# Qualified-class-name => superclass source token (e.g.
|
|
45
|
-
# `
|
|
46
|
-
#
|
|
47
|
-
# emits `class Bar < Base` for the leaf when present.
|
|
40
|
+
# Qualified-class-name => superclass source token (e.g. `{ "Foo::Bar" => "Base" }`). Only plain-constant
|
|
41
|
+
# superclasses appear; computed ones are absent. The Writer emits `class Bar < Base` for the leaf when
|
|
42
|
+
# present.
|
|
48
43
|
@class_superclasses = class_superclasses.freeze
|
|
49
44
|
freeze
|
|
50
45
|
end
|
|
@@ -10,37 +10,26 @@ require_relative "../inference/scope_indexer"
|
|
|
10
10
|
|
|
11
11
|
module Rigor
|
|
12
12
|
module SigGen
|
|
13
|
-
# ADR-14 slice 3 — caller-side argument-type observation
|
|
14
|
-
# collector.
|
|
13
|
+
# ADR-14 slice 3 — caller-side argument-type observation collector.
|
|
15
14
|
#
|
|
16
|
-
# Walks the user-supplied `--observe=PATH...` tree (default
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
# `Prism::CallNode` whose receiver types as a
|
|
21
|
-
# `Type::Nominal`. The {Generator} consumes the resulting
|
|
22
|
-
# map to render `--params=observed` RBS:
|
|
15
|
+
# Walks the user-supplied `--observe=PATH...` tree (default `spec/`), parses every `.rb` file with `Prism`,
|
|
16
|
+
# scope- indexes it the same way the main generator does, and records the per-call-site argument-type tuples
|
|
17
|
+
# for every `Prism::CallNode` whose receiver types as a `Type::Nominal`. The {Generator} consumes the
|
|
18
|
+
# resulting map to render `--params=observed` RBS:
|
|
23
19
|
#
|
|
24
|
-
# @return [Hash{[class_name, method_name] =>
|
|
25
|
-
# Array<Array<Rigor::Type>>}]
|
|
20
|
+
# @return [Hash{[class_name, method_name] => Array<Array<Rigor::Type>>}]
|
|
26
21
|
#
|
|
27
|
-
# ADR-5 clause 2 compliance: the observed union is the
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
# surfaces the data; the default `--params=untyped` keeps
|
|
32
|
-
# the observation inert until the user opts in.
|
|
22
|
+
# ADR-5 clause 2 compliance: the observed union is the MOST PERMISSIVE parameter contract the existing
|
|
23
|
+
# callers prove sufficient — by construction it accepts every type any caller has already passed. The
|
|
24
|
+
# collector only surfaces the data; the default `--params=untyped` keeps the observation inert until the
|
|
25
|
+
# user opts in.
|
|
33
26
|
#
|
|
34
27
|
# MVP scope:
|
|
35
|
-
# - Explicit-receiver calls only (`foo.bar(args)`). Implicit-
|
|
36
|
-
#
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
# -
|
|
40
|
-
# (e.g. `(some_dynamic).bar(...)`) are skipped — the
|
|
41
|
-
# collector cannot attribute them to a specific class.
|
|
42
|
-
# - Zero-argument calls give no observation; methods are
|
|
43
|
-
# matched by `(class_name, method_name)` only.
|
|
28
|
+
# - Explicit-receiver calls only (`foo.bar(args)`). Implicit-self calls inside class bodies and RSpec-style
|
|
29
|
+
# `let` / `subject` bindings ride on slice 5's optional `rigor-rspec` integration.
|
|
30
|
+
# - Calls whose receiver does not type as a `Type::Nominal` (e.g. `(some_dynamic).bar(...)`) are skipped —
|
|
31
|
+
# the collector cannot attribute them to a specific class.
|
|
32
|
+
# - Zero-argument calls give no observation; methods are matched by `(class_name, method_name)` only.
|
|
44
33
|
class ObservationCollector # rubocop:disable Metrics/ClassLength
|
|
45
34
|
# @param configuration [Rigor::Configuration]
|
|
46
35
|
# @param paths [Array<String>] observe paths (files /
|
|
@@ -104,11 +93,9 @@ module Rigor
|
|
|
104
93
|
walk_calls(parse_result.value, scope_index, bindings, observations)
|
|
105
94
|
end
|
|
106
95
|
|
|
107
|
-
# Pre-walks `@source_paths` to collect every qualified
|
|
108
|
-
#
|
|
109
|
-
#
|
|
110
|
-
# `Foo.new` and `Foo` resolve to the right singleton carrier
|
|
111
|
-
# even when no RBS sig describes `Foo` yet.
|
|
96
|
+
# Pre-walks `@source_paths` to collect every qualified class / module declaration. The result seeds the
|
|
97
|
+
# `discovered_classes` table on each observe-tree scope so `Foo.new` and `Foo` resolve to the right
|
|
98
|
+
# singleton carrier even when no RBS sig describes `Foo` yet.
|
|
112
99
|
def preindex_source_classes
|
|
113
100
|
accumulator = {}
|
|
114
101
|
resolve_paths(@source_paths).each { |path| harvest_classes_from(path, accumulator) }
|
|
@@ -122,8 +109,7 @@ module Rigor
|
|
|
122
109
|
|
|
123
110
|
walk_class_decls(parse_result.value, [], accumulator)
|
|
124
111
|
rescue StandardError
|
|
125
|
-
# Source-side harvest failures are tolerated silently
|
|
126
|
-
# — the collector still runs on whichever files
|
|
112
|
+
# Source-side harvest failures are tolerated silently — the collector still runs on whichever files
|
|
127
113
|
# parsed cleanly.
|
|
128
114
|
end
|
|
129
115
|
|
|
@@ -180,13 +166,10 @@ module Rigor
|
|
|
180
166
|
observations[key] << observation
|
|
181
167
|
end
|
|
182
168
|
|
|
183
|
-
# ADR-14 follow-up (A): `.new` → `:initialize` routing.
|
|
184
|
-
# `MethodCatalog
|
|
185
|
-
# `
|
|
186
|
-
#
|
|
187
|
-
# to `MethodCatalog#initialize(path: ...)`. Route the
|
|
188
|
-
# observation under `[class_name, :initialize]` so the
|
|
189
|
-
# initialize-stub renderer can consult it.
|
|
169
|
+
# ADR-14 follow-up (A): `.new` → `:initialize` routing. `MethodCatalog.new(path: ...)` types its receiver
|
|
170
|
+
# as `Type::Singleton[MethodCatalog]` and its call name as `:new`, but the *implicit* effect at runtime is
|
|
171
|
+
# a call to `MethodCatalog#initialize(path: ...)`. Route the observation under `[class_name, :initialize]`
|
|
172
|
+
# so the initialize-stub renderer can consult it.
|
|
190
173
|
def observation_key(call_node, receiver_type)
|
|
191
174
|
if receiver_type.is_a?(Type::Singleton) && call_node.name == :new
|
|
192
175
|
[receiver_type.class_name, :initialize]
|
|
@@ -195,20 +178,15 @@ module Rigor
|
|
|
195
178
|
end
|
|
196
179
|
end
|
|
197
180
|
|
|
198
|
-
# ADR-14 slice 5 — RSpec-aware receiver typing.
|
|
199
|
-
#
|
|
200
|
-
# `bindings` map (built by {#collect_rspec_bindings})
|
|
201
|
-
# before falling back to ordinary `scope.type_of`. The
|
|
181
|
+
# ADR-14 slice 5 — RSpec-aware receiver typing. Resolves a CallNode receiver against the collected
|
|
182
|
+
# `bindings` map (built by {#collect_rspec_bindings}) before falling back to ordinary `scope.type_of`. The
|
|
202
183
|
# three RSpec-shaped receivers we recognise:
|
|
203
184
|
#
|
|
204
|
-
# - Bare-name CallNode (`subject`, `other`, ...) whose
|
|
205
|
-
# name matches a `subject` / `let(:name)` binding —
|
|
185
|
+
# - Bare-name CallNode (`subject`, `other`, ...) whose name matches a `subject` / `let(:name)` binding —
|
|
206
186
|
# return the binding's recorded type.
|
|
207
|
-
# - `described_class.new(...)` chain — when the
|
|
208
|
-
# surrounding `describe Foo do … end` resolved `Foo`,
|
|
187
|
+
# - `described_class.new(...)` chain — when the surrounding `describe Foo do … end` resolved `Foo`,
|
|
209
188
|
# return `Type::Nominal[Foo]`.
|
|
210
|
-
# - Anything else — pass through to `scope.type_of`,
|
|
211
|
-
# matching slice-3 behaviour.
|
|
189
|
+
# - Anything else — pass through to `scope.type_of`, matching slice-3 behaviour.
|
|
212
190
|
def resolve_receiver_type(receiver, scope, bindings)
|
|
213
191
|
return resolve_described_class_new(bindings) if described_class_new?(receiver)
|
|
214
192
|
return bindings[receiver.name] if bound_call?(receiver, bindings)
|
|
@@ -246,21 +224,14 @@ module Rigor
|
|
|
246
224
|
node.block.nil?
|
|
247
225
|
end
|
|
248
226
|
|
|
249
|
-
# Walks the spec file for `describe X do … end` /
|
|
250
|
-
# `
|
|
251
|
-
#
|
|
252
|
-
# Returns a flat map `{ binding_name (Symbol) => Type }`
|
|
253
|
-
# plus a synthetic `:described_class` slot keyed off
|
|
254
|
-
# the nearest enclosing `describe`.
|
|
227
|
+
# Walks the spec file for `describe X do … end` / `RSpec.describe X do … end` blocks plus the
|
|
228
|
+
# `subject` / `let(:name)` declarations inside them. Returns a flat map `{ binding_name (Symbol) => Type }`
|
|
229
|
+
# plus a synthetic `:described_class` slot keyed off the nearest enclosing `describe`.
|
|
255
230
|
#
|
|
256
|
-
# The recogniser is intentionally lightweight: it does
|
|
257
|
-
#
|
|
258
|
-
# `
|
|
259
|
-
#
|
|
260
|
-
# remainder of the walk; same-name `let` bindings are
|
|
261
|
-
# last-wins. This matches the typical one-spec-file
|
|
262
|
-
# shape ADR-14 slice 5 targets without re-implementing
|
|
263
|
-
# the `rigor-rspec` plugin's full scope analyser.
|
|
231
|
+
# The recogniser is intentionally lightweight: it does not enforce RSpec scope rules across `describe` /
|
|
232
|
+
# `context` blocks. Nested `describe` declarations overwrite the outer `described_class` for the
|
|
233
|
+
# remainder of the walk; same-name `let` bindings are last-wins. This matches the typical one-spec-file
|
|
234
|
+
# shape ADR-14 slice 5 targets without re-implementing the `rigor-rspec` plugin's full scope analyser.
|
|
264
235
|
def collect_rspec_bindings(root, scope_index)
|
|
265
236
|
bindings = {}
|
|
266
237
|
walk_rspec_bindings(root, bindings, scope_index)
|
|
@@ -339,12 +310,9 @@ module Rigor
|
|
|
339
310
|
end
|
|
340
311
|
end
|
|
341
312
|
|
|
342
|
-
# ADR-14 follow-up (B): walks a call's argument list
|
|
343
|
-
#
|
|
344
|
-
#
|
|
345
|
-
# forwarded / block arguments still abort the
|
|
346
|
-
# observation (`nil`) — those don't map cleanly to a
|
|
347
|
-
# single per-position type the renderer can union.
|
|
313
|
+
# ADR-14 follow-up (B): walks a call's argument list separating positional from keyword arguments and
|
|
314
|
+
# returning an {ObservedCall} carrier. Splat / forwarded / block arguments still abort the observation
|
|
315
|
+
# (`nil`) — those don't map cleanly to a single per-position type the renderer can union.
|
|
348
316
|
def collect_args(call_node, scope)
|
|
349
317
|
positional = []
|
|
350
318
|
keyword = {}
|
|
@@ -2,27 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
module Rigor
|
|
4
4
|
module SigGen
|
|
5
|
-
# Per-call-site argument observation produced by
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
# were silently skipped in that shape.
|
|
11
|
-
# The new shape carries positional and keyword arg types
|
|
12
|
-
# in parallel so the per-position / per-keyword unions
|
|
13
|
-
# can each be reconstructed independently.
|
|
5
|
+
# Per-call-site argument observation produced by {ObservationCollector}. ADR-14 follow-up: the earlier MVP
|
|
6
|
+
# shape (`Array[Type]` of positional types only) could not represent keyword arguments — keyword calls like
|
|
7
|
+
# `MethodCatalog.new(path: ..., mutating_selectors: ...)` were silently skipped in that shape. The new shape
|
|
8
|
+
# carries positional and keyword arg types in parallel so the per-position / per-keyword unions can each be
|
|
9
|
+
# reconstructed independently.
|
|
14
10
|
#
|
|
15
11
|
# The carrier is intentionally minimal:
|
|
16
|
-
# - `positional` — frozen Array of `Rigor::Type` per
|
|
17
|
-
#
|
|
18
|
-
# - `keyword` — frozen Hash mapping each keyword
|
|
19
|
-
# argument's Symbol name to its `Rigor::Type`.
|
|
12
|
+
# - `positional` — frozen Array of `Rigor::Type` per positional argument, in call-site order.
|
|
13
|
+
# - `keyword` — frozen Hash mapping each keyword argument's Symbol name to its `Rigor::Type`.
|
|
20
14
|
#
|
|
21
|
-
# Generator-side callers also accept a legacy shape
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
# this carrier existed; `ObservedCall.from(...)` does the
|
|
25
|
-
# lift.
|
|
15
|
+
# Generator-side callers also accept a legacy shape (plain Array of types) for backward compatibility with
|
|
16
|
+
# specs that constructed observations directly before this carrier existed; `ObservedCall.from(...)` does
|
|
17
|
+
# the lift.
|
|
26
18
|
class ObservedCall
|
|
27
19
|
attr_reader :positional, :keyword
|
|
28
20
|
|
|
@@ -45,11 +37,9 @@ module Rigor
|
|
|
45
37
|
[ObservedCall, positional, keyword].hash
|
|
46
38
|
end
|
|
47
39
|
|
|
48
|
-
# Lifts the legacy plain-Array shape into an
|
|
49
|
-
# `
|
|
50
|
-
#
|
|
51
|
-
# observations-normalisation pass so spec fixtures
|
|
52
|
-
# written against the slice-3 surface keep working.
|
|
40
|
+
# Lifts the legacy plain-Array shape into an `ObservedCall` carrier. Already-lifted values pass through
|
|
41
|
+
# unchanged. Used by `Generator#initialize`'s observations-normalisation pass so spec fixtures written
|
|
42
|
+
# against the slice-3 surface keep working.
|
|
53
43
|
def self.from(value)
|
|
54
44
|
case value
|
|
55
45
|
when ObservedCall then value
|
|
@@ -2,33 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
module Rigor
|
|
4
4
|
module SigGen
|
|
5
|
-
# Maps a source `.rb` file to its target `.rbs` sig file
|
|
6
|
-
# under the project's signature tree.
|
|
5
|
+
# Maps a source `.rb` file to its target `.rbs` sig file under the project's signature tree.
|
|
7
6
|
#
|
|
8
7
|
# ADR-14 § "Output layout":
|
|
9
|
-
# - `--write` MUST NOT touch files outside
|
|
10
|
-
#
|
|
11
|
-
# - The first slice supports one source file → one RBS
|
|
12
|
-
# file; multi-class files emit one RBS containing both
|
|
8
|
+
# - `--write` MUST NOT touch files outside `configuration.signature_paths` (default `sig/`).
|
|
9
|
+
# - The first slice supports one source file → one RBS file; multi-class files emit one RBS containing both
|
|
13
10
|
# classes (handled by the {Writer}, not here).
|
|
14
11
|
#
|
|
15
|
-
# The mapping convention mirrors the Ruby community
|
|
16
|
-
#
|
|
17
|
-
# of `configuration.
|
|
18
|
-
# extension, and place the result under the first entry of
|
|
19
|
-
# `configuration.signature_paths` (typically `"sig"`).
|
|
12
|
+
# The mapping convention mirrors the Ruby community default: strip the source root prefix (the first entry
|
|
13
|
+
# of `configuration.paths`, typically `"lib"`), swap the extension, and place the result under the first
|
|
14
|
+
# entry of `configuration.signature_paths` (typically `"sig"`).
|
|
20
15
|
#
|
|
21
|
-
# ADR-14 follow-up: when a class is already declared in
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
# writer updates the consolidated declaration instead of
|
|
26
|
-
# creating a duplicate at the 1:1 mirror path.
|
|
16
|
+
# ADR-14 follow-up: when a class is already declared in an existing consolidated sig file (e.g.
|
|
17
|
+
# `sig/rigor/type.rbs` holds all `Rigor::Type::*` classes), the optional `LayoutIndex` re-routes the target
|
|
18
|
+
# to that file so the writer updates the consolidated declaration instead of creating a duplicate at the 1:1
|
|
19
|
+
# mirror path.
|
|
27
20
|
#
|
|
28
|
-
# When the source path is not under any configured source
|
|
29
|
-
#
|
|
30
|
-
# outside `lib/`), the full relative path is preserved
|
|
31
|
-
# under the sig root.
|
|
21
|
+
# When the source path is not under any configured source root (e.g. files supplied directly on the CLI
|
|
22
|
+
# from outside `lib/`), the full relative path is preserved under the sig root.
|
|
32
23
|
class PathMapper
|
|
33
24
|
# @param configuration [Rigor::Configuration]
|
|
34
25
|
# @param project_root [String, Pathname] (defaults to `Dir.pwd`)
|
|
@@ -63,9 +54,8 @@ module Rigor
|
|
|
63
54
|
@layout_index.file_for(class_name)
|
|
64
55
|
end
|
|
65
56
|
|
|
66
|
-
# The directory `--write` is allowed to create / modify.
|
|
67
|
-
#
|
|
68
|
-
# configured signature tree before touching the disk.
|
|
57
|
+
# The directory `--write` is allowed to create / modify. Used by callers to assert the target stays inside
|
|
58
|
+
# the configured signature tree before touching the disk.
|
|
69
59
|
def sig_root_dir
|
|
70
60
|
@sig_root_dir ||= @project_root / sig_root_name
|
|
71
61
|
end
|
|
@@ -76,8 +66,7 @@ module Rigor
|
|
|
76
66
|
path = Pathname(source_path)
|
|
77
67
|
return path unless path.absolute?
|
|
78
68
|
|
|
79
|
-
# Both sides go through realpath so macOS `/tmp` vs
|
|
80
|
-
# `/private/tmp` (and any other symlinked project
|
|
69
|
+
# Both sides go through realpath so macOS `/tmp` vs `/private/tmp` (and any other symlinked project
|
|
81
70
|
# root) compare cleanly.
|
|
82
71
|
path.realpath.relative_path_from(@project_root.realpath)
|
|
83
72
|
rescue ArgumentError, Errno::ENOENT
|
|
@@ -95,9 +84,8 @@ module Rigor
|
|
|
95
84
|
components.empty? ? Pathname("") : Pathname(components.join(File::SEPARATOR))
|
|
96
85
|
end
|
|
97
86
|
|
|
98
|
-
# `Configuration` resolves `paths:` and `signature_paths:`
|
|
99
|
-
#
|
|
100
|
-
# for the mapping (`/abs/lib` → `lib`, `/abs/app` → `app`).
|
|
87
|
+
# `Configuration` resolves `paths:` and `signature_paths:` to absolute Strings. We only need the trailing
|
|
88
|
+
# basename for the mapping (`/abs/lib` → `lib`, `/abs/app` → `app`).
|
|
101
89
|
def source_root_name
|
|
102
90
|
@source_root_name ||= begin
|
|
103
91
|
path = @configuration.paths.first
|
|
@@ -9,16 +9,12 @@ module Rigor
|
|
|
9
9
|
# Output formatter for `rigor sig-gen`.
|
|
10
10
|
#
|
|
11
11
|
# Supports three modes:
|
|
12
|
-
# - `:print` (default) — RBS skeletons grouped by source
|
|
13
|
-
# file and class declaration, ready for the user to
|
|
12
|
+
# - `:print` (default) — RBS skeletons grouped by source file and class declaration, ready for the user to
|
|
14
13
|
# paste into `sig/<path>.rbs`.
|
|
15
|
-
# - `:diff` — a unified-style diff comparing the existing
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
# `--write` merge.
|
|
20
|
-
# - `:json` — machine-readable payload with the same
|
|
21
|
-
# classification table as `:print`.
|
|
14
|
+
# - `:diff` — a unified-style diff comparing the existing RBS spelling (if any) against the inferred
|
|
15
|
+
# spelling. The MVP renders a minimal "- declared / + inferred" block; full per-file diffing arrives with
|
|
16
|
+
# slice 2's `--write` merge.
|
|
17
|
+
# - `:json` — machine-readable payload with the same classification table as `:print`.
|
|
22
18
|
class Renderer
|
|
23
19
|
def initialize(out:)
|
|
24
20
|
@out = out
|
|
@@ -107,10 +103,8 @@ module Rigor
|
|
|
107
103
|
|
|
108
104
|
public
|
|
109
105
|
|
|
110
|
-
# Renders the per-source-file outcomes of a `--write`
|
|
111
|
-
#
|
|
112
|
-
# path's reporting surface is action-oriented (created
|
|
113
|
-
# / updated / skipped) rather than candidate-oriented.
|
|
106
|
+
# Renders the per-source-file outcomes of a `--write` run. Distinct from {#render} because the write
|
|
107
|
+
# path's reporting surface is action-oriented (created / updated / skipped) rather than candidate-oriented.
|
|
114
108
|
def render_write(results:, format:)
|
|
115
109
|
case format
|
|
116
110
|
when "json" then render_write_json(results)
|
|
@@ -5,30 +5,20 @@ require_relative "../type"
|
|
|
5
5
|
|
|
6
6
|
module Rigor
|
|
7
7
|
module SigGen
|
|
8
|
-
# ADR-14 follow-up to the dogfood findings: when the
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
# `
|
|
12
|
-
# `
|
|
13
|
-
# `erase_to_rbs` renders just `Array` / `Hash` / etc. While
|
|
14
|
-
# RBS itself accepts the bare form, downstream consumers
|
|
15
|
-
# (Steep, IDE plugins, gem-published `sig/` trees) expect
|
|
16
|
-
# the elaborated `Array[untyped]` / `Hash[untyped, untyped]`
|
|
17
|
-
# spelling.
|
|
8
|
+
# ADR-14 follow-up to the dogfood findings: when the inference engine produces a `Type::Nominal` for a class
|
|
9
|
+
# that requires type parameters (`Array`, `Hash`, `Set`, `Range`, `Enumerable`, `Enumerator`, ...) with an
|
|
10
|
+
# empty `type_args` array, the carrier is structurally valid but `erase_to_rbs` renders just `Array` /
|
|
11
|
+
# `Hash` / etc. While RBS itself accepts the bare form, downstream consumers (Steep, IDE plugins,
|
|
12
|
+
# gem-published `sig/` trees) expect the elaborated `Array[untyped]` / `Hash[untyped, untyped]` spelling.
|
|
18
13
|
#
|
|
19
|
-
# This module walks a `Rigor::Type` tree and rebuilds every
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
# `
|
|
23
|
-
#
|
|
24
|
-
# distinct from the raw form, but `accepts(other) == accepts(other)`
|
|
25
|
-
# holds because the gradual mode treats `Dynamic[top]`
|
|
26
|
-
# arguments as covering anything.
|
|
14
|
+
# This module walks a `Rigor::Type` tree and rebuilds every raw `Nominal[C]` for a generic `C` into
|
|
15
|
+
# `Nominal[C, [Dynamic, ...]]` where the arity comes from `Reflection.class_type_param_names`. The
|
|
16
|
+
# transformation is purely cosmetic — the resulting carrier is structurally distinct from the raw form, but
|
|
17
|
+
# `accepts(other) == accepts(other)` holds because the gradual mode treats `Dynamic[top]` arguments as
|
|
18
|
+
# covering anything.
|
|
27
19
|
#
|
|
28
|
-
# The module is sig-gen-local; the broader question of
|
|
29
|
-
#
|
|
30
|
-
# construct generics with explicit type_args is queued as
|
|
31
|
-
# an ADR-14 follow-up.
|
|
20
|
+
# The module is sig-gen-local; the broader question of whether the inference engine itself should always
|
|
21
|
+
# construct generics with explicit type_args is queued as an ADR-14 follow-up.
|
|
32
22
|
module TypeElaborator
|
|
33
23
|
# @param type [Rigor::Type]
|
|
34
24
|
# @param environment [Rigor::Environment]
|
|
@@ -70,12 +60,9 @@ module Rigor
|
|
|
70
60
|
end
|
|
71
61
|
|
|
72
62
|
def self.elaborate_hash_shape(type, _environment, _arity_cache)
|
|
73
|
-
# HashShape's element types are read-only on the carrier;
|
|
74
|
-
#
|
|
75
|
-
#
|
|
76
|
-
# routes top-level returns through here for now —
|
|
77
|
-
# nested HashShape elaboration ships as a follow-up if
|
|
78
|
-
# the need surfaces.
|
|
63
|
+
# HashShape's element types are read-only on the carrier; rebuilding them would need going through the
|
|
64
|
+
# per-pair required/optional/read-only machinery. Sig-gen only routes top-level returns through here for
|
|
65
|
+
# now — nested HashShape elaboration ships as a follow-up if the need surfaces.
|
|
79
66
|
type
|
|
80
67
|
end
|
|
81
68
|
|
|
@@ -4,24 +4,16 @@ module Rigor
|
|
|
4
4
|
module SigGen
|
|
5
5
|
# Per-source-file outcome of a `rigor sig-gen --write` run.
|
|
6
6
|
#
|
|
7
|
-
# The writer reports back what it did so the renderer (and
|
|
8
|
-
#
|
|
9
|
-
# surface user-authored-skip decisions without having to
|
|
10
|
-
# re-parse the produced files.
|
|
7
|
+
# The writer reports back what it did so the renderer (and the CLI's exit-status logic) can summarise
|
|
8
|
+
# actions and surface user-authored-skip decisions without having to re-parse the produced files.
|
|
11
9
|
#
|
|
12
10
|
# - `source_path` — original `.rb` file.
|
|
13
|
-
# - `target_path` — `.rbs` file the writer was responsible
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
# - `
|
|
18
|
-
# `:
|
|
19
|
-
# - `applied` — the {MethodCandidate}s that actually
|
|
20
|
-
# landed on disk.
|
|
21
|
-
# - `skipped` — the {MethodCandidate}s the writer
|
|
22
|
-
# declined (e.g. tighter-return without `--overwrite`).
|
|
23
|
-
# Each entry pairs the candidate with a skip reason
|
|
24
|
-
# keyword (`:user_authored`).
|
|
11
|
+
# - `target_path` — `.rbs` file the writer was responsible for (`nil` when the source path falls outside
|
|
12
|
+
# the project signature tree, in which case `action` is `:skipped_outside_sig_root`).
|
|
13
|
+
# - `action` — one of `:created` / `:updated` / `:noop` / `:skipped_outside_sig_root`.
|
|
14
|
+
# - `applied` — the {MethodCandidate}s that actually landed on disk.
|
|
15
|
+
# - `skipped` — the {MethodCandidate}s the writer declined (e.g. tighter-return without `--overwrite`). Each
|
|
16
|
+
# entry pairs the candidate with a skip reason keyword (`:user_authored`).
|
|
25
17
|
class WriteResult
|
|
26
18
|
attr_reader :source_path, :target_path, :action, :applied, :skipped
|
|
27
19
|
|