rigortype 0.4.6 → 0.4.7
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 +2 -2
- data/data/gem_overlay/activesupport/core_ext.rbs +16 -13
- data/data/vendored_gem_sigs/bundler/bundler.rbs +1 -1
- data/data/vendored_gem_sigs/rubygems/rubygems_extras.rbs +4 -3
- data/docs/handbook/01-getting-started.md +5 -2
- data/docs/handbook/11-sig-gen.md +50 -3
- data/docs/handbook/appendix-phpstan.md +4 -4
- data/docs/manual/02-cli-reference.md +152 -26
- data/docs/manual/03-configuration.md +36 -3
- data/docs/manual/06-baseline.md +6 -4
- data/docs/manual/09-editor-integration.md +13 -2
- data/docs/manual/10-mcp-server.md +38 -2
- data/docs/manual/12-caching.md +4 -3
- data/docs/manual/plugins/rigor-actionpack.md +19 -11
- data/docs/manual/plugins/rigor-activesupport-core-ext.md +20 -1
- data/lib/rigor/analysis/baseline.rb +24 -27
- data/lib/rigor/analysis/check_rules/always_truthy_condition_collector.rb +5 -6
- data/lib/rigor/analysis/check_rules/dead_assignment_collector.rb +2 -2
- data/lib/rigor/analysis/check_rules/declaration_sourced_guard.rb +4 -4
- data/lib/rigor/analysis/check_rules/duplicate_hash_key_collector.rb +2 -2
- data/lib/rigor/analysis/check_rules/inferred_param_guard.rb +85 -13
- data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +3 -2
- data/lib/rigor/analysis/check_rules/lexical_method_sites.rb +0 -1
- data/lib/rigor/analysis/check_rules/main_pass_collector.rb +5 -8
- data/lib/rigor/analysis/check_rules/published_constant_guard.rb +1 -1
- data/lib/rigor/analysis/check_rules/rebinding_block_callees.rb +3 -3
- data/lib/rigor/analysis/check_rules/return_in_ensure_collector.rb +1 -2
- data/lib/rigor/analysis/check_rules/rule_ids.rb +1 -1
- data/lib/rigor/analysis/check_rules/rule_walk.rb +9 -7
- data/lib/rigor/analysis/check_rules/shadowed_rescue_collector.rb +3 -4
- data/lib/rigor/analysis/check_rules/special_global_setters.rb +3 -3
- data/lib/rigor/analysis/check_rules/unreachable_clause_collector.rb +2 -2
- data/lib/rigor/analysis/check_rules/void_value_use_collector.rb +1 -1
- data/lib/rigor/analysis/check_rules.rb +124 -44
- data/lib/rigor/analysis/crash_signature.rb +2 -2
- data/lib/rigor/analysis/dependency_recorder.rb +4 -4
- data/lib/rigor/analysis/dependency_source_inference/boundary_cross_reporter.rb +14 -3
- data/lib/rigor/analysis/dependency_source_inference/gem_resolver.rb +1 -1
- data/lib/rigor/analysis/dependency_source_inference/index.rb +6 -8
- data/lib/rigor/analysis/dependency_source_inference/walker.rb +4 -4
- data/lib/rigor/analysis/edit_replay.rb +93 -6
- data/lib/rigor/analysis/fact_store.rb +3 -3
- data/lib/rigor/analysis/incremental_run_slot/write_guard.rb +2 -2
- data/lib/rigor/analysis/incremental_run_slot.rb +2 -2
- data/lib/rigor/analysis/incremental_session.rb +27 -16
- data/lib/rigor/analysis/rule_catalog.rb +2 -2
- data/lib/rigor/analysis/run_stats.rb +2 -2
- data/lib/rigor/analysis/runner/buffer_pool_dispatcher.rb +2 -2
- data/lib/rigor/analysis/runner/declaration_position.rb +1 -1
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +193 -93
- data/lib/rigor/analysis/runner/effect_envelope_pass.rb +1 -1
- data/lib/rigor/analysis/runner/pool_coordinator.rb +147 -323
- data/lib/rigor/analysis/runner/project_pre_passes.rb +3 -3
- data/lib/rigor/analysis/runner/run_level_facts.rb +304 -0
- data/lib/rigor/analysis/runner/run_snapshots.rb +44 -54
- data/lib/rigor/analysis/runner/worker_payload.rb +36 -0
- data/lib/rigor/analysis/runner.rb +77 -71
- data/lib/rigor/analysis/self_call_resolution_recorder.rb +1 -1
- data/lib/rigor/analysis/template_unit_positions.rb +2 -3
- data/lib/rigor/analysis/template_units.rb +9 -1
- data/lib/rigor/analysis/worker_session.rb +24 -31
- data/lib/rigor/bleeding_edge.rb +3 -6
- data/lib/rigor/builtins/imported_refinements.rb +6 -8
- data/lib/rigor/builtins/predefined_constant_refinements.rb +1 -1
- data/lib/rigor/builtins/regex_refinement.rb +4 -6
- data/lib/rigor/cache/descriptor.rb +6 -5
- data/lib/rigor/cache/incremental_snapshot.rb +31 -12
- data/lib/rigor/cache/rbs_cache_producer.rb +2 -2
- data/lib/rigor/cache/rbs_class_ancestor_table.rb +1 -1
- data/lib/rigor/cache/rbs_class_type_param_names.rb +2 -2
- data/lib/rigor/cache/rbs_constant_table.rb +1 -1
- data/lib/rigor/cache/rbs_descriptor.rb +54 -3
- data/lib/rigor/cache/rbs_environment.rb +4 -1
- data/lib/rigor/cache/rbs_environment_marshal_patch.rb +2 -2
- data/lib/rigor/cache/rbs_known_class_names.rb +1 -1
- data/lib/rigor/cache/store.rb +11 -10
- data/lib/rigor/ci_detector.rb +1 -1
- data/lib/rigor/cli/annotate_command.rb +24 -19
- data/lib/rigor/cli/baseline_command.rb +145 -55
- data/lib/rigor/cli/catalogue.rb +256 -0
- data/lib/rigor/cli/check_command.rb +108 -102
- data/lib/rigor/cli/check_runner_factory.rb +2 -2
- data/lib/rigor/cli/command.rb +15 -1
- data/lib/rigor/cli/coverage_command.rb +21 -8
- data/lib/rigor/cli/coverage_mutation.rb +5 -7
- data/lib/rigor/cli/coverage_renderer.rb +2 -1
- data/lib/rigor/cli/coverage_scan.rb +3 -5
- data/lib/rigor/cli/diff_command.rb +25 -20
- data/lib/rigor/cli/docs_command.rb +1 -2
- data/lib/rigor/cli/doctor_command.rb +12 -12
- data/lib/rigor/cli/effects_command.rb +50 -40
- data/lib/rigor/cli/effects_diff_renderer.rb +18 -17
- data/lib/rigor/cli/effects_explain_renderer.rb +13 -12
- data/lib/rigor/cli/effects_renderer.rb +2 -1
- data/lib/rigor/cli/effects_snapshot_command.rb +18 -17
- data/lib/rigor/cli/explain_command.rb +18 -8
- data/lib/rigor/cli/fused_protection_renderer.rb +2 -1
- data/lib/rigor/cli/json_document.rb +41 -0
- data/lib/rigor/cli/lens_command.rb +12 -8
- data/lib/rigor/cli/lsp_command.rb +250 -23
- data/lib/rigor/cli/mcp_command.rb +12 -7
- data/lib/rigor/cli/mutation_fork_scan.rb +1 -1
- data/lib/rigor/cli/mutation_protection_renderer.rb +3 -2
- data/lib/rigor/cli/options.rb +40 -1
- data/lib/rigor/cli/plugin_command.rb +93 -46
- data/lib/rigor/cli/plugins_command.rb +17 -18
- data/lib/rigor/cli/plugins_renderer.rb +10 -6
- data/lib/rigor/cli/protection_fork_scan.rb +2 -2
- data/lib/rigor/cli/protection_renderer.rb +2 -1
- data/lib/rigor/cli/show_bleedingedge_command.rb +21 -15
- data/lib/rigor/cli/sig_gen_command.rb +84 -27
- data/lib/rigor/cli/skill_command.rb +32 -3
- data/lib/rigor/cli/skill_deep_probe.rb +1 -1
- data/lib/rigor/cli/skill_describe.rb +1 -1
- data/lib/rigor/cli/trace_command.rb +14 -9
- data/lib/rigor/cli/triage_command.rb +10 -11
- data/lib/rigor/cli/triage_renderer.rb +2 -1
- data/lib/rigor/cli/type_of_command.rb +16 -11
- data/lib/rigor/cli/type_of_project_scope.rb +1 -4
- data/lib/rigor/cli/type_of_renderer.rb +4 -1
- data/lib/rigor/cli/type_scan_command.rb +14 -9
- data/lib/rigor/cli/type_scan_renderer.rb +2 -1
- data/lib/rigor/cli/unused_command.rb +27 -17
- data/lib/rigor/cli/upgrade_command.rb +5 -0
- data/lib/rigor/cli.rb +209 -54
- data/lib/rigor/config_audit.rb +1 -1
- data/lib/rigor/configuration/severity_profile.rb +5 -5
- data/lib/rigor/configuration.rb +72 -30
- data/lib/rigor/effects/definition_context.rb +0 -2
- data/lib/rigor/effects/envelope.rb +1 -1
- data/lib/rigor/effects/framework_units.rb +1 -1
- data/lib/rigor/effects/mutation_classifier.rb +4 -7
- data/lib/rigor/effects/propagator.rb +1 -1
- data/lib/rigor/effects/registry.rb +2 -2
- data/lib/rigor/effects/snapshot.rb +1 -1
- data/lib/rigor/effects/taint_cause.rb +0 -2
- data/lib/rigor/effects/unit_scan.rb +9 -13
- data/lib/rigor/environment/bundle_sig_discovery.rb +5 -9
- data/lib/rigor/environment/class_registry.rb +3 -3
- data/lib/rigor/environment/core_root.rb +77 -0
- data/lib/rigor/environment/default_libraries.rb +1 -1
- data/lib/rigor/environment/deferred_signature_plan.rb +283 -0
- data/lib/rigor/environment/gated_signature_guard.rb +1 -1
- data/lib/rigor/environment/gated_signature_plan.rb +5 -2
- data/lib/rigor/environment/lockfile_resolver.rb +28 -12
- data/lib/rigor/environment/member_consistency/comparator.rb +18 -1
- data/lib/rigor/environment/member_consistency.rb +56 -7
- data/lib/rigor/environment/missing_gem_constant_index.rb +3 -2
- data/lib/rigor/environment/project_path_gems.rb +124 -0
- data/lib/rigor/environment/rbs_hierarchy.rb +6 -15
- data/lib/rigor/environment/rbs_loader.rb +480 -67
- data/lib/rigor/environment/reflection.rb +7 -7
- data/lib/rigor/environment/required_features.rb +0 -3
- data/lib/rigor/environment/ruby_library_roots.rb +1 -1
- data/lib/rigor/environment/vendored_signature_plan.rb +153 -0
- data/lib/rigor/environment.rb +41 -10
- data/lib/rigor/flow_contribution/merger.rb +4 -4
- data/lib/rigor/inference/acceptance.rb +93 -32
- data/lib/rigor/inference/block_parameter_binder.rb +2 -3
- data/lib/rigor/inference/block_run_count.rb +178 -0
- data/lib/rigor/inference/budget_trace.rb +8 -2
- data/lib/rigor/inference/builtins/exception_catalog.rb +2 -2
- data/lib/rigor/inference/builtins/numeric_catalog.rb +2 -5
- data/lib/rigor/inference/builtins/random_catalog.rb +2 -2
- data/lib/rigor/inference/callee_mutation_chain.rb +88 -77
- data/lib/rigor/inference/callee_write_census.rb +815 -0
- data/lib/rigor/inference/construction_escape.rb +217 -0
- data/lib/rigor/inference/declaration_walk/traversal.rb +1 -1
- data/lib/rigor/inference/deep_erasure.rb +39 -7
- data/lib/rigor/inference/def_handle.rb +1 -1
- data/lib/rigor/inference/def_node_resolver.rb +1 -1
- data/lib/rigor/inference/def_return_typer.rb +46 -4
- data/lib/rigor/inference/definer_resolution.rb +4 -2
- data/lib/rigor/inference/definers_index.rb +106 -0
- data/lib/rigor/inference/direct_ivar_writes.rb +300 -0
- data/lib/rigor/inference/element_read_widening.rb +49 -3
- data/lib/rigor/inference/expression_typer.rb +116 -49
- data/lib/rigor/inference/external_ancestor_resolution.rb +3 -4
- data/lib/rigor/inference/global_write_census.rb +76 -2
- data/lib/rigor/inference/global_writer_reach.rb +260 -0
- data/lib/rigor/inference/hkt_body.rb +1 -2
- data/lib/rigor/inference/hkt_body_parser.rb +3 -5
- data/lib/rigor/inference/hkt_reducer.rb +2 -2
- data/lib/rigor/inference/hkt_registry.rb +3 -5
- data/lib/rigor/inference/indexed_narrowing.rb +4 -7
- data/lib/rigor/inference/intervening_ivar_reset.rb +26 -4
- data/lib/rigor/inference/ivar_writer_census.rb +51 -0
- data/lib/rigor/inference/key_presence_guard.rb +2 -1
- data/lib/rigor/inference/loop_value_record.rb +8 -4
- data/lib/rigor/inference/match_rebinding/frame.rb +46 -0
- data/lib/rigor/inference/match_rebinding/yielding_match.rb +45 -0
- data/lib/rigor/inference/match_rebinding.rb +11 -1
- data/lib/rigor/inference/memo_audit.rb +55 -0
- data/lib/rigor/inference/method_dispatcher/alias_strict_nominals.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/argument_distribution.rb +40 -0
- data/lib/rigor/inference/method_dispatcher/block_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/constant_folding.rb +3 -3
- data/lib/rigor/inference/method_dispatcher/contested_overloads.rb +89 -0
- data/lib/rigor/inference/method_dispatcher/iterator_dispatch.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/kernel_dispatch.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/no_match_fallback.rb +54 -0
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +39 -27
- data/lib/rigor/inference/method_dispatcher/random_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +203 -17
- data/lib/rigor/inference/method_dispatcher/reduce_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/regexp_folding.rb +2 -2
- data/lib/rigor/inference/method_dispatcher/self_substitute.rb +2 -2
- data/lib/rigor/inference/method_dispatcher/set_folding.rb +9 -7
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +83 -20
- data/lib/rigor/inference/method_dispatcher/singleton_folding.rb +0 -1
- data/lib/rigor/inference/method_dispatcher/singleton_mixin_dispatch.rb +50 -17
- data/lib/rigor/inference/method_dispatcher/struct_folding.rb +5 -5
- data/lib/rigor/inference/method_dispatcher/struct_materialization.rb +4 -6
- data/lib/rigor/inference/method_dispatcher/uri_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher.rb +64 -14
- data/lib/rigor/inference/module_function_state.rb +11 -1
- data/lib/rigor/inference/multi_target_binder.rb +1 -1
- data/lib/rigor/inference/mutation_rejoin.rb +240 -4
- data/lib/rigor/inference/mutation_widening.rb +157 -27
- data/lib/rigor/inference/narrowing.rb +47 -33
- data/lib/rigor/inference/optimistic_origin.rb +1 -1
- data/lib/rigor/inference/out_buffer_mutation.rb +72 -0
- data/lib/rigor/inference/parameter_inference_collector.rb +5 -6
- data/lib/rigor/inference/pre_eval_constants.rb +1 -1
- data/lib/rigor/inference/project_method_ownership.rb +6 -3
- data/lib/rigor/inference/project_yielder.rb +11 -17
- data/lib/rigor/inference/receiver_alias.rb +20 -0
- data/lib/rigor/inference/refined_dispatch/constructed_class.rb +3 -1
- data/lib/rigor/inference/refined_dispatch/own_method.rb +2 -1
- data/lib/rigor/inference/remover_holder_scan.rb +233 -0
- data/lib/rigor/inference/remover_narrowing.rb +224 -0
- data/lib/rigor/inference/rewrite_mutation.rb +53 -2
- data/lib/rigor/inference/scope_indexer/certainty.rb +0 -1
- data/lib/rigor/inference/scope_indexer/constant_ivar_value.rb +93 -0
- data/lib/rigor/inference/scope_indexer/declared_param_writes.rb +58 -15
- data/lib/rigor/inference/scope_indexer/derived_param_value.rb +112 -0
- data/lib/rigor/inference/scope_indexer/empty_seed.rb +99 -0
- data/lib/rigor/inference/scope_indexer/ivar_contributions.rb +135 -0
- data/lib/rigor/inference/scope_indexer.rb +137 -46
- data/lib/rigor/inference/self_call_ivar_writes.rb +84 -12
- data/lib/rigor/inference/set_mutation.rb +189 -0
- data/lib/rigor/inference/singleton_hook_decline.rb +1 -2
- data/lib/rigor/inference/statement_evaluator.rb +2328 -138
- data/lib/rigor/inference/struct_fold_safety.rb +4 -6
- data/lib/rigor/inference/synthetic_method_scanner.rb +5 -6
- data/lib/rigor/inference/toplevel_def_census.rb +59 -0
- data/lib/rigor/inference/unknown_store_widening.rb +103 -4
- data/lib/rigor/inference/unthreaded_rebinds.rb +2 -3
- data/lib/rigor/inference/void_tail_summary.rb +2 -1
- data/lib/rigor/language_server/buffer_table.rb +3 -3
- data/lib/rigor/language_server/completion_provider.rb +26 -20
- data/lib/rigor/language_server/config_warning_announcer.rb +28 -0
- data/lib/rigor/language_server/diagnostic_publisher.rb +8 -3
- data/lib/rigor/language_server/document_symbol_provider.rb +1 -1
- data/lib/rigor/language_server/folding_range_provider.rb +1 -2
- data/lib/rigor/language_server/hover_provider.rb +1 -7
- data/lib/rigor/language_server/hover_renderer.rb +6 -8
- data/lib/rigor/language_server/project_context.rb +39 -1
- data/lib/rigor/language_server/publish_batcher.rb +3 -4
- data/lib/rigor/language_server/selection_range_provider.rb +2 -4
- data/lib/rigor/language_server/server.rb +7 -3
- data/lib/rigor/language_server/signature_help_provider.rb +4 -4
- data/lib/rigor/lens/plugins.rb +1 -1
- data/lib/rigor/mcp/server.rb +73 -2
- data/lib/rigor/mcp.rb +1 -1
- data/lib/rigor/plugin/access_denied_error.rb +1 -2
- data/lib/rigor/plugin/bundled_catalog.rb +1 -12
- data/lib/rigor/plugin/io_boundary.rb +1 -1
- data/lib/rigor/plugin/loader.rb +25 -8
- data/lib/rigor/plugin/macro/heredoc_template.rb +7 -8
- data/lib/rigor/plugin/macro/trait_registry.rb +6 -9
- data/lib/rigor/plugin/manifest.rb +9 -13
- data/lib/rigor/plugin/registry.rb +3 -3
- data/lib/rigor/plugin/services.rb +2 -3
- data/lib/rigor/plugin/source_rbs_synthesis_reporter.rb +11 -0
- data/lib/rigor/plugin/trust_policy.rb +2 -2
- data/lib/rigor/plugin/type_node_resolver.rb +2 -4
- data/lib/rigor/plugin.rb +6 -8
- data/lib/rigor/plugin_gap_advisory.rb +5 -1
- data/lib/rigor/project_environment.rb +16 -2
- data/lib/rigor/protection/analysis_guard.rb +1 -1
- data/lib/rigor/protection/discovery_seed.rb +44 -5
- data/lib/rigor/protection/mutator.rb +1 -1
- data/lib/rigor/rbs_extended/envelope_scanner.rb +4 -6
- data/lib/rigor/rbs_extended/hkt_directives.rb +6 -10
- data/lib/rigor/rbs_extended/reporter.rb +27 -3
- data/lib/rigor/rbs_extended.rb +2 -3
- data/lib/rigor/reflection/constant_ancestors.rb +5 -3
- data/lib/rigor/rooted_glob.rb +15 -1
- data/lib/rigor/run_scoped_slots.rb +38 -0
- data/lib/rigor/runtime/jit.rb +1 -1
- data/lib/rigor/scope/discovery_index.rb +19 -6
- data/lib/rigor/scope/resolution_chain.rb +3 -1
- data/lib/rigor/scope.rb +365 -31
- data/lib/rigor/sig_gen/classification.rb +4 -0
- data/lib/rigor/sig_gen/effect_annotation.rb +3 -3
- data/lib/rigor/sig_gen/generator.rb +371 -58
- data/lib/rigor/sig_gen/generic_header_scan.rb +189 -0
- data/lib/rigor/sig_gen/inline_declarations.rb +2 -2
- data/lib/rigor/sig_gen/layout_index.rb +3 -3
- data/lib/rigor/sig_gen/method_candidate.rb +23 -4
- data/lib/rigor/sig_gen/observation_collector.rb +3 -5
- data/lib/rigor/sig_gen/observed_call.rb +1 -1
- data/lib/rigor/sig_gen/path_mapper.rb +6 -0
- data/lib/rigor/sig_gen/renderer.rb +15 -9
- data/lib/rigor/sig_gen/skip_reason_catalog.rb +15 -2
- data/lib/rigor/sig_gen/type_name_qualification.rb +69 -0
- data/lib/rigor/sig_gen/write_reporter.rb +63 -14
- data/lib/rigor/sig_gen/write_result.rb +23 -12
- data/lib/rigor/sig_gen/writer.rb +217 -37
- data/lib/rigor/type/acceptance_router.rb +2 -2
- data/lib/rigor/type/accepts_result.rb +1 -1
- data/lib/rigor/type/app.rb +4 -6
- data/lib/rigor/type/combinator.rb +9 -13
- data/lib/rigor/type/constant.rb +4 -5
- data/lib/rigor/type/hash_shape.rb +21 -40
- data/lib/rigor/type/union.rb +1 -1
- data/lib/rigor/type_node/identifier.rb +1 -2
- data/lib/rigor/type_node/resolver_chain.rb +1 -1
- data/lib/rigor/type_node/string_literal.rb +1 -2
- data/lib/rigor/type_node/symbol_literal.rb +1 -2
- data/lib/rigor/type_node/union.rb +3 -6
- data/lib/rigor/value_semantics.rb +1 -10
- data/lib/rigor/version.rb +1 -1
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_discoverer.rb +2 -2
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_index.rb +2 -3
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +1 -1
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_discoverer.rb +38 -36
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_index.rb +4 -2
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb +6 -4
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb +1 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_index.rb +1 -5
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_scan.rb +0 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/erb_compiler.rb +2 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/view_assigns.rb +1 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +66 -19
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/effects.rb +1 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +4 -3
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/association_roots.rb +3 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/effects.rb +2 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +21 -31
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_index.rb +10 -16
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_parser.rb +2 -3
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_table.rb +0 -1
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +5 -4
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_discoverer.rb +3 -4
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_index.rb +1 -1
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +7 -12
- data/plugins/rigor-activestorage/lib/rigor-activestorage.rb +1 -1
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext/effects.rb +1 -1
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext/symbolize_keys.rb +102 -0
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb +19 -6
- data/plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs +26 -13
- data/plugins/rigor-alba/lib/rigor/plugin/alba/resource_index.rb +3 -3
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema/schema_scanner.rb +1 -3
- data/plugins/rigor-dry-struct/lib/rigor/plugin/dry_struct.rb +6 -6
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types/alias_scanner.rb +5 -6
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types.rb +1 -1
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation/params_shape.rb +2 -3
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation.rb +5 -8
- data/plugins/rigor-ethon/lib/rigor/plugin/ethon.rb +0 -1
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_discoverer.rb +1 -1
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot.rb +10 -18
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi/analyzer.rb +0 -1
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi/discoverer.rb +0 -2
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi.rb +4 -5
- data/plugins/rigor-grape/lib/rigor/plugin/grape.rb +0 -2
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql/type_scanner.rb +6 -7
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami/action_checker.rb +2 -4
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami.rb +2 -5
- data/plugins/rigor-mangrove/lib/rigor/plugin/mangrove.rb +2 -2
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest/assertion_analyzer.rb +6 -6
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_discoverer.rb +2 -1
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/analyzer.rb +3 -8
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_index.rb +2 -3
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_loader.rb +5 -8
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/analyzer.rb +1 -3
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/devise_routes.rb +2 -3
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_discoverer.rb +1 -1
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/routes_parser.rb +4 -11
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +1 -1
- data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb +2 -1
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +1 -1
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec.rb +2 -2
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails.rb +3 -4
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers/analyzer.rb +6 -8
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb +3 -2
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/absurd_recognizer.rb +4 -5
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/assertion_recognizer.rb +6 -7
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog.rb +1 -1
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sig_parser.rb +2 -2
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +17 -21
- data/plugins/rigor-statesman/lib/rigor/plugin/statesman.rb +2 -3
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer/serializer_discoverer.rb +3 -2
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer/serializer_index.rb +4 -4
- data/sig/rigor/analysis/baseline.rbs +0 -3
- data/sig/rigor/analysis/fact_store.rbs +1 -0
- data/sig/rigor/analysis/reachability/scan_cache.rbs +1 -1
- data/sig/rigor/cli/diff_command.rbs +1 -1
- data/sig/rigor/cli/explain_command.rbs +1 -1
- data/sig/rigor/effects/registry.rbs +2 -2
- data/sig/rigor/inference.rbs +4 -1
- data/sig/rigor/plugin/additional_initializer.rbs +0 -5
- data/sig/rigor/plugin/base.rbs +1 -0
- data/sig/rigor/plugin/effect_attribution.rbs +3 -3
- data/sig/rigor/plugin/effect_edge.rbs +1 -1
- data/sig/rigor/plugin/effect_entry_points.rbs +3 -3
- data/sig/rigor/plugin/io_boundary.rbs +2 -1
- data/sig/rigor/plugin/manifest.rbs +9 -9
- data/sig/rigor/plugin/protocol_contract.rbs +3 -7
- data/sig/rigor/scope.rbs +23 -3
- data/skills/rigor-plugin-author/SKILL.md +4 -4
- data/skills/rigor-plugin-author/references/02-walker-and-types.md +5 -5
- data/skills/rigor-plugin-review/SKILL.md +3 -3
- data/skills/rigor-project-init/references/03-baseline-and-bugs.md +12 -1
- metadata +36 -3
|
@@ -14,7 +14,7 @@ module Rigor
|
|
|
14
14
|
# declared types. See {MemberConsistency} for the rule; this class holds the type work.
|
|
15
15
|
#
|
|
16
16
|
# A contradiction is reported only where it is PROVEN: no value, and no call, satisfies both sides.
|
|
17
|
-
# Everything short of a proof is undecided.
|
|
17
|
+
# Everything short of a proof is undecided. Five places carry that burden:
|
|
18
18
|
#
|
|
19
19
|
# - {#disjoint?} proves two types share no value, from the RBS hierarchy of Ruby core and stdlib
|
|
20
20
|
# classes ({RbsProof}) only: two such classes neither of which is an RBS ancestor of the other, or a
|
|
@@ -103,6 +103,7 @@ module Rigor
|
|
|
103
103
|
# `:inline` (the inline side is more precise), `:contradiction` or `:undecided`; `detail` names the
|
|
104
104
|
# deciding position for the two reported outcomes and is nil otherwise.
|
|
105
105
|
def compare(signature_member, inline_member, method_name)
|
|
106
|
+
return compare_variables(signature_member, inline_member) if variable?(signature_member)
|
|
106
107
|
return EQUAL if same_declaration?(signature_member, inline_member)
|
|
107
108
|
return SIGNATURE_MORE_PRECISE if inferred_signature?(inline_member)
|
|
108
109
|
|
|
@@ -174,6 +175,22 @@ module Rigor
|
|
|
174
175
|
member_annotation_strings(member).include?(INFERRED_SIGNATURE_DIRECTIVE)
|
|
175
176
|
end
|
|
176
177
|
|
|
178
|
+
def variable?(member)
|
|
179
|
+
member.is_a?(::RBS::AST::Members::InstanceVariable) ||
|
|
180
|
+
member.is_a?(::RBS::AST::Members::ClassInstanceVariable)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Issue #2440 — an instance variable (or class instance variable) declared on both sides. Two
|
|
184
|
+
# declarations of one type are equal and merge silently. Any other pair is undecided, never ranked
|
|
185
|
+
# and never a contradiction: `sig/` binds and the inline declaration is reported at `:info`. A
|
|
186
|
+
# variable has no call to satisfy, so "more precise" has no reader to favour, and the committed
|
|
187
|
+
# `.rbs` (typically `rbs-inline --output`'s own) is the declaration the project's other tools read.
|
|
188
|
+
def compare_variables(signature_member, inline_member)
|
|
189
|
+
return EQUAL if signature_member.type == inline_member.type
|
|
190
|
+
|
|
191
|
+
[:undecided, "the type is `#{signature_member.type}` in `sig/` and `#{inline_member.type}` inline"]
|
|
192
|
+
end
|
|
193
|
+
|
|
177
194
|
def compare_aliases(signature_member, inline_member)
|
|
178
195
|
both = signature_member.is_a?(::RBS::AST::Members::Alias) && inline_member.is_a?(::RBS::AST::Members::Alias)
|
|
179
196
|
return EQUAL if both && signature_member.old_name == inline_member.old_name
|
|
@@ -59,6 +59,9 @@ module Rigor
|
|
|
59
59
|
NO_RECORDS = [].freeze
|
|
60
60
|
private_constant :NO_RECORDS
|
|
61
61
|
|
|
62
|
+
# The key kinds {.member_keys} gives a variable member.
|
|
63
|
+
VARIABLE_KINDS = %i[instance_variable class_instance_variable].freeze
|
|
64
|
+
|
|
62
65
|
# What a disjointness proof may lean on (ADR-112 WD5, #1075): the RBS class hierarchy the analysis
|
|
63
66
|
# itself uses, restricted to classes Ruby core and the stdlib declare. Never Ruby constants loaded in
|
|
64
67
|
# the analyzer process — those depend on which libraries happen to be required, and rbs and Ruby
|
|
@@ -115,8 +118,8 @@ module Rigor
|
|
|
115
118
|
class << self
|
|
116
119
|
# @param signature_members — `{[class, method, kind] => [signature_path, member, visibility]}`, the
|
|
117
120
|
# first project `.rbs` member declaring each key, with its effective visibility.
|
|
118
|
-
# @param inline_members — `[[virtual_name, class_name, member, visibility], ...]`, every member
|
|
119
|
-
# inline sources declare.
|
|
121
|
+
# @param inline_members — `[[virtual_name, class_name, member, visibility, nesting], ...]`, every member
|
|
122
|
+
# the inline sources declare, with the lexical nesting {.member_keys} keys a mixin by.
|
|
120
123
|
# @param shadowable — the first segment of every class / module name the project's inputs declare
|
|
121
124
|
# ({Comparator#initialize}).
|
|
122
125
|
# @param proof — an {RbsProof} for the reported rows, or nil for the environment build.
|
|
@@ -131,9 +134,9 @@ module Rigor
|
|
|
131
134
|
|
|
132
135
|
state = { comparator: Comparator.new(shadowable, proof: proof), records: [], inline: Set.new,
|
|
133
136
|
signature: Hash.new { |hash, file| hash[file] = Set.new }, checked: {}.compare_by_identity }
|
|
134
|
-
inline_members.each do |virtual_name, class_name, member, visibility|
|
|
137
|
+
inline_members.each do |virtual_name, class_name, member, visibility, nesting|
|
|
135
138
|
state[:records].concat(refinement_records(state, class_name, member, nil, virtual_name))
|
|
136
|
-
resolve_member(state, signature_members, [virtual_name, class_name, member, visibility])
|
|
139
|
+
resolve_member(state, signature_members, [virtual_name, class_name, member, visibility, nesting])
|
|
137
140
|
end
|
|
138
141
|
Resolution.new(
|
|
139
142
|
records: state[:records].uniq.sort_by { |r| record_sort_key(r) }.freeze,
|
|
@@ -159,11 +162,57 @@ module Rigor
|
|
|
159
162
|
end
|
|
160
163
|
end
|
|
161
164
|
|
|
165
|
+
# Issue #2440 — every key one RBS member contributes to a definition build: its method keys
|
|
166
|
+
# ({.member_method_keys}) and, for an instance variable (`@x: T`) or a class instance variable
|
|
167
|
+
# (`self.@x: T`), `[:@x, :instance_variable]` / `[:@x, :class_instance_variable]`. rbs 4.2 raises
|
|
168
|
+
# `InstanceVariableDuplicationError` / `ClassInstanceVariableDuplicationError` for two of those in one
|
|
169
|
+
# class even when the types agree, so a `sig/` and an inline declaration of one has to be reconciled
|
|
170
|
+
# like a method. A method name never starts with `@`, so the two key spaces cannot meet. A class
|
|
171
|
+
# variable (`@@x`) contributes nothing: rbs does not reject a duplicate. Neither does an attribute's
|
|
172
|
+
# implied instance variable, which rbs lets an explicit `@x` declaration override.
|
|
173
|
+
#
|
|
174
|
+
# A mixin (`include M`, `extend M`, `prepend M`) is keyed by the lexical nesting of the declaration
|
|
175
|
+
# it sits in and the module and type arguments exactly as written, `[:"A/C|M[String]", :include]`:
|
|
176
|
+
# rbs 4.2 counts every instance variable `M` declares once per declaration of the class that mixes it
|
|
177
|
+
# in, so the same `include M` in `sig/` and inline raises `InstanceVariableDuplicationError ... in ::M`
|
|
178
|
+
# for the class. A relative name resolves through the nesting it is written in, so `include M` inside
|
|
179
|
+
# `module A; class C` (`A::M` when that exists) and inside `class A::C` (`::M`) are different mixins,
|
|
180
|
+
# and so are `M` and `::M`; only an identical spelling in an identical nesting is the same member and
|
|
181
|
+
# stands down. `rbs-inline --output` mirrors the Ruby file's nesting, so its committed output still
|
|
182
|
+
# pairs with the inline buffer. A mixin with different arguments keys differently and is left alone.
|
|
183
|
+
# Two members sharing a mixin key declare no method types to compare, so they read as equal.
|
|
184
|
+
#
|
|
185
|
+
# `nesting` is the declaration names as written, outermost first, joined by `/`
|
|
186
|
+
# ({RbsLoader.each_declared_member}); nil keys a mixin by its spelling alone.
|
|
187
|
+
#
|
|
188
|
+
# Kept apart from {.member_method_keys} on purpose: the plugin-signature plans key collisions by
|
|
189
|
+
# method only, and this rule is the inline-vs-`sig/` one.
|
|
190
|
+
def member_keys(member, nesting = nil)
|
|
191
|
+
case member
|
|
192
|
+
when ::RBS::AST::Members::InstanceVariable then [[member.name, :instance_variable]]
|
|
193
|
+
when ::RBS::AST::Members::ClassInstanceVariable then [[member.name, :class_instance_variable]]
|
|
194
|
+
when ::RBS::AST::Members::Include then [[mixin_key(member, nesting), :include]]
|
|
195
|
+
when ::RBS::AST::Members::Extend then [[mixin_key(member, nesting), :extend]]
|
|
196
|
+
when ::RBS::AST::Members::Prepend then [[mixin_key(member, nesting), :prepend]]
|
|
197
|
+
else member_method_keys(member)
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Whether a key `kind` names a variable rather than a method.
|
|
202
|
+
def variable_kind?(kind)
|
|
203
|
+
VARIABLE_KINDS.include?(kind)
|
|
204
|
+
end
|
|
205
|
+
|
|
162
206
|
private
|
|
163
207
|
|
|
208
|
+
def mixin_key(member, nesting)
|
|
209
|
+
args = member.args.empty? ? "" : "[#{member.args.join(', ')}]"
|
|
210
|
+
:"#{nesting}|#{member.name}#{args}"
|
|
211
|
+
end
|
|
212
|
+
|
|
164
213
|
def resolve_member(state, signature_members, inline)
|
|
165
|
-
_virtual_name, class_name, member, = inline
|
|
166
|
-
overlapping =
|
|
214
|
+
_virtual_name, class_name, member, _visibility, nesting = inline
|
|
215
|
+
overlapping = member_keys(member, nesting).filter_map do |method_name, kind|
|
|
167
216
|
key = [class_name, method_name, kind]
|
|
168
217
|
owner = signature_members[key]
|
|
169
218
|
owner && [key, *owner]
|
|
@@ -235,7 +284,7 @@ module Rigor
|
|
|
235
284
|
end
|
|
236
285
|
|
|
237
286
|
def full_keys(class_name, member)
|
|
238
|
-
|
|
287
|
+
member_keys(member).map { |method_name, kind| [class_name, method_name, kind] }
|
|
239
288
|
end
|
|
240
289
|
|
|
241
290
|
# The `.rbs` line is read only for an outcome that reports it: asking an `RBS::Buffer` for a line
|
|
@@ -107,8 +107,9 @@ module Rigor
|
|
|
107
107
|
# difference is worth stating because the two look like the same problem. There, a stale
|
|
108
108
|
# `bundler/gems/` directory left behind by a gem that moved to a released version made the loader
|
|
109
109
|
# load the WRONG SIGNATURES, collapsing the RBS environment. Here the index's whole output is a gem
|
|
110
|
-
# NAME, so reading a stale checkout of the same gem yields the same answer; and the
|
|
111
|
-
# is consulted FIRST in {.build}, so a gem
|
|
110
|
+
# NAME, so reading a stale checkout of the same gem yields the same answer; and the RubyGems-layout
|
|
111
|
+
# bundle directory is consulted FIRST in {.build}, so a gem installed from RubyGems at its locked
|
|
112
|
+
# version never reaches this map.
|
|
112
113
|
def git_gem_dirs(bundle_path)
|
|
113
114
|
return {} if bundle_path.nil?
|
|
114
115
|
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../analysis/path_expansion"
|
|
4
|
+
|
|
5
|
+
module Rigor
|
|
6
|
+
class Environment
|
|
7
|
+
# Issue #2441 — the locked gems that ARE the analysed project: a `PATH` stanza whose directory Rigor analyses
|
|
8
|
+
# as project source. `rbs collection install` still fetches community RBS for such a gem (its generator skips
|
|
9
|
+
# only a `gemspec` source), and the project's `sig/` declares the same classes, so the collection copy would
|
|
10
|
+
# double-declare every member. The same gem is not `:missing` RBS either, so it must not make an ADR-72
|
|
11
|
+
# overlay or a WD9 missing-gem index entry eligible.
|
|
12
|
+
#
|
|
13
|
+
# "Analysed as project source" means the gem's directory is at or under one of the configured `paths:`
|
|
14
|
+
# entries, or contains one: rails lists `actionpack/lib` in `paths:` and locks `actionpack` from
|
|
15
|
+
# `PATH remote: actionpack`. A `PATH` gem no `paths:` entry reaches — a vendored `vendor/gems/foo`, a sibling
|
|
16
|
+
# checkout — is a dependency and keeps its collection RBS.
|
|
17
|
+
#
|
|
18
|
+
# #2592 — a reached gem counts only when the file walker would analyse at least one of its Ruby files: some
|
|
19
|
+
# `**/*.rb` under the part of the gem a `paths:` entry covers survives `Analysis::PathExpansion.reject_excluded`.
|
|
20
|
+
# A gem whose Ruby the configuration's `exclude:` patterns all leave out — `vendor/**`, `vendor/**/*.rb`, or
|
|
21
|
+
# `vendor/gems/foo/lib/**` when `lib/` holds all of it — keeps its collection RBS, and so does a reached
|
|
22
|
+
# directory with no Ruby at all. A `paths:` entry naming one `.rb` file inside the gem counts that file. The
|
|
23
|
+
# overlap is found on real paths, so a symlinked spelling of the same directory matches, but the files are
|
|
24
|
+
# walked and matched against `exclude:` through the `paths:` entry as written, as the walker matches them.
|
|
25
|
+
module ProjectPathGems
|
|
26
|
+
module_function
|
|
27
|
+
|
|
28
|
+
# @param locked — `{name => LockfileResolver::LockedGem}`.
|
|
29
|
+
# @param paths — the configured `paths:` entries; relative ones resolve against `root`.
|
|
30
|
+
# @param exclude_patterns — the configuration's `exclude_patterns`, matched against `exclude_base`.
|
|
31
|
+
# @return frozen set of gem names. Empty when `paths` is nil or empty.
|
|
32
|
+
def names(locked, paths:, root: Dir.pwd, exclude_patterns: [], exclude_base: root)
|
|
33
|
+
entries = Array(paths).map do |path|
|
|
34
|
+
logical = File.expand_path(path.to_s, root.to_s)
|
|
35
|
+
[logical, real(logical)]
|
|
36
|
+
end.uniq
|
|
37
|
+
return Set.new.freeze if entries.empty?
|
|
38
|
+
|
|
39
|
+
locked.each_value.filter_map do |gem|
|
|
40
|
+
dir = gem.path_source
|
|
41
|
+
next unless dir
|
|
42
|
+
|
|
43
|
+
dir = real(dir)
|
|
44
|
+
covered = entries.filter_map { |logical, real_entry| covered_part(dir, logical, real_entry) }
|
|
45
|
+
gem.name if covered.uniq.any? { |part| analysed_ruby?(part, Array(exclude_patterns), exclude_base.to_s) }
|
|
46
|
+
end.to_set.freeze
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# The part of the gem at real directory `dir` that the `paths:` entry covers, spelled through the entry as
|
|
50
|
+
# written (`logical`), as the file walker spells the files it matches `exclude:` against: the entry itself
|
|
51
|
+
# when it lies at or under the gem, or the gem's directory reached through the entry when the gem lies under
|
|
52
|
+
# it. Nil when they do not overlap.
|
|
53
|
+
def covered_part(dir, logical, real_entry)
|
|
54
|
+
return logical if at_or_under?(real_entry, dir)
|
|
55
|
+
return unless at_or_under?(dir, real_entry)
|
|
56
|
+
|
|
57
|
+
rest = dir.byteslice(real_entry.bytesize..).delete_prefix("/")
|
|
58
|
+
rest.empty? ? logical : File.join(logical, rest)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# True when `path` is `dir` or lies under it. Joined with a `/` only when `dir` does not already end in one,
|
|
62
|
+
# so `/` reaches everything without spelling `//`, and `/proj/lib2` is not under `/proj/lib`.
|
|
63
|
+
def at_or_under?(path, dir)
|
|
64
|
+
return true if path == dir
|
|
65
|
+
|
|
66
|
+
path.start_with?(dir.end_with?("/") ? dir : "#{dir}/")
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Files are matched in slices as the walk finds them, so a large gem stops at the first slice holding a
|
|
70
|
+
# surviving file instead of listing its whole tree first (`Dir.glob` with a block still builds the list).
|
|
71
|
+
EXCLUDE_SLICE = 64
|
|
72
|
+
private_constant :EXCLUDE_SLICE
|
|
73
|
+
|
|
74
|
+
# True when the file walker ({Analysis::PathExpansion.ruby_files}) would analyse some `.rb` file of `part`:
|
|
75
|
+
# the `.rb` file itself when `part` names one, else a `**/*.rb` under the directory, that survives `patterns`.
|
|
76
|
+
def analysed_ruby?(part, patterns, base)
|
|
77
|
+
return surviving?([part], patterns, base) if File.file?(part)
|
|
78
|
+
return false unless File.directory?(part)
|
|
79
|
+
|
|
80
|
+
slice = []
|
|
81
|
+
found = each_ruby_file(part) do |file|
|
|
82
|
+
slice << file
|
|
83
|
+
next false if slice.size < EXCLUDE_SLICE
|
|
84
|
+
|
|
85
|
+
hit = surviving?(slice, patterns, base)
|
|
86
|
+
slice = []
|
|
87
|
+
hit
|
|
88
|
+
end
|
|
89
|
+
found || surviving?(slice, patterns, base)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Walks `dir` as `Dir.glob("dir/**/*.rb")` matches: sorted, no dot-named entries, no descent through a
|
|
93
|
+
# symlinked directory. Stops and returns true as soon as the block returns true.
|
|
94
|
+
def each_ruby_file(dir, &)
|
|
95
|
+
Dir.children(dir).sort.each do |name|
|
|
96
|
+
next if name.start_with?(".")
|
|
97
|
+
|
|
98
|
+
path = File.join(dir, name)
|
|
99
|
+
if name.end_with?(".rb") && !File.directory?(path)
|
|
100
|
+
return true if File.exist?(path) && yield(path)
|
|
101
|
+
elsif File.directory?(path) && !File.symlink?(path)
|
|
102
|
+
return true if each_ruby_file(path, &)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
false
|
|
106
|
+
rescue SystemCallError
|
|
107
|
+
false
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def surviving?(files, patterns, base)
|
|
111
|
+
return false if files.empty?
|
|
112
|
+
return files.any? { |file| file.end_with?(".rb") } if patterns.empty?
|
|
113
|
+
|
|
114
|
+
Analysis::PathExpansion.reject_excluded(files, patterns, base: base).any? { |file| file.end_with?(".rb") }
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def real(path)
|
|
118
|
+
File.realpath(path)
|
|
119
|
+
rescue SystemCallError
|
|
120
|
+
File.expand_path(path)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -41,21 +41,12 @@ module Rigor
|
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
# Issue #696 review, second pass — the ancestry lookup
|
|
45
|
-
#
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
# classes failed to build" — 504 on a cold store, 0 on a warm one, 2 with no store. On the DEFAULT
|
|
51
|
-
# `--workers=0` path nothing pre-warms the store, so the cold answer was the one written into the
|
|
52
|
-
# run-result cache and replayed until a file changed.
|
|
53
|
-
#
|
|
54
|
-
# The cache-state branch still exists — it is worth 50x on the warm path — but it lives behind the
|
|
55
|
-
# loader now, where both of its sides are marked as RIGOR'S OWN demand. Ordering two classes is not
|
|
56
|
-
# the analysis asking whether either one's methods resolve, so neither side reaches the diagnostic,
|
|
57
|
-
# and the answer is identical on both (the table's producer computes exactly this, keyed the same
|
|
58
|
-
# way). What this method keeps is its own per-name memo, which is about repeated comparisons.
|
|
44
|
+
# Issue #696 review, second pass — the ancestry lookup lives in {RbsLoader#ancestor_names_for}.
|
|
45
|
+
# Read directly from `Cache::RbsClassAncestorTable`, the same question gave 504 failed classes on a
|
|
46
|
+
# cold store, 0 on a warm one and 2 with no store, and the cold answer was cached into the run result.
|
|
47
|
+
# Through the loader, both cache states are marked as Rigor's own demand, so ordering two classes
|
|
48
|
+
# never reaches the "which classes failed to build" diagnostic. The cache-state branch stays behind
|
|
49
|
+
# the loader (it is worth 50x on the warm path); this method keeps only its per-name memo.
|
|
59
50
|
def ancestor_names(class_name)
|
|
60
51
|
key = normalize_name(class_name)
|
|
61
52
|
return @ancestor_names_cache[key] if @ancestor_names_cache.key?(key)
|