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
data/lib/rigor/environment.rb
CHANGED
|
@@ -21,36 +21,28 @@ require_relative "type_node/name_scope"
|
|
|
21
21
|
require_relative "type_node/resolver_chain"
|
|
22
22
|
|
|
23
23
|
module Rigor
|
|
24
|
-
# The engine's view of the type universe outside the current scope.
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
# constant-folding tiers cannot answer.
|
|
24
|
+
# The engine's view of the type universe outside the current scope. Slice 1 exposed only the class
|
|
25
|
+
# registry; Slice 4 added the RBS loader, which threads through ExpressionTyper and MethodDispatcher to
|
|
26
|
+
# type constant references and method calls that the literal-typer and constant-folding tiers cannot
|
|
27
|
+
# answer.
|
|
29
28
|
#
|
|
30
29
|
# See docs/internal-spec/inference-engine.md for the binding contract.
|
|
31
30
|
class Environment # rubocop:disable Metrics/ClassLength
|
|
32
31
|
DEFAULT_PROJECT_SIG_DIR = "sig"
|
|
33
32
|
private_constant :DEFAULT_PROJECT_SIG_DIR
|
|
34
33
|
|
|
35
|
-
# Slice A stdlib expansion. Stdlib libraries that
|
|
36
|
-
# `
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
# `
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
# (`pathname`, `optparse`, `json`, `yaml`, `fileutils`,
|
|
44
|
-
# `tempfile`, `uri`, `logger`, `date`) plus the analyzer-
|
|
45
|
-
# adjacent gems shipping their own RBS in this bundle
|
|
46
|
-
# (`prism`, `rbs`). On hosts where one of these libraries is
|
|
47
|
-
# not installed, the loader silently drops it.
|
|
34
|
+
# Slice A stdlib expansion. Stdlib libraries that `Environment.for_project` loads on top of RBS core
|
|
35
|
+
# unless the caller passes an explicit `libraries:` array. Each entry MUST be a stdlib library name
|
|
36
|
+
# accepted by `RBS::EnvironmentLoader#has_library?`; unknown libraries MUST fail-soft
|
|
37
|
+
# (`RbsLoader#build_env` already filters through `has_library?`). The default set covers the common
|
|
38
|
+
# stdlib surface a Ruby program is likely to import (`pathname`, `optparse`, `json`, `yaml`, `fileutils`,
|
|
39
|
+
# `tempfile`, `uri`, `logger`, `date`) plus the analyzer-adjacent gems shipping their own RBS in this
|
|
40
|
+
# bundle (`prism`, `rbs`). On hosts where one of these libraries is not installed, the loader silently
|
|
41
|
+
# drops it.
|
|
48
42
|
#
|
|
49
|
-
# Callers MAY add to the default by passing
|
|
50
|
-
# `
|
|
51
|
-
# `
|
|
52
|
-
# a strictly RBS-core view MUST construct an `RbsLoader`
|
|
53
|
-
# directly instead of going through `for_project`.
|
|
43
|
+
# Callers MAY add to the default by passing `libraries: %w[csv ...]`; the explicit list is appended to
|
|
44
|
+
# `DEFAULT_LIBRARIES` and de-duplicated. Callers that need a strictly RBS-core view MUST construct an
|
|
45
|
+
# `RbsLoader` directly instead of going through `for_project`.
|
|
54
46
|
DEFAULT_LIBRARIES = %w[
|
|
55
47
|
pathname optparse json yaml fileutils tempfile tmpdir
|
|
56
48
|
stringio forwardable digest securerandom
|
|
@@ -65,11 +57,10 @@ module Rigor
|
|
|
65
57
|
prism rbs
|
|
66
58
|
].freeze
|
|
67
59
|
|
|
68
|
-
# ADR-72 — a Gemfile.lock gem name mapped to the opt-in plugin id
|
|
69
|
-
# that
|
|
70
|
-
#
|
|
71
|
-
#
|
|
72
|
-
# error). Keyed on the gem name `RbsCoverageReport` reports.
|
|
60
|
+
# ADR-72 — a Gemfile.lock gem name mapped to the opt-in plugin id that ships the SAME core-ext RBS. When
|
|
61
|
+
# that plugin is loaded the auto-overlay for the gem stands down, so the two never both declare the
|
|
62
|
+
# methods (which would raise a duplicate-declaration error). Keyed on the gem name `RbsCoverageReport`
|
|
63
|
+
# reports.
|
|
73
64
|
GEM_OVERLAY_PLUGIN_IDS = { "activesupport" => "activesupport-core-ext" }.freeze
|
|
74
65
|
|
|
75
66
|
attr_reader :class_registry, :rbs_loader, :plugin_registry, :dependency_source_index,
|
|
@@ -77,24 +68,17 @@ module Rigor
|
|
|
77
68
|
:synthetic_method_index, :project_patched_methods
|
|
78
69
|
|
|
79
70
|
# @param class_registry [Rigor::Environment::ClassRegistry]
|
|
80
|
-
# @param rbs_loader [Rigor::Environment::RbsLoader, nil] when nil the
|
|
81
|
-
#
|
|
82
|
-
#
|
|
83
|
-
#
|
|
84
|
-
#
|
|
85
|
-
#
|
|
86
|
-
#
|
|
87
|
-
#
|
|
88
|
-
#
|
|
89
|
-
#
|
|
90
|
-
# default), no
|
|
91
|
-
# participates — useful for tests, the `Environment.default`
|
|
92
|
-
# facade, and analyses that don't load plugins.
|
|
93
|
-
# @param dependency_source_index [Rigor::Analysis::DependencySourceInference::Index, nil]
|
|
94
|
-
# ADR-10 slice 2b-ii. The per-run index of opt-in gem
|
|
95
|
-
# sources the dispatcher consults BELOW RBS dispatch.
|
|
96
|
-
# When nil (the default), no dep-source contribution
|
|
97
|
-
# participates and the dispatcher tier is a no-op.
|
|
71
|
+
# @param rbs_loader [Rigor::Environment::RbsLoader, nil] when nil the environment is "RBS-blind"; useful
|
|
72
|
+
# in tests that want to assert how the engine behaves without RBS data. The default Environment wires
|
|
73
|
+
# the shared core loader, which is itself lazy: requesting an environment instance does NOT load RBS
|
|
74
|
+
# until a method or class query actually consults the loader.
|
|
75
|
+
# @param plugin_registry [Rigor::Plugin::Registry, nil] v0.1.1 Track 2 slice 7. The per-run plugin
|
|
76
|
+
# registry the inference engine consults at call sites for plugin `dynamic_return` rules. When nil
|
|
77
|
+
# (the default), no plugin-level return-type contribution participates — useful for tests, the
|
|
78
|
+
# `Environment.default` facade, and analyses that don't load plugins.
|
|
79
|
+
# @param dependency_source_index [Rigor::Analysis::DependencySourceInference::Index, nil] ADR-10 slice
|
|
80
|
+
# 2b-ii. The per-run index of opt-in gem sources the dispatcher consults BELOW RBS dispatch. When nil
|
|
81
|
+
# (the default), no dep-source contribution participates and the dispatcher tier is a no-op.
|
|
98
82
|
def initialize(class_registry: ClassRegistry.default, rbs_loader: nil, # rubocop:disable Metrics/ParameterLists
|
|
99
83
|
plugin_registry: nil, dependency_source_index: nil,
|
|
100
84
|
rbs_extended_reporter: nil, boundary_cross_reporter: nil,
|
|
@@ -105,11 +89,9 @@ module Rigor
|
|
|
105
89
|
@rbs_loader = rbs_loader
|
|
106
90
|
@plugin_registry = plugin_registry
|
|
107
91
|
@dependency_source_index = dependency_source_index
|
|
108
|
-
# ADR-pending — reporters live in a mutable container so
|
|
109
|
-
#
|
|
110
|
-
#
|
|
111
|
-
# existing `#rbs_extended_reporter` / `#boundary_cross_reporter`
|
|
112
|
-
# accessors below preserve the public lookup shape.
|
|
92
|
+
# ADR-pending — reporters live in a mutable container so long-lived integrations (LSP `ProjectContext`)
|
|
93
|
+
# can swap them per `Runner.run` without rebuilding the env. The existing `#rbs_extended_reporter` /
|
|
94
|
+
# `#boundary_cross_reporter` accessors below preserve the public lookup shape.
|
|
113
95
|
@reporters = Reporters.new(
|
|
114
96
|
rbs_extended: rbs_extended_reporter,
|
|
115
97
|
boundary_cross: boundary_cross_reporter,
|
|
@@ -117,19 +99,13 @@ module Rigor
|
|
|
117
99
|
)
|
|
118
100
|
@synthetic_method_index = synthetic_method_index || Inference::SyntheticMethodIndex::EMPTY
|
|
119
101
|
@project_patched_methods = project_patched_methods || Inference::ProjectPatchedMethods::EMPTY
|
|
120
|
-
# ADR-20 slice 2c + 2e — the per-env HKT registry
|
|
121
|
-
#
|
|
122
|
-
#
|
|
123
|
-
# the
|
|
124
|
-
# with the
|
|
125
|
-
#
|
|
126
|
-
# the RBS
|
|
127
|
-
# (defined below) MEMOIZES the result of merging the
|
|
128
|
-
# base with the RBS scan so the scan is paid at most
|
|
129
|
-
# once per Environment lifetime — and only when first
|
|
130
|
-
# consulted, leaving fast paths like `rigor check
|
|
131
|
-
# --cache-stats --no-stats` from doing the RBS env
|
|
132
|
-
# build at all.
|
|
102
|
+
# ADR-20 slice 2c + 2e — the per-env HKT registry consulted by the reducer when resolving `Type::App`
|
|
103
|
+
# carriers. Defaults to {Inference::HktRegistry::EMPTY}; the {.default} / {.for_project} class methods
|
|
104
|
+
# seed it with the bundled builtins (`json::value`, …) plus any `%a{rigor:v1:hkt_register /
|
|
105
|
+
# hkt_define}` annotations the RBS loader exposes. The hkt_registry getter (defined below) MEMOIZES
|
|
106
|
+
# the result of merging the base with the RBS scan so the scan is paid at most once per Environment
|
|
107
|
+
# lifetime — and only when first consulted, leaving fast paths like `rigor check --cache-stats
|
|
108
|
+
# --no-stats` from doing the RBS env build at all.
|
|
133
109
|
@hkt_registry_base = hkt_registry || Inference::HktRegistry::EMPTY
|
|
134
110
|
@hkt_registry_holder = HktRegistryHolder.new
|
|
135
111
|
@constant_type_cache = ConstantTypeCacheHolder.new
|
|
@@ -137,14 +113,10 @@ module Rigor
|
|
|
137
113
|
freeze
|
|
138
114
|
end
|
|
139
115
|
|
|
140
|
-
# ADR-20 slices 2e + 6 — lazy HKT registry getter.
|
|
141
|
-
#
|
|
142
|
-
#
|
|
143
|
-
#
|
|
144
|
-
# plugin entries, which beat the bundled JSON_VALUE.
|
|
145
|
-
# Memoised; single-threaded use only (under the Ractor
|
|
146
|
-
# pool path each worker has its own Environment so
|
|
147
|
-
# cross-worker mutation is impossible; the LSP
|
|
116
|
+
# ADR-20 slices 2e + 6 — lazy HKT registry getter. Merge order on first call: builtins (base) ← plugin
|
|
117
|
+
# manifest aggregation ← RBS env scan. Last-write-wins on URI collisions so user-authored `.rbs` overlays
|
|
118
|
+
# beat plugin entries, which beat the bundled JSON_VALUE. Memoised; single-threaded use only (under the
|
|
119
|
+
# Ractor pool path each worker has its own Environment so cross-worker mutation is impossible; the LSP
|
|
148
120
|
# single-publish-at-a-time invariant serialises here).
|
|
149
121
|
def hkt_registry
|
|
150
122
|
@hkt_registry_holder.fetch do
|
|
@@ -161,10 +133,9 @@ module Rigor
|
|
|
161
133
|
end
|
|
162
134
|
end
|
|
163
135
|
|
|
164
|
-
# Backwards-compatible reporter accessors — every existing
|
|
165
|
-
#
|
|
166
|
-
#
|
|
167
|
-
# via {#attach_reporters!} below.
|
|
136
|
+
# Backwards-compatible reporter accessors — every existing consumer (rbs_extended, method_dispatcher)
|
|
137
|
+
# calls these. The frozen `@reporters` container is mutable for slot reassignment via
|
|
138
|
+
# {#attach_reporters!} below.
|
|
168
139
|
def rbs_extended_reporter
|
|
169
140
|
@reporters.rbs_extended
|
|
170
141
|
end
|
|
@@ -173,29 +144,22 @@ module Rigor
|
|
|
173
144
|
@reporters.boundary_cross
|
|
174
145
|
end
|
|
175
146
|
|
|
176
|
-
# ADR-32 WD6 — the per-run accumulator for synthesizer
|
|
177
|
-
#
|
|
178
|
-
# `
|
|
179
|
-
#
|
|
180
|
-
# `source-rbs-synthesis-failed` `:info` diagnostics after
|
|
181
|
-
# analysis completes. Nil when no plugin contributes a
|
|
182
|
-
# synthesizer.
|
|
147
|
+
# ADR-32 WD6 — the per-run accumulator for synthesizer failure events. `Environment.for_project` records
|
|
148
|
+
# `[:error, message]` returns from a plugin's `source_rbs_synthesizer` here so the Runner can emit
|
|
149
|
+
# `source-rbs-synthesis-failed` `:info` diagnostics after analysis completes. Nil when no plugin
|
|
150
|
+
# contributes a synthesizer.
|
|
183
151
|
def source_rbs_synthesis_reporter
|
|
184
152
|
@reporters.source_rbs_synthesis
|
|
185
153
|
end
|
|
186
154
|
|
|
187
|
-
# Replaces the env's per-run reporter slots. Intended for
|
|
188
|
-
#
|
|
189
|
-
#
|
|
190
|
-
#
|
|
191
|
-
# events stay scoped to that call rather than accumulating
|
|
192
|
-
# across publishes.
|
|
155
|
+
# Replaces the env's per-run reporter slots. Intended for long-lived integrations (LSP `ProjectContext`)
|
|
156
|
+
# that share one Environment instance across many `Runner.run` calls: each call attaches its own fresh
|
|
157
|
+
# reporter pair so per-call diagnostic events stay scoped to that call rather than accumulating across
|
|
158
|
+
# publishes.
|
|
193
159
|
#
|
|
194
|
-
# Single-threaded use only. Concurrent publishes against one
|
|
195
|
-
#
|
|
196
|
-
#
|
|
197
|
-
# path. The Ractor pool path builds a per-worker Environment
|
|
198
|
-
# and does not reach this surface.
|
|
160
|
+
# Single-threaded use only. Concurrent publishes against one Environment must serialise — the LSP
|
|
161
|
+
# `Server` debouncer + synchronized writer already enforces this for the editor path. The Ractor pool
|
|
162
|
+
# path builds a per-worker Environment and does not reach this surface.
|
|
199
163
|
def attach_reporters!(rbs_extended_reporter:, boundary_cross_reporter:)
|
|
200
164
|
@reporters.rbs_extended = rbs_extended_reporter
|
|
201
165
|
@reporters.boundary_cross = boundary_cross_reporter
|
|
@@ -210,26 +174,20 @@ module Rigor
|
|
|
210
174
|
).freeze
|
|
211
175
|
end
|
|
212
176
|
|
|
213
|
-
# Builds an Environment that consults the project's local
|
|
214
|
-
#
|
|
177
|
+
# Builds an Environment that consults the project's local signatures and any opt-in stdlib libraries on
|
|
178
|
+
# top of RBS core.
|
|
215
179
|
#
|
|
216
|
-
# @param root [String, Pathname] project root used to auto-detect
|
|
217
|
-
#
|
|
218
|
-
#
|
|
219
|
-
#
|
|
220
|
-
#
|
|
221
|
-
#
|
|
222
|
-
#
|
|
223
|
-
#
|
|
224
|
-
# @param
|
|
225
|
-
#
|
|
226
|
-
# the
|
|
227
|
-
# exists, otherwise no signature path is loaded.
|
|
228
|
-
# @param cache_store [Rigor::Cache::Store, nil] persistent cache
|
|
229
|
-
# threaded into the underlying {Environment::RbsLoader} so
|
|
230
|
-
# constant lookups (and, in later v0.0.9 slices, other
|
|
231
|
-
# reflection artefacts) consult the cache. Pass `nil` (the
|
|
232
|
-
# default) to skip caching for this environment.
|
|
180
|
+
# @param root [String, Pathname] project root used to auto-detect the default signature path. Defaults
|
|
181
|
+
# to the current working directory.
|
|
182
|
+
# @param libraries [Array<String, Symbol>] additional stdlib libraries to load on top of
|
|
183
|
+
# {DEFAULT_LIBRARIES}. The final list is the union of the two, de-duplicated while preserving order.
|
|
184
|
+
# Pass an empty array (the default) to load only the defaults.
|
|
185
|
+
# @param signature_paths [Array<String, Pathname>, nil] explicit list of `sig/`-style directories. When
|
|
186
|
+
# `nil` (the default), the canonical project layout `<root>/sig` is used if it exists, otherwise no
|
|
187
|
+
# signature path is loaded.
|
|
188
|
+
# @param cache_store [Rigor::Cache::Store, nil] persistent cache threaded into the underlying
|
|
189
|
+
# {Environment::RbsLoader} so constant lookups (and, in later v0.0.9 slices, other reflection
|
|
190
|
+
# artefacts) consult the cache. Pass `nil` (the default) to skip caching for this environment.
|
|
233
191
|
# @return [Rigor::Environment]
|
|
234
192
|
# rubocop:disable Metrics/MethodLength, Metrics/ParameterLists
|
|
235
193
|
def for_project(root: Dir.pwd, libraries: [], signature_paths: nil, cache_store: nil,
|
|
@@ -242,21 +200,15 @@ module Rigor
|
|
|
242
200
|
synthetic_method_index: nil, project_patched_methods: nil,
|
|
243
201
|
source_files: [])
|
|
244
202
|
resolved_paths = signature_paths || default_signature_paths(root)
|
|
245
|
-
# O4 MVP — append per-gem `sig/` directories discovered
|
|
246
|
-
#
|
|
247
|
-
#
|
|
248
|
-
#
|
|
249
|
-
# (semantic precedence inside `RbsLoader.build_env_for`);
|
|
250
|
-
# gem-shipped sigs append last so user overrides stay
|
|
251
|
-
# authoritative.
|
|
203
|
+
# O4 MVP — append per-gem `sig/` directories discovered under the target project's bundler install
|
|
204
|
+
# root. Empty array when neither an explicit path nor auto-detection finds a bundle. Order: user
|
|
205
|
+
# `signature_paths:` win first (semantic precedence inside `RbsLoader.build_env_for`); gem-shipped
|
|
206
|
+
# sigs append last so user overrides stay authoritative.
|
|
252
207
|
#
|
|
253
|
-
# O4 Layer 3 — when a Gemfile.lock is available (explicit
|
|
254
|
-
#
|
|
255
|
-
#
|
|
256
|
-
#
|
|
257
|
-
# tree (out-of-band installs, version drift after a
|
|
258
|
-
# `bundle update`) are silently dropped so only gems the
|
|
259
|
-
# project actually declares contribute RBS.
|
|
208
|
+
# O4 Layer 3 — when a Gemfile.lock is available (explicit `bundler_lockfile:` or auto-detected next
|
|
209
|
+
# to the project root), use the locked gem set to filter the discovered `sig/` directories. Stale
|
|
210
|
+
# gems in the bundle install tree (out-of-band installs, version drift after a `bundle update`) are
|
|
211
|
+
# silently dropped so only gems the project actually declares contribute RBS.
|
|
260
212
|
locked = LockfileResolver.locked_gems(
|
|
261
213
|
lockfile_path: bundler_lockfile,
|
|
262
214
|
project_root: root,
|
|
@@ -268,19 +220,13 @@ module Rigor
|
|
|
268
220
|
auto_detect: bundler_auto_detect,
|
|
269
221
|
locked_gems: locked.empty? ? nil : locked
|
|
270
222
|
).map(&:to_s)
|
|
271
|
-
# O4 Layer 3 slice 2 — when `rbs collection install`
|
|
272
|
-
#
|
|
273
|
-
#
|
|
274
|
-
#
|
|
275
|
-
#
|
|
276
|
-
#
|
|
277
|
-
#
|
|
278
|
-
# source — stdlib-extracted default gems (`cgi`,
|
|
279
|
-
# `logger`, …, shipped by the collection under a `git`
|
|
280
|
-
# source) and the `data/vendored_gem_sigs/` bundle
|
|
281
|
-
# (`redis`, `nokogiri`, `pg`, …). `skip_gem_names:`
|
|
282
|
-
# passes both sets so the collection copy doesn't
|
|
283
|
-
# double-declare against rigor's bundled RBS (the
|
|
223
|
+
# O4 Layer 3 slice 2 — when `rbs collection install` has been run for the target project, parse the
|
|
224
|
+
# resulting `rbs_collection.lock.yaml` and feed each gem's `<collection_path>/<name>/<version>/`
|
|
225
|
+
# directory into `signature_paths:`. Stdlib-typed entries are skipped (already covered by
|
|
226
|
+
# `DEFAULT_LIBRARIES`), as are gems whose RBS rigor already loads from another source —
|
|
227
|
+
# stdlib-extracted default gems (`cgi`, `logger`, …, shipped by the collection under a `git` source)
|
|
228
|
+
# and the `data/vendored_gem_sigs/` bundle (`redis`, `nokogiri`, `pg`, …). `skip_gem_names:` passes
|
|
229
|
+
# both sets so the collection copy doesn't double-declare against rigor's bundled RBS (the
|
|
284
230
|
# `RBS::DuplicatedDeclarationError` hazard).
|
|
285
231
|
merged_libraries = (DEFAULT_LIBRARIES + libraries.map(&:to_s)).uniq
|
|
286
232
|
skip_gem_names = merged_libraries + RbsLoader.vendored_gem_names
|
|
@@ -290,25 +236,18 @@ module Rigor
|
|
|
290
236
|
auto_detect: rbs_collection_auto_detect,
|
|
291
237
|
skip_gem_names: skip_gem_names
|
|
292
238
|
).map(&:to_s)
|
|
293
|
-
# ADR-25 — RBS signature directories contributed by loaded
|
|
294
|
-
#
|
|
295
|
-
#
|
|
296
|
-
#
|
|
297
|
-
# `signature_paths:` and above the opportunistic bundle /
|
|
298
|
-
# collection discovery. A duplicate-declaration conflict
|
|
299
|
-
# degrades through the same O7 failure-memo path.
|
|
239
|
+
# ADR-25 — RBS signature directories contributed by loaded plugins via their manifest
|
|
240
|
+
# `signature_paths:`. Resolved to absolute dirs by `Plugin::Base#signature_paths`; additive, ranked
|
|
241
|
+
# below the user's explicit `signature_paths:` and above the opportunistic bundle / collection
|
|
242
|
+
# discovery. A duplicate-declaration conflict degrades through the same O7 failure-memo path.
|
|
300
243
|
plugin_sig_paths = plugin_registry ? plugin_registry.signature_paths.map(&:to_s) : []
|
|
301
|
-
# ADR-72 — Gemfile.lock-gated bundled RBS overlays. For each
|
|
302
|
-
#
|
|
303
|
-
# (
|
|
304
|
-
#
|
|
305
|
-
#
|
|
306
|
-
#
|
|
307
|
-
#
|
|
308
|
-
# last so any RBS the project already supplies wins, and skipped
|
|
309
|
-
# for a gem whose opt-in plugin twin is loaded (no duplicate
|
|
310
|
-
# declaration). The paths ride in `loader_signature_paths`, so
|
|
311
|
-
# the env cache descriptor digests them for free.
|
|
244
|
+
# ADR-72 — Gemfile.lock-gated bundled RBS overlays. For each locked gem that ships no RBS through any
|
|
245
|
+
# resolution path (`:missing`) and has a Rigor-bundled overlay, load that overlay so its core-class
|
|
246
|
+
# extensions resolve (e.g. `Integer#minutes` on a Rails project) — turning a systematic false
|
|
247
|
+
# `call.undefined-method` into a no-op while a project WITHOUT the gem still sees the genuine
|
|
248
|
+
# diagnostic. Appended last so any RBS the project already supplies wins, and skipped for a gem whose
|
|
249
|
+
# opt-in plugin twin is loaded (no duplicate declaration). The paths ride in
|
|
250
|
+
# `loader_signature_paths`, so the env cache descriptor digests them for free.
|
|
312
251
|
overlay_paths = gem_overlay_paths(
|
|
313
252
|
locked: locked, default_libraries: merged_libraries,
|
|
314
253
|
bundle_sig_paths: gem_sig_paths, rbs_collection_paths: collection_paths,
|
|
@@ -316,22 +255,15 @@ module Rigor
|
|
|
316
255
|
)
|
|
317
256
|
loader_signature_paths = resolved_paths + plugin_sig_paths + gem_sig_paths +
|
|
318
257
|
collection_paths + overlay_paths
|
|
319
|
-
# ADR-32 WD4 + WD5 — invoke each loaded plugin's
|
|
320
|
-
# `
|
|
321
|
-
#
|
|
322
|
-
#
|
|
323
|
-
# `rigor-rbs-inline`) is responsible for its own
|
|
324
|
-
# fail-soft on parse errors per WD6; this loop only
|
|
325
|
-
# filters `nil` returns.
|
|
258
|
+
# ADR-32 WD4 + WD5 — invoke each loaded plugin's `source_rbs_synthesizer` once per project source
|
|
259
|
+
# file and collect non-nil `[filename, rbs_source]` pairs. The synthesizer-emitting plugin (currently
|
|
260
|
+
# only `rigor-rbs-inline`) is responsible for its own fail-soft on parse errors per WD6; this loop
|
|
261
|
+
# only filters `nil` returns.
|
|
326
262
|
#
|
|
327
|
-
# When a `cache_store` is supplied, each synthesizer
|
|
328
|
-
#
|
|
329
|
-
#
|
|
330
|
-
#
|
|
331
|
-
# source skips the rbs-inline parse cost. The empty
|
|
332
|
-
# string is the sentinel for "no contribution" so the
|
|
333
|
-
# Store (which treats `nil` as cache miss) can persist
|
|
334
|
-
# the no-contribution decision too.
|
|
263
|
+
# When a `cache_store` is supplied, each synthesizer invocation is memoised per `(file path + content
|
|
264
|
+
# SHA, plugin id + version + config_hash)` — WD5's cache key — so a second run with unchanged source
|
|
265
|
+
# skips the rbs-inline parse cost. The empty string is the sentinel for "no contribution" so the
|
|
266
|
+
# Store (which treats `nil` as cache miss) can persist the no-contribution decision too.
|
|
335
267
|
virtual_rbs = collect_virtual_rbs(plugin_registry, source_files, cache_store,
|
|
336
268
|
source_rbs_synthesis_reporter)
|
|
337
269
|
loader = RbsLoader.new(
|
|
@@ -340,15 +272,11 @@ module Rigor
|
|
|
340
272
|
cache_store: cache_store,
|
|
341
273
|
virtual_rbs: virtual_rbs
|
|
342
274
|
)
|
|
343
|
-
# ADR-20 slice 2c + 2e — seed hkt_registry with the
|
|
344
|
-
#
|
|
345
|
-
#
|
|
346
|
-
#
|
|
347
|
-
# (
|
|
348
|
-
# pay the eager env-build cost up front. URI
|
|
349
|
-
# collisions let the user-authored overlay win over
|
|
350
|
-
# the bundled builtin (last-write-wins per ADR-20
|
|
351
|
-
# OQ3 tentative).
|
|
275
|
+
# ADR-20 slice 2c + 2e — seed hkt_registry with the bundled builtins. The Environment's
|
|
276
|
+
# `#hkt_registry` getter then LAZILY merges in the RBS env scan on first call so fast paths that
|
|
277
|
+
# don't consult HKT (e.g. `rigor check --cache-stats --no-stats`) don't pay the eager env-build cost
|
|
278
|
+
# up front. URI collisions let the user-authored overlay win over the bundled builtin
|
|
279
|
+
# (last-write-wins per ADR-20 OQ3 tentative).
|
|
352
280
|
new(
|
|
353
281
|
rbs_loader: loader,
|
|
354
282
|
plugin_registry: plugin_registry,
|
|
@@ -370,13 +298,11 @@ module Rigor
|
|
|
370
298
|
sig.directory? ? [sig] : []
|
|
371
299
|
end
|
|
372
300
|
|
|
373
|
-
# ADR-72 — resolve the bundled RBS overlay directories to load for
|
|
374
|
-
#
|
|
375
|
-
#
|
|
376
|
-
#
|
|
377
|
-
#
|
|
378
|
-
# not loaded. Returns `[Pathname]`, deterministically ordered, or
|
|
379
|
-
# `[]` when no lockfile / no eligible gem.
|
|
301
|
+
# ADR-72 — resolve the bundled RBS overlay directories to load for this project. A gem is eligible when
|
|
302
|
+
# it is locked in the Gemfile.lock, classified `:missing` by {RbsCoverageReport} (no RBS through
|
|
303
|
+
# default-library / vendored / bundle-`sig/` / rbs-collection), and its conflicting opt-in plugin (if
|
|
304
|
+
# any) is not loaded. Returns `[Pathname]`, deterministically ordered, or `[]` when no lockfile / no
|
|
305
|
+
# eligible gem.
|
|
380
306
|
def gem_overlay_paths(locked:, default_libraries:, bundle_sig_paths:,
|
|
381
307
|
rbs_collection_paths:, plugin_registry:)
|
|
382
308
|
return [] if locked.empty?
|
|
@@ -394,27 +320,19 @@ module Rigor
|
|
|
394
320
|
RbsLoader.gem_overlay_sig_paths(eligible)
|
|
395
321
|
end
|
|
396
322
|
|
|
397
|
-
# ADR-32 WD4 + WD5 — for each project source file, invoke
|
|
398
|
-
#
|
|
399
|
-
#
|
|
400
|
-
# rbs_source], ...]`; the loader threads it through to
|
|
401
|
-
# `RbsLoader.new(virtual_rbs: ...)`.
|
|
323
|
+
# ADR-32 WD4 + WD5 — for each project source file, invoke every plugin-registered synthesizer once and
|
|
324
|
+
# collect non-nil returns. The returned array is `[[virtual_filename, rbs_source], ...]`; the loader
|
|
325
|
+
# threads it through to `RbsLoader.new(virtual_rbs: ...)`.
|
|
402
326
|
#
|
|
403
|
-
# `virtual_filename` is the source file path prefixed with
|
|
404
|
-
# the plugin
|
|
405
|
-
# contributing plugin in their diagnostic location string.
|
|
327
|
+
# `virtual_filename` is the source file path prefixed with the plugin id so RBS parse errors point back
|
|
328
|
+
# to the contributing plugin in their diagnostic location string.
|
|
406
329
|
#
|
|
407
|
-
# When no plugin declares a synthesizer (the common case),
|
|
408
|
-
#
|
|
409
|
-
# this method short-circuits to `[]` without walking the
|
|
410
|
-
# file list.
|
|
330
|
+
# When no plugin declares a synthesizer (the common case), the registry's `source_rbs_synthesizers` is
|
|
331
|
+
# empty and this method short-circuits to `[]` without walking the file list.
|
|
411
332
|
#
|
|
412
|
-
# WD5 — when `cache_store` is supplied, each (file, plugin)
|
|
413
|
-
#
|
|
414
|
-
#
|
|
415
|
-
# plugin's `PluginEntry` (id + version + config_hash) so a
|
|
416
|
-
# config change or content change invalidates the entry
|
|
417
|
-
# automatically.
|
|
333
|
+
# WD5 — when `cache_store` is supplied, each (file, plugin) synthesizer call is memoised through
|
|
334
|
+
# `Cache::Store`. The cache key composes the file's content SHA with the plugin's `PluginEntry` (id +
|
|
335
|
+
# version + config_hash) so a config change or content change invalidates the entry automatically.
|
|
418
336
|
def collect_virtual_rbs(plugin_registry, source_files, cache_store, reporter)
|
|
419
337
|
return [] if plugin_registry.nil?
|
|
420
338
|
|
|
@@ -436,14 +354,10 @@ module Rigor
|
|
|
436
354
|
result
|
|
437
355
|
end
|
|
438
356
|
|
|
439
|
-
# ADR-32 WD5 — cache wrapper around a single (plugin,
|
|
440
|
-
#
|
|
441
|
-
#
|
|
442
|
-
#
|
|
443
|
-
# tuples are stored as the canonical
|
|
444
|
-
# `[:error, message_string]` Array so the same wrapper
|
|
445
|
-
# short-circuits subsequent runs against unchanged broken
|
|
446
|
-
# input.
|
|
357
|
+
# ADR-32 WD5 — cache wrapper around a single (plugin, file) invocation. The cache stores the empty
|
|
358
|
+
# string `""` as the "no contribution" sentinel because `Cache::Store` treats `nil` as a cache miss.
|
|
359
|
+
# Error tuples are stored as the canonical `[:error, message_string]` Array so the same wrapper
|
|
360
|
+
# short-circuits subsequent runs against unchanged broken input.
|
|
447
361
|
def synthesizer_output_for(plugin, callable, path, cache_store)
|
|
448
362
|
return invoke_synthesizer_safely(callable, path) if cache_store.nil?
|
|
449
363
|
return invoke_synthesizer_safely(callable, path) unless File.file?(path)
|
|
@@ -456,17 +370,14 @@ module Rigor
|
|
|
456
370
|
) { invoke_synthesizer_safely(callable, path) || "" }
|
|
457
371
|
end
|
|
458
372
|
|
|
459
|
-
# ADR-32 WD6 — route a synthesizer return value through
|
|
460
|
-
#
|
|
461
|
-
#
|
|
462
|
-
# admits three return shapes:
|
|
373
|
+
# ADR-32 WD6 — route a synthesizer return value through the per-run failure reporter. The
|
|
374
|
+
# synthesizer's contract (declared in
|
|
375
|
+
# `plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb`) admits three return shapes:
|
|
463
376
|
# - `String` (non-empty) → successful RBS source
|
|
464
377
|
# - `nil` / `""` → no contribution
|
|
465
378
|
# - `[:error, message]` → parse failed
|
|
466
|
-
# The error tuple is converted into a reporter entry +
|
|
467
|
-
#
|
|
468
|
-
# continues. Reporter is `nil` for callers that don't care
|
|
469
|
-
# (legacy Environment.new, tests).
|
|
379
|
+
# The error tuple is converted into a reporter entry + treated as "no contribution" so the analysis
|
|
380
|
+
# pipeline continues. Reporter is `nil` for callers that don't care (legacy Environment.new, tests).
|
|
470
381
|
def interpret_synthesizer_outcome(outcome, plugin, path, reporter)
|
|
471
382
|
return outcome unless outcome.is_a?(Array) && outcome[0] == :error
|
|
472
383
|
|
|
@@ -495,8 +406,7 @@ module Rigor
|
|
|
495
406
|
def synthesizer_input_digest(path)
|
|
496
407
|
Digest::SHA256.hexdigest(File.binread(path))
|
|
497
408
|
rescue ::SystemCallError
|
|
498
|
-
# Unreadable file → key on the path alone; the
|
|
499
|
-
# synthesizer's File.file?/File.read will see the same
|
|
409
|
+
# Unreadable file → key on the path alone; the synthesizer's File.file?/File.read will see the same
|
|
500
410
|
# failure and return nil.
|
|
501
411
|
Digest::SHA256.hexdigest(path.to_s)
|
|
502
412
|
end
|
|
@@ -504,23 +414,19 @@ module Rigor
|
|
|
504
414
|
def invoke_synthesizer_safely(callable, path)
|
|
505
415
|
callable.call(path.to_s)
|
|
506
416
|
rescue StandardError
|
|
507
|
-
# WD6 fail-soft — a synthesizer that raises does NOT crash
|
|
508
|
-
#
|
|
509
|
-
# the
|
|
510
|
-
# an unhandled raise is swallowed silently; the
|
|
511
|
-
# unexamined-raise channel is deliberately silent per WD6.
|
|
417
|
+
# WD6 fail-soft — a synthesizer that raises does NOT crash analysis. Unlike the `[:error, msg]`
|
|
418
|
+
# return path (which the runner surfaces as `source-rbs-synthesis-failed`), an unhandled raise is
|
|
419
|
+
# swallowed silently; the unexamined-raise channel is deliberately silent per WD6.
|
|
512
420
|
nil
|
|
513
421
|
end
|
|
514
422
|
end
|
|
515
423
|
|
|
516
|
-
# Resolves a constant name to a Rigor::Type::Nominal (the *instance*
|
|
517
|
-
#
|
|
518
|
-
#
|
|
519
|
-
# the name is unknown to both.
|
|
424
|
+
# Resolves a constant name to a Rigor::Type::Nominal (the *instance* type carrier). Consults the static
|
|
425
|
+
# class registry first (cheap, hardcoded), then falls back to the RBS loader. Returns nil when the name
|
|
426
|
+
# is unknown to both.
|
|
520
427
|
#
|
|
521
|
-
# NOTE: This is the construction helper for "an instance of class
|
|
522
|
-
#
|
|
523
|
-
# constant), use {#singleton_for_name} instead.
|
|
428
|
+
# NOTE: This is the construction helper for "an instance of class `Foo`". For "the class object `Foo`
|
|
429
|
+
# itself" (the value of the constant), use {#singleton_for_name} instead.
|
|
524
430
|
def nominal_for_name(name)
|
|
525
431
|
registered = class_registry.nominal_for_name(name)
|
|
526
432
|
return registered if registered
|
|
@@ -528,36 +434,29 @@ module Rigor
|
|
|
528
434
|
class_known_in_rbs?(name) ? Type::Combinator.nominal_of(name.to_s) : nil
|
|
529
435
|
end
|
|
530
436
|
|
|
531
|
-
# Resolves a constant name to a Rigor::Type::Singleton (the *class
|
|
532
|
-
# object
|
|
533
|
-
#
|
|
534
|
-
# corresponding Rigor construction helper.
|
|
437
|
+
# Resolves a constant name to a Rigor::Type::Singleton (the *class object* carrier). The expression `Foo`
|
|
438
|
+
# evaluates to the class object, whose RBS type is `singleton(Foo)` -- this method is the corresponding
|
|
439
|
+
# Rigor construction helper.
|
|
535
440
|
#
|
|
536
|
-
# The lookup uses the same registry/RBS chain as {#nominal_for_name}
|
|
537
|
-
#
|
|
441
|
+
# The lookup uses the same registry/RBS chain as {#nominal_for_name} so a class is either known to both
|
|
442
|
+
# queries or to neither.
|
|
538
443
|
def singleton_for_name(name)
|
|
539
444
|
return nil unless class_known?(name)
|
|
540
445
|
|
|
541
446
|
Type::Combinator.singleton_of(name.to_s)
|
|
542
447
|
end
|
|
543
448
|
|
|
544
|
-
# Slice A constant-value lookup. Returns the translated
|
|
545
|
-
# `Rigor::
|
|
546
|
-
#
|
|
547
|
-
#
|
|
548
|
-
#
|
|
549
|
-
#
|
|
550
|
-
# only resolves names that name a class or module. Callers
|
|
551
|
-
# that need to type a `Prism::ConstantReadNode`/
|
|
552
|
-
# `Prism::ConstantPathNode` MUST consult {#singleton_for_name}
|
|
553
|
-
# first and fall through to this query when the constant is
|
|
554
|
-
# not a class.
|
|
449
|
+
# Slice A constant-value lookup. Returns the translated `Rigor::Type` for an RBS-declared **non-class**
|
|
450
|
+
# constant (`Rigor::Analysis::FactStore::BUCKETS: Array[Symbol]`, `Rigor::Configuration::DEFAULT_PATH:
|
|
451
|
+
# String`, ...) or `nil` when no RBS constant declaration covers `name`. This is the value-bearing
|
|
452
|
+
# counterpart of {#singleton_for_name}, which only resolves names that name a class or module. Callers
|
|
453
|
+
# that need to type a `Prism::ConstantReadNode`/ `Prism::ConstantPathNode` MUST consult
|
|
454
|
+
# {#singleton_for_name} first and fall through to this query when the constant is not a class.
|
|
555
455
|
def constant_for_name(name)
|
|
556
456
|
return nil if rbs_loader.nil?
|
|
557
457
|
|
|
558
|
-
# Pure function of `name` for this Environment's lifetime — the
|
|
559
|
-
#
|
|
560
|
-
# memoise across the lexical-candidate ladder's heavy name reuse.
|
|
458
|
+
# Pure function of `name` for this Environment's lifetime — the refinement table and the RBS constant
|
|
459
|
+
# table are both fixed — so memoise across the lexical-candidate ladder's heavy name reuse.
|
|
561
460
|
key = name.to_s
|
|
562
461
|
@constant_type_cache.fetch(key) do
|
|
563
462
|
Builtins::PredefinedConstantRefinements.lookup(key) ||
|
|
@@ -565,50 +464,39 @@ module Rigor
|
|
|
565
464
|
end
|
|
566
465
|
end
|
|
567
466
|
|
|
568
|
-
# Returns true when the constant name is known to either the static
|
|
569
|
-
#
|
|
570
|
-
# presence check without materialising a type carrier.
|
|
467
|
+
# Returns true when the constant name is known to either the static registry or the RBS loader. Useful
|
|
468
|
+
# for callers that only need a presence check without materialising a type carrier.
|
|
571
469
|
def class_known?(name)
|
|
572
470
|
return true if class_registry.nominal_for_name(name)
|
|
573
471
|
return true if class_known_in_rbs?(name)
|
|
574
472
|
|
|
575
|
-
# ADR-36 nested-class emission — a variant subclass the
|
|
576
|
-
#
|
|
577
|
-
#
|
|
578
|
-
# class for resolution purposes even though no RBS / source
|
|
579
|
-
# declares it.
|
|
473
|
+
# ADR-36 nested-class emission — a variant subclass the substrate synthesised (e.g. `Shape::Circle`
|
|
474
|
+
# from a `variants do variant Circle, Float end` block) is a real class for resolution purposes even
|
|
475
|
+
# though no RBS / source declares it.
|
|
580
476
|
@synthetic_method_index&.knows_class?(name) || false
|
|
581
477
|
end
|
|
582
478
|
|
|
583
|
-
# ADR-15 Phase 2b — returns the loader's read-only,
|
|
584
|
-
#
|
|
585
|
-
#
|
|
586
|
-
# access; subsequent calls return the same instance.
|
|
587
|
-
# Returns `nil` when the environment carries no RBS
|
|
588
|
-
# loader (test-only `Environment.new` without
|
|
479
|
+
# ADR-15 Phase 2b — returns the loader's read-only, `Ractor.shareable?` query surface as a frozen
|
|
480
|
+
# {Environment::Reflection}. Built lazily on first access; subsequent calls return the same instance.
|
|
481
|
+
# Returns `nil` when the environment carries no RBS loader (test-only `Environment.new` without
|
|
589
482
|
# `rbs_loader:`).
|
|
590
483
|
def reflection
|
|
591
484
|
@rbs_loader&.reflection
|
|
592
485
|
end
|
|
593
486
|
|
|
594
|
-
# Returns true when the RBS environment carries the named
|
|
595
|
-
#
|
|
596
|
-
# `
|
|
597
|
-
#
|
|
598
|
-
# unresolved method calls through the `Nominal[Object]`
|
|
599
|
-
# fallback — every concrete includer of M honours Kernel /
|
|
600
|
-
# Object instance methods through its own ancestor chain.
|
|
487
|
+
# Returns true when the RBS environment carries the named declaration as a Module (not a Class). Used by
|
|
488
|
+
# the `user_class_fallback_receiver` tier to detect a module-mixin receiver (e.g. `PP::ObjectMixin`) so
|
|
489
|
+
# the dispatcher can route unresolved method calls through the `Nominal[Object]` fallback — every
|
|
490
|
+
# concrete includer of M honours Kernel / Object instance methods through its own ancestor chain.
|
|
601
491
|
def rbs_module?(name)
|
|
602
492
|
return false unless rbs_loader
|
|
603
493
|
|
|
604
494
|
rbs_loader.rbs_module?(name)
|
|
605
495
|
end
|
|
606
496
|
|
|
607
|
-
# Compares two class/module names using analyzer-owned class data.
|
|
608
|
-
#
|
|
609
|
-
#
|
|
610
|
-
# loader handles project/stdlib classes without relying on host Ruby
|
|
611
|
-
# constants being loaded.
|
|
497
|
+
# Compares two class/module names using analyzer-owned class data. Returns `:equal`, `:subclass`,
|
|
498
|
+
# `:superclass`, `:disjoint`, or `:unknown`. The static registry handles built-ins cheaply; the RBS
|
|
499
|
+
# loader handles project/stdlib classes without relying on host Ruby constants being loaded.
|
|
612
500
|
def class_ordering(lhs, rhs)
|
|
613
501
|
lhs = normalize_class_name(lhs)
|
|
614
502
|
rhs = normalize_class_name(rhs)
|
|
@@ -634,14 +522,11 @@ module Rigor
|
|
|
634
522
|
name.to_s.delete_prefix("::")
|
|
635
523
|
end
|
|
636
524
|
|
|
637
|
-
# ADR-13 slice 3b — composes the per-run plugin-supplied
|
|
638
|
-
# {Rigor::TypeNode::
|
|
639
|
-
# {Rigor::
|
|
640
|
-
#
|
|
641
|
-
#
|
|
642
|
-
# `nil` when no plugin contributes a type-node resolver so
|
|
643
|
-
# the parser short-circuits the chain consultation and
|
|
644
|
-
# behaves bit-for-bit like the v0.1.0 → v0.1.3 default.
|
|
525
|
+
# ADR-13 slice 3b — composes the per-run plugin-supplied {Rigor::TypeNode::ResolverChain} into a single
|
|
526
|
+
# {Rigor::TypeNode::NameScope} that the RBS::Extended directive parser threads down to the
|
|
527
|
+
# {Rigor::Builtins::ImportedRefinements::Resolver}. Returns `nil` when no plugin contributes a type-node
|
|
528
|
+
# resolver so the parser short-circuits the chain consultation and behaves bit-for-bit like the v0.1.0 →
|
|
529
|
+
# v0.1.3 default.
|
|
645
530
|
def build_name_scope
|
|
646
531
|
return nil if @plugin_registry.nil? || @plugin_registry.empty?
|
|
647
532
|
|