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.
Files changed (414) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/docs/manual/04-diagnostics.md +7 -4
  4. data/docs/manual/06-baseline.md +5 -2
  5. data/docs/manual/15-type-protection-coverage.md +6 -4
  6. data/lib/rigor/analysis/baseline.rb +56 -96
  7. data/lib/rigor/analysis/buffer_binding.rb +13 -20
  8. data/lib/rigor/analysis/check_rules/always_truthy_condition_collector.rb +29 -48
  9. data/lib/rigor/analysis/check_rules/dead_assignment_collector.rb +35 -54
  10. data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +23 -37
  11. data/lib/rigor/analysis/check_rules/main_pass_collector.rb +16 -23
  12. data/lib/rigor/analysis/check_rules/rule_walk.rb +48 -71
  13. data/lib/rigor/analysis/check_rules/self_closedness_scanner.rb +19 -28
  14. data/lib/rigor/analysis/check_rules/unreachable_clause_collector.rb +48 -67
  15. data/lib/rigor/analysis/check_rules.rb +174 -274
  16. data/lib/rigor/analysis/dependency_recorder.rb +26 -38
  17. data/lib/rigor/analysis/dependency_source_inference/boundary_cross_reporter.rb +13 -25
  18. data/lib/rigor/analysis/dependency_source_inference/builder.rb +17 -30
  19. data/lib/rigor/analysis/dependency_source_inference/gem_resolver.rb +15 -26
  20. data/lib/rigor/analysis/dependency_source_inference/index.rb +45 -76
  21. data/lib/rigor/analysis/dependency_source_inference/return_type_heuristic.rb +23 -40
  22. data/lib/rigor/analysis/dependency_source_inference/walker.rb +50 -83
  23. data/lib/rigor/analysis/dependency_source_inference.rb +6 -10
  24. data/lib/rigor/analysis/diagnostic.rb +48 -75
  25. data/lib/rigor/analysis/erb_template_detector.rb +13 -18
  26. data/lib/rigor/analysis/fact_store.rb +12 -22
  27. data/lib/rigor/analysis/incremental.rb +47 -63
  28. data/lib/rigor/analysis/incremental_session.rb +74 -100
  29. data/lib/rigor/analysis/project_scan.rb +12 -23
  30. data/lib/rigor/analysis/result.rb +3 -5
  31. data/lib/rigor/analysis/rule_catalog.rb +67 -95
  32. data/lib/rigor/analysis/run_stats.rb +38 -61
  33. data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +101 -160
  34. data/lib/rigor/analysis/runner/pool_coordinator.rb +121 -188
  35. data/lib/rigor/analysis/runner/project_pre_passes.rb +62 -96
  36. data/lib/rigor/analysis/runner/run_snapshots.rb +12 -18
  37. data/lib/rigor/analysis/runner.rb +220 -333
  38. data/lib/rigor/analysis/self_call_resolution_recorder.rb +30 -43
  39. data/lib/rigor/analysis/worker_session.rb +64 -102
  40. data/lib/rigor/ast/type_node.rb +6 -8
  41. data/lib/rigor/ast.rb +6 -10
  42. data/lib/rigor/bleeding_edge.rb +27 -35
  43. data/lib/rigor/builtins/hkt_builtins.rb +7 -14
  44. data/lib/rigor/builtins/imported_refinements.rb +106 -149
  45. data/lib/rigor/builtins/predefined_constant_refinements.rb +51 -65
  46. data/lib/rigor/builtins/regex_refinement.rb +32 -43
  47. data/lib/rigor/builtins/static_return_refinements.rb +57 -81
  48. data/lib/rigor/cache/descriptor.rb +58 -94
  49. data/lib/rigor/cache/incremental_snapshot.rb +32 -48
  50. data/lib/rigor/cache/rbs_cache_producer.rb +10 -15
  51. data/lib/rigor/cache/rbs_class_ancestor_table.rb +10 -16
  52. data/lib/rigor/cache/rbs_class_type_param_names.rb +10 -16
  53. data/lib/rigor/cache/rbs_constant_table.rb +8 -13
  54. data/lib/rigor/cache/rbs_descriptor.rb +8 -13
  55. data/lib/rigor/cache/rbs_environment.rb +11 -19
  56. data/lib/rigor/cache/rbs_environment_marshal_patch.rb +11 -19
  57. data/lib/rigor/cache/rbs_known_class_names.rb +8 -12
  58. data/lib/rigor/cache/store.rb +96 -151
  59. data/lib/rigor/cli/annotate_command.rb +51 -88
  60. data/lib/rigor/cli/baseline_command.rb +10 -17
  61. data/lib/rigor/cli/check_command.rb +121 -199
  62. data/lib/rigor/cli/check_runner_factory.rb +8 -14
  63. data/lib/rigor/cli/ci_detector.rb +9 -14
  64. data/lib/rigor/cli/command.rb +8 -14
  65. data/lib/rigor/cli/coverage_command.rb +19 -26
  66. data/lib/rigor/cli/coverage_mutation.rb +14 -19
  67. data/lib/rigor/cli/coverage_report.rb +0 -2
  68. data/lib/rigor/cli/coverage_scan.rb +7 -11
  69. data/lib/rigor/cli/diagnostic_formats.rb +43 -62
  70. data/lib/rigor/cli/diff_command.rb +10 -20
  71. data/lib/rigor/cli/docs_command.rb +26 -40
  72. data/lib/rigor/cli/doctor_command.rb +8 -9
  73. data/lib/rigor/cli/explain_command.rb +4 -7
  74. data/lib/rigor/cli/fused_protection_renderer.rb +4 -5
  75. data/lib/rigor/cli/fused_protection_report.rb +6 -8
  76. data/lib/rigor/cli/lsp_command.rb +11 -19
  77. data/lib/rigor/cli/mcp_command.rb +4 -6
  78. data/lib/rigor/cli/mutation_protection_renderer.rb +3 -4
  79. data/lib/rigor/cli/mutation_protection_report.rb +6 -9
  80. data/lib/rigor/cli/options.rb +11 -19
  81. data/lib/rigor/cli/plugin_command.rb +18 -30
  82. data/lib/rigor/cli/plugins_command.rb +29 -51
  83. data/lib/rigor/cli/plugins_renderer.rb +12 -20
  84. data/lib/rigor/cli/prism_colorizer.rb +13 -19
  85. data/lib/rigor/cli/protection_renderer.rb +5 -7
  86. data/lib/rigor/cli/protection_report.rb +27 -17
  87. data/lib/rigor/cli/renderable.rb +4 -6
  88. data/lib/rigor/cli/show_bleedingedge_command.rb +5 -8
  89. data/lib/rigor/cli/sig_gen_command.rb +14 -26
  90. data/lib/rigor/cli/skill_command.rb +30 -47
  91. data/lib/rigor/cli/skill_describe.rb +40 -64
  92. data/lib/rigor/cli/trace_command.rb +9 -16
  93. data/lib/rigor/cli/trace_renderer.rb +35 -51
  94. data/lib/rigor/cli/triage_command.rb +6 -10
  95. data/lib/rigor/cli/triage_renderer.rb +1 -2
  96. data/lib/rigor/cli/type_of_command.rb +14 -23
  97. data/lib/rigor/cli/type_of_renderer.rb +3 -5
  98. data/lib/rigor/cli/type_scan_command.rb +6 -10
  99. data/lib/rigor/cli/type_scan_renderer.rb +3 -5
  100. data/lib/rigor/cli/type_scan_report.rb +2 -3
  101. data/lib/rigor/cli/upgrade_command.rb +2 -3
  102. data/lib/rigor/cli.rb +16 -28
  103. data/lib/rigor/config_audit.rb +35 -44
  104. data/lib/rigor/configuration/dependencies.rb +41 -70
  105. data/lib/rigor/configuration/severity_profile.rb +28 -42
  106. data/lib/rigor/configuration.rb +150 -241
  107. data/lib/rigor/environment/bundle_sig_discovery.rb +74 -118
  108. data/lib/rigor/environment/class_registry.rb +19 -26
  109. data/lib/rigor/environment/constant_type_cache_holder.rb +14 -21
  110. data/lib/rigor/environment/hkt_registry_holder.rb +6 -12
  111. data/lib/rigor/environment/lockfile_resolver.rb +31 -47
  112. data/lib/rigor/environment/rbs_collection_discovery.rb +39 -63
  113. data/lib/rigor/environment/rbs_coverage_report.rb +24 -42
  114. data/lib/rigor/environment/rbs_loader.rb +420 -518
  115. data/lib/rigor/environment/reflection.rb +28 -53
  116. data/lib/rigor/environment/reporters.rb +13 -24
  117. data/lib/rigor/environment.rb +176 -291
  118. data/lib/rigor/flow_contribution/conflict.rb +16 -27
  119. data/lib/rigor/flow_contribution/element.rb +7 -12
  120. data/lib/rigor/flow_contribution/fact.rb +33 -57
  121. data/lib/rigor/flow_contribution/merge_result.rb +6 -9
  122. data/lib/rigor/flow_contribution/merger.rb +32 -47
  123. data/lib/rigor/flow_contribution.rb +37 -55
  124. data/lib/rigor/inference/acceptance.rb +133 -219
  125. data/lib/rigor/inference/block_parameter_binder.rb +52 -82
  126. data/lib/rigor/inference/body_fixpoint.rb +22 -30
  127. data/lib/rigor/inference/budget_trace.rb +43 -63
  128. data/lib/rigor/inference/builtins/array_catalog.rb +4 -6
  129. data/lib/rigor/inference/builtins/comparable_catalog.rb +4 -6
  130. data/lib/rigor/inference/builtins/complex_catalog.rb +13 -19
  131. data/lib/rigor/inference/builtins/date_catalog.rb +38 -67
  132. data/lib/rigor/inference/builtins/encoding_catalog.rb +22 -36
  133. data/lib/rigor/inference/builtins/enumerable_catalog.rb +4 -6
  134. data/lib/rigor/inference/builtins/exception_catalog.rb +38 -57
  135. data/lib/rigor/inference/builtins/hash_catalog.rb +9 -14
  136. data/lib/rigor/inference/builtins/method_catalog.rb +29 -48
  137. data/lib/rigor/inference/builtins/numeric_catalog.rb +13 -18
  138. data/lib/rigor/inference/builtins/pathname_catalog.rb +8 -13
  139. data/lib/rigor/inference/builtins/proc_catalog.rb +38 -62
  140. data/lib/rigor/inference/builtins/random_catalog.rb +21 -32
  141. data/lib/rigor/inference/builtins/range_catalog.rb +12 -21
  142. data/lib/rigor/inference/builtins/rational_catalog.rb +9 -15
  143. data/lib/rigor/inference/builtins/re_catalog.rb +29 -48
  144. data/lib/rigor/inference/builtins/set_catalog.rb +18 -27
  145. data/lib/rigor/inference/builtins/string_catalog.rb +12 -19
  146. data/lib/rigor/inference/builtins/struct_catalog.rb +18 -30
  147. data/lib/rigor/inference/builtins/time_catalog.rb +28 -44
  148. data/lib/rigor/inference/closure_escape_analyzer.rb +44 -67
  149. data/lib/rigor/inference/coverage_scanner.rb +13 -18
  150. data/lib/rigor/inference/def_return_typer.rb +8 -14
  151. data/lib/rigor/inference/dynamic_origin.rb +23 -20
  152. data/lib/rigor/inference/expression_typer.rb +774 -1152
  153. data/lib/rigor/inference/fallback.rb +8 -12
  154. data/lib/rigor/inference/fallback_tracer.rb +4 -10
  155. data/lib/rigor/inference/flow_tracer.rb +25 -36
  156. data/lib/rigor/inference/hkt_body.rb +45 -68
  157. data/lib/rigor/inference/hkt_body_parser.rb +33 -52
  158. data/lib/rigor/inference/hkt_reducer.rb +38 -59
  159. data/lib/rigor/inference/hkt_registry.rb +50 -76
  160. data/lib/rigor/inference/indexed_narrowing.rb +55 -81
  161. data/lib/rigor/inference/macro_block_self_type.rb +21 -34
  162. data/lib/rigor/inference/method_dispatcher/array_to_h_folding.rb +11 -18
  163. data/lib/rigor/inference/method_dispatcher/block_folding.rb +49 -83
  164. data/lib/rigor/inference/method_dispatcher/call_context.rb +16 -23
  165. data/lib/rigor/inference/method_dispatcher/cgi_folding.rb +13 -22
  166. data/lib/rigor/inference/method_dispatcher/constant_folding.rb +307 -454
  167. data/lib/rigor/inference/method_dispatcher/data_folding.rb +24 -34
  168. data/lib/rigor/inference/method_dispatcher/file_folding.rb +22 -37
  169. data/lib/rigor/inference/method_dispatcher/iterator_dispatch.rb +52 -81
  170. data/lib/rigor/inference/method_dispatcher/kernel_dispatch.rb +51 -78
  171. data/lib/rigor/inference/method_dispatcher/literal_string_folding.rb +60 -97
  172. data/lib/rigor/inference/method_dispatcher/math_folding.rb +23 -34
  173. data/lib/rigor/inference/method_dispatcher/member_shape_projection.rb +18 -26
  174. data/lib/rigor/inference/method_dispatcher/method_folding.rb +37 -71
  175. data/lib/rigor/inference/method_dispatcher/overload_selector.rb +114 -182
  176. data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +122 -193
  177. data/lib/rigor/inference/method_dispatcher/receiver_affinity.rb +15 -24
  178. data/lib/rigor/inference/method_dispatcher/reduce_folding.rb +64 -93
  179. data/lib/rigor/inference/method_dispatcher/regexp_folding.rb +31 -45
  180. data/lib/rigor/inference/method_dispatcher/set_folding.rb +6 -9
  181. data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +356 -511
  182. data/lib/rigor/inference/method_dispatcher/shellwords_folding.rb +22 -32
  183. data/lib/rigor/inference/method_dispatcher/singleton_folding.rb +15 -21
  184. data/lib/rigor/inference/method_dispatcher/struct_folding.rb +66 -82
  185. data/lib/rigor/inference/method_dispatcher/time_folding.rb +10 -15
  186. data/lib/rigor/inference/method_dispatcher/uri_folding.rb +9 -13
  187. data/lib/rigor/inference/method_dispatcher.rb +378 -524
  188. data/lib/rigor/inference/method_parameter_binder.rb +81 -114
  189. data/lib/rigor/inference/multi_target_binder.rb +51 -68
  190. data/lib/rigor/inference/mutation_widening.rb +115 -158
  191. data/lib/rigor/inference/narrowing.rb +509 -727
  192. data/lib/rigor/inference/origin_lookup.rb +38 -0
  193. data/lib/rigor/inference/parameter_inference_collector.rb +100 -100
  194. data/lib/rigor/inference/precision_scanner.rb +26 -35
  195. data/lib/rigor/inference/project_patched_methods.rb +20 -32
  196. data/lib/rigor/inference/project_patched_scanner.rb +23 -37
  197. data/lib/rigor/inference/protection_scanner.rb +16 -18
  198. data/lib/rigor/inference/rbs_type_translator.rb +49 -66
  199. data/lib/rigor/inference/scope_indexer.rb +473 -817
  200. data/lib/rigor/inference/statement_evaluator.rb +706 -1111
  201. data/lib/rigor/inference/struct_fold_safety.rb +34 -48
  202. data/lib/rigor/inference/synthetic_method.rb +9 -16
  203. data/lib/rigor/inference/synthetic_method_index.rb +20 -35
  204. data/lib/rigor/inference/synthetic_method_scanner.rb +63 -103
  205. data/lib/rigor/language_server/buffer_resolution.rb +6 -9
  206. data/lib/rigor/language_server/buffer_table.rb +11 -18
  207. data/lib/rigor/language_server/completion_provider.rb +69 -116
  208. data/lib/rigor/language_server/debouncer.rb +16 -25
  209. data/lib/rigor/language_server/diagnostic_publisher.rb +26 -40
  210. data/lib/rigor/language_server/document_symbol_provider.rb +14 -19
  211. data/lib/rigor/language_server/folding_range_provider.rb +11 -19
  212. data/lib/rigor/language_server/hover_provider.rb +8 -11
  213. data/lib/rigor/language_server/hover_renderer.rb +56 -93
  214. data/lib/rigor/language_server/loop.rb +14 -19
  215. data/lib/rigor/language_server/project_context.rb +46 -74
  216. data/lib/rigor/language_server/selection_range_provider.rb +9 -12
  217. data/lib/rigor/language_server/server.rb +55 -83
  218. data/lib/rigor/language_server/signature_help_provider.rb +29 -46
  219. data/lib/rigor/language_server/synchronized_writer.rb +4 -7
  220. data/lib/rigor/language_server/uri.rb +8 -13
  221. data/lib/rigor/language_server.rb +4 -6
  222. data/lib/rigor/mcp/loop.rb +2 -3
  223. data/lib/rigor/mcp/server.rb +4 -7
  224. data/lib/rigor/mcp.rb +3 -6
  225. data/lib/rigor/plugin/access_denied_error.rb +5 -8
  226. data/lib/rigor/plugin/additional_initializer.rb +21 -31
  227. data/lib/rigor/plugin/base.rb +335 -518
  228. data/lib/rigor/plugin/blueprint.rb +14 -23
  229. data/lib/rigor/plugin/box.rb +18 -29
  230. data/lib/rigor/plugin/fact_store.rb +16 -26
  231. data/lib/rigor/plugin/inflector.rb +37 -53
  232. data/lib/rigor/plugin/io_boundary.rb +33 -56
  233. data/lib/rigor/plugin/isolation.rb +42 -55
  234. data/lib/rigor/plugin/load_error.rb +10 -15
  235. data/lib/rigor/plugin/loader.rb +30 -49
  236. data/lib/rigor/plugin/macro/block_as_method.rb +20 -32
  237. data/lib/rigor/plugin/macro/heredoc_template.rb +35 -58
  238. data/lib/rigor/plugin/macro/nested_class_template.rb +22 -36
  239. data/lib/rigor/plugin/macro/trait_registry.rb +34 -51
  240. data/lib/rigor/plugin/macro.rb +10 -15
  241. data/lib/rigor/plugin/manifest.rb +85 -144
  242. data/lib/rigor/plugin/node_context.rb +14 -22
  243. data/lib/rigor/plugin/node_rule_walk.rb +49 -74
  244. data/lib/rigor/plugin/protocol_contract.rb +25 -39
  245. data/lib/rigor/plugin/registry.rb +132 -205
  246. data/lib/rigor/plugin/services.rb +21 -33
  247. data/lib/rigor/plugin/source_rbs_synthesis_reporter.rb +11 -19
  248. data/lib/rigor/plugin/trust_policy.rb +24 -38
  249. data/lib/rigor/plugin/type_node_resolver.rb +15 -24
  250. data/lib/rigor/protection/diagnostic_oracle.rb +11 -13
  251. data/lib/rigor/protection/mutation_scanner.rb +27 -35
  252. data/lib/rigor/protection/mutator.rb +50 -70
  253. data/lib/rigor/protection/test_suite_oracle.rb +20 -27
  254. data/lib/rigor/rbs_extended/conformance_checker.rb +48 -68
  255. data/lib/rigor/rbs_extended/hkt_directives.rb +28 -54
  256. data/lib/rigor/rbs_extended/reporter.rb +24 -40
  257. data/lib/rigor/rbs_extended.rb +107 -197
  258. data/lib/rigor/reflection.rb +68 -86
  259. data/lib/rigor/scope/discovery_index.rb +14 -19
  260. data/lib/rigor/scope.rb +255 -310
  261. data/lib/rigor/sig_gen/classification.rb +6 -10
  262. data/lib/rigor/sig_gen/generator.rb +197 -323
  263. data/lib/rigor/sig_gen/layout_index.rb +12 -20
  264. data/lib/rigor/sig_gen/method_candidate.rb +12 -17
  265. data/lib/rigor/sig_gen/observation_collector.rb +38 -70
  266. data/lib/rigor/sig_gen/observed_call.rb +13 -23
  267. data/lib/rigor/sig_gen/path_mapper.rb +17 -29
  268. data/lib/rigor/sig_gen/renderer.rb +7 -13
  269. data/lib/rigor/sig_gen/type_elaborator.rb +15 -28
  270. data/lib/rigor/sig_gen/write_result.rb +8 -16
  271. data/lib/rigor/sig_gen/writer.rb +95 -174
  272. data/lib/rigor/sig_gen.rb +3 -6
  273. data/lib/rigor/signature_path_audit.rb +24 -30
  274. data/lib/rigor/source/constant_path.rb +10 -14
  275. data/lib/rigor/source/literals.rb +31 -45
  276. data/lib/rigor/source/node_locator.rb +9 -11
  277. data/lib/rigor/source/node_walker.rb +9 -13
  278. data/lib/rigor/source.rb +3 -4
  279. data/lib/rigor/testing.rb +16 -20
  280. data/lib/rigor/triage/catalogue.rb +38 -62
  281. data/lib/rigor/triage.rb +31 -52
  282. data/lib/rigor/trinary.rb +9 -13
  283. data/lib/rigor/type/acceptance_router.rb +4 -6
  284. data/lib/rigor/type/accepts_result.rb +10 -14
  285. data/lib/rigor/type/app.rb +19 -27
  286. data/lib/rigor/type/bot.rb +4 -6
  287. data/lib/rigor/type/bound_method.rb +10 -15
  288. data/lib/rigor/type/combinator.rb +165 -257
  289. data/lib/rigor/type/constant.rb +23 -34
  290. data/lib/rigor/type/data_class.rb +10 -15
  291. data/lib/rigor/type/data_instance.rb +14 -20
  292. data/lib/rigor/type/difference.rb +21 -32
  293. data/lib/rigor/type/dynamic.rb +3 -5
  294. data/lib/rigor/type/hash_shape.rb +32 -18
  295. data/lib/rigor/type/integer_range.rb +11 -16
  296. data/lib/rigor/type/intersection.rb +27 -42
  297. data/lib/rigor/type/nominal.rb +10 -15
  298. data/lib/rigor/type/plain_lattice.rb +9 -13
  299. data/lib/rigor/type/refined.rb +67 -114
  300. data/lib/rigor/type/singleton.rb +4 -6
  301. data/lib/rigor/type/struct_class.rb +11 -16
  302. data/lib/rigor/type/struct_instance.rb +15 -21
  303. data/lib/rigor/type/tuple.rb +14 -19
  304. data/lib/rigor/type/union.rb +30 -42
  305. data/lib/rigor/type_node/generic.rb +14 -26
  306. data/lib/rigor/type_node/identifier.rb +12 -19
  307. data/lib/rigor/type_node.rb +3 -12
  308. data/lib/rigor/value_semantics.rb +16 -21
  309. data/lib/rigor/version.rb +1 -1
  310. data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/analyzer.rb +18 -30
  311. data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_discoverer.rb +16 -29
  312. data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_index.rb +12 -23
  313. data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +22 -39
  314. data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/analyzer.rb +26 -46
  315. data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_discoverer.rb +51 -87
  316. data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_index.rb +10 -17
  317. data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb +26 -39
  318. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb +118 -176
  319. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_discoverer.rb +30 -51
  320. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_index.rb +57 -92
  321. data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +71 -108
  322. data/plugins/rigor-activejob/lib/rigor/plugin/activejob/analyzer.rb +13 -22
  323. data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_discoverer.rb +15 -25
  324. data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_index.rb +8 -13
  325. data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +16 -24
  326. data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/analyzer.rb +30 -47
  327. data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +79 -129
  328. data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_index.rb +36 -57
  329. data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_parser.rb +27 -41
  330. data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_table.rb +16 -24
  331. data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +148 -235
  332. data/plugins/rigor-activerecord/lib/rigor-activerecord.rb +3 -5
  333. data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/analyzer.rb +8 -14
  334. data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_discoverer.rb +9 -15
  335. data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_index.rb +4 -7
  336. data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +23 -41
  337. data/plugins/rigor-activestorage/lib/rigor-activestorage.rb +3 -5
  338. data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb +6 -10
  339. data/plugins/rigor-activesupport-core-ext/lib/rigor-activesupport-core-ext.rb +8 -11
  340. data/plugins/rigor-devise/lib/rigor/plugin/devise.rb +30 -45
  341. data/plugins/rigor-devise/lib/rigor-devise.rb +3 -5
  342. data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema/schema_scanner.rb +43 -69
  343. data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema.rb +26 -35
  344. data/plugins/rigor-dry-schema/lib/rigor-dry-schema.rb +3 -5
  345. data/plugins/rigor-dry-struct/lib/rigor/plugin/dry_struct.rb +30 -47
  346. data/plugins/rigor-dry-struct/lib/rigor-dry-struct.rb +3 -5
  347. data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types/alias_scanner.rb +67 -113
  348. data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types.rb +29 -46
  349. data/plugins/rigor-dry-types/lib/rigor-dry-types.rb +3 -5
  350. data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation/contract_scanner.rb +13 -20
  351. data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation.rb +14 -23
  352. data/plugins/rigor-dry-validation/lib/rigor-dry-validation.rb +2 -3
  353. data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/analyzer.rb +22 -37
  354. data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_discoverer.rb +28 -46
  355. data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_index.rb +13 -17
  356. data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot.rb +30 -47
  357. data/plugins/rigor-graphql/lib/rigor/plugin/graphql/type_scanner.rb +52 -80
  358. data/plugins/rigor-graphql/lib/rigor/plugin/graphql.rb +21 -31
  359. data/plugins/rigor-graphql/lib/rigor-graphql.rb +3 -5
  360. data/plugins/rigor-hanami/lib/rigor/plugin/hanami/action_checker.rb +11 -17
  361. data/plugins/rigor-hanami/lib/rigor/plugin/hanami.rb +20 -34
  362. data/plugins/rigor-mangrove/lib/rigor/plugin/mangrove.rb +45 -75
  363. data/plugins/rigor-minitest/lib/rigor/plugin/minitest/assertion_analyzer.rb +22 -36
  364. data/plugins/rigor-minitest/lib/rigor/plugin/minitest.rb +22 -41
  365. data/plugins/rigor-pundit/lib/rigor/plugin/pundit/analyzer.rb +17 -32
  366. data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_discoverer.rb +6 -12
  367. data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_index.rb +4 -8
  368. data/plugins/rigor-pundit/lib/rigor/plugin/pundit.rb +17 -32
  369. data/plugins/rigor-rails/lib/rigor-rails.rb +11 -18
  370. data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/analyzer.rb +58 -92
  371. data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_index.rb +20 -34
  372. data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_loader.rb +20 -31
  373. data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n.rb +49 -82
  374. data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/analyzer.rb +55 -92
  375. data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/devise_routes.rb +51 -90
  376. data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/doorkeeper_routes.rb +17 -30
  377. data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_discoverer.rb +38 -70
  378. data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_table.rb +42 -74
  379. data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/routes_parser.rb +280 -497
  380. data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +54 -89
  381. data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb +32 -54
  382. data/plugins/rigor-rbs-inline/lib/rigor-rbs-inline.rb +8 -13
  383. data/plugins/rigor-rspec/lib/rigor/plugin/rspec/analyzer.rb +9 -16
  384. data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_scope_index.rb +24 -39
  385. data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_type_resolver.rb +13 -22
  386. data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +34 -56
  387. data/plugins/rigor-rspec/lib/rigor/plugin/rspec/scope_walker.rb +22 -42
  388. data/plugins/rigor-rspec/lib/rigor/plugin/rspec.rb +43 -75
  389. data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails/have_http_status_analyzer.rb +27 -39
  390. data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails/http_status_codes.rb +14 -19
  391. data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails.rb +20 -34
  392. data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers/analyzer.rb +28 -47
  393. data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers.rb +21 -37
  394. data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/analyzer.rb +13 -22
  395. data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_discoverer.rb +18 -31
  396. data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_index.rb +6 -10
  397. data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb +14 -29
  398. data/plugins/rigor-sinatra/lib/rigor/plugin/sinatra.rb +23 -41
  399. data/plugins/rigor-sinatra/lib/rigor-sinatra.rb +3 -5
  400. data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/absurd_recognizer.rb +23 -38
  401. data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/assertion_recognizer.rb +57 -96
  402. data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog.rb +22 -35
  403. data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog_walker.rb +41 -69
  404. data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/method_signature.rb +6 -10
  405. data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sig_parser.rb +24 -41
  406. data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sigil_detector.rb +29 -50
  407. data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/type_translator.rb +55 -88
  408. data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +159 -262
  409. data/plugins/rigor-statesman/lib/rigor/plugin/statesman.rb +21 -29
  410. data/plugins/rigor-statesman/lib/rigor-statesman.rb +3 -5
  411. data/plugins/rigor-typescript-utility-types/lib/rigor/plugin/typescript_utility_types.rb +23 -37
  412. data/plugins/rigor-typescript-utility-types/lib/rigor-typescript-utility-types.rb +4 -6
  413. data/sig/rigor/scope.rbs +6 -0
  414. metadata +2 -1
