rigortype 0.4.0 → 0.4.2
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 +4 -3
- data/data/builtins/ruby_core/io.yml +1 -0
- data/data/builtins/ruby_core/proc.yml +4 -0
- data/data/builtins/ruby_core/random.yml +4 -0
- data/data/builtins/ruby_core/struct.yml +3 -0
- data/data/core_overlay/env.rbs +34 -0
- data/data/core_overlay/gc.rbs +50 -0
- data/data/core_overlay/hash.rbs +45 -0
- data/data/core_overlay/integer.rbs +31 -0
- data/data/core_overlay/io_buffer.rbs +27 -0
- data/data/core_overlay/kernel.rbs +40 -0
- data/data/core_overlay/match_data.rbs +28 -0
- data/data/core_overlay/module.rbs +51 -0
- data/data/core_overlay/object_space.rbs +29 -0
- data/data/core_overlay/proc.rbs +45 -0
- data/data/core_overlay/range.rbs +40 -0
- data/data/core_overlay/source_range.rbs +78 -0
- data/data/core_overlay/string.rbs +86 -0
- data/data/vendored_gem_sigs/prime/integer-extension.rbs +41 -0
- data/data/vendored_gem_sigs/prime/prime.rbs +372 -0
- data/docs/handbook/01-getting-started.md +3 -3
- data/docs/handbook/06-classes.md +3 -1
- data/docs/handbook/08-understanding-errors.md +3 -2
- data/docs/handbook/11-sig-gen.md +6 -0
- data/docs/handbook/appendix-liskov.md +5 -0
- data/docs/install.md +87 -15
- data/docs/manual/02-cli-reference.md +2 -2
- data/docs/manual/03-configuration.md +6 -1
- data/docs/manual/04-diagnostics.md +2 -1
- data/docs/manual/06-baseline.md +2 -0
- data/docs/manual/07-plugins.md +1 -1
- data/docs/manual/08-skills.md +4 -3
- data/docs/manual/12-caching.md +43 -4
- data/docs/manual/14-rails-quickstart.md +19 -11
- data/docs/manual/18-removing-dead-code.md +32 -2
- data/docs/manual/plugins/README.md +6 -1
- data/docs/manual/plugins/rigor-activerecord.md +21 -0
- data/docs/manual/plugins/rigor-alba.md +60 -0
- data/docs/manual/plugins/rigor-minitest.md +22 -4
- data/docs/manual/plugins/rigor-typelizer.md +71 -0
- data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +27 -3
- data/lib/rigor/analysis/check_rules/lexical_method_sites.rb +21 -92
- data/lib/rigor/analysis/check_rules/ruby_deprecations.rb +275 -0
- data/lib/rigor/analysis/check_rules/rule_ids.rb +4 -0
- data/lib/rigor/analysis/check_rules/source_arity.rb +184 -61
- data/lib/rigor/analysis/check_rules.rb +407 -144
- data/lib/rigor/analysis/dependency_recorder.rb +215 -18
- data/lib/rigor/analysis/dependency_source_inference/builder.rb +8 -1
- data/lib/rigor/analysis/dependency_source_inference/gem_resolver.rb +21 -0
- data/lib/rigor/analysis/dependency_source_inference/index.rb +36 -11
- data/lib/rigor/analysis/dependency_source_inference/walker.rb +196 -27
- data/lib/rigor/analysis/erb_template_detector.rb +2 -1
- data/lib/rigor/analysis/incremental.rb +29 -9
- data/lib/rigor/analysis/incremental_run_slot/write_guard.rb +291 -0
- data/lib/rigor/analysis/incremental_run_slot.rb +173 -0
- data/lib/rigor/analysis/incremental_session.rb +287 -50
- data/lib/rigor/analysis/plugin_fact_fingerprint.rb +24 -13
- data/lib/rigor/analysis/reachability/graph.rb +123 -23
- data/lib/rigor/analysis/reachability/scan.rb +290 -36
- data/lib/rigor/analysis/reachability/scan_cache.rb +2 -1
- data/lib/rigor/analysis/rule_catalog.rb +43 -0
- data/lib/rigor/analysis/run_cache_key.rb +43 -9
- data/lib/rigor/analysis/run_stats.rb +2 -2
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +88 -6
- data/lib/rigor/analysis/runner/pool_coordinator.rb +52 -13
- data/lib/rigor/analysis/runner/project_pre_passes.rb +21 -13
- data/lib/rigor/analysis/runner/run_snapshots.rb +6 -1
- data/lib/rigor/analysis/runner.rb +371 -49
- data/lib/rigor/analysis/shadow_harness.rb +27 -0
- data/lib/rigor/analysis/source_rbs_gate.rb +157 -0
- data/lib/rigor/analysis/template_unit_paths.rb +6 -4
- data/lib/rigor/analysis/template_units.rb +15 -5
- data/lib/rigor/analysis/worker_session.rb +11 -7
- data/lib/rigor/cache/descriptor.rb +40 -1
- data/lib/rigor/cache/file_digest.rb +28 -0
- data/lib/rigor/cache/incremental_snapshot.rb +92 -8
- data/lib/rigor/cache/store.rb +63 -3
- data/lib/rigor/cache/value_digest.rb +325 -0
- data/lib/rigor/cli/annotate_command.rb +5 -0
- data/lib/rigor/cli/baseline_command.rb +7 -18
- data/lib/rigor/cli/check_command.rb +85 -14
- data/lib/rigor/cli/doctor_command.rb +1 -1
- data/lib/rigor/cli/effects_report.rb +2 -2
- data/lib/rigor/cli/trace_command.rb +5 -0
- data/lib/rigor/cli/type_of_command.rb +5 -3
- data/lib/rigor/cli/unused_command.rb +16 -10
- data/lib/rigor/cli.rb +11 -3
- data/lib/rigor/config_audit.rb +3 -2
- data/lib/rigor/config_path.rb +29 -0
- data/lib/rigor/configuration/severity_profile.rb +11 -0
- data/lib/rigor/configuration.rb +52 -7
- data/lib/rigor/effects/plugin_facts.rb +6 -6
- data/lib/rigor/environment/bundle_sig_discovery.rb +5 -3
- data/lib/rigor/environment/gated_signature_guard.rb +43 -0
- data/lib/rigor/environment/gated_signature_plan.rb +339 -0
- data/lib/rigor/environment/lockfile_resolver.rb +10 -1
- data/lib/rigor/environment/rbs_collection_discovery.rb +10 -1
- data/lib/rigor/environment/rbs_coverage_report.rb +1 -1
- data/lib/rigor/environment/rbs_loader.rb +284 -15
- data/lib/rigor/environment/required_features.rb +206 -0
- data/lib/rigor/environment/source_rbs_synthesis.rb +147 -0
- data/lib/rigor/environment.rb +34 -73
- data/lib/rigor/inference/acceptance.rb +28 -3
- data/lib/rigor/inference/block_parameter_binder.rb +29 -13
- data/lib/rigor/inference/builtins/cruby_definers.rb +61 -0
- data/lib/rigor/inference/builtins/method_catalog.rb +3 -0
- data/lib/rigor/inference/captured_locals.rb +7 -1
- data/lib/rigor/inference/declaration_walk/context.rb +195 -0
- data/lib/rigor/inference/declaration_walk/errors.rb +18 -0
- data/lib/rigor/inference/declaration_walk/shadow.rb +147 -0
- data/lib/rigor/inference/declaration_walk/traversal.rb +441 -0
- data/lib/rigor/inference/declaration_walk.rb +7 -0
- data/lib/rigor/inference/def_node_resolver.rb +26 -3
- data/lib/rigor/inference/definer_resolution.rb +266 -0
- data/lib/rigor/inference/expression_typer.rb +351 -61
- data/lib/rigor/inference/external_ancestor_resolution.rb +13 -16
- data/lib/rigor/inference/global_write_census.rb +7 -4
- data/lib/rigor/inference/guard_rebinding.rb +54 -13
- data/lib/rigor/inference/in_effect_refinements/proc_literals.rb +83 -0
- data/lib/rigor/inference/in_effect_refinements/refine_defs.rb +54 -0
- data/lib/rigor/inference/in_effect_refinements/scope_reads.rb +282 -0
- data/lib/rigor/inference/in_effect_refinements/walk.rb +276 -0
- data/lib/rigor/inference/in_effect_refinements.rb +256 -0
- data/lib/rigor/inference/key_presence_guard/scan.rb +281 -0
- data/lib/rigor/inference/key_presence_guard.rb +303 -0
- data/lib/rigor/inference/macro_block_self_type.rb +73 -14
- data/lib/rigor/inference/method_dispatcher/alias_strict_nominals.rb +36 -0
- data/lib/rigor/inference/method_dispatcher/arithmetic_sequence_elements.rb +73 -0
- data/lib/rigor/inference/method_dispatcher/imprecise_argument.rb +68 -0
- data/lib/rigor/inference/method_dispatcher/integer_step_block_params.rb +81 -0
- data/lib/rigor/inference/method_dispatcher/iterator_dispatch.rb +6 -0
- data/lib/rigor/inference/method_dispatcher/keyword_arguments.rb +267 -0
- data/lib/rigor/inference/method_dispatcher/method_folding.rb +2 -1
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +122 -105
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +305 -54
- data/lib/rigor/inference/method_dispatcher/splat_arity.rb +71 -0
- data/lib/rigor/inference/method_dispatcher.rb +44 -11
- data/lib/rigor/inference/module_function_state.rb +214 -0
- data/lib/rigor/inference/multi_target_binder.rb +21 -16
- data/lib/rigor/inference/narrowing.rb +166 -22
- data/lib/rigor/inference/object_mixins.rb +180 -0
- data/lib/rigor/inference/parameter_inference_collector.rb +10 -9
- data/lib/rigor/inference/project_patched_methods.rb +10 -5
- data/lib/rigor/inference/project_patched_scanner.rb +71 -3
- data/lib/rigor/inference/refine_census.rb +239 -0
- data/lib/rigor/inference/refine_self.rb +317 -0
- data/lib/rigor/inference/refined_dispatch/own_method.rb +403 -0
- data/lib/rigor/inference/refined_dispatch.rb +272 -0
- data/lib/rigor/inference/scope_indexer/certainty.rb +176 -0
- data/lib/rigor/inference/scope_indexer/class_cvars_collector.rb +35 -0
- data/lib/rigor/inference/scope_indexer/def_nestings_collector.rb +47 -0
- data/lib/rigor/inference/scope_indexer/layered_def_nestings.rb +36 -0
- data/lib/rigor/inference/scope_indexer/member_layouts_collector.rb +61 -0
- data/lib/rigor/inference/scope_indexer/mixin_accumulator.rb +143 -0
- data/lib/rigor/inference/scope_indexer/superclasses_collector.rb +64 -0
- data/lib/rigor/inference/scope_indexer.rb +2129 -354
- data/lib/rigor/inference/singleton_hook_decline.rb +253 -0
- data/lib/rigor/inference/statement_evaluator.rb +149 -32
- data/lib/rigor/inference/string_mutation.rb +9 -3
- data/lib/rigor/inference/synthetic_method_scanner.rb +2 -1
- data/lib/rigor/inference/version_guard.rb +19 -10
- data/lib/rigor/language_server/project_context.rb +31 -0
- data/lib/rigor/language_server/server.rb +18 -0
- data/lib/rigor/plugin/base.rb +28 -8
- data/lib/rigor/plugin/inflector.rb +1 -1
- data/lib/rigor/plugin/io_boundary.rb +124 -7
- data/lib/rigor/plugin/isolation.rb +1 -1
- data/lib/rigor/plugin/macro/block_as_method.rb +51 -8
- data/lib/rigor/plugin/trust_policy.rb +3 -3
- data/lib/rigor/project_environment.rb +29 -6
- data/lib/rigor/protection/discovery_seed.rb +18 -9
- data/lib/rigor/protection/mutation_cache.rb +4 -4
- data/lib/rigor/protection/mutator.rb +1 -1
- data/lib/rigor/reflection/constant_ancestors.rb +211 -46
- data/lib/rigor/reflection/constant_path.rb +33 -7
- data/lib/rigor/reflection.rb +41 -10
- data/lib/rigor/scope/discovery_index.rb +258 -3
- data/lib/rigor/scope/resolution_chain/relevance.rb +165 -0
- data/lib/rigor/scope/resolution_chain.rb +1032 -0
- data/lib/rigor/scope.rb +480 -328
- data/lib/rigor/sig_gen/alias_index.rb +1 -1
- data/lib/rigor/sig_gen/classification.rb +4 -1
- data/lib/rigor/sig_gen/effect_annotation.rb +2 -2
- data/lib/rigor/sig_gen/generator.rb +77 -21
- data/lib/rigor/sig_gen/method_candidate.rb +2 -2
- data/lib/rigor/sig_gen/skip_reason_catalog.rb +12 -0
- data/lib/rigor/source/alias_names.rb +52 -0
- data/lib/rigor/source/literals.rb +3 -2
- data/lib/rigor/source/symbol_name.rb +20 -0
- data/lib/rigor/type/combinator.rb +59 -3
- data/lib/rigor/type/float_range.rb +4 -1
- data/lib/rigor/type/nominal.rb +6 -1
- data/lib/rigor/version.rb +1 -1
- data/plugins/rigor-ac-library-rb/lib/rigor/plugin/ac_library_rb.rb +28 -0
- data/plugins/rigor-ac-library-rb/lib/rigor-ac-library-rb.rb +3 -0
- data/plugins/rigor-ac-library-rb/sig/ac_library_rb/convolution.rbs +7 -0
- data/plugins/rigor-ac-library-rb/sig/ac_library_rb/data_structures.rbs +160 -0
- data/plugins/rigor-ac-library-rb/sig/ac_library_rb/graph.rbs +94 -0
- data/plugins/rigor-ac-library-rb/sig/ac_library_rb/math.rbs +42 -0
- data/plugins/rigor-ac-library-rb/sig/ac_library_rb/modint.rbs +71 -0
- data/plugins/rigor-ac-library-rb/sig/ac_library_rb/object.rbs +37 -0
- data/plugins/rigor-ac-library-rb/sig/ac_library_rb/segtree.rbs +83 -0
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb +2 -1
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/association_roots.rb +100 -0
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +94 -10
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +43 -2
- data/plugins/rigor-activerecord/sig/active_record/relation.rbs +3 -1
- data/plugins/rigor-alba/lib/rigor/plugin/alba/resource_collector.rb +149 -0
- data/plugins/rigor-alba/lib/rigor/plugin/alba/resource_discoverer.rb +74 -0
- data/plugins/rigor-alba/lib/rigor/plugin/alba/resource_index.rb +104 -0
- data/plugins/rigor-alba/lib/rigor/plugin/alba.rb +85 -0
- data/plugins/rigor-alba/lib/rigor-alba.rb +3 -0
- data/plugins/rigor-alba/sig/alba.rbs +4 -0
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi/analyzer.rb +2 -2
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi/target_detector.rb +29 -12
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi.rb +13 -2
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest/assertion_analyzer.rb +130 -21
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest.rb +6 -4
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/analyzer.rb +4 -4
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/analyzer.rb +1 -1
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/routes_parser.rb +1 -1
- data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb +31 -0
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer/serializer_collector.rb +102 -0
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer/serializer_discoverer.rb +87 -0
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer/serializer_index.rb +76 -0
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer.rb +73 -0
- data/plugins/rigor-typelizer/lib/rigor-typelizer.rb +3 -0
- data/sig/rigor/analysis/dependency_source_inference/index.rbs +1 -1
- data/sig/rigor/environment.rbs +2 -0
- data/sig/rigor/plugin/io_boundary.rbs +4 -0
- data/sig/rigor/scope.rbs +69 -4
- data/sig/rigor/source.rbs +4 -0
- data/sig/rigor.rbs +3 -1
- data/skills/rigor-project-init/SKILL.md +37 -11
- data/skills/rigor-project-init/references/02-configure.md +7 -2
- metadata +90 -1
|
@@ -95,12 +95,12 @@ module Rigor
|
|
|
95
95
|
# with any of the signature path prefixes (after expansion to absolute paths); `bundled` is the
|
|
96
96
|
# remainder.
|
|
97
97
|
def self.partition_classes(class_decl_paths:, signature_paths:)
|
|
98
|
-
prefixes = Array(signature_paths).map { |p| File.
|
|
98
|
+
prefixes = Array(signature_paths).map { |p| File.absolute_path(p.to_s) }
|
|
99
99
|
return [0, class_decl_paths.size] if prefixes.empty?
|
|
100
100
|
|
|
101
101
|
project = 0
|
|
102
102
|
class_decl_paths.each_value do |path|
|
|
103
|
-
expanded = File.
|
|
103
|
+
expanded = File.absolute_path(path)
|
|
104
104
|
project += 1 if prefixes.any? { |prefix| expanded.start_with?("#{prefix}/") || expanded == prefix }
|
|
105
105
|
end
|
|
106
106
|
[project, class_decl_paths.size - project]
|
|
@@ -36,6 +36,8 @@ module Rigor
|
|
|
36
36
|
# that stood down against a colliding generic arity (#610), as
|
|
37
37
|
# `[path, class_name, existing_arity, incoming_arity, existing_file]` tuples. Defaults to none so
|
|
38
38
|
# a caller that snapshots nothing of the kind need not say so.
|
|
39
|
+
# @param vendored_standdowns_snapshot — issue #1713 — reader returning what each required-feature-gated
|
|
40
|
+
# vendored directory left out (`Environment::RbsLoader#vendored_standdowns`). Defaults to none.
|
|
39
41
|
# @param env_build_failure_snapshot — reader returning the total RBS env-build failure tuple
|
|
40
42
|
# (`[error_class, first_error_line, conflicting_buffer_names]`) or nil when the env built.
|
|
41
43
|
# @param definition_build_failures_snapshot — issue #696 — reader returning the per-class
|
|
@@ -55,7 +57,7 @@ module Rigor
|
|
|
55
57
|
quarantined_signatures_snapshot:, env_build_failure_snapshot:,
|
|
56
58
|
definition_build_failures_snapshot:, hkt_scan_failure_snapshot:,
|
|
57
59
|
conformance_results_snapshot:, signature_standdowns_snapshot: -> { [] },
|
|
58
|
-
pooled_run_disclosures: -> { [] })
|
|
60
|
+
vendored_standdowns_snapshot: -> { [] }, pooled_run_disclosures: -> { [] })
|
|
59
61
|
@configuration = configuration
|
|
60
62
|
@rbs_extended_reporter = rbs_extended_reporter
|
|
61
63
|
@boundary_cross_reporter = boundary_cross_reporter
|
|
@@ -68,6 +70,7 @@ module Rigor
|
|
|
68
70
|
@synthesized_namespaces_snapshot_reader = synthesized_namespaces_snapshot
|
|
69
71
|
@quarantined_signatures_snapshot_reader = quarantined_signatures_snapshot
|
|
70
72
|
@signature_standdowns_snapshot_reader = signature_standdowns_snapshot
|
|
73
|
+
@vendored_standdowns_snapshot_reader = vendored_standdowns_snapshot
|
|
71
74
|
@env_build_failure_snapshot_reader = env_build_failure_snapshot
|
|
72
75
|
@definition_build_failures_snapshot_reader = definition_build_failures_snapshot
|
|
73
76
|
@hkt_scan_failure_snapshot_reader = hkt_scan_failure_snapshot
|
|
@@ -437,11 +440,23 @@ module Rigor
|
|
|
437
440
|
standdowns.map { |entry| build_rbs_plugin_signature_stood_down_diagnostic(entry) }
|
|
438
441
|
end
|
|
439
442
|
|
|
440
|
-
#
|
|
441
|
-
#
|
|
442
|
-
#
|
|
443
|
+
# Issue #1713 — the other outcome that avoided a definition-build failure: a required-feature-gated
|
|
444
|
+
# vendored directory (`data/vendored_gem_sigs/prime/`) left out what another signature source already
|
|
445
|
+
# declares — a member, a whole type, or, when nothing narrower built, the directory. One `:info` per
|
|
446
|
+
# directory, naming the declarations that stood down and the files that displaced them.
|
|
447
|
+
def rbs_vendored_signature_stood_down_diagnostics
|
|
448
|
+
standdowns = vendored_standdowns_snapshot
|
|
449
|
+
return [] if standdowns.nil? || standdowns.empty?
|
|
450
|
+
|
|
451
|
+
standdowns.map { |entry| build_rbs_vendored_signature_stood_down_diagnostic(entry) }
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
# The `:info` notices that close the `rbs.coverage.*` ladder, in this order: the namespace synthesis
|
|
455
|
+
# first, then the stand-downs (#610, #1713) — the outcomes that AVOIDED a definition-build failure and so
|
|
456
|
+
# the quietest rows on it. One method so the runner's assembly reads them as one slot.
|
|
443
457
|
def rbs_coverage_notice_diagnostics
|
|
444
|
-
rbs_synthesized_namespace_diagnostics + rbs_plugin_signature_stood_down_diagnostics
|
|
458
|
+
rbs_synthesized_namespace_diagnostics + rbs_plugin_signature_stood_down_diagnostics +
|
|
459
|
+
rbs_vendored_signature_stood_down_diagnostics
|
|
445
460
|
end
|
|
446
461
|
|
|
447
462
|
# Maps the per-run `rigor:v1:conforms-to` scan results into diagnostics (spec: `rbs-extended.md` §
|
|
@@ -769,6 +784,69 @@ module Rigor
|
|
|
769
784
|
)
|
|
770
785
|
end
|
|
771
786
|
|
|
787
|
+
def build_rbs_vendored_signature_stood_down_diagnostic(entry)
|
|
788
|
+
dir, declarations, whole = entry
|
|
789
|
+
Diagnostic.new(
|
|
790
|
+
path: ".rigor.yml",
|
|
791
|
+
line: 1,
|
|
792
|
+
column: 1,
|
|
793
|
+
message: vendored_standdown_message(dir, declarations, whole),
|
|
794
|
+
severity: :info,
|
|
795
|
+
rule: "rbs.coverage.vendored-signature-stood-down",
|
|
796
|
+
source_family: :builtin
|
|
797
|
+
)
|
|
798
|
+
end
|
|
799
|
+
|
|
800
|
+
def vendored_standdown_message(dir, declarations, whole)
|
|
801
|
+
subject = "Rigor's vendored `#{dir}` signatures (loaded because the project requires `#{dir}` or lists " \
|
|
802
|
+
"it under `libraries:`)"
|
|
803
|
+
return vendored_whole_standdown_message(subject, dir, declarations) if whole
|
|
804
|
+
|
|
805
|
+
vendored_partial_standdown_message(subject, declarations)
|
|
806
|
+
end
|
|
807
|
+
|
|
808
|
+
# One sentence per kind of stand-down present ({Environment::GatedSignaturePlan.standdowns}' reasons).
|
|
809
|
+
VENDORED_STANDDOWN_SENTENCES = {
|
|
810
|
+
"member" => "left out %<count>d method declaration(s) another signature source also makes, since two " \
|
|
811
|
+
"declarations of one method fail the class's definition build, and uses the other " \
|
|
812
|
+
"source's: %<list>s.",
|
|
813
|
+
"type" => "stood %<count>d type(s) down whole, keeping only the types nested in them, because another " \
|
|
814
|
+
"source declares each with a different kind (class or module) or generic arity, or the type " \
|
|
815
|
+
"failed to build beside that source's declaration: %<list>s.",
|
|
816
|
+
"open" => "kept %<count>d type(s) without their superclass, because each failed to build beside the " \
|
|
817
|
+
"other signatures although no other source declares it; calls they no longer answer read " \
|
|
818
|
+
"untyped rather than undefined: %<list>s."
|
|
819
|
+
}.freeze
|
|
820
|
+
private_constant :VENDORED_STANDDOWN_SENTENCES
|
|
821
|
+
|
|
822
|
+
def vendored_partial_standdown_message(subject, declarations)
|
|
823
|
+
sentences = VENDORED_STANDDOWN_SENTENCES.filter_map do |reason, template|
|
|
824
|
+
group = declarations.select { |entry| (entry[2] || "member") == reason }
|
|
825
|
+
next if group.empty?
|
|
826
|
+
|
|
827
|
+
format(template, count: group.size, list: sampled(vendored_standdown_labels(group), 5))
|
|
828
|
+
end
|
|
829
|
+
"#{subject} loaded without some of their declarations. Rigor #{sentences.join(' Rigor ')} The rest of the " \
|
|
830
|
+
"vendored signatures still load. Nothing to fix unless the other declaration is an outdated copy; " \
|
|
831
|
+
"removing it brings the vendored one back."
|
|
832
|
+
end
|
|
833
|
+
|
|
834
|
+
def vendored_whole_standdown_message(subject, dir, declarations)
|
|
835
|
+
labels = vendored_standdown_labels(declarations)
|
|
836
|
+
clashes = labels.empty? ? "" : " Declarations it clashed with: #{sampled(labels, 5)}."
|
|
837
|
+
"#{subject} stood down " \
|
|
838
|
+
"entirely: a type they declare failed to build beside the other signature sources even with the " \
|
|
839
|
+
"clashing declarations left out, so calls into `#{dir}`'s API resolve only against what those " \
|
|
840
|
+
"sources declare.#{clashes}"
|
|
841
|
+
end
|
|
842
|
+
|
|
843
|
+
def vendored_standdown_labels(declarations)
|
|
844
|
+
declarations.map do |declaration, cause_file|
|
|
845
|
+
cause = cause_file.nil? ? "" : " (#{relative_signature_path(cause_file.to_s)})"
|
|
846
|
+
"`#{declaration}`#{cause}"
|
|
847
|
+
end
|
|
848
|
+
end
|
|
849
|
+
|
|
772
850
|
def displacing_source_phrase(existing_file)
|
|
773
851
|
return "another loaded signature source" if existing_file.nil?
|
|
774
852
|
|
|
@@ -965,7 +1043,7 @@ module Rigor
|
|
|
965
1043
|
|
|
966
1044
|
# Issue #959 — surfaces the {Plugin::IoBoundary} refusal history each loaded plugin accumulated over
|
|
967
1045
|
# the whole run (prepare AND every per-file call: `#io_boundary` is memoised per plugin instance, so
|
|
968
|
-
# one boundary sees both). `TrustPolicy#allow_read?` stays `File.
|
|
1046
|
+
# one boundary sees both). `TrustPolicy#allow_read?` stays `File.absolute_path`-only per ADR-2 — a
|
|
969
1047
|
# project rooted under a symlink (macOS' `/tmp` → `/private/tmp` is the common case) can have every
|
|
970
1048
|
# plugin read fall outside its own read roots with nothing said about it. One `:info` row per plugin
|
|
971
1049
|
# that hit this, never one per path, naming the count and the first path so the row stays legible on
|
|
@@ -1196,6 +1274,10 @@ module Rigor
|
|
|
1196
1274
|
@signature_standdowns_snapshot_reader.call
|
|
1197
1275
|
end
|
|
1198
1276
|
|
|
1277
|
+
def vendored_standdowns_snapshot
|
|
1278
|
+
@vendored_standdowns_snapshot_reader.call
|
|
1279
|
+
end
|
|
1280
|
+
|
|
1199
1281
|
def env_build_failure_snapshot
|
|
1200
1282
|
@env_build_failure_snapshot_reader.call
|
|
1201
1283
|
end
|
|
@@ -45,7 +45,8 @@ module Rigor
|
|
|
45
45
|
snapshots:, plugin_registry:, dependency_source_index:,
|
|
46
46
|
synthetic_method_index:, project_patched_methods:,
|
|
47
47
|
analyze_file:, project_scope_seed: -> { {} }, record_dependencies: false,
|
|
48
|
-
restored_run_level_rows: nil, template_units: -> { TemplateUnits.empty }
|
|
48
|
+
restored_run_level_rows: nil, template_units: -> { TemplateUnits.empty },
|
|
49
|
+
feature_sources: -> { {} })
|
|
49
50
|
@configuration = configuration
|
|
50
51
|
@cache_store = cache_store
|
|
51
52
|
@explain = explain
|
|
@@ -67,6 +68,7 @@ module Rigor
|
|
|
67
68
|
@collected_run_disclosures = {}
|
|
68
69
|
@collect_stats = collect_stats
|
|
69
70
|
@buffer = buffer
|
|
71
|
+
@feature_sources = feature_sources
|
|
70
72
|
@environment_override = environment_override
|
|
71
73
|
@rbs_extended_reporter = rbs_extended_reporter
|
|
72
74
|
@boundary_cross_reporter = boundary_cross_reporter
|
|
@@ -208,7 +210,7 @@ module Rigor
|
|
|
208
210
|
|
|
209
211
|
env = resolve_sequential_environment(source_files: project_files)
|
|
210
212
|
end
|
|
211
|
-
snapshot_project_signature_state(signature_state_environment(resolve))
|
|
213
|
+
snapshot_project_signature_state(signature_state_environment(resolve, project_files))
|
|
212
214
|
snapshot_effect_annotation_carrier(
|
|
213
215
|
annotation_carrier_environment(resolve, in_hand: !env.nil?)&.rbs_loader
|
|
214
216
|
)
|
|
@@ -220,11 +222,21 @@ module Rigor
|
|
|
220
222
|
record_hkt_scan_failure(hkt_scan_outcome(resolve.call))
|
|
221
223
|
end
|
|
222
224
|
|
|
223
|
-
# Issue #794 — the signature-state snapshot's own gates, asked BEFORE an environment exists.
|
|
224
|
-
#
|
|
225
|
-
# {#snapshot_project_signature_state} writes the same empty state a nil
|
|
226
|
-
|
|
227
|
-
|
|
225
|
+
# Issue #794 — the signature-state snapshot's own gates, asked BEFORE an environment exists. Every
|
|
226
|
+
# answer is loader-free (the configuration, the plugin registry and, issue #1713, the required-feature
|
|
227
|
+
# scan), and with no gate open {#snapshot_project_signature_state} writes the same empty state a nil
|
|
228
|
+
# environment gives it.
|
|
229
|
+
def signature_state_environment(resolve, project_files)
|
|
230
|
+
gated = plugin_signature_paths? || project_signature_paths? || vendored_features_requested?(project_files)
|
|
231
|
+
gated ? resolve.call : nil
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# Issue #1713 — whether this run activates a required-feature-gated vendored directory, whose stand-down
|
|
235
|
+
# {#snapshot_project_signature_state} reports: the scan every build of this run gates on, or the
|
|
236
|
+
# feature named under `libraries:`.
|
|
237
|
+
def vendored_features_requested?(project_files)
|
|
238
|
+
features = project_files.nil? || project_files.empty? ? [] : required_features_for(project_files)
|
|
239
|
+
!Environment::RequiredFeatures.tokens(features, @configuration.libraries).empty?
|
|
228
240
|
end
|
|
229
241
|
|
|
230
242
|
# Issue #794 — the same, for the #441 carrier. The carrier is a filter over the loader's
|
|
@@ -287,10 +299,10 @@ module Rigor
|
|
|
287
299
|
buffers = failure.is_a?(Array) ? failure[3] : nil
|
|
288
300
|
return false if buffers.nil?
|
|
289
301
|
|
|
290
|
-
closure_paths = closure.to_set { |path| File.
|
|
302
|
+
closure_paths = closure.to_set { |path| File.absolute_path(path.to_s) }
|
|
291
303
|
Array(buffers).any? do |name|
|
|
292
304
|
path = virtual_buffer_path(name)
|
|
293
|
-
!path.nil? && closure_paths.include?(File.
|
|
305
|
+
!path.nil? && closure_paths.include?(File.absolute_path(path))
|
|
294
306
|
end
|
|
295
307
|
end
|
|
296
308
|
|
|
@@ -344,6 +356,10 @@ module Rigor
|
|
|
344
356
|
# no such plugin reads nothing off its loader here, as before.
|
|
345
357
|
@snapshots.signature_standdowns =
|
|
346
358
|
plugin_signature_paths? ? signature_standdowns_for(environment&.rbs_loader) : []
|
|
359
|
+
# Issue #1713 — NOT behind the `signature_paths:` gate either: what displaces a vendored declaration may
|
|
360
|
+
# be a gem's or a collection's copy. The loader answers without building its env when no gated
|
|
361
|
+
# directory is active.
|
|
362
|
+
@snapshots.vendored_standdowns = vendored_standdowns_for(environment&.rbs_loader)
|
|
347
363
|
unless project_signature_paths?
|
|
348
364
|
@snapshots.synthesized_namespaces = []
|
|
349
365
|
@snapshots.quarantined_signatures = []
|
|
@@ -459,7 +475,22 @@ module Rigor
|
|
|
459
475
|
**ProjectEnvironment.dependency_discovery_options(@configuration),
|
|
460
476
|
synthetic_method_index: synthetic_method_index,
|
|
461
477
|
project_patched_methods: project_patched_methods,
|
|
462
|
-
source_files: source_files
|
|
478
|
+
source_files: source_files,
|
|
479
|
+
required_features: required_features_for(source_files)
|
|
480
|
+
)
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
# Issue #1700 — the {Environment::RequiredFeatures} this run's environments gate on: the configured paths
|
|
484
|
+
# plus `source_files`, whichever files the run checks, with an editor buffer or an in-memory source read
|
|
485
|
+
# in place of its file. Taken once per file list and handed to every build (the sequential one, the
|
|
486
|
+
# pool's prewarm and each worker), so they agree and a pool does not re-read the project per worker.
|
|
487
|
+
def required_features_for(source_files)
|
|
488
|
+
key = source_files.map(&:to_s)
|
|
489
|
+
return @required_features if @required_features_key == key
|
|
490
|
+
|
|
491
|
+
@required_features_key = key
|
|
492
|
+
@required_features = Ractor.make_shareable(
|
|
493
|
+
Environment::RequiredFeatures.for_configuration(@configuration, key, sources: @feature_sources.call)
|
|
463
494
|
)
|
|
464
495
|
end
|
|
465
496
|
|
|
@@ -575,9 +606,10 @@ module Rigor
|
|
|
575
606
|
# a frozen Array<String>; cheaply shareable. Issue #793 — it IS the full project now
|
|
576
607
|
# (`source_files`), not the analyzed subset this comment always described.
|
|
577
608
|
shareable_source_files = source_files.map { |path| path.to_s.dup.freeze }.freeze
|
|
609
|
+
features = required_features_for(source_files)
|
|
578
610
|
|
|
579
611
|
pool = Array.new(@workers) do
|
|
580
|
-
Ractor.new(configuration, cache_root, blueprints, explain, shareable_source_files, locked_gems) do |configuration, cache_root, blueprints, explain, shareable_source_files, locked_gems| # rubocop:disable Layout/LineLength
|
|
612
|
+
Ractor.new(configuration, cache_root, blueprints, explain, shareable_source_files, locked_gems, features) do |configuration, cache_root, blueprints, explain, shareable_source_files, locked_gems, features| # rubocop:disable Layout/LineLength
|
|
581
613
|
cache_store = cache_root ? Rigor::Cache::Store.new(root: cache_root) : nil
|
|
582
614
|
session = Rigor::Analysis::WorkerSession.new(
|
|
583
615
|
configuration: configuration,
|
|
@@ -585,7 +617,8 @@ module Rigor
|
|
|
585
617
|
plugin_blueprints: blueprints,
|
|
586
618
|
explain: explain,
|
|
587
619
|
source_files: shareable_source_files,
|
|
588
|
-
locked_gems: locked_gems
|
|
620
|
+
locked_gems: locked_gems,
|
|
621
|
+
required_features: features
|
|
589
622
|
)
|
|
590
623
|
main = Ractor.main
|
|
591
624
|
main.send([:prepare, session.prepare_diagnostics])
|
|
@@ -713,7 +746,8 @@ module Rigor
|
|
|
713
746
|
project_scope_seed: project_scope_seed,
|
|
714
747
|
source_files: source_files,
|
|
715
748
|
record_dependencies: @record_dependencies,
|
|
716
|
-
template_units: template_units
|
|
749
|
+
template_units: template_units,
|
|
750
|
+
required_features: required_features_for(source_files)
|
|
717
751
|
)
|
|
718
752
|
# Force the full RBS load on the parent so children copy-on-write inherit a warm Environment
|
|
719
753
|
# rather than each rebuilding it after the fork.
|
|
@@ -890,6 +924,7 @@ module Rigor
|
|
|
890
924
|
plugin_registry: plugin_registry,
|
|
891
925
|
source_files: source_files,
|
|
892
926
|
locked_gems: locked_gems,
|
|
927
|
+
required_features: required_features_for(source_files),
|
|
893
928
|
**ProjectEnvironment.dependency_discovery_options(@configuration)
|
|
894
929
|
)
|
|
895
930
|
warm_env.rbs_loader&.prewarm
|
|
@@ -1094,6 +1129,10 @@ module Rigor
|
|
|
1094
1129
|
loader.signature_standdowns
|
|
1095
1130
|
end
|
|
1096
1131
|
|
|
1132
|
+
def vendored_standdowns_for(loader)
|
|
1133
|
+
loader.respond_to?(:vendored_standdowns) ? loader.vendored_standdowns : []
|
|
1134
|
+
end
|
|
1135
|
+
|
|
1097
1136
|
def plugin_registry
|
|
1098
1137
|
@plugin_registry_reader.call
|
|
1099
1138
|
end
|
|
@@ -23,7 +23,7 @@ module Rigor
|
|
|
23
23
|
# ivar surface, preserving the exact assignment order and timing the inline body had. The `pool_mode`
|
|
24
24
|
# predicate is injected (it keys on `@workers` / `@buffer`, owned by the Runner) so this collaborator
|
|
25
25
|
# never calls back into it.
|
|
26
|
-
class ProjectPrePasses
|
|
26
|
+
class ProjectPrePasses # rubocop:disable Metrics/ClassLength -- the Discovery slots are one declaration per table
|
|
27
27
|
# Frozen bundle of the EAGER (env-input) project-wide state the pre-passes produce — the slots whose
|
|
28
28
|
# products feed the RBS environment build. Mirrors the env-input ivars `apply_pre_passes_result`
|
|
29
29
|
# sets on the {Runner}. The cross-file discovery tables live in the separate {Discovery} bundle
|
|
@@ -53,12 +53,13 @@ module Rigor
|
|
|
53
53
|
# consumes them and so never pays the double parse (see {#discover} + `Runner#ensure_project_discovery`).
|
|
54
54
|
# The slot names mirror the discovery half of {Result} exactly.
|
|
55
55
|
Discovery = Data.define(
|
|
56
|
-
:discovered_classes, :discovered_def_nodes, :discovered_def_nestings,
|
|
57
|
-
:
|
|
58
|
-
:
|
|
59
|
-
:
|
|
56
|
+
:discovered_classes, :discovered_def_nodes, :discovered_def_nestings, :discovered_singleton_def_nodes,
|
|
57
|
+
:discovered_def_sources, :discovered_singleton_def_sources, :discovered_superclasses,
|
|
58
|
+
:discovered_header_nestings, :discovered_includes, :discovered_prepends, :discovered_extends,
|
|
59
|
+
:unpositioned_mixins, :discovered_class_sources, :constant_values, :constant_sources, :constant_writes,
|
|
60
60
|
:discovered_method_visibilities, :discovered_methods, :discovered_parameter_envelopes, :data_member_layouts,
|
|
61
|
-
:struct_member_layouts, :discovered_deferred_ranges, :discovered_refinements, :
|
|
61
|
+
:struct_member_layouts, :discovered_deferred_ranges, :discovered_refinements, :siblings,
|
|
62
|
+
:discovered_global_write_census
|
|
62
63
|
)
|
|
63
64
|
|
|
64
65
|
# Internal: drives every EAGER project-wide pre-pass — the ones whose products feed the RBS
|
|
@@ -172,7 +173,7 @@ module Rigor
|
|
|
172
173
|
discovered_prepends: def_index.fetch(:prepends),
|
|
173
174
|
# Issue #898 — the singleton-side mixin table, kept beside the instance-side one so a class
|
|
174
175
|
# object's `extend`s reach `Narrowing` from a sibling file the way its `include`s already do.
|
|
175
|
-
discovered_extends: def_index.fetch(:extends),
|
|
176
|
+
discovered_extends: def_index.fetch(:extends), unpositioned_mixins: def_index.fetch(:unpositioned_mixins),
|
|
176
177
|
discovered_class_sources: def_index.fetch(:class_sources),
|
|
177
178
|
# Issue #644 — the cross-file value-constant publication table and its write attribution.
|
|
178
179
|
constant_values: def_index.fetch(:constant_values), constant_sources: def_index.fetch(:constant_sources),
|
|
@@ -186,7 +187,8 @@ module Rigor
|
|
|
186
187
|
# `*_def_shadows_call?` predicates order `sig`-shadowing defs against.
|
|
187
188
|
discovered_deferred_ranges: def_index.fetch(:deferred_ranges),
|
|
188
189
|
discovered_refinements: def_index.fetch(:refinements), # Issue #1120
|
|
189
|
-
|
|
190
|
+
# Issue #1367 — the census; ADR-119 WD1 — `{sibling name => table}` for `DiscoveryIndex::SIBLINGS`.
|
|
191
|
+
discovered_global_write_census: def_index.fetch(:global_write_census), siblings: def_index.fetch(:siblings)
|
|
190
192
|
)
|
|
191
193
|
end
|
|
192
194
|
|
|
@@ -233,13 +235,19 @@ module Rigor
|
|
|
233
235
|
# {Rigor::Plugin::Registry} WITHOUT the synthetic-method / dependency-source / pre-eval scanners. The
|
|
234
236
|
# incremental fact-surface fingerprint probe ({Analysis::PluginFactFingerprint}) uses this to read the
|
|
235
237
|
# ADR-9 fact store + drive the ADR-60 producers without paying for the full pre-pass or building the RBS
|
|
236
|
-
# environment. `prepare` runs
|
|
238
|
+
# environment. `prepare` runs whatever the pool mode — the probe is always sequential (its `pool_mode?`
|
|
237
239
|
# reader returns false), so the pool-mode skip in {#run} does not apply. Prepare diagnostics are
|
|
238
240
|
# discarded: a plugin that raises in `#prepare` publishes no facts, so its surface is simply absent from
|
|
239
241
|
# the fingerprint, exactly as it would be absent from analysis.
|
|
240
|
-
|
|
242
|
+
#
|
|
243
|
+
# Issue #1536 — `prepare: false` loads the plugins without running `#prepare`, for a caller that reads
|
|
244
|
+
# only what a manifest declares: the incremental session reads each plugin's `source_rbs_synthesizer`
|
|
245
|
+
# before its recheck runner exists. A synthesizer's output is a function of the file, the plugin's
|
|
246
|
+
# config and the engine — the key its `Cache::Store` entry already rests on — so `#prepare` has
|
|
247
|
+
# nothing to add to it, and skipping it keeps that read off every plugin's prepare-time scans.
|
|
248
|
+
def prepared_registry(prepare: true)
|
|
241
249
|
registry = load_plugins
|
|
242
|
-
plugin_prepare_diagnostics(registry)
|
|
250
|
+
plugin_prepare_diagnostics(registry) if prepare && !registry.empty?
|
|
243
251
|
registry
|
|
244
252
|
end
|
|
245
253
|
|
|
@@ -288,12 +296,12 @@ module Rigor
|
|
|
288
296
|
def build_trust_policy
|
|
289
297
|
trusted_gems = @configuration.plugins.map { |entry| trusted_gem_name(entry) }.uniq
|
|
290
298
|
roots = [Dir.pwd]
|
|
291
|
-
Array(@configuration.signature_paths).each { |sp| roots << File.
|
|
299
|
+
Array(@configuration.signature_paths).each { |sp| roots << File.absolute_path(sp) }
|
|
292
300
|
trusted_gems.each do |gem_name|
|
|
293
301
|
path = trusted_gem_root(gem_name)
|
|
294
302
|
roots << path if path
|
|
295
303
|
end
|
|
296
|
-
@configuration.plugins_io_allowed_paths.each { |p| roots << File.
|
|
304
|
+
@configuration.plugins_io_allowed_paths.each { |p| roots << File.absolute_path(p) }
|
|
297
305
|
|
|
298
306
|
Plugin::TrustPolicy.new(
|
|
299
307
|
trusted_gems: trusted_gems,
|
|
@@ -16,7 +16,8 @@ module Rigor
|
|
|
16
16
|
# back-reference cycle.
|
|
17
17
|
class RunSnapshots
|
|
18
18
|
attr_accessor :class_decl_paths, :signature_paths,
|
|
19
|
-
:synthesized_namespaces, :quarantined_signatures, :signature_standdowns, :
|
|
19
|
+
:synthesized_namespaces, :quarantined_signatures, :signature_standdowns, :vendored_standdowns,
|
|
20
|
+
:conformance_results,
|
|
20
21
|
:env_build_failure, :definition_build_failures, :hkt_scan_failure,
|
|
21
22
|
:effect_annotation_carrier
|
|
22
23
|
|
|
@@ -32,12 +33,15 @@ module Rigor
|
|
|
32
33
|
# `signature_standdowns` (#610) is the quarantine slot's twin for the plugin-contributed files that
|
|
33
34
|
# stood down against a colliding generic arity: a list, assigned once from the loader as
|
|
34
35
|
# `quarantined_signatures` is, and derived from the final env so a cache HIT carries it too.
|
|
36
|
+
# `vendored_standdowns` (#1713) is the same shape of slot for what a required-feature-gated vendored
|
|
37
|
+
# directory left out because another signature source declares it.
|
|
35
38
|
def initialize
|
|
36
39
|
@class_decl_paths = {}.freeze
|
|
37
40
|
@signature_paths = [].freeze
|
|
38
41
|
@synthesized_namespaces = [].freeze
|
|
39
42
|
@quarantined_signatures = [].freeze
|
|
40
43
|
@signature_standdowns = [].freeze
|
|
44
|
+
@vendored_standdowns = [].freeze
|
|
41
45
|
@conformance_results = [].freeze
|
|
42
46
|
@env_build_failure = nil
|
|
43
47
|
@definition_build_failures = [].freeze
|
|
@@ -53,6 +57,7 @@ module Rigor
|
|
|
53
57
|
@synthesized_namespaces = []
|
|
54
58
|
@quarantined_signatures = []
|
|
55
59
|
@signature_standdowns = []
|
|
60
|
+
@vendored_standdowns = []
|
|
56
61
|
@conformance_results = []
|
|
57
62
|
@env_build_failure = nil
|
|
58
63
|
@definition_build_failures = []
|