rigortype 0.2.7 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/docs/manual/04-diagnostics.md +7 -4
- data/docs/manual/06-baseline.md +5 -2
- data/docs/manual/15-type-protection-coverage.md +6 -4
- data/lib/rigor/analysis/baseline.rb +56 -96
- data/lib/rigor/analysis/buffer_binding.rb +13 -20
- data/lib/rigor/analysis/check_rules/always_truthy_condition_collector.rb +29 -48
- data/lib/rigor/analysis/check_rules/dead_assignment_collector.rb +35 -54
- data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +23 -37
- data/lib/rigor/analysis/check_rules/main_pass_collector.rb +16 -23
- data/lib/rigor/analysis/check_rules/rule_walk.rb +48 -71
- data/lib/rigor/analysis/check_rules/self_closedness_scanner.rb +19 -28
- data/lib/rigor/analysis/check_rules/unreachable_clause_collector.rb +48 -67
- data/lib/rigor/analysis/check_rules.rb +174 -274
- data/lib/rigor/analysis/dependency_recorder.rb +26 -38
- data/lib/rigor/analysis/dependency_source_inference/boundary_cross_reporter.rb +13 -25
- data/lib/rigor/analysis/dependency_source_inference/builder.rb +17 -30
- data/lib/rigor/analysis/dependency_source_inference/gem_resolver.rb +15 -26
- data/lib/rigor/analysis/dependency_source_inference/index.rb +45 -76
- data/lib/rigor/analysis/dependency_source_inference/return_type_heuristic.rb +23 -40
- data/lib/rigor/analysis/dependency_source_inference/walker.rb +50 -83
- data/lib/rigor/analysis/dependency_source_inference.rb +6 -10
- data/lib/rigor/analysis/diagnostic.rb +48 -75
- data/lib/rigor/analysis/erb_template_detector.rb +13 -18
- data/lib/rigor/analysis/fact_store.rb +12 -22
- data/lib/rigor/analysis/incremental.rb +47 -63
- data/lib/rigor/analysis/incremental_session.rb +74 -100
- data/lib/rigor/analysis/project_scan.rb +12 -23
- data/lib/rigor/analysis/result.rb +3 -5
- data/lib/rigor/analysis/rule_catalog.rb +67 -95
- data/lib/rigor/analysis/run_stats.rb +38 -61
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +101 -160
- data/lib/rigor/analysis/runner/pool_coordinator.rb +121 -188
- data/lib/rigor/analysis/runner/project_pre_passes.rb +62 -96
- data/lib/rigor/analysis/runner/run_snapshots.rb +12 -18
- data/lib/rigor/analysis/runner.rb +220 -333
- data/lib/rigor/analysis/self_call_resolution_recorder.rb +30 -43
- data/lib/rigor/analysis/worker_session.rb +64 -102
- data/lib/rigor/ast/type_node.rb +6 -8
- data/lib/rigor/ast.rb +6 -10
- data/lib/rigor/bleeding_edge.rb +27 -35
- data/lib/rigor/builtins/hkt_builtins.rb +7 -14
- data/lib/rigor/builtins/imported_refinements.rb +106 -149
- data/lib/rigor/builtins/predefined_constant_refinements.rb +51 -65
- data/lib/rigor/builtins/regex_refinement.rb +32 -43
- data/lib/rigor/builtins/static_return_refinements.rb +57 -81
- data/lib/rigor/cache/descriptor.rb +58 -94
- data/lib/rigor/cache/incremental_snapshot.rb +32 -48
- data/lib/rigor/cache/rbs_cache_producer.rb +10 -15
- data/lib/rigor/cache/rbs_class_ancestor_table.rb +10 -16
- data/lib/rigor/cache/rbs_class_type_param_names.rb +10 -16
- data/lib/rigor/cache/rbs_constant_table.rb +8 -13
- data/lib/rigor/cache/rbs_descriptor.rb +8 -13
- data/lib/rigor/cache/rbs_environment.rb +11 -19
- data/lib/rigor/cache/rbs_environment_marshal_patch.rb +11 -19
- data/lib/rigor/cache/rbs_known_class_names.rb +8 -12
- data/lib/rigor/cache/store.rb +96 -151
- data/lib/rigor/cli/annotate_command.rb +51 -88
- data/lib/rigor/cli/baseline_command.rb +10 -17
- data/lib/rigor/cli/check_command.rb +121 -199
- data/lib/rigor/cli/check_runner_factory.rb +8 -14
- data/lib/rigor/cli/ci_detector.rb +9 -14
- data/lib/rigor/cli/command.rb +8 -14
- data/lib/rigor/cli/coverage_command.rb +19 -26
- data/lib/rigor/cli/coverage_mutation.rb +14 -19
- data/lib/rigor/cli/coverage_report.rb +0 -2
- data/lib/rigor/cli/coverage_scan.rb +7 -11
- data/lib/rigor/cli/diagnostic_formats.rb +43 -62
- data/lib/rigor/cli/diff_command.rb +10 -20
- data/lib/rigor/cli/docs_command.rb +26 -40
- data/lib/rigor/cli/doctor_command.rb +8 -9
- data/lib/rigor/cli/explain_command.rb +4 -7
- data/lib/rigor/cli/fused_protection_renderer.rb +4 -5
- data/lib/rigor/cli/fused_protection_report.rb +6 -8
- data/lib/rigor/cli/lsp_command.rb +11 -19
- data/lib/rigor/cli/mcp_command.rb +4 -6
- data/lib/rigor/cli/mutation_protection_renderer.rb +3 -4
- data/lib/rigor/cli/mutation_protection_report.rb +6 -9
- data/lib/rigor/cli/options.rb +11 -19
- data/lib/rigor/cli/plugin_command.rb +18 -30
- data/lib/rigor/cli/plugins_command.rb +29 -51
- data/lib/rigor/cli/plugins_renderer.rb +12 -20
- data/lib/rigor/cli/prism_colorizer.rb +13 -19
- data/lib/rigor/cli/protection_renderer.rb +5 -7
- data/lib/rigor/cli/protection_report.rb +27 -17
- data/lib/rigor/cli/renderable.rb +4 -6
- data/lib/rigor/cli/show_bleedingedge_command.rb +5 -8
- data/lib/rigor/cli/sig_gen_command.rb +14 -26
- data/lib/rigor/cli/skill_command.rb +30 -47
- data/lib/rigor/cli/skill_describe.rb +40 -64
- data/lib/rigor/cli/trace_command.rb +9 -16
- data/lib/rigor/cli/trace_renderer.rb +35 -51
- data/lib/rigor/cli/triage_command.rb +6 -10
- data/lib/rigor/cli/triage_renderer.rb +1 -2
- data/lib/rigor/cli/type_of_command.rb +14 -23
- data/lib/rigor/cli/type_of_renderer.rb +3 -5
- data/lib/rigor/cli/type_scan_command.rb +6 -10
- data/lib/rigor/cli/type_scan_renderer.rb +3 -5
- data/lib/rigor/cli/type_scan_report.rb +2 -3
- data/lib/rigor/cli/upgrade_command.rb +2 -3
- data/lib/rigor/cli.rb +16 -28
- data/lib/rigor/config_audit.rb +35 -44
- data/lib/rigor/configuration/dependencies.rb +41 -70
- data/lib/rigor/configuration/severity_profile.rb +28 -42
- data/lib/rigor/configuration.rb +150 -241
- data/lib/rigor/environment/bundle_sig_discovery.rb +74 -118
- data/lib/rigor/environment/class_registry.rb +19 -26
- data/lib/rigor/environment/constant_type_cache_holder.rb +14 -21
- data/lib/rigor/environment/hkt_registry_holder.rb +6 -12
- data/lib/rigor/environment/lockfile_resolver.rb +31 -47
- data/lib/rigor/environment/rbs_collection_discovery.rb +39 -63
- data/lib/rigor/environment/rbs_coverage_report.rb +24 -42
- data/lib/rigor/environment/rbs_loader.rb +420 -518
- data/lib/rigor/environment/reflection.rb +28 -53
- data/lib/rigor/environment/reporters.rb +13 -24
- data/lib/rigor/environment.rb +176 -291
- data/lib/rigor/flow_contribution/conflict.rb +16 -27
- data/lib/rigor/flow_contribution/element.rb +7 -12
- data/lib/rigor/flow_contribution/fact.rb +33 -57
- data/lib/rigor/flow_contribution/merge_result.rb +6 -9
- data/lib/rigor/flow_contribution/merger.rb +32 -47
- data/lib/rigor/flow_contribution.rb +37 -55
- data/lib/rigor/inference/acceptance.rb +133 -219
- data/lib/rigor/inference/block_parameter_binder.rb +52 -82
- data/lib/rigor/inference/body_fixpoint.rb +22 -30
- data/lib/rigor/inference/budget_trace.rb +43 -63
- data/lib/rigor/inference/builtins/array_catalog.rb +4 -6
- data/lib/rigor/inference/builtins/comparable_catalog.rb +4 -6
- data/lib/rigor/inference/builtins/complex_catalog.rb +13 -19
- data/lib/rigor/inference/builtins/date_catalog.rb +38 -67
- data/lib/rigor/inference/builtins/encoding_catalog.rb +22 -36
- data/lib/rigor/inference/builtins/enumerable_catalog.rb +4 -6
- data/lib/rigor/inference/builtins/exception_catalog.rb +38 -57
- data/lib/rigor/inference/builtins/hash_catalog.rb +9 -14
- data/lib/rigor/inference/builtins/method_catalog.rb +29 -48
- data/lib/rigor/inference/builtins/numeric_catalog.rb +13 -18
- data/lib/rigor/inference/builtins/pathname_catalog.rb +8 -13
- data/lib/rigor/inference/builtins/proc_catalog.rb +38 -62
- data/lib/rigor/inference/builtins/random_catalog.rb +21 -32
- data/lib/rigor/inference/builtins/range_catalog.rb +12 -21
- data/lib/rigor/inference/builtins/rational_catalog.rb +9 -15
- data/lib/rigor/inference/builtins/re_catalog.rb +29 -48
- data/lib/rigor/inference/builtins/set_catalog.rb +18 -27
- data/lib/rigor/inference/builtins/string_catalog.rb +12 -19
- data/lib/rigor/inference/builtins/struct_catalog.rb +18 -30
- data/lib/rigor/inference/builtins/time_catalog.rb +28 -44
- data/lib/rigor/inference/closure_escape_analyzer.rb +44 -67
- data/lib/rigor/inference/coverage_scanner.rb +13 -18
- data/lib/rigor/inference/def_return_typer.rb +8 -14
- data/lib/rigor/inference/dynamic_origin.rb +23 -20
- data/lib/rigor/inference/expression_typer.rb +774 -1152
- data/lib/rigor/inference/fallback.rb +8 -12
- data/lib/rigor/inference/fallback_tracer.rb +4 -10
- data/lib/rigor/inference/flow_tracer.rb +25 -36
- data/lib/rigor/inference/hkt_body.rb +45 -68
- data/lib/rigor/inference/hkt_body_parser.rb +33 -52
- data/lib/rigor/inference/hkt_reducer.rb +38 -59
- data/lib/rigor/inference/hkt_registry.rb +50 -76
- data/lib/rigor/inference/indexed_narrowing.rb +55 -81
- data/lib/rigor/inference/macro_block_self_type.rb +21 -34
- data/lib/rigor/inference/method_dispatcher/array_to_h_folding.rb +11 -18
- data/lib/rigor/inference/method_dispatcher/block_folding.rb +49 -83
- data/lib/rigor/inference/method_dispatcher/call_context.rb +16 -23
- data/lib/rigor/inference/method_dispatcher/cgi_folding.rb +13 -22
- data/lib/rigor/inference/method_dispatcher/constant_folding.rb +307 -454
- data/lib/rigor/inference/method_dispatcher/data_folding.rb +24 -34
- data/lib/rigor/inference/method_dispatcher/file_folding.rb +22 -37
- data/lib/rigor/inference/method_dispatcher/iterator_dispatch.rb +52 -81
- data/lib/rigor/inference/method_dispatcher/kernel_dispatch.rb +51 -78
- data/lib/rigor/inference/method_dispatcher/literal_string_folding.rb +60 -97
- data/lib/rigor/inference/method_dispatcher/math_folding.rb +23 -34
- data/lib/rigor/inference/method_dispatcher/member_shape_projection.rb +18 -26
- data/lib/rigor/inference/method_dispatcher/method_folding.rb +37 -71
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +114 -182
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +122 -193
- data/lib/rigor/inference/method_dispatcher/receiver_affinity.rb +15 -24
- data/lib/rigor/inference/method_dispatcher/reduce_folding.rb +64 -93
- data/lib/rigor/inference/method_dispatcher/regexp_folding.rb +31 -45
- data/lib/rigor/inference/method_dispatcher/set_folding.rb +6 -9
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +356 -511
- data/lib/rigor/inference/method_dispatcher/shellwords_folding.rb +22 -32
- data/lib/rigor/inference/method_dispatcher/singleton_folding.rb +15 -21
- data/lib/rigor/inference/method_dispatcher/struct_folding.rb +66 -82
- data/lib/rigor/inference/method_dispatcher/time_folding.rb +10 -15
- data/lib/rigor/inference/method_dispatcher/uri_folding.rb +9 -13
- data/lib/rigor/inference/method_dispatcher.rb +378 -524
- data/lib/rigor/inference/method_parameter_binder.rb +81 -114
- data/lib/rigor/inference/multi_target_binder.rb +51 -68
- data/lib/rigor/inference/mutation_widening.rb +115 -158
- data/lib/rigor/inference/narrowing.rb +509 -727
- data/lib/rigor/inference/origin_lookup.rb +38 -0
- data/lib/rigor/inference/parameter_inference_collector.rb +100 -100
- data/lib/rigor/inference/precision_scanner.rb +26 -35
- data/lib/rigor/inference/project_patched_methods.rb +20 -32
- data/lib/rigor/inference/project_patched_scanner.rb +23 -37
- data/lib/rigor/inference/protection_scanner.rb +16 -18
- data/lib/rigor/inference/rbs_type_translator.rb +49 -66
- data/lib/rigor/inference/scope_indexer.rb +473 -817
- data/lib/rigor/inference/statement_evaluator.rb +706 -1111
- data/lib/rigor/inference/struct_fold_safety.rb +34 -48
- data/lib/rigor/inference/synthetic_method.rb +9 -16
- data/lib/rigor/inference/synthetic_method_index.rb +20 -35
- data/lib/rigor/inference/synthetic_method_scanner.rb +63 -103
- data/lib/rigor/language_server/buffer_resolution.rb +6 -9
- data/lib/rigor/language_server/buffer_table.rb +11 -18
- data/lib/rigor/language_server/completion_provider.rb +69 -116
- data/lib/rigor/language_server/debouncer.rb +16 -25
- data/lib/rigor/language_server/diagnostic_publisher.rb +26 -40
- data/lib/rigor/language_server/document_symbol_provider.rb +14 -19
- data/lib/rigor/language_server/folding_range_provider.rb +11 -19
- data/lib/rigor/language_server/hover_provider.rb +8 -11
- data/lib/rigor/language_server/hover_renderer.rb +56 -93
- data/lib/rigor/language_server/loop.rb +14 -19
- data/lib/rigor/language_server/project_context.rb +46 -74
- data/lib/rigor/language_server/selection_range_provider.rb +9 -12
- data/lib/rigor/language_server/server.rb +55 -83
- data/lib/rigor/language_server/signature_help_provider.rb +29 -46
- data/lib/rigor/language_server/synchronized_writer.rb +4 -7
- data/lib/rigor/language_server/uri.rb +8 -13
- data/lib/rigor/language_server.rb +4 -6
- data/lib/rigor/mcp/loop.rb +2 -3
- data/lib/rigor/mcp/server.rb +4 -7
- data/lib/rigor/mcp.rb +3 -6
- data/lib/rigor/plugin/access_denied_error.rb +5 -8
- data/lib/rigor/plugin/additional_initializer.rb +21 -31
- data/lib/rigor/plugin/base.rb +335 -518
- data/lib/rigor/plugin/blueprint.rb +14 -23
- data/lib/rigor/plugin/box.rb +18 -29
- data/lib/rigor/plugin/fact_store.rb +16 -26
- data/lib/rigor/plugin/inflector.rb +37 -53
- data/lib/rigor/plugin/io_boundary.rb +33 -56
- data/lib/rigor/plugin/isolation.rb +42 -55
- data/lib/rigor/plugin/load_error.rb +10 -15
- data/lib/rigor/plugin/loader.rb +30 -49
- data/lib/rigor/plugin/macro/block_as_method.rb +20 -32
- data/lib/rigor/plugin/macro/heredoc_template.rb +35 -58
- data/lib/rigor/plugin/macro/nested_class_template.rb +22 -36
- data/lib/rigor/plugin/macro/trait_registry.rb +34 -51
- data/lib/rigor/plugin/macro.rb +10 -15
- data/lib/rigor/plugin/manifest.rb +85 -144
- data/lib/rigor/plugin/node_context.rb +14 -22
- data/lib/rigor/plugin/node_rule_walk.rb +49 -74
- data/lib/rigor/plugin/protocol_contract.rb +25 -39
- data/lib/rigor/plugin/registry.rb +132 -205
- data/lib/rigor/plugin/services.rb +21 -33
- data/lib/rigor/plugin/source_rbs_synthesis_reporter.rb +11 -19
- data/lib/rigor/plugin/trust_policy.rb +24 -38
- data/lib/rigor/plugin/type_node_resolver.rb +15 -24
- data/lib/rigor/protection/diagnostic_oracle.rb +11 -13
- data/lib/rigor/protection/mutation_scanner.rb +27 -35
- data/lib/rigor/protection/mutator.rb +50 -70
- data/lib/rigor/protection/test_suite_oracle.rb +20 -27
- data/lib/rigor/rbs_extended/conformance_checker.rb +48 -68
- data/lib/rigor/rbs_extended/hkt_directives.rb +28 -54
- data/lib/rigor/rbs_extended/reporter.rb +24 -40
- data/lib/rigor/rbs_extended.rb +107 -197
- data/lib/rigor/reflection.rb +68 -86
- data/lib/rigor/scope/discovery_index.rb +14 -19
- data/lib/rigor/scope.rb +255 -310
- data/lib/rigor/sig_gen/classification.rb +6 -10
- data/lib/rigor/sig_gen/generator.rb +197 -323
- data/lib/rigor/sig_gen/layout_index.rb +12 -20
- data/lib/rigor/sig_gen/method_candidate.rb +12 -17
- data/lib/rigor/sig_gen/observation_collector.rb +38 -70
- data/lib/rigor/sig_gen/observed_call.rb +13 -23
- data/lib/rigor/sig_gen/path_mapper.rb +17 -29
- data/lib/rigor/sig_gen/renderer.rb +7 -13
- data/lib/rigor/sig_gen/type_elaborator.rb +15 -28
- data/lib/rigor/sig_gen/write_result.rb +8 -16
- data/lib/rigor/sig_gen/writer.rb +95 -174
- data/lib/rigor/sig_gen.rb +3 -6
- data/lib/rigor/signature_path_audit.rb +24 -30
- data/lib/rigor/source/constant_path.rb +10 -14
- data/lib/rigor/source/literals.rb +31 -45
- data/lib/rigor/source/node_locator.rb +9 -11
- data/lib/rigor/source/node_walker.rb +9 -13
- data/lib/rigor/source.rb +3 -4
- data/lib/rigor/testing.rb +16 -20
- data/lib/rigor/triage/catalogue.rb +38 -62
- data/lib/rigor/triage.rb +31 -52
- data/lib/rigor/trinary.rb +9 -13
- data/lib/rigor/type/acceptance_router.rb +4 -6
- data/lib/rigor/type/accepts_result.rb +10 -14
- data/lib/rigor/type/app.rb +19 -27
- data/lib/rigor/type/bot.rb +4 -6
- data/lib/rigor/type/bound_method.rb +10 -15
- data/lib/rigor/type/combinator.rb +165 -257
- data/lib/rigor/type/constant.rb +23 -34
- data/lib/rigor/type/data_class.rb +10 -15
- data/lib/rigor/type/data_instance.rb +14 -20
- data/lib/rigor/type/difference.rb +21 -32
- data/lib/rigor/type/dynamic.rb +3 -5
- data/lib/rigor/type/hash_shape.rb +32 -18
- data/lib/rigor/type/integer_range.rb +11 -16
- data/lib/rigor/type/intersection.rb +27 -42
- data/lib/rigor/type/nominal.rb +10 -15
- data/lib/rigor/type/plain_lattice.rb +9 -13
- data/lib/rigor/type/refined.rb +67 -114
- data/lib/rigor/type/singleton.rb +4 -6
- data/lib/rigor/type/struct_class.rb +11 -16
- data/lib/rigor/type/struct_instance.rb +15 -21
- data/lib/rigor/type/tuple.rb +14 -19
- data/lib/rigor/type/union.rb +30 -42
- data/lib/rigor/type_node/generic.rb +14 -26
- data/lib/rigor/type_node/identifier.rb +12 -19
- data/lib/rigor/type_node.rb +3 -12
- data/lib/rigor/value_semantics.rb +16 -21
- data/lib/rigor/version.rb +1 -1
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/analyzer.rb +18 -30
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_discoverer.rb +16 -29
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_index.rb +12 -23
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +22 -39
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/analyzer.rb +26 -46
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_discoverer.rb +51 -87
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_index.rb +10 -17
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb +26 -39
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb +118 -176
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_discoverer.rb +30 -51
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_index.rb +57 -92
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +71 -108
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/analyzer.rb +13 -22
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_discoverer.rb +15 -25
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_index.rb +8 -13
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +16 -24
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/analyzer.rb +30 -47
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +79 -129
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_index.rb +36 -57
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_parser.rb +27 -41
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_table.rb +16 -24
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +148 -235
- data/plugins/rigor-activerecord/lib/rigor-activerecord.rb +3 -5
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/analyzer.rb +8 -14
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_discoverer.rb +9 -15
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_index.rb +4 -7
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +23 -41
- data/plugins/rigor-activestorage/lib/rigor-activestorage.rb +3 -5
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb +6 -10
- data/plugins/rigor-activesupport-core-ext/lib/rigor-activesupport-core-ext.rb +8 -11
- data/plugins/rigor-devise/lib/rigor/plugin/devise.rb +30 -45
- data/plugins/rigor-devise/lib/rigor-devise.rb +3 -5
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema/schema_scanner.rb +43 -69
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema.rb +26 -35
- data/plugins/rigor-dry-schema/lib/rigor-dry-schema.rb +3 -5
- data/plugins/rigor-dry-struct/lib/rigor/plugin/dry_struct.rb +30 -47
- data/plugins/rigor-dry-struct/lib/rigor-dry-struct.rb +3 -5
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types/alias_scanner.rb +67 -113
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types.rb +29 -46
- data/plugins/rigor-dry-types/lib/rigor-dry-types.rb +3 -5
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation/contract_scanner.rb +13 -20
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation.rb +14 -23
- data/plugins/rigor-dry-validation/lib/rigor-dry-validation.rb +2 -3
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/analyzer.rb +22 -37
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_discoverer.rb +28 -46
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_index.rb +13 -17
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot.rb +30 -47
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql/type_scanner.rb +52 -80
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql.rb +21 -31
- data/plugins/rigor-graphql/lib/rigor-graphql.rb +3 -5
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami/action_checker.rb +11 -17
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami.rb +20 -34
- data/plugins/rigor-mangrove/lib/rigor/plugin/mangrove.rb +45 -75
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest/assertion_analyzer.rb +22 -36
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest.rb +22 -41
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/analyzer.rb +17 -32
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_discoverer.rb +6 -12
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_index.rb +4 -8
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit.rb +17 -32
- data/plugins/rigor-rails/lib/rigor-rails.rb +11 -18
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/analyzer.rb +58 -92
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_index.rb +20 -34
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_loader.rb +20 -31
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n.rb +49 -82
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/analyzer.rb +55 -92
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/devise_routes.rb +51 -90
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/doorkeeper_routes.rb +17 -30
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_discoverer.rb +38 -70
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_table.rb +42 -74
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/routes_parser.rb +280 -497
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +54 -89
- data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb +32 -54
- data/plugins/rigor-rbs-inline/lib/rigor-rbs-inline.rb +8 -13
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/analyzer.rb +9 -16
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_scope_index.rb +24 -39
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_type_resolver.rb +13 -22
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +34 -56
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/scope_walker.rb +22 -42
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec.rb +43 -75
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails/have_http_status_analyzer.rb +27 -39
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails/http_status_codes.rb +14 -19
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails.rb +20 -34
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers/analyzer.rb +28 -47
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers.rb +21 -37
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/analyzer.rb +13 -22
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_discoverer.rb +18 -31
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_index.rb +6 -10
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb +14 -29
- data/plugins/rigor-sinatra/lib/rigor/plugin/sinatra.rb +23 -41
- data/plugins/rigor-sinatra/lib/rigor-sinatra.rb +3 -5
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/absurd_recognizer.rb +23 -38
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/assertion_recognizer.rb +57 -96
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog.rb +22 -35
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog_walker.rb +41 -69
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/method_signature.rb +6 -10
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sig_parser.rb +24 -41
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sigil_detector.rb +29 -50
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/type_translator.rb +55 -88
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +159 -262
- data/plugins/rigor-statesman/lib/rigor/plugin/statesman.rb +21 -29
- data/plugins/rigor-statesman/lib/rigor-statesman.rb +3 -5
- data/plugins/rigor-typescript-utility-types/lib/rigor/plugin/typescript_utility_types.rb +23 -37
- data/plugins/rigor-typescript-utility-types/lib/rigor-typescript-utility-types.rb +4 -6
- data/sig/rigor/scope.rbs +6 -0
- metadata +2 -1
|
@@ -5,14 +5,11 @@ require_relative "buffer_table"
|
|
|
5
5
|
|
|
6
6
|
module Rigor
|
|
7
7
|
module LanguageServer
|
|
8
|
-
# LSP server lifecycle state machine + JSON-RPC method dispatcher.
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
# `MethodNotFound` (-32601). Full v1 capability surface (document
|
|
14
|
-
# sync, publishDiagnostics, hover, completion, sig-help, folding,
|
|
15
|
-
# selection, and watched-file invalidation) is implemented.
|
|
8
|
+
# LSP server lifecycle state machine + JSON-RPC method dispatcher. State machine: `:uninitialized` →
|
|
9
|
+
# `:initialized` → `:shutdown` → `:exited`. {#dispatch} routes (method, params) to the matching handler and
|
|
10
|
+
# returns the response payload (`nil` for notifications); out-of-state requests return `InvalidRequest`
|
|
11
|
+
# (-32002) / `MethodNotFound` (-32601). Full v1 capability surface (document sync, publishDiagnostics,
|
|
12
|
+
# hover, completion, sig-help, folding, selection, and watched-file invalidation) is implemented.
|
|
16
13
|
class Server # rubocop:disable Metrics/ClassLength
|
|
17
14
|
# JSON-RPC error codes per LSP spec § "Response Message".
|
|
18
15
|
ERROR_PARSE_ERROR = -32_700
|
|
@@ -24,16 +21,13 @@ module Rigor
|
|
|
24
21
|
ERROR_SERVER_NOT_INITIALIZED = -32_002
|
|
25
22
|
ERROR_INVALID_REQUEST_AFTER_SHUTDOWN = -32_600
|
|
26
23
|
|
|
27
|
-
# `TextDocumentSyncKind::Full = 1`. Slice 10 (deferred)
|
|
28
|
-
# promotes to `Incremental = 2`.
|
|
24
|
+
# `TextDocumentSyncKind::Full = 1`. Slice 10 (deferred) promotes to `Incremental = 2`.
|
|
29
25
|
TEXT_DOCUMENT_SYNC_FULL = 1
|
|
30
26
|
|
|
31
|
-
# Methods callable BEFORE `initialize`. Per LSP spec § 3 only
|
|
32
|
-
# `
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
-
# (the conformance harness) round-trips even when the client
|
|
36
|
-
# skips real work.
|
|
27
|
+
# Methods callable BEFORE `initialize`. Per LSP spec § 3 only `initialize` and `exit` are allowed
|
|
28
|
+
# pre-initialization; every other request returns `ServerNotInitialized`. We also accept `shutdown` so a
|
|
29
|
+
# sequence like `initialize → shutdown → exit` (the conformance harness) round-trips even when the
|
|
30
|
+
# client skips real work.
|
|
37
31
|
PRE_INITIALIZE_METHODS = %w[initialize shutdown exit].freeze
|
|
38
32
|
|
|
39
33
|
attr_reader :state, :exit_code, :buffer_table, :publisher,
|
|
@@ -45,13 +39,11 @@ module Rigor
|
|
|
45
39
|
# resolves `textDocument/completion`. Nil → `MethodNotFound`.
|
|
46
40
|
# @param signature_help_provider [Rigor::LanguageServer::SignatureHelpProvider, nil]
|
|
47
41
|
# resolves `textDocument/signatureHelp`. Nil → `MethodNotFound`.
|
|
48
|
-
# @param project_context [Rigor::LanguageServer::ProjectContext, nil]
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
#
|
|
53
|
-
# nil means "no project context": each request rebuilds env
|
|
54
|
-
# from scratch (mainly for specs and backward compatibility).
|
|
42
|
+
# @param project_context [Rigor::LanguageServer::ProjectContext, nil] the per-session cache of
|
|
43
|
+
# `Environment` + `Cache::Store` the providers read on every request. When present,
|
|
44
|
+
# `workspace/didChangeWatchedFiles` and `workspace/didChangeConfiguration` invalidate the cache; nil
|
|
45
|
+
# means "no project context": each request rebuilds env from scratch (mainly for specs and backward
|
|
46
|
+
# compatibility).
|
|
55
47
|
def initialize(buffer_table: BufferTable.new, publisher: nil, # rubocop:disable Metrics/ParameterLists
|
|
56
48
|
hover_provider: nil, document_symbol_provider: nil,
|
|
57
49
|
completion_provider: nil, signature_help_provider: nil,
|
|
@@ -143,10 +135,9 @@ module Rigor
|
|
|
143
135
|
end
|
|
144
136
|
end
|
|
145
137
|
|
|
146
|
-
# Per LSP spec § "Server lifecycle / initialize": the server
|
|
147
|
-
#
|
|
148
|
-
#
|
|
149
|
-
# clients asking for unadvertised methods get `MethodNotFound`.
|
|
138
|
+
# Per LSP spec § "Server lifecycle / initialize": the server responds with its capabilities. Each later
|
|
139
|
+
# slice extends `advertised_capabilities` with the handler it wires; clients asking for unadvertised
|
|
140
|
+
# methods get `MethodNotFound`.
|
|
150
141
|
def handle_initialize(_params)
|
|
151
142
|
@state = :initialized
|
|
152
143
|
{
|
|
@@ -169,20 +160,17 @@ module Rigor
|
|
|
169
160
|
caps[:documentSymbolProvider] = true if @document_symbol_provider
|
|
170
161
|
if @completion_provider
|
|
171
162
|
caps[:completionProvider] = {
|
|
172
|
-
# `.` for method completion; `:` for constant-path
|
|
173
|
-
#
|
|
174
|
-
# by looking one character back when `:` triggers.
|
|
163
|
+
# `.` for method completion; `:` for constant-path completion (slice 6). The server detects which
|
|
164
|
+
# form by looking one character back when `:` triggers.
|
|
175
165
|
triggerCharacters: [".", ":"],
|
|
176
|
-
# v1 eager — full payload returned on first request.
|
|
177
|
-
#
|
|
178
|
-
# (Object descendants) become noticeable.
|
|
166
|
+
# v1 eager — full payload returned on first request. Resolve becomes relevant if large
|
|
167
|
+
# enumerations (Object descendants) become noticeable.
|
|
179
168
|
resolveProvider: false
|
|
180
169
|
}
|
|
181
170
|
end
|
|
182
171
|
if @signature_help_provider
|
|
183
172
|
caps[:signatureHelpProvider] = {
|
|
184
|
-
# `(` opens the argument list; `,` advances to the
|
|
185
|
-
# next argument. Editors retrigger on both.
|
|
173
|
+
# `(` opens the argument list; `,` advances to the next argument. Editors retrigger on both.
|
|
186
174
|
triggerCharacters: ["(", ","]
|
|
187
175
|
}
|
|
188
176
|
end
|
|
@@ -191,17 +179,15 @@ module Rigor
|
|
|
191
179
|
caps
|
|
192
180
|
end
|
|
193
181
|
|
|
194
|
-
# `initialized` is a notification — no response body. Slice 7
|
|
195
|
-
#
|
|
196
|
-
# if the client advertised the capability.
|
|
182
|
+
# `initialized` is a notification — no response body. Slice 7 will hook this to register
|
|
183
|
+
# `workspace/didChangeWatchedFiles` if the client advertised the capability.
|
|
197
184
|
def handle_initialized
|
|
198
185
|
nil
|
|
199
186
|
end
|
|
200
187
|
|
|
201
188
|
def handle_shutdown
|
|
202
189
|
@state = :shutdown
|
|
203
|
-
# Drop any in-flight debounced publishes so they don't
|
|
204
|
-
# fire after the client has stopped listening.
|
|
190
|
+
# Drop any in-flight debounced publishes so they don't fire after the client has stopped listening.
|
|
205
191
|
@publisher&.cancel_pending
|
|
206
192
|
nil
|
|
207
193
|
end
|
|
@@ -212,10 +198,9 @@ module Rigor
|
|
|
212
198
|
nil
|
|
213
199
|
end
|
|
214
200
|
|
|
215
|
-
# textDocument/didOpen notification. Per LSP spec § the
|
|
216
|
-
# `
|
|
217
|
-
#
|
|
218
|
-
# `publishDiagnostics` push when a publisher is wired.
|
|
201
|
+
# textDocument/didOpen notification. Per LSP spec § the `textDocument` payload carries `uri`,
|
|
202
|
+
# `languageId`, `version`, and the full initial `text`. Triggers a `publishDiagnostics` push when a
|
|
203
|
+
# publisher is wired.
|
|
219
204
|
def handle_did_open(params)
|
|
220
205
|
doc = params.fetch(:textDocument)
|
|
221
206
|
uri = doc.fetch(:uri)
|
|
@@ -228,12 +213,10 @@ module Rigor
|
|
|
228
213
|
nil
|
|
229
214
|
end
|
|
230
215
|
|
|
231
|
-
# textDocument/didChange under FULL sync. Each `contentChanges`
|
|
232
|
-
# entry
|
|
233
|
-
#
|
|
234
|
-
#
|
|
235
|
-
# `.last` defensively for clients that pad. Triggers
|
|
236
|
-
# `publishDiagnostics` afterwards.
|
|
216
|
+
# textDocument/didChange under FULL sync. Each `contentChanges` entry carries only `{ text: }`; the LAST
|
|
217
|
+
# entry is the new full document text. Per LSP spec § "FULL sync" the array MUST be exactly one entry in
|
|
218
|
+
# practice — we still take `.last` defensively for clients that pad. Triggers `publishDiagnostics`
|
|
219
|
+
# afterwards.
|
|
237
220
|
def handle_did_change(params)
|
|
238
221
|
doc = params.fetch(:textDocument)
|
|
239
222
|
changes = params.fetch(:contentChanges)
|
|
@@ -249,13 +232,10 @@ module Rigor
|
|
|
249
232
|
nil
|
|
250
233
|
end
|
|
251
234
|
|
|
252
|
-
# textDocument/hover REQUEST. Slice 5 returns either a
|
|
253
|
-
#
|
|
254
|
-
#
|
|
255
|
-
#
|
|
256
|
-
# spec; clients suppress the popup. Returns
|
|
257
|
-
# `MethodNotFound` when no hover_provider is wired (slice
|
|
258
|
-
# 1-4 behaviour).
|
|
235
|
+
# textDocument/hover REQUEST. Slice 5 returns either a `Hover` payload (markdown contents wrapping type
|
|
236
|
+
# + erased-RBS info) or nil when no expression is at the queried position. Nil maps to `result: null`
|
|
237
|
+
# per LSP spec; clients suppress the popup. Returns `MethodNotFound` when no hover_provider is wired
|
|
238
|
+
# (slice 1-4 behaviour).
|
|
259
239
|
def handle_hover(params)
|
|
260
240
|
return method_not_found("textDocument/hover") unless @hover_provider
|
|
261
241
|
|
|
@@ -268,29 +248,25 @@ module Rigor
|
|
|
268
248
|
)
|
|
269
249
|
end
|
|
270
250
|
|
|
271
|
-
# workspace/didChangeWatchedFiles NOTIFICATION. Invalidates
|
|
272
|
-
# the
|
|
273
|
-
#
|
|
274
|
-
#
|
|
275
|
-
# surgical invalidation (per design doc § "Project context
|
|
276
|
-
# refresh") is a follow-up; this is the LSP-correct floor.
|
|
251
|
+
# workspace/didChangeWatchedFiles NOTIFICATION. Invalidates the ProjectContext so cached pre-pass /
|
|
252
|
+
# Environment is rebuilt on the next request. Slice 7's floor: any watched file change triggers a full
|
|
253
|
+
# context rebuild. Per-file surgical invalidation (per design doc § "Project context refresh") is a
|
|
254
|
+
# follow-up; this is the LSP-correct floor.
|
|
277
255
|
def handle_did_change_watched_files(_params)
|
|
278
256
|
@project_context&.invalidate!
|
|
279
257
|
nil
|
|
280
258
|
end
|
|
281
259
|
|
|
282
|
-
# workspace/didChangeConfiguration NOTIFICATION. The payload
|
|
283
|
-
#
|
|
284
|
-
#
|
|
285
|
-
# external config changes (.rigor.yml / Gemfile.lock / etc).
|
|
260
|
+
# workspace/didChangeConfiguration NOTIFICATION. The payload shape is client-specific; v1 ignores the
|
|
261
|
+
# payload and invalidates the context so the next read picks up any external config changes
|
|
262
|
+
# (.rigor.yml / Gemfile.lock / etc).
|
|
286
263
|
def handle_did_change_configuration(_params)
|
|
287
264
|
@project_context&.invalidate!
|
|
288
265
|
nil
|
|
289
266
|
end
|
|
290
267
|
|
|
291
|
-
# textDocument/selectionRange REQUEST. Routes to the
|
|
292
|
-
#
|
|
293
|
-
# otherwise.
|
|
268
|
+
# textDocument/selectionRange REQUEST. Routes to the selection-range provider when wired;
|
|
269
|
+
# `MethodNotFound` otherwise.
|
|
294
270
|
def handle_selection_range(params)
|
|
295
271
|
return method_not_found("textDocument/selectionRange") unless @selection_range_provider
|
|
296
272
|
|
|
@@ -299,8 +275,7 @@ module Rigor
|
|
|
299
275
|
@selection_range_provider.provide(doc.fetch(:uri), positions)
|
|
300
276
|
end
|
|
301
277
|
|
|
302
|
-
# textDocument/foldingRange REQUEST. Routes to the
|
|
303
|
-
# folding-range provider when wired; `MethodNotFound`
|
|
278
|
+
# textDocument/foldingRange REQUEST. Routes to the folding-range provider when wired; `MethodNotFound`
|
|
304
279
|
# otherwise.
|
|
305
280
|
def handle_folding_range(params)
|
|
306
281
|
return method_not_found("textDocument/foldingRange") unless @folding_range_provider
|
|
@@ -309,8 +284,7 @@ module Rigor
|
|
|
309
284
|
@folding_range_provider.provide(doc.fetch(:uri))
|
|
310
285
|
end
|
|
311
286
|
|
|
312
|
-
# textDocument/signatureHelp REQUEST. Routes to the
|
|
313
|
-
# signature-help provider when wired; `MethodNotFound`
|
|
287
|
+
# textDocument/signatureHelp REQUEST. Routes to the signature-help provider when wired; `MethodNotFound`
|
|
314
288
|
# otherwise.
|
|
315
289
|
def handle_signature_help(params)
|
|
316
290
|
return method_not_found("textDocument/signatureHelp") unless @signature_help_provider
|
|
@@ -326,8 +300,8 @@ module Rigor
|
|
|
326
300
|
)
|
|
327
301
|
end
|
|
328
302
|
|
|
329
|
-
# textDocument/completion REQUEST. Routes to the completion
|
|
330
|
-
#
|
|
303
|
+
# textDocument/completion REQUEST. Routes to the completion provider when wired; `MethodNotFound`
|
|
304
|
+
# otherwise.
|
|
331
305
|
def handle_completion(params)
|
|
332
306
|
return method_not_found("textDocument/completion") unless @completion_provider
|
|
333
307
|
|
|
@@ -342,9 +316,8 @@ module Rigor
|
|
|
342
316
|
)
|
|
343
317
|
end
|
|
344
318
|
|
|
345
|
-
# textDocument/documentSymbol REQUEST. Returns the
|
|
346
|
-
# `
|
|
347
|
-
# URI. Returns `MethodNotFound` when no provider is wired.
|
|
319
|
+
# textDocument/documentSymbol REQUEST. Returns the `DocumentSymbol[]` outline for the buffer at the
|
|
320
|
+
# requested URI. Returns `MethodNotFound` when no provider is wired.
|
|
348
321
|
def handle_document_symbol(params)
|
|
349
322
|
return method_not_found("textDocument/documentSymbol") unless @document_symbol_provider
|
|
350
323
|
|
|
@@ -352,10 +325,9 @@ module Rigor
|
|
|
352
325
|
@document_symbol_provider.provide(doc.fetch(:uri))
|
|
353
326
|
end
|
|
354
327
|
|
|
355
|
-
# textDocument/didClose. Drops the buffer table entry AND
|
|
356
|
-
#
|
|
357
|
-
#
|
|
358
|
-
# way to indicate "no diagnostics remain for this URI".
|
|
328
|
+
# textDocument/didClose. Drops the buffer table entry AND publishes an empty diagnostic set so clients
|
|
329
|
+
# clear inline markers — per LSP spec § "publishDiagnostics" the standard way to indicate "no
|
|
330
|
+
# diagnostics remain for this URI".
|
|
359
331
|
def handle_did_close(params)
|
|
360
332
|
doc = params.fetch(:textDocument)
|
|
361
333
|
uri = doc.fetch(:uri)
|
|
@@ -19,22 +19,19 @@ require_relative "../type/hash_shape"
|
|
|
19
19
|
|
|
20
20
|
module Rigor
|
|
21
21
|
module LanguageServer
|
|
22
|
-
# Answers `textDocument/signatureHelp` requests. When the user
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
# inline. The provider parses the buffer, locates the enclosing
|
|
26
|
-
# `CallNode`, infers the receiver's type, and returns the
|
|
22
|
+
# Answers `textDocument/signatureHelp` requests. When the user types `(` inside a method call
|
|
23
|
+
# (`obj.foo(|`) editors fire `signatureHelp` to show the method's parameter signature inline. The provider
|
|
24
|
+
# parses the buffer, locates the enclosing `CallNode`, infers the receiver's type, and returns the
|
|
27
25
|
# method's first overload as a `SignatureInformation`.
|
|
28
26
|
#
|
|
29
27
|
# Slice C1 (this commit) ships:
|
|
30
|
-
# - Sentinel patching for `obj.foo(|` so Prism's parse
|
|
31
|
-
#
|
|
28
|
+
# - Sentinel patching for `obj.foo(|` so Prism's parse succeeds (mirrors `CompletionProvider`'s slice B4
|
|
29
|
+
# pattern).
|
|
32
30
|
# - First-overload signature only.
|
|
33
31
|
# - Active parameter = comma count before cursor.
|
|
34
32
|
#
|
|
35
|
-
# Multi-overload presentation + `documentation` field +
|
|
36
|
-
#
|
|
37
|
-
# slices (queued in the design doc § "Out of scope for v2").
|
|
33
|
+
# Multi-overload presentation + `documentation` field + active-parameter override per overload land in
|
|
34
|
+
# follow-up slices (queued in the design doc § "Out of scope for v2").
|
|
38
35
|
class SignatureHelpProvider
|
|
39
36
|
include BufferResolution
|
|
40
37
|
|
|
@@ -75,12 +72,10 @@ module Rigor
|
|
|
75
72
|
patch_with_arg_sentinel(original_bytes, line, character)
|
|
76
73
|
end
|
|
77
74
|
|
|
78
|
-
# Mid-edit buffer at `obj.foo(|` or `obj.foo(1,|`: truncate
|
|
79
|
-
#
|
|
80
|
-
#
|
|
81
|
-
#
|
|
82
|
-
# call's signature; downstream content (closing parens,
|
|
83
|
-
# subsequent statements) is irrelevant.
|
|
75
|
+
# Mid-edit buffer at `obj.foo(|` or `obj.foo(1,|`: truncate everything from the cursor onwards and append
|
|
76
|
+
# `SENTINEL)` so the call is syntactically complete. The truncation is aggressive — signatureHelp only
|
|
77
|
+
# cares about the enclosing call's signature; downstream content (closing parens, subsequent statements)
|
|
78
|
+
# is irrelevant.
|
|
84
79
|
def patch_with_arg_sentinel(original_bytes, line, character)
|
|
85
80
|
prefix_offset = byte_offset_for(original_bytes, line, character)
|
|
86
81
|
return [original_bytes, [line, character]] if prefix_offset.nil?
|
|
@@ -93,11 +88,9 @@ module Rigor
|
|
|
93
88
|
[patched, [line, character]]
|
|
94
89
|
end
|
|
95
90
|
|
|
96
|
-
# Walks the AST for the smallest CallNode whose `arguments`
|
|
97
|
-
#
|
|
98
|
-
#
|
|
99
|
-
# isn't enough; we re-walk. For LSP usage this is cheap —
|
|
100
|
-
# the buffer is parsed once per request.
|
|
91
|
+
# Walks the AST for the smallest CallNode whose `arguments` location encloses the cursor offset. Prism
|
|
92
|
+
# doesn't expose parent pointers, so NodeLocator's leaf-returning shape isn't enough; we re-walk. For
|
|
93
|
+
# LSP usage this is cheap — the buffer is parsed once per request.
|
|
101
94
|
def enclosing_call_for_offset(root, cursor_offset)
|
|
102
95
|
result = nil
|
|
103
96
|
walk = lambda do |n|
|
|
@@ -137,23 +130,18 @@ module Rigor
|
|
|
137
130
|
end
|
|
138
131
|
{
|
|
139
132
|
signatures: signatures,
|
|
140
|
-
# `activeSignature` is the index editors highlight by
|
|
141
|
-
#
|
|
142
|
-
# a future slice could choose the overload that best
|
|
143
|
-
# matches the current argument shape.
|
|
133
|
+
# `activeSignature` is the index editors highlight by default. Slice C2 picks the first overload
|
|
134
|
+
# uniformly; a future slice could choose the overload that best matches the current argument shape.
|
|
144
135
|
activeSignature: 0,
|
|
145
136
|
activeParameter: active_param
|
|
146
137
|
}
|
|
147
138
|
end
|
|
148
139
|
|
|
149
|
-
# Builds the LSP `ParameterInformation[]` for a method type's
|
|
150
|
-
#
|
|
151
|
-
# (
|
|
152
|
-
#
|
|
153
|
-
#
|
|
154
|
-
# index expectation: required positionals, then optionals,
|
|
155
|
-
# then rest, then trailing, then required keywords, then
|
|
156
|
-
# optional keywords, then rest keywords.
|
|
140
|
+
# Builds the LSP `ParameterInformation[]` for a method type's parameter list. Each entry's `label` is a
|
|
141
|
+
# STRING form (e.g. `"::int width"`, `"?::string pad_string"`); LSP's offset-tuple form
|
|
142
|
+
# (`[start, end]`) for in-signature highlighting is queued. Order matches `activeParameter`'s index
|
|
143
|
+
# expectation: required positionals, then optionals, then rest, then trailing, then required keywords,
|
|
144
|
+
# then optional keywords, then rest keywords.
|
|
157
145
|
def parameter_information(method_type) # rubocop:disable Metrics/AbcSize
|
|
158
146
|
func = method_type.type
|
|
159
147
|
return [] unless func.respond_to?(:required_positionals)
|
|
@@ -172,12 +160,9 @@ module Rigor
|
|
|
172
160
|
param.name ? "#{param.type} #{param.name}" : param.type.to_s
|
|
173
161
|
end
|
|
174
162
|
|
|
175
|
-
# Identical contract to HoverRenderer#rbs_documentation —
|
|
176
|
-
#
|
|
177
|
-
#
|
|
178
|
-
# call sites are small and the shape may diverge (signatureHelp
|
|
179
|
-
# might want per-parameter docs split out; hover wants the
|
|
180
|
-
# full paragraph).
|
|
163
|
+
# Identical contract to HoverRenderer#rbs_documentation — surfaces the method's RBS comment text or nil.
|
|
164
|
+
# Kept inline rather than extracted to a shared mixin because the two call sites are small and the shape
|
|
165
|
+
# may diverge (signatureHelp might want per-parameter docs split out; hover wants the full paragraph).
|
|
181
166
|
def rbs_documentation(definition)
|
|
182
167
|
comments = definition.respond_to?(:comments) ? definition.comments : nil
|
|
183
168
|
return nil if comments.nil? || comments.empty?
|
|
@@ -200,9 +185,8 @@ module Rigor
|
|
|
200
185
|
end
|
|
201
186
|
end
|
|
202
187
|
|
|
203
|
-
# Mirrors CompletionProvider's receiver-type mapping. Tuple →
|
|
204
|
-
#
|
|
205
|
-
# their base (handled in `lookup_method` above for clarity).
|
|
188
|
+
# Mirrors CompletionProvider's receiver-type mapping. Tuple → Array, HashShape → Hash, Refined /
|
|
189
|
+
# Difference unwrap to their base (handled in `lookup_method` above for clarity).
|
|
206
190
|
def nominal_class_name(type)
|
|
207
191
|
case type
|
|
208
192
|
when Type::Nominal then type.class_name
|
|
@@ -217,10 +201,9 @@ module Rigor
|
|
|
217
201
|
Inference::ScopeIndexer.index(root, default_scope: scope)
|
|
218
202
|
end
|
|
219
203
|
|
|
220
|
-
# Counts commas in the buffer between the call's opening `(`
|
|
221
|
-
#
|
|
222
|
-
#
|
|
223
|
-
# location so commas in nested expressions don't bleed in.
|
|
204
|
+
# Counts commas in the buffer between the call's opening `(` and the cursor position. Cursor on the
|
|
205
|
+
# first argument → 0; after one comma → 1; etc. Bounded by the call's arguments location so commas in
|
|
206
|
+
# nested expressions don't bleed in.
|
|
224
207
|
def active_parameter_index(call_node, bytes, line, character)
|
|
225
208
|
return 0 if call_node.arguments.nil?
|
|
226
209
|
|
|
@@ -2,14 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
module Rigor
|
|
4
4
|
module LanguageServer
|
|
5
|
-
# Wraps the LSP gem's `Io::Writer` with a Mutex so concurrent
|
|
6
|
-
#
|
|
7
|
-
# async `publishDiagnostics` writes) don't interleave on the
|
|
8
|
-
# shared STDOUT.
|
|
5
|
+
# Wraps the LSP gem's `Io::Writer` with a Mutex so concurrent writes (the dispatch loop's response writes +
|
|
6
|
+
# the Debouncer's async `publishDiagnostics` writes) don't interleave on the shared STDOUT.
|
|
9
7
|
#
|
|
10
|
-
# Pass-through proxy: `#write(message)` is the only call site
|
|
11
|
-
#
|
|
12
|
-
# completeness.
|
|
8
|
+
# Pass-through proxy: `#write(message)` is the only call site the rest of the LSP uses; `#close` is
|
|
9
|
+
# forwarded for completeness.
|
|
13
10
|
class SynchronizedWriter
|
|
14
11
|
def initialize(inner)
|
|
15
12
|
@inner = inner
|
|
@@ -2,15 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
module Rigor
|
|
4
4
|
module LanguageServer
|
|
5
|
-
# LSP DocumentUri ↔ filesystem path conversions. v1 supports
|
|
6
|
-
#
|
|
7
|
-
# nil from `#to_path` so the caller can short-circuit.
|
|
5
|
+
# LSP DocumentUri ↔ filesystem path conversions. v1 supports only `file://` URIs; other schemes (e.g.
|
|
6
|
+
# `untitled:`) return nil from `#to_path` so the caller can short-circuit.
|
|
8
7
|
#
|
|
9
|
-
# Windows drive-letter handling: `file:///C:/path` → `C:/path`.
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
# land when Windows CI is wired (see design doc § "Open
|
|
13
|
-
# questions").
|
|
8
|
+
# Windows drive-letter handling: `file:///C:/path` → `C:/path`. The leading slash after the scheme is
|
|
9
|
+
# dropped on Windows; on POSIX it stays. v1 ships POSIX behaviour; Windows specifics land when Windows CI is
|
|
10
|
+
# wired (see design doc § "Open questions").
|
|
14
11
|
module Uri
|
|
15
12
|
module_function
|
|
16
13
|
|
|
@@ -22,11 +19,9 @@ module Rigor
|
|
|
22
19
|
def to_path(uri)
|
|
23
20
|
return nil unless uri.is_a?(String) && uri.start_with?(FILE_SCHEME)
|
|
24
21
|
|
|
25
|
-
# Percent-decode at the BYTE level so multi-byte UTF-8
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
# we re-interpret as UTF-8. `delete_prefix` always returns
|
|
29
|
-
# a String (vs `byteslice` whose RBS return is `String?`).
|
|
22
|
+
# Percent-decode at the BYTE level so multi-byte UTF-8 escapes (`%E6%97%A5` → `日`) reassemble
|
|
23
|
+
# correctly. Each `%xx` decodes to one raw byte; the result is a byte string we re-interpret as UTF-8.
|
|
24
|
+
# `delete_prefix` always returns a String (vs `byteslice` whose RBS return is `String?`).
|
|
30
25
|
uri.delete_prefix(FILE_SCHEME).b
|
|
31
26
|
.gsub(/%([0-9A-Fa-f]{2})/) { ::Regexp.last_match(1).hex.chr }
|
|
32
27
|
.force_encoding(Encoding::UTF_8)
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Rigor
|
|
4
|
-
# The Language Server subsystem. See
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
# invalidation) is implemented. This module is the namespace and
|
|
9
|
-
# require entry point for the subsystem.
|
|
4
|
+
# The Language Server subsystem. See `docs/design/20260517-language-server.md` for the design. The full v1
|
|
5
|
+
# capability surface (document sync, publishDiagnostics, hover, completion, sig-help, folding, selection, and
|
|
6
|
+
# watched-file invalidation) is implemented. This module is the namespace and require entry point for the
|
|
7
|
+
# subsystem.
|
|
10
8
|
module LanguageServer
|
|
11
9
|
end
|
|
12
10
|
end
|
data/lib/rigor/mcp/loop.rb
CHANGED
|
@@ -4,9 +4,8 @@ require "json"
|
|
|
4
4
|
|
|
5
5
|
module Rigor
|
|
6
6
|
module MCP
|
|
7
|
-
# Reads newline-delimited JSON-RPC 2.0 messages from `input`,
|
|
8
|
-
#
|
|
9
|
-
# Runs until input reaches EOF (the client closes the connection).
|
|
7
|
+
# Reads newline-delimited JSON-RPC 2.0 messages from `input`, dispatches each to `server`, and writes responses to
|
|
8
|
+
# `output`. Runs until input reaches EOF (the client closes the connection).
|
|
10
9
|
class Loop
|
|
11
10
|
def initialize(input:, output:, server:)
|
|
12
11
|
@input = input
|
data/lib/rigor/mcp/server.rb
CHANGED
|
@@ -7,11 +7,9 @@ module Rigor
|
|
|
7
7
|
module MCP
|
|
8
8
|
# JSON-RPC 2.0 dispatcher for the MCP server.
|
|
9
9
|
#
|
|
10
|
-
# Each public `handle` call takes a parsed request hash and returns
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
# with StringIO capture — every tool stays in sync with its CLI
|
|
14
|
-
# counterpart automatically (ADR-33 WD4).
|
|
10
|
+
# Each public `handle` call takes a parsed request hash and returns a response hash (or nil for notifications that
|
|
11
|
+
# require no reply). Tool implementations delegate to `CLI.new(argv, out:, err:).run` with StringIO capture — every
|
|
12
|
+
# tool stays in sync with its CLI counterpart automatically (ADR-33 WD4).
|
|
15
13
|
class Server # rubocop:disable Metrics/ClassLength
|
|
16
14
|
PROTOCOL_VERSION = "2024-11-05"
|
|
17
15
|
|
|
@@ -142,8 +140,7 @@ module Rigor
|
|
|
142
140
|
@err = err
|
|
143
141
|
end
|
|
144
142
|
|
|
145
|
-
# Dispatches a parsed JSON-RPC request hash.
|
|
146
|
-
# Returns nil for notifications (requests without an `id`).
|
|
143
|
+
# Dispatches a parsed JSON-RPC request hash. Returns nil for notifications (requests without an `id`).
|
|
147
144
|
def handle(request)
|
|
148
145
|
id = request["id"]
|
|
149
146
|
method_name = request["method"]
|
data/lib/rigor/mcp.rb
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Rigor
|
|
4
|
-
# The MCP (Model Context Protocol) server subsystem.
|
|
5
|
-
# See `docs/adr/33-mcp-server.md` for the design.
|
|
4
|
+
# The MCP (Model Context Protocol) server subsystem. See `docs/adr/33-mcp-server.md` for the design.
|
|
6
5
|
#
|
|
7
|
-
# Entry point: `rigor mcp --transport stdio`.
|
|
8
|
-
#
|
|
9
|
-
# annotate, sig-gen, explain, coverage) as MCP tool calls over a
|
|
10
|
-
# newline-delimited JSON-RPC 2.0 stdio stream.
|
|
6
|
+
# Entry point: `rigor mcp --transport stdio`. The server exposes Rigor's analysis tools (check, type-of, triage,
|
|
7
|
+
# annotate, sig-gen, explain, coverage) as MCP tool calls over a newline-delimited JSON-RPC 2.0 stdio stream.
|
|
11
8
|
module MCP
|
|
12
9
|
end
|
|
13
10
|
end
|
|
@@ -2,15 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
module Rigor
|
|
4
4
|
module Plugin
|
|
5
|
-
# Raised when a plugin's I/O attempt fails the active
|
|
6
|
-
#
|
|
7
|
-
# can convert the exception into a `:plugin_loader` diagnostic
|
|
8
|
-
# without crashing `rigor check`.
|
|
5
|
+
# Raised when a plugin's I/O attempt fails the active {TrustPolicy}. Surfaced through {IoBoundary} so the
|
|
6
|
+
# analyzer can convert the exception into a `:plugin_loader` diagnostic without crashing `rigor check`.
|
|
9
7
|
#
|
|
10
|
-
# The policy is documented in [ADR-2 § "Plugin Trust and I/O
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
# as the two reason codes; future slices may extend the set.
|
|
8
|
+
# The policy is documented in [ADR-2 § "Plugin Trust and I/O Policy"](../../../docs/adr/2-extension-api.md).
|
|
9
|
+
# Slice 2's surface lists `:read_outside_scope` and `:network_disabled` as the two reason codes; future slices
|
|
10
|
+
# may extend the set.
|
|
14
11
|
class AccessDeniedError < StandardError
|
|
15
12
|
attr_reader :reason, :resource
|
|
16
13
|
|