@@ -5,32 +5,25 @@ require_relative "../../type"
5
5
  module Rigor
6
6
  module Inference
7
7
  module MethodDispatcher
8
- # `Array#to_h { |x| [k, v] }` (and the no-block-pair tuple form's
9
- # block sibling) return-type fold.
8
+ # `Array#to_h { |x| [k, v] }` (and the no-block-pair tuple form's block sibling) return-type fold.
10
9
  #
11
- # `Enumerable#to_h` with a block maps every element to a
12
- # `[key, value]` pair and collects them into a Hash. When the
13
- # block's inferred return type is a recognizable 2-element
14
- # `Tuple` (`[K, V]`), this tier projects the pair into a
15
- # `Hash[K, V]` nominal whose key/value parameters are the
16
- # widened pair types. Without this fold the call hits the RBS
17
- # generic and the block's `[K, V]` return is dropped, typing as
10
+ # `Enumerable#to_h` with a block maps every element to a `[key, value]` pair and collects them into a Hash.
11
+ # When the block's inferred return type is a recognizable 2-element `Tuple` (`[K, V]`), this tier projects
12
+ # the pair into a `Hash[K, V]` nominal whose key/value parameters are the widened pair types. Without this
13
+ # fold the call hits the RBS generic and the block's `[K, V]` return is dropped, typing as
18
14
  # `Hash[Dynamic[top], Dynamic[top]]`.
