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
|
@@ -3,10 +3,9 @@
|
|
|
3
3
|
module Rigor
|
|
4
4
|
module Plugin
|
|
5
5
|
module Macro
|
|
6
|
-
# ADR-36 — the nested-class emission tier of the ADR-16
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
# subclasses* declared by an enum-shaped block DSL.
|
|
6
|
+
# ADR-36 — the nested-class emission tier of the ADR-16 macro substrate. Where Tier C ({HeredocTemplate})
|
|
7
|
+
# synthesises *methods* on the calling class, this tier synthesises *nested subclasses* declared by an
|
|
8
|
+
# enum-shaped block DSL.
|
|
10
9
|
#
|
|
11
10
|
# Motivating shape — Mangrove's `Enum`:
|
|
12
11
|
#
|
|
@@ -18,13 +17,10 @@ module Rigor
|
|
|
18
17
|
# end
|
|
19
18
|
# end
|
|
20
19
|
#
|
|
21
|
-
# Each `variant <Const>, <Type>` row is meant to mint a nested
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
# statically so `Shape::Circle.new(1.0).inner` resolves the
|
|
26
|
-
# payload to `Float` instead of `call.undefined-constant` /
|
|
27
|
-
# `Dynamic[Top]`.
|
|
20
|
+
# Each `variant <Const>, <Type>` row is meant to mint a nested subclass `Shape::Circle < Shape` carrying
|
|
21
|
+
# `#inner : <Type>`. Mangrove builds this at runtime via `const_missing` + `class_eval`; the substrate
|
|
22
|
+
# replays the same contract statically so `Shape::Circle.new(1.0).inner` resolves the payload to `Float`
|
|
23
|
+
# instead of `call.undefined-constant` / `Dynamic[Top]`.
|
|
28
24
|
#
|
|
29
25
|
# ## Authoring shape
|
|
30
26
|
#
|
|
@@ -41,34 +37,24 @@ module Rigor
|
|
|
41
37
|
#
|
|
42
38
|
# ## Fields
|
|
43
39
|
#
|
|
44
|
-
# - `receiver_constraint` — fully-qualified module name (String)
|
|
45
|
-
# the
|
|
46
|
-
#
|
|
47
|
-
# - `
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
# - `
|
|
52
|
-
#
|
|
53
|
-
# (
|
|
54
|
-
#
|
|
55
|
-
# - `inner_arg_position` — Integer (default 1): the argument
|
|
56
|
-
# index whose type expression becomes the `#inner` reader's
|
|
57
|
-
# return type. Slice A resolves a constant type argument
|
|
58
|
-
# (`Float`, `String`); non-constant inner shapes (shape
|
|
59
|
-
# hashes) degrade to `Dynamic[Top]`.
|
|
60
|
-
# - `inner_reader` — Symbol (default `:inner`): the payload
|
|
61
|
-
# reader synthesised on each variant subclass.
|
|
40
|
+
# - `receiver_constraint` — fully-qualified module name (String) the enclosing class must `extend` for
|
|
41
|
+
# the block to be recognised (e.g. `"Mangrove::Enum"`).
|
|
42
|
+
# - `block_method` — Symbol naming the enclosing DSL block (`:variants`).
|
|
43
|
+
# - `variant_method` — Symbol naming each declaration call inside the block (`:variant`).
|
|
44
|
+
# - `symbol_arg_position` — Integer (default 0): the argument index whose literal **constant** names the
|
|
45
|
+
# nested subclass. (Named `name_arg_position:` before ADR-60 WD2 normalised the macro value-object
|
|
46
|
+
# vocabulary.)
|
|
47
|
+
# - `inner_arg_position` — Integer (default 1): the argument index whose type expression becomes the
|
|
48
|
+
# `#inner` reader's return type. Slice A resolves a constant type argument (`Float`, `String`);
|
|
49
|
+
# non-constant inner shapes (shape hashes) degrade to `Dynamic[Top]`.
|
|
50
|
+
# - `inner_reader` — Symbol (default `:inner`): the payload reader synthesised on each variant subclass.
|
|
62
51
|
#
|
|
63
52
|
# ## Floor / ceiling per ADR-16 WD13 + ADR-36 WD4
|
|
64
53
|
#
|
|
65
|
-
# Slice A ships the floor: each variant constant resolves as a
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
#
|
|
69
|
-
# exhaustive narrowing (ADR-36 WD3) is the ceiling, deferred —
|
|
70
|
-
# it needs the synthetic-class hierarchy threaded into
|
|
71
|
-
# `Environment#class_ordering`.
|
|
54
|
+
# Slice A ships the floor: each variant constant resolves as a class (so `<Variant>.new(...)` and the
|
|
55
|
+
# constant reference type), and the `#inner` reader resolves to the declared inner type. The
|
|
56
|
+
# `sealed`-parent fact + `is_a?` cross-variant exhaustive narrowing (ADR-36 WD3) is the ceiling,
|
|
57
|
+
# deferred — it needs the synthetic-class hierarchy threaded into `Environment#class_ordering`.
|
|
72
58
|
class NestedClassTemplate
|
|
73
59
|
attr_reader :receiver_constraint, :block_method, :variant_method,
|
|
74
60
|
:symbol_arg_position, :inner_arg_position, :inner_reader
|
|
@@ -4,16 +4,14 @@ module Rigor
|
|
|
4
4
|
module Plugin
|
|
5
5
|
module Macro
|
|
6
6
|
# ADR-16 Tier B declaration: "the class-level DSL call
|
|
7
|
-
# `<receiver_constraint>.<method_name>(:trait_a, :trait_b, ...)`
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
# `always_included` modules) on the calling class."
|
|
7
|
+
# `<receiver_constraint>.<method_name>(:trait_a, :trait_b, ...)` effectively includes the modules named
|
|
8
|
+
# in `modules_by_symbol[:trait_a]` + `[:trait_b]` (plus any `always_included` modules) on the calling
|
|
9
|
+
# class."
|
|
11
10
|
#
|
|
12
|
-
# Worked target: Devise's model-side `devise :database_authenticatable,
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
# `
|
|
16
|
-
# regardless of selection (e.g. `Devise::Models::Authenticatable`).
|
|
11
|
+
# Worked target: Devise's model-side `devise :database_authenticatable, :recoverable` DSL (per-library
|
|
12
|
+
# survey § Devise). The bundled registry mirrors `lib/devise/modules.rb`'s symbol → module table;
|
|
13
|
+
# `always_included` carries the modules Devise always mixes in regardless of selection (e.g.
|
|
14
|
+
# `Devise::Models::Authenticatable`).
|
|
17
15
|
#
|
|
18
16
|
# ## Authoring shape
|
|
19
17
|
#
|
|
@@ -37,50 +35,36 @@ module Rigor
|
|
|
37
35
|
#
|
|
38
36
|
# ## Fields
|
|
39
37
|
#
|
|
40
|
-
# - `receiver_constraint` — fully-qualified class name (String).
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
# - `
|
|
44
|
-
# (
|
|
45
|
-
#
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
# recognised trait symbol to a fully-qualified module name.
|
|
52
|
-
# Symbols not in the table fall through (silent skip; the
|
|
53
|
-
# scanner emits a `macro.tier_b.unknown-trait` `:info`
|
|
54
|
-
# provenance marker per WD9 / WD13).
|
|
55
|
-
# - `always_included` — Array<String>. Fully-qualified module
|
|
56
|
-
# names that are added to every call site (even when no
|
|
57
|
-
# symbols match). Mirrors Devise's `always_include` modules.
|
|
38
|
+
# - `receiver_constraint` — fully-qualified class name (String). Synthesis fires when the call's
|
|
39
|
+
# lexical receiver class equals or inherits from this constraint.
|
|
40
|
+
# - `method_name` — Symbol naming the DSL method (e.g. `:devise`).
|
|
41
|
+
# - `symbol_arg_position` — `:rest` (all positional Symbol args are traits, slice 3a's only supported
|
|
42
|
+
# form) or a non-negative Integer (the index of a single trait symbol — reserved for future shapes;
|
|
43
|
+
# not yet honoured by the scanner).
|
|
44
|
+
# - `modules_by_symbol` — Hash<Symbol, String>. Maps each recognised trait symbol to a fully-qualified
|
|
45
|
+
# module name. Symbols not in the table fall through (silent skip; the scanner emits a
|
|
46
|
+
# `macro.tier_b.unknown-trait` `:info` provenance marker per WD9 / WD13).
|
|
47
|
+
# - `always_included` — Array<String>. Fully-qualified module names that are added to every call site
|
|
48
|
+
# (even when no symbols match). Mirrors Devise's `always_include` modules.
|
|
58
49
|
#
|
|
59
50
|
# ## Floor / ceiling per ADR-16 WD13
|
|
60
51
|
#
|
|
61
|
-
# Slice 3 ships at the **floor**: the substrate per-method-
|
|
62
|
-
#
|
|
63
|
-
# the
|
|
64
|
-
#
|
|
65
|
-
#
|
|
66
|
-
# `Dynamic[T]` floor because the source-of-truth (the
|
|
67
|
-
# module's authored RBS) is not a manifest-declared string.
|
|
68
|
-
# Per ADR-5 robustness, the substrate does not fabricate
|
|
69
|
-
# precision; it simply replays the modules's signatures.
|
|
52
|
+
# Slice 3 ships at the **floor**: the substrate per-method-explodes each included module's RBS instance
|
|
53
|
+
# methods into the existing `SyntheticMethodIndex` (slice 2b primitive). The synthesised methods adopt
|
|
54
|
+
# the module's authored RBS return types — Tier B is NOT subject to the Tier C `Dynamic[T]` floor
|
|
55
|
+
# because the source-of-truth (the module's authored RBS) is not a manifest-declared string. Per ADR-5
|
|
56
|
+
# robustness, the substrate does not fabricate precision; it simply replays the modules's signatures.
|
|
70
57
|
#
|
|
71
58
|
# **Out of scope for slice 3** (deferred follow-ups):
|
|
72
|
-
# - `class_methods_module:` per-trait (Devise's `ClassMethods`
|
|
73
|
-
#
|
|
74
|
-
# - `sort_key:` for controlled include ordering across traits;
|
|
75
|
-
#
|
|
76
|
-
#
|
|
77
|
-
#
|
|
78
|
-
# facts (attr_reader / after_save / etc.); slice 3 emits
|
|
79
|
-
# only the module's plain instance methods.
|
|
59
|
+
# - `class_methods_module:` per-trait (Devise's `ClassMethods` extend-pattern); slice 3 covers instance
|
|
60
|
+
# methods only.
|
|
61
|
+
# - `sort_key:` for controlled include ordering across traits; slice 3 uses plugin-registration order
|
|
62
|
+
# then registry declaration order.
|
|
63
|
+
# - `included_do_digest:` — the per-module `included do` block facts (attr_reader / after_save / etc.);
|
|
64
|
+
# slice 3 emits only the module's plain instance methods.
|
|
80
65
|
#
|
|
81
|
-
# Engine wiring: `Inference::SyntheticMethodScanner#collect_trait_registries`
|
|
82
|
-
#
|
|
83
|
-
# entries. Worked consumer: `plugins/rigor-devise/` (slice 3c).
|
|
66
|
+
# Engine wiring: `Inference::SyntheticMethodScanner#collect_trait_registries` (slice 3b) walks Tier B
|
|
67
|
+
# call sites and explodes per-method entries. Worked consumer: `plugins/rigor-devise/` (slice 3c).
|
|
84
68
|
class TraitRegistry
|
|
85
69
|
REST_POSITION = :rest
|
|
86
70
|
|
|
@@ -121,10 +105,9 @@ module Rigor
|
|
|
121
105
|
to_h.hash
|
|
122
106
|
end
|
|
123
107
|
|
|
124
|
-
# @return [String, nil] fully-qualified module name for the
|
|
125
|
-
#
|
|
126
|
-
#
|
|
127
|
-
# provenance marker and falls through).
|
|
108
|
+
# @return [String, nil] fully-qualified module name for the given trait symbol, or nil when the
|
|
109
|
+
# registry doesn't know the symbol (caller emits a tier_b.unknown-trait provenance marker and falls
|
|
110
|
+
# through).
|
|
128
111
|
def module_for(symbol)
|
|
129
112
|
modules_by_symbol[symbol.to_sym]
|
|
130
113
|
end
|
data/lib/rigor/plugin/macro.rb
CHANGED
|
@@ -7,23 +7,18 @@ require_relative "macro/trait_registry"
|
|
|
7
7
|
|
|
8
8
|
module Rigor
|
|
9
9
|
module Plugin
|
|
10
|
-
# Substrate declarations for the macro / DSL expansion tiers
|
|
11
|
-
#
|
|
12
|
-
# `
|
|
13
|
-
#
|
|
14
|
-
# `nested_class_templates:`) and the substrate consumes them
|
|
15
|
-
# to recognise the call shapes a library exposes to its users.
|
|
10
|
+
# Substrate declarations for the macro / DSL expansion tiers introduced by ADR-16. Plugin authors declare
|
|
11
|
+
# entries under `Plugin::Manifest` slots (`block_as_methods:`, `trait_registries:`, `heredoc_templates:`,
|
|
12
|
+
# `nested_class_templates:`) and the substrate consumes them to recognise the call shapes a library exposes
|
|
13
|
+
# to its users.
|
|
16
14
|
#
|
|
17
|
-
# Tier A (`BlockAsMethod`), Tier B (`TraitRegistry`), Tier C
|
|
18
|
-
# (`
|
|
19
|
-
#
|
|
20
|
-
# Engine wiring lives in `lib/rigor/inference/`.
|
|
15
|
+
# Tier A (`BlockAsMethod`), Tier B (`TraitRegistry`), Tier C (`HeredocTemplate`), and ADR-36 nested-class
|
|
16
|
+
# emission (`NestedClassTemplate`) value classes are all shipped here. Engine wiring lives in
|
|
17
|
+
# `lib/rigor/inference/`.
|
|
21
18
|
#
|
|
22
|
-
# Per ADR-16 § WD13, substrate-produced output ships at a
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
# emission is the ceiling and arrives in a later slice through
|
|
26
|
-
# the ADR-13 `Plugin::TypeNodeResolver` chain.
|
|
19
|
+
# Per ADR-16 § WD13, substrate-produced output ships at a **floor** in v0.1.x ("substrate-affected code
|
|
20
|
+
# parses cleanly and has its identifiers resolved"); precise return-type emission is the ceiling and arrives
|
|
21
|
+
# in a later slice through the ADR-13 `Plugin::TypeNodeResolver` chain.
|
|
27
22
|
module Macro
|
|
28
23
|
end
|
|
29
24
|
end
|
|
@@ -6,35 +6,27 @@ require_relative "additional_initializer"
|
|
|
6
6
|
|
|
7
7
|
module Rigor
|
|
8
8
|
module Plugin
|
|
9
|
-
# Value object describing one plugin's identity and metadata.
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
# configuration entries to registered plugins and by
|
|
13
|
-
# {Rigor::Cache::Descriptor::PluginEntry} when deriving cache keys.
|
|
9
|
+
# Value object describing one plugin's identity and metadata. Constructed once per plugin class through
|
|
10
|
+
# {Rigor::Plugin::Base.manifest}; consumed by {Rigor::Plugin::Loader} when matching project configuration
|
|
11
|
+
# entries to registered plugins and by {Rigor::Cache::Descriptor::PluginEntry} when deriving cache keys.
|
|
14
12
|
#
|
|
15
|
-
# The fields are pinned by ADR-2 § "Registration, Configuration,
|
|
16
|
-
#
|
|
17
|
-
# struct as the public manifest shape.
|
|
13
|
+
# The fields are pinned by ADR-2 § "Registration, Configuration, and Caching"; the v0.1.0 plugin contract
|
|
14
|
+
# surface treats this struct as the public manifest shape.
|
|
18
15
|
class Manifest # rubocop:disable Metrics/ClassLength
|
|
19
|
-
# Same regex {Rigor::Cache::Store::VALID_PRODUCER_ID} uses,
|
|
20
|
-
#
|
|
21
|
-
# `plugin.<id>.<rule>` diagnostic identifiers without escape.
|
|
16
|
+
# Same regex {Rigor::Cache::Store::VALID_PRODUCER_ID} uses, so plugin ids round-trip through cache
|
|
17
|
+
# producer ids and `plugin.<id>.<rule>` diagnostic identifiers without escape.
|
|
22
18
|
VALID_ID = /\A[a-z][a-z0-9._-]*\z/
|
|
23
19
|
|
|
24
|
-
# The first-implementation `config_schema` accepts these value
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
# the v0.1.0 protocol slices need them.
|
|
20
|
+
# The first-implementation `config_schema` accepts these value kinds. Slice 1 only checks key presence
|
|
21
|
+
# and shallow value kind; richer schemas (nested maps, enums) land later when the v0.1.0 protocol slices
|
|
22
|
+
# need them.
|
|
28
23
|
VALID_VALUE_KINDS = %i[string boolean integer array hash any].freeze
|
|
29
24
|
|
|
30
|
-
# ADR-9 slice 4 — declared cross-plugin fact dependencies.
|
|
31
|
-
# `
|
|
32
|
-
#
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
-
# topological sort + missing-producer detection; slice 4
|
|
36
|
-
# added the declarations; slice 5 (`Loader#topo_sort_plugins`)
|
|
37
|
-
# enforces ordering and missing-producer validation.
|
|
25
|
+
# ADR-9 slice 4 — declared cross-plugin fact dependencies. `produces:` lists the names this plugin
|
|
26
|
+
# publishes through its `#prepare(services)` hook. `consumes:` lists the `(plugin_id, name)` pairs this
|
|
27
|
+
# plugin reads from `services.fact_store`. The loader uses both for topological sort + missing-producer
|
|
28
|
+
# detection; slice 4 added the declarations; slice 5 (`Loader#topo_sort_plugins`) enforces ordering and
|
|
29
|
+
# missing-producer validation.
|
|
38
30
|
class Consumption < Data.define(:plugin_id, :name, :optional)
|
|
39
31
|
def initialize(plugin_id:, name:, optional: false)
|
|
40
32
|
super(plugin_id: plugin_id.to_s, name: name.to_sym, optional: optional ? true : false)
|
|
@@ -110,17 +102,15 @@ module Rigor
|
|
|
110
102
|
@source_rbs_synthesizer = source_rbs_synthesizer
|
|
111
103
|
end
|
|
112
104
|
|
|
113
|
-
# Assigned outside assign_fields (which already carries the
|
|
114
|
-
#
|
|
115
|
-
# final freeze. ADR-36 nested-class emission tier.
|
|
105
|
+
# Assigned outside assign_fields (which already carries the maximum positional arity) — set in
|
|
106
|
+
# `initialize` before the final freeze. ADR-36 nested-class emission tier.
|
|
116
107
|
def assign_nested_class_templates(nested_class_templates)
|
|
117
108
|
@nested_class_templates = nested_class_templates.dup.freeze
|
|
118
109
|
end
|
|
119
110
|
private :assign_nested_class_templates
|
|
120
111
|
|
|
121
|
-
# ADR-38 — assigned outside assign_fields (which already carries
|
|
122
|
-
#
|
|
123
|
-
# final freeze.
|
|
112
|
+
# ADR-38 — assigned outside assign_fields (which already carries the maximum positional arity), set in
|
|
113
|
+
# `initialize` before the final freeze.
|
|
124
114
|
def assign_additional_initializers(additional_initializers)
|
|
125
115
|
@additional_initializers = additional_initializers.dup.freeze
|
|
126
116
|
end
|
|
@@ -129,11 +119,9 @@ module Rigor
|
|
|
129
119
|
|
|
130
120
|
public
|
|
131
121
|
|
|
132
|
-
# Validates the user-supplied plugin config block against this
|
|
133
|
-
#
|
|
134
|
-
#
|
|
135
|
-
# only unknown keys and shallow value kind; nested schemas come
|
|
136
|
-
# with later slices.
|
|
122
|
+
# Validates the user-supplied plugin config block against this manifest's `config_schema`. Returns an
|
|
123
|
+
# array of human-readable error strings (empty when the config is valid). Slice 1 checks only unknown
|
|
124
|
+
# keys and shallow value kind; nested schemas come with later slices.
|
|
137
125
|
def validate_config(config)
|
|
138
126
|
return ["plugin config must be a Hash, got #{config.class}"] unless config.is_a?(Hash)
|
|
139
127
|
|
|
@@ -226,9 +214,8 @@ module Rigor
|
|
|
226
214
|
end
|
|
227
215
|
end
|
|
228
216
|
|
|
229
|
-
# ADR-40 — a `config_schema` value is either a bare kind
|
|
230
|
-
#
|
|
231
|
-
# Hash. These three helpers read whichever shape was given.
|
|
217
|
+
# ADR-40 — a `config_schema` value is either a bare kind (`Symbol`/`String`, the original form) or a
|
|
218
|
+
# `{kind:, default:}` Hash. These three helpers read whichever shape was given.
|
|
232
219
|
def schema_kind(value)
|
|
233
220
|
if value.is_a?(Hash)
|
|
234
221
|
kind = value[:kind] || value["kind"]
|
|
@@ -277,10 +264,9 @@ module Rigor
|
|
|
277
264
|
end
|
|
278
265
|
end
|
|
279
266
|
|
|
280
|
-
# Shared shape check for the Array-of-X manifest fields. Every entry
|
|
281
|
-
# must
|
|
282
|
-
#
|
|
283
|
-
# field validators below share so it cannot drift between them.
|
|
267
|
+
# Shared shape check for the Array-of-X manifest fields. Every entry must satisfy the block; otherwise
|
|
268
|
+
# raise the uniform "must be an Array of <label>" message. Centralises the message format the field
|
|
269
|
+
# validators below share so it cannot drift between them.
|
|
284
270
|
def validate_array_of!(field, value, label, &)
|
|
285
271
|
return if value.is_a?(Array) && value.all?(&)
|
|
286
272
|
|
|
@@ -291,73 +277,56 @@ module Rigor
|
|
|
291
277
|
validate_array_of!("produces", produces, "Symbol/String") { |p| p.is_a?(Symbol) || p.is_a?(String) }
|
|
292
278
|
end
|
|
293
279
|
|
|
294
|
-
# ADR-10 5a — `owns_receivers:` declares the class names
|
|
295
|
-
# this
|
|
296
|
-
#
|
|
297
|
-
#
|
|
298
|
-
# registered plugin (directly or via subclass) decline,
|
|
299
|
-
# so plugin contributions stay authoritative for those
|
|
300
|
-
# types.
|
|
280
|
+
# ADR-10 5a — `owns_receivers:` declares the class names this plugin claims sole ownership of. The
|
|
281
|
+
# dispatcher's dependency-source-inference tier consults this list before consulting its own catalog:
|
|
282
|
+
# receivers owned by a registered plugin (directly or via subclass) decline, so plugin contributions
|
|
283
|
+
# stay authoritative for those types.
|
|
301
284
|
def validate_owns_receivers!(owns_receivers)
|
|
302
285
|
validate_array_of!("owns_receivers", owns_receivers, "non-empty String") { |c| c.is_a?(String) && !c.empty? }
|
|
303
286
|
end
|
|
304
287
|
|
|
305
|
-
# ADR-26 — `open_receivers:` declares the class names this
|
|
306
|
-
#
|
|
307
|
-
#
|
|
308
|
-
#
|
|
309
|
-
#
|
|
310
|
-
#
|
|
311
|
-
# loaded plugin lists here — flagging a method on a class
|
|
312
|
-
# with an open dynamic surface is unsound. Distinct from
|
|
313
|
-
# `owns_receivers:` (which routes dispatch); this one only
|
|
314
|
-
# suppresses the diagnostic.
|
|
288
|
+
# ADR-26 — `open_receivers:` declares the class names this plugin marks as "open": statically known to
|
|
289
|
+
# respond beyond their RBS-declared method surface (e.g. `ActiveRecord::Relation`, which delegates an
|
|
290
|
+
# unbounded set of user-defined scopes to its model). `Analysis::CheckRules` skips the
|
|
291
|
+
# `call.undefined-method` rule for a receiver whose class any loaded plugin lists here — flagging a
|
|
292
|
+
# method on a class with an open dynamic surface is unsound. Distinct from `owns_receivers:` (which
|
|
293
|
+
# routes dispatch); this one only suppresses the diagnostic.
|
|
315
294
|
def validate_open_receivers!(open_receivers)
|
|
316
295
|
validate_array_of!("open_receivers", open_receivers, "non-empty String") { |c| c.is_a?(String) && !c.empty? }
|
|
317
296
|
end
|
|
318
297
|
|
|
319
|
-
# ADR-13 slice 2 — `type_node_resolvers:` declares the
|
|
320
|
-
#
|
|
321
|
-
#
|
|
322
|
-
#
|
|
323
|
-
# Slice 2 carries the declarations on the manifest and the
|
|
324
|
-
# registry exposes them in registration order; the parser
|
|
325
|
-
# integration that actually drives the chain lands in
|
|
326
|
-
# slice 3.
|
|
298
|
+
# ADR-13 slice 2 — `type_node_resolvers:` declares the plugin-supplied `TypeNodeResolver` instances the
|
|
299
|
+
# parser consults (in slice 3) when an RBS::Extended payload's named- or generic-type head misses the
|
|
300
|
+
# built-in registry. Slice 2 carries the declarations on the manifest and the registry exposes them in
|
|
301
|
+
# registration order; the parser integration that actually drives the chain lands in slice 3.
|
|
327
302
|
def validate_type_node_resolvers!(resolvers)
|
|
328
303
|
validate_array_of!("type_node_resolvers", resolvers, "Rigor::Plugin::TypeNodeResolver instances") do |r|
|
|
329
304
|
r.is_a?(TypeNodeResolver)
|
|
330
305
|
end
|
|
331
306
|
end
|
|
332
307
|
|
|
333
|
-
# ADR-16 slice 1a — `block_as_methods:` declares the Tier A
|
|
334
|
-
#
|
|
335
|
-
#
|
|
336
|
-
# actually narrows `Scope#self_type` for matching blocks
|
|
337
|
-
# arrives in a subsequent slice.
|
|
308
|
+
# ADR-16 slice 1a — `block_as_methods:` declares the Tier A substrate entries the plugin contributes.
|
|
309
|
+
# Slice 1a carries the declarations on the manifest; the engine hook that actually narrows
|
|
310
|
+
# `Scope#self_type` for matching blocks arrives in a subsequent slice.
|
|
338
311
|
def validate_block_as_methods!(entries)
|
|
339
312
|
validate_array_of!("block_as_methods", entries, "Rigor::Plugin::Macro::BlockAsMethod instances") do |e|
|
|
340
313
|
e.is_a?(Macro::BlockAsMethod)
|
|
341
314
|
end
|
|
342
315
|
end
|
|
343
316
|
|
|
344
|
-
# ADR-16 slice 2a — `heredoc_templates:` declares the Tier C
|
|
345
|
-
#
|
|
346
|
-
#
|
|
347
|
-
# manifest; the pre-pass + `SyntheticMethodIndex` that actually
|
|
348
|
-
# emit synthetic methods arrive in slice 2b.
|
|
317
|
+
# ADR-16 slice 2a — `heredoc_templates:` declares the Tier C substrate entries (heredoc-template
|
|
318
|
+
# synthesis on class-level DSL calls). Slice 2a carries the declarations on the manifest; the pre-pass +
|
|
319
|
+
# `SyntheticMethodIndex` that actually emit synthetic methods arrive in slice 2b.
|
|
349
320
|
def validate_heredoc_templates!(entries)
|
|
350
321
|
validate_array_of!("heredoc_templates", entries, "Rigor::Plugin::Macro::HeredocTemplate instances") do |e|
|
|
351
322
|
e.is_a?(Macro::HeredocTemplate)
|
|
352
323
|
end
|
|
353
324
|
end
|
|
354
325
|
|
|
355
|
-
# ADR-36 — `nested_class_templates:` declares the
|
|
356
|
-
# nested
|
|
357
|
-
#
|
|
358
|
-
#
|
|
359
|
-
# subclasses + their `#inner` reader through the existing
|
|
360
|
-
# `SyntheticMethodIndex` primitive.
|
|
326
|
+
# ADR-36 — `nested_class_templates:` declares the nested-class emission tier (enum-shaped block DSLs
|
|
327
|
+
# that mint nested subclasses, e.g. Mangrove's `variants do variant Const, Type end`). The scanner
|
|
328
|
+
# synthesises the variant subclasses + their `#inner` reader through the existing `SyntheticMethodIndex`
|
|
329
|
+
# primitive.
|
|
361
330
|
def validate_nested_class_templates!(entries)
|
|
362
331
|
validate_array_of!("nested_class_templates", entries,
|
|
363
332
|
"Rigor::Plugin::Macro::NestedClassTemplate instances") do |e|
|
|
@@ -365,105 +334,77 @@ module Rigor
|
|
|
365
334
|
end
|
|
366
335
|
end
|
|
367
336
|
|
|
368
|
-
# ADR-16 slice 3a — `trait_registries:` declares the Tier B
|
|
369
|
-
#
|
|
370
|
-
#
|
|
371
|
-
# manifest; the scanner + per-method explosion through
|
|
372
|
-
# `SyntheticMethodIndex` (slice 2b primitive) arrives in
|
|
373
|
-
# slice 3b.
|
|
337
|
+
# ADR-16 slice 3a — `trait_registries:` declares the Tier B substrate entries (trait-inlining via
|
|
338
|
+
# bundled module registry). Slice 3a carries the declarations on the manifest; the scanner + per-method
|
|
339
|
+
# explosion through `SyntheticMethodIndex` (slice 2b primitive) arrives in slice 3b.
|
|
374
340
|
def validate_trait_registries!(entries)
|
|
375
341
|
validate_array_of!("trait_registries", entries, "Rigor::Plugin::Macro::TraitRegistry instances") do |e|
|
|
376
342
|
e.is_a?(Macro::TraitRegistry)
|
|
377
343
|
end
|
|
378
344
|
end
|
|
379
345
|
|
|
380
|
-
# ADR-20 slice 6 — `hkt_registrations:` declares the
|
|
381
|
-
#
|
|
382
|
-
#
|
|
383
|
-
#
|
|
384
|
-
#
|
|
385
|
-
# `
|
|
386
|
-
# registry aggregator on `Plugin::Registry` flattens
|
|
387
|
-
# entries from every loaded plugin and merges them into
|
|
388
|
-
# `env.hkt_registry` on top of `Builtins::HktBuiltins.registry`;
|
|
389
|
-
# user `.rbs` overlays merge on top of plugin entries
|
|
390
|
-
# last-write-wins.
|
|
346
|
+
# ADR-20 slice 6 — `hkt_registrations:` declares the Lightweight HKT URI registrations this plugin
|
|
347
|
+
# ships (analogous to `%a{rigor:v1:hkt_register: ...}` directives but published via the manifest
|
|
348
|
+
# contract instead of a shipped `.rbs` file). Each entry MUST be an
|
|
349
|
+
# `Rigor::Inference::HktRegistry::Registration`. The registry aggregator on `Plugin::Registry` flattens
|
|
350
|
+
# entries from every loaded plugin and merges them into `env.hkt_registry` on top of
|
|
351
|
+
# `Builtins::HktBuiltins.registry`; user `.rbs` overlays merge on top of plugin entries last-write-wins.
|
|
391
352
|
def validate_hkt_registrations!(entries)
|
|
392
353
|
validate_array_of!("hkt_registrations", entries, "Rigor::Inference::HktRegistry::Registration instances") do |e|
|
|
393
354
|
e.is_a?(Inference::HktRegistry::Registration)
|
|
394
355
|
end
|
|
395
356
|
end
|
|
396
357
|
|
|
397
|
-
# ADR-20 slice 6 — `hkt_definitions:` declares the
|
|
398
|
-
#
|
|
399
|
-
#
|
|
400
|
-
#
|
|
401
|
-
#
|
|
402
|
-
# `Rigor::Inference::HktRegistry.definition_with_body_tree(...)`
|
|
403
|
-
# so plugin authors can build the body programmatically
|
|
404
|
-
# via {Rigor::Inference::HktBody}'s node-constructor API
|
|
405
|
-
# without parsing a string.
|
|
358
|
+
# ADR-20 slice 6 — `hkt_definitions:` declares the plugin's HKT type-function bodies (analogous to
|
|
359
|
+
# `%a{rigor:v1:hkt_define: ...}` directives). Each entry MUST be an
|
|
360
|
+
# `Rigor::Inference::HktRegistry::Definition` — typically built via
|
|
361
|
+
# `Rigor::Inference::HktRegistry.definition_with_body_tree(...)` so plugin authors can build the body
|
|
362
|
+
# programmatically via {Rigor::Inference::HktBody}'s node-constructor API without parsing a string.
|
|
406
363
|
def validate_hkt_definitions!(entries)
|
|
407
364
|
validate_array_of!("hkt_definitions", entries, "Rigor::Inference::HktRegistry::Definition instances") do |e|
|
|
408
365
|
e.is_a?(Inference::HktRegistry::Definition)
|
|
409
366
|
end
|
|
410
367
|
end
|
|
411
368
|
|
|
412
|
-
# ADR-25 — `signature_paths:` declares the RBS signature
|
|
413
|
-
#
|
|
414
|
-
#
|
|
415
|
-
# resolves them to absolute dirs against the gem root; the
|
|
416
|
-
# loader validates each exists and `Environment.for_project`
|
|
369
|
+
# ADR-25 — `signature_paths:` declares the RBS signature directories this plugin gem ships, as paths
|
|
370
|
+
# relative to the plugin's own gem root (e.g. `["sig"]`). `Plugin::Base#signature_paths` resolves them
|
|
371
|
+
# to absolute dirs against the gem root; the loader validates each exists and `Environment.for_project`
|
|
417
372
|
# merges the resolved set into the RBS environment.
|
|
418
373
|
def validate_signature_paths!(paths)
|
|
419
374
|
validate_array_of!("signature_paths", paths, "non-empty String") { |p| p.is_a?(String) && !p.empty? }
|
|
420
375
|
end
|
|
421
376
|
|
|
422
|
-
# ADR-28 — `protocol_contracts:` declares the path-scoped
|
|
423
|
-
#
|
|
424
|
-
#
|
|
425
|
-
#
|
|
426
|
-
#
|
|
427
|
-
#
|
|
428
|
-
#
|
|
429
|
-
# the contributing plugin's `#diagnostics_for_file` checks
|
|
430
|
-
# method presence + return-type conformance. The manifest
|
|
431
|
-
# field carries the plugin's *default* contracts; a plugin
|
|
432
|
-
# MAY override `Plugin::Base#protocol_contracts` to fold in
|
|
433
|
-
# per-project config (e.g. a custom convention path).
|
|
377
|
+
# ADR-28 — `protocol_contracts:` declares the path-scoped method-protocol contracts the plugin
|
|
378
|
+
# contributes. Each entry MUST be a `Rigor::Plugin::ProtocolContract`. The registry aggregator on
|
|
379
|
+
# `Plugin::Registry` flattens contracts across loaded plugins; the engine consults them in two places —
|
|
380
|
+
# `MethodParameterBinder` provides the declared parameter types into matching method bodies, and the
|
|
381
|
+
# contributing plugin's `#diagnostics_for_file` checks method presence + return-type conformance. The
|
|
382
|
+
# manifest field carries the plugin's *default* contracts; a plugin MAY override
|
|
383
|
+
# `Plugin::Base#protocol_contracts` to fold in per-project config (e.g. a custom convention path).
|
|
434
384
|
def validate_protocol_contracts!(entries)
|
|
435
385
|
validate_array_of!("protocol_contracts", entries, "Rigor::Plugin::ProtocolContract instances") do |e|
|
|
436
386
|
e.is_a?(ProtocolContract)
|
|
437
387
|
end
|
|
438
388
|
end
|
|
439
389
|
|
|
440
|
-
# ADR-38 — `additional_initializers:` declares the
|
|
441
|
-
#
|
|
442
|
-
#
|
|
443
|
-
#
|
|
444
|
-
# `Rigor::Plugin::AdditionalInitializer`. The registry
|
|
445
|
-
# aggregator on `Plugin::Registry` flattens entries across
|
|
446
|
-
# loaded plugins; `Inference::ScopeIndexer` consults the set at
|
|
447
|
-
# its single gate.
|
|
390
|
+
# ADR-38 — `additional_initializers:` declares the (receiver_constraint, methods) pairs whose `def`-form
|
|
391
|
+
# methods the engine treats like `initialize` for the read-before-write nil soundness gate. Each entry
|
|
392
|
+
# MUST be a `Rigor::Plugin::AdditionalInitializer`. The registry aggregator on `Plugin::Registry`
|
|
393
|
+
# flattens entries across loaded plugins; `Inference::ScopeIndexer` consults the set at its single gate.
|
|
448
394
|
def validate_additional_initializers!(entries)
|
|
449
395
|
validate_array_of!("additional_initializers", entries, "Rigor::Plugin::AdditionalInitializer instances") do |e|
|
|
450
396
|
e.is_a?(AdditionalInitializer)
|
|
451
397
|
end
|
|
452
398
|
end
|
|
453
399
|
|
|
454
|
-
# ADR-32 WD4 — `source_rbs_synthesizer:` declares a callable
|
|
455
|
-
#
|
|
456
|
-
#
|
|
457
|
-
#
|
|
458
|
-
# into the analysis environment or `nil` (no contribution
|
|
459
|
-
# for this file). Distinct from `signature_paths:` (static,
|
|
460
|
-
# bundled RBS): the synthesizer derives RBS from project
|
|
400
|
+
# ADR-32 WD4 — `source_rbs_synthesizer:` declares a callable the engine invokes once per analysed Ruby
|
|
401
|
+
# source file at env-build time. The callable receives a source file path (String) and returns either
|
|
402
|
+
# an RBS source String to merge into the analysis environment or `nil` (no contribution for this file).
|
|
403
|
+
# Distinct from `signature_paths:` (static, bundled RBS): the synthesizer derives RBS from project
|
|
461
404
|
# source on each run.
|
|
462
405
|
#
|
|
463
|
-
# The value is held as-given (no dup / freeze) because a
|
|
464
|
-
#
|
|
465
|
-
# author is responsible for thread-/Ractor-safety of any
|
|
466
|
-
# captured state (per ADR-15).
|
|
406
|
+
# The value is held as-given (no dup / freeze) because a callable instance is opaque to the manifest;
|
|
407
|
+
# the plugin author is responsible for thread-/Ractor-safety of any captured state (per ADR-15).
|
|
467
408
|
def validate_source_rbs_synthesizer!(synthesizer)
|
|
468
409
|
return if synthesizer.nil?
|
|
469
410
|
return if synthesizer.respond_to?(:call)
|