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,44 +3,32 @@
|
|
|
3
3
|
module Rigor
|
|
4
4
|
module Plugin
|
|
5
5
|
class Activerecord < Rigor::Plugin::Base
|
|
6
|
-
# Maps a discovered ActiveRecord model class name to its
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
# trips it through the standard pair.
|
|
6
|
+
# Maps a discovered ActiveRecord model class name to its resolved table name and the column set the
|
|
7
|
+
# schema attaches to that table. Marshal-clean; the cache producer round-trips it through the
|
|
8
|
+
# standard pair.
|
|
10
9
|
#
|
|
11
10
|
# Construction is two-phase by design:
|
|
12
|
-
# 1. {ModelDiscoverer} walks the project source for model
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
# 2. The plugin combines those rows with the parsed
|
|
16
|
-
# {SchemaTable} to produce this index.
|
|
11
|
+
# 1. {ModelDiscoverer} walks the project source for model class declarations (direct base-class
|
|
12
|
+
# children plus transitive STI subclasses) and yields a row per model.
|
|
13
|
+
# 2. The plugin combines those rows with the parsed {SchemaTable} to produce this index.
|
|
17
14
|
#
|
|
18
|
-
# `table_name_override` is non-nil when the source contained
|
|
19
|
-
#
|
|
20
|
-
# derives from {Inflector.tableize}.
|
|
15
|
+
# `table_name_override` is non-nil when the source contained `self.table_name = "..."`. When nil,
|
|
16
|
+
# the table name derives from {Inflector.tableize}.
|
|
21
17
|
#
|
|
22
|
-
# Single-table-inheritance subclasses (`class Admin < User`)
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
# declared associations / enums / aliases / scopes /
|
|
26
|
-
# validations / callbacks.
|
|
18
|
+
# Single-table-inheritance subclasses (`class Admin < User`) carry an `sti_parent:` pointer; their
|
|
19
|
+
# {Entry} resolves its table from the root model and inherits the chain's declared associations /
|
|
20
|
+
# enums / aliases / scopes / validations / callbacks.
|
|
27
21
|
class ModelIndex
|
|
28
|
-
# `associations` is a frozen `Array<Hash>` where each
|
|
29
|
-
#
|
|
22
|
+
# `associations` is a frozen `Array<Hash>` where each row carries `{ name:, kind:, target:,
|
|
23
|
+
# nullable: }`:
|
|
30
24
|
#
|
|
31
|
-
# - `name` — String, the association method name as
|
|
32
|
-
#
|
|
33
|
-
# - `
|
|
34
|
-
# or `:collection` (`has_many`).
|
|
35
|
-
# - `target` — String, the target class name resolved
|
|
36
|
-
# either from an explicit `class_name:`
|
|
25
|
+
# - `name` — String, the association method name as the user invokes it (`"posts"`).
|
|
26
|
+
# - `kind` — `:singular` (`belongs_to` / `has_one`) or `:collection` (`has_many`).
|
|
27
|
+
# - `target` — String, the target class name resolved either from an explicit `class_name:`
|
|
37
28
|
# option or via {Inflector.classify}.
|
|
38
|
-
# - `nullable` — Boolean; whether a `:singular` accessor
|
|
39
|
-
#
|
|
40
|
-
# `
|
|
41
|
-
# since Rails 5) unless `optional: true` /
|
|
42
|
-
# `required: false`. Meaningless for
|
|
43
|
-
# `:collection` rows.
|
|
29
|
+
# - `nullable` — Boolean; whether a `:singular` accessor can return `nil`. `has_one` → `true`;
|
|
30
|
+
# `belongs_to` → `false` (required by default since Rails 5) unless `optional: true`
|
|
31
|
+
# / `required: false`. Meaningless for `:collection` rows.
|
|
44
32
|
Entry = Struct.new(:class_name, :table_name, :columns, :associations,
|
|
45
33
|
:enums, :scopes, :validations, :callbacks, :aliases,
|
|
46
34
|
keyword_init: true) do
|
|
@@ -71,8 +59,7 @@ module Rigor
|
|
|
71
59
|
# `scopes` is `Array<scope_name>`.
|
|
72
60
|
def scope?(name) = scopes.include?(name.to_s)
|
|
73
61
|
|
|
74
|
-
# `validations` is `Array<attribute_name>` covering
|
|
75
|
-
# both `validates :name, ...` and the
|
|
62
|
+
# `validations` is `Array<attribute_name>` covering both `validates :name, ...` and the
|
|
76
63
|
# `validates_*_of :name, ...` shorthand families.
|
|
77
64
|
def validation?(name) = validations.include?(name.to_s)
|
|
78
65
|
def validated_attributes = validations
|
|
@@ -80,8 +67,8 @@ module Rigor
|
|
|
80
67
|
# `callbacks` is `Array<{ name:, callback: }>`.
|
|
81
68
|
def callback_targets = callbacks.map { |c| c[:name] }
|
|
82
69
|
|
|
83
|
-
# `aliases` is `Hash<alias_name => target_attribute>`
|
|
84
|
-
#
|
|
70
|
+
# `aliases` is `Hash<alias_name => target_attribute>` populated from `alias_attribute`
|
|
71
|
+
# declarations.
|
|
85
72
|
def alias?(name) = aliases.key?(name.to_s)
|
|
86
73
|
def resolve_alias(name) = aliases[name.to_s]
|
|
87
74
|
end
|
|
@@ -106,17 +93,14 @@ module Rigor
|
|
|
106
93
|
|
|
107
94
|
entries = model_rows.each_with_object({}) do |row, acc|
|
|
108
95
|
class_name = row.fetch(:class_name)
|
|
109
|
-
# The STI ancestry chain, root → self. For a plain
|
|
110
|
-
# (non-STI) model this is just `[row]`.
|
|
96
|
+
# The STI ancestry chain, root → self. For a plain (non-STI) model this is just `[row]`.
|
|
111
97
|
chain = sti_chain(row, rows_by_name)
|
|
112
98
|
table_name = sti_table_name(chain)
|
|
113
99
|
columns = schema_table.columns_for(table_name) || []
|
|
114
100
|
|
|
115
|
-
# STI children inherit their ancestors' declared
|
|
116
|
-
#
|
|
117
|
-
#
|
|
118
|
-
# `where(<parent-association>: ...)` on the child
|
|
119
|
-
# would surface as a false `unknown-column`.
|
|
101
|
+
# STI children inherit their ancestors' declared associations / enums / aliases / scopes /
|
|
102
|
+
# validations / callbacks. Without the merge a `where(<parent-association>: ...)` on the
|
|
103
|
+
# child would surface as a false `unknown-column`.
|
|
120
104
|
acc[class_name] = Entry.new(
|
|
121
105
|
class_name: class_name,
|
|
122
106
|
table_name: table_name,
|
|
@@ -132,8 +116,8 @@ module Rigor
|
|
|
132
116
|
new(entries.freeze)
|
|
133
117
|
end
|
|
134
118
|
|
|
135
|
-
# The STI ancestry chain for a row, ordered root → self.
|
|
136
|
-
#
|
|
119
|
+
# The STI ancestry chain for a row, ordered root → self. Walks `sti_parent` pointers, guarding
|
|
120
|
+
# against a cycle.
|
|
137
121
|
def self.sti_chain(row, rows_by_name, seen = [])
|
|
138
122
|
class_name = row.fetch(:class_name)
|
|
139
123
|
parent_name = row[:sti_parent]
|
|
@@ -145,9 +129,8 @@ module Rigor
|
|
|
145
129
|
sti_chain(parent, rows_by_name, seen + [class_name]) + [row]
|
|
146
130
|
end
|
|
147
131
|
|
|
148
|
-
# The effective table name for an STI chain: the nearest
|
|
149
|
-
#
|
|
150
|
-
# root, else the name inflected from the root class.
|
|
132
|
+
# The effective table name for an STI chain: the nearest explicit `self.table_name =` override
|
|
133
|
+
# walking leaf → root, else the name inflected from the root class.
|
|
151
134
|
def self.sti_table_name(chain)
|
|
152
135
|
chain.reverse_each do |row|
|
|
153
136
|
override = row[:table_name_override]
|
|
@@ -156,18 +139,16 @@ module Rigor
|
|
|
156
139
|
Rigor::Plugin::Inflector.tableize(strip_leading_namespace(chain.first.fetch(:class_name)))
|
|
157
140
|
end
|
|
158
141
|
|
|
159
|
-
# Dedups association-style rows by `:name`, keeping the
|
|
160
|
-
#
|
|
161
|
-
# inherited ancestor row.
|
|
142
|
+
# Dedups association-style rows by `:name`, keeping the LAST occurrence so a child redeclaration
|
|
143
|
+
# overrides the inherited ancestor row.
|
|
162
144
|
def self.merge_named_rows(rows)
|
|
163
145
|
seen = {}
|
|
164
146
|
rows.each { |row| seen[row[:name]] = row }
|
|
165
147
|
seen.values.map(&:freeze).freeze
|
|
166
148
|
end
|
|
167
149
|
|
|
168
|
-
# `Hash<column => Array<value>>` merged across the STI
|
|
169
|
-
#
|
|
170
|
-
# overrides the ancestor's value list.
|
|
150
|
+
# `Hash<column => Array<value>>` merged across the STI chain; a child redeclaration of the same
|
|
151
|
+
# enum column overrides the ancestor's value list.
|
|
171
152
|
def self.merge_enums(chain)
|
|
172
153
|
chain.each_with_object({}) do |row, acc|
|
|
173
154
|
(row[:enums] || {}).each { |col, values| acc[col] = Array(values).map(&:freeze).freeze }
|
|
@@ -181,10 +162,8 @@ module Rigor
|
|
|
181
162
|
end.freeze
|
|
182
163
|
end
|
|
183
164
|
|
|
184
|
-
# `::User` → `User`. The discoverer might prefix with
|
|
185
|
-
#
|
|
186
|
-
# resolved the path; the table-name derivation uses the
|
|
187
|
-
# short form regardless.
|
|
165
|
+
# `::User` → `User`. The discoverer might prefix with `::` for top-level constants depending on
|
|
166
|
+
# how it resolved the path; the table-name derivation uses the short form regardless.
|
|
188
167
|
def self.strip_leading_namespace(name)
|
|
189
168
|
name.start_with?("::") ? name[2..] : name
|
|
190
169
|
end
|
|
@@ -21,30 +21,23 @@ module Rigor
|
|
|
21
21
|
# end
|
|
22
22
|
# end
|
|
23
23
|
#
|
|
24
|
-
# `t.references "x"` becomes an `x_id` integer column
|
|
25
|
-
#
|
|
26
|
-
# column
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
# whose type symbol is the method name — unknown types degrade
|
|
32
|
-
# to `Object` per `SchemaTable.ruby_type_for` rather than being
|
|
33
|
-
# dropped. Only the structural calls in {NON_COLUMN_METHODS}
|
|
34
|
-
# (indexes, constraints, foreign keys) are skipped.
|
|
24
|
+
# `t.references "x"` becomes an `x_id` integer column (foreign-key indices and constraints are
|
|
25
|
+
# ignored — only the column shape matters for type inference); add a `polymorphic: true` option and
|
|
26
|
+
# an `x_type` string column is emitted too. `t.timestamps` adds `created_at` and `updated_at`
|
|
27
|
+
# datetime columns. `t.column "x", :type` is the generic column form. Any other `t.<method> "name"`
|
|
28
|
+
# call is treated as a column whose type symbol is the method name — unknown types degrade to
|
|
29
|
+
# `Object` per `SchemaTable.ruby_type_for` rather than being dropped. Only the structural calls in
|
|
30
|
+
# {NON_COLUMN_METHODS} (indexes, constraints, foreign keys) are skipped.
|
|
35
31
|
#
|
|
36
|
-
# Designed for the Prism interpretation pattern from
|
|
37
|
-
#
|
|
32
|
+
# Designed for the Prism interpretation pattern from rigor-lisp-eval — recursive descent on the AST,
|
|
33
|
+
# no eval.
|
|
38
34
|
class SchemaParser
|
|
39
35
|
TIMESTAMPS_COLUMNS = %w[created_at updated_at].freeze
|
|
40
36
|
|
|
41
|
-
# Structural `t.<method>` calls inside a `create_table`
|
|
42
|
-
#
|
|
43
|
-
#
|
|
44
|
-
#
|
|
45
|
-
# so a real column is never silently dropped — a dropped
|
|
46
|
-
# column turns every query against it into a false
|
|
47
|
-
# `unknown-column` diagnostic.
|
|
37
|
+
# Structural `t.<method>` calls inside a `create_table` block that declare indexes / constraints
|
|
38
|
+
# rather than columns. Everything NOT in this set that carries a literal column name is treated as
|
|
39
|
+
# a column declaration so a real column is never silently dropped — a dropped column turns every
|
|
40
|
+
# query against it into a false `unknown-column` diagnostic.
|
|
48
41
|
NON_COLUMN_METHODS = %i[
|
|
49
42
|
index check_constraint exclusion_constraint
|
|
50
43
|
unique_constraint foreign_key primary_keys
|
|
@@ -114,10 +107,9 @@ module Rigor
|
|
|
114
107
|
false
|
|
115
108
|
end
|
|
116
109
|
|
|
117
|
-
# Walks the block body collecting `t.<method>(...)` calls.
|
|
118
|
-
#
|
|
119
|
-
#
|
|
120
|
-
# parser falls back silently.
|
|
110
|
+
# Walks the block body collecting `t.<method>(...)` calls. Skips nested blocks (e.g. inside
|
|
111
|
+
# `if`-conditioned columns) only at the top level — for richer schema constructs the parser falls
|
|
112
|
+
# back silently.
|
|
121
113
|
def collect_column_calls(node, &)
|
|
122
114
|
return if node.nil?
|
|
123
115
|
|
|
@@ -139,13 +131,11 @@ module Rigor
|
|
|
139
131
|
when :column
|
|
140
132
|
parse_generic_column(call_node)
|
|
141
133
|
else
|
|
142
|
-
# Structural DSL call (index / constraint / FK) —
|
|
143
|
-
# not a column.
|
|
134
|
+
# Structural DSL call (index / constraint / FK) — not a column.
|
|
144
135
|
return nil if NON_COLUMN_METHODS.include?(method)
|
|
145
136
|
|
|
146
|
-
# Any other `t.<method> "name"` is a column. The
|
|
147
|
-
#
|
|
148
|
-
# degrade to `Object` rather than dropping the column.
|
|
137
|
+
# Any other `t.<method> "name"` is a column. The method name is the type symbol; unknown
|
|
138
|
+
# types degrade to `Object` rather than dropping the column.
|
|
149
139
|
parse_typed_column(method, call_node)
|
|
150
140
|
end
|
|
151
141
|
end
|
|
@@ -162,11 +152,9 @@ module Rigor
|
|
|
162
152
|
)
|
|
163
153
|
end
|
|
164
154
|
|
|
165
|
-
# `t.references "x"` adds an `x_id` integer column.
|
|
166
|
-
# `
|
|
167
|
-
#
|
|
168
|
-
# `where(x_type: ...)` on the polymorphic owner surfaces
|
|
169
|
-
# as a false `unknown-column`.
|
|
155
|
+
# `t.references "x"` adds an `x_id` integer column. `t.references "x", polymorphic: true`
|
|
156
|
+
# additionally adds an `x_type` string column — without it every `where(x_type: ...)` on the
|
|
157
|
+
# polymorphic owner surfaces as a false `unknown-column`.
|
|
170
158
|
def parse_references_column(call_node)
|
|
171
159
|
name = string_argument(call_node, 0)
|
|
172
160
|
return nil if name.nil?
|
|
@@ -184,10 +172,9 @@ module Rigor
|
|
|
184
172
|
keyword_true?(call_node, :polymorphic)
|
|
185
173
|
end
|
|
186
174
|
|
|
187
|
-
# Returns true iff `call_node` has a `name: true` keyword
|
|
188
|
-
#
|
|
189
|
-
#
|
|
190
|
-
# column) and `t.references "x", polymorphic: true`.
|
|
175
|
+
# Returns true iff `call_node` has a `name: true` keyword argument. Used to detect schema
|
|
176
|
+
# modifiers like `t.bigint "status_ids", array: true` (Postgres array column) and `t.references
|
|
177
|
+
# "x", polymorphic: true`.
|
|
191
178
|
def keyword_true?(call_node, name)
|
|
192
179
|
return false if call_node.arguments.nil?
|
|
193
180
|
|
|
@@ -204,9 +191,8 @@ module Rigor
|
|
|
204
191
|
false
|
|
205
192
|
end
|
|
206
193
|
|
|
207
|
-
# `t.column "name", "type"` / `t.column "name", :type` —
|
|
208
|
-
# the
|
|
209
|
-
# second argument; an absent type degrades to `:string`.
|
|
194
|
+
# `t.column "name", "type"` / `t.column "name", :type` — the explicit generic column form. The
|
|
195
|
+
# type lives in the second argument; an absent type degrades to `:string`.
|
|
210
196
|
def parse_generic_column(call_node)
|
|
211
197
|
name = string_argument(call_node, 0)
|
|
212
198
|
return nil if name.nil?
|
|
@@ -3,18 +3,15 @@
|
|
|
3
3
|
module Rigor
|
|
4
4
|
module Plugin
|
|
5
5
|
class Activerecord < Rigor::Plugin::Base
|
|
6
|
-
# Parsed `db/schema.rb`. Maps each table name to its column
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
# without a custom serialize / deserialize pair.
|
|
6
|
+
# Parsed `db/schema.rb`. Maps each table name to its column set; each column carries its declared
|
|
7
|
+
# type. Marshal-clean by construction so the cache producer can round-trip it without a custom
|
|
8
|
+
# serialize / deserialize pair.
|
|
10
9
|
#
|
|
11
|
-
# The mapping from Rails column types to Ruby class names is
|
|
12
|
-
#
|
|
13
|
-
# `:
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
# ltree, hstore, custom) fall back to `Object` so the
|
|
17
|
-
# plugin stays silent rather than guessing.
|
|
10
|
+
# The mapping from Rails column types to Ruby class names is deliberately conservative —
|
|
11
|
+
# `:string`/`:text` → `String`, `:integer`/`:bigint` → `Integer`, `:boolean` → `bool`,
|
|
12
|
+
# `:datetime`/`:timestamp` → `Time`, `:date` → `Date`, `:decimal`/`:float` → `Float`. Exotic types
|
|
13
|
+
# (json, jsonb, ltree, hstore, custom) fall back to `Object` so the plugin stays silent rather than
|
|
14
|
+
# guessing.
|
|
18
15
|
class SchemaTable
|
|
19
16
|
Column = Struct.new(:name, :type, :ruby_type, :array, keyword_init: true) do
|
|
20
17
|
def to_h = { name: name, type: type, ruby_type: ruby_type, array: array }
|
|
@@ -40,21 +37,17 @@ module Rigor
|
|
|
40
37
|
binary: "String",
|
|
41
38
|
json: "Object",
|
|
42
39
|
jsonb: "Object",
|
|
43
|
-
# PostgreSQL-flavoured string-ish column types Rails
|
|
44
|
-
#
|
|
45
|
-
#
|
|
46
|
-
# them here keeps the column out of the "unknown type
|
|
47
|
-
# → dropped column → false unknown-column" path.
|
|
40
|
+
# PostgreSQL-flavoured string-ish column types Rails schemas commonly carry. `uuid` / `citext` /
|
|
41
|
+
# `inet` all behave as `String` for query purposes; mapping them here keeps the column out of
|
|
42
|
+
# the "unknown type → dropped column → false unknown-column" path.
|
|
48
43
|
uuid: "String",
|
|
49
44
|
citext: "String",
|
|
50
45
|
inet: "String"
|
|
51
46
|
}.freeze
|
|
52
47
|
|
|
53
|
-
# Implicit columns that every Rails table has unless the
|
|
54
|
-
#
|
|
55
|
-
#
|
|
56
|
-
# implicit `id` column from the parser, but most apps
|
|
57
|
-
# never disable it.
|
|
48
|
+
# Implicit columns that every Rails table has unless the schema explicitly opts out. The plugin
|
|
49
|
+
# assumes these exist; users who run `create_table id: false` get no implicit `id` column from
|
|
50
|
+
# the parser, but most apps never disable it.
|
|
58
51
|
IMPLICIT_COLUMNS = [
|
|
59
52
|
Column.new(name: "id", type: :integer, ruby_type: "Integer").freeze
|
|
60
53
|
].freeze
|
|
@@ -86,9 +79,8 @@ module Rigor
|
|
|
86
79
|
|
|
87
80
|
def table_names = tables.keys
|
|
88
81
|
|
|
89
|
-
# Maps a Rails column type symbol to its Ruby class name.
|
|
90
|
-
#
|
|
91
|
-
# that as "do not narrow" (silent on unknowns).
|
|
82
|
+
# Maps a Rails column type symbol to its Ruby class name. Returns "Object" for unknown types —
|
|
83
|
+
# the analyzer treats that as "do not narrow" (silent on unknowns).
|
|
92
84
|
def self.ruby_type_for(column_type)
|
|
93
85
|
RUBY_TYPE_MAPPING.fetch(column_type.to_sym, "Object")
|
|
94
86
|
end
|