19
15
  #
20
- # Value-pinned constants in the pair (`Constant[2]`) are widened
21
- # to their nominal (`Integer`) for the Hash parameters: the built
22
- # hash holds many keys, so pinning the parameter to a single
23
- # element's literal would be unsound for the aggregate. The same
24
- # widening the loop-body fixpoint applies (`Combinator#
25
- # widen_value_pinned`) is reused.
16
+ # Value-pinned constants in the pair (`Constant[2]`) are widened to their nominal (`Integer`) for the Hash
17
+ # parameters: the built hash holds many keys, so pinning the parameter to a single element's literal would
18
+ # be unsound for the aggregate. The same widening the loop-body fixpoint applies
19
+ # (`Combinator#widen_value_pinned`) is reused.
26
20
  #
27
21
  # Declines (returns `nil`, leaving today's RBS answer) when:
28
22
  #
29
23
  # - there is no block at the call site,
30
24
  # - the block return type is not a 2-element `Tuple`, or
31
- # - the receiver is not an Array-shaped carrier (`Tuple` or
32
- # `Array` nominal). Hash receivers keep their existing
33
- # `ShapeDispatch#hash_to_h` identity fold.
25
+ # - the receiver is not an Array-shaped carrier (`Tuple` or `Array` nominal). Hash receivers keep their
26
+ # existing `ShapeDispatch#hash_to_h` identity fold.
34
27
  module ArrayToHFolding
