rigortype 0.2.7 → 0.2.9
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/data/core_overlay/csv.rbs +28 -0
- data/data/core_overlay/psych.rbs +22 -0
- data/docs/handbook/01-getting-started.md +9 -1
- data/docs/handbook/02-everyday-types.md +4 -1
- data/docs/handbook/08-understanding-errors.md +3 -3
- data/docs/manual/01-installation.md +1 -0
- data/docs/manual/02-cli-reference.md +16 -7
- data/docs/manual/04-diagnostics.md +7 -4
- data/docs/manual/06-baseline.md +5 -2
- data/docs/manual/07-plugins.md +1 -1
- data/docs/manual/14-rails-quickstart.md +4 -2
- data/docs/manual/15-type-protection-coverage.md +27 -4
- data/docs/manual/plugins/rigor-actionpack.md +1 -1
- data/docs/manual/plugins/rigor-activerecord.md +12 -5
- data/docs/manual/plugins/rigor-rails-routes.md +11 -0
- 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 +248 -186
- 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 +62 -48
- 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 +46 -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_fork_scan.rb +55 -0
- data/lib/rigor/cli/protection_renderer.rb +5 -7
- data/lib/rigor/cli/protection_report.rb +34 -18
- 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/missing_gem_constant_index.rb +128 -0
- 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 +225 -304
- 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 +794 -1154
- 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/fork_map.rb +87 -0
- 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 +627 -727
- data/lib/rigor/inference/origin_lookup.rb +38 -0
- data/lib/rigor/inference/parameter_inference_collector.rb +154 -109
- 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 -821
- data/lib/rigor/inference/statement_evaluator.rb +754 -1114
- 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 +141 -184
- 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 +92 -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 +40 -48
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +140 -129
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_index.rb +56 -59
- 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/structure_sql_parser.rb +172 -0
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +168 -241
- 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-activesupport-core-ext/sig/active_support/core_ext.rbs +32 -0
- 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/grape_api_discoverer.rb +189 -0
- 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 +61 -75
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/routes_parser.rb +319 -505
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +91 -96
- 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/environment.rbs +1 -0
- data/sig/rigor/scope.rbs +6 -0
- metadata +9 -1
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# Gem entry point. Required by Rigor's plugin loader when
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# `Rigor::Plugin.register`, which the body of
|
|
7
|
-
# `lib/rigor/plugin/activerecord.rb` performs at load time.
|
|
3
|
+
# Gem entry point. Required by Rigor's plugin loader when `.rigor.yml` lists `rigor-activerecord` under
|
|
4
|
+
# `plugins:`. The loader expects this `require` to side-effect a call to `Rigor::Plugin.register`, which
|
|
5
|
+
# the body of `lib/rigor/plugin/activerecord.rb` performs at load time.
|
|
8
6
|
require_relative "rigor/plugin/activerecord"
|
|
@@ -5,17 +5,13 @@ require "prism"
|
|
|
5
5
|
module Rigor
|
|
6
6
|
module Plugin
|
|
7
7
|
class Activestorage < Rigor::Plugin::Base
|
|
8
|
-
# Per-file walker. Emits one `:info` `attachment-call`
|
|
9
|
-
# diagnostic
|
|
10
|
-
#
|
|
11
|
-
# plugin recognised so users can verify the model →
|
|
12
|
-
# attachment mapping the plugin sees.
|
|
8
|
+
# Per-file walker. Emits one `:info` `attachment-call` diagnostic per recognised attachment access
|
|
9
|
+
# on a known AR class. The diagnostic surfaces what the plugin recognised so users can verify the
|
|
10
|
+
# model → attachment mapping the plugin sees.
|
|
13
11
|
#
|
|
14
|
-
# No `:error` diagnostics here — the `dynamic_return`
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
# `rigor-activerecord`'s `unknown-column`) is deferred:
|
|
18
|
-
# it requires a coupled receiver-class narrowing pass.
|
|
12
|
+
# No `:error` diagnostics here — the `dynamic_return` return-type narrowing carries the
|
|
13
|
+
# type-checking value. An `unknown-attachment` rule (similar to `rigor-activerecord`'s
|
|
14
|
+
# `unknown-column`) is deferred: it requires a coupled receiver-class narrowing pass.
|
|
19
15
|
class Analyzer
|
|
20
16
|
attr_reader :diagnostics
|
|
21
17
|
|
|
@@ -47,10 +43,8 @@ module Rigor
|
|
|
47
43
|
@attachment_index.attachments_for("::#{owner}")
|
|
48
44
|
return if attachments.nil?
|
|
49
45
|
|
|
50
|
-
# Only flag when the method matches a known
|
|
51
|
-
#
|
|
52
|
-
# provides the narrowing; the diagnostic just
|
|
53
|
-
# confirms the recognition).
|
|
46
|
+
# Only flag when the method matches a known attachment name (the `dynamic_return` rule provides
|
|
47
|
+
# the narrowing; the diagnostic just confirms the recognition).
|
|
54
48
|
attachment = attachments.find { |a| a[:name] == node.name.to_s }
|
|
55
49
|
return if attachment.nil?
|
|
56
50
|
|
|
@@ -6,10 +6,8 @@ require "rigor/source/literals"
|
|
|
6
6
|
module Rigor
|
|
7
7
|
module Plugin
|
|
8
8
|
class Activestorage < Rigor::Plugin::Base
|
|
9
|
-
# Walks the configured model search paths via the plugin's
|
|
10
|
-
#
|
|
11
|
-
# collects `has_one_attached` / `has_many_attached`
|
|
12
|
-
# declarations.
|
|
9
|
+
# Walks the configured model search paths via the plugin's `IoBoundary`, parses each `.rb` file
|
|
10
|
+
# with Prism, and collects `has_one_attached` / `has_many_attached` declarations.
|
|
13
11
|
#
|
|
14
12
|
# Returns rows the {AttachmentIndex} consumes:
|
|
15
13
|
#
|
|
@@ -19,17 +17,13 @@ module Rigor
|
|
|
19
17
|
#
|
|
20
18
|
# Limitations (intentional for v0.1.0 of the plugin):
|
|
21
19
|
#
|
|
22
|
-
# - The walker matches any class declaration that
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
# `rigor-activerecord`
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
# - Only Symbol-literal attachment names are recognised.
|
|
30
|
-
# `has_one_attached(args)` or computed names decline.
|
|
31
|
-
# - Modules (`class Admin::User`) are recognised; the
|
|
32
|
-
# resulting class name is the lexical path
|
|
20
|
+
# - The walker matches any class declaration that contains a `has_*_attached` call. Whether the
|
|
21
|
+
# class IS an ActiveRecord model is not verified here — `rigor-activerecord` provides that check
|
|
22
|
+
# via its own model index. The analyser is intentionally lenient so the plugin runs standalone in
|
|
23
|
+
# projects that haven't loaded `rigor-activerecord` yet.
|
|
24
|
+
# - Only Symbol-literal attachment names are recognised. `has_one_attached(args)` or computed names
|
|
25
|
+
# decline.
|
|
26
|
+
# - Modules (`class Admin::User`) are recognised; the resulting class name is the lexical path
|
|
33
27
|
# (`Admin::User`).
|
|
34
28
|
class AttachmentDiscoverer
|
|
35
29
|
ATTACHMENT_METHODS = {
|
|
@@ -3,16 +3,13 @@
|
|
|
3
3
|
module Rigor
|
|
4
4
|
module Plugin
|
|
5
5
|
class Activestorage < Rigor::Plugin::Base
|
|
6
|
-
# Maps a discovered class name to the list of attachment
|
|
7
|
-
#
|
|
8
|
-
# round-trips it through the standard pair.
|
|
6
|
+
# Maps a discovered class name to the list of attachment rows declared on it. Marshal-clean so the
|
|
7
|
+
# cache producer round-trips it through the standard pair.
|
|
9
8
|
#
|
|
10
9
|
# Each row is `{ name:, kind: }`:
|
|
11
10
|
#
|
|
12
|
-
# - `name` — String, the attachment method name as the
|
|
13
|
-
#
|
|
14
|
-
# - `kind` — `:singular` (`has_one_attached`) or
|
|
15
|
-
# `:collection` (`has_many_attached`).
|
|
11
|
+
# - `name` — String, the attachment method name as the user invokes it (`"avatar"`).
|
|
12
|
+
# - `kind` — `:singular` (`has_one_attached`) or `:collection` (`has_many_attached`).
|
|
16
13
|
class AttachmentIndex
|
|
17
14
|
attr_reader :entries
|
|
18
15
|
|
|
@@ -8,26 +8,18 @@ require_relative "activestorage/analyzer"
|
|
|
8
8
|
|
|
9
9
|
module Rigor
|
|
10
10
|
module Plugin
|
|
11
|
-
# rigor-activestorage — recognises `has_one_attached` /
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
# calls (`user.avatar.attached?`) route through Rigor's
|
|
15
|
-
# normal dispatch.
|
|
11
|
+
# rigor-activestorage — recognises `has_one_attached` / `has_many_attached` macros on ActiveRecord
|
|
12
|
+
# models and contributes attachment accessor return types so chained calls (`user.avatar.attached?`)
|
|
13
|
+
# route through Rigor's normal dispatch.
|
|
16
14
|
#
|
|
17
15
|
# ## Architecture
|
|
18
16
|
#
|
|
19
|
-
# One discovery pass per run reads the configured AR model
|
|
20
|
-
#
|
|
21
|
-
# `
|
|
22
|
-
#
|
|
23
|
-
# `
|
|
24
|
-
#
|
|
25
|
-
# stand-alone (mirrors `rigor-activerecord`'s
|
|
26
|
-
# `ModelDiscoverer`) so the plugin works even when
|
|
27
|
-
# `rigor-activerecord` is not loaded; when it IS loaded,
|
|
28
|
-
# the published `:model_index` fact (ADR-9 cross-plugin
|
|
29
|
-
# API) drives the same class set so the two plugins agree
|
|
30
|
-
# on what counts as a model.
|
|
17
|
+
# One discovery pass per run reads the configured AR model paths (default `app/models/`) via the
|
|
18
|
+
# plugin's `IoBoundary`, walks each `.rb` file with Prism, and collects `has_one_attached :avatar` /
|
|
19
|
+
# `has_many_attached :photos` macros into an {AttachmentIndex} keyed by class name. The walker is
|
|
20
|
+
# stand-alone (mirrors `rigor-activerecord`'s `ModelDiscoverer`) so the plugin works even when
|
|
21
|
+
# `rigor-activerecord` is not loaded; when it IS loaded, the published `:model_index` fact (ADR-9
|
|
22
|
+
# cross-plugin API) drives the same class set so the two plugins agree on what counts as a model.
|
|
31
23
|
#
|
|
32
24
|
# ## Configuration
|
|
33
25
|
#
|
|
@@ -39,9 +31,8 @@ module Rigor
|
|
|
39
31
|
#
|
|
40
32
|
# `model_search_paths` defaults to `["app/models"]`.
|
|
41
33
|
#
|
|
42
|
-
# The class name `Rigor::Plugin::Activestorage` (single
|
|
43
|
-
#
|
|
44
|
-
# used by `rigor-activerecord`.
|
|
34
|
+
# The class name `Rigor::Plugin::Activestorage` (single capital A) matches the constant-distinguishing
|
|
35
|
+
# convention used by `rigor-activerecord`.
|
|
45
36
|
class Activestorage < Rigor::Plugin::Base
|
|
46
37
|
manifest(
|
|
47
38
|
id: "activestorage",
|
|
@@ -53,11 +44,9 @@ module Rigor
|
|
|
53
44
|
consumes: [{ plugin_id: "activerecord", name: :model_index, optional: true }]
|
|
54
45
|
)
|
|
55
46
|
|
|
56
|
-
# Cached: attachment index. Walks every `.rb` file under
|
|
57
|
-
#
|
|
58
|
-
#
|
|
59
|
-
# in-block reads are captured into the record-and-validate
|
|
60
|
-
# dependency descriptor after the block runs.
|
|
47
|
+
# Cached: attachment index. Walks every `.rb` file under `model_search_paths` for `has_*_attached`
|
|
48
|
+
# macros. `watch:` (ADR-60 WD3) covers model-file additions; the discoverer's in-block reads are
|
|
49
|
+
# captured into the record-and-validate dependency descriptor after the block runs.
|
|
61
50
|
producer :attachment_index, watch: -> { [[@model_search_paths, "**/*.rb"]] } do |_params|
|
|
62
51
|
rows = AttachmentDiscoverer.new(
|
|
63
52
|
io_boundary: io_boundary,
|
|
@@ -80,18 +69,12 @@ module Rigor
|
|
|
80
69
|
Analyzer.new(path: path, attachment_index: index).analyze(root).diagnostics
|
|
81
70
|
end
|
|
82
71
|
|
|
83
|
-
# Return-type contribution: when the receiver is
|
|
84
|
-
# `Nominal[
|
|
85
|
-
#
|
|
86
|
-
#
|
|
87
|
-
# `
|
|
88
|
-
#
|
|
89
|
-
# model class names from the attachment index.
|
|
90
|
-
# The chained call (`.attached?`, `.purge`, `.url`)
|
|
91
|
-
# then resolves through ActiveStorage's RBS surface.
|
|
92
|
-
# Attachment setters (`user.avatar=`) decline — they
|
|
93
|
-
# take side-effecting argument types that the RBS
|
|
94
|
-
# surface already covers.
|
|
72
|
+
# Return-type contribution: when the receiver is `Nominal[Model]` and the method matches a
|
|
73
|
+
# discovered attachment, narrows to `Nominal[ActiveStorage::Attached::One]` (singular) or
|
|
74
|
+
# `Nominal[ActiveStorage::Attached::Many]` (collection) via a `dynamic_return` rule keyed on the
|
|
75
|
+
# live set of model class names from the attachment index. The chained call (`.attached?`, `.purge`,
|
|
76
|
+
# `.url`) then resolves through ActiveStorage's RBS surface. Attachment setters (`user.avatar=`)
|
|
77
|
+
# decline — they take side-effecting argument types that the RBS surface already covers.
|
|
95
78
|
dynamic_return receivers: -> { attachment_index&.class_names || [] } do |call_node, scope|
|
|
96
79
|
next nil unless call_node.is_a?(Prism::CallNode)
|
|
97
80
|
next nil if call_node.receiver.nil?
|
|
@@ -129,10 +112,9 @@ module Rigor
|
|
|
129
112
|
def attachment_index
|
|
130
113
|
return @attachment_index if @attachment_index
|
|
131
114
|
|
|
132
|
-
# ADR-60 WD3 record-and-validate: the producer's in-block
|
|
133
|
-
#
|
|
134
|
-
#
|
|
135
|
-
# producer's `watch:` covers model-file additions.
|
|
115
|
+
# ADR-60 WD3 record-and-validate: the producer's in-block `AttachmentDiscoverer` reads are
|
|
116
|
+
# captured into the dependency descriptor after the block runs, and the producer's `watch:`
|
|
117
|
+
# covers model-file additions.
|
|
136
118
|
@attachment_index = cache_for(:attachment_index, params: {}).call
|
|
137
119
|
rescue Plugin::AccessDeniedError => e
|
|
138
120
|
@load_errors << "rigor-activestorage: #{e.message}"
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# Entry point matching the `rigor-<id>` gem-name convention.
|
|
4
|
-
#
|
|
5
|
-
# `
|
|
6
|
-
# plugin's actual implementation under the `rigor/plugin/`
|
|
7
|
-
# namespace so the require / register pair fires.
|
|
3
|
+
# Entry point matching the `rigor-<id>` gem-name convention. The Plugin::Loader's `require_gem!` step
|
|
4
|
+
# calls `require "rigor-activestorage"`, and this file loads the plugin's actual implementation under
|
|
5
|
+
# the `rigor/plugin/` namespace so the require / register pair fires.
|
|
8
6
|
require "rigor/plugin/activestorage"
|
|
@@ -4,14 +4,11 @@ require "rigor/plugin"
|
|
|
4
4
|
|
|
5
5
|
module Rigor
|
|
6
6
|
module Plugin
|
|
7
|
-
# ADR-25 — a pure RBS-bundle plugin. It ships NO analyzer code:
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
# this gem's root and `Environment.for_project` merges it into
|
|
13
|
-
# the RBS environment, so the ActiveSupport core-extension
|
|
14
|
-
# selectors (`3.days`, `"x".squish`, `Time.current`, …) resolve.
|
|
7
|
+
# ADR-25 — a pure RBS-bundle plugin. It ships NO analyzer code: no `diagnostics_for_file`, no
|
|
8
|
+
# `dynamic_return`. Its whole contribution is the manifest's `signature_paths: ["sig"]`, which
|
|
9
|
+
# declares the bundled ActiveSupport `core_ext` RBS directory. `Plugin::Loader` resolves that
|
|
10
|
+
# directory against this gem's root and `Environment.for_project` merges it into the RBS environment,
|
|
11
|
+
# so the ActiveSupport core-extension selectors (`3.days`, `"x".squish`, `Time.current`, …) resolve.
|
|
15
12
|
#
|
|
16
13
|
# Activate it like any plugin — no path, no vendoring:
|
|
17
14
|
#
|
|
@@ -23,8 +20,7 @@ module Rigor
|
|
|
23
20
|
class ActivesupportCoreExt < Rigor::Plugin::Base
|
|
24
21
|
manifest(
|
|
25
22
|
id: "activesupport-core-ext",
|
|
26
|
-
# Bumped 2026-05-28 — added Date#midnight /
|
|
27
|
-
# at_midnight / beginning_of_day / end_of_day (Rails
|
|
23
|
+
# Bumped 2026-05-28 — added Date#midnight / at_midnight / beginning_of_day / end_of_day (Rails
|
|
28
24
|
# aliases that return Time, not Date).
|
|
29
25
|
version: "0.2.0",
|
|
30
26
|
description: "RBS bundle for the most-frequently-flagged ActiveSupport core_ext extensions.",
|
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# rigor-activesupport-core-ext — a community-maintained RBS bundle
|
|
4
|
-
#
|
|
3
|
+
# rigor-activesupport-core-ext — a community-maintained RBS bundle for the most-frequently-flagged
|
|
4
|
+
# ActiveSupport core extensions.
|
|
5
5
|
#
|
|
6
|
-
# Per ADR-25 this gem is a pure RBS-bundle *plugin*: it ships a
|
|
7
|
-
# `
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
# resolves and loads the bundled `sig/` automatically, with no
|
|
11
|
-
# hand-written path:
|
|
6
|
+
# Per ADR-25 this gem is a pure RBS-bundle *plugin*: it ships a `sig/` directory and a trivial
|
|
7
|
+
# `Rigor::Plugin::Base` subclass whose manifest declares `signature_paths: ["sig"]`. Activate it by
|
|
8
|
+
# listing the gem under `.rigor.yml`'s `plugins:` — Rigor resolves and loads the bundled `sig/`
|
|
9
|
+
# automatically, with no hand-written path:
|
|
12
10
|
#
|
|
13
11
|
# # .rigor.yml
|
|
14
12
|
# plugins:
|
|
15
13
|
# - rigor-activesupport-core-ext
|
|
16
14
|
#
|
|
17
|
-
# Coverage scope and rationale: see `README.md` in this directory
|
|
18
|
-
#
|
|
19
|
-
# survey that established the selector ranking.
|
|
15
|
+
# Coverage scope and rationale: see `README.md` in this directory and
|
|
16
|
+
# `docs/notes/20260515-real-world-rails-survey.md` for the survey that established the selector ranking.
|
|
20
17
|
require_relative "rigor/plugin/activesupport_core_ext"
|
|
@@ -62,6 +62,9 @@ class Object
|
|
|
62
62
|
# `acts_like?(:string)` / `acts_like?(:date)` / `acts_like?(:time)`
|
|
63
63
|
# is ActiveSupport's "duck-typing helper" predicate.
|
|
64
64
|
def acts_like?: (Symbol | String) -> bool
|
|
65
|
+
|
|
66
|
+
# `core_ext/object/inclusion` — `x.in?([a, b])` / `x.in?(1..10)`.
|
|
67
|
+
def in?: (untyped) -> bool
|
|
65
68
|
end
|
|
66
69
|
|
|
67
70
|
# `nil.blank?` / `nil.present?` / `nil.try` are the most frequent
|
|
@@ -99,6 +102,9 @@ class String
|
|
|
99
102
|
def demodulize: () -> String
|
|
100
103
|
def deconstantize: () -> String
|
|
101
104
|
def titleize: () -> String
|
|
105
|
+
def titlecase: () -> String
|
|
106
|
+
def dasherize: () -> String
|
|
107
|
+
def upcase_first: () -> String
|
|
102
108
|
def parameterize: (?separator: String, ?preserve_case: bool, ?locale: Symbol?) -> String
|
|
103
109
|
def tableize: () -> String
|
|
104
110
|
def foreign_key: (?bool separate_class_name_and_id_with_underscore) -> String
|
|
@@ -112,6 +118,9 @@ class String
|
|
|
112
118
|
def truncate: (Integer truncate_at, ?omission: String, ?separator: String | Regexp | nil) -> String
|
|
113
119
|
def truncate_bytes: (Integer truncate_at, ?omission: String) -> String
|
|
114
120
|
def truncate_words: (Integer words_count, ?omission: String, ?separator: String | Regexp | nil) -> String
|
|
121
|
+
# `remove` / `remove!` delete every occurrence of the given patterns.
|
|
122
|
+
def remove: (*Regexp | String patterns) -> String
|
|
123
|
+
def remove!: (*Regexp | String patterns) -> String
|
|
115
124
|
|
|
116
125
|
# `core_ext/string/output_safety` — `html_safe` returns an
|
|
117
126
|
# `ActiveSupport::SafeBuffer` (a String subclass). The closest
|
|
@@ -274,6 +283,9 @@ class Time
|
|
|
274
283
|
def noon: () -> Time
|
|
275
284
|
def utc?: () -> bool
|
|
276
285
|
def acts_like_time?: () -> true
|
|
286
|
+
# `advance(days: 1, months: -2)` and `all_day` (a `beginning_of_day..end_of_day` Range).
|
|
287
|
+
def advance: (untyped options) -> Time
|
|
288
|
+
def all_day: () -> Range[Time]
|
|
277
289
|
end
|
|
278
290
|
|
|
279
291
|
# ---------------------------------------------------------------
|
|
@@ -314,6 +326,11 @@ class Date
|
|
|
314
326
|
def at_beginning_of_day: () -> Time
|
|
315
327
|
def end_of_day: () -> Time
|
|
316
328
|
def at_end_of_day: () -> Time
|
|
329
|
+
# `advance(days: 1)`, `all_day` (a Time Range), and `to_time(form)` — the
|
|
330
|
+
# `:local` / `:utc` form arg core RBS' `Date#to_time` (arity 0) omits.
|
|
331
|
+
def advance: (untyped options) -> Date
|
|
332
|
+
def all_day: () -> Range[Time]
|
|
333
|
+
def to_time: (?Symbol form) -> Time
|
|
317
334
|
end
|
|
318
335
|
|
|
319
336
|
# ---------------------------------------------------------------
|
|
@@ -476,3 +493,18 @@ end
|
|
|
476
493
|
class String
|
|
477
494
|
def exclude?: (String) -> bool
|
|
478
495
|
end
|
|
496
|
+
|
|
497
|
+
# ---------------------------------------------------------------
|
|
498
|
+
# ERB::Util — ActionView extends it with `html_escape_once`
|
|
499
|
+
# ---------------------------------------------------------------
|
|
500
|
+
|
|
501
|
+
# `ERB` is a CLASS in Ruby / RBS (not a module), so reopen it as a class —
|
|
502
|
+
# a `module ERB` wrapper collides with upstream `class ERB` once the `erb`
|
|
503
|
+
# stdlib is in scope. `ERB::Util` itself is a module.
|
|
504
|
+
class ERB
|
|
505
|
+
module Util
|
|
506
|
+
# `ERB::Util.html_escape_once(s)` escapes HTML without double-escaping
|
|
507
|
+
# an already-escaped entity. ActionView adds it on top of stdlib ERB.
|
|
508
|
+
def self.html_escape_once: (untyped) -> String
|
|
509
|
+
end
|
|
510
|
+
end
|
|
@@ -4,26 +4,21 @@ require "rigor/plugin"
|
|
|
4
4
|
|
|
5
5
|
module Rigor
|
|
6
6
|
module Plugin
|
|
7
|
-
# ADR-16 Tier B worked plugin: recognises Devise's model-side
|
|
8
|
-
# `
|
|
9
|
-
# subclasses and explodes each strategy's module RBS into the
|
|
10
|
-
# calling class.
|
|
7
|
+
# ADR-16 Tier B worked plugin: recognises Devise's model-side `devise :strategy_a, :strategy_b` DSL on
|
|
8
|
+
# `ActiveRecord::Base` subclasses and explodes each strategy's module RBS into the calling class.
|
|
11
9
|
#
|
|
12
|
-
# Per the per-library survey (§ Devise), Devise's `devise(*modules)`
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
# `Devise
|
|
17
|
-
# calling class
|
|
18
|
-
#
|
|
19
|
-
# Devise's `lib/devise/modules.rb` and the pre-pass scanner
|
|
20
|
-
# synthesises one SyntheticMethod per (calling class, included
|
|
21
|
-
# module instance method) pair into the SyntheticMethodIndex.
|
|
10
|
+
# Per the per-library survey (§ Devise), Devise's `devise(*modules)` at `lib/devise/models.rb:79-112`
|
|
11
|
+
# is a **table-driven include sequence**: each Symbol argument resolves through
|
|
12
|
+
# `Devise::Models.const_get(m.to_s.classify)` to a concrete `Devise::Models::*` module, which is then
|
|
13
|
+
# mixed into the calling class. The substrate replays the same shape statically — the manifest's
|
|
14
|
+
# `modules_by_symbol:` mirrors Devise's `lib/devise/modules.rb` and the pre-pass scanner synthesises
|
|
15
|
+
# one SyntheticMethod per (calling class, included module instance method) pair into the
|
|
16
|
+
# SyntheticMethodIndex.
|
|
22
17
|
#
|
|
23
18
|
# ## Reach
|
|
24
19
|
#
|
|
25
|
-
# The full set of strategies Devise registers via
|
|
26
|
-
# `
|
|
20
|
+
# The full set of strategies Devise registers via `Devise.add_module` at gem load (per
|
|
21
|
+
# `lib/devise/modules.rb`):
|
|
27
22
|
#
|
|
28
23
|
# - `:database_authenticatable` — password + email auth core
|
|
29
24
|
# - `:recoverable` — password-reset flow
|
|
@@ -37,41 +32,31 @@ module Rigor
|
|
|
37
32
|
# - `:omniauthable` — OmniAuth providers
|
|
38
33
|
# - `:authenticatable` — always-included base module
|
|
39
34
|
#
|
|
40
|
-
# The substrate's pre-pass scanner consults each module's RBS
|
|
41
|
-
# via
|
|
42
|
-
#
|
|
43
|
-
#
|
|
44
|
-
# `send_reset_password_instructions`, etc. resolve through the
|
|
45
|
-
# synthetic-method tier without `call.undefined-method`.
|
|
35
|
+
# The substrate's pre-pass scanner consults each module's RBS via `Environment::RbsLoader#instance_definition`
|
|
36
|
+
# to enumerate method names. A user project providing real Devise via Bundler will see methods like
|
|
37
|
+
# `valid_password?`, `send_reset_password_instructions`, etc. resolve through the synthetic-method
|
|
38
|
+
# tier without `call.undefined-method`.
|
|
46
39
|
#
|
|
47
40
|
# ## Precision tier
|
|
48
41
|
#
|
|
49
|
-
# The scanner records `origin_module:` in each synthetic
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
# `
|
|
53
|
-
# authored RBS return types win: `valid_password?` returns
|
|
54
|
-
# `bool`, not `Dynamic[T]`. Unknown return types degrade
|
|
55
|
-
# gracefully to `Dynamic[T]`.
|
|
42
|
+
# The scanner records `origin_module:` in each synthetic method's provenance. The dispatcher's
|
|
43
|
+
# slice-6a TierB path (`promote_via_origin_module`) redispatches on `Nominal[origin_module]` via
|
|
44
|
+
# `RbsDispatch`, so Devise's authored RBS return types win: `valid_password?` returns `bool`, not
|
|
45
|
+
# `Dynamic[T]`. Unknown return types degrade gracefully to `Dynamic[T]`.
|
|
56
46
|
#
|
|
57
47
|
# ## Scope
|
|
58
48
|
#
|
|
59
|
-
# - Recognises model-side `devise :a, :b` on any AR::Base
|
|
60
|
-
#
|
|
61
|
-
# - `Devise::Models::Authenticatable` is always_included
|
|
62
|
-
#
|
|
63
|
-
#
|
|
64
|
-
#
|
|
65
|
-
#
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
# -
|
|
69
|
-
#
|
|
70
|
-
# slice that consumes ADR-9 fact-store entries from a
|
|
71
|
-
# `rigor-rails-routes`-style walker.
|
|
72
|
-
# - Per-strategy `ClassMethods` extend (Devise's `extend
|
|
73
|
-
# Mod::ClassMethods` pattern) is NOT yet wired — slice 3
|
|
74
|
-
# covers instance methods only per WD13 floor.
|
|
49
|
+
# - Recognises model-side `devise :a, :b` on any AR::Base subclass; trait symbol set mirrors
|
|
50
|
+
# `lib/devise/modules.rb`.
|
|
51
|
+
# - `Devise::Models::Authenticatable` is always_included (matches Devise's `with_options model: true`).
|
|
52
|
+
# - Unknown trait symbols silently skipped (per slice-3 design judgment (2)). User initializers that
|
|
53
|
+
# call `Devise.add_module :my_strategy, ...` are NOT seen — that path requires a separate scanner
|
|
54
|
+
# for `config/initializers/` and is deferred.
|
|
55
|
+
# - Controller-side helpers (`current_user`, `authenticate_user!`, etc.) are Tier C work, NOT Tier B;
|
|
56
|
+
# deferred to a future slice that consumes ADR-9 fact-store entries from a `rigor-rails-routes`-style
|
|
57
|
+
# walker.
|
|
58
|
+
# - Per-strategy `ClassMethods` extend (Devise's `extend Mod::ClassMethods` pattern) is NOT yet wired
|
|
59
|
+
# — slice 3 covers instance methods only per WD13 floor.
|
|
75
60
|
class Devise < Rigor::Plugin::Base
|
|
76
61
|
manifest(
|
|
77
62
|
id: "devise",
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# Gem entry point. Required by Rigor's plugin loader when
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# `Rigor::Plugin.register`, which the body of
|
|
7
|
-
# `lib/rigor/plugin/devise.rb` performs at load time.
|
|
3
|
+
# Gem entry point. Required by Rigor's plugin loader when `.rigor.yml` lists `rigor-devise` under
|
|
4
|
+
# `plugins:`. The loader expects this `require` to side-effect a call to `Rigor::Plugin.register`,
|
|
5
|
+
# which the body of `lib/rigor/plugin/devise.rb` performs at load time.
|
|
8
6
|
require_relative "rigor/plugin/devise"
|