rigortype 0.2.7 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/docs/manual/04-diagnostics.md +7 -4
- data/docs/manual/06-baseline.md +5 -2
- data/docs/manual/15-type-protection-coverage.md +6 -4
- data/lib/rigor/analysis/baseline.rb +56 -96
- data/lib/rigor/analysis/buffer_binding.rb +13 -20
- data/lib/rigor/analysis/check_rules/always_truthy_condition_collector.rb +29 -48
- data/lib/rigor/analysis/check_rules/dead_assignment_collector.rb +35 -54
- data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +23 -37
- data/lib/rigor/analysis/check_rules/main_pass_collector.rb +16 -23
- data/lib/rigor/analysis/check_rules/rule_walk.rb +48 -71
- data/lib/rigor/analysis/check_rules/self_closedness_scanner.rb +19 -28
- data/lib/rigor/analysis/check_rules/unreachable_clause_collector.rb +48 -67
- data/lib/rigor/analysis/check_rules.rb +174 -274
- data/lib/rigor/analysis/dependency_recorder.rb +26 -38
- data/lib/rigor/analysis/dependency_source_inference/boundary_cross_reporter.rb +13 -25
- data/lib/rigor/analysis/dependency_source_inference/builder.rb +17 -30
- data/lib/rigor/analysis/dependency_source_inference/gem_resolver.rb +15 -26
- data/lib/rigor/analysis/dependency_source_inference/index.rb +45 -76
- data/lib/rigor/analysis/dependency_source_inference/return_type_heuristic.rb +23 -40
- data/lib/rigor/analysis/dependency_source_inference/walker.rb +50 -83
- data/lib/rigor/analysis/dependency_source_inference.rb +6 -10
- data/lib/rigor/analysis/diagnostic.rb +48 -75
- data/lib/rigor/analysis/erb_template_detector.rb +13 -18
- data/lib/rigor/analysis/fact_store.rb +12 -22
- data/lib/rigor/analysis/incremental.rb +47 -63
- data/lib/rigor/analysis/incremental_session.rb +74 -100
- data/lib/rigor/analysis/project_scan.rb +12 -23
- data/lib/rigor/analysis/result.rb +3 -5
- data/lib/rigor/analysis/rule_catalog.rb +67 -95
- data/lib/rigor/analysis/run_stats.rb +38 -61
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +101 -160
- data/lib/rigor/analysis/runner/pool_coordinator.rb +121 -188
- data/lib/rigor/analysis/runner/project_pre_passes.rb +62 -96
- data/lib/rigor/analysis/runner/run_snapshots.rb +12 -18
- data/lib/rigor/analysis/runner.rb +220 -333
- data/lib/rigor/analysis/self_call_resolution_recorder.rb +30 -43
- data/lib/rigor/analysis/worker_session.rb +64 -102
- data/lib/rigor/ast/type_node.rb +6 -8
- data/lib/rigor/ast.rb +6 -10
- data/lib/rigor/bleeding_edge.rb +27 -35
- data/lib/rigor/builtins/hkt_builtins.rb +7 -14
- data/lib/rigor/builtins/imported_refinements.rb +106 -149
- data/lib/rigor/builtins/predefined_constant_refinements.rb +51 -65
- data/lib/rigor/builtins/regex_refinement.rb +32 -43
- data/lib/rigor/builtins/static_return_refinements.rb +57 -81
- data/lib/rigor/cache/descriptor.rb +58 -94
- data/lib/rigor/cache/incremental_snapshot.rb +32 -48
- data/lib/rigor/cache/rbs_cache_producer.rb +10 -15
- data/lib/rigor/cache/rbs_class_ancestor_table.rb +10 -16
- data/lib/rigor/cache/rbs_class_type_param_names.rb +10 -16
- data/lib/rigor/cache/rbs_constant_table.rb +8 -13
- data/lib/rigor/cache/rbs_descriptor.rb +8 -13
- data/lib/rigor/cache/rbs_environment.rb +11 -19
- data/lib/rigor/cache/rbs_environment_marshal_patch.rb +11 -19
- data/lib/rigor/cache/rbs_known_class_names.rb +8 -12
- data/lib/rigor/cache/store.rb +96 -151
- data/lib/rigor/cli/annotate_command.rb +51 -88
- data/lib/rigor/cli/baseline_command.rb +10 -17
- data/lib/rigor/cli/check_command.rb +121 -199
- data/lib/rigor/cli/check_runner_factory.rb +8 -14
- data/lib/rigor/cli/ci_detector.rb +9 -14
- data/lib/rigor/cli/command.rb +8 -14
- data/lib/rigor/cli/coverage_command.rb +19 -26
- data/lib/rigor/cli/coverage_mutation.rb +14 -19
- data/lib/rigor/cli/coverage_report.rb +0 -2
- data/lib/rigor/cli/coverage_scan.rb +7 -11
- data/lib/rigor/cli/diagnostic_formats.rb +43 -62
- data/lib/rigor/cli/diff_command.rb +10 -20
- data/lib/rigor/cli/docs_command.rb +26 -40
- data/lib/rigor/cli/doctor_command.rb +8 -9
- data/lib/rigor/cli/explain_command.rb +4 -7
- data/lib/rigor/cli/fused_protection_renderer.rb +4 -5
- data/lib/rigor/cli/fused_protection_report.rb +6 -8
- data/lib/rigor/cli/lsp_command.rb +11 -19
- data/lib/rigor/cli/mcp_command.rb +4 -6
- data/lib/rigor/cli/mutation_protection_renderer.rb +3 -4
- data/lib/rigor/cli/mutation_protection_report.rb +6 -9
- data/lib/rigor/cli/options.rb +11 -19
- data/lib/rigor/cli/plugin_command.rb +18 -30
- data/lib/rigor/cli/plugins_command.rb +29 -51
- data/lib/rigor/cli/plugins_renderer.rb +12 -20
- data/lib/rigor/cli/prism_colorizer.rb +13 -19
- data/lib/rigor/cli/protection_renderer.rb +5 -7
- data/lib/rigor/cli/protection_report.rb +27 -17
- data/lib/rigor/cli/renderable.rb +4 -6
- data/lib/rigor/cli/show_bleedingedge_command.rb +5 -8
- data/lib/rigor/cli/sig_gen_command.rb +14 -26
- data/lib/rigor/cli/skill_command.rb +30 -47
- data/lib/rigor/cli/skill_describe.rb +40 -64
- data/lib/rigor/cli/trace_command.rb +9 -16
- data/lib/rigor/cli/trace_renderer.rb +35 -51
- data/lib/rigor/cli/triage_command.rb +6 -10
- data/lib/rigor/cli/triage_renderer.rb +1 -2
- data/lib/rigor/cli/type_of_command.rb +14 -23
- data/lib/rigor/cli/type_of_renderer.rb +3 -5
- data/lib/rigor/cli/type_scan_command.rb +6 -10
- data/lib/rigor/cli/type_scan_renderer.rb +3 -5
- data/lib/rigor/cli/type_scan_report.rb +2 -3
- data/lib/rigor/cli/upgrade_command.rb +2 -3
- data/lib/rigor/cli.rb +16 -28
- data/lib/rigor/config_audit.rb +35 -44
- data/lib/rigor/configuration/dependencies.rb +41 -70
- data/lib/rigor/configuration/severity_profile.rb +28 -42
- data/lib/rigor/configuration.rb +150 -241
- data/lib/rigor/environment/bundle_sig_discovery.rb +74 -118
- data/lib/rigor/environment/class_registry.rb +19 -26
- data/lib/rigor/environment/constant_type_cache_holder.rb +14 -21
- data/lib/rigor/environment/hkt_registry_holder.rb +6 -12
- data/lib/rigor/environment/lockfile_resolver.rb +31 -47
- data/lib/rigor/environment/rbs_collection_discovery.rb +39 -63
- data/lib/rigor/environment/rbs_coverage_report.rb +24 -42
- data/lib/rigor/environment/rbs_loader.rb +420 -518
- data/lib/rigor/environment/reflection.rb +28 -53
- data/lib/rigor/environment/reporters.rb +13 -24
- data/lib/rigor/environment.rb +176 -291
- data/lib/rigor/flow_contribution/conflict.rb +16 -27
- data/lib/rigor/flow_contribution/element.rb +7 -12
- data/lib/rigor/flow_contribution/fact.rb +33 -57
- data/lib/rigor/flow_contribution/merge_result.rb +6 -9
- data/lib/rigor/flow_contribution/merger.rb +32 -47
- data/lib/rigor/flow_contribution.rb +37 -55
- data/lib/rigor/inference/acceptance.rb +133 -219
- data/lib/rigor/inference/block_parameter_binder.rb +52 -82
- data/lib/rigor/inference/body_fixpoint.rb +22 -30
- data/lib/rigor/inference/budget_trace.rb +43 -63
- data/lib/rigor/inference/builtins/array_catalog.rb +4 -6
- data/lib/rigor/inference/builtins/comparable_catalog.rb +4 -6
- data/lib/rigor/inference/builtins/complex_catalog.rb +13 -19
- data/lib/rigor/inference/builtins/date_catalog.rb +38 -67
- data/lib/rigor/inference/builtins/encoding_catalog.rb +22 -36
- data/lib/rigor/inference/builtins/enumerable_catalog.rb +4 -6
- data/lib/rigor/inference/builtins/exception_catalog.rb +38 -57
- data/lib/rigor/inference/builtins/hash_catalog.rb +9 -14
- data/lib/rigor/inference/builtins/method_catalog.rb +29 -48
- data/lib/rigor/inference/builtins/numeric_catalog.rb +13 -18
- data/lib/rigor/inference/builtins/pathname_catalog.rb +8 -13
- data/lib/rigor/inference/builtins/proc_catalog.rb +38 -62
- data/lib/rigor/inference/builtins/random_catalog.rb +21 -32
- data/lib/rigor/inference/builtins/range_catalog.rb +12 -21
- data/lib/rigor/inference/builtins/rational_catalog.rb +9 -15
- data/lib/rigor/inference/builtins/re_catalog.rb +29 -48
- data/lib/rigor/inference/builtins/set_catalog.rb +18 -27
- data/lib/rigor/inference/builtins/string_catalog.rb +12 -19
- data/lib/rigor/inference/builtins/struct_catalog.rb +18 -30
- data/lib/rigor/inference/builtins/time_catalog.rb +28 -44
- data/lib/rigor/inference/closure_escape_analyzer.rb +44 -67
- data/lib/rigor/inference/coverage_scanner.rb +13 -18
- data/lib/rigor/inference/def_return_typer.rb +8 -14
- data/lib/rigor/inference/dynamic_origin.rb +23 -20
- data/lib/rigor/inference/expression_typer.rb +774 -1152
- data/lib/rigor/inference/fallback.rb +8 -12
- data/lib/rigor/inference/fallback_tracer.rb +4 -10
- data/lib/rigor/inference/flow_tracer.rb +25 -36
- data/lib/rigor/inference/hkt_body.rb +45 -68
- data/lib/rigor/inference/hkt_body_parser.rb +33 -52
- data/lib/rigor/inference/hkt_reducer.rb +38 -59
- data/lib/rigor/inference/hkt_registry.rb +50 -76
- data/lib/rigor/inference/indexed_narrowing.rb +55 -81
- data/lib/rigor/inference/macro_block_self_type.rb +21 -34
- data/lib/rigor/inference/method_dispatcher/array_to_h_folding.rb +11 -18
- data/lib/rigor/inference/method_dispatcher/block_folding.rb +49 -83
- data/lib/rigor/inference/method_dispatcher/call_context.rb +16 -23
- data/lib/rigor/inference/method_dispatcher/cgi_folding.rb +13 -22
- data/lib/rigor/inference/method_dispatcher/constant_folding.rb +307 -454
- data/lib/rigor/inference/method_dispatcher/data_folding.rb +24 -34
- data/lib/rigor/inference/method_dispatcher/file_folding.rb +22 -37
- data/lib/rigor/inference/method_dispatcher/iterator_dispatch.rb +52 -81
- data/lib/rigor/inference/method_dispatcher/kernel_dispatch.rb +51 -78
- data/lib/rigor/inference/method_dispatcher/literal_string_folding.rb +60 -97
- data/lib/rigor/inference/method_dispatcher/math_folding.rb +23 -34
- data/lib/rigor/inference/method_dispatcher/member_shape_projection.rb +18 -26
- data/lib/rigor/inference/method_dispatcher/method_folding.rb +37 -71
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +114 -182
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +122 -193
- data/lib/rigor/inference/method_dispatcher/receiver_affinity.rb +15 -24
- data/lib/rigor/inference/method_dispatcher/reduce_folding.rb +64 -93
- data/lib/rigor/inference/method_dispatcher/regexp_folding.rb +31 -45
- data/lib/rigor/inference/method_dispatcher/set_folding.rb +6 -9
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +356 -511
- data/lib/rigor/inference/method_dispatcher/shellwords_folding.rb +22 -32
- data/lib/rigor/inference/method_dispatcher/singleton_folding.rb +15 -21
- data/lib/rigor/inference/method_dispatcher/struct_folding.rb +66 -82
- data/lib/rigor/inference/method_dispatcher/time_folding.rb +10 -15
- data/lib/rigor/inference/method_dispatcher/uri_folding.rb +9 -13
- data/lib/rigor/inference/method_dispatcher.rb +378 -524
- data/lib/rigor/inference/method_parameter_binder.rb +81 -114
- data/lib/rigor/inference/multi_target_binder.rb +51 -68
- data/lib/rigor/inference/mutation_widening.rb +115 -158
- data/lib/rigor/inference/narrowing.rb +509 -727
- data/lib/rigor/inference/origin_lookup.rb +38 -0
- data/lib/rigor/inference/parameter_inference_collector.rb +100 -100
- data/lib/rigor/inference/precision_scanner.rb +26 -35
- data/lib/rigor/inference/project_patched_methods.rb +20 -32
- data/lib/rigor/inference/project_patched_scanner.rb +23 -37
- data/lib/rigor/inference/protection_scanner.rb +16 -18
- data/lib/rigor/inference/rbs_type_translator.rb +49 -66
- data/lib/rigor/inference/scope_indexer.rb +473 -817
- data/lib/rigor/inference/statement_evaluator.rb +706 -1111
- data/lib/rigor/inference/struct_fold_safety.rb +34 -48
- data/lib/rigor/inference/synthetic_method.rb +9 -16
- data/lib/rigor/inference/synthetic_method_index.rb +20 -35
- data/lib/rigor/inference/synthetic_method_scanner.rb +63 -103
- data/lib/rigor/language_server/buffer_resolution.rb +6 -9
- data/lib/rigor/language_server/buffer_table.rb +11 -18
- data/lib/rigor/language_server/completion_provider.rb +69 -116
- data/lib/rigor/language_server/debouncer.rb +16 -25
- data/lib/rigor/language_server/diagnostic_publisher.rb +26 -40
- data/lib/rigor/language_server/document_symbol_provider.rb +14 -19
- data/lib/rigor/language_server/folding_range_provider.rb +11 -19
- data/lib/rigor/language_server/hover_provider.rb +8 -11
- data/lib/rigor/language_server/hover_renderer.rb +56 -93
- data/lib/rigor/language_server/loop.rb +14 -19
- data/lib/rigor/language_server/project_context.rb +46 -74
- data/lib/rigor/language_server/selection_range_provider.rb +9 -12
- data/lib/rigor/language_server/server.rb +55 -83
- data/lib/rigor/language_server/signature_help_provider.rb +29 -46
- data/lib/rigor/language_server/synchronized_writer.rb +4 -7
- data/lib/rigor/language_server/uri.rb +8 -13
- data/lib/rigor/language_server.rb +4 -6
- data/lib/rigor/mcp/loop.rb +2 -3
- data/lib/rigor/mcp/server.rb +4 -7
- data/lib/rigor/mcp.rb +3 -6
- data/lib/rigor/plugin/access_denied_error.rb +5 -8
- data/lib/rigor/plugin/additional_initializer.rb +21 -31
- data/lib/rigor/plugin/base.rb +335 -518
- data/lib/rigor/plugin/blueprint.rb +14 -23
- data/lib/rigor/plugin/box.rb +18 -29
- data/lib/rigor/plugin/fact_store.rb +16 -26
- data/lib/rigor/plugin/inflector.rb +37 -53
- data/lib/rigor/plugin/io_boundary.rb +33 -56
- data/lib/rigor/plugin/isolation.rb +42 -55
- data/lib/rigor/plugin/load_error.rb +10 -15
- data/lib/rigor/plugin/loader.rb +30 -49
- data/lib/rigor/plugin/macro/block_as_method.rb +20 -32
- data/lib/rigor/plugin/macro/heredoc_template.rb +35 -58
- data/lib/rigor/plugin/macro/nested_class_template.rb +22 -36
- data/lib/rigor/plugin/macro/trait_registry.rb +34 -51
- data/lib/rigor/plugin/macro.rb +10 -15
- data/lib/rigor/plugin/manifest.rb +85 -144
- data/lib/rigor/plugin/node_context.rb +14 -22
- data/lib/rigor/plugin/node_rule_walk.rb +49 -74
- data/lib/rigor/plugin/protocol_contract.rb +25 -39
- data/lib/rigor/plugin/registry.rb +132 -205
- data/lib/rigor/plugin/services.rb +21 -33
- data/lib/rigor/plugin/source_rbs_synthesis_reporter.rb +11 -19
- data/lib/rigor/plugin/trust_policy.rb +24 -38
- data/lib/rigor/plugin/type_node_resolver.rb +15 -24
- data/lib/rigor/protection/diagnostic_oracle.rb +11 -13
- data/lib/rigor/protection/mutation_scanner.rb +27 -35
- data/lib/rigor/protection/mutator.rb +50 -70
- data/lib/rigor/protection/test_suite_oracle.rb +20 -27
- data/lib/rigor/rbs_extended/conformance_checker.rb +48 -68
- data/lib/rigor/rbs_extended/hkt_directives.rb +28 -54
- data/lib/rigor/rbs_extended/reporter.rb +24 -40
- data/lib/rigor/rbs_extended.rb +107 -197
- data/lib/rigor/reflection.rb +68 -86
- data/lib/rigor/scope/discovery_index.rb +14 -19
- data/lib/rigor/scope.rb +255 -310
- data/lib/rigor/sig_gen/classification.rb +6 -10
- data/lib/rigor/sig_gen/generator.rb +197 -323
- data/lib/rigor/sig_gen/layout_index.rb +12 -20
- data/lib/rigor/sig_gen/method_candidate.rb +12 -17
- data/lib/rigor/sig_gen/observation_collector.rb +38 -70
- data/lib/rigor/sig_gen/observed_call.rb +13 -23
- data/lib/rigor/sig_gen/path_mapper.rb +17 -29
- data/lib/rigor/sig_gen/renderer.rb +7 -13
- data/lib/rigor/sig_gen/type_elaborator.rb +15 -28
- data/lib/rigor/sig_gen/write_result.rb +8 -16
- data/lib/rigor/sig_gen/writer.rb +95 -174
- data/lib/rigor/sig_gen.rb +3 -6
- data/lib/rigor/signature_path_audit.rb +24 -30
- data/lib/rigor/source/constant_path.rb +10 -14
- data/lib/rigor/source/literals.rb +31 -45
- data/lib/rigor/source/node_locator.rb +9 -11
- data/lib/rigor/source/node_walker.rb +9 -13
- data/lib/rigor/source.rb +3 -4
- data/lib/rigor/testing.rb +16 -20
- data/lib/rigor/triage/catalogue.rb +38 -62
- data/lib/rigor/triage.rb +31 -52
- data/lib/rigor/trinary.rb +9 -13
- data/lib/rigor/type/acceptance_router.rb +4 -6
- data/lib/rigor/type/accepts_result.rb +10 -14
- data/lib/rigor/type/app.rb +19 -27
- data/lib/rigor/type/bot.rb +4 -6
- data/lib/rigor/type/bound_method.rb +10 -15
- data/lib/rigor/type/combinator.rb +165 -257
- data/lib/rigor/type/constant.rb +23 -34
- data/lib/rigor/type/data_class.rb +10 -15
- data/lib/rigor/type/data_instance.rb +14 -20
- data/lib/rigor/type/difference.rb +21 -32
- data/lib/rigor/type/dynamic.rb +3 -5
- data/lib/rigor/type/hash_shape.rb +32 -18
- data/lib/rigor/type/integer_range.rb +11 -16
- data/lib/rigor/type/intersection.rb +27 -42
- data/lib/rigor/type/nominal.rb +10 -15
- data/lib/rigor/type/plain_lattice.rb +9 -13
- data/lib/rigor/type/refined.rb +67 -114
- data/lib/rigor/type/singleton.rb +4 -6
- data/lib/rigor/type/struct_class.rb +11 -16
- data/lib/rigor/type/struct_instance.rb +15 -21
- data/lib/rigor/type/tuple.rb +14 -19
- data/lib/rigor/type/union.rb +30 -42
- data/lib/rigor/type_node/generic.rb +14 -26
- data/lib/rigor/type_node/identifier.rb +12 -19
- data/lib/rigor/type_node.rb +3 -12
- data/lib/rigor/value_semantics.rb +16 -21
- data/lib/rigor/version.rb +1 -1
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/analyzer.rb +18 -30
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_discoverer.rb +16 -29
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_index.rb +12 -23
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +22 -39
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/analyzer.rb +26 -46
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_discoverer.rb +51 -87
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_index.rb +10 -17
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb +26 -39
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb +118 -176
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_discoverer.rb +30 -51
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_index.rb +57 -92
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +71 -108
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/analyzer.rb +13 -22
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_discoverer.rb +15 -25
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_index.rb +8 -13
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +16 -24
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/analyzer.rb +30 -47
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +79 -129
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_index.rb +36 -57
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_parser.rb +27 -41
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_table.rb +16 -24
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +148 -235
- data/plugins/rigor-activerecord/lib/rigor-activerecord.rb +3 -5
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/analyzer.rb +8 -14
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_discoverer.rb +9 -15
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_index.rb +4 -7
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +23 -41
- data/plugins/rigor-activestorage/lib/rigor-activestorage.rb +3 -5
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb +6 -10
- data/plugins/rigor-activesupport-core-ext/lib/rigor-activesupport-core-ext.rb +8 -11
- data/plugins/rigor-devise/lib/rigor/plugin/devise.rb +30 -45
- data/plugins/rigor-devise/lib/rigor-devise.rb +3 -5
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema/schema_scanner.rb +43 -69
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema.rb +26 -35
- data/plugins/rigor-dry-schema/lib/rigor-dry-schema.rb +3 -5
- data/plugins/rigor-dry-struct/lib/rigor/plugin/dry_struct.rb +30 -47
- data/plugins/rigor-dry-struct/lib/rigor-dry-struct.rb +3 -5
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types/alias_scanner.rb +67 -113
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types.rb +29 -46
- data/plugins/rigor-dry-types/lib/rigor-dry-types.rb +3 -5
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation/contract_scanner.rb +13 -20
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation.rb +14 -23
- data/plugins/rigor-dry-validation/lib/rigor-dry-validation.rb +2 -3
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/analyzer.rb +22 -37
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_discoverer.rb +28 -46
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_index.rb +13 -17
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot.rb +30 -47
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql/type_scanner.rb +52 -80
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql.rb +21 -31
- data/plugins/rigor-graphql/lib/rigor-graphql.rb +3 -5
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami/action_checker.rb +11 -17
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami.rb +20 -34
- data/plugins/rigor-mangrove/lib/rigor/plugin/mangrove.rb +45 -75
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest/assertion_analyzer.rb +22 -36
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest.rb +22 -41
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/analyzer.rb +17 -32
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_discoverer.rb +6 -12
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_index.rb +4 -8
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit.rb +17 -32
- data/plugins/rigor-rails/lib/rigor-rails.rb +11 -18
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/analyzer.rb +58 -92
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_index.rb +20 -34
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_loader.rb +20 -31
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n.rb +49 -82
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/analyzer.rb +55 -92
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/devise_routes.rb +51 -90
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/doorkeeper_routes.rb +17 -30
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_discoverer.rb +38 -70
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_table.rb +42 -74
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/routes_parser.rb +280 -497
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +54 -89
- data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb +32 -54
- data/plugins/rigor-rbs-inline/lib/rigor-rbs-inline.rb +8 -13
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/analyzer.rb +9 -16
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_scope_index.rb +24 -39
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_type_resolver.rb +13 -22
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +34 -56
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/scope_walker.rb +22 -42
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec.rb +43 -75
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails/have_http_status_analyzer.rb +27 -39
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails/http_status_codes.rb +14 -19
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails.rb +20 -34
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers/analyzer.rb +28 -47
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers.rb +21 -37
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/analyzer.rb +13 -22
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_discoverer.rb +18 -31
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_index.rb +6 -10
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb +14 -29
- data/plugins/rigor-sinatra/lib/rigor/plugin/sinatra.rb +23 -41
- data/plugins/rigor-sinatra/lib/rigor-sinatra.rb +3 -5
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/absurd_recognizer.rb +23 -38
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/assertion_recognizer.rb +57 -96
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog.rb +22 -35
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog_walker.rb +41 -69
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/method_signature.rb +6 -10
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sig_parser.rb +24 -41
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sigil_detector.rb +29 -50
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/type_translator.rb +55 -88
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +159 -262
- data/plugins/rigor-statesman/lib/rigor/plugin/statesman.rb +21 -29
- data/plugins/rigor-statesman/lib/rigor-statesman.rb +3 -5
- data/plugins/rigor-typescript-utility-types/lib/rigor/plugin/typescript_utility_types.rb +23 -37
- data/plugins/rigor-typescript-utility-types/lib/rigor-typescript-utility-types.rb +4 -6
- data/sig/rigor/scope.rbs +6 -0
- metadata +2 -1
|
@@ -4,53 +4,40 @@ require_relative "check_rules"
|
|
|
4
4
|
|
|
5
5
|
module Rigor
|
|
6
6
|
module Analysis
|
|
7
|
-
# Single-source-of-truth metadata table for every CheckRule
|
|
8
|
-
# the
|
|
9
|
-
#
|
|
10
|
-
# publishes without leaving the terminal.
|
|
7
|
+
# Single-source-of-truth metadata table for every CheckRule the analyzer ships. Consumed by `rigor
|
|
8
|
+
# explain <rule>` so users can read the same information the docs site eventually publishes without
|
|
9
|
+
# leaving the terminal.
|
|
11
10
|
#
|
|
12
11
|
# Each entry carries:
|
|
13
12
|
#
|
|
14
13
|
# - `id` — canonical rule id (`call.undefined-method`).
|
|
15
14
|
# - `summary` — single-line headline (≤ 80 chars).
|
|
16
|
-
# - `fires_when` — bullet-shaped list of conditions that
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
# -
|
|
23
|
-
#
|
|
24
|
-
# `# rigor:disable-file`, plus `.rigor.yml` `disable:`,
|
|
25
|
-
# apply to every rule, so the note covers any rule-specific
|
|
26
|
-
# nuance — e.g. unreachable-branch lives on the dead-branch
|
|
27
|
-
# line, not the predicate line).
|
|
15
|
+
# - `fires_when` — bullet-shaped list of conditions that trigger the rule, in the order a reader can
|
|
16
|
+
# scan top-to-bottom.
|
|
17
|
+
# - `does_not_fire_when` — explicit list of cases the rule intentionally skips. Useful for "why am I NOT
|
|
18
|
+
# seeing this diagnostic?" questions.
|
|
19
|
+
# - `suppression` — short note on how to suppress (in-source `# rigor:disable` and the v0.1.2
|
|
20
|
+
# file-scope variant `# rigor:disable-file`, plus `.rigor.yml` `disable:`, apply to every rule, so
|
|
21
|
+
# the note covers any rule-specific nuance — e.g. unreachable-branch lives on the dead-branch line,
|
|
22
|
+
# not the predicate line).
|
|
28
23
|
# - `severity_authored` — Symbol the rule emits with.
|
|
29
|
-
# - `severity_by_profile` — Hash of `:lenient` / `:balanced`
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
# that
|
|
40
|
-
# RBS-strictness modelling gaps); `:low` rules are
|
|
41
|
-
# resolution- or coverage-gap signals where a firing often
|
|
42
|
-
# reflects missing context rather than a definite bug. The
|
|
43
|
-
# tier routes a consumer's attention (and lets a downstream
|
|
44
|
-
# classifier promote a `:high` firing without cross-tool
|
|
45
|
-
# corroboration); it never feeds severity — that stays the
|
|
46
|
-
# `severity_profile:` decision.
|
|
24
|
+
# - `severity_by_profile` — Hash of `:lenient` / `:balanced` / `:strict` to the configured severity per
|
|
25
|
+
# profile, taken from `Configuration::SeverityProfile::PROFILES`.
|
|
26
|
+
# - `evidence_tier` — `:high` / `:medium` / `:low` (or `nil` for informational helpers), Rigor's own
|
|
27
|
+
# confidence that a firing is a true positive, derived from the rule's firing gates. `:high` rules
|
|
28
|
+
# fire only on a concrete, statically- known type with no metaprogramming escape (Rigor's
|
|
29
|
+
# false-positive discipline has already filtered the uncertain cases); `:medium` rules rest on flow /
|
|
30
|
+
# inference proofs that inherit a documented FP envelope (loop / mutation / RBS-strictness modelling
|
|
31
|
+
# gaps); `:low` rules are resolution- or coverage-gap signals where a firing often reflects missing
|
|
32
|
+
# context rather than a definite bug. The tier routes a consumer's attention (and lets a downstream
|
|
33
|
+
# classifier promote a `:high` firing without cross-tool corroboration); it never feeds severity —
|
|
34
|
+
# that stays the `severity_profile:` decision.
|
|
47
35
|
# - `since` — first version the rule shipped in.
|
|
48
36
|
module RuleCatalog # rubocop:disable Metrics/ModuleLength
|
|
49
|
-
# Stable documentation home for a built-in rule. `documentation_url`
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
# `
|
|
53
|
-
# Mirrors the gemspec `documentation_uri` URL scheme (`…/tree/main`).
|
|
37
|
+
# Stable documentation home for a built-in rule. `documentation_url` appends a per-rule fragment that
|
|
38
|
+
# resolves to the rule's anchor in the published diagnostics catalogue; the page itself points at
|
|
39
|
+
# `rigor explain <rule>` as the authoritative per-rule reference. Mirrors the gemspec
|
|
40
|
+
# `documentation_uri` URL scheme (`…/tree/main`).
|
|
54
41
|
DOCUMENTATION_BASE = "https://github.com/rigortype/rigor/blob/main/docs/manual/04-diagnostics.md"
|
|
55
42
|
|
|
56
43
|
class Entry < Data.define(:id, :summary, :fires_when, :does_not_fire_when,
|
|
@@ -65,10 +52,9 @@ module Rigor
|
|
|
65
52
|
RuleCatalog.documentation_url(id)
|
|
66
53
|
end
|
|
67
54
|
|
|
68
|
-
# Hash-shaped form for `--format=json` consumers. Keys are
|
|
69
|
-
#
|
|
70
|
-
#
|
|
71
|
-
# helpers carry no confidence tier).
|
|
55
|
+
# Hash-shaped form for `--format=json` consumers. Keys are Strings so the payload is JSON-stable
|
|
56
|
+
# without a transform pass. `evidence_tier` is omitted when nil (informational helpers carry no
|
|
57
|
+
# confidence tier).
|
|
72
58
|
def to_h
|
|
73
59
|
base = {
|
|
74
60
|
"id" => id,
|
|
@@ -131,11 +117,9 @@ module Rigor
|
|
|
131
117
|
"`severity_overrides: { call.self-undefined-method: warning }` in `.rigor.yml`.",
|
|
132
118
|
severity_authored: :warning,
|
|
133
119
|
severity_by_profile: { lenient: :off, balanced: :off, strict: :off },
|
|
134
|
-
# Off by default and metaprogramming-prone — a firing on a
|
|
135
|
-
# class
|
|
136
|
-
#
|
|
137
|
-
# known FP mode, so a firing is a candidate to review, not a
|
|
138
|
-
# high-confidence bug.
|
|
120
|
+
# Off by default and metaprogramming-prone — a firing on a class whose real surface the
|
|
121
|
+
# per-class scan cannot enumerate (C-extension, `class << self`, dynamic accessors) is the known
|
|
122
|
+
# FP mode, so a firing is a candidate to review, not a high-confidence bug.
|
|
139
123
|
evidence_tier: :low,
|
|
140
124
|
since: "0.1.17"
|
|
141
125
|
),
|
|
@@ -160,10 +144,9 @@ module Rigor
|
|
|
160
144
|
"file in `.rigor.yml`'s `pre_eval:` so the analyzer sees the top-level `def` / patch.",
|
|
161
145
|
severity_authored: :warning,
|
|
162
146
|
severity_by_profile: { lenient: :off, balanced: :warning, strict: :error },
|
|
163
|
-
# A firing is frequently a resolution gap — the defining file
|
|
164
|
-
#
|
|
165
|
-
#
|
|
166
|
-
# a definite typo, so it routes to the `pre_eval:` review path.
|
|
147
|
+
# A firing is frequently a resolution gap — the defining file is not in the analyzed set or
|
|
148
|
+
# injects the method via a metaprogramming patch the analyzer does not see — rather than a
|
|
149
|
+
# definite typo, so it routes to the `pre_eval:` review path.
|
|
167
150
|
evidence_tier: :low,
|
|
168
151
|
since: "0.1.14"
|
|
169
152
|
),
|
|
@@ -303,8 +286,8 @@ module Rigor
|
|
|
303
286
|
"points at the dead branch, not the predicate, so the suppression goes there).",
|
|
304
287
|
severity_authored: :warning,
|
|
305
288
|
severity_by_profile: { lenient: :info, balanced: :warning, strict: :error },
|
|
306
|
-
# The literal-only firing envelope makes the deadness provable
|
|
307
|
-
#
|
|
289
|
+
# The literal-only firing envelope makes the deadness provable from syntax alone — no inference
|
|
290
|
+
# uncertainty.
|
|
308
291
|
evidence_tier: :high,
|
|
309
292
|
since: "0.1.2"
|
|
310
293
|
),
|
|
@@ -328,10 +311,9 @@ module Rigor
|
|
|
328
311
|
suppression: "`# rigor:disable always-truthy-condition` on the predicate line.",
|
|
329
312
|
severity_authored: :warning,
|
|
330
313
|
severity_by_profile: { lenient: :info, balanced: :warning, strict: :error },
|
|
331
|
-
# Rests on inferred-constant folding, which inherits the
|
|
332
|
-
#
|
|
333
|
-
#
|
|
334
|
-
# provable like `unreachable-branch`.
|
|
314
|
+
# Rests on inferred-constant folding, which inherits the loop / mutation FP envelope the
|
|
315
|
+
# `does_not_fire_when` guards narrow — true positive in the common case, but not
|
|
316
|
+
# literal-provable like `unreachable-branch`.
|
|
335
317
|
evidence_tier: :medium,
|
|
336
318
|
since: "0.1.2"
|
|
337
319
|
),
|
|
@@ -355,11 +337,11 @@ module Rigor
|
|
|
355
337
|
],
|
|
356
338
|
suppression: "`# rigor:disable unreachable-clause` on the dead-clause body line.",
|
|
357
339
|
severity_authored: :warning,
|
|
358
|
-
# ADR-47 WD4: balanced stays :info (one notch below its `flow.*`
|
|
359
|
-
#
|
|
340
|
+
# ADR-47 WD4: balanced stays :info (one notch below its `flow.*` siblings' :warning) until the
|
|
341
|
+
# regression-corpus FP gate is green.
|
|
360
342
|
severity_by_profile: { lenient: :info, balanced: :info, strict: :warning },
|
|
361
|
-
# Narrowing-driven proof that inherits the `always-truthy`
|
|
362
|
-
#
|
|
343
|
+
# Narrowing-driven proof that inherits the `always-truthy` FP envelope; balanced keeps it `:info`
|
|
344
|
+
# pending the corpus gate.
|
|
363
345
|
evidence_tier: :medium,
|
|
364
346
|
since: "0.1.17"
|
|
365
347
|
),
|
|
@@ -382,10 +364,8 @@ module Rigor
|
|
|
382
364
|
suppression: "`# rigor:disable dead-assignment` on the offending line, or rename the local to `_<name>`.",
|
|
383
365
|
severity_authored: :warning,
|
|
384
366
|
severity_by_profile: { lenient: :info, balanced: :warning, strict: :error },
|
|
385
|
-
# The unread-write proof is reliable, but it flags a code
|
|
386
|
-
#
|
|
387
|
-
# classification has narrow corners (the `does_not_fire_when`
|
|
388
|
-
# exclusions).
|
|
367
|
+
# The unread-write proof is reliable, but it flags a code smell rather than a runtime fault, and
|
|
368
|
+
# the syntactic write classification has narrow corners (the `does_not_fire_when` exclusions).
|
|
389
369
|
evidence_tier: :medium,
|
|
390
370
|
since: "0.1.2"
|
|
391
371
|
),
|
|
@@ -408,9 +388,8 @@ module Rigor
|
|
|
408
388
|
suppression: "`# rigor:disable def.return-type-mismatch`.",
|
|
409
389
|
severity_authored: :warning,
|
|
410
390
|
severity_by_profile: { lenient: :warning, balanced: :warning, strict: :error },
|
|
411
|
-
# Depends on re-typing the body against an authored RBS return;
|
|
412
|
-
#
|
|
413
|
-
# firing usually-right but not concrete-call certain.
|
|
391
|
+
# Depends on re-typing the body against an authored RBS return; RBS strict-on-returns plus
|
|
392
|
+
# incomplete body inference makes a firing usually-right but not concrete-call certain.
|
|
414
393
|
evidence_tier: :medium,
|
|
415
394
|
since: "0.1.0"
|
|
416
395
|
),
|
|
@@ -456,9 +435,8 @@ module Rigor
|
|
|
456
435
|
suppression: "`# rigor:disable def.override-visibility-reduced` on the override.",
|
|
457
436
|
severity_authored: :warning,
|
|
458
437
|
severity_by_profile: { lenient: :off, balanced: :warning, strict: :error },
|
|
459
|
-
# Both the override and the shadowed ancestor visibility are
|
|
460
|
-
#
|
|
461
|
-
# violation is concrete.
|
|
438
|
+
# Both the override and the shadowed ancestor visibility are statically observed from project
|
|
439
|
+
# source — the substitutability violation is concrete.
|
|
462
440
|
evidence_tier: :high,
|
|
463
441
|
since: "0.1.15"
|
|
464
442
|
),
|
|
@@ -487,8 +465,8 @@ module Rigor
|
|
|
487
465
|
suppression: "`# rigor:disable def.override-return-widened` on the override.",
|
|
488
466
|
severity_authored: :warning,
|
|
489
467
|
severity_by_profile: { lenient: :off, balanced: :warning, strict: :error },
|
|
490
|
-
# Gated on both-sides-authored RBS and a resolvable subtype
|
|
491
|
-
#
|
|
468
|
+
# Gated on both-sides-authored RBS and a resolvable subtype relationship, so a firing is a
|
|
469
|
+
# concrete covariance violation.
|
|
492
470
|
evidence_tier: :high,
|
|
493
471
|
since: "0.1.15"
|
|
494
472
|
),
|
|
@@ -520,8 +498,8 @@ module Rigor
|
|
|
520
498
|
suppression: "`# rigor:disable def.override-param-narrowed` on the override.",
|
|
521
499
|
severity_authored: :warning,
|
|
522
500
|
severity_by_profile: { lenient: :off, balanced: :warning, strict: :error },
|
|
523
|
-
# Gated on both-sides-authored RBS and a resolvable subtype
|
|
524
|
-
#
|
|
501
|
+
# Gated on both-sides-authored RBS and a resolvable subtype relationship, so a firing is a
|
|
502
|
+
# concrete contravariance violation.
|
|
525
503
|
evidence_tier: :high,
|
|
526
504
|
since: "0.1.15"
|
|
527
505
|
),
|
|
@@ -544,8 +522,8 @@ module Rigor
|
|
|
544
522
|
suppression: "`# rigor:disable ivar-write-mismatch` on the offending write.",
|
|
545
523
|
severity_authored: :error,
|
|
546
524
|
severity_by_profile: { lenient: :warning, balanced: :warning, strict: :error },
|
|
547
|
-
# Both writes resolve to concrete classes before firing; the
|
|
548
|
-
#
|
|
525
|
+
# Both writes resolve to concrete classes before firing; the union / Dynamic / clear-idiom
|
|
526
|
+
# escapes are excluded.
|
|
549
527
|
evidence_tier: :high,
|
|
550
528
|
since: "0.1.2"
|
|
551
529
|
)
|
|
@@ -553,8 +531,7 @@ module Rigor
|
|
|
553
531
|
|
|
554
532
|
module_function
|
|
555
533
|
|
|
556
|
-
# Looks up a rule by canonical id, legacy alias, or family
|
|
557
|
-
# wildcard. Returns an Array<Entry>:
|
|
534
|
+
# Looks up a rule by canonical id, legacy alias, or family wildcard. Returns an Array<Entry>:
|
|
558
535
|
#
|
|
559
536
|
# - canonical id → 1-element array,
|
|
560
537
|
# - legacy alias → 1-element array (resolved to canonical),
|
|
@@ -580,12 +557,10 @@ module Rigor
|
|
|
580
557
|
ENTRIES.values.sort_by(&:id)
|
|
581
558
|
end
|
|
582
559
|
|
|
583
|
-
# Rigor's confidence tier (`:high` / `:medium` / `:low`) that a
|
|
584
|
-
#
|
|
585
|
-
#
|
|
586
|
-
#
|
|
587
|
-
# tier). Resolves legacy aliases. See {Entry}'s `evidence_tier`
|
|
588
|
-
# documentation for the tier semantics.
|
|
560
|
+
# Rigor's confidence tier (`:high` / `:medium` / `:low`) that a firing of `token` is a true positive,
|
|
561
|
+
# or nil for an informational rule (`dump.type`) or an unknown / non-built-in token (plugin and
|
|
562
|
+
# `rbs_extended.*` rules carry no built-in tier). Resolves legacy aliases. See {Entry}'s
|
|
563
|
+
# `evidence_tier` documentation for the tier semantics.
|
|
589
564
|
def evidence_tier(token)
|
|
590
565
|
entries = resolve(token)
|
|
591
566
|
return nil unless entries.size == 1
|
|
@@ -593,12 +568,10 @@ module Rigor
|
|
|
593
568
|
entries.first.evidence_tier
|
|
594
569
|
end
|
|
595
570
|
|
|
596
|
-
# Stable documentation URL for `token`, or nil for an unknown /
|
|
597
|
-
#
|
|
598
|
-
#
|
|
599
|
-
#
|
|
600
|
-
# `rigor explain <rule>` as the authoritative per-rule reference.
|
|
601
|
-
# Resolves legacy aliases to the canonical id.
|
|
571
|
+
# Stable documentation URL for `token`, or nil for an unknown / non-built-in token. The URL is the
|
|
572
|
+
# published diagnostics catalogue page anchored at the rule's per-rule anchor
|
|
573
|
+
# (`#rule-<id-with-dots-as-dashes>`); the page itself names `rigor explain <rule>` as the
|
|
574
|
+
# authoritative per-rule reference. Resolves legacy aliases to the canonical id.
|
|
602
575
|
def documentation_url(token)
|
|
603
576
|
entries = resolve(token)
|
|
604
577
|
return nil unless entries.size == 1
|
|
@@ -606,9 +579,8 @@ module Rigor
|
|
|
606
579
|
"#{DOCUMENTATION_BASE}##{doc_anchor(entries.first.id)}"
|
|
607
580
|
end
|
|
608
581
|
|
|
609
|
-
# The per-rule fragment a `documentation_url` points at:
|
|
610
|
-
# `
|
|
611
|
-
# `04-diagnostics.md` catalogue carries the matching `<a id>`
|
|
582
|
+
# The per-rule fragment a `documentation_url` points at: `call.undefined-method` →
|
|
583
|
+
# `rule-call-undefined-method`. The `04-diagnostics.md` catalogue carries the matching `<a id>`
|
|
612
584
|
# anchors.
|
|
613
585
|
def doc_anchor(rule_id)
|
|
614
586
|
"rule-#{rule_id.tr('.', '-')}"
|
|
@@ -4,35 +4,25 @@ require "rbconfig"
|
|
|
4
4
|
|
|
5
5
|
module Rigor
|
|
6
6
|
module Analysis
|
|
7
|
-
# End-of-run telemetry for the `rigor check` CLI's `--stats`
|
|
8
|
-
# output. Captures four cheap-to-measure groups:
|
|
7
|
+
# End-of-run telemetry for the `rigor check` CLI's `--stats` output. Captures four cheap-to-measure groups:
|
|
9
8
|
#
|
|
10
|
-
# - **Check targets** — the Ruby files the analyser actually
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
# `
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
# the project's own `sig/` tree).
|
|
18
|
-
# - **Gem source-walk** — the ADR-10
|
|
19
|
-
# `dependencies.source_inference` catalogue. Reports the
|
|
20
|
-
# class count and the number of opt-in gems contributing.
|
|
9
|
+
# - **Check targets** — the Ruby files the analyser actually walks for diagnostics (`expand_paths` output).
|
|
10
|
+
# - **Type universe** — RBS class/module declarations the analyser had visibility of, broken down by
|
|
11
|
+
# source: `project_sig` (declarations whose source file lives under the configured `signature_paths`)
|
|
12
|
+
# vs `bundled` (RBS core, stdlib libraries, gem-bundled RBS — everything outside the project's own
|
|
13
|
+
# `sig/` tree).
|
|
14
|
+
# - **Gem source-walk** — the ADR-10 `dependencies.source_inference` catalogue. Reports the class count
|
|
15
|
+
# and the number of opt-in gems contributing.
|
|
21
16
|
# - **Process** — wall-clock seconds + peak resident set size.
|
|
22
17
|
#
|
|
23
|
-
# The split between "check targets" and "type universe" makes
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
# much larger) RBS class universe is symbol-discovery, not a
|
|
27
|
-
# diagnostic surface.
|
|
18
|
+
# The split between "check targets" and "type universe" makes explicit that the analyser's diagnostic
|
|
19
|
+
# surface is bounded by the user-controlled `paths:` configuration; the (typically much larger) RBS
|
|
20
|
+
# class universe is symbol-discovery, not a diagnostic surface.
|
|
28
21
|
#
|
|
29
|
-
# Stats collection is intentionally cheap: wall + RSS are
|
|
30
|
-
#
|
|
31
|
-
# `
|
|
32
|
-
#
|
|
33
|
-
# walks `class_decl_paths` (a frozen `Hash<String, String>`
|
|
34
|
-
# populated once per environment by the RBS loader; ~1000-2000
|
|
35
|
-
# entries × one `String#start_with?`).
|
|
22
|
+
# Stats collection is intentionally cheap: wall + RSS are single syscalls, target file count is already
|
|
23
|
+
# in `expand_paths`, gem source-walk uses `Index#class_to_gem.size`, and the RBS class breakdown walks
|
|
24
|
+
# `class_decl_paths` (a frozen `Hash<String, String>` populated once per environment by the RBS loader;
|
|
25
|
+
# ~1000-2000 entries × one `String#start_with?`).
|
|
36
26
|
class RunStats
|
|
37
27
|
attr_reader :wall_seconds, :peak_rss_bytes,
|
|
38
28
|
:target_files,
|
|
@@ -56,13 +46,10 @@ module Rigor
|
|
|
56
46
|
freeze
|
|
57
47
|
end
|
|
58
48
|
|
|
59
|
-
# Reports the process's resident set size in bytes. Source
|
|
60
|
-
#
|
|
61
|
-
#
|
|
62
|
-
#
|
|
63
|
-
# RSS, the closest universally-available proxy). Returns
|
|
64
|
-
# nil when neither route works so the formatter can render
|
|
65
|
-
# `unavailable` instead of misleading zero.
|
|
49
|
+
# Reports the process's resident set size in bytes. Source ordering: `/proc/self/status` (Linux — reads
|
|
50
|
+
# `VmHWM:`, the peak RSS the kernel records) first; otherwise `ps -o rss= -p <pid>` (macOS / BSD —
|
|
51
|
+
# reports CURRENT RSS, the closest universally-available proxy). Returns nil when neither route works
|
|
52
|
+
# so the formatter can render `unavailable` instead of misleading zero.
|
|
66
53
|
def self.peak_rss_bytes
|
|
67
54
|
from_proc = read_vmhwm_from_proc
|
|
68
55
|
return from_proc unless from_proc.nil?
|
|
@@ -96,22 +83,17 @@ module Rigor
|
|
|
96
83
|
nil
|
|
97
84
|
end
|
|
98
85
|
|
|
99
|
-
# Source-attribution sentinel produced by `RBS::Environment`
|
|
100
|
-
#
|
|
101
|
-
# `
|
|
102
|
-
#
|
|
103
|
-
#
|
|
104
|
-
# `[0, total]` AND `attribution_available: false`, which
|
|
105
|
-
# the format routine consumes to suppress the misleading
|
|
106
|
-
# breakdown row.
|
|
86
|
+
# Source-attribution sentinel produced by `RBS::Environment` entries restored from a cached blob
|
|
87
|
+
# (Marshal-loaded `RBS::Environment` loses real file-path attribution; every buffer reports
|
|
88
|
+
# `"<cached>"`). When every entry carries this sentinel the partition_classes routine returns `[0,
|
|
89
|
+
# total]` AND `attribution_available: false`, which the format routine consumes to suppress the
|
|
90
|
+
# misleading breakdown row.
|
|
107
91
|
CACHED_SENTINEL = "<cached>"
|
|
108
92
|
|
|
109
|
-
# Computes `(project_sig, bundled)` counts from a frozen
|
|
110
|
-
# `
|
|
111
|
-
#
|
|
112
|
-
#
|
|
113
|
-
# signature path prefixes (after expansion to absolute
|
|
114
|
-
# paths); `bundled` is the remainder.
|
|
93
|
+
# Computes `(project_sig, bundled)` counts from a frozen `Hash<class_name => source_path>` snapshot and
|
|
94
|
+
# the configured `signature_paths`. `project_sig` is the count of classes whose source path begins
|
|
95
|
+
# with any of the signature path prefixes (after expansion to absolute paths); `bundled` is the
|
|
96
|
+
# remainder.
|
|
115
97
|
def self.partition_classes(class_decl_paths:, signature_paths:)
|
|
116
98
|
prefixes = Array(signature_paths).map { |p| File.expand_path(p.to_s) }
|
|
117
99
|
return [0, class_decl_paths.size] if prefixes.empty?
|
|
@@ -124,33 +106,28 @@ module Rigor
|
|
|
124
106
|
[project, class_decl_paths.size - project]
|
|
125
107
|
end
|
|
126
108
|
|
|
127
|
-
# True when at least one entry in `class_decl_paths` carries
|
|
128
|
-
#
|
|
129
|
-
#
|
|
130
|
-
# `project_sig` / `bundled` split is meaningful.
|
|
109
|
+
# True when at least one entry in `class_decl_paths` carries a real source file path (i.e. not the
|
|
110
|
+
# cached-sentinel marker). Used by callers to decide whether the `project_sig` / `bundled` split is
|
|
111
|
+
# meaningful.
|
|
131
112
|
def self.attribution_available?(class_decl_paths:)
|
|
132
113
|
return false if class_decl_paths.empty?
|
|
133
114
|
|
|
134
115
|
class_decl_paths.each_value.any? { |path| path != CACHED_SENTINEL }
|
|
135
116
|
end
|
|
136
117
|
|
|
137
|
-
# Writes a human-facing rendering of the stats to `out`
|
|
138
|
-
#
|
|
139
|
-
#
|
|
140
|
-
# output of `rigor check --format=json` and consult `stats`
|
|
141
|
-
# there.
|
|
118
|
+
# Writes a human-facing rendering of the stats to `out` (typically `$stderr` from the CLI). Format is
|
|
119
|
+
# intentionally plain text — JSON consumers should parse the structured output of `rigor check
|
|
120
|
+
# --format=json` and consult `stats` there.
|
|
142
121
|
def format(out, prefix: "")
|
|
143
122
|
out.puts("#{prefix}Check targets")
|
|
144
123
|
out.puts("#{prefix} Ruby source files: #{@target_files}")
|
|
145
124
|
out.puts("#{prefix}Type universe (symbol discovery; not analyzed for diagnostics)")
|
|
146
125
|
out.puts("#{prefix} RBS classes available: #{@rbs_classes_total}")
|
|
147
126
|
if @rbs_classes_total.zero?
|
|
148
|
-
# A normal run always loads the bundled core+stdlib RBS (~1300+
|
|
149
|
-
#
|
|
150
|
-
#
|
|
151
|
-
#
|
|
152
|
-
# still "succeeds". Surface it loudly so a broken setup is not
|
|
153
|
-
# read as a clean analysis (the 20260620 field trial: redmine
|
|
127
|
+
# A normal run always loads the bundled core+stdlib RBS (~1300+ classes), so zero means the
|
|
128
|
+
# environment failed to build (most often a duplicate declaration in `signature_paths:`) and fell
|
|
129
|
+
# back to empty — type coverage is then near-useless but the run still "succeeds". Surface it
|
|
130
|
+
# loudly so a broken setup is not read as a clean analysis (the 20260620 field trial: redmine
|
|
154
131
|
# would otherwise wire a 0-coverage check into CI).
|
|
155
132
|
out.puts("#{prefix} WARNING: the RBS environment is empty — it failed to build or loaded no")
|
|
156
133
|
out.puts("#{prefix} signatures, so type coverage is severely limited (most diagnostics")
|