35
28
  module_function
36
29
 
@@ -7,36 +7,25 @@ module Rigor
7
7
  module MethodDispatcher
8
8
  # Block-shaped fold dispatch (v0.0.6 phase 1).
9
9
  #
10
- # Sits ahead of `RbsDispatch.try_dispatch` and folds a small
11
- # set of block-taking Enumerable methods when the inferred
12
- # block return type is a Ruby-truthy or Ruby-falsey
13
- # `Type::Constant`. The block-parameter typing for the same
14
- # methods continues to be answered by `IteratorDispatch`
15
- # (this module concerns the *return* of the call, not the
16
- # block-param binding).
10
+ # Sits ahead of `RbsDispatch.try_dispatch` and folds a small set of block-taking Enumerable methods when
11
+ # the inferred block return type is a Ruby-truthy or Ruby-falsey `Type::Constant`. The block-parameter
12
+ # typing for the same methods continues to be answered by `IteratorDispatch` (this module concerns the
13
+ # *return* of the call, not the block-param binding).
17
14
  #
18
15
  # The methods covered fall in two families:
19
16
  #
20
- # - **Filter-shaped** (`select` / `filter` / `reject` /
21
- # `take_while` / `drop_while`): the block's truthiness
22
- # selects the all-or-nothing endpoints either the
23
- # receiver's full shape (when every element is kept) or
24
- # the empty-tuple carrier (when every element is dropped).
25
- # - **Predicate-shaped** (`all?` / `any?` / `none?`): the
26
- # block's truthiness combined with the receiver's
27
- # emptiness collapses the call to a `Constant[bool]` in
28
- # the cases where Ruby's actual semantics make it
29
- # unconditional. Non-empty + truthy `any?` is `true`;
30
- # non-empty + falsey `all?` is `false`; the empty-receiver
31
- # "vacuous" answers (`[].all? { false } == true`,
32
- # `[].any? { true } == false`, `[].none? { true } == true`)
33
- # are likewise honoured.
17
+ # - **Filter-shaped** (`select` / `filter` / `reject` / `take_while` / `drop_while`): the block's
18
+ # truthiness selects the all-or-nothing endpoints — either the receiver's full shape (when every
19
+ # element is kept) or the empty-tuple carrier (when every element is dropped).
20
+ # - **Predicate-shaped** (`all?` / `any?` / `none?`): the block's truthiness combined with the
21
+ # receiver's emptiness collapses the call to a `Constant[bool]` in the cases where Ruby's actual
22
+ # semantics make it unconditional. Non-empty + truthy `any?` is `true`; non-empty + falsey `all?` is
23
+ # `false`; the empty-receiver "vacuous" answers (`[].all? { false } == true`, `[].any? { true } ==
24
+ # false`, `[].none? { true } == true`) are likewise honoured.
34
25
  #
