From 1416e1d1e3f51c5c44dea3807796cbccccd870d3 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 28 Sep 2025 12:08:05 -0400 Subject: [PATCH 01/25] Reduce number of build jobs for faster CI feedback This takes out some lower value combinations - ideally we could keep the number of jobs to <= 20, which is the max that GHA will run simultaneously here. --- .github/workflows/rspec.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index ecc3d9771..33d09b579 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -23,12 +23,26 @@ jobs: matrix: ruby-version: ['3.0', '3.1', '3.2', '3.3', '3.4', 'head'] rbs-version: ['3.6.1', '3.9.4', '4.0.0.dev.4'] - # Ruby 3.0 doesn't work with RBS 3.9.4 or 4.0.0.dev.4 exclude: + # Ruby 3.0 doesn't work with RBS 3.9.4 or 4.0.0.dev.4 - ruby-version: '3.0' rbs-version: '3.9.4' - ruby-version: '3.0' rbs-version: '4.0.0.dev.4' + # only include the 3.1 variants we include later + - ruby-version: '3.1' + # only include the 3.2 variants we include later + - ruby-version: '3.2' + # only include the 3.3 variants we include later + - ruby-version: '3.3' + include: + - ruby-version: '3.1' + rbs_version: '3.6.1' + - ruby-version: '3.2' + rbs_version: '3.9.4' + - ruby-version: '3.3' + rbs_version: '4.0.0.dev.4' + steps: - uses: actions/checkout@v3 - name: Set up Ruby From f2abb735f39f7adb08d4a487dd4c6a1b76acbfd2 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 28 Sep 2025 12:10:38 -0400 Subject: [PATCH 02/25] Fix punctuation --- .github/workflows/rspec.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index 33d09b579..76003b412 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -37,12 +37,11 @@ jobs: - ruby-version: '3.3' include: - ruby-version: '3.1' - rbs_version: '3.6.1' + rbs-version: '3.6.1' - ruby-version: '3.2' - rbs_version: '3.9.4' + rbs-version: '3.9.4' - ruby-version: '3.3' - rbs_version: '4.0.0.dev.4' - + rbs-version: '4.0.0.dev.4' steps: - uses: actions/checkout@v3 - name: Set up Ruby From d486e6485d4cce9d182da079c588c3821c69cfa6 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 30 Sep 2025 22:36:37 -0400 Subject: [PATCH 03/25] Trim more matrix entries to make room for solargraph-rspec specs --- .github/workflows/rspec.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index 76003b412..628bbc8ab 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -35,6 +35,8 @@ jobs: - ruby-version: '3.2' # only include the 3.3 variants we include later - ruby-version: '3.3' + # only include the 3.4 variants we include later + - ruby-version: '3.3' include: - ruby-version: '3.1' rbs-version: '3.6.1' @@ -42,6 +44,8 @@ jobs: rbs-version: '3.9.4' - ruby-version: '3.3' rbs-version: '4.0.0.dev.4' + - ruby-version: '3.4' + rbs-version: '4.0.0.dev.4' steps: - uses: actions/checkout@v3 - name: Set up Ruby From 56342d4a9ff7c1141372404883cd2ddd1f337de7 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 30 Sep 2025 22:50:42 -0400 Subject: [PATCH 04/25] Fix version number --- .github/workflows/rspec.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index 628bbc8ab..cc4efda4b 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -36,7 +36,7 @@ jobs: # only include the 3.3 variants we include later - ruby-version: '3.3' # only include the 3.4 variants we include later - - ruby-version: '3.3' + - ruby-version: '3.4' include: - ruby-version: '3.1' rbs-version: '3.6.1' From 2b753e87d0ded080af7fa5c4afa7b22f6ff84e87 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Wed, 31 Dec 2025 16:47:28 -0500 Subject: [PATCH 05/25] Bump RBS versions in rspec test --- .github/workflows/rspec.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index 73edd47a3..db84786dd 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -21,8 +21,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - ruby-version: ['3.0', '3.1', '3.2', '3.3', '3.4', '4.0'] - rbs-version: ['3.6.1', '3.9.5', '4.0.0.dev.4'] + ruby-version: ['3.0', '3.1', '3.2', '3.3', '3.4', '4.0', 'head'] + rbs-version: ['3.6.1', '3.8.1', '3.9.5', '3.10.0', '4.0.0.dev.4'] # Ruby 3.0 doesn't work with RBS 3.9.4 or 4.0.0.dev.4 exclude: # Ruby 3.0 doesn't work with RBS 3.9.4 or 4.0.0.dev.4 @@ -42,16 +42,19 @@ jobs: # fixed in next RBS release - ruby-version: '4.0' rbs-version: '3.6.1' - - ruby-version: '4.0' + - ruby-version: 'head' + rbs-version: '3.6.1' include: - ruby-version: '3.1' rbs-version: '3.6.1' - ruby-version: '3.2' - rbs-version: '3.9.4' + rbs-version: '3.8.1' - ruby-version: '3.3' - rbs-version: '4.0.0.dev.4' + rbs-version: '3.8.5' - ruby-version: '3.4' - rbs-version: '4.0.0.dev.4' + rbs-version: '3.10.0' + - ruby-version: '3.4' + rbs-version: '4.0.0.dev' steps: - uses: actions/checkout@v3 - name: Set up Ruby From e182a53fe173d866e6d7ca4c256a5cdf7d774c55 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Wed, 31 Dec 2025 16:48:26 -0500 Subject: [PATCH 06/25] Fix version --- .github/workflows/rspec.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index db84786dd..95d721900 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -54,7 +54,7 @@ jobs: - ruby-version: '3.4' rbs-version: '3.10.0' - ruby-version: '3.4' - rbs-version: '4.0.0.dev' + rbs-version: '4.0.0.dev.4' steps: - uses: actions/checkout@v3 - name: Set up Ruby From 34cdf784ad06ae9688c04a65af12310859ebca5a Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Wed, 31 Dec 2025 16:50:37 -0500 Subject: [PATCH 07/25] Fix version matrix --- .github/workflows/rspec.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index 95d721900..406268714 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -25,9 +25,11 @@ jobs: rbs-version: ['3.6.1', '3.8.1', '3.9.5', '3.10.0', '4.0.0.dev.4'] # Ruby 3.0 doesn't work with RBS 3.9.4 or 4.0.0.dev.4 exclude: - # Ruby 3.0 doesn't work with RBS 3.9.4 or 4.0.0.dev.4 + # Ruby 3.0 doesn't work with RBS >=3.9 - ruby-version: '3.0' rbs-version: '3.9.5' + - ruby-version: '3.0' + rbs-version: '3.8.1' - ruby-version: '3.0' rbs-version: '4.0.0.dev.4' # only include the 3.1 variants we include later @@ -38,12 +40,10 @@ jobs: - ruby-version: '3.3' # only include the 3.4 variants we include later - ruby-version: '3.4' - # Missing require in 'rbs collection update' - hopefully - # fixed in next RBS release - - ruby-version: '4.0' - rbs-version: '3.6.1' - - ruby-version: 'head' - rbs-version: '3.6.1' + # - ruby-version: '4.0' + # rbs-version: '3.6.1' + # - ruby-version: 'head' + # rbs-version: '3.6.1' include: - ruby-version: '3.1' rbs-version: '3.6.1' From 851d142473fd362a04c0c3bca6aad97e3c06224e Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Wed, 31 Dec 2025 16:58:47 -0500 Subject: [PATCH 08/25] Fix version matrix --- .github/workflows/rspec.yml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index 406268714..7913bdabf 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -25,13 +25,8 @@ jobs: rbs-version: ['3.6.1', '3.8.1', '3.9.5', '3.10.0', '4.0.0.dev.4'] # Ruby 3.0 doesn't work with RBS 3.9.4 or 4.0.0.dev.4 exclude: - # Ruby 3.0 doesn't work with RBS >=3.9 - - ruby-version: '3.0' - rbs-version: '3.9.5' - - ruby-version: '3.0' - rbs-version: '3.8.1' - - ruby-version: '3.0' - rbs-version: '4.0.0.dev.4' + # only include the 3.0 variants we include later + - ruby-version: '3.1' # only include the 3.1 variants we include later - ruby-version: '3.1' # only include the 3.2 variants we include later @@ -40,11 +35,18 @@ jobs: - ruby-version: '3.3' # only include the 3.4 variants we include later - ruby-version: '3.4' + # only include the 4.0 variants we include later + - ruby-version: '4.0' + # Don't exclude 'head' - let's test all RBS versions we + # can there + # - ruby-version: '4.0' # rbs-version: '3.6.1' # - ruby-version: 'head' # rbs-version: '3.6.1' include: + - ruby-version: '3.0' + rbs-version: '3.6.1' - ruby-version: '3.1' rbs-version: '3.6.1' - ruby-version: '3.2' From e2d27c9dcaec14b90cd8f3e262dc8ca36d3a28c3 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Wed, 31 Dec 2025 16:59:50 -0500 Subject: [PATCH 09/25] Fix version matrix --- .github/workflows/rspec.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index 7913bdabf..94a714508 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -26,7 +26,7 @@ jobs: # Ruby 3.0 doesn't work with RBS 3.9.4 or 4.0.0.dev.4 exclude: # only include the 3.0 variants we include later - - ruby-version: '3.1' + - ruby-version: '3.0' # only include the 3.1 variants we include later - ruby-version: '3.1' # only include the 3.2 variants we include later From 8df808a8bf5cf3b13c3a46d41e4c1ff88286e122 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Wed, 31 Dec 2025 17:01:05 -0500 Subject: [PATCH 10/25] Fix version matrix --- .github/workflows/rspec.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index 94a714508..dcb726445 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -52,7 +52,7 @@ jobs: - ruby-version: '3.2' rbs-version: '3.8.1' - ruby-version: '3.3' - rbs-version: '3.8.5' + rbs-version: '3.9.5' - ruby-version: '3.4' rbs-version: '3.10.0' - ruby-version: '3.4' From 9974481a534d2e7c386121c01142c933f90c120b Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Wed, 31 Dec 2025 17:10:50 -0500 Subject: [PATCH 11/25] Fix version matrix --- .github/workflows/rspec.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index dcb726445..ced8df10d 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -40,10 +40,12 @@ jobs: # Don't exclude 'head' - let's test all RBS versions we # can there - # - ruby-version: '4.0' - # rbs-version: '3.6.1' - # - ruby-version: 'head' - # rbs-version: '3.6.1' + # For some reason 'rbs collection install' is broken in + # 4.0.0.dev.4 on newer Rubies: + # + # https://github.com/castwide/solargraph/actions/runs/20627923548/job/59241444380?pr=1102 + - ruby-version: 'head' + rbs-version: '4.0.0.dev.4' include: - ruby-version: '3.0' rbs-version: '3.6.1' From 56e25350a0bffe071172d3f563bf4935f6290e56 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Wed, 31 Dec 2025 17:22:43 -0500 Subject: [PATCH 12/25] Exclude another --- .github/workflows/rspec.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index ced8df10d..65eb8cac8 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -40,10 +40,9 @@ jobs: # Don't exclude 'head' - let's test all RBS versions we # can there - # For some reason 'rbs collection install' is broken in - # 4.0.0.dev.4 on newer Rubies: - # # https://github.com/castwide/solargraph/actions/runs/20627923548/job/59241444380?pr=1102 + - ruby-version: 'head' + rbs-version: '3.8.1' - ruby-version: 'head' rbs-version: '4.0.0.dev.4' include: From d9e49366f2de9f8093c3bd48eecb566ddc751af2 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Wed, 31 Dec 2025 17:29:22 -0500 Subject: [PATCH 13/25] Exclude another --- .github/workflows/rspec.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index 65eb8cac8..39475cc1d 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -41,6 +41,8 @@ jobs: # can there # https://github.com/castwide/solargraph/actions/runs/20627923548/job/59241444380?pr=1102 + - ruby-version: 'head' + rbs-version: '3.6.1' - ruby-version: 'head' rbs-version: '3.8.1' - ruby-version: 'head' From 751430271fbb5ac9b899923508200605171320b0 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Wed, 31 Dec 2025 17:52:29 -0500 Subject: [PATCH 14/25] Add version, fix doc --- .github/workflows/rspec.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index 39475cc1d..f761b61aa 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -38,8 +38,12 @@ jobs: # only include the 4.0 variants we include later - ruby-version: '4.0' # Don't exclude 'head' - let's test all RBS versions we - # can there - + # can there. + # + # + # Just exclude some odd-ball compatibility issues we can't + # work around: + # # https://github.com/castwide/solargraph/actions/runs/20627923548/job/59241444380?pr=1102 - ruby-version: 'head' rbs-version: '3.6.1' @@ -56,6 +60,8 @@ jobs: rbs-version: '3.8.1' - ruby-version: '3.3' rbs-version: '3.9.5' + - ruby-version: '3.3' + rbs-version: '3.10.0' - ruby-version: '3.4' rbs-version: '3.10.0' - ruby-version: '3.4' From 977b18355a293deb5677e73303cdb02e11530534 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Thu, 1 Jan 2026 20:03:51 -0500 Subject: [PATCH 15/25] Improve signature combination Use our generated RBS signature from parameters as a key to combine method signatures from RBS/YARD pins. This is closer to what RBS does than the current technique of using the arity alone, and fixes a key degenerate case in Integer#+ revealed by updated definitions used by recently released RBS gems --- lib/solargraph/doc_map.rb | 2 +- lib/solargraph/parser/parser_gem/class_methods.rb | 1 + lib/solargraph/parser/parser_gem/node_methods.rb | 1 - lib/solargraph/pin/callable.rb | 7 ++++++- lib/solargraph/pin/method.rb | 14 +++++++------- spec/pin/method_spec.rb | 10 ++++++++++ 6 files changed, 25 insertions(+), 10 deletions(-) diff --git a/lib/solargraph/doc_map.rb b/lib/solargraph/doc_map.rb index e45ff0b65..136c02078 100644 --- a/lib/solargraph/doc_map.rb +++ b/lib/solargraph/doc_map.rb @@ -346,7 +346,7 @@ def gemspec_or_preference gemspec end # @param gemspec [Gem::Specification] - # @param version [Gem::Version] + # @param version [Gem::Version, String] # @return [Gem::Specification] def change_gemspec_version gemspec, version Gem::Specification.find_by_name(gemspec.name, "= #{version}") diff --git a/lib/solargraph/parser/parser_gem/class_methods.rb b/lib/solargraph/parser/parser_gem/class_methods.rb index 2daf22fc7..c8fc186c8 100644 --- a/lib/solargraph/parser/parser_gem/class_methods.rb +++ b/lib/solargraph/parser/parser_gem/class_methods.rb @@ -19,6 +19,7 @@ def parse_with_comments code, filename = nil # @param filename [String, nil] # @param line [Integer] # @return [Parser::AST::Node] + # @sg-ignore Need to handle type of 'raise' def parse code, filename = nil, line = 0 buffer = ::Parser::Source::Buffer.new(filename, line) buffer.source = code diff --git a/lib/solargraph/parser/parser_gem/node_methods.rb b/lib/solargraph/parser/parser_gem/node_methods.rb index b77c4cd47..02f790c00 100644 --- a/lib/solargraph/parser/parser_gem/node_methods.rb +++ b/lib/solargraph/parser/parser_gem/node_methods.rb @@ -119,7 +119,6 @@ def convert_hash node result end - # @sg-ignore Wrong argument type for AST::Node.new: type expected AST::_ToSym, received :nil NIL_NODE = ::Parser::AST::Node.new(:nil) # @param node [Parser::AST::Node] diff --git a/lib/solargraph/pin/callable.rb b/lib/solargraph/pin/callable.rb index edbc3f941..bfce92c24 100644 --- a/lib/solargraph/pin/callable.rb +++ b/lib/solargraph/pin/callable.rb @@ -215,8 +215,13 @@ def mandatory_positional_param_count parameters.count(&:arg?) end + # @return [String] + def parameters_to_rbs + rbs_generics + '(' + parameters.map { |param| param.to_rbs }.join(', ') + ') ' + (block.nil? ? '' : '{ ' + block.to_rbs + ' } ') + end + def to_rbs - rbs_generics + '(' + parameters.map { |param| param.to_rbs }.join(', ') + ') ' + (block.nil? ? '' : '{ ' + block.to_rbs + ' } ') + '-> ' + return_type.to_rbs + parameters_to_rbs + '-> ' + return_type.to_rbs end def block? diff --git a/lib/solargraph/pin/method.rb b/lib/solargraph/pin/method.rb index 86bf1cd09..30afb8f48 100644 --- a/lib/solargraph/pin/method.rb +++ b/lib/solargraph/pin/method.rb @@ -37,21 +37,21 @@ def initialize visibility: :public, explicit: true, block: :undefined, node: nil # @param signature_pins [Array] # @return [Array] def combine_all_signature_pins(*signature_pins) - # @type [Hash{Array => Array}] - by_arity = {} + # @type [Hash{String => Array}] + by_rbs = {} signature_pins.each do |signature_pin| - by_arity[signature_pin.arity] ||= [] - by_arity[signature_pin.arity] << signature_pin + by_rbs[signature_pin.parameters_to_rbs] ||= [] + by_rbs[signature_pin.parameters_to_rbs] << signature_pin end - by_arity.transform_values! do |same_arity_pins| + by_rbs.transform_values! do |same_rbs_pins| # @param memo [Pin::Signature, nil] # @param signature [Pin::Signature] - same_arity_pins.reduce(nil) do |memo, signature| + same_rbs_pins.reduce(nil) do |memo, signature| next signature if memo.nil? memo.combine_with(signature) end end - by_arity.values.flatten + by_rbs.values.flatten end # @param other [Pin::Method] diff --git a/spec/pin/method_spec.rb b/spec/pin/method_spec.rb index 283ef6d51..c2ef40448 100644 --- a/spec/pin/method_spec.rb +++ b/spec/pin/method_spec.rb @@ -549,6 +549,16 @@ class Foo expect(pin.return_type).to be_undefined end + it 'combines signatures by type' do + # Integer+ in RBS is a number of signatures that dispatch based + # on type. Let's make sure we combine those with anything else + # found (e.g., additions from the BigDecimal RBS collection) + # without collapsing signatures + api_map = Solargraph::ApiMap.load_with_cache(Dir.pwd, nil) + method = api_map.get_method_stack('Integer', '+', scope: :instance).first + expect(method.signatures.count).to be > 3 + end + it 'infers untagged types from instance variables' do source = Solargraph::Source.load_string(%( class Foo From 81927c837dd9e5fbc367647b7afca61c22abe812 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Thu, 1 Jan 2026 20:22:14 -0500 Subject: [PATCH 16/25] Drop annotation --- lib/solargraph/parser/parser_gem/class_methods.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/solargraph/parser/parser_gem/class_methods.rb b/lib/solargraph/parser/parser_gem/class_methods.rb index c8fc186c8..2daf22fc7 100644 --- a/lib/solargraph/parser/parser_gem/class_methods.rb +++ b/lib/solargraph/parser/parser_gem/class_methods.rb @@ -19,7 +19,6 @@ def parse_with_comments code, filename = nil # @param filename [String, nil] # @param line [Integer] # @return [Parser::AST::Node] - # @sg-ignore Need to handle type of 'raise' def parse code, filename = nil, line = 0 buffer = ::Parser::Source::Buffer.new(filename, line) buffer.source = code From 1b931447c424f8597491f7d3ccb76aa3e2944333 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Thu, 1 Jan 2026 20:24:01 -0500 Subject: [PATCH 17/25] Fix RuboCop issue --- lib/solargraph/workspace.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/solargraph/workspace.rb b/lib/solargraph/workspace.rb index 06980e6d0..156855a1b 100644 --- a/lib/solargraph/workspace.rb +++ b/lib/solargraph/workspace.rb @@ -70,10 +70,10 @@ def merge *sources includes_any = false sources.each do |source| - if directory == "*" || config.calculated.include?(source.filename) - source_hash[source.filename] = source - includes_any = true - end + next unless directory == "*" || config.calculated.include?(source.filename) + + source_hash[source.filename] = source + includes_any = true end includes_any From 40a915f62c0d2a0c885ace0981ab02003bdb789e Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 3 Jan 2026 10:36:09 -0500 Subject: [PATCH 18/25] Use "type arity" to guide signature combination --- lib/solargraph/pin/callable.rb | 18 +++++- lib/solargraph/pin/method.rb | 99 ++++++++++++++++++++++----------- lib/solargraph/pin/parameter.rb | 5 ++ 3 files changed, 87 insertions(+), 35 deletions(-) diff --git a/lib/solargraph/pin/callable.rb b/lib/solargraph/pin/callable.rb index bfce92c24..ed1c2d7c9 100644 --- a/lib/solargraph/pin/callable.rb +++ b/lib/solargraph/pin/callable.rb @@ -89,11 +89,25 @@ def blockless_parameters end end - # @return [Array] + # e.g., [["T"], "", "?", "foo:"] - parameter arity declarations, + # ignoring positional names. Used to match signatures. + # + # @return [Array, String>] def arity [generics, blockless_parameters.map(&:arity_decl), block&.arity] end + # e.g., [["T"], "1", "?3", "foo:5"] - parameter arity + # declarations, including the number of unique types in each + # parameter. Used to determine whether combining two + # signatures has lost useful information mapping specific + # parameter types to specific return types. + # + # @return [Array, String>] + def type_arity + [generics, blockless_parameters.map(&:type_arity_decl), block&.arity] + end + # @param generics_to_resolve [Enumerable] # @param arg_types [Array, nil] # @param return_type_context [ComplexType, nil] @@ -101,6 +115,7 @@ def arity # @param yield_return_type_context [ComplexType, nil] # @param context [ComplexType, nil] # @param resolved_generic_values [Hash{String => ComplexType}] + # # @return [self] def resolve_generics_from_context(generics_to_resolve, arg_types = nil, @@ -150,6 +165,7 @@ def method_name # @param yield_return_type_context [ComplexType, nil] # @param context [ComplexType, nil] # @param resolved_generic_values [Hash{String => ComplexType}] + # # @return [self] def resolve_generics_from_context_until_complete(generics_to_resolve, arg_types = nil, diff --git a/lib/solargraph/pin/method.rb b/lib/solargraph/pin/method.rb index 30afb8f48..a60b455d3 100644 --- a/lib/solargraph/pin/method.rb +++ b/lib/solargraph/pin/method.rb @@ -34,26 +34,6 @@ def initialize visibility: :public, explicit: true, block: :undefined, node: nil @anon_splat = anon_splat end - # @param signature_pins [Array] - # @return [Array] - def combine_all_signature_pins(*signature_pins) - # @type [Hash{String => Array}] - by_rbs = {} - signature_pins.each do |signature_pin| - by_rbs[signature_pin.parameters_to_rbs] ||= [] - by_rbs[signature_pin.parameters_to_rbs] << signature_pin - end - by_rbs.transform_values! do |same_rbs_pins| - # @param memo [Pin::Signature, nil] - # @param signature [Pin::Signature] - same_rbs_pins.reduce(nil) do |memo, signature| - next signature if memo.nil? - memo.combine_with(signature) - end - end - by_rbs.values.flatten - end - # @param other [Pin::Method] # @return [::Symbol] def combine_visibility(other) @@ -66,20 +46,6 @@ def combine_visibility(other) end end - # @param other [Pin::Method] - # @return [Array] - def combine_signatures(other) - all_undefined = signatures.all? { |sig| sig.return_type.undefined? } - other_all_undefined = other.signatures.all? { |sig| sig.return_type.undefined? } - if all_undefined && !other_all_undefined - other.signatures - elsif other_all_undefined && !all_undefined - signatures - else - combine_all_signature_pins(*signatures, *other.signatures) - end - end - def combine_with(other, attrs = {}) priority_choice = choose_priority(other) return priority_choice unless priority_choice.nil? @@ -485,6 +451,71 @@ def dodgy_visibility_source? private + # @param other [Pin::Method] + # @return [Array] + def combine_signatures(other) + all_undefined = signatures.all? { |sig| !sig.return_type&.defined? } + other_all_undefined = other.signatures.all? { |sig| !sig.return_type&.defined? } + if all_undefined && !other_all_undefined + other.signatures + elsif other_all_undefined && !all_undefined + signatures + else + combine_signatures_by_type_arity(*signatures, *other.signatures) + end + end + + # @param signature_pins [Array] + # + # @return [Array] + def combine_signatures_by_type_arity(*signature_pins) + # @type [Hash{Array => Array}] + by_type_arity = {} + signature_pins.each do |signature_pin| + by_type_arity[signature_pin.type_arity] ||= [] + by_type_arity[signature_pin.type_arity] << signature_pin + end + + by_type_arity.transform_values! do |same_type_arity_signatures| + combine_same_type_arity_signatures same_type_arity_signatures + end + by_type_arity.values.flatten + end + + # @param same_type_arity_signatures [Array] + # + # @return [Array] + def combine_same_type_arity_signatures(same_type_arity_signatures) + # This is an O(n^2) operation, so bail out if n is not small + return same_type_arity_signatures if same_type_arity_signatures.length > 10 + + # @param old_signatures [Array] + # @param new_signature [Pin::Signature] + same_type_arity_signatures.reduce([]) do |old_signatures, new_signature| + next [new_signature] if old_signatures.empty? + + found_merge = false + old_signatures.flat_map do |old_signature| + potential_new_signature = old_signature.combine_with(new_signature) + + if potential_new_signature.type_arity == old_signature.type_arity + # the number of types in each parameter and return type + # match, so we found compatible signatures to merge. If + # we increased the number of types, we'd potentially + # have taken away the ability to use parameter types to + # choose the correct return type (while Ruby doesn't + # dispatch based on type, RBS does distinguish overloads + # based on types, not just arity, allowing for type + # information describing how methods behave based on + # their input types) + old_signatures - [old_signature] + [potential_new_signature] + else + old_signatures + [new_signature] + end + end + end + end + # @param name [String] # @param asgn [Boolean] # diff --git a/lib/solargraph/pin/parameter.rb b/lib/solargraph/pin/parameter.rb index 91c205921..ebcf7727f 100644 --- a/lib/solargraph/pin/parameter.rb +++ b/lib/solargraph/pin/parameter.rb @@ -72,6 +72,11 @@ def arity_decl end end + # @return [String] + def type_arity_decl + arity_decl + return_type.items.count.to_s + end + def arg? decl == :arg end From 11bf98728e3e4a6e8456521ef074cd47a8ee7ae2 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 3 Jan 2026 10:41:42 -0500 Subject: [PATCH 19/25] Update rubocop todo --- .rubocop_todo.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 962ac9bb6..f811c2102 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -468,6 +468,7 @@ Metrics/ClassLength: Exclude: - 'lib/solargraph/api_map.rb' - 'lib/solargraph/language_server/host.rb' + - 'lib/solargraph/pin/method.rb' - 'lib/solargraph/rbs_map/conversions.rb' - 'lib/solargraph/type_checker.rb' @@ -1175,7 +1176,6 @@ Style/StringLiterals: # This cop supports safe autocorrection (--autocorrect). Style/SuperArguments: Exclude: - - 'lib/solargraph/pin/base_variable.rb' - 'lib/solargraph/pin/callable.rb' - 'lib/solargraph/pin/method.rb' - 'lib/solargraph/pin/signature.rb' From 72131e89c0cdccdb2470107f6fa0c42037294f75 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 3 Jan 2026 11:02:40 -0500 Subject: [PATCH 20/25] Include return type arity in comparison --- lib/solargraph/pin/callable.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/solargraph/pin/callable.rb b/lib/solargraph/pin/callable.rb index ed1c2d7c9..de5869073 100644 --- a/lib/solargraph/pin/callable.rb +++ b/lib/solargraph/pin/callable.rb @@ -103,9 +103,16 @@ def arity # signatures has lost useful information mapping specific # parameter types to specific return types. # - # @return [Array, String>] + # @return [Array] def type_arity - [generics, blockless_parameters.map(&:type_arity_decl), block&.arity] + [generics, blockless_parameters.map(&:type_arity_decl), block&.type_arity] + end + + # Same as type_arity, but includes return type arity at the front. + # + # @return [Array] + def full_type_arity + [return_type&.items.count.to_s] + type_arity end # @param generics_to_resolve [Enumerable] From 334f4e06f86a814a5587a2abf62d54bc678dbb79 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 3 Jan 2026 11:46:36 -0500 Subject: [PATCH 21/25] Add dodgy return type --- lib/solargraph/pin/base.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/solargraph/pin/base.rb b/lib/solargraph/pin/base.rb index 57d083453..3f9d95331 100644 --- a/lib/solargraph/pin/base.rb +++ b/lib/solargraph/pin/base.rb @@ -205,7 +205,9 @@ def combine_return_type(other) def dodgy_return_type_source? # uses a lot of 'Object' instead of 'self' - location&.filename&.include?('core_ext/object/') + location&.filename&.include?('core_ext/object/') || + # ditto + location&.filename&.include?('stdlib/date/0/date.rbs') end # when choices are arbitrary, make sure the choice is consistent From a2e59646a079dcafb6d54f493b61ccdfa232cc50 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 3 Jan 2026 17:00:35 -0500 Subject: [PATCH 22/25] Fix RuboCop issue --- lib/solargraph/pin/callable.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/solargraph/pin/callable.rb b/lib/solargraph/pin/callable.rb index de5869073..8f247205c 100644 --- a/lib/solargraph/pin/callable.rb +++ b/lib/solargraph/pin/callable.rb @@ -112,7 +112,7 @@ def type_arity # # @return [Array] def full_type_arity - [return_type&.items.count.to_s] + type_arity + [return_type ? return_type.items.count.to_s : nil] + type_arity end # @param generics_to_resolve [Enumerable] From 0ac3cb444c962beea001daca71f64ab07650a681 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 4 Jan 2026 12:08:44 -0500 Subject: [PATCH 23/25] Add Ruby 4.0 jobs --- .github/workflows/rspec.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index f761b61aa..b9848b7ab 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -35,8 +35,6 @@ jobs: - ruby-version: '3.3' # only include the 3.4 variants we include later - ruby-version: '3.4' - # only include the 4.0 variants we include later - - ruby-version: '4.0' # Don't exclude 'head' - let's test all RBS versions we # can there. # @@ -64,8 +62,6 @@ jobs: rbs-version: '3.10.0' - ruby-version: '3.4' rbs-version: '3.10.0' - - ruby-version: '3.4' - rbs-version: '4.0.0.dev.4' steps: - uses: actions/checkout@v3 - name: Set up Ruby From 3e3e4d9ea08b46da2c050c43376384ff52777dd0 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 4 Jan 2026 12:56:49 -0500 Subject: [PATCH 24/25] Exclude another combo --- .github/workflows/rspec.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index b9848b7ab..a5af74830 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -43,6 +43,8 @@ jobs: # work around: # # https://github.com/castwide/solargraph/actions/runs/20627923548/job/59241444380?pr=1102 + - ruby-version: '4.0' + rbs-version: '4.0.0.dev.4' - ruby-version: 'head' rbs-version: '3.6.1' - ruby-version: 'head' From c7eefc29b1a4768049ea59c521c147a7288ec42f Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 4 Jan 2026 13:06:09 -0500 Subject: [PATCH 25/25] Exclude another combo --- .github/workflows/rspec.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index a5af74830..25ab551b2 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -35,6 +35,8 @@ jobs: - ruby-version: '3.3' # only include the 3.4 variants we include later - ruby-version: '3.4' + # only include the 4.0 variants we include later + - ruby-version: '4.0' # Don't exclude 'head' - let's test all RBS versions we # can there. # @@ -43,8 +45,6 @@ jobs: # work around: # # https://github.com/castwide/solargraph/actions/runs/20627923548/job/59241444380?pr=1102 - - ruby-version: '4.0' - rbs-version: '4.0.0.dev.4' - ruby-version: 'head' rbs-version: '3.6.1' - ruby-version: 'head' @@ -63,6 +63,8 @@ jobs: - ruby-version: '3.3' rbs-version: '3.10.0' - ruby-version: '3.4' + rbs-version: '4.0.0.dev.4' + - ruby-version: '4.0' rbs-version: '3.10.0' steps: - uses: actions/checkout@v3