35
- # The dispatcher returns `nil` for any case that cannot be
36
- # decided from the (receiver-shape, method, block-truthiness)
37
- # tuple element-wise block re-evaluation against
38
- # `Constant<Array>` receivers (the `map` / `filter_map` /
39
- # `flat_map` precision tier) is reserved for a later slice.
26
+ # The dispatcher returns `nil` for any case that cannot be decided from the (receiver-shape, method,
27
+ # block-truthiness) tuple element-wise block re-evaluation against `Constant<Array>` receivers (the
28
+ # `map` / `filter_map` / `flat_map` precision tier) is reserved for a later slice.
40
29
  module BlockFolding
41
30
  module_function
42
31
 
@@ -45,21 +34,16 @@ module Rigor
45
34
 
46
35
  PREDICATE_METHODS = Set[:all?, :any?, :none?].freeze
47
36
 
48
- # Methods whose answer is `nil` when the block always
49
- # returns Ruby-falsey `find` / `detect` short-circuit
50
- # to nil when nothing matches, `find_index` / `index`
51
- # likewise. These methods only fold on the falsey side
52
- # for now; the truthy-block side requires per-position
53
- # analysis (the index of the first kept element, or the
54
- # element itself, depend on the receiver's shape and on
55
- # which positions actually evaluate to truthy).
37
+ # Methods whose answer is `nil` when the block always returns Ruby-falsey — `find` / `detect`
38
+ # short-circuit to nil when nothing matches, `find_index` / `index` likewise. These methods only fold
39
+ # on the falsey side for now; the truthy-block side requires per-position analysis (the index of the
40
+ # first kept element, or the element itself, depend on the receiver's shape and on which positions
41
+ # actually evaluate to truthy).
56
42
  FALSEY_BLOCK_NIL_METHODS = Set[:find, :detect, :find_index, :index].freeze
57
43
 
58
- # Block-taking `count` returns the number of elements
59
- # for which the block is truthy. With a Constant-falsey
60
- # block the answer is unconditionally `Constant[0]`;
61
- # with a Constant-truthy block on a finitely-sized
62
- # receiver it is `Constant[size]`.
44
+ # Block-taking `count` returns the number of elements for which the block is truthy. With a
45
+ # Constant-falsey block the answer is unconditionally `Constant[0]`; with a Constant-truthy block on
46
+ # a finitely-sized receiver it is `Constant[size]`.
63
47
  COUNT_METHOD = :count
64
48
 
65
49
  # @param receiver [Rigor::Type, nil]
@@ -106,13 +90,10 @@ module Rigor
106
90
  block_type.value ? :truthy : :falsey
107
91
  end
108
92
 
109
- # Filter-shaped methods collapse to either the receiver
110
- # (every element kept) or the empty tuple (every element
111
- # dropped). Tuple-shaped receivers widen to
112
- # `Array[union of elements]` on the all-kept side because
113
- # we cannot prove WHICH positional subset survives —
114
- # Tuple's per-position semantics do not carry over to a
115
- # filtered Array.
93
+ # Filter-shaped methods collapse to either the receiver (every element kept) or the empty tuple
94
+ # (every element dropped). Tuple-shaped receivers widen to `Array[union of elements]` on the
95
+ # all-kept side because we cannot prove WHICH positional subset survives — Tuple's per-position
96
+ # semantics do not carry over to a filtered Array.
116
97
  def fold_filter(receiver, method_name, truthiness)
117
98
  return nil unless filter_receiver_known?(receiver)
118
99
 
@@ -140,8 +121,7 @@ module Rigor
140
121
  Type::Combinator.nominal_of("Array", type_args: [element])
141
122
  end
142
123
 
143
- # Predicate folds. The decision table mirrors Ruby's
144
- # actual semantics on `Enumerable#all?` / `#any?` /
124
+ # Predicate folds. The decision table mirrors Ruby's actual semantics on `Enumerable#all?` / `#any?` /
145
125
  # `#none?` — see the table at the top of the module.
146
126
  def fold_predicate(receiver, method_name, truthiness)
147
127
  emptiness = receiver_emptiness(receiver)
@@ -205,12 +185,9 @@ module Rigor
205
185
  end
206
186
 
207
187
  def constant_emptiness(value)
208
- # Only `Range` constants reach these folds: `Type::Constant`
209
- # rejects Array / Hash literals (they become `Tuple` /
210
- # `HashShape` carriers), and the remaining scalar
211
- # constants (Integer / Float / Symbol / String / …)
212
- # are not Enumerable receivers for the filter or
213
- # predicate methods folded here.
188
+ # Only `Range` constants reach these folds: `Type::Constant` rejects Array / Hash literals (they
189
+ # become `Tuple` / `HashShape` carriers), and the remaining scalar constants (Integer / Float /
190
+ # Symbol / String / …) are not Enumerable receivers for the filter or predicate methods folded here.
214
191
  return range_emptiness(value) if value.is_a?(Range)
215
192
 
216
193
  :unknown
@@ -228,12 +205,9 @@ module Rigor
228
205
  end
229
206
  end
230
207
 
231
- # `non-empty-array[T]` is encoded as
232
- # `Difference[Array[T], Tuple[]]` the imported built-in
233
- # carrier for non-emptiness. Recognising it here lets
234
- # `arr.any? { true }` fold to `Constant[true]` for
235
- # callers who threaded the non-emptiness through their
236
- # type signature.
208
+ # `non-empty-array[T]` is encoded as `Difference[Array[T], Tuple[]]` — the imported built-in carrier
209
+ # for non-emptiness. Recognising it here lets `arr.any? { true }` fold to `Constant[true]` for
210
+ # callers who threaded the non-emptiness through their type signature.
237
211
  def difference_emptiness(diff)
238
212
  base = diff.base
239
213
  removed = diff.removed
@@ -247,11 +221,9 @@ module Rigor
247
221
  type.is_a?(Type::Nominal) && %w[Array Hash Set].include?(type.class_name)
248
222
  end
249
223
 
250
- # Filter folds need at least a recognised collection
251
- # carrier; `Top` / `Dynamic` / arbitrary nominals decline
252
- # so the RBS tier answers (its `Array#select { … } -> Array[T]`
253
- # projection is correct, just less precise on the empty
254
- # endpoint).
224
+ # Filter folds need at least a recognised collection carrier; `Top` / `Dynamic` / arbitrary nominals
225
+ # decline so the RBS tier answers (its `Array#select { … } -> Array[T]` projection is correct, just
226
+ # less precise on the empty endpoint).
255
227
  def filter_receiver_known?(receiver)
256
228
  case receiver
257
229
  when Type::Tuple, Type::HashShape, Type::Constant, Type::Difference then true
@@ -260,12 +232,10 @@ module Rigor
260
232
  end
261
233
  end
262
234
 
263
- # `find` / `detect` / `find_index` / `index` (block form)
264
- # short-circuit to nil when the block is provably falsey.
265
- # `index` and `find_index` also accept a non-block argument
266
- # form (`arr.index(value)`); we decline whenever the call
267
- # carries a positional argument so the RBS tier still
268
- # answers the value-search variant correctly.
235
+ # `find` / `detect` / `find_index` / `index` (block form) short-circuit to nil when the block is
236
+ # provably falsey. `index` and `find_index` also accept a non-block argument form
237
+ # (`arr.index(value)`); we decline whenever the call carries a positional argument so the RBS tier
238
+ # still answers the value-search variant correctly.
269
239
  def fold_falsey_nil_short_circuit(_method_name, truthiness, args)
270
240
  return nil unless args.empty?
271
241
  return nil unless truthiness == :falsey
@@ -273,11 +243,9 @@ module Rigor
273
243
  Type::Combinator.constant_of(nil)
274
244
  end
275
245
 
276
- # `count` with a block returns the count of elements
277
- # for which the block is truthy. The non-block forms
278
- # (`count` / `count(value)`) carry positional arguments
279
- # and are handled by the RBS tier; this fold only fires
280
- # when the block is the sole source of selection.
246
+ # `count` with a block returns the count of elements for which the block is truthy. The non-block
247
+ # forms (`count` / `count(value)`) carry positional arguments and are handled by the RBS tier; this
248
+ # fold only fires when the block is the sole source of selection.
281
249
  def fold_count(receiver, truthiness, args)
282
250
  return nil unless args.empty?
283
251
  return Type::Combinator.constant_of(0) if truthiness == :falsey
@@ -292,11 +260,9 @@ module Rigor
292
260
  Type::Combinator.constant_of(size)
293
261
  end
294
262
 
295
- # Returns the receiver's known finite element count, or
296
- # nil when the carrier does not pin a size. Tuple and
297
- # HashShape are pinned by construction; `Constant<…>`
298
- # exposes the literal's `.size`. Other shapes (Array[T],
299
- # Range[T], Nominal) decline so the RBS tier widens.
263
+ # Returns the receiver's known finite element count, or nil when the carrier does not pin a size.
264
+ # Tuple and HashShape are pinned by construction; `Constant<…>` exposes the literal's `.size`. Other
265
+ # shapes (Array[T], Range[T], Nominal) decline so the RBS tier widens.
300
266
  def finite_size(receiver)
301
267
  case receiver
302
268
  when Type::Tuple then receiver.elements.size
@@ -306,8 +272,8 @@ module Rigor
306
272
  end
307
273
 
308
274
  def constant_size(value)
309
- # Mirrors `constant_emptiness` — only `Range` produces
310
- # a meaningful finite size for the methods folded here.
275
+ # Mirrors `constant_emptiness` — only `Range` produces a meaningful finite size for the methods
276
+ # folded here.
311
277
  range_size(value) if value.is_a?(Range)
312
278
  end
313
279
 
@@ -3,22 +3,18 @@
3
3
  module Rigor
4
4
  module Inference
5
5
  module MethodDispatcher
6
- # Immutable value object carrying everything a dispatch tier needs
7
- # to fold a single call site. Built once per `MethodDispatcher.dispatch`
8
- # and threaded unchanged through every tier, replacing the
9
- # `(receiver:, method_name:, args:, )` keyword quartet that each
10
- # tier used to redeclare (several with `# rubocop:disable
11
- # Metrics/ParameterLists`).
6
+ # Immutable value object carrying everything a dispatch tier needs to fold a single call site. Built
7
+ # once per `MethodDispatcher.dispatch` and threaded unchanged through every tier, replacing the
8
+ # `(receiver:, method_name:, args:, …)` keyword quartet that each tier used to redeclare (several
9
+ # needing a Metrics/ParameterLists rubocop exemption).
12
10
  #
13
- # Every tier satisfies one interface — `try_dispatch(CallContext) ->
14
- # Rigor::Type?` (the `_DispatchTier` RBS interface). Pure tiers
15
- # (the singleton folders, ConstantFolding, ShapeDispatch, …) read
16
- # only `receiver` / `method_name` / `args` and ignore the rest;
17
- # the RBS / backward / block-param tiers consult the wider context.
11
+ # Every tier satisfies one interface — `try_dispatch(CallContext) -> Rigor::Type?` (the `_DispatchTier`
12
+ # RBS interface). Pure tiers (the singleton folders, ConstantFolding, ShapeDispatch, …) read only
13
+ # `receiver` / `method_name` / `args` and ignore the rest; the RBS / backward / block-param tiers
14
+ # consult the wider context.
18
15
  #
19
- # Derived call sites (the user-class fallback's `public_only` RBS
20
- # retry, the Tier-B origin-module redispatch) use `Data#with` to
21
- # copy the base context with the few fields that differ rather than
16
+ # Derived call sites (the user-class fallback's `public_only` RBS retry, the Tier-B origin-module
17
+ # redispatch) use `Data#with` to copy the base context with the few fields that differ rather than
22
18
  # rebuilding the quartet by hand.
23
19
  #
24
20
  # Fields:
@@ -36,19 +32,16 @@ module Rigor
36
32
  :block_type, :environment, :call_node, :scope,
37
33
  :self_type_override, :public_only
38
34
  ) do
39
- # Keyword factory with nil/false defaults for the optional
40
- # context fields, so a caller that only has the call quartet
41
- # (the common precise-tier path) need not spell out the rest.
35
+ # Keyword factory with nil/false defaults for the optional context fields, so a caller that only has
36
+ # the call quartet (the common precise-tier path) need not spell out the rest.
42
37
  #
43
- # This is the single place the call-context field list is
44
- # enumerated the whole point of the value object is to absorb
45
- # the wide keyword list the tiers used to each redeclare.
38
+ # This is the single place the call-context field list is enumerated — the whole point of the value
39
+ # object is to absorb the wide keyword list the tiers used to each redeclare.
46
40
  def self.build(receiver:, method_name:, args:, # rubocop:disable Metrics/ParameterLists
47
41
  block_type: nil, environment: nil, call_node: nil,
48
42
  scope: nil, self_type_override: nil, public_only: false)
49
- # Positional `new` (field-definition order) avoids the keyword
50
- # hash a `new(receiver:, …)` call allocates — this runs once per
51
- # dispatch and was a top allocation site. Order MUST track the
43
+ # Positional `new` (field-definition order) avoids the keyword hash a `new(receiver:, …)` call
44
+ # allocates — this runs once per dispatch and was a top allocation site. Order MUST track the
52
45
  # `Data.define` field list above.
53
46
  new(
54
47
  receiver, method_name, args,
@@ -7,31 +7,23 @@ require_relative "singleton_folding"
7
7
  module Rigor
8
8
  module Inference
9
9
  module MethodDispatcher
10
- # Folds `CGI` module-function calls on statically known
11
- # string constants.
10
+ # Folds `CGI` module-function calls on statically known string constants.
12
11
  #
13
- # `CGI.escapeHTML` / `CGI.unescapeHTML` and related methods
14
- # are pure, deterministic functions over their string inputs.
15
- # When the argument is a `Constant[String]`, the analyzer can
16
- # evaluate the call at inference time and return the concrete
17
- # `Constant[String]` result.
12
+ # `CGI.escapeHTML` / `CGI.unescapeHTML` and related methods are pure, deterministic functions over
13
+ # their string inputs. When the argument is a `Constant[String]`, the analyzer can evaluate the call
14
+ # at inference time and return the concrete `Constant[String]` result.
18
15
  #
19
16
  # === Supported methods
20
17
  #
21
- # * `escapeHTML(str)` / `escape_html(str)` / `h(str)` —
22
- # HTML-escape. Returns `Constant[String]`.
23
- # * `unescapeHTML(str)` / `unescape_html(str)` —
24
- # HTML-unescape. Returns `Constant[String]`.
25
- # * `escape(str)` / `unescape(str)` —
26
- # URL-encode / decode (`application/x-www-form-urlencoded`).
18
+ # * `escapeHTML(str)` / `escape_html(str)` / `h(str)` — HTML-escape. Returns `Constant[String]`.
19
+ # * `unescapeHTML(str)` / `unescape_html(str)` — HTML-unescape. Returns `Constant[String]`.
20
+ # * `escape(str)` / `unescape(str)` — URL-encode / decode (`application/x-www-form-urlencoded`).
27
21
  # Returns `Constant[String]`.
28
- # * `escapeURIComponent(str)` / `escape_uri_component(str)`,
29
- # `unescapeURIComponent(str)` / `unescape_uri_component(str)` —
30
- # URI-component percent-encode / decode. Returns `Constant[String]`.
22
+ # * `escapeURIComponent(str)` / `escape_uri_component(str)`, `unescapeURIComponent(str)` /
23
+ # `unescape_uri_component(str)` — URI-component percent-encode / decode. Returns `Constant[String]`.
31
24
  # * `escapeElement(str, *elements)` / `escape_element(str, *elements)`,
32
- # `unescapeElement(str, *elements)` / `unescape_element(str, *elements)` —
33
- # element-level escape / unescape (first arg is the string,
34
- # remaining args are element names). Returns `Constant[String]`.
25
+ # `unescapeElement(str, *elements)` / `unescape_element(str, *elements)` — element-level escape /
26
+ # unescape (first arg is the string, remaining args are element names). Returns `Constant[String]`.
35
27
  #
36
28
  # === Non-constant / unsupported cases
37
29
  #
@@ -89,9 +81,8 @@ module Rigor
89
81
  nil
90
82
  end
91
83
 
92
- # `CGI.escapeElement(str, "elem1", "elem2", ...)` — element-
93
- # level escape / unescape. The remaining args after the first
94
- # must be `Constant[String]` element names.
84
+ # `CGI.escapeElement(str, "elem1", "elem2", ...)` — element-level escape / unescape. The remaining
85
+ # args after the first must be `Constant[String]` element names.
95
86
  def fold_cgi_element(method_name, str, element_args)
96
87
  elements = element_args.map do |arg|
97
88
  value = SingletonFolding.constant_string(arg)