From df1334b7ff02bfaa637ba2fe180c3a8ea966f6da Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 6 May 2025 12:39:50 -0400 Subject: [PATCH 001/106] Enable strict type checking in CI --- .github/workflows/typecheck.yml | 2 +- Rakefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml index 5b1b5e151..8f9119592 100644 --- a/.github/workflows/typecheck.yml +++ b/.github/workflows/typecheck.yml @@ -31,4 +31,4 @@ jobs: - name: Install gems run: bundle install - name: Typecheck self - run: bundle exec solargraph typecheck --level typed + run: bundle exec solargraph typecheck --level strict diff --git a/Rakefile b/Rakefile index 33b91bfa4..a7fea9b13 100755 --- a/Rakefile +++ b/Rakefile @@ -15,7 +15,7 @@ end desc "Run the type checker" task :typecheck do - sh "bundle exec solargraph typecheck --level typed" + sh "bundle exec solargraph typecheck --level strict" end desc "Run all tests" From 8b1107501abeb326df1f8fecf3030f8f4b632b9e Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 13 Jul 2025 12:44:19 -0400 Subject: [PATCH 002/106] Add 'solargraph method_pin' command for debugging ```sh $ SOLARGRAPH_ASSERTS=on bundle exec solargraph method_pin --rbs 'RuboCop::AST::ArrayNode#values' def values: () -> Array $ bundle exec solargraph help method_pin Usage: solargraph method_pin [PATH] Options: [--rbs], [--no-rbs], [--skip-rbs] # Output the pin as RBS # Default: false [--typify], [--no-typify], [--skip-typify] # Output the calculated return type of the pin from annotations # Default: false [--probe], [--no-probe], [--skip-probe] # Output the calculated return type of the pin from annotations and inference # Default: false [--stack], [--no-stack], [--skip-stack] # Show entire stack by including definitions in superclasses # Default: false Describe a method pin $ ``` --- lib/solargraph/shell.rb | 48 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/lib/solargraph/shell.rb b/lib/solargraph/shell.rb index 8f02f6ec9..938c31a11 100755 --- a/lib/solargraph/shell.rb +++ b/lib/solargraph/shell.rb @@ -239,6 +239,54 @@ def list puts "#{workspace.filenames.length} files total." end + desc 'method_pin [PATH]', 'Describe a method pin' + option :rbs, type: :boolean, desc: 'Output the pin as RBS', default: false + option :typify, type: :boolean, desc: 'Output the calculated return type of the pin from annotations', default: false + option :probe, type: :boolean, desc: 'Output the calculated return type of the pin from annotations and inference', default: false + option :stack, type: :boolean, desc: 'Show entire stack by including definitions in superclasses', default: false + # @param path [String] The path to the method pin, e.g. 'Class#method' or 'Class.method' + # @return [void] + def method_pin path + api_map = Solargraph::ApiMap.load_with_cache('.', STDERR) + + pins = if options[:stack] + scope, ns, meth = if path.include? '#' + [:instance, *path.split('#', 2)] + else + [:class, *path.split('.', 2)] + end + api_map.get_method_stack(ns, meth, scope: scope) + else + api_map.get_path_pins path + end + if pins.empty? + STDERR.puts "Pin not found for path '#{path}'" + exit 1 + end + pins.each do |pin| + if options[:typify] || options[:probe] + type = ComplexType::UNDEFINED + if options[:typify] + type = pin.typify(api_map) + end + if options[:probe] && type.undefined? + type = pin.probe(api_map) + end + if options[:rbs] + puts type.to_rbs + else + puts type.rooted_tag + end + else + if options[:rbs] + puts pin.to_rbs + else + puts pin.inspect + end + end + end + end + private # @param pin [Solargraph::Pin::Base] From bf612959ec8b43b888dac18b4ee6823af5e6ffc5 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Mon, 14 Jul 2025 07:27:58 -0400 Subject: [PATCH 003/106] RuboCop and Solargraph fixes --- lib/solargraph/shell.rb | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/lib/solargraph/shell.rb b/lib/solargraph/shell.rb index 938c31a11..153e77f0e 100755 --- a/lib/solargraph/shell.rb +++ b/lib/solargraph/shell.rb @@ -272,18 +272,11 @@ def method_pin path if options[:probe] && type.undefined? type = pin.probe(api_map) end - if options[:rbs] - puts type.to_rbs - else - puts type.rooted_tag - end - else - if options[:rbs] - puts pin.to_rbs - else - puts pin.inspect - end + print_type(type) + next end + + print_pin(pin) end end @@ -312,5 +305,25 @@ def do_cache gemspec, api_map # typecheck doesn't complain on the below line api_map.cache_gem(gemspec, rebuild: options.rebuild, out: $stdout) end + + # @param type [ComplexType] + # @return [void] + def print_type(type) + if options[:rbs] + puts type.to_rbs + else + puts type.rooted_tag + end + end + + # @param pin [Solargraph::Pin::Base] + # @return [void] + def print_pin(pin) + if options[:rbs] + puts pin.to_rbs + else + puts pin.inspect + end + end end end From fdd3810f34eeaa81e4bbac956d9e8372da1c5c6c Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 3 Aug 2025 21:07:30 -0400 Subject: [PATCH 004/106] Linting fix --- lib/solargraph/shell.rb | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/solargraph/shell.rb b/lib/solargraph/shell.rb index 153e77f0e..92f8fed38 100755 --- a/lib/solargraph/shell.rb +++ b/lib/solargraph/shell.rb @@ -266,12 +266,8 @@ def method_pin path pins.each do |pin| if options[:typify] || options[:probe] type = ComplexType::UNDEFINED - if options[:typify] - type = pin.typify(api_map) - end - if options[:probe] && type.undefined? - type = pin.probe(api_map) - end + type = pin.typify(api_map) if options[:typify] + type = pin.probe(api_map) if options[:probe] && type.undefined? print_type(type) next end From 30cdfc8b3091ff327c15d06eddb1c96315b2464c Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 3 Aug 2025 21:38:42 -0400 Subject: [PATCH 005/106] Add spec --- spec/shell_spec.rb | 114 ++++++++++++++++++++++++++++++++++++++++++++ spec/spec_helper.rb | 27 +++++++++++ 2 files changed, 141 insertions(+) create mode 100644 spec/shell_spec.rb diff --git a/spec/shell_spec.rb b/spec/shell_spec.rb new file mode 100644 index 000000000..1da2a98a9 --- /dev/null +++ b/spec/shell_spec.rb @@ -0,0 +1,114 @@ +# frozen_string_literal: true + +require 'tmpdir' +require 'open3' + +describe Solargraph::Shell do + let(:shell) { described_class.new } + + # @type cmd [Array] + # @return [String] + def bundle_exec(*cmd) + # run the command in the temporary directory with bundle exec + Bundler.with_unbundled_env do + output, status = Open3.capture2e("bundle exec #{cmd.join(' ')}") + expect(status.success?).to be(true), "Command failed: #{output}" + output + end + end + + describe 'method_pin' do + let(:api_map) { instance_double(Solargraph::ApiMap) } + let(:to_s_pin) { instance_double(Solargraph::Pin::Method, return_type: Solargraph::ComplexType.parse('String')) } + + before do + allow(Solargraph::ApiMap).to receive(:load_with_cache).and_return(api_map) + allow(api_map).to receive(:get_path_pins).with('String#to_s').and_return([to_s_pin]) + end + + context 'with no options' do + it 'prints a pin' do + allow(to_s_pin).to receive(:inspect).and_return('pin inspect result') + + out = capture_both { shell.method_pin('String#to_s') } + + expect(out).to eq("pin inspect result\n") + end + end + + context 'with --rbs option' do + it 'prints a pin with RBS type' do + allow(to_s_pin).to receive(:to_rbs).and_return('pin RBS result') + + out = capture_both do + shell.options = { rbs: true } + shell.method_pin('String#to_s') + end + expect(out).to eq("pin RBS result\n") + end + end + + context 'with --stack option' do + it 'prints a pin using stack results' do + allow(to_s_pin).to receive(:to_rbs).and_return('pin RBS result') + + allow(api_map).to receive(:get_method_stack).and_return([to_s_pin]) + capture_both do + shell.options = { stack: true } + shell.method_pin('String#to_s') + end + expect(api_map).to have_received(:get_method_stack).with('String', 'to_s', scope: :instance) + end + + it 'prints a static pin using stack results' do + # allow(to_s_pin).to receive(:to_rbs).and_return('pin RBS result') + string_new_pin = instance_double(Solargraph::Pin::Method, return_type: Solargraph::ComplexType.parse('String')) + + allow(api_map).to receive(:get_method_stack).with('String', 'new', scope: :class).and_return([string_new_pin]) + capture_both do + shell.options = { stack: true } + shell.method_pin('String.new') + end + expect(api_map).to have_received(:get_method_stack).with('String', 'new', scope: :class) + end + end + + context 'with --typify option' do + it 'prints a pin with typify type' do + allow(to_s_pin).to receive(:typify).and_return(Solargraph::ComplexType.parse('::String')) + + out = capture_both do + shell.options = { typify: true } + shell.method_pin('String#to_s') + end + expect(out).to eq("::String\n") + end + end + + context 'with --typify --rbs options' do + it 'prints a pin with typify type' do + allow(to_s_pin).to receive(:typify).and_return(Solargraph::ComplexType.parse('::String')) + + out = capture_both do + shell.options = { typify: true, rbs: true } + shell.method_pin('String#to_s') + end + expect(out).to eq("::String\n") + end + end + + context 'with no pin' do + it 'prints error' do + allow(api_map).to receive(:get_path_pins).with('Not#found').and_return([]) + + out = capture_both do + shell.options = {} + shell.method_pin('Not#found') + rescue SystemExit + # Ignore the SystemExit raised by the shell when no pin is found + end + expect(out).to include("Pin not found for path 'Not#found'") + end + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index faba8172e..b69e64097 100755 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -19,3 +19,30 @@ def with_env_var(name, value) ENV[name] = old_value # Restore the old value end end + + +def capture_stdout &block + original_stdout = $stdout + $stdout = StringIO.new + begin + block.call + $stdout.string + ensure + $stdout = original_stdout + end +end + +def capture_both &block + original_stdout = $stdout + original_stderr = $stderr + stringio = StringIO.new + $stdout = stringio + $stderr = stringio + begin + block.call + ensure + $stdout = original_stdout + $stderr = original_stderr + end + stringio.string +end From a30d7904818b16a1a88eafbe9977b9e8598f534d Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 3 Aug 2025 21:53:24 -0400 Subject: [PATCH 006/106] Fix spec --- lib/solargraph/shell.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/solargraph/shell.rb b/lib/solargraph/shell.rb index 92f8fed38..76f711552 100755 --- a/lib/solargraph/shell.rb +++ b/lib/solargraph/shell.rb @@ -247,7 +247,7 @@ def list # @param path [String] The path to the method pin, e.g. 'Class#method' or 'Class.method' # @return [void] def method_pin path - api_map = Solargraph::ApiMap.load_with_cache('.', STDERR) + api_map = Solargraph::ApiMap.load_with_cache('.', $stderr) pins = if options[:stack] scope, ns, meth = if path.include? '#' @@ -260,7 +260,7 @@ def method_pin path api_map.get_path_pins path end if pins.empty? - STDERR.puts "Pin not found for path '#{path}'" + $stderr.puts "Pin not found for path '#{path}'" exit 1 end pins.each do |pin| From e4afaada19c69de9dfc574ae3bcfc66880a44be9 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 19 Aug 2025 08:21:34 -0400 Subject: [PATCH 007/106] Allow newer RBS gem versions, exclude incompatible ones (#995) * Allow newer RBS gem versions This allow users to upgrade to recent Tapioca versions. Tapioca now requires newish versions of the spoom gem, which depends on 4.x pre-releases of the rbs gem. * Add RBS version to test matrix * Add exclude rule * Move to 3.6.1 --- .github/workflows/rspec.yml | 10 +++++++++- solargraph.gemspec | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index 94ef5771c..35f7a1d13 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -22,7 +22,13 @@ jobs: strategy: 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-version: '3.0' + rbs-version: '3.9.4' + - ruby-version: '3.0' + rbs-version: '4.0.0.dev.4' steps: - uses: actions/checkout@v3 - name: Set up Ruby @@ -30,6 +36,8 @@ jobs: with: ruby-version: ${{ matrix.ruby-version }} bundler-cache: false + - name: Set rbs version + run: echo "gem 'rbs', '${{ matrix.rbs-version }}'" >> .Gemfile # /home/runner/.rubies/ruby-head/lib/ruby/gems/3.5.0+2/gems/rbs-3.9.4/lib/rbs.rb:11: # warning: tsort was loaded from the standard library, # but will no longer be part of the default gems diff --git a/solargraph.gemspec b/solargraph.gemspec index e4d30c537..e6bb9394a 100755 --- a/solargraph.gemspec +++ b/solargraph.gemspec @@ -35,7 +35,7 @@ Gem::Specification.new do |s| s.add_runtime_dependency 'ostruct', '~> 0.6' s.add_runtime_dependency 'parser', '~> 3.0' s.add_runtime_dependency 'prism', '~> 1.4' - s.add_runtime_dependency 'rbs', '~> 3.6.1' + s.add_runtime_dependency 'rbs', ['>= 3.6.1', '<= 4.0.0.dev.4'] s.add_runtime_dependency 'reverse_markdown', '~> 3.0' s.add_runtime_dependency 'rubocop', '~> 1.76' s.add_runtime_dependency 'thor', '~> 1.0' From a0a78785c23a2fa2f65865192fab961ee8a9a751 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 19 Aug 2025 08:55:48 -0400 Subject: [PATCH 008/106] Look for external requires before cataloging bench (#1021) * Look for external requires before cataloging bench It seems like sync_catalog will go through the motions but not actually load pins from gems here due to passing an empty requires array to ApiMap. I'm sure those requires get pulled in eventually, but we go through at least one catalog cycle without it happening. Found while trying to test a different issue but not being able to get completions from a gem in a spec. * Ensure backport is pre-cached --- lib/solargraph/library.rb | 2 +- spec/library_spec.rb | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/solargraph/library.rb b/lib/solargraph/library.rb index 0316a01b0..9eb171879 100644 --- a/lib/solargraph/library.rb +++ b/lib/solargraph/library.rb @@ -680,8 +680,8 @@ def sync_catalog mutex.synchronize do logger.info "Cataloging #{workspace.directory.empty? ? 'generic workspace' : workspace.directory}" - api_map.catalog bench source_map_hash.values.each { |map| find_external_requires(map) } + api_map.catalog bench logger.info "Catalog complete (#{api_map.source_maps.length} files, #{api_map.pins.length} pins)" logger.info "#{api_map.uncached_yard_gemspecs.length} uncached YARD gemspecs" logger.info "#{api_map.uncached_rbs_collection_gemspecs.length} uncached RBS collection gemspecs" diff --git a/spec/library_spec.rb b/spec/library_spec.rb index bd7cc25a0..bea0f2983 100644 --- a/spec/library_spec.rb +++ b/spec/library_spec.rb @@ -26,6 +26,28 @@ expect(completion.pins.map(&:name)).to include('x') end + context 'with a require from an already-cached external gem' do + before do + Solargraph::Shell.new.gems('backport') + end + + it "returns a Completion" do + library = Solargraph::Library.new(Solargraph::Workspace.new(Dir.pwd, + Solargraph::Workspace::Config.new)) + library.attach Solargraph::Source.load_string(%( + require 'backport' + + # @param adapter [Backport::Adapter] + def foo(adapter) + adapter.remo + end + ), 'file.rb', 0) + completion = library.completions_at('file.rb', 5, 19) + expect(completion).to be_a(Solargraph::SourceMap::Completion) + expect(completion.pins.map(&:name)).to include('remote') + end + end + it "gets definitions from a file" do library = Solargraph::Library.new src = Solargraph::Source.load_string %( From 0e86b883ee16ac764ed41f24e424a85954137736 Mon Sep 17 00:00:00 2001 From: Fred Snyder Date: Tue, 19 Aug 2025 10:01:27 -0400 Subject: [PATCH 009/106] Remove Library#folding_ranges (#904) --- lib/solargraph/library.rb | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/lib/solargraph/library.rb b/lib/solargraph/library.rb index 9eb171879..72224f672 100644 --- a/lib/solargraph/library.rb +++ b/lib/solargraph/library.rb @@ -437,17 +437,6 @@ def bench ) end - # Get an array of foldable ranges for the specified file. - # - # @deprecated The library should not need to handle folding ranges. The - # source itself has all the information it needs. - # - # @param filename [String] - # @return [Array] - def folding_ranges filename - read(filename).folding_ranges - end - # Create a library from a directory. # # @param directory [String] The path to be used for the workspace From c90f01684972682abfbd21da124f3d6c7b37f9a1 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 19 Aug 2025 10:29:27 -0400 Subject: [PATCH 010/106] Complain in strong type-checking if an @sg-ignore line is not needed (#1011) * Complain in strong type-checking if an @sg-ignore line is not needed * Fix return type * Fix spec * Linting/coverage fixes * Coverage fix --- lib/solargraph/api_map.rb | 3 - lib/solargraph/complex_type.rb | 1 - lib/solargraph/complex_type/unique_type.rb | 4 -- lib/solargraph/parser/comment_ripper.rb | 2 +- .../parser/flow_sensitive_typing.rb | 2 - .../parser/parser_gem/class_methods.rb | 2 +- lib/solargraph/pin/base.rb | 2 - lib/solargraph/pin/base_variable.rb | 1 - lib/solargraph/pin/method.rb | 1 - lib/solargraph/source.rb | 3 +- lib/solargraph/source/cursor.rb | 1 - lib/solargraph/type_checker.rb | 64 +++++++++++++++---- lib/solargraph/type_checker/rules.rb | 8 +++ lib/solargraph/workspace/config.rb | 2 - spec/type_checker/levels/strong_spec.rb | 11 ++++ 15 files changed, 75 insertions(+), 32 deletions(-) diff --git a/lib/solargraph/api_map.rb b/lib/solargraph/api_map.rb index 9db37a166..eed02b4ef 100755 --- a/lib/solargraph/api_map.rb +++ b/lib/solargraph/api_map.rb @@ -211,9 +211,6 @@ class << self # any missing gems. # # - # @todo IO::NULL is incorrectly inferred to be a String. - # @sg-ignore - # # @param directory [String] # @param out [IO] The output stream for messages # @return [ApiMap] diff --git a/lib/solargraph/complex_type.rb b/lib/solargraph/complex_type.rb index 9e23eb502..ac9599329 100644 --- a/lib/solargraph/complex_type.rb +++ b/lib/solargraph/complex_type.rb @@ -299,7 +299,6 @@ class << self # # @todo Need ability to use a literal true as a type below # # @param partial [Boolean] True if the string is part of a another type # # @return [Array] - # @sg-ignore # @todo To be able to select the right signature above, # Chain::Call needs to know the decl type (:arg, :optarg, # :kwarg, etc) of the arguments given, instead of just having diff --git a/lib/solargraph/complex_type/unique_type.rb b/lib/solargraph/complex_type/unique_type.rb index 0f4ec430d..63a6ae15b 100644 --- a/lib/solargraph/complex_type/unique_type.rb +++ b/lib/solargraph/complex_type/unique_type.rb @@ -49,11 +49,7 @@ def self.parse name, substring = '', make_rooted: nil parameters_type = PARAMETERS_TYPE_BY_STARTING_TAG.fetch(substring[0]) if parameters_type == :hash raise ComplexTypeError, "Bad hash type: name=#{name}, substring=#{substring}" unless !subs.is_a?(ComplexType) and subs.length == 2 and !subs[0].is_a?(UniqueType) and !subs[1].is_a?(UniqueType) - # @todo should be able to resolve map; both types have it - # with same return type - # @sg-ignore key_types.concat(subs[0].map { |u| ComplexType.new([u]) }) - # @sg-ignore subtypes.concat(subs[1].map { |u| ComplexType.new([u]) }) elsif parameters_type == :list && name == 'Hash' # Treat Hash as Hash{A => B} diff --git a/lib/solargraph/parser/comment_ripper.rb b/lib/solargraph/parser/comment_ripper.rb index 62a4dacc5..e74fcb259 100644 --- a/lib/solargraph/parser/comment_ripper.rb +++ b/lib/solargraph/parser/comment_ripper.rb @@ -51,7 +51,7 @@ def on_embdoc_end *args result end - # @return [Hash{Integer => String}] + # @return [Hash{Integer => Solargraph::Parser::Snippet}] def parse @comments = {} super diff --git a/lib/solargraph/parser/flow_sensitive_typing.rb b/lib/solargraph/parser/flow_sensitive_typing.rb index 58f149d73..308db214b 100644 --- a/lib/solargraph/parser/flow_sensitive_typing.rb +++ b/lib/solargraph/parser/flow_sensitive_typing.rb @@ -236,8 +236,6 @@ def type_name(node) "#{module_type_name}::#{class_node}" end - # @todo "return type could not be inferred" should not trigger here - # @sg-ignore # @param clause_node [Parser::AST::Node] def always_breaks?(clause_node) clause_node&.type == :break diff --git a/lib/solargraph/parser/parser_gem/class_methods.rb b/lib/solargraph/parser/parser_gem/class_methods.rb index 58ca8056b..ddc742bd8 100644 --- a/lib/solargraph/parser/parser_gem/class_methods.rb +++ b/lib/solargraph/parser/parser_gem/class_methods.rb @@ -17,7 +17,7 @@ module ParserGem module ClassMethods # @param code [String] # @param filename [String, nil] - # @return [Array(Parser::AST::Node, Hash{Integer => String})] + # @return [Array(Parser::AST::Node, Hash{Integer => Solargraph::Parser::Snippet})] def parse_with_comments code, filename = nil node = parse(code, filename) comments = CommentRipper.new(code, filename, 0).parse diff --git a/lib/solargraph/pin/base.rb b/lib/solargraph/pin/base.rb index 6ac2cac52..fb3274dab 100644 --- a/lib/solargraph/pin/base.rb +++ b/lib/solargraph/pin/base.rb @@ -129,7 +129,6 @@ def choose_longer(other, attr) val2 = other.send(attr) return val1 if val1 == val2 return val2 if val1.nil? - # @sg-ignore val1.length > val2.length ? val1 : val2 end @@ -268,7 +267,6 @@ def assert_same_array_content(other, attr, &block) raise "Expected #{attr} on #{other} to be an Enumerable, got #{arr2.class}" unless arr2.is_a?(::Enumerable) # @type arr2 [::Enumerable] - # @sg-ignore # @type [undefined] values1 = arr1.map(&block) # @type [undefined] diff --git a/lib/solargraph/pin/base_variable.rb b/lib/solargraph/pin/base_variable.rb index cef3f44cb..764c1fb39 100644 --- a/lib/solargraph/pin/base_variable.rb +++ b/lib/solargraph/pin/base_variable.rb @@ -43,7 +43,6 @@ def return_type @return_type ||= generate_complex_type end - # @sg-ignore def nil_assignment? # this will always be false - should it be return_type == # ComplexType::NIL or somesuch? diff --git a/lib/solargraph/pin/method.rb b/lib/solargraph/pin/method.rb index 6302a940a..6309cb55a 100644 --- a/lib/solargraph/pin/method.rb +++ b/lib/solargraph/pin/method.rb @@ -305,7 +305,6 @@ def typify api_map super end - # @sg-ignore def documentation if @documentation.nil? method_docs ||= super || '' diff --git a/lib/solargraph/source.rb b/lib/solargraph/source.rb index 11ab215ed..d2b24cc61 100644 --- a/lib/solargraph/source.rb +++ b/lib/solargraph/source.rb @@ -30,7 +30,7 @@ def node @node end - # @return [Hash{Integer => Array}] + # @return [Hash{Integer => Solargraph::Parser::Snippet}] def comments finalize @comments @@ -235,6 +235,7 @@ def synchronized? # @return [Hash{Integer => String}] def associated_comments @associated_comments ||= begin + # @type [Hash{Integer => String}] result = {} buffer = String.new('') # @type [Integer, nil] diff --git a/lib/solargraph/source/cursor.rb b/lib/solargraph/source/cursor.rb index 0b95bb9bd..70e4fd47a 100644 --- a/lib/solargraph/source/cursor.rb +++ b/lib/solargraph/source/cursor.rb @@ -35,7 +35,6 @@ def word # The part of the word before the current position. Given the text # `foo.bar`, the start_of_word at position(0, 6) is `ba`. # - # @sg-ignore Improve resolution of String#match below # @return [String] def start_of_word @start_of_word ||= begin diff --git a/lib/solargraph/type_checker.rb b/lib/solargraph/type_checker.rb index aa215f97b..e99f99195 100644 --- a/lib/solargraph/type_checker.rb +++ b/lib/solargraph/type_checker.rb @@ -38,15 +38,20 @@ def source_map @source_map ||= api_map.source_map(filename) end + # @return [Source] + def source + @source_map.source + end + # @return [Array] def problems @problems ||= begin - without_ignored( - method_tag_problems - .concat variable_type_tag_problems - .concat const_problems - .concat call_problems - ) + all = method_tag_problems + .concat(variable_type_tag_problems) + .concat(const_problems) + .concat(call_problems) + unignored = without_ignored(all) + unignored.concat(unneeded_sgignore_problems) end end @@ -140,7 +145,7 @@ def resolved_constant? pin # @param pin [Pin::Base] def virtual_pin? pin - pin.location && source_map.source.comment_at?(pin.location.range.ending) + pin.location && source.comment_at?(pin.location.range.ending) end # @param pin [Pin::Method] @@ -231,7 +236,7 @@ def all_variables def const_problems return [] unless rules.validate_consts? result = [] - Solargraph::Parser::NodeMethods.const_nodes_from(source_map.source.node).each do |const| + Solargraph::Parser::NodeMethods.const_nodes_from(source.node).each do |const| rng = Solargraph::Range.from_node(const) chain = Solargraph::Parser.chain(const, filename) block_pin = source_map.locate_block_pin(rng.start.line, rng.start.column) @@ -249,7 +254,7 @@ def const_problems # @return [Array] def call_problems result = [] - Solargraph::Parser::NodeMethods.call_nodes_from(source_map.source.node).each do |call| + Solargraph::Parser::NodeMethods.call_nodes_from(source.node).each do |call| rng = Solargraph::Range.from_node(call) next if @marked_ranges.any? { |d| d.contain?(rng.start) } chain = Solargraph::Parser.chain(call, filename) @@ -646,7 +651,6 @@ def parameterized_arity_problems_for(pin, parameters, arguments, location) # @param parameters [Enumerable] # @todo need to use generic types in method to choose correct # signature and generate Integer as return type - # @sg-ignore # @return [Integer] def required_param_count(parameters) parameters.sum { |param| %i[arg kwarg].include?(param.decl) ? 1 : 0 } @@ -687,12 +691,48 @@ def fake_args_for(pin) args end + # @return [Set] + def sg_ignore_lines_processed + @sg_ignore_lines_processed ||= Set.new + end + + # @return [Set] + def all_sg_ignore_lines + source.associated_comments.select do |_line, text| + text.include?('@sg-ignore') + end.keys.to_set + end + + # @return [Array] + def unprocessed_sg_ignore_lines + (all_sg_ignore_lines - sg_ignore_lines_processed).to_a.sort + end + + # @return [Array] + def unneeded_sgignore_problems + return [] unless rules.validate_sg_ignores? + + unprocessed_sg_ignore_lines.map do |line| + Problem.new( + Location.new(filename, Range.from_to(line, 0, line, 0)), + 'Unneeded @sg-ignore comment' + ) + end + end + # @param problems [Array] # @return [Array] def without_ignored problems problems.reject do |problem| - node = source_map.source.node_at(problem.location.range.start.line, problem.location.range.start.column) - node && source_map.source.comments_for(node)&.include?('@sg-ignore') + node = source.node_at(problem.location.range.start.line, problem.location.range.start.column) + ignored = node && source.comments_for(node)&.include?('@sg-ignore') + unless !ignored || all_sg_ignore_lines.include?(problem.location.range.start.line) + # :nocov: + Solargraph.assert_or_log(:sg_ignore) { "@sg-ignore accounting issue - node is #{node}" } + # :nocov: + end + sg_ignore_lines_processed.add problem.location.range.start.line if ignored + ignored end end end diff --git a/lib/solargraph/type_checker/rules.rb b/lib/solargraph/type_checker/rules.rb index 0aad5ed8a..8f15037d5 100644 --- a/lib/solargraph/type_checker/rules.rb +++ b/lib/solargraph/type_checker/rules.rb @@ -57,6 +57,14 @@ def validate_tags? def require_all_return_types_match_inferred? rank >= LEVELS[:alpha] end + + # We keep this at strong because if you added an @sg-ignore to + # address a strong-level issue, then ran at a lower level, you'd + # get a false positive - we don't run stronger level checks than + # requested for performance reasons + def validate_sg_ignores? + rank >= LEVELS[:strong] + end end end end diff --git a/lib/solargraph/workspace/config.rb b/lib/solargraph/workspace/config.rb index ce45e5b11..0b2d84a01 100644 --- a/lib/solargraph/workspace/config.rb +++ b/lib/solargraph/workspace/config.rb @@ -90,7 +90,6 @@ def reporters # A hash of options supported by the formatter # - # @sg-ignore pending https://github.com/castwide/solargraph/pull/905 # @return [Hash] def formatter raw_data['formatter'] @@ -105,7 +104,6 @@ def plugins # The maximum number of files to parse from the workspace. # - # @sg-ignore pending https://github.com/castwide/solargraph/pull/905 # @return [Integer] def max_files raw_data['max_files'] diff --git a/spec/type_checker/levels/strong_spec.rb b/spec/type_checker/levels/strong_spec.rb index 12db1e442..6fdf84e30 100644 --- a/spec/type_checker/levels/strong_spec.rb +++ b/spec/type_checker/levels/strong_spec.rb @@ -4,6 +4,17 @@ def type_checker(code) Solargraph::TypeChecker.load_string(code, 'test.rb', :strong) end + it 'reports unneeded @sg-ignore tags' do + checker = type_checker(%( + class Foo + # @sg-ignore + # @return [void] + def bar; end + end + )) + expect(checker.problems.map(&:message)).to eq(['Unneeded @sg-ignore comment']) + end + it 'reports missing return tags' do checker = type_checker(%( class Foo From 8c7a5b8195d7a689b47f89ceae1e4d84098473d9 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Thu, 21 Aug 2025 08:16:33 -0400 Subject: [PATCH 011/106] Document a log level env variable (#894) * Document a log level env variable * Fix logger reference * Fix env var name * Populate location information from RBS files (#768) * Populate location information from RBS files The 'rbs' gem maps the location of different definitions to the relevant point in the RGS files themselves - this change provides the ability to jump into the right place in those files to see the type definition via the LSP. * Prefer source location in language server * Resolve merge issue * Fix Path vs String type error * Consolidate parameter handling into Pin::Callable (#844) * Consolidate parameter handling into Pin::Closure * Clarify clobbered variable names * Fix bug in to_rbs, add spec, then fix new bug found after running spec * Catch one more Signature.new to translate from strict typechecking * Introduce Pin::Callable * Introduce Pin::Callable * Introduce Pin::Callable * Introduce Pin::Callable * Introduce Pin::Callable * Introduce Pin::Callable * Introduce Pin::Callable * Use Pin::Callable type in args_node.rb * Select String#each_line overload with mandatory vs optional arg info * Adjust local variable presence to start after assignment, not before (#864) * Adjust local variable presence to start after assignment, not before * Add regression test around assignment in return position * Fix assignment visibility code, which relied on bad asgn semantics * Resolve params from ref tags (#872) * Resolve params from ref tags * Resolve ref tags with namespaces * Fix merge issue * RuboCop fixes * Add @sg-ignore * Linting * Linting fix * Linting fix --------- Co-authored-by: Fred Snyder --- README.md | 4 ++++ lib/solargraph/logging.rb | 14 ++++++++++++-- lib/solargraph/source/chain.rb | 6 +++++- spec/spec_helper.rb | 4 +++- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b3cb2ef5a..3e94a60b9 100755 --- a/README.md +++ b/README.md @@ -132,6 +132,10 @@ See [https://solargraph.org/guides](https://solargraph.org/guides) for more tips ### Development +To see more logging when typechecking or running specs, set the +`SOLARGRAPH_LOG` environment variable to `debug` or `info`. `warn` is +the default value. + Code contributions are always appreciated. Feel free to fork the repo and submit pull requests. Check for open issues that could use help. Start new issues to discuss changes that have a major impact on the code or require large time commitments. ### Sponsorship and Donation diff --git a/lib/solargraph/logging.rb b/lib/solargraph/logging.rb index a26610fee..a8bc3b3ee 100644 --- a/lib/solargraph/logging.rb +++ b/lib/solargraph/logging.rb @@ -11,8 +11,18 @@ module Logging 'info' => Logger::INFO, 'debug' => Logger::DEBUG } - - @@logger = Logger.new(STDERR, level: DEFAULT_LOG_LEVEL) + configured_level = ENV.fetch('SOLARGRAPH_LOG', nil) + level = if LOG_LEVELS.keys.include?(configured_level) + LOG_LEVELS.fetch(configured_level) + else + if configured_level + warn "Invalid value for SOLARGRAPH_LOG: #{configured_level.inspect} - " \ + "valid values are #{LOG_LEVELS.keys}" + end + DEFAULT_LOG_LEVEL + end + # @sg-ignore Fix cvar issue + @@logger = Logger.new(STDERR, level: level) # @sg-ignore Fix cvar issue @@logger.formatter = proc do |severity, datetime, progname, msg| "[#{severity}] #{msg}\n" diff --git a/lib/solargraph/source/chain.rb b/lib/solargraph/source/chain.rb index 8fdeed228..065c3bf10 100644 --- a/lib/solargraph/source/chain.rb +++ b/lib/solargraph/source/chain.rb @@ -15,6 +15,7 @@ class Source # class Chain include Equality + include Logging autoload :Link, 'solargraph/source/chain/link' autoload :Call, 'solargraph/source/chain/call' @@ -75,7 +76,9 @@ def base # Determine potential Pins returned by this chain of words # - # @param api_map [ApiMap] @param name_pin [Pin::Base] A pin + # @param api_map [ApiMap] + # + # @param name_pin [Pin::Base] A pin # representing the place in which expression is evaluated (e.g., # a Method pin, or a Module or Class pin if not run within a # method - both in terms of the closure around the chain, as well @@ -192,6 +195,7 @@ def nullable? include Logging + # @return [String] def desc links.map(&:desc).to_s end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index b23c21b74..3e2631976 100755 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -27,7 +27,9 @@ end require 'solargraph' # Suppress logger output in specs (if possible) -Solargraph::Logging.logger.reopen(File::NULL) if Solargraph::Logging.logger.respond_to?(:reopen) +if Solargraph::Logging.logger.respond_to?(:reopen) && !ENV.key?('SOLARGRAPH_LOG') + Solargraph::Logging.logger.reopen(File::NULL) +end # @param name [String] # @param value [String] From fba485e78664078a23f2f23f5f5dbc8d4be48e56 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 24 Aug 2025 10:44:31 -0400 Subject: [PATCH 012/106] Fix hole in type checking evaluation (#1009) * Fix hole in type checking evaluation The call to `bar()` in `[ bar('string') ].compact` is not currently type-checked due to a missed spot in `NodeMethods#call_nodes_from(node)` * Avoid over-reporting call issues * Fix annotation * Add nocov markers around unreachable area * Fix a coverage issue * Cover more paths in type checking * Fix a code coverage issue * Drop blank line * Ratchet Rubocop todo * Fix missing coverage --- .rubocop_todo.yml | 11 - .../parser/parser_gem/node_methods.rb | 1 + lib/solargraph/type_checker.rb | 223 +++++++++--------- spec/parser/node_methods_spec.rb | 40 ++++ spec/type_checker/levels/strict_spec.rb | 35 ++- spec/type_checker/levels/strong_spec.rb | 120 ++++++++++ 6 files changed, 311 insertions(+), 119 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index d8283c5c6..fe8ab7c48 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -99,7 +99,6 @@ Layout/ElseAlignment: - 'lib/solargraph/source/chain/call.rb' - 'lib/solargraph/source_map/clip.rb' - 'lib/solargraph/source_map/mapper.rb' - - 'lib/solargraph/type_checker.rb' - 'lib/solargraph/type_checker/rules.rb' - 'lib/solargraph/yard_map/mapper.rb' @@ -159,7 +158,6 @@ Layout/EndAlignment: - 'lib/solargraph/source/chain/call.rb' - 'lib/solargraph/source_map/clip.rb' - 'lib/solargraph/source_map/mapper.rb' - - 'lib/solargraph/type_checker.rb' - 'lib/solargraph/type_checker/rules.rb' - 'lib/solargraph/yard_map/mapper.rb' @@ -778,7 +776,6 @@ Metrics/MethodLength: - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - 'lib/solargraph/source/chain/call.rb' - 'lib/solargraph/source_map/mapper.rb' - - 'lib/solargraph/type_checker.rb' # Configuration parameters: CountComments, Max, CountAsOne. Metrics/ModuleLength: @@ -2135,13 +2132,6 @@ Style/NegatedIfElseCondition: - 'lib/solargraph/shell.rb' - 'lib/solargraph/type_checker.rb' -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowedMethods. -# AllowedMethods: be, be_a, be_an, be_between, be_falsey, be_kind_of, be_instance_of, be_truthy, be_within, eq, eql, end_with, include, match, raise_error, respond_to, start_with -Style/NestedParenthesizedCalls: - Exclude: - - 'lib/solargraph/type_checker.rb' - # This cop supports safe autocorrection (--autocorrect). Style/NestedTernaryOperator: Exclude: @@ -2237,7 +2227,6 @@ Style/RedundantBegin: - 'lib/solargraph/shell.rb' - 'lib/solargraph/source/cursor.rb' - 'lib/solargraph/source/encoding_fixes.rb' - - 'lib/solargraph/type_checker.rb' - 'lib/solargraph/workspace.rb' # This cop supports safe autocorrection (--autocorrect). diff --git a/lib/solargraph/parser/parser_gem/node_methods.rb b/lib/solargraph/parser/parser_gem/node_methods.rb index b716b352d..af5c62cca 100644 --- a/lib/solargraph/parser/parser_gem/node_methods.rb +++ b/lib/solargraph/parser/parser_gem/node_methods.rb @@ -179,6 +179,7 @@ def call_nodes_from node node.children[1..-1].each { |child| result.concat call_nodes_from(child) } elsif node.type == :send result.push node + result.concat call_nodes_from(node.children.first) node.children[2..-1].each { |child| result.concat call_nodes_from(child) } elsif [:super, :zsuper].include?(node.type) result.push node diff --git a/lib/solargraph/type_checker.rb b/lib/solargraph/type_checker.rb index e99f99195..55bf55745 100644 --- a/lib/solargraph/type_checker.rb +++ b/lib/solargraph/type_checker.rb @@ -289,127 +289,136 @@ def call_problems # @param chain [Solargraph::Source::Chain] # @param api_map [Solargraph::ApiMap] - # @param block_pin [Solargraph::Pin::Base] + # @param closure_pin [Solargraph::Pin::Closure] # @param locals [Array] # @param location [Solargraph::Location] # @return [Array] - def argument_problems_for chain, api_map, block_pin, locals, location + def argument_problems_for chain, api_map, closure_pin, locals, location result = [] base = chain - until base.links.length == 1 && base.undefined? - last_base_link = base.links.last - break unless last_base_link.is_a?(Solargraph::Source::Chain::Call) - - arguments = last_base_link.arguments - - pins = base.define(api_map, block_pin, locals) - - first_pin = pins.first - if first_pin.is_a?(Pin::DelegatedMethod) && !first_pin.resolvable?(api_map) - # Do nothing, as we can't find the actual method implementation - elsif first_pin.is_a?(Pin::Method) - # @type [Pin::Method] - pin = first_pin - ap = if base.links.last.is_a?(Solargraph::Source::Chain::ZSuper) - arity_problems_for(pin, fake_args_for(block_pin), location) - elsif pin.path == 'Class#new' - fqns = if base.links.one? - block_pin.namespace + # @type last_base_link [Solargraph::Source::Chain::Call] + last_base_link = base.links.last + return [] unless last_base_link.is_a?(Solargraph::Source::Chain::Call) + + arguments = last_base_link.arguments + + pins = base.define(api_map, closure_pin, locals) + + first_pin = pins.first + unresolvable = first_pin.is_a?(Pin::DelegatedMethod) && !first_pin.resolvable?(api_map) + if !unresolvable && first_pin.is_a?(Pin::Method) + # @type [Pin::Method] + pin = first_pin + ap = if base.links.last.is_a?(Solargraph::Source::Chain::ZSuper) + arity_problems_for(pin, fake_args_for(closure_pin), location) + elsif pin.path == 'Class#new' + fqns = if base.links.one? + closure_pin.namespace + else + base.base.infer(api_map, closure_pin, locals).namespace + end + init = api_map.get_method_stack(fqns, 'initialize').first + + init ? arity_problems_for(init, arguments, location) : [] + else + arity_problems_for(pin, arguments, location) + end + return ap unless ap.empty? + return [] if !rules.validate_calls? || base.links.first.is_a?(Solargraph::Source::Chain::ZSuper) + + params = first_param_hash(pins) + + all_errors = [] + pin.signatures.sort { |sig| sig.parameters.length }.each do |sig| + signature_errors = signature_argument_problems_for location, locals, closure_pin, params, arguments, sig, pin + if signature_errors.empty? + # we found a signature that works - meaning errors from + # other signatures don't matter. + return [] + end + all_errors.concat signature_errors + end + result.concat all_errors + end + result + end + + # @param location [Location] + # @param locals [Array] + # @param closure_pin [Pin::Closure] + # @param params [Hash{String => Hash{Symbol => String, Solargraph::ComplexType}}] + # @param arguments [Array] + # @param sig [Pin::Signature] + # @param pin [Pin::Method] + # @param pins [Array] + # + # @return [Array] + def signature_argument_problems_for location, locals, closure_pin, params, arguments, sig, pin + errors = [] + # @todo add logic mapping up restarg parameters with + # arguments (including restarg arguments). Use tuples + # when possible, and when not, ensure provably + # incorrect situations are detected. + sig.parameters.each_with_index do |par, idx| + return errors if par.decl == :restarg # bail out and assume the rest is valid pending better arg processing + argchain = arguments[idx] + if argchain.nil? + if par.decl == :arg + final_arg = arguments.last + if final_arg && final_arg.node.type == :splat + argchain = final_arg + return errors else - base.base.infer(api_map, block_pin, locals).namespace + errors.push Problem.new(location, "Not enough arguments to #{pin.path}") end - init = api_map.get_method_stack(fqns, 'initialize').first - init ? arity_problems_for(init, arguments, location) : [] else - arity_problems_for(pin, arguments, location) - end - unless ap.empty? - result.concat ap - break + final_arg = arguments.last + argchain = final_arg if final_arg && [:kwsplat, :hash].include?(final_arg.node.type) end - break if !rules.validate_calls? || base.links.first.is_a?(Solargraph::Source::Chain::ZSuper) - - params = first_param_hash(pins) - - all_errors = [] - pin.signatures.sort { |sig| sig.parameters.length }.each do |sig| - errors = [] - sig.parameters.each_with_index do |par, idx| - # @todo add logic mapping up restarg parameters with - # arguments (including restarg arguments). Use tuples - # when possible, and when not, ensure provably - # incorrect situations are detected. - break if par.decl == :restarg # bail out pending better arg processing - argchain = arguments[idx] - if argchain.nil? - if par.decl == :arg - final_arg = arguments.last - if final_arg && final_arg.node.type == :splat - argchain = final_arg - next # don't try to apply the type of the splat - unlikely to be specific enough - else - errors.push Problem.new(location, "Not enough arguments to #{pin.path}") - next - end - else - final_arg = arguments.last - argchain = final_arg if final_arg && [:kwsplat, :hash].include?(final_arg.node.type) - end - end - if argchain - if par.decl != :arg - errors.concat kwarg_problems_for sig, argchain, api_map, block_pin, locals, location, pin, params, idx - next - else - if argchain.node.type == :splat && argchain == arguments.last - final_arg = argchain - end - if (final_arg && final_arg.node.type == :splat) - # The final argument given has been seen and was a - # splat, which doesn't give us useful types or - # arities against positional parameters, so let's - # continue on in case there are any required - # kwargs we should warn about - next - end - - if argchain.node.type == :splat && par != sig.parameters.last - # we have been given a splat and there are more - # arguments to come. - - # @todo Improve this so that we can skip past the - # rest of the positional parameters here but still - # process the kwargs - break - end - ptype = params.key?(par.name) ? params[par.name][:qualified] : ComplexType::UNDEFINED - ptype = ptype.self_to_type(par.context) - if ptype.nil? - # @todo Some level (strong, I guess) should require the param here - else - argtype = argchain.infer(api_map, block_pin, locals) - if argtype.defined? && ptype.defined? && !any_types_match?(api_map, ptype, argtype) - errors.push Problem.new(location, "Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}") - next - end - end - end - elsif par.decl == :kwarg - errors.push Problem.new(location, "Call to #{pin.path} is missing keyword argument #{par.name}") - next - end + end + if argchain + if par.decl != :arg + errors.concat kwarg_problems_for sig, argchain, api_map, closure_pin, locals, location, pin, params, idx + next + else + if argchain.node.type == :splat && argchain == arguments.last + final_arg = argchain + end + if (final_arg && final_arg.node.type == :splat) + # The final argument given has been seen and was a + # splat, which doesn't give us useful types or + # arities against positional parameters, so let's + # continue on in case there are any required + # kwargs we should warn about + next end - if errors.empty? - all_errors.clear - break + if argchain.node.type == :splat && par != sig.parameters.last + # we have been given a splat and there are more + # arguments to come. + + # @todo Improve this so that we can skip past the + # rest of the positional parameters here but still + # process the kwargs + return errors + end + ptype = params.key?(par.name) ? params[par.name][:qualified] : ComplexType::UNDEFINED + ptype = ptype.self_to_type(par.context) + if ptype.nil? + # @todo Some level (strong, I guess) should require the param here + else + argtype = argchain.infer(api_map, closure_pin, locals) + if argtype.defined? && ptype.defined? && !any_types_match?(api_map, ptype, argtype) + errors.push Problem.new(location, "Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}") + return errors + end end - all_errors.concat errors end - result.concat all_errors + elsif par.decl == :kwarg + errors.push Problem.new(location, "Call to #{pin.path} is missing keyword argument #{par.name}") + next end - base = base.base end - result + errors end # @param sig [Pin::Signature] diff --git a/spec/parser/node_methods_spec.rb b/spec/parser/node_methods_spec.rb index eb026725b..f9504b584 100644 --- a/spec/parser/node_methods_spec.rb +++ b/spec/parser/node_methods_spec.rb @@ -440,5 +440,45 @@ def super_with_block calls = Solargraph::Parser::NodeMethods.call_nodes_from(source.node) expect(calls).to be_one end + + it 'handles chained calls' do + source = Solargraph::Source.load_string(%( + Foo.new.bar('string') + )) + calls = Solargraph::Parser::NodeMethods.call_nodes_from(source.node) + expect(calls.length).to eq(2) + end + + it 'handles calls from inside array literals' do + source = Solargraph::Source.load_string(%( + [ Foo.new.bar('string') ] + )) + calls = Solargraph::Parser::NodeMethods.call_nodes_from(source.node) + expect(calls.length).to eq(2) + end + + it 'handles calls from inside array literals that are chained' do + source = Solargraph::Source.load_string(%( + [ Foo.new.bar('string') ].compact + )) + calls = Solargraph::Parser::NodeMethods.call_nodes_from(source.node) + expect(calls.length).to eq(3) + end + + it 'does not over-report calls' do + source = Solargraph::Source.load_string(%( + class Foo + def something + end + end + class Bar < Foo + def something + super(1) + 2 + end + end + )) + calls = Solargraph::Parser::NodeMethods.call_nodes_from(source.node) + expect(calls.length).to eq(2) + end end end diff --git a/spec/type_checker/levels/strict_spec.rb b/spec/type_checker/levels/strict_spec.rb index b198cec89..25890683b 100644 --- a/spec/type_checker/levels/strict_spec.rb +++ b/spec/type_checker/levels/strict_spec.rb @@ -115,6 +115,39 @@ def bar(baz); end expect(checker.problems.first.message).to include('Wrong argument type') end + it 'reports mismatched argument types in chained calls' do + checker = type_checker(%( + # @param baz [Integer] + # @return [String] + def bar(baz); "foo"; end + bar('string').upcase + )) + expect(checker.problems).to be_one + expect(checker.problems.first.message).to include('Wrong argument type') + end + + it 'reports mismatched argument types in calls inside array literals' do + checker = type_checker(%( + # @param baz [Integer] + # @return [String] + def bar(baz); "foo"; end + [ bar('string') ] + )) + expect(checker.problems).to be_one + expect(checker.problems.first.message).to include('Wrong argument type') + end + + it 'reports mismatched argument types in calls inside array literals used in a chain' do + checker = type_checker(%( + # @param baz [Integer] + # @return [String] + def bar(baz); "foo"; end + [ bar('string') ].compact + )) + expect(checker.problems).to be_one + expect(checker.problems.first.message).to include('Wrong argument type') + end + xit 'complains about calling a private method from an illegal place' xit 'complains about calling a non-existent method' @@ -126,7 +159,7 @@ def foo(a) a[0] = :something end )) - expect(checker.problems.map(&:problems)).to eq(['Wrong argument type']) + expect(checker.problems.map(&:message)).to eq(['Wrong argument type']) end it 'complains about dereferencing a non-existent tuple slot' diff --git a/spec/type_checker/levels/strong_spec.rb b/spec/type_checker/levels/strong_spec.rb index 6fdf84e30..a03e6eb5d 100644 --- a/spec/type_checker/levels/strong_spec.rb +++ b/spec/type_checker/levels/strong_spec.rb @@ -4,6 +4,48 @@ def type_checker(code) Solargraph::TypeChecker.load_string(code, 'test.rb', :strong) end + it 'does not complain on array dereference' do + checker = type_checker(%( + # @param idx [Integer, nil] an index + # @param arr [Array] an array of integers + # + # @return [void] + def foo(idx, arr) + arr[idx] + end + )) + expect(checker.problems.map(&:message)).to be_empty + end + + it 'complains on bad @type assignment' do + checker = type_checker(%( + # @type [Integer] + c = Class.new + )) + expect(checker.problems.map(&:message)) + .to eq ['Declared type Integer does not match inferred type Class for variable c'] + end + + it 'does not complain on another variant of Class.new' do + checker = type_checker(%( + class Class + # @return [self] + def self.blah + new + end + end + )) + expect(checker.problems.map(&:message)).to be_empty + end + + it 'does not complain on indirect Class.new', skip: 'hangs in a loop currently' do + checker = type_checker(%( + class Foo < Class; end + Foo.new + )) + expect(checker.problems.map(&:message)).to be_empty + end + it 'reports unneeded @sg-ignore tags' do checker = type_checker(%( class Foo @@ -25,6 +67,84 @@ def bar; end expect(checker.problems.first.message).to include('Missing @return tag') end + it 'ignores nilable type issues' do + checker = type_checker(%( + # @param a [String] + # @return [void] + def foo(a); end + + # @param b [String, nil] + # @return [void] + def bar(b) + foo(b) + end + )) + expect(checker.problems.map(&:message)).to eq([]) + end + + it 'calls out keyword issues even when required arg count matches' do + checker = type_checker(%( + # @param a [String] + # @param b [String] + # @return [void] + def foo(a = 'foo', b:); end + + # @return [void] + def bar + foo('baz') + end + )) + expect(checker.problems.map(&:message)).to include('Call to #foo is missing keyword argument b') + end + + it 'calls out type issues even when keyword issues are there' do + pending('fixes to arg vs param checking algorithm') + + checker = type_checker(%( + # @param a [String] + # @param b [String] + # @return [void] + def foo(a = 'foo', b:); end + + # @return [void] + def bar + foo(123) + end + )) + expect(checker.problems.map(&:message)) + .to include('Wrong argument type for #foo: a expected String, received 123') + end + + it 'calls out keyword issues even when arg type issues are there' do + checker = type_checker(%( + # @param a [String] + # @param b [String] + # @return [void] + def foo(a = 'foo', b:); end + + # @return [void] + def bar + foo(123) + end + )) + expect(checker.problems.map(&:message)).to include('Call to #foo is missing keyword argument b') + end + + it 'calls out missing args after a defaulted param' do + checker = type_checker(%( + # @param a [String] + # @param b [String] + # @return [void] + def foo(a = 'foo', b); end + + # @return [void] + def bar + foo(123) + end + )) + expect(checker.problems.map(&:message)).to include('Not enough arguments to #foo') + end + it 'reports missing param tags' do checker = type_checker(%( class Foo From f61b1b6a94439c21b0eb0a986053b5d88276316f Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 24 Aug 2025 10:47:12 -0400 Subject: [PATCH 013/106] Improve typechecking error message (#1014) If we know the target of an unresolved method call, include it in the error message. --- lib/solargraph/type_checker.rb | 6 +++++- spec/type_checker/levels/strict_spec.rb | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/solargraph/type_checker.rb b/lib/solargraph/type_checker.rb index 55bf55745..e0b23f56b 100644 --- a/lib/solargraph/type_checker.rb +++ b/lib/solargraph/type_checker.rb @@ -277,7 +277,11 @@ def call_problems # @todo remove the internal_or_core? check at a higher-than-strict level if !found || found.is_a?(Pin::BaseVariable) || (closest.defined? && internal_or_core?(found)) unless closest.generic? || ignored_pins.include?(found) - result.push Problem.new(location, "Unresolved call to #{missing.links.last.word}") + if closest.defined? + result.push Problem.new(location, "Unresolved call to #{missing.links.last.word} on #{closest}") + else + result.push Problem.new(location, "Unresolved call to #{missing.links.last.word}") + end @marked_ranges.push rng end end diff --git a/spec/type_checker/levels/strict_spec.rb b/spec/type_checker/levels/strict_spec.rb index 25890683b..0e2159d95 100644 --- a/spec/type_checker/levels/strict_spec.rb +++ b/spec/type_checker/levels/strict_spec.rb @@ -40,6 +40,7 @@ def bar(a); end )) expect(checker.problems).to be_one expect(checker.problems.first.message).to include('Unresolved call') + expect(checker.problems.first.message).not_to include('undefined') end it 'reports undefined method calls with defined roots' do @@ -48,6 +49,7 @@ def bar(a); end )) expect(checker.problems).to be_one expect(checker.problems.first.message).to include('Unresolved call') + expect(checker.problems.first.message).to include('String') expect(checker.problems.first.message).to include('not_a_method') end From 9d4c711bed1af477224bae346b98e93a2d2e732e Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 24 Aug 2025 10:48:37 -0400 Subject: [PATCH 014/106] Internal strict type-checking fixes (#1013) * Internal strict type-checking fixes * Add annotation * Add annotation * Add @sg-ignores for now --- lib/solargraph/api_map/cache.rb | 5 +++-- lib/solargraph/api_map/index.rb | 8 ++++---- lib/solargraph/api_map/store.rb | 1 + lib/solargraph/complex_type/unique_type.rb | 4 ++-- lib/solargraph/diagnostics/rubocop_helpers.rb | 1 - lib/solargraph/library.rb | 3 ++- lib/solargraph/parser/node_processor/base.rb | 2 +- .../parser/parser_gem/node_processors/block_node.rb | 5 +++-- .../parser/parser_gem/node_processors/if_node.rb | 2 ++ lib/solargraph/rbs_map/conversions.rb | 2 +- lib/solargraph/source.rb | 2 +- lib/solargraph/source_map/clip.rb | 2 +- lib/solargraph/yard_map/mapper/to_method.rb | 2 +- 13 files changed, 22 insertions(+), 17 deletions(-) diff --git a/lib/solargraph/api_map/cache.rb b/lib/solargraph/api_map/cache.rb index 329a1e5e1..0052d91ea 100644 --- a/lib/solargraph/api_map/cache.rb +++ b/lib/solargraph/api_map/cache.rb @@ -4,9 +4,9 @@ module Solargraph class ApiMap class Cache def initialize - # @type [Hash{Array => Array}] + # @type [Hash{String => Array}] @methods = {} - # @type [Hash{(String, Array) => Array}] + # @type [Hash{String, Array => Array}] @constants = {} # @type [Hash{String => String}] @qualified_namespaces = {} @@ -101,6 +101,7 @@ def empty? private + # @return [Array] def all_caches [@methods, @constants, @qualified_namespaces, @receiver_definitions, @clips] end diff --git a/lib/solargraph/api_map/index.rb b/lib/solargraph/api_map/index.rb index ea358297e..5237a3802 100644 --- a/lib/solargraph/api_map/index.rb +++ b/lib/solargraph/api_map/index.rb @@ -42,22 +42,22 @@ def pins_by_class klass @pin_select_cache[klass] ||= pin_class_hash.each_with_object(s) { |(key, o), n| n.merge(o) if key <= klass } end - # @return [Hash{String => Array}] + # @return [Hash{String => Array}] def include_references @include_references ||= Hash.new { |h, k| h[k] = [] } end - # @return [Hash{String => Array}] + # @return [Hash{String => Array}] def extend_references @extend_references ||= Hash.new { |h, k| h[k] = [] } end - # @return [Hash{String => Array}] + # @return [Hash{String => Array}] def prepend_references @prepend_references ||= Hash.new { |h, k| h[k] = [] } end - # @return [Hash{String => Array}] + # @return [Hash{String => Array}] def superclass_references @superclass_references ||= Hash.new { |h, k| h[k] = [] } end diff --git a/lib/solargraph/api_map/store.rb b/lib/solargraph/api_map/store.rb index d41a2a0ae..87f053596 100644 --- a/lib/solargraph/api_map/store.rb +++ b/lib/solargraph/api_map/store.rb @@ -210,6 +210,7 @@ def index # @return [Boolean] def catalog pinsets @pinsets = pinsets + # @type [Array] @indexes = [] pinsets.each do |pins| if @indexes.last && pins.empty? diff --git a/lib/solargraph/complex_type/unique_type.rb b/lib/solargraph/complex_type/unique_type.rb index 63a6ae15b..a782656f0 100644 --- a/lib/solargraph/complex_type/unique_type.rb +++ b/lib/solargraph/complex_type/unique_type.rb @@ -349,9 +349,9 @@ def to_a # @param new_name [String, nil] # @param make_rooted [Boolean, nil] - # @param new_key_types [Array, nil] + # @param new_key_types [Array, nil] # @param rooted [Boolean, nil] - # @param new_subtypes [Array, nil] + # @param new_subtypes [Array, nil] # @return [self] def recreate(new_name: nil, make_rooted: nil, new_key_types: nil, new_subtypes: nil) raise "Please remove leading :: and set rooted instead - #{new_name}" if new_name&.start_with?('::') diff --git a/lib/solargraph/diagnostics/rubocop_helpers.rb b/lib/solargraph/diagnostics/rubocop_helpers.rb index 4eb2c711d..bfae43822 100644 --- a/lib/solargraph/diagnostics/rubocop_helpers.rb +++ b/lib/solargraph/diagnostics/rubocop_helpers.rb @@ -19,7 +19,6 @@ def require_rubocop(version = nil) gem_path = Gem::Specification.find_by_name('rubocop', version).full_gem_path gem_lib_path = File.join(gem_path, 'lib') $LOAD_PATH.unshift(gem_lib_path) unless $LOAD_PATH.include?(gem_lib_path) - # @todo Gem::MissingSpecVersionError is undocumented for some reason # @sg-ignore rescue Gem::MissingSpecVersionError => e raise InvalidRubocopVersionError, diff --git a/lib/solargraph/library.rb b/lib/solargraph/library.rb index 72224f672..b4da03b2e 100644 --- a/lib/solargraph/library.rb +++ b/lib/solargraph/library.rb @@ -500,7 +500,7 @@ def external_requires private - # @return [Hash{String => Set}] + # @return [Hash{String => Array}] def source_map_external_require_hash @source_map_external_require_hash ||= {} end @@ -508,6 +508,7 @@ def source_map_external_require_hash # @param source_map [SourceMap] # @return [void] def find_external_requires source_map + # @type [Set] new_set = source_map.requires.map(&:name).to_set # return if new_set == source_map_external_require_hash[source_map.filename] _filenames = nil diff --git a/lib/solargraph/parser/node_processor/base.rb b/lib/solargraph/parser/node_processor/base.rb index d87268a91..fad31e95b 100644 --- a/lib/solargraph/parser/node_processor/base.rb +++ b/lib/solargraph/parser/node_processor/base.rb @@ -13,7 +13,7 @@ class Base # @return [Array] attr_reader :pins - # @return [Array] + # @return [Array] attr_reader :locals # @param node [Parser::AST::Node] diff --git a/lib/solargraph/parser/parser_gem/node_processors/block_node.rb b/lib/solargraph/parser/parser_gem/node_processors/block_node.rb index 70a2d9e68..d773e8e50 100644 --- a/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +++ b/lib/solargraph/parser/parser_gem/node_processors/block_node.rb @@ -19,7 +19,7 @@ def process else region.closure end - pins.push Solargraph::Pin::Block.new( + block_pin = Solargraph::Pin::Block.new( location: location, closure: parent, node: node, @@ -28,7 +28,8 @@ def process scope: region.scope || region.closure.context.scope, source: :parser ) - process_children region.update(closure: pins.last) + pins.push block_pin + process_children region.update(closure: block_pin) end private diff --git a/lib/solargraph/parser/parser_gem/node_processors/if_node.rb b/lib/solargraph/parser/parser_gem/node_processors/if_node.rb index 5784afcbe..2452b9cc5 100644 --- a/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +++ b/lib/solargraph/parser/parser_gem/node_processors/if_node.rb @@ -11,6 +11,8 @@ def process process_children position = get_node_start_position(node) + # @sg-ignore + # @type [Solargraph::Pin::Breakable, nil] enclosing_breakable_pin = pins.select{|pin| pin.is_a?(Pin::Breakable) && pin.location.range.contain?(position)}.last FlowSensitiveTyping.new(locals, enclosing_breakable_pin).process_if(node) end diff --git a/lib/solargraph/rbs_map/conversions.rb b/lib/solargraph/rbs_map/conversions.rb index 6e50c022a..f8deec251 100644 --- a/lib/solargraph/rbs_map/conversions.rb +++ b/lib/solargraph/rbs_map/conversions.rb @@ -345,7 +345,7 @@ def global_decl_to_pin decl } # @param decl [RBS::AST::Members::MethodDefinition, RBS::AST::Members::AttrReader, RBS::AST::Members::AttrAccessor] - # @param closure [Pin::Namespace] + # @param closure [Pin::Closure] # @param context [Context] # @param scope [Symbol] :instance or :class # @param name [String] The name of the method diff --git a/lib/solargraph/source.rb b/lib/solargraph/source.rb index d2b24cc61..ee8baa768 100644 --- a/lib/solargraph/source.rb +++ b/lib/solargraph/source.rb @@ -318,7 +318,7 @@ def string_nodes @string_nodes ||= string_nodes_in(node) end - # @return [Array] + # @return [Array] def comment_ranges @comment_ranges ||= comments.values.map(&:range) end diff --git a/lib/solargraph/source_map/clip.rb b/lib/solargraph/source_map/clip.rb index ba69b1b93..16a4ec845 100644 --- a/lib/solargraph/source_map/clip.rb +++ b/lib/solargraph/source_map/clip.rb @@ -65,7 +65,7 @@ def infer # position. Locals can be local variables, method parameters, or block # parameters. The array starts with the nearest local pin. # - # @return [::Array] + # @return [::Array] def locals @locals ||= source_map.locals_at(location) end diff --git a/lib/solargraph/yard_map/mapper/to_method.rb b/lib/solargraph/yard_map/mapper/to_method.rb index df431bb3c..6bb4fa261 100644 --- a/lib/solargraph/yard_map/mapper/to_method.rb +++ b/lib/solargraph/yard_map/mapper/to_method.rb @@ -27,7 +27,7 @@ def self.make code_object, name = nil, scope = nil, visibility = nil, closure = final_scope = scope || code_object.scope override_key = [closure.path, final_scope, name] final_visibility = VISIBILITY_OVERRIDE[override_key] - final_visibility ||= VISIBILITY_OVERRIDE[override_key[0..-2]] + final_visibility ||= VISIBILITY_OVERRIDE[[closure.path, final_scope]] final_visibility ||= :private if closure.path == 'Kernel' && Kernel.private_instance_methods(false).include?(name) final_visibility ||= visibility final_visibility ||= :private if code_object.module_function? && final_scope == :instance From 3bcbf85d5a5e7445754b1a0392e39238f8a681c3 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 24 Aug 2025 10:50:13 -0400 Subject: [PATCH 015/106] Reproduce and fix a ||= (or-asgn) evaluation issue (#1017) * Reproduce and fix a ||= (or-asgn) evaluation issue * Fix linting issue --- .../parser/parser_gem/node_chainer.rb | 3 ++- spec/type_checker/levels/strict_spec.rb | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/solargraph/parser/parser_gem/node_chainer.rb b/lib/solargraph/parser/parser_gem/node_chainer.rb index 646e753d5..d8d46319b 100644 --- a/lib/solargraph/parser/parser_gem/node_chainer.rb +++ b/lib/solargraph/parser/parser_gem/node_chainer.rb @@ -99,7 +99,8 @@ def generate_links n elsif [:gvar, :gvasgn].include?(n.type) result.push Chain::GlobalVariable.new(n.children[0].to_s) elsif n.type == :or_asgn - result.concat generate_links n.children[1] + new_node = n.updated(n.children[0].type, n.children[0].children + [n.children[1]]) + result.concat generate_links new_node elsif [:class, :module, :def, :defs].include?(n.type) # @todo Undefined or what? result.push Chain::UNDEFINED_CALL diff --git a/spec/type_checker/levels/strict_spec.rb b/spec/type_checker/levels/strict_spec.rb index 0e2159d95..7e57cb7cf 100644 --- a/spec/type_checker/levels/strict_spec.rb +++ b/spec/type_checker/levels/strict_spec.rb @@ -976,5 +976,22 @@ def bar(a) )) expect(checker.problems.map(&:message)).to eq([]) end + + it 'does not complain on defaulted reader with detailed expression' do + checker = type_checker(%( + class Foo + # @return [Integer, nil] + def bar + @bar ||= + if rand + 123 + elsif rand + 456 + end + end + end + )) + expect(checker.problems.map(&:message)).to eq([]) + end end end From 25557b42fea981ddf8d5a01042204e55c71fdab5 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 24 Aug 2025 10:51:19 -0400 Subject: [PATCH 016/106] Define closure for Pin::Symbol, for completeness (#1027) This isn't used anywhere to my knowledge, but it makes sense to think of symbols as being in the global namespace, helps guarantee that closure is always available on a pin, and of course keeps the assert happy ;) --- lib/solargraph/pin/symbol.rb | 4 ++++ spec/pin/symbol_spec.rb | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/solargraph/pin/symbol.rb b/lib/solargraph/pin/symbol.rb index 9e11c3d7d..9c59155a1 100644 --- a/lib/solargraph/pin/symbol.rb +++ b/lib/solargraph/pin/symbol.rb @@ -20,6 +20,10 @@ def path '' end + def closure + @closure ||= Pin::ROOT_PIN + end + def completion_item_kind Solargraph::LanguageServer::CompletionItemKinds::KEYWORD end diff --git a/spec/pin/symbol_spec.rb b/spec/pin/symbol_spec.rb index 98d88137e..16961cadc 100644 --- a/spec/pin/symbol_spec.rb +++ b/spec/pin/symbol_spec.rb @@ -1,10 +1,15 @@ describe Solargraph::Pin::Symbol do context "as an unquoted literal" do - it "is a kind of keyword" do + it "is a kind of keyword to the LSP" do pin = Solargraph::Pin::Symbol.new(nil, ':symbol') expect(pin.completion_item_kind).to eq(Solargraph::LanguageServer::CompletionItemKinds::KEYWORD) end + it "has global closure" do + pin = Solargraph::Pin::Symbol.new(nil, ':symbol') + expect(pin.closure).to eq(Solargraph::Pin::ROOT_PIN) + end + it "has a Symbol return type" do pin = Solargraph::Pin::Symbol.new(nil, ':symbol') expect(pin.return_type.tag).to eq('Symbol') From 32565d4488765c6a4ebfc302ee24bb123dd5c5af Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 24 Aug 2025 10:52:07 -0400 Subject: [PATCH 017/106] Fix 'all!' config to reporters (#1018) * Fix 'all!' config to reporters Solargraph found the type error here! * Linting fixes --- lib/solargraph/library.rb | 4 ++-- spec/library_spec.rb | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/solargraph/library.rb b/lib/solargraph/library.rb index b4da03b2e..9d5162431 100644 --- a/lib/solargraph/library.rb +++ b/lib/solargraph/library.rb @@ -402,8 +402,8 @@ def diagnose filename repargs = {} workspace.config.reporters.each do |line| if line == 'all!' - Diagnostics.reporters.each do |reporter| - repargs[reporter] ||= [] + Diagnostics.reporters.each do |reporter_name| + repargs[Diagnostics.reporter(reporter_name)] ||= [] end else args = line.split(':').map(&:strip) diff --git a/spec/library_spec.rb b/spec/library_spec.rb index bea0f2983..34de9e1f0 100644 --- a/spec/library_spec.rb +++ b/spec/library_spec.rb @@ -132,6 +132,20 @@ def bar baz, key: '' # @todo More tests end + it 'diagnoses using all reporters' do + directory = '' + config = instance_double(Solargraph::Workspace::Config) + allow(config).to receive_messages(plugins: [], required: [], reporters: ['all!']) + workspace = Solargraph::Workspace.new directory, config + library = Solargraph::Library.new workspace + src = Solargraph::Source.load_string(%( + puts 'hello' + ), 'file.rb', 0) + library.attach src + result = library.diagnose 'file.rb' + expect(result.to_s).to include('rubocop') + end + it "documents symbols" do library = Solargraph::Library.new src = Solargraph::Source.load_string(%( From 3946cc481c12c704bd9265b87516079d179ce5a2 Mon Sep 17 00:00:00 2001 From: Fred Snyder Date: Sun, 24 Aug 2025 11:54:48 -0400 Subject: [PATCH 018/106] Fix DocMap.all_rbs_collection_gems_in_memory return type (#1037) --- lib/solargraph/doc_map.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/solargraph/doc_map.rb b/lib/solargraph/doc_map.rb index 43c8768b0..56f51973f 100644 --- a/lib/solargraph/doc_map.rb +++ b/lib/solargraph/doc_map.rb @@ -133,7 +133,7 @@ def self.all_yard_gems_in_memory @yard_gems_in_memory ||= {} end - # @return [Hash{String => Array}] stored by RBS collection path + # @return [Hash{String => Hash{Array(String, String) => Array}}] stored by RBS collection path def self.all_rbs_collection_gems_in_memory @rbs_collection_gems_in_memory ||= {} end From 43caccadaaf71bbd51acc85d74d437fd061875f1 Mon Sep 17 00:00:00 2001 From: Fred Snyder Date: Sun, 24 Aug 2025 12:40:56 -0400 Subject: [PATCH 019/106] Fix RuboCop linting errors in regular expressions (#1038) * Fix RuboCop linting errors in regular expressions * Continue on rubocop_todo errors * Move configuration * Continue on undercover errors --- .github/workflows/linting.yml | 1 + .github/workflows/rspec.yml | 1 + lib/solargraph/parser/parser_gem/node_methods.rb | 2 +- lib/solargraph/pin/method.rb | 4 ++-- lib/solargraph/pin/parameter.rb | 2 +- lib/solargraph/source/change.rb | 4 ++-- lib/solargraph/source/cursor.rb | 4 ++-- lib/solargraph/source/source_chainer.rb | 2 +- lib/solargraph/source_map/mapper.rb | 4 ++-- 9 files changed, 13 insertions(+), 11 deletions(-) diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 2a5968351..8abbf51ef 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -113,6 +113,7 @@ jobs: run: bundle exec rubocop -c .rubocop.yml - name: Run RuboCop against todo file + continue-on-error: true run: | bundle exec rubocop --auto-gen-config --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp if [ -n "$(git status --porcelain)" ] diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index 35f7a1d13..ecc3d9771 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -69,3 +69,4 @@ jobs: run: bundle exec rake spec - name: Check PR coverage run: bundle exec rake undercover + continue-on-error: true diff --git a/lib/solargraph/parser/parser_gem/node_methods.rb b/lib/solargraph/parser/parser_gem/node_methods.rb index af5c62cca..1397f9583 100644 --- a/lib/solargraph/parser/parser_gem/node_methods.rb +++ b/lib/solargraph/parser/parser_gem/node_methods.rb @@ -243,7 +243,7 @@ def find_recipient_node cursor if source.synchronized? return node if source.code[0..offset-1] =~ /\(\s*\z/ && source.code[offset..-1] =~ /^\s*\)/ else - return node if source.code[0..offset-1] =~ /\([^\(]*\z/ + return node if source.code[0..offset-1] =~ /\([^(]*\z/ end end end diff --git a/lib/solargraph/pin/method.rb b/lib/solargraph/pin/method.rb index 6309cb55a..0482b2b54 100644 --- a/lib/solargraph/pin/method.rb +++ b/lib/solargraph/pin/method.rb @@ -428,7 +428,7 @@ def resolve_ref_tag api_map @resolved_ref_tag = true return self unless docstring.ref_tags.any? docstring.ref_tags.each do |tag| - ref = if tag.owner.to_s.start_with?(/[#\.]/) + ref = if tag.owner.to_s.start_with?(/[#.]/) api_map.get_methods(namespace) .select { |pin| pin.path.end_with?(tag.owner.to_s) } .first @@ -552,7 +552,7 @@ def typify_from_super api_map # @param api_map [ApiMap] # @return [ComplexType, nil] def resolve_reference ref, api_map - parts = ref.split(/[\.#]/) + parts = ref.split(/[.#]/) if parts.first.empty? || parts.one? path = "#{namespace}#{ref}" else diff --git a/lib/solargraph/pin/parameter.rb b/lib/solargraph/pin/parameter.rb index e298ba20a..512ee0ead 100644 --- a/lib/solargraph/pin/parameter.rb +++ b/lib/solargraph/pin/parameter.rb @@ -247,7 +247,7 @@ def see_reference heredoc, api_map, skip = [] def resolve_reference ref, api_map, skip return nil if skip.include?(ref) skip.push ref - parts = ref.split(/[\.#]/) + parts = ref.split(/[.#]/) if parts.first.empty? path = "#{namespace}#{ref}" else diff --git a/lib/solargraph/source/change.rb b/lib/solargraph/source/change.rb index 72a99b6a6..65c47c7e0 100644 --- a/lib/solargraph/source/change.rb +++ b/lib/solargraph/source/change.rb @@ -28,7 +28,7 @@ def initialize range, new_text # syntax errors will be repaired. # @return [String] The updated text. def write text, nullable = false - if nullable and !range.nil? and new_text.match(/[\.\[\{\(@\$:]$/) + if nullable and !range.nil? and new_text.match(/[.\[{(@$:]$/) [':', '@'].each do |dupable| next unless new_text == dupable offset = Position.to_offset(text, range.start) @@ -59,7 +59,7 @@ def repair text else result = commit text, fixed off = Position.to_offset(text, range.start) - match = result[0, off].match(/[\.:]+\z/) + match = result[0, off].match(/[.:]+\z/) if match result = result[0, off].sub(/#{match[0]}\z/, ' ' * match[0].length) + result[off..-1] end diff --git a/lib/solargraph/source/cursor.rb b/lib/solargraph/source/cursor.rb index 70e4fd47a..a8226eb07 100644 --- a/lib/solargraph/source/cursor.rb +++ b/lib/solargraph/source/cursor.rb @@ -124,7 +124,7 @@ def node def node_position @node_position ||= begin if start_of_word.empty? - match = source.code[0, offset].match(/[\s]*(\.|:+)[\s]*$/) + match = source.code[0, offset].match(/\s*(\.|:+)\s*$/) if match Position.from_offset(source.code, offset - match[0].length) else @@ -159,7 +159,7 @@ def start_word_pattern # # @return [Regexp] def end_word_pattern - /^([a-z0-9_]|[^\u0000-\u007F])*[\?\!]?/i + /^([a-z0-9_]|[^\u0000-\u007F])*[?!]?/i end end end diff --git a/lib/solargraph/source/source_chainer.rb b/lib/solargraph/source/source_chainer.rb index e79d85b7e..5758a9d35 100644 --- a/lib/solargraph/source/source_chainer.rb +++ b/lib/solargraph/source/source_chainer.rb @@ -97,7 +97,7 @@ def fixed_position # @return [String] def end_of_phrase @end_of_phrase ||= begin - match = phrase.match(/[\s]*(\.{1}|::)[\s]*$/) + match = phrase.match(/\s*(\.{1}|::)\s*$/) if match match[0] else diff --git a/lib/solargraph/source_map/mapper.rb b/lib/solargraph/source_map/mapper.rb index d53fd49a0..5fdcb9fe6 100644 --- a/lib/solargraph/source_map/mapper.rb +++ b/lib/solargraph/source_map/mapper.rb @@ -163,7 +163,7 @@ def process_directive source_position, comment_position, directive end end when 'visibility' - begin + kind = directive.tag.text&.to_sym return unless [:private, :protected, :public].include?(kind) @@ -182,7 +182,7 @@ def process_directive source_position, comment_position, directive pin.instance_variable_set(:@visibility, kind) end end - end + when 'parse' begin ns = closure_at(source_position) From d3bdfea12869252296c8b2cf9ca1ce2186f86321 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 24 Aug 2025 13:33:58 -0400 Subject: [PATCH 020/106] Resolve class aliases via Constant pins (#1029) * Resolve class aliases via Constant pins This also eliminates the need for Parser::NodeMethods as a searately defined class. * Resolve merge issues * Resolve Solargraph strong complaint * Add @sg-ignore * Fix RuboCop issues * Drop unused method * Ratchet .rubocop_todo.yml --- .rubocop_todo.yml | 11 +- lib/solargraph.rb | 18 +- lib/solargraph/api_map.rb | 118 +++++++++++--- lib/solargraph/api_map/store.rb | 9 +- lib/solargraph/complex_type.rb | 3 + lib/solargraph/complex_type/type_methods.rb | 12 +- lib/solargraph/complex_type/unique_type.rb | 5 +- lib/solargraph/parser/node_methods.rb | 97 ----------- .../parser/parser_gem/node_methods.rb | 2 +- lib/solargraph/pin/base.rb | 2 +- lib/solargraph/rbs_map/conversions.rb | 2 +- spec/api_map/api_map_method_spec.rb | 154 ++++++++++++++++++ spec/api_map_spec.rb | 59 +++++++ spec/convention/struct_definition_spec.rb | 4 +- 14 files changed, 355 insertions(+), 141 deletions(-) delete mode 100644 lib/solargraph/parser/node_methods.rb create mode 100644 spec/api_map/api_map_method_spec.rb diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index fe8ab7c48..14cc0ca5d 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -397,7 +397,6 @@ Layout/SpaceBeforeComma: # SupportedStylesForEmptyBraces: space, no_space Layout/SpaceInsideBlockBraces: Exclude: - - 'lib/solargraph/api_map.rb' - 'lib/solargraph/api_map/store.rb' - 'lib/solargraph/diagnostics/update_errors.rb' - 'lib/solargraph/language_server/host.rb' @@ -569,7 +568,6 @@ Lint/NonAtomicFileOperation: # This cop supports safe autocorrection (--autocorrect). Lint/ParenthesesAsGroupedExpression: Exclude: - - 'lib/solargraph.rb' - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - 'spec/language_server/host_spec.rb' - 'spec/source_map/clip_spec.rb' @@ -672,7 +670,6 @@ Lint/UselessAccessModifier: # Configuration parameters: AutoCorrect. Lint/UselessAssignment: Exclude: - - 'lib/solargraph/api_map.rb' - 'lib/solargraph/doc_map.rb' - 'lib/solargraph/language_server/message/extended/check_gem_version.rb' - 'lib/solargraph/language_server/message/extended/document_gems.rb' @@ -757,6 +754,7 @@ Metrics/ClassLength: # Configuration parameters: AllowedMethods, AllowedPatterns, Max. Metrics/CyclomaticComplexity: Exclude: + - 'lib/solargraph/api_map.rb' - 'lib/solargraph/api_map/source_to_yard.rb' - 'lib/solargraph/complex_type.rb' - 'lib/solargraph/parser/parser_gem/node_chainer.rb' @@ -1057,7 +1055,6 @@ RSpec/ExampleLength: # DisallowedExamples: works RSpec/ExampleWording: Exclude: - - 'spec/convention/struct_definition_spec.rb' - 'spec/pin/base_spec.rb' - 'spec/pin/method_spec.rb' @@ -1098,7 +1095,6 @@ RSpec/ImplicitExpect: RSpec/InstanceVariable: Exclude: - 'spec/api_map/config_spec.rb' - - 'spec/api_map_spec.rb' - 'spec/diagnostics/require_not_found_spec.rb' - 'spec/language_server/host/dispatch_spec.rb' - 'spec/language_server/host_spec.rb' @@ -1282,6 +1278,7 @@ RSpec/ScatteredLet: RSpec/SpecFilePathFormat: Exclude: - '**/spec/routing/**/*' + - 'spec/api_map/api_map_method_spec.rb' - 'spec/api_map/cache_spec.rb' - 'spec/api_map/config_spec.rb' - 'spec/api_map/source_to_yard_spec.rb' @@ -1622,7 +1619,6 @@ Style/Documentation: - 'lib/solargraph/parser.rb' - 'lib/solargraph/parser/comment_ripper.rb' - 'lib/solargraph/parser/flow_sensitive_typing.rb' - - 'lib/solargraph/parser/node_methods.rb' - 'lib/solargraph/parser/node_processor/base.rb' - 'lib/solargraph/parser/parser_gem.rb' - 'lib/solargraph/parser/parser_gem/class_methods.rb' @@ -1763,7 +1759,6 @@ Style/FrozenStringLiteralComment: - 'lib/solargraph/parser.rb' - 'lib/solargraph/parser/comment_ripper.rb' - 'lib/solargraph/parser/flow_sensitive_typing.rb' - - 'lib/solargraph/parser/node_methods.rb' - 'lib/solargraph/parser/parser_gem.rb' - 'lib/solargraph/parser/snippet.rb' - 'lib/solargraph/pin/breakable.rb' @@ -2037,7 +2032,6 @@ Style/MethodDefParentheses: - 'lib/solargraph/location.rb' - 'lib/solargraph/parser/comment_ripper.rb' - 'lib/solargraph/parser/flow_sensitive_typing.rb' - - 'lib/solargraph/parser/node_methods.rb' - 'lib/solargraph/parser/node_processor/base.rb' - 'lib/solargraph/parser/parser_gem/flawed_builder.rb' - 'lib/solargraph/parser/parser_gem/node_chainer.rb' @@ -2249,7 +2243,6 @@ Style/RedundantInitialize: # This cop supports unsafe autocorrection (--autocorrect-all). Style/RedundantInterpolation: Exclude: - - 'lib/solargraph/api_map/store.rb' - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - 'lib/solargraph/source_map/mapper.rb' diff --git a/lib/solargraph.rb b/lib/solargraph.rb index 038e7bccf..8520e3a93 100755 --- a/lib/solargraph.rb +++ b/lib/solargraph.rb @@ -72,7 +72,23 @@ def self.asserts_on?(type) # @param block [Proc] A block that returns a message to log # @return [void] def self.assert_or_log(type, msg = nil, &block) - raise (msg || block.call) if asserts_on?(type) && ![:combine_with_visibility].include?(type) + if asserts_on? type + # @type [String, nil] + msg ||= block.call + + raise "No message given for #{type.inspect}" if msg.nil? + + # @todo :combine_with_visibility is not ready for prime time - + # lots of disagreements found in practice that heuristics need + # to be created for and/or debugging needs to resolve in pin + # generation. + # @todo :api_map_namespace_pin_stack triggers in a badly handled + # self type case - 'keeps track of self type in method + # parameters in subclass' in call_spec.rb + return if %i[api_map_namespace_pin_stack combine_with_visibility].include?(type) + + raise msg + end logger.info msg, &block end diff --git a/lib/solargraph/api_map.rb b/lib/solargraph/api_map.rb index eed02b4ef..9db21128f 100755 --- a/lib/solargraph/api_map.rb +++ b/lib/solargraph/api_map.rb @@ -308,12 +308,11 @@ def qualify tag, context_tag = '' return unless type return tag if type.literal? - context_type = ComplexType.try_parse(context_tag) - return unless context_type - fqns = qualify_namespace(type.rooted_namespace, context_type.rooted_namespace) return unless fqns + return fqns if %w[Class Module].include? type + fqns + type.substring end @@ -406,16 +405,18 @@ def get_block_pins # @param deep [Boolean] True to include superclasses, mixins, etc. # @return [Array] def get_methods rooted_tag, scope: :instance, visibility: [:public], deep: true + rooted_tag = qualify(rooted_tag, '') + return [] unless rooted_tag if rooted_tag.start_with? 'Array(' # Array() are really tuples - use our fill, as the RBS repo # does not give us definitions for it rooted_tag = "Solargraph::Fills::Tuple(#{rooted_tag[6..-2]})" end - rooted_type = ComplexType.try_parse(rooted_tag) - fqns = rooted_type.namespace - namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first cached = cache.get_methods(rooted_tag, scope, visibility, deep) return cached.clone unless cached.nil? + rooted_type = ComplexType.try_parse(rooted_tag) + fqns = rooted_type.namespace + namespace_pin = get_namespace_pin(fqns) # @type [Array] result = [] skip = Set.new @@ -535,10 +536,20 @@ def get_complex_type_methods complex_type, context = '', internal = false # @param visibility [Array] :public, :protected, and/or :private # @param preserve_generics [Boolean] # @return [Array] - def get_method_stack rooted_tag, name, scope: :instance, visibility: [:private, :protected, :public], preserve_generics: false - rooted_type = ComplexType.parse(rooted_tag) + def get_method_stack rooted_tag, name, scope: :instance, visibility: [:private, :protected, :public], + preserve_generics: false + rooted_tag = qualify(rooted_tag, '') + return [] unless rooted_tag + rooted_type = ComplexType.try_parse(rooted_tag) + return [] if rooted_type.nil? fqns = rooted_type.namespace - namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first + namespace_pin = get_namespace_pin(fqns) + if namespace_pin.nil? + # :nocov: + Solargraph.assert_or_log(:api_map_namespace_pin_stack, "Could not find namespace pin for #{fqns} while looking for method #{name}") + return [] + # :nocov: + end methods = get_methods(rooted_tag, scope: scope, visibility: visibility).select { |p| p.name == name } methods = erase_generics(namespace_pin, rooted_type, methods) unless preserve_generics methods @@ -695,7 +706,7 @@ def resolve_method_aliases pins, visibility = [:public, :private, :protected] # @param skip [Set] # @param no_core [Boolean] Skip core classes if true # @return [Array] - def inner_get_methods_from_reference(fq_reference_tag, namespace_pin, type, scope, visibility, deep, skip, no_core) + def inner_get_methods_from_reference fq_reference_tag, namespace_pin, type, scope, visibility, deep, skip, no_core logger.debug { "ApiMap#add_methods_from_reference(type=#{type}) starting" } # Ensure the types returned by the methods in the referenced @@ -709,7 +720,7 @@ def inner_get_methods_from_reference(fq_reference_tag, namespace_pin, type, scop # @todo Can inner_get_methods be cached? Lots of lookups of base types going on. methods = inner_get_methods(resolved_reference_type.tag, scope, visibility, deep, skip, no_core) if namespace_pin && !resolved_reference_type.all_params.empty? - reference_pin = store.get_path_pins(resolved_reference_type.name).select { |p| p.is_a?(Pin::Namespace) }.first + reference_pin = get_namespace_pin(resolved_reference_type.namespace) # logger.debug { "ApiMap#add_methods_from_reference(type=#{type}) - resolving generics with #{reference_pin.generics}, #{resolved_reference_type.rooted_tags}" } methods = methods.map do |method_pin| method_pin.resolve_generics(reference_pin, resolved_reference_type) @@ -734,6 +745,13 @@ def store # @return [Solargraph::ApiMap::Cache] attr_reader :cache + # @param fqns [String] + # @return [Pin::Namespace, nil] + def get_namespace_pin fqns + # fqns = ComplexType.parse(fqns).namespace + store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first + end + # @param rooted_tag [String] A fully qualified namespace, with # generic parameter values if applicable # @param scope [Symbol] :class or :instance @@ -743,11 +761,20 @@ def store # @param no_core [Boolean] Skip core classes if true # @return [Array] def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false + rooted_tag = qualify(rooted_tag, '') + return [] if rooted_tag.nil? + return [] unless rooted_tag rooted_type = ComplexType.parse(rooted_tag).force_rooted fqns = rooted_type.namespace - fqns_generic_params = rooted_type.all_params - namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first + namespace_pin = get_namespace_pin(fqns) + if namespace_pin.nil? + # :nocov: + Solargraph.assert_or_log(:api_map_namespace_pin_inner, "Could not find namespace pin for #{fqns}") + return [] + # :nocov: + end return [] if no_core && fqns =~ /^(Object|BasicObject|Class|Module)$/ + # @todo should this by by rooted_tag_? reqstr = "#{fqns}|#{scope}|#{visibility.sort}|#{deep}" return [] if skip.include?(reqstr) skip.add reqstr @@ -770,7 +797,10 @@ def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false if scope == :instance store.get_includes(fqns).reverse.each do |include_tag| rooted_include_tag = qualify(include_tag, rooted_tag) - result.concat inner_get_methods_from_reference(rooted_include_tag, namespace_pin, rooted_type, scope, visibility, deep, skip, true) + if rooted_include_tag + result.concat inner_get_methods_from_reference(rooted_include_tag, namespace_pin, rooted_type, scope, + visibility, deep, skip, true) + end end rooted_sc_tag = qualify_superclass(rooted_tag) unless rooted_sc_tag.nil? @@ -864,16 +894,21 @@ def inner_qualify name, root, skip if root == '' return '' else + root = root[2..-1] if root&.start_with?('::') return inner_qualify(root, '', skip) end else - return name if root == '' && store.namespace_exists?(name) roots = root.to_s.split('::') while roots.length > 0 - fqns = roots.join('::') + '::' + name - return fqns if store.namespace_exists?(fqns) - incs = store.get_includes(roots.join('::')) + potential_root = roots.join('::') + potential_root = potential_root[2..-1] if potential_root.start_with?('::') + potential_fqns = potential_root + '::' + name + potential_fqns = potential_fqns[2..-1] if potential_fqns.start_with?('::') + fqns = resolve_fqns(potential_fqns) + return fqns if fqns + incs = store.get_includes(potential_root) incs.each do |inc| + next if potential_root == root && inc == name foundinc = inner_qualify(name, inc, skip) possibles.push foundinc unless foundinc.nil? end @@ -886,11 +921,54 @@ def inner_qualify name, root, skip possibles.push foundinc unless foundinc.nil? end end - return name if store.namespace_exists?(name) + resolved_fqns = resolve_fqns(name) + return resolved_fqns if resolved_fqns + return possibles.last end end + # @param fqns [String] + # @return [String, nil] + def resolve_fqns fqns + return fqns if store.namespace_exists?(fqns) + + constant_namespace = nil + constant = store.constant_pins.find do |c| + constant_fqns = if c.namespace.empty? + c.name + else + c.namespace + '::' + c.name + end + constant_namespace = c.namespace + constant_fqns == fqns + end + return nil unless constant + + return constant.return_type.namespace if constant.return_type.defined? + + assignment = constant.assignment + + # @sg-ignore Wrong argument type for Solargraph::ApiMap#resolve_trivial_constant: node expected AST::Node, received Parser::AST::Node, nil + target_ns = resolve_trivial_constant(assignment) if assignment + return nil unless target_ns + qualify_namespace target_ns, constant_namespace + end + + # @param node [AST::Node] + # @return [String, nil] + def resolve_trivial_constant node + return nil unless node.is_a?(::Parser::AST::Node) + return nil unless node.type == :const + return nil if node.children.empty? + prefix_node = node.children[0] + prefix = '' + prefix = resolve_trivial_constant(prefix_node) + '::' unless prefix_node.nil? || prefix_node.children.empty? + const_name = node.children[1].to_s + return nil if const_name.empty? + return prefix + const_name + end + # Get the namespace's type (Class or Module). # # @param fqns [String] A fully qualified namespace @@ -898,7 +976,7 @@ def inner_qualify name, root, skip def get_namespace_type fqns return nil if fqns.nil? # @type [Pin::Namespace, nil] - pin = store.get_path_pins(fqns).select{|p| p.is_a?(Pin::Namespace)}.first + pin = get_namespace_pin(fqns) return nil if pin.nil? pin.type end diff --git a/lib/solargraph/api_map/store.rb b/lib/solargraph/api_map/store.rb index 87f053596..3b3fffd69 100644 --- a/lib/solargraph/api_map/store.rb +++ b/lib/solargraph/api_map/store.rb @@ -73,13 +73,13 @@ def get_methods fqns, scope: :instance, visibility: [:public] def get_superclass fq_tag raise "Do not prefix fully qualified tags with '::' - #{fq_tag.inspect}" if fq_tag.start_with?('::') sub = ComplexType.parse(fq_tag) + return sub.simplify_literals.name if sub.literal? + return 'Boolean' if %w[TrueClass FalseClass].include?(fq_tag) fqns = sub.namespace return superclass_references[fq_tag].first if superclass_references.key?(fq_tag) return superclass_references[fqns].first if superclass_references.key?(fqns) return 'Object' if fqns != 'BasicObject' && namespace_exists?(fqns) return 'Object' if fqns == 'Boolean' - simplified_literal_name = ComplexType.parse("#{fqns}").simplify_literals.name - return simplified_literal_name if simplified_literal_name != fqns nil end @@ -143,6 +143,11 @@ def namespace_pins pins_by_class(Solargraph::Pin::Namespace) end + # @return [Enumerable] + def constant_pins + pins_by_class(Solargraph::Pin::Constant) + end + # @return [Enumerable] def method_pins pins_by_class(Solargraph::Pin::Method) diff --git a/lib/solargraph/complex_type.rb b/lib/solargraph/complex_type.rb index ac9599329..00dda2d3e 100644 --- a/lib/solargraph/complex_type.rb +++ b/lib/solargraph/complex_type.rb @@ -17,10 +17,13 @@ def initialize types = [UniqueType::UNDEFINED] # @todo @items here should not need an annotation # @type [Array] items = types.flat_map(&:items).uniq(&:to_s) + + # Canonicalize 'true, false' to the non-runtime-type 'Boolean' if items.any? { |i| i.name == 'false' } && items.any? { |i| i.name == 'true' } items.delete_if { |i| i.name == 'false' || i.name == 'true' } items.unshift(ComplexType::BOOLEAN) end + items = [UniqueType::UNDEFINED] if items.any?(&:undefined?) @items = items end diff --git a/lib/solargraph/complex_type/type_methods.rb b/lib/solargraph/complex_type/type_methods.rb index e6d596244..6bf383a1a 100644 --- a/lib/solargraph/complex_type/type_methods.rb +++ b/lib/solargraph/complex_type/type_methods.rb @@ -10,11 +10,7 @@ class ComplexType # @name: String # @subtypes: Array # @rooted: boolish - # methods: - # transform() - # all_params() - # rooted?() - # can_root_name?() + # methods: (see @!method declarations below) module TypeMethods # @!method transform(new_name = nil, &transform_type) # @param new_name [String, nil] @@ -24,6 +20,9 @@ module TypeMethods # @!method all_params # @return [Array] # @!method rooted? + # @!method literal? + # @!method simplify_literals + # @return [ComplexType::UniqueType, ComplexType] # @!method can_root_name?(name_to_check = nil) # @param name_to_check [String, nil] @@ -124,7 +123,8 @@ def key_types def namespace # if priority higher than ||=, old implements cause unnecessary check @namespace ||= lambda do - return 'Object' if duck_type? + return simplify_literals.namespace if literal? + return 'Object' if duck_type? || name == 'Boolean' return 'NilClass' if nil_type? return (name == 'Class' || name == 'Module') && !subtypes.empty? ? subtypes.first.name : name end.call diff --git a/lib/solargraph/complex_type/unique_type.rb b/lib/solargraph/complex_type/unique_type.rb index a782656f0..86a69fe0f 100644 --- a/lib/solargraph/complex_type/unique_type.rb +++ b/lib/solargraph/complex_type/unique_type.rb @@ -74,6 +74,8 @@ def initialize(name, key_types = [], subtypes = [], rooted:, parameters_type: ni if parameters_type.nil? raise "You must supply parameters_type if you provide parameters" unless key_types.empty? && subtypes.empty? end + + raise "name must be a String" unless name.is_a?(String) raise "Please remove leading :: and set rooted instead - #{name.inspect}" if name.start_with?('::') @name = name @parameters_type = parameters_type @@ -126,7 +128,8 @@ def determine_non_literal_name # | `false` return name if name.empty? return 'NilClass' if name == 'nil' - return 'Boolean' if ['true', 'false'].include?(name) + return 'TrueClass' if name == 'true' + return 'FalseClass' if name == 'false' return 'Symbol' if name[0] == ':' return 'String' if ['"', "'"].include?(name[0]) return 'Integer' if name.match?(/^-?\d+$/) diff --git a/lib/solargraph/parser/node_methods.rb b/lib/solargraph/parser/node_methods.rb deleted file mode 100644 index 5d3d1079a..000000000 --- a/lib/solargraph/parser/node_methods.rb +++ /dev/null @@ -1,97 +0,0 @@ -module Solargraph - module Parser - module NodeMethods - module_function - - # @abstract - # @param node [Parser::AST::Node] - # @return [String] - def unpack_name node - raise NotImplementedError - end - - # @abstract - # @todo Temporarily here for testing. Move to Solargraph::Parser. - # @param node [Parser::AST::Node] - # @return [Array] - def call_nodes_from node - raise NotImplementedError - end - - # Find all the nodes within the provided node that potentially return a - # value. - # - # The node parameter typically represents a method's logic, e.g., the - # second child (after the :args node) of a :def node. A simple one-line - # method would typically return itself, while a node with conditions - # would return the resulting node from each conditional branch. Nodes - # that follow a :return node are assumed to be unreachable. Nil values - # are converted to nil node types. - # - # @abstract - # @param node [Parser::AST::Node] - # @return [Array] - def returns_from_method_body node - raise NotImplementedError - end - - # @abstract - # @param node [Parser::AST::Node] - # - # @return [Array] - def const_nodes_from node - raise NotImplementedError - end - - # @abstract - # @param cursor [Solargraph::Source::Cursor] - # @return [Parser::AST::Node, nil] - def find_recipient_node cursor - raise NotImplementedError - end - - # @abstract - # @param node [Parser::AST::Node] - # @return [Array] low-level value nodes in - # value position. Does not include explicit return - # statements - def value_position_nodes_only(node) - raise NotImplementedError - end - - # @abstract - # @param nodes [Enumerable] - def any_splatted_call?(nodes) - raise NotImplementedError - end - - # @abstract - # @param node [Parser::AST::Node] - # @return [void] - def process node - raise NotImplementedError - end - - # @abstract - # @param node [Parser::AST::Node] - # @return [Hash{Parser::AST::Node => Source::Chain}] - def convert_hash node - raise NotImplementedError - end - - # @abstract - # @param node [Parser::AST::Node] - # @return [Position] - def get_node_start_position(node) - raise NotImplementedError - end - - # @abstract - # @param node [Parser::AST::Node] - # @return [Position] - def get_node_end_position(node) - raise NotImplementedError - end - end - end -end diff --git a/lib/solargraph/parser/parser_gem/node_methods.rb b/lib/solargraph/parser/parser_gem/node_methods.rb index 1397f9583..5b1c47996 100644 --- a/lib/solargraph/parser/parser_gem/node_methods.rb +++ b/lib/solargraph/parser/parser_gem/node_methods.rb @@ -120,7 +120,7 @@ def drill_signature node, signature end # @param node [Parser::AST::Node] - # @return [Hash{Parser::AST::Node => Chain}] + # @return [Hash{Parser::AST::Node, Symbol => Source::Chain}] def convert_hash node return {} unless Parser.is_ast_node?(node) return convert_hash(node.children[0]) if node.type == :kwsplat diff --git a/lib/solargraph/pin/base.rb b/lib/solargraph/pin/base.rb index fb3274dab..020d92def 100644 --- a/lib/solargraph/pin/base.rb +++ b/lib/solargraph/pin/base.rb @@ -300,8 +300,8 @@ def assert_same_count(other, attr) # # @return [Object, nil] def assert_same(other, attr) - return false if other.nil? val1 = send(attr) + return val1 if other.nil? val2 = other.send(attr) return val1 if val1 == val2 Solargraph.assert_or_log("combine_with_#{attr}".to_sym, diff --git a/lib/solargraph/rbs_map/conversions.rb b/lib/solargraph/rbs_map/conversions.rb index f8deec251..657ea982f 100644 --- a/lib/solargraph/rbs_map/conversions.rb +++ b/lib/solargraph/rbs_map/conversions.rb @@ -240,6 +240,7 @@ def module_decl_to_pin decl # # @return [Solargraph::Pin::Constant] def create_constant(name, tag, comments, decl, base = nil) + tag = "#{base}<#{tag}>" if base parts = name.split('::') if parts.length > 1 name = parts.last @@ -255,7 +256,6 @@ def create_constant(name, tag, comments, decl, base = nil) comments: comments, source: :rbs ) - tag = "#{base}<#{tag}>" if base rooted_tag = ComplexType.parse(tag).force_rooted.rooted_tags constant_pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', rooted_tag)) constant_pin diff --git a/spec/api_map/api_map_method_spec.rb b/spec/api_map/api_map_method_spec.rb new file mode 100644 index 000000000..a3adc9b94 --- /dev/null +++ b/spec/api_map/api_map_method_spec.rb @@ -0,0 +1,154 @@ +# frozen_string_literal: true + +describe Solargraph::ApiMap do + let(:api_map) { described_class.new } + let(:bench) do + Solargraph::Bench.new(external_requires: external_requires, workspace: Solargraph::Workspace.new('.')) + end + let(:external_requires) { [] } + + before do + api_map.catalog bench + end + + describe '#qualify' do + let(:external_requires) { ['yaml'] } + + it 'resolves YAML to Psych' do + expect(api_map.qualify('YAML', '')).to eq('Psych') + end + + it 'resolves constants used to alias namespaces' do + map = Solargraph::SourceMap.load_string(%( + class Foo + def bing; end + end + + module Bar + Baz = ::Foo + end + )) + api_map.index map.pins + fqns = api_map.qualify('Bar::Baz') + expect(fqns).to eq('Foo') + end + + it 'understands alias namespaces resolving types' do + source = Solargraph::Source.load_string(%( + class Foo + # @return [Symbol] + def bing; end + end + + module Bar + Baz = ::Foo + end + + a = Bar::Baz.new.bing + a + Bar::Baz + ), 'test.rb') + + api_map = described_class.new.map(source) + + clip = api_map.clip_at('test.rb', [11, 8]) + expect(clip.infer.to_s).to eq('Symbol') + end + + it 'understands nested alias namespaces to nested classes resolving types' do + source = Solargraph::Source.load_string(%( + module A + class Foo + # @return [Symbol] + def bing; end + end + end + + module Bar + Baz = A::Foo + end + + a = Bar::Baz.new.bing + a + ), 'test.rb') + + api_map = described_class.new.map(source) + + clip = api_map.clip_at('test.rb', [13, 8]) + expect(clip.infer.to_s).to eq('Symbol') + end + + it 'understands nested alias namespaces resolving types' do + source = Solargraph::Source.load_string(%( + module Bar + module A + class Foo + # @return [Symbol] + def bing; :bingo; end + end + end + end + + module Bar + Foo = A::Foo + end + + a = Bar::Foo.new.bing + a + ), 'test.rb') + + api_map = described_class.new.map(source) + + clip = api_map.clip_at('test.rb', [15, 8]) + expect(clip.infer.to_s).to eq('Symbol') + end + + it 'understands includes using nested alias namespaces resolving types' do + source = Solargraph::Source.load_string(%( + module Foo + # @return [Symbol] + def bing; :yay; end + end + + module Bar + Baz = Foo + end + + class B + include Foo + end + + a = B.new.bing + a + ), 'test.rb') + + api_map = described_class.new.map(source) + + clip = api_map.clip_at('test.rb', [15, 8]) + expect(clip.infer.to_s).to eq('Symbol') + end + end + + describe '#get_method_stack' do + let(:out) { StringIO.new } + let(:api_map) { described_class.load_with_cache(Dir.pwd, out) } + + context 'with stdlib that has vital dependencies' do + let(:external_requires) { ['yaml'] } + let(:method_stack) { api_map.get_method_stack('YAML', 'safe_load', scope: :class) } + + it 'handles the YAML gem aliased to Psych' do + expect(method_stack).not_to be_empty + end + end + + context 'with thor' do + let(:external_requires) { ['thor'] } + let(:method_stack) { api_map.get_method_stack('Thor', 'desc', scope: :class) } + + it 'handles finding Thor.desc' do + expect(method_stack).not_to be_empty + end + end + end +end diff --git a/spec/api_map_spec.rb b/spec/api_map_spec.rb index c95d4d8ec..494f9e156 100755 --- a/spec/api_map_spec.rb +++ b/spec/api_map_spec.rb @@ -1,6 +1,7 @@ require 'tmpdir' describe Solargraph::ApiMap do + # rubocop:disable RSpec/InstanceVariable before :all do @api_map = Solargraph::ApiMap.new end @@ -817,4 +818,62 @@ def baz clip = api_map.clip_at('test.rb', [11, 10]) expect(clip.infer.to_s).to eq('Symbol') end + + it 'resolves aliases in identically named deeply nested classes' do + source = Solargraph::Source.load_string(%( + module A + module Bar + # @return [Integer] + def quux; 123; end + end + + Baz = Bar + + class Foo + include Baz + end + end + + def c + b = A::Foo.new.quux + b + end + ), 'test.rb') + + api_map = described_class.new.map(source) + + clip = api_map.clip_at('test.rb', [16, 4]) + expect(clip.infer.to_s).to eq('Integer') + end + + it 'resolves aliases in nested classes' do + source = Solargraph::Source.load_string(%( + module A + module Bar + class Baz + # @return [Integer] + def quux; 123; end + end + end + + Baz = Bar::Baz + + class Foo + include Baz + end + end + + def c + b = A::Foo.new.quux + b + end + ), 'test.rb') + + api_map = described_class.new.map(source) + + clip = api_map.clip_at('test.rb', [18, 4]) + expect(clip.infer.to_s).to eq('Integer') + end + + # rubocop:enable RSpec/InstanceVariable end diff --git a/spec/convention/struct_definition_spec.rb b/spec/convention/struct_definition_spec.rb index fe317a42b..5c3fc5211 100644 --- a/spec/convention/struct_definition_spec.rb +++ b/spec/convention/struct_definition_spec.rb @@ -21,7 +21,7 @@ expect(param_baz.return_type.tag).to eql('Integer') end - it 'should set closure to method on assignment operator parameters' do + it 'sets closure to method on assignment operator parameters' do source = Solargraph::SourceMap.load_string(%( # @param bar [String] # @param baz [Integer] @@ -140,7 +140,7 @@ def type_checker code Solargraph::TypeChecker.load_string(code, 'test.rb', :strong) end - it 'should not crash' do + it "doesn't crash" do checker = type_checker(%( Foo = Struct.new(:bar, :baz) )) From 4a10b44b3802ea9bd077b7aaab0238b865363e82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lek=C3=AB=20Mula?= Date: Sun, 24 Aug 2025 19:46:19 +0200 Subject: [PATCH 021/106] Speed-up LSP completion response times (#1035) * Improve performance of resolve_method_aliases method - Add indexed lookups for methods and aliases by name - Cache ancestor traversal to avoid repeated computations - Separate regular pins from aliases for more efficient processing - Replace linear search with direct indexed method lookup - Add fast path for creating resolved alias pins without individual lookups Generated with Claude Code * Update .rubocop_todo.yml * Fix typechecking - get_method_stack order `get_method_stack` returns the following order for `Enumerable#select`: - master branch: => ["Enumerable#select", "Kernel#select"] - current branch: => ["Kernel#select", "Enumerable#select"] * Avoid redundant indexing methods_by_name loop through ancestors and rely on store.get_path_pins --- .rubocop_todo.yml | 2 - lib/solargraph/api_map.rb | 91 +++++++++++++++++++++------------ lib/solargraph/api_map/store.rb | 38 ++++++++++++++ spec/api_map_spec.rb | 12 ++--- 4 files changed, 103 insertions(+), 40 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 14cc0ca5d..f400dcfaf 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -77,7 +77,6 @@ Layout/ClosingHeredocIndentation: # Configuration parameters: AllowForAlignment. Layout/CommentIndentation: Exclude: - - 'lib/solargraph/api_map.rb' - 'lib/solargraph/language_server/host.rb' - 'lib/solargraph/parser/parser_gem/node_methods.rb' - 'lib/solargraph/source_map/mapper.rb' @@ -2656,7 +2655,6 @@ YARD/MismatchName: - 'lib/solargraph/pin/until.rb' - 'lib/solargraph/pin/while.rb' - 'lib/solargraph/pin_cache.rb' - - 'lib/solargraph/source/chain.rb' - 'lib/solargraph/source/chain/call.rb' - 'lib/solargraph/source/chain/z_super.rb' - 'lib/solargraph/type_checker.rb' diff --git a/lib/solargraph/api_map.rb b/lib/solargraph/api_map.rb index 9db21128f..89ed3a308 100755 --- a/lib/solargraph/api_map.rb +++ b/lib/solargraph/api_map.rb @@ -26,7 +26,6 @@ class ApiMap def initialize pins: [] @source_map_hash = {} @cache = Cache.new - @method_alias_stack = [] index pins end @@ -687,6 +686,7 @@ def type_include?(host_ns, module_ns) # @return [Array] def resolve_method_aliases pins, visibility = [:public, :private, :protected] with_resolved_aliases = pins.map do |pin| + next pin unless pin.is_a?(Pin::MethodAlias) resolved = resolve_method_alias(pin) next nil if resolved.respond_to?(:visibility) && !visibility.include?(resolved.visibility) resolved @@ -998,49 +998,76 @@ def prefer_non_nil_variables pins result + nil_pins end - # @param pin [Pin::MethodAlias, Pin::Base] - # @return [Pin::Method] - def resolve_method_alias pin - return pin unless pin.is_a?(Pin::MethodAlias) - return nil if @method_alias_stack.include?(pin.path) - @method_alias_stack.push pin.path - origin = get_method_stack(pin.full_context.tag, pin.original, scope: pin.scope, preserve_generics: true).first - @method_alias_stack.pop - return nil if origin.nil? + include Logging + + private + + # @param alias_pin [Pin::MethodAlias] + # @return [Pin::Method, nil] + def resolve_method_alias(alias_pin) + ancestors = store.get_ancestors(alias_pin.full_context.tag) + original = nil + + # Search each ancestor for the original method + ancestors.each do |ancestor_fqns| + ancestor_fqns = ComplexType.parse(ancestor_fqns).force_rooted.namespace + ancestor_method_path = "#{ancestor_fqns}#{alias_pin.scope == :instance ? '#' : '.'}#{alias_pin.original}" + + # Search for the original method in the ancestor + original = store.get_path_pins(ancestor_method_path).find do |candidate_pin| + if candidate_pin.is_a?(Pin::MethodAlias) + # recursively resolve method aliases + resolved = resolve_method_alias(candidate_pin) + break resolved if resolved + end + + candidate_pin.is_a?(Pin::Method) && candidate_pin.scope == alias_pin.scope + end + + break if original + end + + # @sg-ignore ignore `received nil` for original + create_resolved_alias_pin(alias_pin, original) if original + end + + # Fast path for creating resolved alias pins without individual method stack lookups + # @param alias_pin [Pin::MethodAlias] The alias pin to resolve + # @param original [Pin::Method] The original method pin that was already found + # @return [Pin::Method] The resolved method pin + def create_resolved_alias_pin(alias_pin, original) + # Build the resolved method pin directly (same logic as resolve_method_alias but without lookup) args = { - location: pin.location, - type_location: origin.type_location, - closure: pin.closure, - name: pin.name, - comments: origin.comments, - scope: origin.scope, -# context: pin.context, - visibility: origin.visibility, - signatures: origin.signatures.map(&:clone).freeze, - attribute: origin.attribute?, - generics: origin.generics.clone, - return_type: origin.return_type, + location: alias_pin.location, + type_location: original.type_location, + closure: alias_pin.closure, + name: alias_pin.name, + comments: original.comments, + scope: original.scope, + visibility: original.visibility, + signatures: original.signatures.map(&:clone).freeze, + attribute: original.attribute?, + generics: original.generics.clone, + return_type: original.return_type, source: :resolve_method_alias } - out = Pin::Method.new **args - out.signatures.each do |sig| + resolved_pin = Pin::Method.new **args + + # Clone signatures and parameters + resolved_pin.signatures.each do |sig| sig.parameters = sig.parameters.map(&:clone).freeze sig.source = :resolve_method_alias sig.parameters.each do |param| - param.closure = out + param.closure = resolved_pin param.source = :resolve_method_alias param.reset_generated! end - sig.closure = out + sig.closure = resolved_pin sig.reset_generated! end - logger.debug { "ApiMap#resolve_method_alias(pin=#{pin}) - returning #{out} from #{origin}" } - out - end - include Logging - - private + resolved_pin + end # @param namespace_pin [Pin::Namespace] # @param rooted_type [ComplexType] diff --git a/lib/solargraph/api_map/store.rb b/lib/solargraph/api_map/store.rb index 3b3fffd69..6479e6039 100644 --- a/lib/solargraph/api_map/store.rb +++ b/lib/solargraph/api_map/store.rb @@ -204,6 +204,44 @@ def fqns_pins fqns fqns_pins_map[[base, name]] end + # Get all ancestors (superclasses, includes, prepends, extends) for a namespace + # @param fqns [String] The fully qualified namespace + # @return [Array] Array of ancestor namespaces including the original + def get_ancestors(fqns) + return [] if fqns.nil? || fqns.empty? + + ancestors = [fqns] + visited = Set.new + queue = [fqns] + + until queue.empty? + current = queue.shift + next if current.nil? || current.empty? || visited.include?(current) + visited.add(current) + + current = current.gsub(/^::/, '') + + # Add superclass + superclass = get_superclass(current) + if superclass && !superclass.empty? && !visited.include?(superclass) + ancestors << superclass + queue << superclass + end + + # Add includes, prepends, and extends + [get_includes(current), get_prepends(current), get_extends(current)].each do |refs| + next if refs.nil? + refs.each do |ref| + next if ref.nil? || ref.empty? || visited.include?(ref) + ancestors << ref + queue << ref + end + end + end + + ancestors.compact.uniq + end + private # @return [Index] diff --git a/spec/api_map_spec.rb b/spec/api_map_spec.rb index 494f9e156..b447e3fd3 100755 --- a/spec/api_map_spec.rb +++ b/spec/api_map_spec.rb @@ -210,19 +210,19 @@ def prot it 'finds stacks of methods' do map = Solargraph::SourceMap.load_string(%( module Mixin - def meth; end + def select; end end - class Foo + class Foo < Array include Mixin - def meth; end + def select; end end class Bar < Foo - def meth; end + def select; end end )) @api_map.index map.pins - pins = @api_map.get_method_stack('Bar', 'meth') - expect(pins.map(&:path)).to eq(['Bar#meth', 'Foo#meth', 'Mixin#meth']) + pins = @api_map.get_method_stack('Bar', 'select') + expect(pins.map(&:path)).to eq(['Bar#select', 'Foo#select', 'Mixin#select', 'Array#select', 'Enumerable#select', 'Kernel#select']) end it 'finds symbols' do From d1e6b128e289ff8ef4ed8bd4c563ec297fcea486 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Wed, 27 Aug 2025 13:18:41 -0400 Subject: [PATCH 022/106] RuboCop todo update --- .rubocop_todo.yml | 43 +++++++++++---------------------------- lib/solargraph/api_map.rb | 2 +- lib/solargraph/shell.rb | 5 +++++ spec/shell_spec.rb | 8 +++++--- spec/spec_helper.rb | 1 - 5 files changed, 23 insertions(+), 36 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index f400dcfaf..d32ff61cb 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,51 +1,44 @@ # This configuration was generated by # `rubocop --auto-gen-config --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp` -# using RuboCop version 1.79.2. +# using RuboCop version 1.80.1. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: Include. -# Include: **/*.gemspec Gemspec/AddRuntimeDependency: Exclude: - 'solargraph.gemspec' # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: Severity, Include. -# Include: **/*.gemspec +# Configuration parameters: Severity. Gemspec/DeprecatedAttributeAssignment: Exclude: - 'solargraph.gemspec' - 'spec/fixtures/rdoc-lib/rdoc-lib.gemspec' -# Configuration parameters: EnforcedStyle, AllowedGems, Include. +# Configuration parameters: EnforcedStyle, AllowedGems. # SupportedStyles: Gemfile, gems.rb, gemspec -# Include: **/*.gemspec, **/Gemfile, **/gems.rb Gemspec/DevelopmentDependencies: Exclude: - 'solargraph.gemspec' # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation, Include. -# Include: **/*.gemspec +# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation. Gemspec/OrderedDependencies: Exclude: - 'solargraph.gemspec' # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: Severity, Include. -# Include: **/*.gemspec +# Configuration parameters: Severity. Gemspec/RequireMFA: Exclude: - 'solargraph.gemspec' - 'spec/fixtures/rdoc-lib/rdoc-lib.gemspec' - 'spec/fixtures/rubocop-custom-version/specifications/rubocop-0.0.0.gemspec' -# Configuration parameters: Severity, Include. -# Include: **/*.gemspec +# Configuration parameters: Severity. Gemspec/RequiredRubyVersion: Exclude: - 'spec/fixtures/rdoc-lib/rdoc-lib.gemspec' @@ -622,7 +615,7 @@ Lint/UnmodifiedReduceAccumulator: - 'lib/solargraph/pin/method.rb' # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AutoCorrect, IgnoreEmptyBlocks, AllowUnusedKeywordArguments. +# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments. Lint/UnusedBlockArgument: Exclude: - 'lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb' @@ -630,7 +623,7 @@ Lint/UnusedBlockArgument: - 'spec/language_server/transport/data_reader_spec.rb' # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AutoCorrect, AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions. +# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions. # NotImplementedExceptions: NotImplementedError Lint/UnusedMethodArgument: Exclude: @@ -660,13 +653,12 @@ Lint/UnusedMethodArgument: - 'spec/doc_map_spec.rb' # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AutoCorrect, ContextCreatingMethods, MethodCreatingMethods. +# Configuration parameters: ContextCreatingMethods, MethodCreatingMethods. Lint/UselessAccessModifier: Exclude: - 'lib/solargraph/api_map.rb' # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AutoCorrect. Lint/UselessAssignment: Exclude: - 'lib/solargraph/doc_map.rb' @@ -697,7 +689,6 @@ Lint/UselessConstantScoping: - 'lib/solargraph/rbs_map/conversions.rb' # This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: AutoCorrect. Lint/UselessMethodDefinition: Exclude: - 'lib/solargraph/pin/signature.rb' @@ -1009,7 +1000,6 @@ RSpec/DescribedClass: - 'spec/yard_map/mapper_spec.rb' # This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: AutoCorrect. RSpec/EmptyExampleGroup: Exclude: - 'spec/convention_spec.rb' @@ -1109,16 +1099,10 @@ RSpec/LeakyConstantDeclaration: - 'spec/complex_type_spec.rb' # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AutoCorrect. RSpec/LetBeforeExamples: Exclude: - 'spec/complex_type_spec.rb' -# Configuration parameters: . -# SupportedStyles: have_received, receive -RSpec/MessageSpies: - EnforcedStyle: receive - RSpec/MissingExampleGroupArgument: Exclude: - 'spec/diagnostics/rubocop_helpers_spec.rb' @@ -1267,13 +1251,11 @@ RSpec/RepeatedExample: - 'spec/type_checker/levels/strict_spec.rb' # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AutoCorrect. RSpec/ScatteredLet: Exclude: - 'spec/complex_type_spec.rb' -# Configuration parameters: Include, CustomTransform, IgnoreMethods, IgnoreMetadata. -# Include: **/*_spec.rb +# Configuration parameters: CustomTransform, IgnoreMethods, IgnoreMetadata. RSpec/SpecFilePathFormat: Exclude: - '**/spec/routing/**/*' @@ -1703,7 +1685,7 @@ Style/EmptyLambdaParameter: - 'spec/rbs_map/core_map_spec.rb' # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AutoCorrect, EnforcedStyle. +# Configuration parameters: EnforcedStyle. # SupportedStyles: compact, expanded Style/EmptyMethod: Exclude: @@ -1842,7 +1824,6 @@ Style/FrozenStringLiteralComment: - 'spec/rbs_map/core_map_spec.rb' - 'spec/rbs_map/stdlib_map_spec.rb' - 'spec/rbs_map_spec.rb' - - 'spec/shell_spec.rb' - 'spec/source/chain/array_spec.rb' - 'spec/source/chain/call_spec.rb' - 'spec/source/chain/class_variable_spec.rb' @@ -2234,7 +2215,7 @@ Style/RedundantFreeze: - 'lib/solargraph/source_map/mapper.rb' # This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: AutoCorrect, AllowComments. +# Configuration parameters: AllowComments. Style/RedundantInitialize: Exclude: - 'lib/solargraph/rbs_map/core_map.rb' diff --git a/lib/solargraph/api_map.rb b/lib/solargraph/api_map.rb index 89ed3a308..9231e6a59 100755 --- a/lib/solargraph/api_map.rb +++ b/lib/solargraph/api_map.rb @@ -568,7 +568,7 @@ def get_path_suggestions path # Get an array of pins that match the specified path. # # @param path [String] - # @return [Enumerable] + # @return [Array] def get_path_pins path get_path_suggestions(path) end diff --git a/lib/solargraph/shell.rb b/lib/solargraph/shell.rb index 48d636bc2..40f5f4323 100755 --- a/lib/solargraph/shell.rb +++ b/lib/solargraph/shell.rb @@ -249,12 +249,17 @@ def list def method_pin path api_map = Solargraph::ApiMap.load_with_cache('.', $stderr) + # @type [Array] pins = if options[:stack] scope, ns, meth = if path.include? '#' [:instance, *path.split('#', 2)] else [:class, *path.split('.', 2)] end + + # @sg-ignore Wrong argument type for + # Solargraph::ApiMap#get_method_stack: rooted_tag + # expected String, received Array api_map.get_method_stack(ns, meth, scope: scope) else api_map.get_path_pins path diff --git a/spec/shell_spec.rb b/spec/shell_spec.rb index f2eba6a83..cdc0d09fc 100644 --- a/spec/shell_spec.rb +++ b/spec/shell_spec.rb @@ -5,7 +5,7 @@ describe Solargraph::Shell do let(:shell) { described_class.new } - + let(:temp_dir) { Dir.mktmpdir } before do @@ -42,7 +42,9 @@ def bundle_exec(*cmd) it "uncaches without erroring out" do output = bundle_exec("solargraph", "uncache", "solargraph") - expect(output).to include('Clearing pin cache in') + expect(output).to include('Clearing pin cache in') + end + end # @type cmd [Array] # @return [String] @@ -95,7 +97,7 @@ def bundle_exec(*cmd) shell.options = { stack: true } shell.method_pin('String#to_s') end - expect(api_map).to have_received(:get_method_stack).with('String', 'to_s', scope: :instance) + expect(api_map).to haveo_received(:get_method_stack).with('String', 'to_s', scope: :instance) end it 'prints a static pin using stack results' do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 3e2631976..59d107aa3 100755 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -44,7 +44,6 @@ def with_env_var(name, value) end end - def capture_stdout &block original_stdout = $stdout $stdout = StringIO.new From 5b612ddee00a78208206095ec32c4bc661820df8 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Wed, 27 Aug 2025 13:21:21 -0400 Subject: [PATCH 023/106] Try rbs collection update before specs --- .github/workflows/rspec.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index ecc3d9771..9c0fe219e 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -48,6 +48,9 @@ jobs: run: | bundle install bundle update rbs # use latest available for this Ruby version + - name: Update types + run: | + bundle update rbs collection update - name: Run tests run: bundle exec rake spec undercover: From f2291f4eadf8cf69b4f9f6baa18908a71e40cbbe Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Wed, 27 Aug 2025 16:14:24 -0400 Subject: [PATCH 024/106] RuboCop fixes --- spec/doc_map_spec.rb | 3 ++- spec/language_server/host/diagnoser_spec.rb | 3 ++- spec/language_server/host/message_worker_spec.rb | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/spec/doc_map_spec.rb b/spec/doc_map_spec.rb index b03e573f0..a13308bf6 100644 --- a/spec/doc_map_spec.rb +++ b/spec/doc_map_spec.rb @@ -42,8 +42,9 @@ it 'does not warn for redundant requires' do # Requiring 'set' is unnecessary because it's already included in core. It # might make sense to log redundant requires, but a warning is overkill. - expect(Solargraph.logger).not_to receive(:warn).with(/path set/) + allow(Solargraph.logger).to receive(:warn).and_call_original Solargraph::DocMap.new(['set'], []) + expect(Solargraph.logger).not_to have_received(:warn).with(/path set/) end it 'ignores nil requires' do diff --git a/spec/language_server/host/diagnoser_spec.rb b/spec/language_server/host/diagnoser_spec.rb index d59a843f1..69ee0b866 100644 --- a/spec/language_server/host/diagnoser_spec.rb +++ b/spec/language_server/host/diagnoser_spec.rb @@ -3,7 +3,8 @@ host = double(Solargraph::LanguageServer::Host, options: { 'diagnostics' => true }, synchronizing?: false) diagnoser = Solargraph::LanguageServer::Host::Diagnoser.new(host) diagnoser.schedule 'file.rb' - expect(host).to receive(:diagnose).with('file.rb') + allow(host).to receive(:diagnose) diagnoser.tick + expect(host).to have_received(:diagnose).with('file.rb') end end diff --git a/spec/language_server/host/message_worker_spec.rb b/spec/language_server/host/message_worker_spec.rb index b9ce2a41f..5e5bef481 100644 --- a/spec/language_server/host/message_worker_spec.rb +++ b/spec/language_server/host/message_worker_spec.rb @@ -2,11 +2,12 @@ it "handle requests on queue" do host = double(Solargraph::LanguageServer::Host) message = {'method' => '$/example'} - expect(host).to receive(:receive).with(message).and_return(nil) + allow(host).to receive(:receive).with(message).and_return(nil) worker = Solargraph::LanguageServer::Host::MessageWorker.new(host) worker.queue(message) expect(worker.messages).to eq [message] worker.tick + expect(host).to have_received(:receive).with(message) end end From be46aa30a4951813535e34f3b540fde75a5fb12f Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Wed, 27 Aug 2025 16:26:40 -0400 Subject: [PATCH 025/106] Add @sg-ignores --- lib/solargraph/shell.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/solargraph/shell.rb b/lib/solargraph/shell.rb index 40f5f4323..0200cc624 100755 --- a/lib/solargraph/shell.rb +++ b/lib/solargraph/shell.rb @@ -239,16 +239,22 @@ def list puts "#{workspace.filenames.length} files total." end + # @sg-ignore Unresolved call to desc desc 'method_pin [PATH]', 'Describe a method pin' + # @sg-ignore Unresolved call to option option :rbs, type: :boolean, desc: 'Output the pin as RBS', default: false + # @sg-ignore Unresolved call to option option :typify, type: :boolean, desc: 'Output the calculated return type of the pin from annotations', default: false + # @sg-ignore Unresolved call to option option :probe, type: :boolean, desc: 'Output the calculated return type of the pin from annotations and inference', default: false + # @sg-ignore Unresolved call to option option :stack, type: :boolean, desc: 'Show entire stack by including definitions in superclasses', default: false # @param path [String] The path to the method pin, e.g. 'Class#method' or 'Class.method' # @return [void] def method_pin path api_map = Solargraph::ApiMap.load_with_cache('.', $stderr) + # @sg-ignore Unresolved call to options # @type [Array] pins = if options[:stack] scope, ns, meth = if path.include? '#' @@ -269,9 +275,12 @@ def method_pin path exit 1 end pins.each do |pin| + # @sg-ignore Unresolved call to options if options[:typify] || options[:probe] type = ComplexType::UNDEFINED + # @sg-ignore Unresolved call to options type = pin.typify(api_map) if options[:typify] + # @sg-ignore Unresolved call to options type = pin.probe(api_map) if options[:probe] && type.undefined? print_type(type) next @@ -311,6 +320,7 @@ def do_cache gemspec, api_map # @param type [ComplexType] # @return [void] def print_type(type) + # @sg-ignore Unresolved call to options if options[:rbs] puts type.to_rbs else @@ -321,6 +331,7 @@ def print_type(type) # @param pin [Solargraph::Pin::Base] # @return [void] def print_pin(pin) + # @sg-ignore Unresolved call to options if options[:rbs] puts pin.to_rbs else From 0927309cf2d4ff598feff0058fc04bcd9e44bad0 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Wed, 27 Aug 2025 17:11:04 -0400 Subject: [PATCH 026/106] Fix typo --- .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 9c0fe219e..8f6dac24d 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -50,7 +50,7 @@ jobs: bundle update rbs # use latest available for this Ruby version - name: Update types run: | - bundle update rbs collection update + bundle exec rbs collection update - name: Run tests run: bundle exec rake spec undercover: From 78995508e6bf35ce1e8c9b2ee4693e71bec52981 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Wed, 27 Aug 2025 17:15:16 -0400 Subject: [PATCH 027/106] Exclude problematic combinations on Ruby head --- .github/workflows/rspec.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index 8f6dac24d..b06f1425e 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -29,7 +29,15 @@ jobs: rbs-version: '3.9.4' - ruby-version: '3.0' rbs-version: '4.0.0.dev.4' - steps: + # Missing require in 'rbs collection update' - hopefully + # fixed in next RBS release + - ruby-version: 'head' + rbs-version: '4.0.0.dev.4' + - ruby-version: 'head' + rbs-version: '3.9.4' + - ruby-version: 'head' + rbs-version: '3.6.1' + steps: - uses: actions/checkout@v3 - name: Set up Ruby uses: ruby/setup-ruby@v1 From d5d6c5fb74415521d5daab6e91aa9ff4e19ada57 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Wed, 27 Aug 2025 17:20:49 -0400 Subject: [PATCH 028/106] Fix indentation --- .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 b06f1425e..7e2c4b9c9 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -37,7 +37,7 @@ jobs: rbs-version: '3.9.4' - ruby-version: 'head' rbs-version: '3.6.1' - steps: + steps: - uses: actions/checkout@v3 - name: Set up Ruby uses: ruby/setup-ruby@v1 From 2c6cacd9a2e9c41bdf6a5085e4d263017a392498 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Wed, 27 Aug 2025 17:28:18 -0400 Subject: [PATCH 029/106] method_pin -> pin, hide command --- lib/solargraph/shell.rb | 6 +++--- spec/shell_spec.rb | 18 +++++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/solargraph/shell.rb b/lib/solargraph/shell.rb index 0200cc624..21a53172f 100755 --- a/lib/solargraph/shell.rb +++ b/lib/solargraph/shell.rb @@ -240,7 +240,7 @@ def list end # @sg-ignore Unresolved call to desc - desc 'method_pin [PATH]', 'Describe a method pin' + desc 'pin [PATH]', 'Describe a pin', hide: true # @sg-ignore Unresolved call to option option :rbs, type: :boolean, desc: 'Output the pin as RBS', default: false # @sg-ignore Unresolved call to option @@ -248,10 +248,10 @@ def list # @sg-ignore Unresolved call to option option :probe, type: :boolean, desc: 'Output the calculated return type of the pin from annotations and inference', default: false # @sg-ignore Unresolved call to option - option :stack, type: :boolean, desc: 'Show entire stack by including definitions in superclasses', default: false + option :stack, type: :boolean, desc: 'Show entire stack of a method pin by including definitions in superclasses', default: false # @param path [String] The path to the method pin, e.g. 'Class#method' or 'Class.method' # @return [void] - def method_pin path + def pin path api_map = Solargraph::ApiMap.load_with_cache('.', $stderr) # @sg-ignore Unresolved call to options diff --git a/spec/shell_spec.rb b/spec/shell_spec.rb index cdc0d09fc..e3c85c6e0 100644 --- a/spec/shell_spec.rb +++ b/spec/shell_spec.rb @@ -57,7 +57,7 @@ def bundle_exec(*cmd) end end - describe 'method_pin' do + describe 'pin' do let(:api_map) { instance_double(Solargraph::ApiMap) } let(:to_s_pin) { instance_double(Solargraph::Pin::Method, return_type: Solargraph::ComplexType.parse('String')) } @@ -70,7 +70,7 @@ def bundle_exec(*cmd) it 'prints a pin' do allow(to_s_pin).to receive(:inspect).and_return('pin inspect result') - out = capture_both { shell.method_pin('String#to_s') } + out = capture_both { shell.pin('String#to_s') } expect(out).to eq("pin inspect result\n") end @@ -82,7 +82,7 @@ def bundle_exec(*cmd) out = capture_both do shell.options = { rbs: true } - shell.method_pin('String#to_s') + shell.pin('String#to_s') end expect(out).to eq("pin RBS result\n") end @@ -95,9 +95,9 @@ def bundle_exec(*cmd) allow(api_map).to receive(:get_method_stack).and_return([to_s_pin]) capture_both do shell.options = { stack: true } - shell.method_pin('String#to_s') + shell.pin('String#to_s') end - expect(api_map).to haveo_received(:get_method_stack).with('String', 'to_s', scope: :instance) + expect(api_map).to have_received(:get_method_stack).with('String', 'to_s', scope: :instance) end it 'prints a static pin using stack results' do @@ -107,7 +107,7 @@ def bundle_exec(*cmd) allow(api_map).to receive(:get_method_stack).with('String', 'new', scope: :class).and_return([string_new_pin]) capture_both do shell.options = { stack: true } - shell.method_pin('String.new') + shell.pin('String.new') end expect(api_map).to have_received(:get_method_stack).with('String', 'new', scope: :class) end @@ -119,7 +119,7 @@ def bundle_exec(*cmd) out = capture_both do shell.options = { typify: true } - shell.method_pin('String#to_s') + shell.pin('String#to_s') end expect(out).to eq("::String\n") end @@ -131,7 +131,7 @@ def bundle_exec(*cmd) out = capture_both do shell.options = { typify: true, rbs: true } - shell.method_pin('String#to_s') + shell.pin('String#to_s') end expect(out).to eq("::String\n") end @@ -143,7 +143,7 @@ def bundle_exec(*cmd) out = capture_both do shell.options = {} - shell.method_pin('Not#found') + shell.pin('Not#found') rescue SystemExit # Ignore the SystemExit raised by the shell when no pin is found end From 56636ae7022c3cc9c47b729e25c42d816243bdb9 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Wed, 27 Aug 2025 17:40:15 -0400 Subject: [PATCH 030/106] Fix type --- lib/solargraph/api_map.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/solargraph/api_map.rb b/lib/solargraph/api_map.rb index 9231e6a59..4e8332080 100755 --- a/lib/solargraph/api_map.rb +++ b/lib/solargraph/api_map.rb @@ -559,7 +559,7 @@ def get_method_stack rooted_tag, name, scope: :instance, visibility: [:private, # @deprecated Use #get_path_pins instead. # # @param path [String] The path to find - # @return [Enumerable] + # @return [Array] def get_path_suggestions path return [] if path.nil? resolve_method_aliases store.get_path_pins(path) From 447c778642edfef4adc62d2af3526f730417342c Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Fri, 29 Aug 2025 12:05:14 -0400 Subject: [PATCH 031/106] Make 'self' types concrete while checking arguments --- lib/solargraph/type_checker.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/solargraph/type_checker.rb b/lib/solargraph/type_checker.rb index e0b23f56b..dd13d7ec7 100644 --- a/lib/solargraph/type_checker.rb +++ b/lib/solargraph/type_checker.rb @@ -411,6 +411,7 @@ def signature_argument_problems_for location, locals, closure_pin, params, argum # @todo Some level (strong, I guess) should require the param here else argtype = argchain.infer(api_map, closure_pin, locals) + argtype = argtype.self_to_type(closure_pin.context) if argtype.defined? && ptype.defined? && !any_types_match?(api_map, ptype, argtype) errors.push Problem.new(location, "Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}") return errors @@ -450,8 +451,10 @@ def kwarg_problems_for sig, argchain, api_map, block_pin, locals, location, pin, # @todo Some level (strong, I guess) should require the param here else ptype = data[:qualified] + ptype = ptype.self_to_type(pin.context) unless ptype.undefined? argtype = argchain.infer(api_map, block_pin, locals) + argtype = argtype.self_to_type(block_pin.context) if argtype.defined? && ptype && !any_types_match?(api_map, ptype, argtype) result.push Problem.new(location, "Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}") end @@ -477,7 +480,9 @@ def kwrestarg_problems_for(api_map, block_pin, locals, location, pin, params, kw kwargs.each_pair do |pname, argchain| next unless params.key?(pname.to_s) ptype = params[pname.to_s][:qualified] + ptype = ptype.self_to_type(pin.context) argtype = argchain.infer(api_map, block_pin, locals) + argtype = argtype.self_to_type(block_pin.context) if argtype.defined? && ptype && !any_types_match?(api_map, ptype, argtype) result.push Problem.new(location, "Wrong argument type for #{pin.path}: #{pname} expected #{ptype}, received #{argtype}") end From 36383596fa21593bb6db0f7fffa343b37141aa75 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Fri, 29 Aug 2025 12:51:12 -0400 Subject: [PATCH 032/106] strict -> strong --- .github/workflows/typecheck.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml index 4cde97763..f40977acf 100644 --- a/.github/workflows/typecheck.yml +++ b/.github/workflows/typecheck.yml @@ -18,7 +18,7 @@ permissions: jobs: solargraph_typed: - name: Solargraph / typed + name: Solargraph / strong runs-on: ubuntu-latest @@ -36,4 +36,4 @@ jobs: - name: Install gem types run: bundle exec rbs collection install - name: Typecheck self - run: SOLARGRAPH_ASSERTS=on bundle exec solargraph typecheck --level strict \ No newline at end of file + run: SOLARGRAPH_ASSERTS=on bundle exec solargraph typecheck --level strong From b4a2ab1443bab5bc083339ffcdbc23d81c463959 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Fri, 29 Aug 2025 12:53:22 -0400 Subject: [PATCH 033/106] Also change default in Rakefile --- Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index 0e20d1280..c83d9ab6b 100755 --- a/Rakefile +++ b/Rakefile @@ -9,7 +9,7 @@ task :console do end desc "Run the type checker" -task typecheck: [:typecheck_strict] +task typecheck: [:typecheck_strong] desc "Run the type checker at typed level - return code issues provable without annotations being correct" task :typecheck_typed do From 6acfa0c54a806da203daf30765c7a99a67066f16 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 30 Aug 2025 09:06:14 -0400 Subject: [PATCH 034/106] RuboCop todo file stability To avoid merge conflicts and contributors having to deal with non-intuitive RuboCop todo changes: * Lock down development versions of RuboCop and plugins so that unrelated PRs aren't affected by newly implemented RuboCop rules. * Exclude rule entirely if more than 5 files violate it today, so that PRs are less likely to cause todo file changes unless they are specifically targeted at cleanup. * Clarify guidance on RuboCop todo file in CI error message. * Fix to hopefully ensure guidance always appears in CI error message. --- .github/workflows/linting.yml | 6 +- .rubocop.yml | 1 - .rubocop_todo.yml | 1588 ++------------------------------- solargraph.gemspec | 13 +- 4 files changed, 98 insertions(+), 1510 deletions(-) diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 8abbf51ef..aa22ce22c 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -115,11 +115,13 @@ jobs: - name: Run RuboCop against todo file continue-on-error: true run: | - bundle exec rubocop --auto-gen-config --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp + cmd="bundle exec rubocop --auto-gen-config --exclude-limit=5 --no-offense-counts --no-auto-gen-timestampxb*com" + ${cmd:?} + set +e if [ -n "$(git status --porcelain)" ] then git status --porcelain git diff -u . - >&2 echo "Please fix deltas if bad or run 'bundle exec rubocop --auto-gen-config --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp' and push up changes if good" + >&2 echo "Please address any new issues, then run '${cmd:?}' and push up any improvements" exit 1 fi diff --git a/.rubocop.yml b/.rubocop.yml index a73324db2..c7643c3c6 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -34,7 +34,6 @@ Metrics/ParameterLists: Max: 7 CountKeywordArgs: false - # we tend to use @@ and the risk doesn't seem high Style/ClassVars: Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index f3f0069f3..bf6b2272a 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,5 +1,5 @@ # This configuration was generated by -# `rubocop --auto-gen-config --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp` +# `rubocop --auto-gen-config --exclude-limit 5 --no-offense-counts --no-auto-gen-timestamp` # using RuboCop version 1.79.2. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. @@ -83,23 +83,7 @@ Layout/CommentIndentation: # This cop supports safe autocorrection (--autocorrect). Layout/ElseAlignment: - Exclude: - - 'lib/solargraph.rb' - - 'lib/solargraph/api_map/store.rb' - - 'lib/solargraph/diagnostics/rubocop.rb' - - 'lib/solargraph/language_server/message/extended/check_gem_version.rb' - - 'lib/solargraph/library.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/block_node.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/pin/namespace.rb' - - 'lib/solargraph/rbs_map.rb' - - 'lib/solargraph/shell.rb' - - 'lib/solargraph/source/chain/call.rb' - - 'lib/solargraph/source_map/clip.rb' - - 'lib/solargraph/source_map/mapper.rb' - - 'lib/solargraph/type_checker/rules.rb' - - 'lib/solargraph/yard_map/mapper.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EmptyLineBetweenMethodDefs, EmptyLineBetweenClassDefs, EmptyLineBetweenModuleDefs, DefLikeMacros, AllowAdjacentOneLineDefs, NumberOfEmptyLines. @@ -111,18 +95,7 @@ Layout/EmptyLineBetweenDefs: # This cop supports safe autocorrection (--autocorrect). Layout/EmptyLines: - Exclude: - - 'lib/solargraph/bench.rb' - - 'lib/solargraph/complex_type/unique_type.rb' - - 'lib/solargraph/doc_map.rb' - - 'lib/solargraph/language_server/message/extended/check_gem_version.rb' - - 'lib/solargraph/language_server/message/initialize.rb' - - 'lib/solargraph/pin/delegated_method.rb' - - 'lib/solargraph/rbs_map/conversions.rb' - - 'spec/complex_type_spec.rb' - - 'spec/pin/local_variable_spec.rb' - - 'spec/pin/symbol_spec.rb' - - 'spec/type_checker/levels/strict_spec.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle. @@ -142,23 +115,7 @@ Layout/EmptyLinesAroundModuleBody: # Configuration parameters: EnforcedStyleAlignWith, Severity. # SupportedStylesAlignWith: keyword, variable, start_of_line Layout/EndAlignment: - Exclude: - - 'lib/solargraph.rb' - - 'lib/solargraph/api_map/store.rb' - - 'lib/solargraph/diagnostics/rubocop.rb' - - 'lib/solargraph/language_server/message/extended/check_gem_version.rb' - - 'lib/solargraph/library.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/block_node.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/pin/namespace.rb' - - 'lib/solargraph/rbs_map.rb' - - 'lib/solargraph/shell.rb' - - 'lib/solargraph/source/chain/call.rb' - - 'lib/solargraph/source_map/clip.rb' - - 'lib/solargraph/source_map/mapper.rb' - - 'lib/solargraph/type_checker/rules.rb' - - 'lib/solargraph/yard_map/mapper.rb' + Enabled: false # Configuration parameters: EnforcedStyle. # SupportedStyles: native, lf, crlf @@ -172,13 +129,7 @@ Layout/EndOfLine: # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowForAlignment, AllowBeforeTrailingComments, ForceEqualSignAlignment. Layout/ExtraSpacing: - Exclude: - - 'lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb' - - 'lib/solargraph/pin/closure.rb' - - 'lib/solargraph/pin/local_variable.rb' - - 'lib/solargraph/rbs_map/conversions.rb' - - 'lib/solargraph/type_checker.rb' - - 'spec/spec_helper.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle, IndentationWidth. @@ -203,22 +154,7 @@ Layout/FirstArrayElementIndentation: # Configuration parameters: EnforcedStyle, IndentationWidth. # SupportedStyles: special_inside_parentheses, consistent, align_braces Layout/FirstHashElementIndentation: - Exclude: - - 'lib/solargraph/language_server/message/extended/check_gem_version.rb' - - 'lib/solargraph/language_server/message/extended/document_gems.rb' - - 'lib/solargraph/language_server/message/text_document/completion.rb' - - 'lib/solargraph/language_server/message/text_document/rename.rb' - - 'lib/solargraph/language_server/message/text_document/signature_help.rb' - - 'lib/solargraph/pin/base_variable.rb' - - 'spec/language_server/host_spec.rb' - - 'spec/language_server/message/completion_item/resolve_spec.rb' - - 'spec/language_server/message/initialize_spec.rb' - - 'spec/language_server/message/text_document/definition_spec.rb' - - 'spec/language_server/message/text_document/formatting_spec.rb' - - 'spec/language_server/message/text_document/hover_spec.rb' - - 'spec/language_server/message/text_document/rename_spec.rb' - - 'spec/language_server/message/text_document/type_definition_spec.rb' - - 'spec/language_server/message/workspace/did_change_watched_files_spec.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle. @@ -239,27 +175,7 @@ Layout/HeredocIndentation: # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: Width, AllowedPatterns. Layout/IndentationWidth: - Exclude: - - 'lib/solargraph.rb' - - 'lib/solargraph/api_map/store.rb' - - 'lib/solargraph/diagnostics/rubocop.rb' - - 'lib/solargraph/language_server/message/extended/check_gem_version.rb' - - 'lib/solargraph/library.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/block_node.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/pin/namespace.rb' - - 'lib/solargraph/rbs_map.rb' - - 'lib/solargraph/shell.rb' - - 'lib/solargraph/source/chain/call.rb' - - 'lib/solargraph/source_map/clip.rb' - - 'lib/solargraph/source_map/mapper.rb' - - 'lib/solargraph/type_checker.rb' - - 'lib/solargraph/type_checker/rules.rb' - - 'lib/solargraph/yard_map/mapper.rb' - - 'spec/api_map/config_spec.rb' - - 'spec/shell_spec.rb' - - 'spec/source_map/mapper_spec.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowDoxygenCommentStyle, AllowGemfileRubyComment, AllowRBSInlineAnnotation, AllowSteepAnnotation. @@ -289,14 +205,7 @@ Layout/MultilineMethodCallBraceLayout: # Configuration parameters: EnforcedStyle, IndentationWidth. # SupportedStyles: aligned, indented, indented_relative_to_receiver Layout/MultilineMethodCallIndentation: - Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/diagnostics/type_check.rb' - - 'lib/solargraph/language_server/message/completion_item/resolve.rb' - - 'lib/solargraph/language_server/message/text_document/hover.rb' - - 'lib/solargraph/library.rb' - - 'lib/solargraph/pin/search.rb' - - 'lib/solargraph/type_checker.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle, IndentationWidth. @@ -316,13 +225,7 @@ Layout/SpaceAfterComma: # Configuration parameters: EnforcedStyle. # SupportedStyles: space, no_space Layout/SpaceAroundEqualsInParameterDefault: - Exclude: - - 'lib/solargraph/pin/base.rb' - - 'lib/solargraph/pin/base_variable.rb' - - 'lib/solargraph/pin/callable.rb' - - 'lib/solargraph/pin/closure.rb' - - 'lib/solargraph/pin/local_variable.rb' - - 'lib/solargraph/pin/parameter.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). Layout/SpaceAroundKeyword: @@ -334,56 +237,14 @@ Layout/SpaceAroundKeyword: # SupportedStylesForExponentOperator: space, no_space # SupportedStylesForRationalLiterals: space, no_space Layout/SpaceAroundOperators: - Exclude: - - 'lib/solargraph/library.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/pin/local_variable.rb' - - 'lib/solargraph/source.rb' - - 'lib/solargraph/source/change.rb' - - 'lib/solargraph/source/cursor.rb' - - 'lib/solargraph/source/source_chainer.rb' - - 'lib/solargraph/source_map/clip.rb' - - 'lib/solargraph/workspace/config.rb' - - 'spec/library_spec.rb' - - 'spec/yard_map/mapper_spec.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. # SupportedStyles: space, no_space # SupportedStylesForEmptyBraces: space, no_space Layout/SpaceBeforeBlockBraces: - Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/api_map/store.rb' - - 'lib/solargraph/diagnostics/rubocop.rb' - - 'lib/solargraph/diagnostics/update_errors.rb' - - 'lib/solargraph/language_server/host.rb' - - 'lib/solargraph/library.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/and_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/if_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' - - 'lib/solargraph/pin/base.rb' - - 'lib/solargraph/source.rb' - - 'lib/solargraph/source/chain/call.rb' - - 'lib/solargraph/source/chain/class_variable.rb' - - 'lib/solargraph/source/chain/constant.rb' - - 'lib/solargraph/source/chain/global_variable.rb' - - 'lib/solargraph/source/chain/instance_variable.rb' - - 'lib/solargraph/source/chain/variable.rb' - - 'lib/solargraph/source/source_chainer.rb' - - 'lib/solargraph/source_map/clip.rb' - - 'lib/solargraph/source_map/mapper.rb' - - 'lib/solargraph/workspace/config.rb' - - 'spec/language_server/host_spec.rb' - - 'spec/language_server/protocol_spec.rb' - - 'spec/library_spec.rb' - - 'spec/pin/constant_spec.rb' - - 'spec/pin/instance_variable_spec.rb' - - 'spec/rbs_map/core_map_spec.rb' - - 'spec/source_map/mapper_spec.rb' - - 'spec/source_map_spec.rb' - - 'spec/source_spec.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). Layout/SpaceBeforeComma: @@ -395,28 +256,7 @@ Layout/SpaceBeforeComma: # SupportedStyles: space, no_space # SupportedStylesForEmptyBraces: space, no_space Layout/SpaceInsideBlockBraces: - Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/api_map/store.rb' - - 'lib/solargraph/diagnostics/update_errors.rb' - - 'lib/solargraph/language_server/host.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/and_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/if_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' - - 'lib/solargraph/source/chain/call.rb' - - 'lib/solargraph/source/chain/class_variable.rb' - - 'lib/solargraph/source/chain/global_variable.rb' - - 'lib/solargraph/source/chain/instance_variable.rb' - - 'lib/solargraph/source/chain/variable.rb' - - 'lib/solargraph/source/source_chainer.rb' - - 'lib/solargraph/source_map/mapper.rb' - - 'spec/language_server/protocol_spec.rb' - - 'spec/library_spec.rb' - - 'spec/pin/constant_spec.rb' - - 'spec/rbs_map/core_map_spec.rb' - - 'spec/source_map/mapper_spec.rb' - - 'spec/source_spec.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. @@ -455,13 +295,7 @@ Lint/AmbiguousBlockAssociation: # This cop supports safe autocorrection (--autocorrect). Lint/AmbiguousOperator: - Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/complex_type.rb' - - 'lib/solargraph/language_server/message/workspace/did_change_watched_files.rb' - - 'lib/solargraph/parser/parser_gem/class_methods.rb' - - 'lib/solargraph/pin/constant.rb' - - 'lib/solargraph/pin/method.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). Lint/AmbiguousOperatorPrecedence: @@ -472,15 +306,7 @@ Lint/AmbiguousOperatorPrecedence: # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: RequireParenthesesForMethodChains. Lint/AmbiguousRange: - Exclude: - - 'lib/solargraph/library.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/source.rb' - - 'lib/solargraph/source/change.rb' - - 'lib/solargraph/source/cursor.rb' - - 'lib/solargraph/source/source_chainer.rb' - - 'lib/solargraph/source_map/clip.rb' - - 'spec/library_spec.rb' + Enabled: false # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: AllowSafeAssignment. @@ -514,14 +340,7 @@ Lint/DuplicateBranch: - 'lib/solargraph/rbs_map/conversions.rb' Lint/DuplicateMethods: - Exclude: - - 'lib/solargraph/complex_type.rb' - - 'lib/solargraph/location.rb' - - 'lib/solargraph/pin/base.rb' - - 'lib/solargraph/pin/signature.rb' - - 'lib/solargraph/rbs_map.rb' - - 'lib/solargraph/rbs_map/core_map.rb' - - 'lib/solargraph/source/chain/link.rb' + Enabled: false # Configuration parameters: AllowComments, AllowEmptyLambdas. Lint/EmptyBlock: @@ -530,13 +349,7 @@ Lint/EmptyBlock: # Configuration parameters: AllowComments. Lint/EmptyClass: - Exclude: - - 'spec/fixtures/rubocop-validation-error/app.rb' - - 'spec/fixtures/workspace-with-gemfile/lib/other.rb' - - 'spec/fixtures/workspace/lib/other.rb' - - 'spec/fixtures/workspace/lib/something.rb' - - 'spec/fixtures/workspace_folders/folder1/app.rb' - - 'spec/fixtures/workspace_folders/folder2/app.rb' + Enabled: false # Configuration parameters: AllowComments. Lint/EmptyFile: @@ -635,31 +448,7 @@ Lint/UnusedBlockArgument: # Configuration parameters: AutoCorrect, AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions. # NotImplementedExceptions: NotImplementedError Lint/UnusedMethodArgument: - Exclude: - - 'lib/solargraph.rb' - - 'lib/solargraph/complex_type/type_methods.rb' - - 'lib/solargraph/convention/base.rb' - - 'lib/solargraph/diagnostics/base.rb' - - 'lib/solargraph/diagnostics/update_errors.rb' - - 'lib/solargraph/doc_map.rb' - - 'lib/solargraph/pin/namespace.rb' - - 'lib/solargraph/rbs_map/conversions.rb' - - 'lib/solargraph/source.rb' - - 'lib/solargraph/source/chain.rb' - - 'lib/solargraph/source/chain/block_symbol.rb' - - 'lib/solargraph/source/chain/block_variable.rb' - - 'lib/solargraph/source/chain/call.rb' - - 'lib/solargraph/source/chain/class_variable.rb' - - 'lib/solargraph/source/chain/constant.rb' - - 'lib/solargraph/source/chain/global_variable.rb' - - 'lib/solargraph/source/chain/hash.rb' - - 'lib/solargraph/source/chain/head.rb' - - 'lib/solargraph/source/chain/instance_variable.rb' - - 'lib/solargraph/source/chain/link.rb' - - 'lib/solargraph/source/chain/literal.rb' - - 'lib/solargraph/source/chain/variable.rb' - - 'lib/solargraph/source/chain/z_super.rb' - - 'spec/doc_map_spec.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AutoCorrect, ContextCreatingMethods, MethodCreatingMethods. @@ -670,30 +459,7 @@ Lint/UselessAccessModifier: # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AutoCorrect. Lint/UselessAssignment: - Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/doc_map.rb' - - 'lib/solargraph/language_server/message/extended/check_gem_version.rb' - - 'lib/solargraph/language_server/message/extended/document_gems.rb' - - 'lib/solargraph/language_server/message/text_document/completion.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/pin/parameter.rb' - - 'lib/solargraph/rbs_map/conversions.rb' - - 'lib/solargraph/source.rb' - - 'lib/solargraph/source/chain/call.rb' - - 'lib/solargraph/source/source_chainer.rb' - - 'lib/solargraph/source_map/mapper.rb' - - 'lib/solargraph/type_checker.rb' - - 'spec/fixtures/long_squiggly_heredoc.rb' - - 'spec/fixtures/rubocop-unused-variable-error/app.rb' - - 'spec/fixtures/unicode.rb' - - 'spec/language_server/host_spec.rb' - - 'spec/language_server/protocol_spec.rb' - - 'spec/library_spec.rb' - - 'spec/pin/namespace_spec.rb' - - 'spec/source/chain/call_spec.rb' - - 'spec/source_map/mapper_spec.rb' + Enabled: false Lint/UselessConstantScoping: Exclude: @@ -707,43 +473,16 @@ Lint/UselessMethodDefinition: # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max. Metrics/AbcSize: - Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/api_map/source_to_yard.rb' - - 'lib/solargraph/complex_type.rb' - - 'lib/solargraph/doc_map.rb' - - 'lib/solargraph/language_server/host.rb' - - 'lib/solargraph/language_server/message/initialize.rb' - - 'lib/solargraph/library.rb' - - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/rbs_map/conversions.rb' - - 'lib/solargraph/source/chain/call.rb' - - 'lib/solargraph/source/source_chainer.rb' - - 'lib/solargraph/source_map/clip.rb' - - 'lib/solargraph/source_map/mapper.rb' - - 'lib/solargraph/type_checker.rb' + Enabled: false -# Configuration parameters: CountComments, Max, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode. +# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode. # AllowedMethods: refine Metrics/BlockLength: - Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/api_map/source_to_yard.rb' - - 'lib/solargraph/complex_type.rb' - - 'lib/solargraph/convention/struct_definition.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' - - 'lib/solargraph/source/chain/call.rb' - - 'lib/solargraph/type_checker.rb' + Max: 54 -# Configuration parameters: CountBlocks, CountModifierForms, Max. +# Configuration parameters: CountBlocks, CountModifierForms. Metrics/BlockNesting: - Exclude: - - 'lib/solargraph/source/source_chainer.rb' - - 'lib/solargraph/source_map/clip.rb' - - 'lib/solargraph/type_checker.rb' + Max: 5 # Configuration parameters: CountComments, Max, CountAsOne. Metrics/ClassLength: @@ -755,33 +494,15 @@ Metrics/ClassLength: # Configuration parameters: AllowedMethods, AllowedPatterns, Max. Metrics/CyclomaticComplexity: - Exclude: - - 'lib/solargraph/api_map/source_to_yard.rb' - - 'lib/solargraph/complex_type.rb' - - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/rbs_map/conversions.rb' - - 'lib/solargraph/source/chain/call.rb' - - 'lib/solargraph/source/source_chainer.rb' - - 'lib/solargraph/source_map/mapper.rb' - - 'lib/solargraph/type_checker.rb' + Enabled: false # Configuration parameters: CountComments, Max, CountAsOne, AllowedMethods, AllowedPatterns. Metrics/MethodLength: - Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/complex_type.rb' - - 'lib/solargraph/convention/struct_definition.rb' - - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - - 'lib/solargraph/source/chain/call.rb' - - 'lib/solargraph/source_map/mapper.rb' + Enabled: false -# Configuration parameters: CountComments, Max, CountAsOne. +# Configuration parameters: CountComments, CountAsOne. Metrics/ModuleLength: - Exclude: - - 'lib/solargraph/complex_type/type_methods.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/pin_cache.rb' + Max: 169 # Configuration parameters: Max, CountKeywordArgs, MaxOptionalParameters. Metrics/ParameterLists: @@ -794,13 +515,7 @@ Metrics/ParameterLists: # Configuration parameters: AllowedMethods, AllowedPatterns, Max. Metrics/PerceivedComplexity: - Exclude: - - 'lib/solargraph/complex_type.rb' - - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - - 'lib/solargraph/source/chain/call.rb' - - 'lib/solargraph/source/source_chainer.rb' - - 'lib/solargraph/source_map/mapper.rb' - - 'lib/solargraph/type_checker.rb' + Enabled: false Naming/AccessorMethodName: Exclude: @@ -823,41 +538,18 @@ Naming/HeredocDelimiterNaming: # Configuration parameters: EnforcedStyleForLeadingUnderscores. # SupportedStylesForLeadingUnderscores: disallowed, required, optional Naming/MemoizedInstanceVariableName: - Exclude: - - 'lib/solargraph/complex_type/type_methods.rb' - - 'lib/solargraph/convention/gemfile.rb' - - 'lib/solargraph/convention/gemspec.rb' - - 'lib/solargraph/convention/rakefile.rb' - - 'lib/solargraph/doc_map.rb' - - 'lib/solargraph/rbs_map.rb' - - 'lib/solargraph/workspace.rb' + Enabled: false # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. # AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to Naming/MethodParameterName: - Exclude: - - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - - 'lib/solargraph/pin/base.rb' - - 'lib/solargraph/range.rb' - - 'lib/solargraph/source.rb' - - 'lib/solargraph/yard_map/mapper/to_method.rb' - - 'lib/solargraph/yard_map/to_method.rb' + Enabled: false # Configuration parameters: Mode, AllowedMethods, AllowedPatterns, AllowBangMethods, WaywardPredicates. # AllowedMethods: call # WaywardPredicates: nonzero? Naming/PredicateMethod: - Exclude: - - 'lib/solargraph/api_map/store.rb' - - 'lib/solargraph/convention/data_definition.rb' - - 'lib/solargraph/convention/struct_definition.rb' - - 'lib/solargraph/language_server/progress.rb' - - 'lib/solargraph/library.rb' - - 'lib/solargraph/parser/node_processor/base.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' - - 'lib/solargraph/pin/base.rb' - - 'lib/solargraph/pin/local_variable.rb' - - 'lib/solargraph/workspace.rb' + Enabled: false # Configuration parameters: NamePrefix, ForbiddenPrefixes, AllowedMethods, MethodDefinitionMacros, UseSorbetSigs. # NamePrefix: is_, has_, have_, does_ @@ -912,16 +604,7 @@ RSpec/BeforeAfterAll: # Configuration parameters: Prefixes, AllowedPatterns. # Prefixes: when, with, without RSpec/ContextWording: - Exclude: - - 'spec/complex_type_spec.rb' - - 'spec/library_spec.rb' - - 'spec/pin/method_spec.rb' - - 'spec/pin/parameter_spec.rb' - - 'spec/pin/symbol_spec.rb' - - 'spec/type_checker/levels/normal_spec.rb' - - 'spec/type_checker/levels/strict_spec.rb' - - 'spec/type_checker/levels/strong_spec.rb' - - 'spec/type_checker/levels/typed_spec.rb' + Enabled: false # Configuration parameters: IgnoredMetadata. RSpec/DescribeClass: @@ -938,81 +621,11 @@ RSpec/DescribeClass: # Configuration parameters: SkipBlocks, EnforcedStyle, OnlyStaticConstants. # SupportedStyles: described_class, explicit RSpec/DescribedClass: - Exclude: - - 'spec/api_map/cache_spec.rb' - - 'spec/api_map/source_to_yard_spec.rb' - - 'spec/api_map/store_spec.rb' - - 'spec/api_map_spec.rb' - - 'spec/diagnostics/base_spec.rb' - - 'spec/diagnostics/require_not_found_spec.rb' - - 'spec/diagnostics/rubocop_helpers_spec.rb' - - 'spec/diagnostics/rubocop_spec.rb' - - 'spec/diagnostics/type_check_spec.rb' - - 'spec/diagnostics/update_errors_spec.rb' - - 'spec/diagnostics_spec.rb' - - 'spec/doc_map_spec.rb' - - 'spec/gem_pins_spec.rb' - - 'spec/language_server/host/diagnoser_spec.rb' - - 'spec/language_server/host/dispatch_spec.rb' - - 'spec/language_server/host/message_worker_spec.rb' - - 'spec/language_server/host_spec.rb' - - 'spec/language_server/message/completion_item/resolve_spec.rb' - - 'spec/language_server/message/extended/check_gem_version_spec.rb' - - 'spec/language_server/message/initialize_spec.rb' - - 'spec/language_server/message/text_document/definition_spec.rb' - - 'spec/language_server/message/text_document/formatting_spec.rb' - - 'spec/language_server/message/text_document/hover_spec.rb' - - 'spec/language_server/message/text_document/rename_spec.rb' - - 'spec/language_server/message/text_document/type_definition_spec.rb' - - 'spec/language_server/message/workspace/did_change_watched_files_spec.rb' - - 'spec/language_server/message_spec.rb' - - 'spec/language_server/protocol_spec.rb' - - 'spec/language_server/transport/data_reader_spec.rb' - - 'spec/language_server/uri_helpers_spec.rb' - - 'spec/library_spec.rb' - - 'spec/logging_spec.rb' - - 'spec/parser/node_methods_spec.rb' - - 'spec/parser/node_processor_spec.rb' - - 'spec/parser_spec.rb' - - 'spec/pin/base_spec.rb' - - 'spec/pin/delegated_method_spec.rb' - - 'spec/pin/instance_variable_spec.rb' - - 'spec/pin/keyword_spec.rb' - - 'spec/pin/local_variable_spec.rb' - - 'spec/pin/method_spec.rb' - - 'spec/pin/namespace_spec.rb' - - 'spec/pin/parameter_spec.rb' - - 'spec/pin/search_spec.rb' - - 'spec/pin/symbol_spec.rb' - - 'spec/position_spec.rb' - - 'spec/rbs_map/conversions_spec.rb' - - 'spec/rbs_map/core_map_spec.rb' - - 'spec/rbs_map/stdlib_map_spec.rb' - - 'spec/rbs_map_spec.rb' - - 'spec/source/chain/class_variable_spec.rb' - - 'spec/source/chain/global_variable_spec.rb' - - 'spec/source/chain/head_spec.rb' - - 'spec/source/chain/instance_variable_spec.rb' - - 'spec/source/chain/z_super_spec.rb' - - 'spec/source/change_spec.rb' - - 'spec/source/source_chainer_spec.rb' - - 'spec/source/updater_spec.rb' - - 'spec/source_map/mapper_spec.rb' - - 'spec/source_map_spec.rb' - - 'spec/source_spec.rb' - - 'spec/type_checker/checks_spec.rb' - - 'spec/type_checker/levels/normal_spec.rb' - - 'spec/type_checker/levels/strict_spec.rb' - - 'spec/type_checker/rules_spec.rb' - - 'spec/type_checker_spec.rb' - - 'spec/workspace/config_spec.rb' - - 'spec/workspace_spec.rb' - - 'spec/yard_map/mapper/to_method_spec.rb' - - 'spec/yard_map/mapper_spec.rb' - -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: AutoCorrect. -RSpec/EmptyExampleGroup: + Enabled: false + +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: AutoCorrect. +RSpec/EmptyExampleGroup: Exclude: - 'spec/convention_spec.rb' @@ -1023,33 +636,7 @@ RSpec/EmptyLineAfterFinalLet: # Configuration parameters: Max, CountAsOne. RSpec/ExampleLength: - Exclude: - - 'spec/api_map_spec.rb' - - 'spec/complex_type_spec.rb' - - 'spec/language_server/host_spec.rb' - - 'spec/language_server/message/initialize_spec.rb' - - 'spec/language_server/message/text_document/definition_spec.rb' - - 'spec/language_server/message/text_document/hover_spec.rb' - - 'spec/language_server/message/text_document/rename_spec.rb' - - 'spec/language_server/message/text_document/type_definition_spec.rb' - - 'spec/language_server/message/workspace/did_change_watched_files_spec.rb' - - 'spec/language_server/protocol_spec.rb' - - 'spec/library_spec.rb' - - 'spec/parser/flow_sensitive_typing_spec.rb' - - 'spec/parser/node_methods_spec.rb' - - 'spec/parser/node_processor_spec.rb' - - 'spec/pin/base_variable_spec.rb' - - 'spec/pin/delegated_method_spec.rb' - - 'spec/pin/local_variable_spec.rb' - - 'spec/pin/parameter_spec.rb' - - 'spec/source/chain/call_spec.rb' - - 'spec/source/chain_spec.rb' - - 'spec/source_map/clip_spec.rb' - - 'spec/source_map/mapper_spec.rb' - - 'spec/source_map_spec.rb' - - 'spec/source_spec.rb' - - 'spec/type_checker/levels/strict_spec.rb' - - 'spec/type_checker_spec.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: CustomTransform, IgnoredWords, DisallowedExamples. @@ -1077,15 +664,7 @@ RSpec/ExpectActual: # Configuration parameters: EnforcedStyle. # SupportedStyles: implicit, each, example RSpec/HookArgument: - Exclude: - - 'spec/api_map/config_spec.rb' - - 'spec/diagnostics/require_not_found_spec.rb' - - 'spec/language_server/host/dispatch_spec.rb' - - 'spec/language_server/host_spec.rb' - - 'spec/language_server/message/extended/check_gem_version_spec.rb' - - 'spec/language_server/protocol_spec.rb' - - 'spec/workspace/config_spec.rb' - - 'spec/workspace_spec.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: . @@ -1095,13 +674,7 @@ RSpec/ImplicitExpect: # Configuration parameters: AssignmentOnly. RSpec/InstanceVariable: - Exclude: - - 'spec/api_map/config_spec.rb' - - 'spec/api_map_spec.rb' - - 'spec/diagnostics/require_not_found_spec.rb' - - 'spec/language_server/host/dispatch_spec.rb' - - 'spec/language_server/host_spec.rb' - - 'spec/language_server/protocol_spec.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). RSpec/LeadingSubject: @@ -1127,89 +700,17 @@ RSpec/MissingExampleGroupArgument: Exclude: - 'spec/diagnostics/rubocop_helpers_spec.rb' -# Configuration parameters: Max. RSpec/MultipleExpectations: - Exclude: - - 'spec/api_map/cache_spec.rb' - - 'spec/api_map/config_spec.rb' - - 'spec/api_map/source_to_yard_spec.rb' - - 'spec/api_map/store_spec.rb' - - 'spec/api_map_spec.rb' - - 'spec/complex_type_spec.rb' - - 'spec/convention/struct_definition_spec.rb' - - 'spec/diagnostics/rubocop_spec.rb' - - 'spec/diagnostics/type_check_spec.rb' - - 'spec/diagnostics/update_errors_spec.rb' - - 'spec/diagnostics_spec.rb' - - 'spec/doc_map_spec.rb' - - 'spec/gem_pins_spec.rb' - - 'spec/language_server/host/message_worker_spec.rb' - - 'spec/language_server/host_spec.rb' - - 'spec/language_server/message/completion_item/resolve_spec.rb' - - 'spec/language_server/message/initialize_spec.rb' - - 'spec/language_server/message/text_document/rename_spec.rb' - - 'spec/language_server/message/workspace/did_change_watched_files_spec.rb' - - 'spec/language_server/protocol_spec.rb' - - 'spec/language_server/transport/adapter_spec.rb' - - 'spec/language_server/transport/data_reader_spec.rb' - - 'spec/library_spec.rb' - - 'spec/parser/flow_sensitive_typing_spec.rb' - - 'spec/parser/node_chainer_spec.rb' - - 'spec/parser/node_methods_spec.rb' - - 'spec/parser/node_processor_spec.rb' - - 'spec/pin/base_spec.rb' - - 'spec/pin/base_variable_spec.rb' - - 'spec/pin/constant_spec.rb' - - 'spec/pin/instance_variable_spec.rb' - - 'spec/pin/local_variable_spec.rb' - - 'spec/pin/method_spec.rb' - - 'spec/pin/namespace_spec.rb' - - 'spec/pin/parameter_spec.rb' - - 'spec/position_spec.rb' - - 'spec/rbs_map/core_map_spec.rb' - - 'spec/rbs_map/stdlib_map_spec.rb' - - 'spec/rbs_map_spec.rb' - - 'spec/shell_spec.rb' - - 'spec/source/chain/call_spec.rb' - - 'spec/source/chain/class_variable_spec.rb' - - 'spec/source/chain/global_variable_spec.rb' - - 'spec/source/chain/head_spec.rb' - - 'spec/source/chain/instance_variable_spec.rb' - - 'spec/source/chain_spec.rb' - - 'spec/source/cursor_spec.rb' - - 'spec/source/source_chainer_spec.rb' - - 'spec/source_map/clip_spec.rb' - - 'spec/source_map/mapper_spec.rb' - - 'spec/source_map/node_processor_spec.rb' - - 'spec/source_map_spec.rb' - - 'spec/source_spec.rb' - - 'spec/type_checker/checks_spec.rb' - - 'spec/type_checker/levels/normal_spec.rb' - - 'spec/type_checker/levels/strict_spec.rb' - - 'spec/type_checker/levels/strong_spec.rb' - - 'spec/type_checker/levels/typed_spec.rb' - - 'spec/type_checker/rules_spec.rb' - - 'spec/workspace/config_spec.rb' - - 'spec/workspace_spec.rb' - - 'spec/yard_map/mapper/to_method_spec.rb' - - 'spec/yard_map/mapper_spec.rb' + Max: 14 -# Configuration parameters: Max, AllowedGroups. +# Configuration parameters: AllowedGroups. RSpec/NestedGroups: - Exclude: - - 'spec/complex_type_spec.rb' + Max: 4 # Configuration parameters: AllowedPatterns. # AllowedPatterns: ^expect_, ^assert_ RSpec/NoExpectationExample: - Exclude: - - 'spec/language_server/protocol_spec.rb' - - 'spec/parser/node_methods_spec.rb' - - 'spec/pin/block_spec.rb' - - 'spec/pin/method_spec.rb' - - 'spec/source/chain/call_spec.rb' - - 'spec/type_checker/checks_spec.rb' - - 'spec/type_checker/levels/typed_spec.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle. @@ -1220,18 +721,7 @@ RSpec/NotToNot: - 'spec/rbs_map/core_map_spec.rb' RSpec/PendingWithoutReason: - Exclude: - - 'spec/api_map_spec.rb' - - 'spec/complex_type_spec.rb' - - 'spec/parser/node_chainer_spec.rb' - - 'spec/parser/node_methods_spec.rb' - - 'spec/pin/local_variable_spec.rb' - - 'spec/rbs_map/core_map_spec.rb' - - 'spec/source/chain/call_spec.rb' - - 'spec/source/chain_spec.rb' - - 'spec/source_map/clip_spec.rb' - - 'spec/type_checker/levels/strict_spec.rb' - - 'spec/yard_map/mapper/to_method_spec.rb' + Enabled: false # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: Strict, EnforcedStyle, AllowedExplicitMatchers. @@ -1251,16 +741,7 @@ RSpec/RemoveConst: - 'spec/diagnostics/rubocop_helpers_spec.rb' RSpec/RepeatedDescription: - Exclude: - - 'spec/api_map_spec.rb' - - 'spec/language_server/protocol_spec.rb' - - 'spec/parser/node_methods_spec.rb' - - 'spec/source/chain/call_spec.rb' - - 'spec/source/source_chainer_spec.rb' - - 'spec/source_map/clip_spec.rb' - - 'spec/source_map/mapper_spec.rb' - - 'spec/type_checker/levels/normal_spec.rb' - - 'spec/type_checker/levels/strict_spec.rb' + Enabled: false RSpec/RepeatedExample: Exclude: @@ -1279,99 +760,7 @@ RSpec/ScatteredLet: # Configuration parameters: Include, CustomTransform, IgnoreMethods, IgnoreMetadata. # Include: **/*_spec.rb RSpec/SpecFilePathFormat: - Exclude: - - '**/spec/routing/**/*' - - 'spec/api_map/cache_spec.rb' - - 'spec/api_map/config_spec.rb' - - 'spec/api_map/source_to_yard_spec.rb' - - 'spec/api_map/store_spec.rb' - - 'spec/api_map_spec.rb' - - 'spec/convention/activesupport_concern_spec.rb' - - 'spec/convention/struct_definition_spec.rb' - - 'spec/convention_spec.rb' - - 'spec/diagnostics/base_spec.rb' - - 'spec/diagnostics/require_not_found_spec.rb' - - 'spec/diagnostics/rubocop_helpers_spec.rb' - - 'spec/diagnostics/rubocop_spec.rb' - - 'spec/diagnostics/type_check_spec.rb' - - 'spec/diagnostics/update_errors_spec.rb' - - 'spec/diagnostics_spec.rb' - - 'spec/doc_map_spec.rb' - - 'spec/gem_pins_spec.rb' - - 'spec/language_server/host/diagnoser_spec.rb' - - 'spec/language_server/host/dispatch_spec.rb' - - 'spec/language_server/host/message_worker_spec.rb' - - 'spec/language_server/host_spec.rb' - - 'spec/language_server/message/completion_item/resolve_spec.rb' - - 'spec/language_server/message/extended/check_gem_version_spec.rb' - - 'spec/language_server/message/initialize_spec.rb' - - 'spec/language_server/message/text_document/definition_spec.rb' - - 'spec/language_server/message/text_document/formatting_spec.rb' - - 'spec/language_server/message/text_document/hover_spec.rb' - - 'spec/language_server/message/text_document/rename_spec.rb' - - 'spec/language_server/message/text_document/type_definition_spec.rb' - - 'spec/language_server/message/workspace/did_change_configuration_spec.rb' - - 'spec/language_server/message/workspace/did_change_watched_files_spec.rb' - - 'spec/language_server/message_spec.rb' - - 'spec/language_server/transport/adapter_spec.rb' - - 'spec/language_server/transport/data_reader_spec.rb' - - 'spec/language_server/uri_helpers_spec.rb' - - 'spec/library_spec.rb' - - 'spec/logging_spec.rb' - - 'spec/parser/flow_sensitive_typing_spec.rb' - - 'spec/parser/node_methods_spec.rb' - - 'spec/parser/node_processor_spec.rb' - - 'spec/parser_spec.rb' - - 'spec/pin/base_spec.rb' - - 'spec/pin/base_variable_spec.rb' - - 'spec/pin/block_spec.rb' - - 'spec/pin/constant_spec.rb' - - 'spec/pin/delegated_method_spec.rb' - - 'spec/pin/documenting_spec.rb' - - 'spec/pin/instance_variable_spec.rb' - - 'spec/pin/keyword_spec.rb' - - 'spec/pin/local_variable_spec.rb' - - 'spec/pin/method_spec.rb' - - 'spec/pin/namespace_spec.rb' - - 'spec/pin/parameter_spec.rb' - - 'spec/pin/search_spec.rb' - - 'spec/pin/symbol_spec.rb' - - 'spec/position_spec.rb' - - 'spec/rbs_map/conversions_spec.rb' - - 'spec/rbs_map/core_map_spec.rb' - - 'spec/rbs_map/stdlib_map_spec.rb' - - 'spec/rbs_map_spec.rb' - - 'spec/shell_spec.rb' - - 'spec/source/chain/array_spec.rb' - - 'spec/source/chain/call_spec.rb' - - 'spec/source/chain/class_variable_spec.rb' - - 'spec/source/chain/constant_spec.rb' - - 'spec/source/chain/global_variable_spec.rb' - - 'spec/source/chain/head_spec.rb' - - 'spec/source/chain/instance_variable_spec.rb' - - 'spec/source/chain/link_spec.rb' - - 'spec/source/chain/literal_spec.rb' - - 'spec/source/chain/z_super_spec.rb' - - 'spec/source/chain_spec.rb' - - 'spec/source/change_spec.rb' - - 'spec/source/cursor_spec.rb' - - 'spec/source/source_chainer_spec.rb' - - 'spec/source/updater_spec.rb' - - 'spec/source_map/clip_spec.rb' - - 'spec/source_map/mapper_spec.rb' - - 'spec/source_map_spec.rb' - - 'spec/source_spec.rb' - - 'spec/type_checker/checks_spec.rb' - - 'spec/type_checker/levels/normal_spec.rb' - - 'spec/type_checker/levels/strict_spec.rb' - - 'spec/type_checker/levels/strong_spec.rb' - - 'spec/type_checker/levels/typed_spec.rb' - - 'spec/type_checker/rules_spec.rb' - - 'spec/type_checker_spec.rb' - - 'spec/workspace/config_spec.rb' - - 'spec/workspace_spec.rb' - - 'spec/yard_map/mapper/to_method_spec.rb' - - 'spec/yard_map/mapper_spec.rb' + Enabled: false RSpec/StubbedMock: Exclude: @@ -1379,20 +768,7 @@ RSpec/StubbedMock: # Configuration parameters: IgnoreNameless, IgnoreSymbolicNames. RSpec/VerifiedDoubles: - Exclude: - - 'spec/complex_type_spec.rb' - - 'spec/language_server/host/diagnoser_spec.rb' - - 'spec/language_server/host/message_worker_spec.rb' - - 'spec/language_server/host_spec.rb' - - 'spec/language_server/message/completion_item/resolve_spec.rb' - - 'spec/language_server/message/extended/check_gem_version_spec.rb' - - 'spec/language_server/message/text_document/formatting_spec.rb' - - 'spec/language_server/message/workspace/did_change_watched_files_spec.rb' - - 'spec/language_server/protocol_spec.rb' - - 'spec/source/chain/class_variable_spec.rb' - - 'spec/source/cursor_spec.rb' - - 'spec/source/source_chainer_spec.rb' - - 'spec/workspace_spec.rb' + Enabled: false Security/MarshalLoad: Exclude: @@ -1402,20 +778,7 @@ Security/MarshalLoad: # Configuration parameters: EnforcedStyle, AllowModifiersOnSymbols, AllowModifiersOnAttrs, AllowModifiersOnAliasMethod. # SupportedStyles: inline, group Style/AccessModifierDeclarations: - Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/complex_type.rb' - - 'lib/solargraph/complex_type/unique_type.rb' - - 'lib/solargraph/location.rb' - - 'lib/solargraph/pin/base.rb' - - 'lib/solargraph/position.rb' - - 'lib/solargraph/range.rb' - - 'lib/solargraph/source/chain.rb' - - 'lib/solargraph/source/chain/call.rb' - - 'lib/solargraph/source/chain/hash.rb' - - 'lib/solargraph/source/chain/if.rb' - - 'lib/solargraph/source/chain/link.rb' - - 'lib/solargraph/source/chain/literal.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle. @@ -1431,21 +794,7 @@ Style/AccessorGrouping: # Configuration parameters: EnforcedStyle. # SupportedStyles: always, conditionals Style/AndOr: - Exclude: - - 'lib/solargraph/api_map/source_to_yard.rb' - - 'lib/solargraph/complex_type/unique_type.rb' - - 'lib/solargraph/language_server/message/base.rb' - - 'lib/solargraph/page.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/pin/parameter.rb' - - 'lib/solargraph/position.rb' - - 'lib/solargraph/source/change.rb' - - 'lib/solargraph/source/cursor.rb' - - 'lib/solargraph/source/source_chainer.rb' - - 'lib/solargraph/source/updater.rb' - - 'lib/solargraph/workspace.rb' - - 'lib/solargraph/yard_map/mapper.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowOnlyRestArgument, UseAnonymousForwarding, RedundantRestArgumentNames, RedundantKeywordRestArgumentNames, RedundantBlockArgumentNames. @@ -1464,44 +813,12 @@ Style/ArgumentsForwarding: # FunctionalMethods: let, let!, subject, watch # AllowedMethods: lambda, proc, it Style/BlockDelimiters: - Exclude: - - 'lib/solargraph/api_map/source_to_yard.rb' - - 'lib/solargraph/api_map/store.rb' - - 'lib/solargraph/language_server/host.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/shell.rb' - - 'lib/solargraph/source.rb' - - 'lib/solargraph/source_map/clip.rb' - - 'lib/solargraph/source_map/mapper.rb' - - 'spec/diagnostics/rubocop_spec.rb' - - 'spec/language_server/host_spec.rb' - - 'spec/language_server/message/extended/check_gem_version_spec.rb' - - 'spec/language_server/message/workspace/did_change_watched_files_spec.rb' - - 'spec/language_server/protocol_spec.rb' - - 'spec/language_server/transport/adapter_spec.rb' - - 'spec/language_server/transport/data_reader_spec.rb' - - 'spec/library_spec.rb' - - 'spec/parser/node_processor_spec.rb' - - 'spec/pin/documenting_spec.rb' - - 'spec/position_spec.rb' - - 'spec/source/chain_spec.rb' - - 'spec/source/source_chainer_spec.rb' - - 'spec/source_map/mapper_spec.rb' - - 'spec/source_spec.rb' - - 'spec/type_checker_spec.rb' - - 'spec/workspace_spec.rb' - - 'spec/yard_map/mapper/to_method_spec.rb' + Enabled: false # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: MinBranchesCount. Style/CaseLikeIf: - Exclude: - - 'lib/solargraph/language_server/message/workspace/did_change_watched_files.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/pin/parameter.rb' - - 'lib/solargraph/rbs_map/conversions.rb' - - 'lib/solargraph/source/source_chainer.rb' - - 'lib/solargraph/yard_map/mapper.rb' + Enabled: false # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle, EnforcedStyleForClasses, EnforcedStyleForModules. @@ -1509,18 +826,7 @@ Style/CaseLikeIf: # SupportedStylesForClasses: ~, nested, compact # SupportedStylesForModules: ~, nested, compact Style/ClassAndModuleChildren: - Exclude: - - 'lib/solargraph/language_server/message/text_document/definition.rb' - - 'lib/solargraph/language_server/message/text_document/document_highlight.rb' - - 'lib/solargraph/language_server/message/text_document/document_symbol.rb' - - 'lib/solargraph/language_server/message/text_document/prepare_rename.rb' - - 'lib/solargraph/language_server/message/text_document/references.rb' - - 'lib/solargraph/language_server/message/text_document/rename.rb' - - 'lib/solargraph/language_server/message/text_document/type_definition.rb' - - 'lib/solargraph/language_server/message/workspace/did_change_configuration.rb' - - 'lib/solargraph/language_server/message/workspace/did_change_watched_files.rb' - - 'lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb' - - 'lib/solargraph/language_server/message/workspace/workspace_symbol.rb' + Enabled: false # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: AllowedMethods, AllowedPatterns. @@ -1556,150 +862,13 @@ Style/ConcatArrayLiterals: # SupportedStyles: assign_to_condition, assign_inside_condition Style/ConditionalAssignment: Exclude: + - 'lib/solargraph/api_map/source_to_yard.rb' - 'lib/solargraph/parser/parser_gem/node_processors/defs_node.rb' - 'lib/solargraph/source/chain/call.rb' # Configuration parameters: AllowedConstants. Style/Documentation: - Exclude: - - 'spec/**/*' - - 'test/**/*' - - 'lib/solargraph/api_map/cache.rb' - - 'lib/solargraph/api_map/index.rb' - - 'lib/solargraph/api_map/source_to_yard.rb' - - 'lib/solargraph/convention/data_definition.rb' - - 'lib/solargraph/convention/gemfile.rb' - - 'lib/solargraph/convention/gemspec.rb' - - 'lib/solargraph/convention/rakefile.rb' - - 'lib/solargraph/convention/struct_definition.rb' - - 'lib/solargraph/converters/dd.rb' - - 'lib/solargraph/converters/dl.rb' - - 'lib/solargraph/converters/dt.rb' - - 'lib/solargraph/diagnostics/update_errors.rb' - - 'lib/solargraph/language_server/message/base.rb' - - 'lib/solargraph/language_server/message/cancel_request.rb' - - 'lib/solargraph/language_server/message/client.rb' - - 'lib/solargraph/language_server/message/client/register_capability.rb' - - 'lib/solargraph/language_server/message/completion_item.rb' - - 'lib/solargraph/language_server/message/exit_notification.rb' - - 'lib/solargraph/language_server/message/extended/document.rb' - - 'lib/solargraph/language_server/message/extended/search.rb' - - 'lib/solargraph/language_server/message/initialize.rb' - - 'lib/solargraph/language_server/message/initialized.rb' - - 'lib/solargraph/language_server/message/method_not_found.rb' - - 'lib/solargraph/language_server/message/method_not_implemented.rb' - - 'lib/solargraph/language_server/message/shutdown.rb' - - 'lib/solargraph/language_server/message/text_document.rb' - - 'lib/solargraph/language_server/message/text_document/base.rb' - - 'lib/solargraph/language_server/message/text_document/code_action.rb' - - 'lib/solargraph/language_server/message/text_document/completion.rb' - - 'lib/solargraph/language_server/message/text_document/definition.rb' - - 'lib/solargraph/language_server/message/text_document/did_change.rb' - - 'lib/solargraph/language_server/message/text_document/did_close.rb' - - 'lib/solargraph/language_server/message/text_document/did_open.rb' - - 'lib/solargraph/language_server/message/text_document/did_save.rb' - - 'lib/solargraph/language_server/message/text_document/document_highlight.rb' - - 'lib/solargraph/language_server/message/text_document/document_symbol.rb' - - 'lib/solargraph/language_server/message/text_document/folding_range.rb' - - 'lib/solargraph/language_server/message/text_document/formatting.rb' - - 'lib/solargraph/language_server/message/text_document/hover.rb' - - 'lib/solargraph/language_server/message/text_document/on_type_formatting.rb' - - 'lib/solargraph/language_server/message/text_document/prepare_rename.rb' - - 'lib/solargraph/language_server/message/text_document/references.rb' - - 'lib/solargraph/language_server/message/text_document/rename.rb' - - 'lib/solargraph/language_server/message/text_document/signature_help.rb' - - 'lib/solargraph/language_server/message/text_document/type_definition.rb' - - 'lib/solargraph/language_server/message/workspace.rb' - - 'lib/solargraph/language_server/message/workspace/did_change_configuration.rb' - - 'lib/solargraph/language_server/message/workspace/did_change_watched_files.rb' - - 'lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb' - - 'lib/solargraph/language_server/message/workspace/workspace_symbol.rb' - - 'lib/solargraph/language_server/request.rb' - - 'lib/solargraph/language_server/transport/data_reader.rb' - - 'lib/solargraph/logging.rb' - - 'lib/solargraph/page.rb' - - 'lib/solargraph/parser.rb' - - 'lib/solargraph/parser/comment_ripper.rb' - - 'lib/solargraph/parser/flow_sensitive_typing.rb' - - 'lib/solargraph/parser/node_methods.rb' - - 'lib/solargraph/parser/node_processor/base.rb' - - 'lib/solargraph/parser/parser_gem.rb' - - 'lib/solargraph/parser/parser_gem/class_methods.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/parser/parser_gem/node_processors.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/alias_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/and_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/args_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/begin_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/block_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/def_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/defs_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/if_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/sym_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/until_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/while_node.rb' - - 'lib/solargraph/parser/snippet.rb' - - 'lib/solargraph/pin/base_variable.rb' - - 'lib/solargraph/pin/block.rb' - - 'lib/solargraph/pin/callable.rb' - - 'lib/solargraph/pin/closure.rb' - - 'lib/solargraph/pin/common.rb' - - 'lib/solargraph/pin/constant.rb' - - 'lib/solargraph/pin/instance_variable.rb' - - 'lib/solargraph/pin/keyword.rb' - - 'lib/solargraph/pin/local_variable.rb' - - 'lib/solargraph/pin/namespace.rb' - - 'lib/solargraph/pin/parameter.rb' - - 'lib/solargraph/pin/proxy_type.rb' - - 'lib/solargraph/pin/reference.rb' - - 'lib/solargraph/pin/reference/override.rb' - - 'lib/solargraph/pin/reference/require.rb' - - 'lib/solargraph/pin/search.rb' - - 'lib/solargraph/pin/signature.rb' - - 'lib/solargraph/pin/singleton.rb' - - 'lib/solargraph/pin/symbol.rb' - - 'lib/solargraph/pin/until.rb' - - 'lib/solargraph/pin/while.rb' - - 'lib/solargraph/pin_cache.rb' - - 'lib/solargraph/rbs_map.rb' - - 'lib/solargraph/server_methods.rb' - - 'lib/solargraph/shell.rb' - - 'lib/solargraph/source/chain/array.rb' - - 'lib/solargraph/source/chain/block_symbol.rb' - - 'lib/solargraph/source/chain/block_variable.rb' - - 'lib/solargraph/source/chain/class_variable.rb' - - 'lib/solargraph/source/chain/constant.rb' - - 'lib/solargraph/source/chain/global_variable.rb' - - 'lib/solargraph/source/chain/hash.rb' - - 'lib/solargraph/source/chain/if.rb' - - 'lib/solargraph/source/chain/instance_variable.rb' - - 'lib/solargraph/source/chain/link.rb' - - 'lib/solargraph/source/chain/literal.rb' - - 'lib/solargraph/source/chain/or.rb' - - 'lib/solargraph/source/chain/q_call.rb' - - 'lib/solargraph/source/chain/variable.rb' - - 'lib/solargraph/source/chain/z_super.rb' - - 'lib/solargraph/source/encoding_fixes.rb' - - 'lib/solargraph/source_map/data.rb' - - 'lib/solargraph/yard_map/cache.rb' - - 'lib/solargraph/yard_map/helpers.rb' - - 'lib/solargraph/yard_map/mapper.rb' - - 'lib/solargraph/yard_map/mapper/to_constant.rb' - - 'lib/solargraph/yard_map/mapper/to_method.rb' - - 'lib/solargraph/yard_map/mapper/to_namespace.rb' - - 'lib/solargraph/yard_map/to_method.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). Style/EmptyLambdaParameter: @@ -1750,136 +919,7 @@ Style/FloatDivision: # Configuration parameters: EnforcedStyle. # SupportedStyles: always, always_true, never Style/FrozenStringLiteralComment: - Exclude: - - '**/*.arb' - - 'Gemfile' - - 'Rakefile' - - 'bin/solargraph' - - 'lib/solargraph/converters/dd.rb' - - 'lib/solargraph/converters/dl.rb' - - 'lib/solargraph/converters/dt.rb' - - 'lib/solargraph/converters/misc.rb' - - 'lib/solargraph/parser.rb' - - 'lib/solargraph/parser/comment_ripper.rb' - - 'lib/solargraph/parser/flow_sensitive_typing.rb' - - 'lib/solargraph/parser/node_methods.rb' - - 'lib/solargraph/parser/parser_gem.rb' - - 'lib/solargraph/parser/snippet.rb' - - 'lib/solargraph/pin/breakable.rb' - - 'lib/solargraph/pin/signature.rb' - - 'lib/solargraph/pin_cache.rb' - - 'lib/solargraph/source/chain/array.rb' - - 'lib/solargraph/source/chain/q_call.rb' - - 'lib/solargraph/yard_map/helpers.rb' - - 'solargraph.gemspec' - - 'spec/api_map/cache_spec.rb' - - 'spec/api_map/config_spec.rb' - - 'spec/api_map/source_to_yard_spec.rb' - - 'spec/api_map_spec.rb' - - 'spec/complex_type_spec.rb' - - 'spec/convention/struct_definition_spec.rb' - - 'spec/convention_spec.rb' - - 'spec/diagnostics/base_spec.rb' - - 'spec/diagnostics/require_not_found_spec.rb' - - 'spec/diagnostics/rubocop_helpers_spec.rb' - - 'spec/diagnostics/type_check_spec.rb' - - 'spec/diagnostics/update_errors_spec.rb' - - 'spec/diagnostics_spec.rb' - - 'spec/fixtures/formattable.rb' - - 'spec/fixtures/long_squiggly_heredoc.rb' - - 'spec/fixtures/rdoc-lib/Gemfile' - - 'spec/fixtures/rdoc-lib/lib/example.rb' - - 'spec/fixtures/rdoc-lib/rdoc-lib.gemspec' - - 'spec/fixtures/rubocop-custom-version/specifications/rubocop-0.0.0.gemspec' - - 'spec/fixtures/rubocop-validation-error/app.rb' - - 'spec/fixtures/unicode.rb' - - 'spec/fixtures/workspace-with-gemfile/Gemfile' - - 'spec/fixtures/workspace-with-gemfile/app.rb' - - 'spec/fixtures/workspace-with-gemfile/lib/other.rb' - - 'spec/fixtures/workspace-with-gemfile/lib/thing.rb' - - 'spec/fixtures/workspace/app.rb' - - 'spec/fixtures/workspace/lib/other.rb' - - 'spec/fixtures/workspace/lib/something.rb' - - 'spec/fixtures/workspace/lib/thing.rb' - - 'spec/fixtures/workspace_folders/folder1/app.rb' - - 'spec/fixtures/workspace_folders/folder2/app.rb' - - 'spec/fixtures/yard_map/attr.rb' - - 'spec/language_server/host/diagnoser_spec.rb' - - 'spec/language_server/host/dispatch_spec.rb' - - 'spec/language_server/host/message_worker_spec.rb' - - 'spec/language_server/host_spec.rb' - - 'spec/language_server/message/completion_item/resolve_spec.rb' - - 'spec/language_server/message/extended/check_gem_version_spec.rb' - - 'spec/language_server/message/initialize_spec.rb' - - 'spec/language_server/message/text_document/definition_spec.rb' - - 'spec/language_server/message/text_document/formatting_spec.rb' - - 'spec/language_server/message/text_document/hover_spec.rb' - - 'spec/language_server/message/text_document/type_definition_spec.rb' - - 'spec/language_server/message/workspace/did_change_watched_files_spec.rb' - - 'spec/language_server/message_spec.rb' - - 'spec/language_server/protocol_spec.rb' - - 'spec/language_server/transport/adapter_spec.rb' - - 'spec/language_server/transport/data_reader_spec.rb' - - 'spec/language_server/uri_helpers_spec.rb' - - 'spec/library_spec.rb' - - 'spec/logging_spec.rb' - - 'spec/parser/node_chainer_spec.rb' - - 'spec/parser/node_methods_spec.rb' - - 'spec/parser/node_processor_spec.rb' - - 'spec/parser_spec.rb' - - 'spec/pin/base_spec.rb' - - 'spec/pin/base_variable_spec.rb' - - 'spec/pin/block_spec.rb' - - 'spec/pin/class_variable_spec.rb' - - 'spec/pin/constant_spec.rb' - - 'spec/pin/delegated_method_spec.rb' - - 'spec/pin/documenting_spec.rb' - - 'spec/pin/instance_variable_spec.rb' - - 'spec/pin/keyword_spec.rb' - - 'spec/pin/local_variable_spec.rb' - - 'spec/pin/method_spec.rb' - - 'spec/pin/namespace_spec.rb' - - 'spec/pin/parameter_spec.rb' - - 'spec/pin/search_spec.rb' - - 'spec/pin/symbol_spec.rb' - - 'spec/position_spec.rb' - - 'spec/rbs_map/conversions_spec.rb' - - 'spec/rbs_map/core_map_spec.rb' - - 'spec/rbs_map/stdlib_map_spec.rb' - - 'spec/rbs_map_spec.rb' - - 'spec/shell_spec.rb' - - 'spec/source/chain/array_spec.rb' - - 'spec/source/chain/call_spec.rb' - - 'spec/source/chain/class_variable_spec.rb' - - 'spec/source/chain/constant_spec.rb' - - 'spec/source/chain/global_variable_spec.rb' - - 'spec/source/chain/head_spec.rb' - - 'spec/source/chain/instance_variable_spec.rb' - - 'spec/source/chain/link_spec.rb' - - 'spec/source/chain/literal_spec.rb' - - 'spec/source/chain/z_super_spec.rb' - - 'spec/source/chain_spec.rb' - - 'spec/source/change_spec.rb' - - 'spec/source/cursor_spec.rb' - - 'spec/source/source_chainer_spec.rb' - - 'spec/source/updater_spec.rb' - - 'spec/source_map/clip_spec.rb' - - 'spec/source_map/mapper_spec.rb' - - 'spec/source_map/node_processor_spec.rb' - - 'spec/source_map_spec.rb' - - 'spec/source_spec.rb' - - 'spec/spec_helper.rb' - - 'spec/type_checker/checks_spec.rb' - - 'spec/type_checker/levels/normal_spec.rb' - - 'spec/type_checker/levels/strict_spec.rb' - - 'spec/type_checker/levels/strong_spec.rb' - - 'spec/type_checker/levels/typed_spec.rb' - - 'spec/type_checker/rules_spec.rb' - - 'spec/type_checker_spec.rb' - - 'spec/workspace/config_spec.rb' - - 'spec/workspace_spec.rb' - - 'spec/yard_map/mapper/to_method_spec.rb' - - 'spec/yard_map/mapper_spec.rb' + Enabled: false # This cop supports unsafe autocorrection (--autocorrect-all). Style/GlobalStdStream: @@ -1892,15 +932,7 @@ Style/GlobalStdStream: # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: MinBodyLength, AllowConsecutiveConditionals. Style/GuardClause: - Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/library.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' - - 'lib/solargraph/pin_cache.rb' - - 'lib/solargraph/range.rb' - - 'lib/solargraph/rbs_map/conversions.rb' - - 'lib/solargraph/source.rb' - - 'lib/solargraph/workspace.rb' + Enabled: false # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: AllowSplatArgument. @@ -1935,52 +967,11 @@ Style/IdenticalConditionalBranches: # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowIfModifier. Style/IfInsideElse: - Exclude: - - 'lib/solargraph/complex_type/type_methods.rb' - - 'lib/solargraph/language_server/transport/data_reader.rb' - - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/source_map/clip.rb' - - 'lib/solargraph/type_checker.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). Style/IfUnlessModifier: - Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/api_map/index.rb' - - 'lib/solargraph/complex_type.rb' - - 'lib/solargraph/complex_type/unique_type.rb' - - 'lib/solargraph/doc_map.rb' - - 'lib/solargraph/language_server/message/completion_item/resolve.rb' - - 'lib/solargraph/language_server/message/initialize.rb' - - 'lib/solargraph/language_server/message/text_document/completion.rb' - - 'lib/solargraph/language_server/message/text_document/hover.rb' - - 'lib/solargraph/library.rb' - - 'lib/solargraph/parser/parser_gem/class_methods.rb' - - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb' - - 'lib/solargraph/pin/base.rb' - - 'lib/solargraph/pin/callable.rb' - - 'lib/solargraph/pin/common.rb' - - 'lib/solargraph/pin/constant.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/pin/parameter.rb' - - 'lib/solargraph/range.rb' - - 'lib/solargraph/rbs_map/conversions.rb' - - 'lib/solargraph/source/chain.rb' - - 'lib/solargraph/source/chain/call.rb' - - 'lib/solargraph/source/change.rb' - - 'lib/solargraph/source/cursor.rb' - - 'lib/solargraph/source/source_chainer.rb' - - 'lib/solargraph/source_map.rb' - - 'lib/solargraph/source_map/clip.rb' - - 'lib/solargraph/source_map/mapper.rb' - - 'lib/solargraph/type_checker.rb' - - 'lib/solargraph/workspace.rb' - - 'lib/solargraph/workspace/config.rb' - - 'lib/solargraph/yard_map/helpers.rb' - - 'lib/solargraph/yard_map/mapper/to_method.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle. @@ -2010,69 +1001,8 @@ Style/MapToSet: # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle. # SupportedStyles: require_parentheses, require_no_parentheses, require_no_parentheses_except_multiline -Style/MethodDefParentheses: - Exclude: - - 'lib/solargraph.rb' - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/api_map/index.rb' - - 'lib/solargraph/api_map/store.rb' - - 'lib/solargraph/complex_type.rb' - - 'lib/solargraph/complex_type/type_methods.rb' - - 'lib/solargraph/complex_type/unique_type.rb' - - 'lib/solargraph/convention.rb' - - 'lib/solargraph/convention/data_definition.rb' - - 'lib/solargraph/convention/data_definition/data_assignment_node.rb' - - 'lib/solargraph/convention/data_definition/data_definition_node.rb' - - 'lib/solargraph/convention/struct_definition.rb' - - 'lib/solargraph/convention/struct_definition/struct_assignment_node.rb' - - 'lib/solargraph/convention/struct_definition/struct_definition_node.rb' - - 'lib/solargraph/diagnostics/rubocop_helpers.rb' - - 'lib/solargraph/doc_map.rb' - - 'lib/solargraph/equality.rb' - - 'lib/solargraph/gem_pins.rb' - - 'lib/solargraph/language_server/host/message_worker.rb' - - 'lib/solargraph/language_server/host/sources.rb' - - 'lib/solargraph/language_server/message/text_document/formatting.rb' - - 'lib/solargraph/location.rb' - - 'lib/solargraph/parser/comment_ripper.rb' - - 'lib/solargraph/parser/flow_sensitive_typing.rb' - - 'lib/solargraph/parser/node_methods.rb' - - 'lib/solargraph/parser/node_processor/base.rb' - - 'lib/solargraph/parser/parser_gem/flawed_builder.rb' - - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/args_node.rb' - - 'lib/solargraph/pin/base.rb' - - 'lib/solargraph/pin/base_variable.rb' - - 'lib/solargraph/pin/block.rb' - - 'lib/solargraph/pin/callable.rb' - - 'lib/solargraph/pin/closure.rb' - - 'lib/solargraph/pin/delegated_method.rb' - - 'lib/solargraph/pin/local_variable.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/pin/parameter.rb' - - 'lib/solargraph/pin_cache.rb' - - 'lib/solargraph/position.rb' - - 'lib/solargraph/range.rb' - - 'lib/solargraph/rbs_map/conversions.rb' - - 'lib/solargraph/shell.rb' - - 'lib/solargraph/source.rb' - - 'lib/solargraph/source/chain/call.rb' - - 'lib/solargraph/source/chain/constant.rb' - - 'lib/solargraph/source_map.rb' - - 'lib/solargraph/source_map/mapper.rb' - - 'lib/solargraph/type_checker.rb' - - 'lib/solargraph/type_checker/checks.rb' - - 'lib/solargraph/yard_map/helpers.rb' - - 'lib/solargraph/yardoc.rb' - - 'spec/doc_map_spec.rb' - - 'spec/fixtures/rdoc-lib/lib/example.rb' - - 'spec/source_map_spec.rb' - - 'spec/spec_helper.rb' - - 'spec/type_checker/levels/normal_spec.rb' - - 'spec/type_checker/levels/strict_spec.rb' - - 'spec/type_checker/levels/strong_spec.rb' - - 'spec/type_checker/levels/typed_spec.rb' +Style/MethodDefParentheses: + Enabled: false Style/MultilineBlockChain: Exclude: @@ -2091,29 +1021,13 @@ Style/MultilineTernaryOperator: # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowMethodComparison, ComparisonsThreshold. Style/MultipleComparison: - Exclude: - - 'lib/solargraph/complex_type.rb' - - 'lib/solargraph/complex_type/type_methods.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' - - 'lib/solargraph/pin/base.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/pin/parameter.rb' - - 'lib/solargraph/source.rb' - - 'lib/solargraph/type_checker.rb' + Enabled: false # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle. # SupportedStyles: literals, strict Style/MutableConstant: - Exclude: - - 'lib/solargraph/diagnostics/rubocop.rb' - - 'lib/solargraph/logging.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/rbs_map/conversions.rb' - - 'lib/solargraph/rbs_map/core_fills.rb' - - 'lib/solargraph/yard_map/mapper/to_method.rb' - - 'spec/complex_type_spec.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle. @@ -2148,34 +1062,15 @@ Style/Next: - 'lib/solargraph/type_checker/checks.rb' # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: MinDigits, Strict, AllowedNumbers, AllowedPatterns. +# Configuration parameters: Strict, AllowedNumbers, AllowedPatterns. Style/NumericLiterals: - Exclude: - - 'lib/solargraph/language_server/error_codes.rb' - - 'spec/language_server/protocol_spec.rb' + MinDigits: 6 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle, AllowedMethods, AllowedPatterns. # SupportedStyles: predicate, comparison Style/NumericPredicate: - Exclude: - - 'spec/**/*' - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/api_map/index.rb' - - 'lib/solargraph/api_map/store.rb' - - 'lib/solargraph/complex_type.rb' - - 'lib/solargraph/complex_type/type_methods.rb' - - 'lib/solargraph/complex_type/unique_type.rb' - - 'lib/solargraph/language_server/message/extended/check_gem_version.rb' - - 'lib/solargraph/library.rb' - - 'lib/solargraph/parser/comment_ripper.rb' - - 'lib/solargraph/pin/delegated_method.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/shell.rb' - - 'lib/solargraph/source/chain/array.rb' - - 'lib/solargraph/source/change.rb' - - 'lib/solargraph/source/source_chainer.rb' - - 'lib/solargraph/workspace.rb' + Enabled: false Style/OpenStructUse: Exclude: @@ -2184,14 +1079,7 @@ Style/OpenStructUse: # Configuration parameters: AllowedMethods. # AllowedMethods: respond_to_missing? Style/OptionalBooleanParameter: - Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/language_server/message/text_document/completion.rb' - - 'lib/solargraph/source/chain.rb' - - 'lib/solargraph/source/chain/hash.rb' - - 'lib/solargraph/source/chain/z_super.rb' - - 'lib/solargraph/source/change.rb' - - 'lib/solargraph/source/updater.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowSafeAssignment, AllowInMultilineConditions. @@ -2254,14 +1142,7 @@ Style/RedundantInterpolation: # This cop supports safe autocorrection (--autocorrect). Style/RedundantParentheses: - Exclude: - - 'lib/solargraph/diagnostics/type_check.rb' - - 'lib/solargraph/language_server/message/initialize.rb' - - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/pin/parameter.rb' - - 'lib/solargraph/source.rb' - - 'lib/solargraph/type_checker.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). Style/RedundantRegexpArgument: @@ -2274,13 +1155,7 @@ Style/RedundantRegexpArgument: # This cop supports safe autocorrection (--autocorrect). Style/RedundantRegexpEscape: - Exclude: - - 'lib/solargraph/complex_type.rb' - - 'lib/solargraph/diagnostics/rubocop.rb' - - 'lib/solargraph/language_server/uri_helpers.rb' - - 'lib/solargraph/shell.rb' - - 'lib/solargraph/source_map/clip.rb' - - 'lib/solargraph/source_map/mapper.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowMultipleReturnValues. @@ -2294,15 +1169,7 @@ Style/RedundantReturn: # This cop supports safe autocorrection (--autocorrect). Style/RedundantSelf: - Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/equality.rb' - - 'lib/solargraph/location.rb' - - 'lib/solargraph/pin/base.rb' - - 'lib/solargraph/pin/callable.rb' - - 'lib/solargraph/pin/signature.rb' - - 'lib/solargraph/source/chain.rb' - - 'lib/solargraph/source/chain/link.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle, AllowInnerSlashes. @@ -2323,19 +1190,7 @@ Style/RescueStandardError: # Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength. # AllowedMethods: present?, blank?, presence, try, try! Style/SafeNavigation: - Exclude: - - 'lib/solargraph/api_map/index.rb' - - 'lib/solargraph/doc_map.rb' - - 'lib/solargraph/language_server/message/completion_item/resolve.rb' - - 'lib/solargraph/language_server/request.rb' - - 'lib/solargraph/language_server/transport/data_reader.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' - - 'lib/solargraph/pin/base.rb' - - 'lib/solargraph/pin/conversions.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/pin_cache.rb' - - 'lib/solargraph/range.rb' - - 'lib/solargraph/type_checker.rb' + Enabled: false # Configuration parameters: Max. Style/SafeNavigationChainLength: @@ -2344,36 +1199,12 @@ Style/SafeNavigationChainLength: # This cop supports unsafe autocorrection (--autocorrect-all). Style/SlicingWithRange: - Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/complex_type/unique_type.rb' - - 'lib/solargraph/convention/data_definition/data_definition_node.rb' - - 'lib/solargraph/convention/struct_definition/struct_definition_node.rb' - - 'lib/solargraph/diagnostics/rubocop_helpers.rb' - - 'lib/solargraph/library.rb' - - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/pin/namespace.rb' - - 'lib/solargraph/source.rb' - - 'lib/solargraph/source/chain/constant.rb' - - 'lib/solargraph/source/change.rb' - - 'lib/solargraph/source/cursor.rb' - - 'lib/solargraph/source/source_chainer.rb' - - 'lib/solargraph/source_map/mapper.rb' - - 'lib/solargraph/type_checker/checks.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowModifier. Style/SoleNestedConditional: - Exclude: - - 'lib/solargraph/complex_type/unique_type.rb' - - 'lib/solargraph/parser/flow_sensitive_typing.rb' - - 'lib/solargraph/pin/parameter.rb' - - 'lib/solargraph/source.rb' - - 'lib/solargraph/source/source_chainer.rb' - - 'lib/solargraph/type_checker.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). Style/StderrPuts: @@ -2384,114 +1215,13 @@ Style/StderrPuts: # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: Mode. Style/StringConcatenation: - Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/api_map/index.rb' - - 'lib/solargraph/pin/base.rb' - - 'lib/solargraph/pin/callable.rb' - - 'lib/solargraph/pin/closure.rb' - - 'lib/solargraph/pin/local_variable.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/pin/namespace.rb' - - 'solargraph.gemspec' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline. # SupportedStyles: single_quotes, double_quotes Style/StringLiterals: - Exclude: - - 'Gemfile' - - 'Rakefile' - - 'lib/solargraph/api_map/index.rb' - - 'lib/solargraph/complex_type.rb' - - 'lib/solargraph/complex_type/unique_type.rb' - - 'lib/solargraph/convention/struct_definition.rb' - - 'lib/solargraph/doc_map.rb' - - 'lib/solargraph/language_server/host.rb' - - 'lib/solargraph/language_server/message/extended/document_gems.rb' - - 'lib/solargraph/language_server/message/extended/download_core.rb' - - 'lib/solargraph/language_server/message/initialize.rb' - - 'lib/solargraph/language_server/message/text_document/completion.rb' - - 'lib/solargraph/library.rb' - - 'lib/solargraph/parser/parser_gem/class_methods.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/pin/base.rb' - - 'lib/solargraph/pin/conversions.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/pin/parameter.rb' - - 'lib/solargraph/rbs_map/conversions.rb' - - 'lib/solargraph/server_methods.rb' - - 'lib/solargraph/shell.rb' - - 'lib/solargraph/workspace.rb' - - 'lib/solargraph/yard_map/mapper/to_method.rb' - - 'lib/solargraph/yard_tags.rb' - - 'solargraph.gemspec' - - 'spec/api_map/cache_spec.rb' - - 'spec/api_map/config_spec.rb' - - 'spec/api_map/source_to_yard_spec.rb' - - 'spec/complex_type_spec.rb' - - 'spec/convention/struct_definition_spec.rb' - - 'spec/diagnostics/base_spec.rb' - - 'spec/diagnostics/require_not_found_spec.rb' - - 'spec/diagnostics/rubocop_helpers_spec.rb' - - 'spec/diagnostics/rubocop_spec.rb' - - 'spec/diagnostics/type_check_spec.rb' - - 'spec/diagnostics/update_errors_spec.rb' - - 'spec/diagnostics_spec.rb' - - 'spec/fixtures/rdoc-lib/rdoc-lib.gemspec' - - 'spec/language_server/host/diagnoser_spec.rb' - - 'spec/language_server/host/dispatch_spec.rb' - - 'spec/language_server/host/message_worker_spec.rb' - - 'spec/language_server/host_spec.rb' - - 'spec/language_server/message/completion_item/resolve_spec.rb' - - 'spec/language_server/message/extended/check_gem_version_spec.rb' - - 'spec/language_server/message/initialize_spec.rb' - - 'spec/language_server/message/text_document/rename_spec.rb' - - 'spec/language_server/message_spec.rb' - - 'spec/language_server/protocol_spec.rb' - - 'spec/language_server/transport/adapter_spec.rb' - - 'spec/language_server/transport/data_reader_spec.rb' - - 'spec/library_spec.rb' - - 'spec/logging_spec.rb' - - 'spec/parser/node_chainer_spec.rb' - - 'spec/parser/node_methods_spec.rb' - - 'spec/parser_spec.rb' - - 'spec/pin/base_spec.rb' - - 'spec/pin/base_variable_spec.rb' - - 'spec/pin/constant_spec.rb' - - 'spec/pin/instance_variable_spec.rb' - - 'spec/pin/keyword_spec.rb' - - 'spec/pin/local_variable_spec.rb' - - 'spec/pin/namespace_spec.rb' - - 'spec/pin/symbol_spec.rb' - - 'spec/position_spec.rb' - - 'spec/rbs_map/conversions_spec.rb' - - 'spec/rbs_map/core_map_spec.rb' - - 'spec/rbs_map/stdlib_map_spec.rb' - - 'spec/shell_spec.rb' - - 'spec/source/chain/array_spec.rb' - - 'spec/source/chain/call_spec.rb' - - 'spec/source/chain/class_variable_spec.rb' - - 'spec/source/chain/constant_spec.rb' - - 'spec/source/chain/global_variable_spec.rb' - - 'spec/source/chain/head_spec.rb' - - 'spec/source/chain/instance_variable_spec.rb' - - 'spec/source/chain/link_spec.rb' - - 'spec/source/chain/literal_spec.rb' - - 'spec/source/chain/z_super_spec.rb' - - 'spec/source/chain_spec.rb' - - 'spec/source/change_spec.rb' - - 'spec/source/cursor_spec.rb' - - 'spec/source/source_chainer_spec.rb' - - 'spec/source/updater_spec.rb' - - 'spec/source_map/clip_spec.rb' - - 'spec/source_map/mapper_spec.rb' - - 'spec/source_map_spec.rb' - - 'spec/source_spec.rb' - - 'spec/type_checker/levels/strict_spec.rb' - - 'spec/workspace/config_spec.rb' - - 'spec/workspace_spec.rb' - - 'spec/yard_map/mapper/to_method_spec.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). Style/SuperArguments: @@ -2505,35 +1235,13 @@ Style/SuperArguments: # Configuration parameters: EnforcedStyle, MinSize. # SupportedStyles: percent, brackets Style/SymbolArray: - Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/block_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/pin/parameter.rb' - - 'lib/solargraph/shell.rb' - - 'lib/solargraph/source.rb' - - 'lib/solargraph/source/chain/literal.rb' - - 'lib/solargraph/source_map/clip.rb' - - 'lib/solargraph/source_map/mapper.rb' - - 'lib/solargraph/type_checker.rb' - - 'spec/parser/node_methods_spec.rb' - - 'spec/source_map/mapper_spec.rb' + Enabled: false # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: AllowMethodsWithArguments, AllowedMethods, AllowedPatterns, AllowComments. # AllowedMethods: define_method Style/SymbolProc: - Exclude: - - 'lib/solargraph/gem_pins.rb' - - 'lib/solargraph/language_server/message/text_document/hover.rb' - - 'lib/solargraph/language_server/message/text_document/signature_help.rb' - - 'lib/solargraph/parser/flow_sensitive_typing.rb' - - 'lib/solargraph/pin/base.rb' - - 'lib/solargraph/pin/callable.rb' - - 'lib/solargraph/pin/closure.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle, AllowSafeAssignment. @@ -2546,19 +1254,7 @@ Style/TernaryParentheses: # Configuration parameters: EnforcedStyleForMultiline. # SupportedStylesForMultiline: comma, consistent_comma, no_comma Style/TrailingCommaInArguments: - Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/parser/node_processor.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/block_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/def_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/defs_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/until_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/while_node.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/rbs_map/conversions.rb' - - 'lib/solargraph/yard_map/mapper/to_method.rb' - - 'lib/solargraph/yard_map/mapper/to_namespace.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyleForMultiline. @@ -2572,13 +1268,7 @@ Style/TrailingCommaInArrayLiteral: # Configuration parameters: EnforcedStyleForMultiline. # SupportedStylesForMultiline: comma, consistent_comma, diff_comma, no_comma Style/TrailingCommaInHashLiteral: - Exclude: - - 'lib/solargraph/pin/base_variable.rb' - - 'lib/solargraph/pin/callable.rb' - - 'lib/solargraph/pin/closure.rb' - - 'lib/solargraph/pin/local_variable.rb' - - 'lib/solargraph/pin/parameter.rb' - - 'lib/solargraph/rbs_map/conversions.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: ExactNameMatch, AllowPredicates, AllowDSLWriters, IgnoreClassMethods, AllowedMethods. @@ -2597,20 +1287,7 @@ Style/WhileUntilModifier: # Configuration parameters: EnforcedStyle, MinSize, WordRegex. # SupportedStyles: percent, brackets Style/WordArray: - Exclude: - - 'lib/solargraph/complex_type.rb' - - 'lib/solargraph/complex_type/unique_type.rb' - - 'lib/solargraph/diagnostics/type_check.rb' - - 'lib/solargraph/language_server/message/text_document/formatting.rb' - - 'spec/doc_map_spec.rb' - - 'spec/parser/node_chainer_spec.rb' - - 'spec/pin/method_spec.rb' - - 'spec/source/cursor_spec.rb' - - 'spec/source/source_chainer_spec.rb' - - 'spec/source_map/clip_spec.rb' - - 'spec/source_map/mapper_spec.rb' - - 'spec/source_map_spec.rb' - - 'spec/source_spec.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). Style/YAMLFileRead: @@ -2619,13 +1296,7 @@ Style/YAMLFileRead: # This cop supports unsafe autocorrection (--autocorrect-all). Style/ZeroLengthPredicate: - Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/api_map/index.rb' - - 'lib/solargraph/language_server/host.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/source/chain/array.rb' - - 'spec/language_server/protocol_spec.rb' + Enabled: false # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle. @@ -2638,33 +1309,7 @@ YARD/CollectionType: # Configuration parameters: EnforcedStylePrototypeName. # SupportedStylesPrototypeName: before, after YARD/MismatchName: - Exclude: - - 'lib/solargraph/complex_type.rb' - - 'lib/solargraph/complex_type/unique_type.rb' - - 'lib/solargraph/gem_pins.rb' - - 'lib/solargraph/language_server/host.rb' - - 'lib/solargraph/language_server/host/dispatch.rb' - - 'lib/solargraph/language_server/request.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/parser/region.rb' - - 'lib/solargraph/pin/base.rb' - - 'lib/solargraph/pin/base_variable.rb' - - 'lib/solargraph/pin/block.rb' - - 'lib/solargraph/pin/callable.rb' - - 'lib/solargraph/pin/closure.rb' - - 'lib/solargraph/pin/delegated_method.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/pin/namespace.rb' - - 'lib/solargraph/pin/parameter.rb' - - 'lib/solargraph/pin/proxy_type.rb' - - 'lib/solargraph/pin/reference.rb' - - 'lib/solargraph/pin/symbol.rb' - - 'lib/solargraph/pin/until.rb' - - 'lib/solargraph/pin/while.rb' - - 'lib/solargraph/pin_cache.rb' - - 'lib/solargraph/source/chain/call.rb' - - 'lib/solargraph/source/chain/z_super.rb' - - 'lib/solargraph/type_checker.rb' + Enabled: false YARD/TagTypeSyntax: Exclude: @@ -2673,72 +1318,7 @@ YARD/TagTypeSyntax: - 'lib/solargraph/type_checker.rb' # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings. +# Configuration parameters: AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings. # URISchemes: http, https Layout/LineLength: - Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/api_map/source_to_yard.rb' - - 'lib/solargraph/api_map/store.rb' - - 'lib/solargraph/complex_type.rb' - - 'lib/solargraph/complex_type/unique_type.rb' - - 'lib/solargraph/convention/data_definition.rb' - - 'lib/solargraph/doc_map.rb' - - 'lib/solargraph/gem_pins.rb' - - 'lib/solargraph/language_server/host.rb' - - 'lib/solargraph/language_server/message/extended/check_gem_version.rb' - - 'lib/solargraph/language_server/message/extended/download_core.rb' - - 'lib/solargraph/language_server/message/initialize.rb' - - 'lib/solargraph/language_server/message/text_document/completion.rb' - - 'lib/solargraph/language_server/message/text_document/definition.rb' - - 'lib/solargraph/language_server/message/text_document/document_highlight.rb' - - 'lib/solargraph/language_server/message/text_document/prepare_rename.rb' - - 'lib/solargraph/language_server/message/text_document/references.rb' - - 'lib/solargraph/language_server/message/text_document/rename.rb' - - 'lib/solargraph/language_server/message/workspace/did_change_watched_files.rb' - - 'lib/solargraph/library.rb' - - 'lib/solargraph/parser/comment_ripper.rb' - - 'lib/solargraph/parser/flow_sensitive_typing.rb' - - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/and_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/if_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb' - - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' - - 'lib/solargraph/pin/base.rb' - - 'lib/solargraph/pin/callable.rb' - - 'lib/solargraph/pin/common.rb' - - 'lib/solargraph/pin/documenting.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/pin/parameter.rb' - - 'lib/solargraph/rbs_map/conversions.rb' - - 'lib/solargraph/rbs_map/core_fills.rb' - - 'lib/solargraph/shell.rb' - - 'lib/solargraph/source.rb' - - 'lib/solargraph/source/chain.rb' - - 'lib/solargraph/source/chain/call.rb' - - 'lib/solargraph/source/chain/if.rb' - - 'lib/solargraph/source/chain/instance_variable.rb' - - 'lib/solargraph/source/chain/variable.rb' - - 'lib/solargraph/source/cursor.rb' - - 'lib/solargraph/source/encoding_fixes.rb' - - 'lib/solargraph/source/source_chainer.rb' - - 'lib/solargraph/source_map.rb' - - 'lib/solargraph/source_map/clip.rb' - - 'lib/solargraph/source_map/mapper.rb' - - 'lib/solargraph/type_checker.rb' - - 'lib/solargraph/workspace.rb' - - 'lib/solargraph/workspace/config.rb' - - 'lib/solargraph/yard_map/mapper/to_method.rb' - - 'spec/api_map_spec.rb' - - 'spec/complex_type_spec.rb' - - 'spec/language_server/message/completion_item/resolve_spec.rb' - - 'spec/language_server/message/extended/check_gem_version_spec.rb' - - 'spec/language_server/message/text_document/definition_spec.rb' - - 'spec/language_server/protocol_spec.rb' - - 'spec/pin/parameter_spec.rb' - - 'spec/source/chain_spec.rb' - - 'spec/source_map/clip_spec.rb' - - 'spec/source_map_spec.rb' - - 'spec/workspace_spec.rb' + Max: 244 diff --git a/solargraph.gemspec b/solargraph.gemspec index e6bb9394a..7610bb8ea 100755 --- a/solargraph.gemspec +++ b/solargraph.gemspec @@ -48,9 +48,16 @@ Gem::Specification.new do |s| s.add_development_dependency 'public_suffix', '~> 3.1' s.add_development_dependency 'rake', '~> 13.2' s.add_development_dependency 'rspec', '~> 3.5' - s.add_development_dependency 'rubocop-rake', '~> 0.7' - s.add_development_dependency 'rubocop-rspec', '~> 3.6' - s.add_development_dependency 'rubocop-yard', '~> 1.0' + # + # very specific development-time RuboCop version patterns for CI + # stability - feel free to update in an isolated PR + # + # even more specific on RuboCop itself, which is written into _todo + # file. + s.add_development_dependency 'rubocop', '~> 1.79.2.0' + s.add_development_dependency 'rubocop-rake', '~> 0.7.1' + s.add_development_dependency 'rubocop-rspec', '~> 3.6.0' + s.add_development_dependency 'rubocop-yard', '~> 1.0.0' s.add_development_dependency 'simplecov', '~> 0.21' s.add_development_dependency 'simplecov-lcov', '~> 0.8' s.add_development_dependency 'undercover', '~> 0.7' From 61260f346883de89c8dd9c61b205e88f59ae3a8b Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 30 Aug 2025 10:18:50 -0400 Subject: [PATCH 035/106] Fix merge issue --- .github/workflows/linting.yml | 2 +- .rubocop_todo.yml | 25 +++++++++---------------- lib/solargraph/api_map.rb | 2 -- spec/api_map_spec.rb | 3 --- 4 files changed, 10 insertions(+), 22 deletions(-) diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index aa22ce22c..b4ef26bfe 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -115,7 +115,7 @@ jobs: - name: Run RuboCop against todo file continue-on-error: true run: | - cmd="bundle exec rubocop --auto-gen-config --exclude-limit=5 --no-offense-counts --no-auto-gen-timestampxb*com" + cmd="bundle exec rubocop --auto-gen-config --exclude-limit=5 --no-offense-counts --no-auto-gen-timestamp" ${cmd:?} set +e if [ -n "$(git status --porcelain)" ] diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 7641198af..0ed335f34 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,5 +1,5 @@ # This configuration was generated by -# `rubocop --auto-gen-config --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp` +# `rubocop --auto-gen-config --exclude-limit 5 --no-offense-counts --no-auto-gen-timestamp` # using RuboCop version 1.80.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. @@ -121,7 +121,13 @@ Layout/EndOfLine: # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowForAlignment, AllowBeforeTrailingComments, ForceEqualSignAlignment. - Enabled: false +Layout/ExtraSpacing: + Exclude: + - 'lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb' + - 'lib/solargraph/pin/closure.rb' + - 'lib/solargraph/rbs_map/conversions.rb' + - 'lib/solargraph/type_checker.rb' + - 'spec/spec_helper.rb' # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle, IndentationWidth. @@ -604,9 +610,9 @@ RSpec/DescribeClass: - '**/spec/routing/**/*' - '**/spec/system/**/*' - '**/spec/views/**/*' + - 'spec/api_map_method_spec.rb' - 'spec/complex_type_spec.rb' - 'spec/source_map/node_processor_spec.rb' - - 'spec/api_map_method_spec.rb' # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: SkipBlocks, EnforcedStyle, OnlyStaticConstants. @@ -633,7 +639,6 @@ RSpec/ExampleLength: # DisallowedExamples: works RSpec/ExampleWording: Exclude: - - 'spec/convention/struct_definition_spec.rb' - 'spec/pin/base_spec.rb' - 'spec/pin/method_spec.rb' @@ -1114,12 +1119,6 @@ Style/RedundantFreeze: - 'lib/solargraph/complex_type.rb' - 'lib/solargraph/source_map/mapper.rb' -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: AllowComments. -Style/RedundantInitialize: - Exclude: - - 'lib/solargraph/rbs_map/core_map.rb' - # This cop supports unsafe autocorrection (--autocorrect-all). Style/RedundantInterpolation: Exclude: @@ -1140,12 +1139,6 @@ Style/RedundantRegexpArgument: - 'spec/diagnostics/rubocop_spec.rb' - 'spec/language_server/host_spec.rb' -# This cop supports safe autocorrection (--autocorrect). -Style/RedundantRegexpCharacterClass: - Exclude: - - 'lib/solargraph/source/cursor.rb' - - 'lib/solargraph/source/source_chainer.rb' - # This cop supports safe autocorrection (--autocorrect). Style/RedundantRegexpEscape: Enabled: false diff --git a/lib/solargraph/api_map.rb b/lib/solargraph/api_map.rb index f58633a0c..ee35dc497 100755 --- a/lib/solargraph/api_map.rb +++ b/lib/solargraph/api_map.rb @@ -753,7 +753,6 @@ def store # @param skip [Set] # @param no_core [Boolean] Skip core classes if true # @return [Array] - # rubocop:disable Metrics/CyclomaticComplexity def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false rooted_type = ComplexType.parse(rooted_tag).force_rooted fqns = rooted_type.namespace @@ -827,7 +826,6 @@ def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false end result end - # rubocop:enable Metrics/CyclomaticComplexity # @param fqns [String] # @param visibility [Array] diff --git a/spec/api_map_spec.rb b/spec/api_map_spec.rb index a612b428e..85e62d507 100755 --- a/spec/api_map_spec.rb +++ b/spec/api_map_spec.rb @@ -1,7 +1,6 @@ require 'tmpdir' describe Solargraph::ApiMap do - # rubocop:disable RSpec/InstanceVariable before :all do @api_map = Solargraph::ApiMap.new end @@ -873,6 +872,4 @@ def c clip = api_map.clip_at('test.rb', [18, 4]) expect(clip.infer.to_s).to eq('Integer') end - - # rubocop:enable RSpec/InstanceVariable end From 91ced058c5c81f3b1e63c51b27c08f3ca14c2339 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 30 Aug 2025 21:25:08 -0400 Subject: [PATCH 036/106] Add spec --- spec/type_checker/levels/strong_spec.rb | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/spec/type_checker/levels/strong_spec.rb b/spec/type_checker/levels/strong_spec.rb index a03e6eb5d..94f0f207f 100644 --- a/spec/type_checker/levels/strong_spec.rb +++ b/spec/type_checker/levels/strong_spec.rb @@ -97,6 +97,29 @@ def bar expect(checker.problems.map(&:message)).to include('Call to #foo is missing keyword argument b') end + it 'understands complex use of other' do + checker = type_checker(%( + class A + # @param other [self] + # + # @return [void] + def foo other; end + + # @param other [self] + # + # @return [void] + def bar(other); end + end + + class B < A + def bar(other) + foo(other) + end + end + )) + expect(checker.problems.map(&:message)).to be_empty + end + it 'calls out type issues even when keyword issues are there' do pending('fixes to arg vs param checking algorithm') From 2702f443f84884bc5a72d84a3da66f5d7df51a51 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 30 Aug 2025 21:39:22 -0400 Subject: [PATCH 037/106] Work around strong typechecking issue --- lib/solargraph/type_checker.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/solargraph/type_checker.rb b/lib/solargraph/type_checker.rb index dd13d7ec7..2f9b7da1c 100644 --- a/lib/solargraph/type_checker.rb +++ b/lib/solargraph/type_checker.rb @@ -453,8 +453,7 @@ def kwarg_problems_for sig, argchain, api_map, block_pin, locals, location, pin, ptype = data[:qualified] ptype = ptype.self_to_type(pin.context) unless ptype.undefined? - argtype = argchain.infer(api_map, block_pin, locals) - argtype = argtype.self_to_type(block_pin.context) + argtype = argchain.infer(api_map, block_pin, locals).self_to_type(block_pin.context) if argtype.defined? && ptype && !any_types_match?(api_map, ptype, argtype) result.push Problem.new(location, "Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}") end From f623a73ad88f44d3ff6e6873a1682f33a07d431b Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Mon, 1 Sep 2025 07:52:39 -0400 Subject: [PATCH 038/106] Pull in overcommit fix --- lib/solargraph/yardoc.rb | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/solargraph/yardoc.rb b/lib/solargraph/yardoc.rb index 625e41ce4..ed638a7ce 100644 --- a/lib/solargraph/yardoc.rb +++ b/lib/solargraph/yardoc.rb @@ -26,7 +26,7 @@ def cache(yard_plugins, gemspec) # # @sg-ignore RBS gem doesn't reflect that Open3.* also include # kwopts from Process.spawn() - stdout_and_stderr_str, status = Open3.capture2e(cmd, chdir: gemspec.gem_dir) + stdout_and_stderr_str, status = Open3.capture2e(current_bundle_env_tweaks, cmd, chdir: gemspec.gem_dir) unless status.success? Solargraph.logger.warn { "YARD failed running #{cmd.inspect} in #{gemspec.gem_dir}" } Solargraph.logger.info stdout_and_stderr_str @@ -60,5 +60,22 @@ def load!(gemspec) YARD::Registry.load! PinCache.yardoc_path gemspec YARD::Registry.all end + + # If the BUNDLE_GEMFILE environment variable is set, we need to + # make sure it's an absolute path, as we'll be changing + # directories. + # + # 'bundle exec' sets an absolute path here, but at least the + # overcommit gem does not, breaking on-the-fly documention with a + # spawned yardoc command from our current bundle + # + # @return [Hash{String => String}] a hash of environment variables to override + def current_bundle_env_tweaks + tweaks = {} + if ENV['BUNDLE_GEMFILE'] && !ENV['BUNDLE_GEMFILE'].empty? + tweaks['BUNDLE_GEMFILE'] = File.expand_path(ENV['BUNDLE_GEMFILE']) + end + tweaks + end end end From a8b678b1a1abec6a571ad321b4245575541bf969 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Mon, 1 Sep 2025 08:56:57 -0400 Subject: [PATCH 039/106] Add spec --- .rubocop.yml | 3 +++ spec/yardoc_spec.rb | 52 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 spec/yardoc_spec.rb diff --git a/.rubocop.yml b/.rubocop.yml index a73324db2..c17a56410 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -21,6 +21,9 @@ AllCops: - "vendor/**/.*" TargetRubyVersion: 3.0 +RSpec/SpecFilePathFormat: + Enabled: false + Style/MethodDefParentheses: EnforcedStyle: require_no_parentheses diff --git a/spec/yardoc_spec.rb b/spec/yardoc_spec.rb new file mode 100644 index 000000000..34dcad45c --- /dev/null +++ b/spec/yardoc_spec.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require 'tmpdir' +require 'open3' + +describe Solargraph::Yardoc do + let(:gem_yardoc_path) do + Solargraph::PinCache.yardoc_path gemspec + end + + before do + FileUtils.mkdir_p(gem_yardoc_path) + end + + describe '#cache' do + let(:api_map) { Solargraph::ApiMap.new } + let(:doc_map) { api_map.doc_map } + let(:gemspec) { Gem::Specification.find_by_path('rubocop') } + let(:output) { '' } + + before do + allow(Solargraph.logger).to receive(:warn) + allow(Solargraph.logger).to receive(:info) + FileUtils.rm_rf(gem_yardoc_path) + end + + context 'when given a relative BUNDLE_GEMFILE path' do + around do |example| + # turn absolute BUNDLE_GEMFILE path into relative + existing_gemfile = ENV.fetch('BUNDLE_GEMFILE', nil) + current_dir = Dir.pwd + # remove prefix current_dir from path + ENV['BUNDLE_GEMFILE'] = existing_gemfile.sub("#{current_dir}/", '') + raise 'could not figure out relative path' if Pathname.new(ENV.fetch('BUNDLE_GEMFILE', nil)).absolute? + example.run + ENV['BUNDLE_GEMFILE'] = existing_gemfile + end + + it 'sends Open3 an absolute path' do + called_with = nil + allow(Open3).to receive(:capture2e) do |*args| + called_with = args + ['output', instance_double(Process::Status, success?: true)] + end + + described_class.cache([], gemspec) + + expect(called_with[0]['BUNDLE_GEMFILE']).to start_with('/') + end + end + end +end From 9f7fe59e6f172486fc3cce20fad1d8d5ce29bfa6 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 2 Sep 2025 05:45:12 -0400 Subject: [PATCH 040/106] Add --references flag (superclass for now) --- lib/solargraph/api_map.rb | 31 ++++++++++++------------- lib/solargraph/shell.rb | 49 +++++++++++++++++++++++++-------------- 2 files changed, 46 insertions(+), 34 deletions(-) diff --git a/lib/solargraph/api_map.rb b/lib/solargraph/api_map.rb index 4e8332080..54019d1b8 100755 --- a/lib/solargraph/api_map.rb +++ b/lib/solargraph/api_map.rb @@ -730,6 +730,21 @@ def inner_get_methods_from_reference fq_reference_tag, namespace_pin, type, scop methods end + # @param fq_sub_tag [String] + # @return [String, nil] + def qualify_superclass fq_sub_tag + fq_sub_type = ComplexType.try_parse(fq_sub_tag) + fq_sub_ns = fq_sub_type.name + sup_tag = store.get_superclass(fq_sub_tag) + sup_type = ComplexType.try_parse(sup_tag) + sup_ns = sup_type.name + return nil if sup_tag.nil? + parts = fq_sub_ns.split('::') + last = parts.pop + parts.pop if last == sup_ns + qualify(sup_tag, parts.join('::')) + end + private # A hash of source maps with filename keys. @@ -865,21 +880,6 @@ def qualify_lower namespace, context qualify namespace, context.split('::')[0..-2].join('::') end - # @param fq_sub_tag [String] - # @return [String, nil] - def qualify_superclass fq_sub_tag - fq_sub_type = ComplexType.try_parse(fq_sub_tag) - fq_sub_ns = fq_sub_type.name - sup_tag = store.get_superclass(fq_sub_tag) - sup_type = ComplexType.try_parse(sup_tag) - sup_ns = sup_type.name - return nil if sup_tag.nil? - parts = fq_sub_ns.split('::') - last = parts.pop - parts.pop if last == sup_ns - qualify(sup_tag, parts.join('::')) - end - # @param name [String] Namespace to fully qualify # @param root [String] The context to search # @param skip [Set] Contexts already searched @@ -949,7 +949,6 @@ def resolve_fqns fqns assignment = constant.assignment - # @sg-ignore Wrong argument type for Solargraph::ApiMap#resolve_trivial_constant: node expected AST::Node, received Parser::AST::Node, nil target_ns = resolve_trivial_constant(assignment) if assignment return nil unless target_ns qualify_namespace target_ns, constant_namespace diff --git a/lib/solargraph/shell.rb b/lib/solargraph/shell.rb index 21a53172f..11039b187 100755 --- a/lib/solargraph/shell.rb +++ b/lib/solargraph/shell.rb @@ -246,6 +246,8 @@ def list # @sg-ignore Unresolved call to option option :typify, type: :boolean, desc: 'Output the calculated return type of the pin from annotations', default: false # @sg-ignore Unresolved call to option + option :references, type: :boolean, desc: 'Show references', default: false + # @sg-ignore Unresolved call to option option :probe, type: :boolean, desc: 'Output the calculated return type of the pin from annotations and inference', default: false # @sg-ignore Unresolved call to option option :stack, type: :boolean, desc: 'Show entire stack of a method pin by including definitions in superclasses', default: false @@ -253,27 +255,34 @@ def list # @return [void] def pin path api_map = Solargraph::ApiMap.load_with_cache('.', $stderr) - - # @sg-ignore Unresolved call to options - # @type [Array] - pins = if options[:stack] - scope, ns, meth = if path.include? '#' - [:instance, *path.split('#', 2)] - else - [:class, *path.split('.', 2)] - end - - # @sg-ignore Wrong argument type for - # Solargraph::ApiMap#get_method_stack: rooted_tag - # expected String, received Array - api_map.get_method_stack(ns, meth, scope: scope) - else - api_map.get_path_pins path - end - if pins.empty? + pins = api_map.get_path_pins path + references = {} + pin = pins.first + case pin + when nil $stderr.puts "Pin not found for path '#{path}'" exit 1 + when Pin::Method + if options[:stack] + scope, ns, meth = if path.include? '#' + [:instance, *path.split('#', 2)] + else + [:class, *path.split('.', 2)] + end + + # @sg-ignore Wrong argument type for + # Solargraph::ApiMap#get_method_stack: rooted_tag + # expected String, received Array + pins = api_map.get_method_stack(ns, meth, scope: scope) + end + when Pin::Namespace + if options[:references] + superclass_tag = api_map.qualify_superclass(pin.return_type.tag) + superclass_pin = api_map.get_path_pins(superclass_tag).first if superclass_tag + references[:superclass] = superclass_pin if superclass_pin + end end + pins.each do |pin| # @sg-ignore Unresolved call to options if options[:typify] || options[:probe] @@ -288,6 +297,10 @@ def pin path print_pin(pin) end + references.each do |key, refpin| + puts "\n# #{key.to_s.capitalize}:\n\n" + print_pin(refpin) + end end private From 79e8cd900b13c60591e3bc76e3f5bffeb93bbdcb Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 2 Sep 2025 05:49:18 -0400 Subject: [PATCH 041/106] Add another @sg-ignore --- lib/solargraph/shell.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/solargraph/shell.rb b/lib/solargraph/shell.rb index c56be0107..aa7214196 100755 --- a/lib/solargraph/shell.rb +++ b/lib/solargraph/shell.rb @@ -278,6 +278,7 @@ def pin path pins = api_map.get_method_stack(ns, meth, scope: scope) end when Pin::Namespace + # @sg-ignore Unresolved call to options if options[:references] superclass_tag = api_map.qualify_superclass(pin.return_type.tag) superclass_pin = api_map.get_path_pins(superclass_tag).first if superclass_tag From da205a3b208c7aad3aedced43b889e70ab247348 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 2 Sep 2025 05:52:39 -0400 Subject: [PATCH 042/106] Catch up with .rubocop_todo.yml --- .rubocop_todo.yml | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index c711cd674..c3d28df49 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -920,9 +920,9 @@ RSpec/DescribeClass: - '**/spec/routing/**/*' - '**/spec/system/**/*' - '**/spec/views/**/*' + - 'spec/api_map_method_spec.rb' - 'spec/complex_type_spec.rb' - 'spec/source_map/node_processor_spec.rb' - - 'spec/api_map_method_spec.rb' # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: SkipBlocks, EnforcedStyle, OnlyStaticConstants. @@ -1045,7 +1045,6 @@ RSpec/ExampleLength: # DisallowedExamples: works RSpec/ExampleWording: Exclude: - - 'spec/convention/struct_definition_spec.rb' - 'spec/pin/base_spec.rb' - 'spec/pin/method_spec.rb' @@ -1086,7 +1085,6 @@ RSpec/ImplicitExpect: RSpec/InstanceVariable: Exclude: - 'spec/api_map/config_spec.rb' - - 'spec/api_map_spec.rb' - 'spec/diagnostics/require_not_found_spec.rb' - 'spec/language_server/host/dispatch_spec.rb' - 'spec/language_server/host_spec.rb' @@ -1354,10 +1352,6 @@ RSpec/SpecFilePathFormat: - 'spec/yard_map/mapper/to_method_spec.rb' - 'spec/yard_map/mapper_spec.rb' -RSpec/StubbedMock: - Exclude: - - 'spec/language_server/host/message_worker_spec.rb' - # Configuration parameters: IgnoreNameless, IgnoreSymbolicNames. RSpec/VerifiedDoubles: Exclude: @@ -2219,12 +2213,6 @@ Style/RedundantFreeze: - 'lib/solargraph/complex_type.rb' - 'lib/solargraph/source_map/mapper.rb' -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: AllowComments. -Style/RedundantInitialize: - Exclude: - - 'lib/solargraph/rbs_map/core_map.rb' - # This cop supports unsafe autocorrection (--autocorrect-all). Style/RedundantInterpolation: Exclude: @@ -2252,24 +2240,13 @@ Style/RedundantRegexpArgument: - 'spec/diagnostics/rubocop_spec.rb' - 'spec/language_server/host_spec.rb' -# This cop supports safe autocorrection (--autocorrect). -Style/RedundantRegexpCharacterClass: - Exclude: - - 'lib/solargraph/source/cursor.rb' - - 'lib/solargraph/source/source_chainer.rb' - # This cop supports safe autocorrection (--autocorrect). Style/RedundantRegexpEscape: Exclude: - 'lib/solargraph/complex_type.rb' - 'lib/solargraph/diagnostics/rubocop.rb' - 'lib/solargraph/language_server/uri_helpers.rb' - - 'lib/solargraph/parser/parser_gem/node_methods.rb' - - 'lib/solargraph/pin/method.rb' - - 'lib/solargraph/pin/parameter.rb' - 'lib/solargraph/shell.rb' - - 'lib/solargraph/source/change.rb' - - 'lib/solargraph/source/cursor.rb' - 'lib/solargraph/source_map/clip.rb' - 'lib/solargraph/source_map/mapper.rb' @@ -2632,7 +2609,6 @@ YARD/MismatchName: Exclude: - 'lib/solargraph/complex_type.rb' - 'lib/solargraph/complex_type/unique_type.rb' - - 'lib/solargraph/gem_pins.rb' - 'lib/solargraph/language_server/host.rb' - 'lib/solargraph/language_server/host/dispatch.rb' - 'lib/solargraph/language_server/request.rb' From 4c486edec853f702aaed8384379c17c9226d4f0f Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 2 Sep 2025 05:58:48 -0400 Subject: [PATCH 043/106] Add another @sg-ignore --- lib/solargraph/shell.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/solargraph/shell.rb b/lib/solargraph/shell.rb index aa7214196..cb919476c 100755 --- a/lib/solargraph/shell.rb +++ b/lib/solargraph/shell.rb @@ -265,6 +265,7 @@ def pin path $stderr.puts "Pin not found for path '#{path}'" exit 1 when Pin::Method + # @sg-ignore Unresolved call to options if options[:stack] scope, ns, meth = if path.include? '#' [:instance, *path.split('#', 2)] From 200e7e42b847bfb554de097d9ba5da6f182a7196 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 2 Sep 2025 07:57:19 -0400 Subject: [PATCH 044/106] Tolerate case statement in specs --- spec/shell_spec.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/shell_spec.rb b/spec/shell_spec.rb index e3c85c6e0..b9dc6b327 100644 --- a/spec/shell_spec.rb +++ b/spec/shell_spec.rb @@ -62,6 +62,7 @@ def bundle_exec(*cmd) let(:to_s_pin) { instance_double(Solargraph::Pin::Method, return_type: Solargraph::ComplexType.parse('String')) } before do + allow(Solargraph::Pin::Method).to receive(:===).with(to_s_pin).and_return(true) allow(Solargraph::ApiMap).to receive(:load_with_cache).and_return(api_map) allow(api_map).to receive(:get_path_pins).with('String#to_s').and_return([to_s_pin]) end @@ -105,6 +106,8 @@ def bundle_exec(*cmd) string_new_pin = instance_double(Solargraph::Pin::Method, return_type: Solargraph::ComplexType.parse('String')) allow(api_map).to receive(:get_method_stack).with('String', 'new', scope: :class).and_return([string_new_pin]) + allow(Solargraph::Pin::Method).to receive(:===).with(string_new_pin).and_return(true) + allow(api_map).to receive(:get_path_pins).with('String.new').and_return([string_new_pin]) capture_both do shell.options = { stack: true } shell.pin('String.new') @@ -140,6 +143,7 @@ def bundle_exec(*cmd) context 'with no pin' do it 'prints error' do allow(api_map).to receive(:get_path_pins).with('Not#found').and_return([]) + allow(Solargraph::Pin::Method).to receive(:===).with(nil).and_return(false) out = capture_both do shell.options = {} From b10cdd19a1936c13b504540cda4ce527b4faf0c4 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Thu, 4 Sep 2025 08:36:01 -0400 Subject: [PATCH 045/106] Drop broken 'namespaces' method These unused methods call into ApiMap::Index#namespaces, which does not exist. --- lib/solargraph/api_map.rb | 7 ------- lib/solargraph/api_map/store.rb | 5 ----- 2 files changed, 12 deletions(-) diff --git a/lib/solargraph/api_map.rb b/lib/solargraph/api_map.rb index f58633a0c..c44ceea93 100755 --- a/lib/solargraph/api_map.rb +++ b/lib/solargraph/api_map.rb @@ -236,13 +236,6 @@ def keyword_pins store.pins_by_class(Pin::Keyword) end - # An array of namespace names defined in the ApiMap. - # - # @return [Set] - def namespaces - store.namespaces - end - # True if the namespace exists. # # @param name [String] The namespace to match diff --git a/lib/solargraph/api_map/store.rb b/lib/solargraph/api_map/store.rb index f3e2ed278..a4148f867 100644 --- a/lib/solargraph/api_map/store.rb +++ b/lib/solargraph/api_map/store.rb @@ -142,11 +142,6 @@ def namespace_exists?(fqns) fqns_pins(fqns).any? end - # @return [Set] - def namespaces - index.namespaces - end - # @return [Enumerable] def namespace_pins pins_by_class(Solargraph::Pin::Namespace) From bb0f6079024f1e28ee9f12c26bbc626fe475d2ce Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 6 Sep 2025 14:18:16 -0400 Subject: [PATCH 046/106] Rerun rubocop todo --- .rubocop_todo.yml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 0ed335f34..c55a29039 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -64,7 +64,6 @@ Layout/BlockAlignment: Layout/ClosingHeredocIndentation: Exclude: - 'spec/diagnostics/rubocop_spec.rb' - - 'spec/rbs_map/conversions_spec.rb' # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowForAlignment. @@ -167,7 +166,6 @@ Layout/HashAlignment: Layout/HeredocIndentation: Exclude: - 'spec/diagnostics/rubocop_spec.rb' - - 'spec/rbs_map/conversions_spec.rb' - 'spec/yard_map/mapper/to_method_spec.rb' # This cop supports safe autocorrection (--autocorrect). @@ -685,10 +683,13 @@ RSpec/LetBeforeExamples: Exclude: - 'spec/complex_type_spec.rb' -# Configuration parameters: . +# Configuration parameters: EnforcedStyle. # SupportedStyles: have_received, receive RSpec/MessageSpies: - EnforcedStyle: receive + Exclude: + - 'spec/doc_map_spec.rb' + - 'spec/language_server/host/diagnoser_spec.rb' + - 'spec/language_server/host/message_worker_spec.rb' RSpec/MissingExampleGroupArgument: Exclude: @@ -750,10 +751,6 @@ RSpec/ScatteredLet: Exclude: - 'spec/complex_type_spec.rb' -# Configuration parameters: CustomTransform, IgnoreMethods, IgnoreMetadata. -RSpec/SpecFilePathFormat: - Enabled: false - RSpec/StubbedMock: Exclude: - 'spec/language_server/host/message_worker_spec.rb' From 41f098b9245c194b5367d0e521fd595082118ee6 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 6 Sep 2025 14:41:54 -0400 Subject: [PATCH 047/106] Rebuild rubocop todo file --- .rubocop_todo.yml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 0ed335f34..c55a29039 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -64,7 +64,6 @@ Layout/BlockAlignment: Layout/ClosingHeredocIndentation: Exclude: - 'spec/diagnostics/rubocop_spec.rb' - - 'spec/rbs_map/conversions_spec.rb' # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowForAlignment. @@ -167,7 +166,6 @@ Layout/HashAlignment: Layout/HeredocIndentation: Exclude: - 'spec/diagnostics/rubocop_spec.rb' - - 'spec/rbs_map/conversions_spec.rb' - 'spec/yard_map/mapper/to_method_spec.rb' # This cop supports safe autocorrection (--autocorrect). @@ -685,10 +683,13 @@ RSpec/LetBeforeExamples: Exclude: - 'spec/complex_type_spec.rb' -# Configuration parameters: . +# Configuration parameters: EnforcedStyle. # SupportedStyles: have_received, receive RSpec/MessageSpies: - EnforcedStyle: receive + Exclude: + - 'spec/doc_map_spec.rb' + - 'spec/language_server/host/diagnoser_spec.rb' + - 'spec/language_server/host/message_worker_spec.rb' RSpec/MissingExampleGroupArgument: Exclude: @@ -750,10 +751,6 @@ RSpec/ScatteredLet: Exclude: - 'spec/complex_type_spec.rb' -# Configuration parameters: CustomTransform, IgnoreMethods, IgnoreMetadata. -RSpec/SpecFilePathFormat: - Enabled: false - RSpec/StubbedMock: Exclude: - 'spec/language_server/host/message_worker_spec.rb' From 837d7f67872f47619200320bafb7d80da9abad95 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 7 Sep 2025 16:57:05 -0400 Subject: [PATCH 048/106] Force build --- .github/workflows/rspec.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index ecc3d9771..bfa6dce07 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -48,8 +48,8 @@ jobs: run: | bundle install bundle update rbs # use latest available for this Ruby version - - name: Run tests - run: bundle exec rake spec +# - name: Run tests +# run: bundle exec rake spec undercover: runs-on: ubuntu-latest steps: From a4208e71241a3b2e5e2f9198d8d135a065bd7ea4 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 7 Sep 2025 17:10:41 -0400 Subject: [PATCH 049/106] Restore --- .github/workflows/rspec.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index bfa6dce07..ecc3d9771 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -48,8 +48,8 @@ jobs: run: | bundle install bundle update rbs # use latest available for this Ruby version -# - name: Run tests -# run: bundle exec rake spec + - name: Run tests + run: bundle exec rake spec undercover: runs-on: ubuntu-latest steps: From b66f2ac85a8d5599e36decc6a24fce36eed2f382 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 7 Sep 2025 17:14:22 -0400 Subject: [PATCH 050/106] install -> update with rbs collection --- .github/workflows/plugins.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/plugins.yml b/.github/workflows/plugins.yml index 730882e30..b013abd3b 100644 --- a/.github/workflows/plugins.yml +++ b/.github/workflows/plugins.yml @@ -164,7 +164,7 @@ jobs: cd ${RAILS_DIR} bundle install bundle exec --gemfile ../../Gemfile rbs --version - bundle exec --gemfile ../../Gemfile rbs collection install + bundle exec --gemfile ../../Gemfile rbs collection update cd ../../ # bundle exec rbs collection init # bundle exec rbs collection install From a09a9af2bc797134fac776c370ce4fcc2c6db121 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 7 Sep 2025 17:25:05 -0400 Subject: [PATCH 051/106] Try Ruby 3.2 --- .github/workflows/plugins.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/plugins.yml b/.github/workflows/plugins.yml index b013abd3b..af9997846 100644 --- a/.github/workflows/plugins.yml +++ b/.github/workflows/plugins.yml @@ -144,7 +144,8 @@ jobs: uses: ruby/setup-ruby@v1 with: # solargraph-rails supports Ruby 3.0+ - ruby-version: '3.0' + # RBS 3.9 supports Ruby 3.2+ + ruby-version: '3.2' bundler-cache: false bundler: latest env: @@ -164,7 +165,7 @@ jobs: cd ${RAILS_DIR} bundle install bundle exec --gemfile ../../Gemfile rbs --version - bundle exec --gemfile ../../Gemfile rbs collection update + bundle exec --gemfile ../../Gemfile rbs collection install cd ../../ # bundle exec rbs collection init # bundle exec rbs collection install From 6fc8febcdd4cb9515785e0f85788497ad8923ae7 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 7 Sep 2025 17:44:39 -0400 Subject: [PATCH 052/106] Update solargraph --- .github/workflows/plugins.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/plugins.yml b/.github/workflows/plugins.yml index af9997846..ef9fe0155 100644 --- a/.github/workflows/plugins.yml +++ b/.github/workflows/plugins.yml @@ -158,8 +158,7 @@ jobs: export BUNDLE_PATH cd ../solargraph-rails echo "gem 'solargraph', path: '${GITHUB_WORKSPACE:?}'" >> Gemfile - bundle install - bundle update rbs + bundle update solargraph rbs RAILS_DIR="$(pwd)/spec/rails7" export RAILS_DIR cd ${RAILS_DIR} From 388c170d76531530012eb1dff32579a059e3bda6 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 7 Sep 2025 17:45:56 -0400 Subject: [PATCH 053/106] Re-add bundle install --- .github/workflows/plugins.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/plugins.yml b/.github/workflows/plugins.yml index ef9fe0155..a97b27c7c 100644 --- a/.github/workflows/plugins.yml +++ b/.github/workflows/plugins.yml @@ -158,6 +158,7 @@ jobs: export BUNDLE_PATH cd ../solargraph-rails echo "gem 'solargraph', path: '${GITHUB_WORKSPACE:?}'" >> Gemfile + bundle install bundle update solargraph rbs RAILS_DIR="$(pwd)/spec/rails7" export RAILS_DIR From f80b73a020dd405addf8f56d2317e31614c2f8da Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 7 Sep 2025 17:58:16 -0400 Subject: [PATCH 054/106] Drop MATRIX_SOLARGRAPH_VERSION --- .github/workflows/plugins.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/plugins.yml b/.github/workflows/plugins.yml index a97b27c7c..4dedbd93f 100644 --- a/.github/workflows/plugins.yml +++ b/.github/workflows/plugins.yml @@ -149,7 +149,6 @@ jobs: bundler-cache: false bundler: latest env: - MATRIX_SOLARGRAPH_VERSION: '>=0.56.0.pre1' MATRIX_RAILS_VERSION: "7.0" - name: Install gems run: | @@ -170,7 +169,6 @@ jobs: # bundle exec rbs collection init # bundle exec rbs collection install env: - MATRIX_SOLARGRAPH_VERSION: '>=0.56.0.pre1' MATRIX_RAILS_VERSION: "7.0" MATRIX_RAILS_MAJOR_VERSION: '7' - name: Run specs @@ -184,5 +182,4 @@ jobs: bundle info yard ALLOW_IMPROVEMENTS=true bundle exec rake spec env: - MATRIX_SOLARGRAPH_VERSION: '>=0.56.0.pre1' MATRIX_RAILS_VERSION: "7.0" From ce2bee62f20628f33f1e9abb98f7faf96f69166f Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 7 Sep 2025 18:09:04 -0400 Subject: [PATCH 055/106] Drop debugging changes --- .github/workflows/plugins.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/plugins.yml b/.github/workflows/plugins.yml index 4dedbd93f..b5984f3cb 100644 --- a/.github/workflows/plugins.yml +++ b/.github/workflows/plugins.yml @@ -144,8 +144,7 @@ jobs: uses: ruby/setup-ruby@v1 with: # solargraph-rails supports Ruby 3.0+ - # RBS 3.9 supports Ruby 3.2+ - ruby-version: '3.2' + ruby-version: '3.0' bundler-cache: false bundler: latest env: @@ -158,7 +157,7 @@ jobs: cd ../solargraph-rails echo "gem 'solargraph', path: '${GITHUB_WORKSPACE:?}'" >> Gemfile bundle install - bundle update solargraph rbs + bundle update rbs RAILS_DIR="$(pwd)/spec/rails7" export RAILS_DIR cd ${RAILS_DIR} From dbe9a3edc5291e6cf50632560893306ee074a79f Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 7 Sep 2025 18:40:51 -0400 Subject: [PATCH 056/106] Update expectations from master branch --- .rubocop_todo.yml | 11 ----------- spec/convention_spec.rb | 2 -- 2 files changed, 13 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index c55a29039..89f703d23 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -280,7 +280,6 @@ Layout/TrailingWhitespace: Exclude: - 'lib/solargraph/language_server/message/client/register_capability.rb' - 'spec/api_map/config_spec.rb' - - 'spec/convention_spec.rb' # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowedMethods, AllowedPatterns. @@ -338,11 +337,6 @@ Lint/DuplicateBranch: Lint/DuplicateMethods: Enabled: false -# Configuration parameters: AllowComments, AllowEmptyLambdas. -Lint/EmptyBlock: - Exclude: - - 'spec/convention_spec.rb' - # Configuration parameters: AllowComments. Lint/EmptyClass: Enabled: false @@ -618,11 +612,6 @@ RSpec/DescribeClass: RSpec/DescribedClass: Enabled: false -# This cop supports unsafe autocorrection (--autocorrect-all). -RSpec/EmptyExampleGroup: - Exclude: - - 'spec/convention_spec.rb' - # This cop supports safe autocorrection (--autocorrect). RSpec/EmptyLineAfterFinalLet: Exclude: diff --git a/spec/convention_spec.rb b/spec/convention_spec.rb index 98a8f41bf..b6f4fc52e 100644 --- a/spec/convention_spec.rb +++ b/spec/convention_spec.rb @@ -1,5 +1,4 @@ describe Solargraph::Convention do - # rubocop:disable RSpec/ExampleLength, RSpec/MultipleExpectations it 'newly defined pins are resolved by ApiMap after file changes' do filename = 'test.rb' @@ -106,5 +105,4 @@ def local _source_map described_class.unregister updated_dummy_convention end - # rubocop:enable RSpec/ExampleLength, RSpec/MultipleExpectations end From db725f78fdb3756c917044e35dd6d1eec1c86095 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 13 Sep 2025 16:30:39 -0400 Subject: [PATCH 057/106] Update rubocop todo --- .rubocop_todo.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 89f703d23..f7e83b95f 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -285,7 +285,6 @@ Layout/TrailingWhitespace: # Configuration parameters: AllowedMethods, AllowedPatterns. Lint/AmbiguousBlockAssociation: Exclude: - - 'lib/solargraph/api_map.rb' - 'lib/solargraph/language_server/host.rb' # This cop supports safe autocorrection (--autocorrect). @@ -1108,7 +1107,6 @@ Style/RedundantFreeze: # This cop supports unsafe autocorrection (--autocorrect-all). Style/RedundantInterpolation: Exclude: - - 'lib/solargraph/api_map/store.rb' - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - 'lib/solargraph/source_map/mapper.rb' @@ -1133,7 +1131,6 @@ Style/RedundantRegexpEscape: # Configuration parameters: AllowMultipleReturnValues. Style/RedundantReturn: Exclude: - - 'lib/solargraph/api_map.rb' - 'lib/solargraph/complex_type/type_methods.rb' - 'lib/solargraph/doc_map.rb' - 'lib/solargraph/parser/parser_gem/node_methods.rb' @@ -1268,7 +1265,11 @@ Style/YAMLFileRead: # This cop supports unsafe autocorrection (--autocorrect-all). Style/ZeroLengthPredicate: - Enabled: false + Exclude: + - 'lib/solargraph/language_server/host.rb' + - 'lib/solargraph/pin/method.rb' + - 'lib/solargraph/source/chain/array.rb' + - 'spec/language_server/protocol_spec.rb' # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle. From b6d86ecb49631fc9201aa02e9e0626be85147c23 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 13 Sep 2025 17:37:08 -0400 Subject: [PATCH 058/106] Fix merge failure --- lib/solargraph/api_map.rb | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/lib/solargraph/api_map.rb b/lib/solargraph/api_map.rb index 194e6cd3a..c27fceb7b 100755 --- a/lib/solargraph/api_map.rb +++ b/lib/solargraph/api_map.rb @@ -705,21 +705,6 @@ def inner_get_methods_from_reference(fq_reference_tag, namespace_pin, type, scop methods end - # @param fq_sub_tag [String] - # @return [String, nil] - def qualify_superclass fq_sub_tag - fq_sub_type = ComplexType.try_parse(fq_sub_tag) - fq_sub_ns = fq_sub_type.name - sup_tag = store.get_superclass(fq_sub_tag) - sup_type = ComplexType.try_parse(sup_tag) - sup_ns = sup_type.name - return nil if sup_tag.nil? - parts = fq_sub_ns.split('::') - last = parts.pop - parts.pop if last == sup_ns - qualify(sup_tag, parts.join('::')) - end - private # A hash of source maps with filename keys. From f4399eba824fdd5aa8d605b2143ddef20c5617d8 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Thu, 25 Sep 2025 11:15:45 -0400 Subject: [PATCH 059/106] [regression] Fix issue resolving mixins under same namespace --- lib/solargraph/api_map/constants.rb | 7 ++++- spec/api_map/constants_spec.rb | 36 +++++++++++++++++++++++++ spec/type_checker/levels/strong_spec.rb | 20 ++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/lib/solargraph/api_map/constants.rb b/lib/solargraph/api_map/constants.rb index 430303ae1..51d0a207c 100644 --- a/lib/solargraph/api_map/constants.rb +++ b/lib/solargraph/api_map/constants.rb @@ -120,8 +120,13 @@ def complex_resolve name, gates, internal return [resolved, gates[(idx + 1)..]] if resolved store.get_ancestor_references(gate).each do |ref| return ref.name.sub(/^::/, '') if ref.name.end_with?("::#{name}") - mixin = resolve(ref.name, ref.reference_gates - gates) + + # avoid infinite loops resolving mixin pin + next if ref.name == name && gates.to_set == ref.reference_gates.to_set + + mixin = resolve(ref.name, ref.reference_gates) next unless mixin + resolved = simple_resolve(name, mixin, internal) return [resolved, gates[(idx + 1)..]] if resolved end diff --git a/spec/api_map/constants_spec.rb b/spec/api_map/constants_spec.rb index 26eaf6b25..c0460e79a 100644 --- a/spec/api_map/constants_spec.rb +++ b/spec/api_map/constants_spec.rb @@ -20,6 +20,42 @@ module Quuz expect(resolved).to eq('Foo::Bar') end + it 'resolves straightforward mixins' do + source_map = Solargraph::SourceMap.load_string(%( + module Bar + Baz = 'baz' + end + + class Foo + include Bar + end + ), 'test.rb') + + store = Solargraph::ApiMap::Store.new(source_map.pins) + constants = described_class.new(store) + pin = source_map.first_pin('Foo') + resolved = constants.resolve('Baz', pin.gates) + expect(resolved).to eq('Bar::Baz') + end + + it 'resolves mixin living under same namespace' do + source_map = Solargraph::SourceMap.load_string(%( + class Foo + module Bar + Baz = 'baz' + end + + include Bar + end + ), 'test.rb') + + store = Solargraph::ApiMap::Store.new(source_map.pins) + constants = described_class.new(store) + pin = source_map.first_pin('Foo') + resolved = constants.resolve('Baz', pin.gates) + expect(resolved).to eq('Foo::Bar::Baz') + end + it 'returns namespaces for nested namespaces' do source_map = Solargraph::SourceMap.load_string(%( module Foo diff --git a/spec/type_checker/levels/strong_spec.rb b/spec/type_checker/levels/strong_spec.rb index a03e6eb5d..4bf3b7163 100644 --- a/spec/type_checker/levels/strong_spec.rb +++ b/spec/type_checker/levels/strong_spec.rb @@ -272,5 +272,25 @@ def meth arg )) expect(checker.problems).to be_empty end + + it 'resolves constants inside modules inside classes' do + checker = type_checker(%( + class Bar + module Foo + CONSTANT = 'hi' + end + end + + class Bar + include Foo + + # @return [String] + def baz + CONSTANT + end + end + )) + expect(checker.problems.map(&:message)).to be_empty + end end end From 3324b4c7fb392405c39252701a9494d70d63dcf0 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Thu, 25 Sep 2025 12:11:22 -0400 Subject: [PATCH 060/106] Prevent recursion via caching mechanism --- lib/solargraph/api_map/constants.rb | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/solargraph/api_map/constants.rb b/lib/solargraph/api_map/constants.rb index 51d0a207c..bc508b330 100644 --- a/lib/solargraph/api_map/constants.rb +++ b/lib/solargraph/api_map/constants.rb @@ -24,8 +24,16 @@ def resolve(name, *gates) return store.get_path_pins(name[2..]).first&.path if name.start_with?('::') flat = gates.flatten - flat.push '' if flat.empty? - cached_resolve[[name, flat]] || resolve_and_cache(name, flat) + if flat.empty? + flat.push '' + end + if cached_resolve.include? [name, flat] + cached_result = cached_resolve[[name, flat]] + # don't recurse + return nil if cached_result == :in_process + return cached_result + end + resolve_and_cache(name, flat) end # Get a fully qualified namespace from a reference pin. @@ -82,6 +90,7 @@ def clear # @param gates [Array] # @return [String, nil] def resolve_and_cache name, gates + cached_resolve[[name, gates]] = :in_process cached_resolve[[name, gates]] = resolve_uncached(name, gates) end @@ -121,9 +130,6 @@ def complex_resolve name, gates, internal store.get_ancestor_references(gate).each do |ref| return ref.name.sub(/^::/, '') if ref.name.end_with?("::#{name}") - # avoid infinite loops resolving mixin pin - next if ref.name == name && gates.to_set == ref.reference_gates.to_set - mixin = resolve(ref.name, ref.reference_gates) next unless mixin @@ -159,7 +165,7 @@ def collect_and_cache gates end end - # @return [Hash{Array(Name, Array) => String, nil}] + # @return [Hash{Array(String, Array) => String, :in_process, nil}] def cached_resolve @cached_resolve ||= {} end From 174bf4e430edf7198c9ae3d23d701e359a74146c Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Thu, 25 Sep 2025 12:15:46 -0400 Subject: [PATCH 061/106] Linting fix, ignore rubocop-yard issue pending yard PR merge --- .rubocop_todo.yml | 33 ++--------------------------- lib/solargraph/api_map/constants.rb | 4 +--- 2 files changed, 3 insertions(+), 34 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 89fd47c5d..f17d08a94 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp` -# using RuboCop version 1.80.2. +# using RuboCop version 1.80.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -280,7 +280,6 @@ Layout/MultilineMethodCallBraceLayout: # SupportedStyles: aligned, indented, indented_relative_to_receiver Layout/MultilineMethodCallIndentation: Exclude: - - 'lib/solargraph/api_map.rb' - 'lib/solargraph/diagnostics/type_check.rb' - 'lib/solargraph/language_server/message/completion_item/resolve.rb' - 'lib/solargraph/language_server/message/text_document/hover.rb' @@ -356,7 +355,6 @@ Layout/SpaceBeforeBlockBraces: - 'lib/solargraph/source.rb' - 'lib/solargraph/source/chain/call.rb' - 'lib/solargraph/source/chain/class_variable.rb' - - 'lib/solargraph/source/chain/constant.rb' - 'lib/solargraph/source/chain/global_variable.rb' - 'lib/solargraph/source/chain/instance_variable.rb' - 'lib/solargraph/source/chain/variable.rb' @@ -433,13 +431,11 @@ Layout/TrailingWhitespace: Exclude: - 'lib/solargraph/language_server/message/client/register_capability.rb' - 'spec/api_map/config_spec.rb' - - 'spec/convention_spec.rb' # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowedMethods, AllowedPatterns. Lint/AmbiguousBlockAssociation: Exclude: - - 'lib/solargraph/api_map.rb' - 'lib/solargraph/language_server/host.rb' # This cop supports safe autocorrection (--autocorrect). @@ -512,11 +508,6 @@ Lint/DuplicateMethods: - 'lib/solargraph/rbs_map/core_map.rb' - 'lib/solargraph/source/chain/link.rb' -# Configuration parameters: AllowComments, AllowEmptyLambdas. -Lint/EmptyBlock: - Exclude: - - 'spec/convention_spec.rb' - # Configuration parameters: AllowComments. Lint/EmptyClass: Exclude: @@ -998,11 +989,6 @@ RSpec/DescribedClass: - 'spec/yard_map/mapper/to_method_spec.rb' - 'spec/yard_map/mapper_spec.rb' -# This cop supports unsafe autocorrection (--autocorrect-all). -RSpec/EmptyExampleGroup: - Exclude: - - 'spec/convention_spec.rb' - # This cop supports safe autocorrection (--autocorrect). RSpec/EmptyLineAfterFinalLet: Exclude: @@ -1321,7 +1307,6 @@ Style/AccessorGrouping: # SupportedStyles: always, conditionals Style/AndOr: Exclude: - - 'lib/solargraph/api_map/source_to_yard.rb' - 'lib/solargraph/complex_type/unique_type.rb' - 'lib/solargraph/language_server/message/base.rb' - 'lib/solargraph/page.rb' @@ -1782,7 +1767,6 @@ Style/GlobalStdStream: # Configuration parameters: MinBodyLength, AllowConsecutiveConditionals. Style/GuardClause: Exclude: - - 'lib/solargraph/api_map.rb' - 'lib/solargraph/library.rb' - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' - 'lib/solargraph/pin_cache.rb' @@ -1835,7 +1819,6 @@ Style/IfInsideElse: # This cop supports safe autocorrection (--autocorrect). Style/IfUnlessModifier: Exclude: - - 'lib/solargraph/api_map.rb' - 'lib/solargraph/api_map/index.rb' - 'lib/solargraph/complex_type.rb' - 'lib/solargraph/complex_type/unique_type.rb' @@ -1903,7 +1886,6 @@ Style/MethodDefParentheses: Exclude: - 'lib/solargraph.rb' - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/api_map/index.rb' - 'lib/solargraph/api_map/store.rb' - 'lib/solargraph/complex_type.rb' - 'lib/solargraph/complex_type/type_methods.rb' @@ -1947,7 +1929,6 @@ Style/MethodDefParentheses: - 'lib/solargraph/shell.rb' - 'lib/solargraph/source.rb' - 'lib/solargraph/source/chain/call.rb' - - 'lib/solargraph/source/chain/constant.rb' - 'lib/solargraph/source_map.rb' - 'lib/solargraph/source_map/mapper.rb' - 'lib/solargraph/type_checker.rb' @@ -2049,8 +2030,6 @@ Style/NumericLiterals: Style/NumericPredicate: Exclude: - 'spec/**/*' - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/api_map/index.rb' - 'lib/solargraph/api_map/store.rb' - 'lib/solargraph/complex_type.rb' - 'lib/solargraph/complex_type/type_methods.rb' @@ -2131,7 +2110,6 @@ Style/RedundantFreeze: # This cop supports unsafe autocorrection (--autocorrect-all). Style/RedundantInterpolation: Exclude: - - 'lib/solargraph/api_map/store.rb' - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - 'lib/solargraph/source_map/mapper.rb' @@ -2143,7 +2121,6 @@ Style/RedundantParentheses: - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - 'lib/solargraph/pin/method.rb' - 'lib/solargraph/pin/parameter.rb' - - 'lib/solargraph/pin/search.rb' - 'lib/solargraph/source.rb' - 'lib/solargraph/type_checker.rb' @@ -2170,7 +2147,6 @@ Style/RedundantRegexpEscape: # Configuration parameters: AllowMultipleReturnValues. Style/RedundantReturn: Exclude: - - 'lib/solargraph/api_map.rb' - 'lib/solargraph/complex_type/type_methods.rb' - 'lib/solargraph/doc_map.rb' - 'lib/solargraph/parser/parser_gem/node_methods.rb' @@ -2269,8 +2245,6 @@ Style/StderrPuts: # Configuration parameters: Mode. Style/StringConcatenation: Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/api_map/index.rb' - 'lib/solargraph/pin/base.rb' - 'lib/solargraph/pin/callable.rb' - 'lib/solargraph/pin/closure.rb' @@ -2286,7 +2260,6 @@ Style/StringLiterals: Exclude: - 'Gemfile' - 'Rakefile' - - 'lib/solargraph/api_map/index.rb' - 'lib/solargraph/complex_type.rb' - 'lib/solargraph/complex_type/unique_type.rb' - 'lib/solargraph/convention/struct_definition.rb' @@ -2504,8 +2477,6 @@ Style/YAMLFileRead: # This cop supports unsafe autocorrection (--autocorrect-all). Style/ZeroLengthPredicate: Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/api_map/index.rb' - 'lib/solargraph/language_server/host.rb' - 'lib/solargraph/pin/method.rb' - 'lib/solargraph/source/chain/array.rb' @@ -2551,6 +2522,7 @@ YARD/MismatchName: YARD/TagTypeSyntax: Exclude: + - 'lib/solargraph/api_map/constants.rb' - 'lib/solargraph/language_server/host.rb' - 'lib/solargraph/parser/comment_ripper.rb' - 'lib/solargraph/type_checker.rb' @@ -2614,7 +2586,6 @@ Layout/LineLength: - 'lib/solargraph/workspace.rb' - 'lib/solargraph/workspace/config.rb' - 'lib/solargraph/yard_map/mapper/to_method.rb' - - 'spec/api_map_spec.rb' - 'spec/complex_type_spec.rb' - 'spec/language_server/message/completion_item/resolve_spec.rb' - 'spec/language_server/message/extended/check_gem_version_spec.rb' diff --git a/lib/solargraph/api_map/constants.rb b/lib/solargraph/api_map/constants.rb index bc508b330..0df8d83ce 100644 --- a/lib/solargraph/api_map/constants.rb +++ b/lib/solargraph/api_map/constants.rb @@ -24,9 +24,7 @@ def resolve(name, *gates) return store.get_path_pins(name[2..]).first&.path if name.start_with?('::') flat = gates.flatten - if flat.empty? - flat.push '' - end + flat.push '' if flat.empty? if cached_resolve.include? [name, flat] cached_result = cached_resolve[[name, flat]] # don't recurse From 4898313a80331277b733ce827962ff5eaadf5a16 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Thu, 25 Sep 2025 16:03:39 -0400 Subject: [PATCH 062/106] [regression] Fix resolution in deep YARD namespace hierarchies YARD-parsed namespaces weren't correctly setting their gates, leading to unresolved types from methods. --- lib/solargraph/yard_map/mapper/to_namespace.rb | 1 + spec/yard_map/mapper_spec.rb | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/lib/solargraph/yard_map/mapper/to_namespace.rb b/lib/solargraph/yard_map/mapper/to_namespace.rb index 054ba3306..f7063e3d6 100644 --- a/lib/solargraph/yard_map/mapper/to_namespace.rb +++ b/lib/solargraph/yard_map/mapper/to_namespace.rb @@ -21,6 +21,7 @@ def self.make code_object, spec, closure = nil type: code_object.is_a?(YARD::CodeObjects::ClassObject) ? :class : :module, visibility: code_object.visibility, closure: closure, + gates: closure.gates, source: :yardoc, ) end diff --git a/spec/yard_map/mapper_spec.rb b/spec/yard_map/mapper_spec.rb index 6b00e5c33..63efc3835 100644 --- a/spec/yard_map/mapper_spec.rb +++ b/spec/yard_map/mapper_spec.rb @@ -74,6 +74,14 @@ expect(inc).to be_a(Solargraph::Pin::Reference::Include) end + it 'adds corect gates' do + # Asssuming the ast gem exists because it's a known dependency + pin = pins_with('ast').find do |pin| + pin.is_a?(Solargraph::Pin::Namespace) && pin.name == 'Mixin' && pin.closure.path == 'AST::Processor' + end + expect(pin.gates).to eq(["AST::Processor::Mixin", "AST::Processor", "AST", ""]) + end + it 'adds extend references' do # Asssuming the yard gem exists because it's a known dependency gemspec = Gem::Specification.find_by_name('yard') From f8f7ca27b1dc40864a4ac49e3c26caa1fcb33b84 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Fri, 26 Sep 2025 09:02:13 -0400 Subject: [PATCH 063/106] Linting --- spec/yard_map/mapper_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/yard_map/mapper_spec.rb b/spec/yard_map/mapper_spec.rb index 63efc3835..6fa778f2c 100644 --- a/spec/yard_map/mapper_spec.rb +++ b/spec/yard_map/mapper_spec.rb @@ -79,7 +79,7 @@ pin = pins_with('ast').find do |pin| pin.is_a?(Solargraph::Pin::Namespace) && pin.name == 'Mixin' && pin.closure.path == 'AST::Processor' end - expect(pin.gates).to eq(["AST::Processor::Mixin", "AST::Processor", "AST", ""]) + expect(pin.gates).to eq(['AST::Processor::Mixin', 'AST::Processor', 'AST', '']) end it 'adds extend references' do From 8ce4bb91e5f2f7a57c8125150427e67b8e465ee7 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Fri, 26 Sep 2025 09:26:26 -0400 Subject: [PATCH 064/106] Fix merge --- spec/yard_map/mapper_spec.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spec/yard_map/mapper_spec.rb b/spec/yard_map/mapper_spec.rb index 6fa778f2c..d45af985b 100644 --- a/spec/yard_map/mapper_spec.rb +++ b/spec/yard_map/mapper_spec.rb @@ -76,7 +76,10 @@ it 'adds corect gates' do # Asssuming the ast gem exists because it's a known dependency - pin = pins_with('ast').find do |pin| + gemspec = Gem::Specification.find_by_name('ast') + Solargraph::Yardoc.cache([], gemspec) + pins = Solargraph::YardMap::Mapper.new(Solargraph::Yardoc.load!(gemspec)).map + pin = pins.find do |pin| pin.is_a?(Solargraph::Pin::Namespace) && pin.name == 'Mixin' && pin.closure.path == 'AST::Processor' end expect(pin.gates).to eq(['AST::Processor::Mixin', 'AST::Processor', 'AST', '']) From a398b84bd2f09c4e9148aee79c8ee0a643c651a1 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Fri, 26 Sep 2025 12:45:46 -0400 Subject: [PATCH 065/106] Resolve constants in references Also replaces 'include' logic with call to ApiMap::Constants Fixes #1099 --- lib/solargraph/api_map.rb | 13 +--- lib/solargraph/api_map/constants.rb | 23 ++++--- lib/solargraph/parser/node_methods.rb | 97 --------------------------- spec/api_map/constants_spec.rb | 27 ++++++++ 4 files changed, 44 insertions(+), 116 deletions(-) delete mode 100644 lib/solargraph/parser/node_methods.rb diff --git a/lib/solargraph/api_map.rb b/lib/solargraph/api_map.rb index 44ca19035..7f53e7596 100755 --- a/lib/solargraph/api_map.rb +++ b/lib/solargraph/api_map.rb @@ -772,17 +772,8 @@ def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false if scope == :instance store.get_includes(fqns).reverse.each do |ref| - const = get_constants('', *ref.closure.gates).find { |pin| pin.path.end_with? ref.name } - if const.is_a?(Pin::Namespace) - result.concat inner_get_methods(const.path, scope, visibility, deep, skip, true) - elsif const.is_a?(Pin::Constant) - type = const.infer(self) - result.concat inner_get_methods(type.namespace, scope, visibility, deep, skip, true) if type.defined? - else - referenced_tag = ref.parametrized_tag - next unless referenced_tag.defined? - result.concat inner_get_methods_from_reference(referenced_tag.to_s, namespace_pin, rooted_type, scope, visibility, deep, skip, true) - end + fqin = dereference(ref) + result.concat inner_get_methods(fqin, scope, visibility, deep, skip, true) end rooted_sc_tag = qualify_superclass(rooted_tag) unless rooted_sc_tag.nil? diff --git a/lib/solargraph/api_map/constants.rb b/lib/solargraph/api_map/constants.rb index 430303ae1..5dbcd4b67 100644 --- a/lib/solargraph/api_map/constants.rb +++ b/lib/solargraph/api_map/constants.rb @@ -12,14 +12,21 @@ def initialize store # Resolve a name to a fully qualified namespace or constant. # - # `Constants#resolve` is similar to `Constants#qualify`` in that its - # purpose is to find fully qualified (absolute) namespaces, except - # `#resolve`` is only concerned with real namespaces. It disregards - # parametrized types and special types like literals, self, and Boolean. + # `Constants#resolve` finds fully qualified (absolute) + # namespaces based on relative names and the open gates + # (namespaces) provided. Names must be runtime-visible (erased) + # non-literal types - e.g., TrueClass, NilClass, Integer and + # Hash instead of true, nil, 96, or Hash{String => Symbol} # - # @param name [String] - # @param gates [Array, String>] - # @return [String, nil] + # Note: You may want to be using #qualify. Notably, #resolve: + # - will not gracefully handle nil, self and Boolean + # - will return a constant name instead of following its assignment + # + # @param name [String] Namespace which may relative and not be rooted. + # @param gates [Array, String>] Namespaces to search while resolving the name + # + # @return [String, nil] fully qualified namespace (i.e., is + # absolute, but will not start with ::) def resolve(name, *gates) return store.get_path_pins(name[2..]).first&.path if name.start_with?('::') @@ -33,7 +40,7 @@ def resolve(name, *gates) # @param pin [Pin::Reference] # @return [String, nil] def dereference pin - resolve(pin.name, pin.reference_gates) + qualify(pin.name, pin.reference_gates) end # Collect a list of all constants defined in the specified gates. diff --git a/lib/solargraph/parser/node_methods.rb b/lib/solargraph/parser/node_methods.rb deleted file mode 100644 index f33a924c1..000000000 --- a/lib/solargraph/parser/node_methods.rb +++ /dev/null @@ -1,97 +0,0 @@ -module Solargraph - module Parser - module NodeMethods - module_function - - # @abstract - # @param node [Parser::AST::Node] - # @return [String] - def unpack_name node - raise NotImplementedError - end - - # @abstract - # @todo Temporarily here for testing. Move to Solargraph::Parser. - # @param node [Parser::AST::Node] - # @return [Array] - def call_nodes_from node - raise NotImplementedError - end - - # Find all the nodes within the provided node that potentially return a - # value. - # - # The node parameter typically represents a method's logic, e.g., the - # second child (after the :args node) of a :def node. A simple one-line - # method would typically return itself, while a node with conditions - # would return the resulting node from each conditional branch. Nodes - # that follow a :return node are assumed to be unreachable. Nil values - # are converted to nil node types. - # - # @abstract - # @param node [Parser::AST::Node] - # @return [Array] - def returns_from_method_body node - raise NotImplementedError - end - - # @abstract - # @param node [Parser::AST::Node] - # - # @return [Array] - def const_nodes_from node - raise NotImplementedError - end - - # @abstract - # @param cursor [Solargraph::Source::Cursor] - # @return [Parser::AST::Node, nil] - def find_recipient_node cursor - raise NotImplementedError - end - - # @abstract - # @param node [Parser::AST::Node] - # @return [Array] low-level value nodes in - # value position. Does not include explicit return - # statements - def value_position_nodes_only(node) - raise NotImplementedError - end - - # @abstract - # @param nodes [Enumerable] - def any_splatted_call?(nodes) - raise NotImplementedError - end - - # @abstract - # @param node [Parser::AST::Node] - # @return [void] - def process node - raise NotImplementedError - end - - # @abstract - # @param node [Parser::AST::Node] - # @return [Hash{Symbol => Source::Chain}] - def convert_hash node - raise NotImplementedError - end - - # @abstract - # @param node [Parser::AST::Node] - # @return [Position] - def get_node_start_position(node) - raise NotImplementedError - end - - # @abstract - # @param node [Parser::AST::Node] - # @return [Position] - def get_node_end_position(node) - raise NotImplementedError - end - end - end -end diff --git a/spec/api_map/constants_spec.rb b/spec/api_map/constants_spec.rb index 26eaf6b25..e09c12c29 100644 --- a/spec/api_map/constants_spec.rb +++ b/spec/api_map/constants_spec.rb @@ -20,6 +20,33 @@ module Quuz expect(resolved).to eq('Foo::Bar') end + it 'resolves constants in includes' do + code = %( + module A + module Parser + module C + module_function + + # @return [String] + def baz; "abc"; end + end + + B = C + end + + class Foo + include Parser::B + + # @return [String] + def bar + baz + end + end + end) + checker = Solargraph::TypeChecker.load_string(code, 'test.rb', :strong) + expect(checker.problems.map(&:message)).to be_empty + end + it 'returns namespaces for nested namespaces' do source_map = Solargraph::SourceMap.load_string(%( module Foo From dd06a479b9f12e797b12caef53bdff482f686426 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Fri, 26 Sep 2025 12:51:45 -0400 Subject: [PATCH 066/106] Linting --- spec/api_map/constants_spec.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/spec/api_map/constants_spec.rb b/spec/api_map/constants_spec.rb index e09c12c29..ef07c00b7 100644 --- a/spec/api_map/constants_spec.rb +++ b/spec/api_map/constants_spec.rb @@ -25,8 +25,6 @@ module Quuz module A module Parser module C - module_function - # @return [String] def baz; "abc"; end end From cc86aec403ca74694a408e85e6ccd1f5f5e32343 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Fri, 26 Sep 2025 13:00:55 -0400 Subject: [PATCH 067/106] Ratchet RuboCop --- .rubocop_todo.yml | 35 +---------------------------------- lib/solargraph/api_map.rb | 2 -- 2 files changed, 1 insertion(+), 36 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 89fd47c5d..0de27608a 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp` -# using RuboCop version 1.80.2. +# using RuboCop version 1.80.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -280,7 +280,6 @@ Layout/MultilineMethodCallBraceLayout: # SupportedStyles: aligned, indented, indented_relative_to_receiver Layout/MultilineMethodCallIndentation: Exclude: - - 'lib/solargraph/api_map.rb' - 'lib/solargraph/diagnostics/type_check.rb' - 'lib/solargraph/language_server/message/completion_item/resolve.rb' - 'lib/solargraph/language_server/message/text_document/hover.rb' @@ -356,7 +355,6 @@ Layout/SpaceBeforeBlockBraces: - 'lib/solargraph/source.rb' - 'lib/solargraph/source/chain/call.rb' - 'lib/solargraph/source/chain/class_variable.rb' - - 'lib/solargraph/source/chain/constant.rb' - 'lib/solargraph/source/chain/global_variable.rb' - 'lib/solargraph/source/chain/instance_variable.rb' - 'lib/solargraph/source/chain/variable.rb' @@ -433,13 +431,11 @@ Layout/TrailingWhitespace: Exclude: - 'lib/solargraph/language_server/message/client/register_capability.rb' - 'spec/api_map/config_spec.rb' - - 'spec/convention_spec.rb' # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowedMethods, AllowedPatterns. Lint/AmbiguousBlockAssociation: Exclude: - - 'lib/solargraph/api_map.rb' - 'lib/solargraph/language_server/host.rb' # This cop supports safe autocorrection (--autocorrect). @@ -512,11 +508,6 @@ Lint/DuplicateMethods: - 'lib/solargraph/rbs_map/core_map.rb' - 'lib/solargraph/source/chain/link.rb' -# Configuration parameters: AllowComments, AllowEmptyLambdas. -Lint/EmptyBlock: - Exclude: - - 'spec/convention_spec.rb' - # Configuration parameters: AllowComments. Lint/EmptyClass: Exclude: @@ -998,11 +989,6 @@ RSpec/DescribedClass: - 'spec/yard_map/mapper/to_method_spec.rb' - 'spec/yard_map/mapper_spec.rb' -# This cop supports unsafe autocorrection (--autocorrect-all). -RSpec/EmptyExampleGroup: - Exclude: - - 'spec/convention_spec.rb' - # This cop supports safe autocorrection (--autocorrect). RSpec/EmptyLineAfterFinalLet: Exclude: @@ -1321,7 +1307,6 @@ Style/AccessorGrouping: # SupportedStyles: always, conditionals Style/AndOr: Exclude: - - 'lib/solargraph/api_map/source_to_yard.rb' - 'lib/solargraph/complex_type/unique_type.rb' - 'lib/solargraph/language_server/message/base.rb' - 'lib/solargraph/page.rb' @@ -1510,7 +1495,6 @@ Style/Documentation: - 'lib/solargraph/parser.rb' - 'lib/solargraph/parser/comment_ripper.rb' - 'lib/solargraph/parser/flow_sensitive_typing.rb' - - 'lib/solargraph/parser/node_methods.rb' - 'lib/solargraph/parser/node_processor/base.rb' - 'lib/solargraph/parser/parser_gem.rb' - 'lib/solargraph/parser/parser_gem/class_methods.rb' @@ -1651,7 +1635,6 @@ Style/FrozenStringLiteralComment: - 'lib/solargraph/parser.rb' - 'lib/solargraph/parser/comment_ripper.rb' - 'lib/solargraph/parser/flow_sensitive_typing.rb' - - 'lib/solargraph/parser/node_methods.rb' - 'lib/solargraph/parser/parser_gem.rb' - 'lib/solargraph/parser/snippet.rb' - 'lib/solargraph/pin/breakable.rb' @@ -1782,7 +1765,6 @@ Style/GlobalStdStream: # Configuration parameters: MinBodyLength, AllowConsecutiveConditionals. Style/GuardClause: Exclude: - - 'lib/solargraph/api_map.rb' - 'lib/solargraph/library.rb' - 'lib/solargraph/parser/parser_gem/node_processors/send_node.rb' - 'lib/solargraph/pin_cache.rb' @@ -1835,7 +1817,6 @@ Style/IfInsideElse: # This cop supports safe autocorrection (--autocorrect). Style/IfUnlessModifier: Exclude: - - 'lib/solargraph/api_map.rb' - 'lib/solargraph/api_map/index.rb' - 'lib/solargraph/complex_type.rb' - 'lib/solargraph/complex_type/unique_type.rb' @@ -1903,7 +1884,6 @@ Style/MethodDefParentheses: Exclude: - 'lib/solargraph.rb' - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/api_map/index.rb' - 'lib/solargraph/api_map/store.rb' - 'lib/solargraph/complex_type.rb' - 'lib/solargraph/complex_type/type_methods.rb' @@ -1925,7 +1905,6 @@ Style/MethodDefParentheses: - 'lib/solargraph/location.rb' - 'lib/solargraph/parser/comment_ripper.rb' - 'lib/solargraph/parser/flow_sensitive_typing.rb' - - 'lib/solargraph/parser/node_methods.rb' - 'lib/solargraph/parser/node_processor/base.rb' - 'lib/solargraph/parser/parser_gem/flawed_builder.rb' - 'lib/solargraph/parser/parser_gem/node_chainer.rb' @@ -1947,7 +1926,6 @@ Style/MethodDefParentheses: - 'lib/solargraph/shell.rb' - 'lib/solargraph/source.rb' - 'lib/solargraph/source/chain/call.rb' - - 'lib/solargraph/source/chain/constant.rb' - 'lib/solargraph/source_map.rb' - 'lib/solargraph/source_map/mapper.rb' - 'lib/solargraph/type_checker.rb' @@ -2049,8 +2027,6 @@ Style/NumericLiterals: Style/NumericPredicate: Exclude: - 'spec/**/*' - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/api_map/index.rb' - 'lib/solargraph/api_map/store.rb' - 'lib/solargraph/complex_type.rb' - 'lib/solargraph/complex_type/type_methods.rb' @@ -2131,7 +2107,6 @@ Style/RedundantFreeze: # This cop supports unsafe autocorrection (--autocorrect-all). Style/RedundantInterpolation: Exclude: - - 'lib/solargraph/api_map/store.rb' - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - 'lib/solargraph/source_map/mapper.rb' @@ -2143,7 +2118,6 @@ Style/RedundantParentheses: - 'lib/solargraph/parser/parser_gem/node_chainer.rb' - 'lib/solargraph/pin/method.rb' - 'lib/solargraph/pin/parameter.rb' - - 'lib/solargraph/pin/search.rb' - 'lib/solargraph/source.rb' - 'lib/solargraph/type_checker.rb' @@ -2170,7 +2144,6 @@ Style/RedundantRegexpEscape: # Configuration parameters: AllowMultipleReturnValues. Style/RedundantReturn: Exclude: - - 'lib/solargraph/api_map.rb' - 'lib/solargraph/complex_type/type_methods.rb' - 'lib/solargraph/doc_map.rb' - 'lib/solargraph/parser/parser_gem/node_methods.rb' @@ -2269,8 +2242,6 @@ Style/StderrPuts: # Configuration parameters: Mode. Style/StringConcatenation: Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/api_map/index.rb' - 'lib/solargraph/pin/base.rb' - 'lib/solargraph/pin/callable.rb' - 'lib/solargraph/pin/closure.rb' @@ -2286,7 +2257,6 @@ Style/StringLiterals: Exclude: - 'Gemfile' - 'Rakefile' - - 'lib/solargraph/api_map/index.rb' - 'lib/solargraph/complex_type.rb' - 'lib/solargraph/complex_type/unique_type.rb' - 'lib/solargraph/convention/struct_definition.rb' @@ -2504,8 +2474,6 @@ Style/YAMLFileRead: # This cop supports unsafe autocorrection (--autocorrect-all). Style/ZeroLengthPredicate: Exclude: - - 'lib/solargraph/api_map.rb' - - 'lib/solargraph/api_map/index.rb' - 'lib/solargraph/language_server/host.rb' - 'lib/solargraph/pin/method.rb' - 'lib/solargraph/source/chain/array.rb' @@ -2614,7 +2582,6 @@ Layout/LineLength: - 'lib/solargraph/workspace.rb' - 'lib/solargraph/workspace/config.rb' - 'lib/solargraph/yard_map/mapper/to_method.rb' - - 'spec/api_map_spec.rb' - 'spec/complex_type_spec.rb' - 'spec/language_server/message/completion_item/resolve_spec.rb' - 'spec/language_server/message/extended/check_gem_version_spec.rb' diff --git a/lib/solargraph/api_map.rb b/lib/solargraph/api_map.rb index 7f53e7596..7bac1395c 100755 --- a/lib/solargraph/api_map.rb +++ b/lib/solargraph/api_map.rb @@ -737,7 +737,6 @@ def store # @param skip [Set] # @param no_core [Boolean] Skip core classes if true # @return [Array] - # rubocop:disable Metrics/CyclomaticComplexity def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false rooted_type = ComplexType.parse(rooted_tag).force_rooted fqns = rooted_type.namespace @@ -802,7 +801,6 @@ def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false end result end - # rubocop:enable Metrics/CyclomaticComplexity # @return [Hash] def path_macros From 343cd23307e00ae0c0d4952514f326eac209de5b Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Fri, 26 Sep 2025 14:36:29 -0400 Subject: [PATCH 068/106] Fix lack of parameters in include types --- lib/solargraph/api_map.rb | 6 ++-- lib/solargraph/api_map/constants.rb | 37 +++++++++++++-------- lib/solargraph/api_map/store.rb | 2 +- lib/solargraph/complex_type/type_methods.rb | 4 +++ lib/solargraph/pin/reference.rb | 13 ++------ 5 files changed, 34 insertions(+), 28 deletions(-) diff --git a/lib/solargraph/api_map.rb b/lib/solargraph/api_map.rb index 7bac1395c..14d33b1d7 100755 --- a/lib/solargraph/api_map.rb +++ b/lib/solargraph/api_map.rb @@ -771,8 +771,8 @@ def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false if scope == :instance store.get_includes(fqns).reverse.each do |ref| - fqin = dereference(ref) - result.concat inner_get_methods(fqin, scope, visibility, deep, skip, true) + in_tag = dereference(ref) + result.concat inner_get_methods_from_reference(in_tag, namespace_pin, rooted_type, scope, visibility, deep, skip, true) end rooted_sc_tag = qualify_superclass(rooted_tag) unless rooted_sc_tag.nil? @@ -781,7 +781,7 @@ def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false else logger.info { "ApiMap#inner_get_methods(#{fqns}, #{scope}, #{visibility}, #{deep}, #{skip}) - looking for get_extends() from #{fqns}" } store.get_extends(fqns).reverse.each do |em| - fqem = store.constants.dereference(em) + fqem = dereference(em) result.concat inner_get_methods(fqem, :instance, visibility, deep, skip, true) unless fqem.nil? end rooted_sc_tag = qualify_superclass(rooted_tag) diff --git a/lib/solargraph/api_map/constants.rb b/lib/solargraph/api_map/constants.rb index 5dbcd4b67..0b6070507 100644 --- a/lib/solargraph/api_map/constants.rb +++ b/lib/solargraph/api_map/constants.rb @@ -15,10 +15,12 @@ def initialize store # `Constants#resolve` finds fully qualified (absolute) # namespaces based on relative names and the open gates # (namespaces) provided. Names must be runtime-visible (erased) - # non-literal types - e.g., TrueClass, NilClass, Integer and - # Hash instead of true, nil, 96, or Hash{String => Symbol} + # non-literal types, non-duck, non-signature types - e.g., + # TrueClass, NilClass, Integer and Hash instead of true, nil, + # 96, or Hash{String => Symbol} # # Note: You may want to be using #qualify. Notably, #resolve: + # - does not handle anything with type parameters # - will not gracefully handle nil, self and Boolean # - will return a constant name instead of following its assignment # @@ -40,7 +42,7 @@ def resolve(name, *gates) # @param pin [Pin::Reference] # @return [String, nil] def dereference pin - qualify(pin.name, pin.reference_gates) + qualify_type(pin.type, pin.reference_gates)&.tag end # Collect a list of all constants defined in the specified gates. @@ -52,27 +54,36 @@ def collect(*gates) cached_collect[flat] || collect_and_cache(flat) end - # Determine a fully qualified namespace for a given name referenced - # from the specified open gates. This method will search in each gate - # until it finds a match for the name. + # Determine a fully qualified namespace for a given tag + # referenced from the specified open gates. This method will + # search in each gate until it finds a match for the name. # - # @param name [String, nil] The namespace to match + # @param tag [String, nil] The type to match # @param gates [Array] # @return [String, nil] fully qualified tag - def qualify name, *gates - return name if ['Boolean', 'self', nil].include?(name) + def qualify tag, *gates + type = ComplexType.try_parse(tag) + qualify_type(type)&.tag + end + + # @param type [ComplexType, nil] The type to match + # @param gates [Array] + # + # @return [ComplexType, nil] A new rooted ComplexType + def qualify_type type, *gates + return nil if type.nil? + return type if type.selfy? || type.literal? || type.tag == 'nil' || type.interface? gates.push '' unless gates.include?('') - fqns = resolve(name, gates) + fqns = resolve(type.namespace, type.namespace) return unless fqns pin = store.get_path_pins(fqns).first if pin.is_a?(Pin::Constant) const = Solargraph::Parser::NodeMethods.unpack_name(pin.assignment) return unless const - resolve(const, pin.gates) - else - fqns + fqns = resolve(const, pin.gates) end + type.recreate(new_name: fqns, rooted: true) end # @return [void] diff --git a/lib/solargraph/api_map/store.rb b/lib/solargraph/api_map/store.rb index b3953cfec..a0b2ae856 100644 --- a/lib/solargraph/api_map/store.rb +++ b/lib/solargraph/api_map/store.rb @@ -244,7 +244,7 @@ def get_ancestors(fqns) # Add includes, prepends, and extends [get_includes(current), get_prepends(current), get_extends(current)].each do |refs| next if refs.nil? - refs.map(&:parametrized_tag).map(&:to_s).each do |ref| + refs.map(&:type).map(&:to_s).each do |ref| next if ref.nil? || ref.empty? || visited.include?(ref) ancestors << ref queue << ref diff --git a/lib/solargraph/complex_type/type_methods.rb b/lib/solargraph/complex_type/type_methods.rb index d8d4fc7d7..1145bd034 100644 --- a/lib/solargraph/complex_type/type_methods.rb +++ b/lib/solargraph/complex_type/type_methods.rb @@ -43,6 +43,10 @@ def rooted_tag @rooted_tag ||= rooted_name + rooted_substring end + def interface? + name.start_with?('_') + end + # @return [Boolean] def duck_type? @duck_type ||= name.start_with?('#') diff --git a/lib/solargraph/pin/reference.rb b/lib/solargraph/pin/reference.rb index d678ab7b7..d456fbbf8 100644 --- a/lib/solargraph/pin/reference.rb +++ b/lib/solargraph/pin/reference.rb @@ -18,18 +18,9 @@ def initialize generic_values: [], **splat @generic_values = generic_values end - # @return [String] - def parameter_tag - @parameter_tag ||= if generic_values&.any? - "<#{generic_values.join(', ')}>" - else - '' - end - end - # @return [ComplexType] - def parametrized_tag - @parametrized_tag ||= ComplexType.try_parse( + def type + @type ||= ComplexType.try_parse( name + if generic_values&.length&.> 0 "<#{generic_values.join(', ')}>" From d787886b956aa9b5d748fe4003f0ceb1b4dcd4ca Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Fri, 26 Sep 2025 15:16:22 -0400 Subject: [PATCH 069/106] Bug fixes --- lib/solargraph/api_map.rb | 2 +- lib/solargraph/api_map/constants.rb | 13 +++++++------ lib/solargraph/api_map/source_to_yard.rb | 4 ++-- lib/solargraph/api_map/store.rb | 2 +- lib/solargraph/complex_type.rb | 15 +++++++++++++++ .../convention/active_support_concern.rb | 2 +- 6 files changed, 27 insertions(+), 11 deletions(-) diff --git a/lib/solargraph/api_map.rb b/lib/solargraph/api_map.rb index 14d33b1d7..286761db2 100755 --- a/lib/solargraph/api_map.rb +++ b/lib/solargraph/api_map.rb @@ -662,7 +662,7 @@ def super_and_sub?(sup, sub) # # @return [Boolean] def type_include?(host_ns, module_ns) - store.get_includes(host_ns).map { |inc_tag| inc_tag.parametrized_tag.name }.include?(module_ns) + store.get_includes(host_ns).map { |inc_tag| inc_tag.type.name }.include?(module_ns) end # @param pins [Enumerable] diff --git a/lib/solargraph/api_map/constants.rb b/lib/solargraph/api_map/constants.rb index 0b6070507..9463e2037 100644 --- a/lib/solargraph/api_map/constants.rb +++ b/lib/solargraph/api_map/constants.rb @@ -42,7 +42,7 @@ def resolve(name, *gates) # @param pin [Pin::Reference] # @return [String, nil] def dereference pin - qualify_type(pin.type, pin.reference_gates)&.tag + qualify_type(pin.type, *pin.reference_gates)&.tag end # Collect a list of all constants defined in the specified gates. @@ -63,7 +63,7 @@ def collect(*gates) # @return [String, nil] fully qualified tag def qualify tag, *gates type = ComplexType.try_parse(tag) - qualify_type(type)&.tag + qualify_type(type, *gates)&.tag end # @param type [ComplexType, nil] The type to match @@ -72,18 +72,19 @@ def qualify tag, *gates # @return [ComplexType, nil] A new rooted ComplexType def qualify_type type, *gates return nil if type.nil? - return type if type.selfy? || type.literal? || type.tag == 'nil' || type.interface? + return type if type.selfy? || type.literal? || type.tag == 'nil' || type.interface? || + type.tag == 'Boolean' gates.push '' unless gates.include?('') - fqns = resolve(type.namespace, type.namespace) + fqns = resolve(type.rooted_namespace, *gates) return unless fqns pin = store.get_path_pins(fqns).first if pin.is_a?(Pin::Constant) const = Solargraph::Parser::NodeMethods.unpack_name(pin.assignment) return unless const - fqns = resolve(const, pin.gates) + fqns = resolve(const, *pin.gates) end - type.recreate(new_name: fqns, rooted: true) + type.recreate(new_name: fqns, make_rooted: true) end # @return [void] diff --git a/lib/solargraph/api_map/source_to_yard.rb b/lib/solargraph/api_map/source_to_yard.rb index ccbed3eb6..39d86a85c 100644 --- a/lib/solargraph/api_map/source_to_yard.rb +++ b/lib/solargraph/api_map/source_to_yard.rb @@ -46,13 +46,13 @@ def rake_yard store store.get_includes(pin.path).each do |ref| include_object = code_object_at(pin.path, YARD::CodeObjects::ClassObject) unless include_object.nil? || include_object.nil? - include_object.instance_mixins.push code_object_map[ref.parametrized_tag.to_s] + include_object.instance_mixins.push code_object_map[ref.type.to_s] end end store.get_extends(pin.path).each do |ref| extend_object = code_object_at(pin.path, YARD::CodeObjects::ClassObject) next unless extend_object - code_object = code_object_map[ref.parametrized_tag.to_s] + code_object = code_object_map[ref.type.to_s] next unless code_object extend_object.class_mixins.push code_object # @todo add spec showing why this next line is necessary diff --git a/lib/solargraph/api_map/store.rb b/lib/solargraph/api_map/store.rb index a0b2ae856..d97d1d342 100644 --- a/lib/solargraph/api_map/store.rb +++ b/lib/solargraph/api_map/store.rb @@ -97,7 +97,7 @@ def qualify_superclass fq_sub_tag return unless ref res = constants.dereference(ref) return unless res - res + type.substring + res end # @param fqns [String] diff --git a/lib/solargraph/complex_type.rb b/lib/solargraph/complex_type.rb index 8798ecb88..db378743f 100644 --- a/lib/solargraph/complex_type.rb +++ b/lib/solargraph/complex_type.rb @@ -105,6 +105,21 @@ def can_assign?(api_map, atype) any? { |ut| ut.can_assign?(api_map, atype) } end + # @param new_name [String, nil] + # @param make_rooted [Boolean, nil] + # @param new_key_types [Array, nil] + # @param rooted [Boolean, nil] + # @param new_subtypes [Array, nil] + # @return [self] + def recreate(new_name: nil, make_rooted: nil, new_key_types: nil, new_subtypes: nil) + ComplexType.new(map do |ut| + ut.recreate(new_name: new_name, + make_rooted: make_rooted, + new_key_types: new_key_types, + new_subtypes: new_subtypes) + end) + end + # @return [Integer] def length @items.length diff --git a/lib/solargraph/convention/active_support_concern.rb b/lib/solargraph/convention/active_support_concern.rb index 74c9ce765..ed1fba175 100644 --- a/lib/solargraph/convention/active_support_concern.rb +++ b/lib/solargraph/convention/active_support_concern.rb @@ -80,7 +80,7 @@ def process_include include_tag "ActiveSupportConcern#object(#{fqns}, #{scope}, #{visibility}, #{deep}) - " \ "Handling class include include_tag=#{include_tag}" end - module_extends = api_map.get_extends(rooted_include_tag).map(&:parametrized_tag).map(&:to_s) + module_extends = api_map.get_extends(rooted_include_tag).map(&:type).map(&:to_s) logger.debug do "ActiveSupportConcern#object(#{fqns}, #{scope}, #{visibility}, #{deep}) - " \ "found module extends of #{rooted_include_tag}: #{module_extends}" From 63a53dbed3be0c68d0eac7a7a61dd031b6c8466d Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Fri, 26 Sep 2025 15:35:50 -0400 Subject: [PATCH 070/106] Add actual type for Mutexes --- lib/solargraph/language_server/progress.rb | 2 +- lib/solargraph/library.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/solargraph/language_server/progress.rb b/lib/solargraph/language_server/progress.rb index 10900a37e..98b155714 100644 --- a/lib/solargraph/language_server/progress.rb +++ b/lib/solargraph/language_server/progress.rb @@ -134,7 +134,7 @@ def keep_alive host end end - # @return [Mutex] + # @return [Thread::Mutex] def mutex @mutex ||= Mutex.new end diff --git a/lib/solargraph/library.rb b/lib/solargraph/library.rb index 9d5162431..bdbd1354f 100644 --- a/lib/solargraph/library.rb +++ b/lib/solargraph/library.rb @@ -522,7 +522,7 @@ def find_external_requires source_map @external_requires = nil end - # @return [Mutex] + # @return [Thread::Mutex] def mutex @mutex ||= Mutex.new end From 9d4ba443abbe73a9bbab2cc3179ecee6e54d7d46 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Fri, 26 Sep 2025 16:25:40 -0400 Subject: [PATCH 071/106] Allow more valid method pin paths --- lib/solargraph/shell.rb | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/lib/solargraph/shell.rb b/lib/solargraph/shell.rb index cb919476c..f9b655664 100755 --- a/lib/solargraph/shell.rb +++ b/lib/solargraph/shell.rb @@ -257,7 +257,21 @@ def list # @return [void] def pin path api_map = Solargraph::ApiMap.load_with_cache('.', $stderr) - pins = api_map.get_path_pins path + is_method = path.include?('#') || path.include?('.') + if is_method && options[:stack] + scope, ns, meth = if path.include? '#' + [:instance, *path.split('#', 2)] + else + [:class, *path.split('.', 2)] + end + + # @sg-ignore Wrong argument type for + # Solargraph::ApiMap#get_method_stack: rooted_tag + # expected String, received Array + pins = api_map.get_method_stack(ns, meth, scope: scope) + else + pins = api_map.get_path_pins path + end references = {} pin = pins.first case pin @@ -265,19 +279,6 @@ def pin path $stderr.puts "Pin not found for path '#{path}'" exit 1 when Pin::Method - # @sg-ignore Unresolved call to options - if options[:stack] - scope, ns, meth = if path.include? '#' - [:instance, *path.split('#', 2)] - else - [:class, *path.split('.', 2)] - end - - # @sg-ignore Wrong argument type for - # Solargraph::ApiMap#get_method_stack: rooted_tag - # expected String, received Array - pins = api_map.get_method_stack(ns, meth, scope: scope) - end when Pin::Namespace # @sg-ignore Unresolved call to options if options[:references] From 2712e6624275f341fffcb03aa62c2da881c3feaf Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Fri, 26 Sep 2025 16:31:05 -0400 Subject: [PATCH 072/106] RuboCop fix --- lib/solargraph/shell.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/solargraph/shell.rb b/lib/solargraph/shell.rb index f9b655664..40410d909 100755 --- a/lib/solargraph/shell.rb +++ b/lib/solargraph/shell.rb @@ -278,7 +278,6 @@ def pin path when nil $stderr.puts "Pin not found for path '#{path}'" exit 1 - when Pin::Method when Pin::Namespace # @sg-ignore Unresolved call to options if options[:references] From 7bc2092b7844aaa78298f1d94d5f5e7e7cc84f1f Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Fri, 26 Sep 2025 16:36:10 -0400 Subject: [PATCH 073/106] Linting --- lib/solargraph/shell.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/solargraph/shell.rb b/lib/solargraph/shell.rb index 40410d909..046a74296 100755 --- a/lib/solargraph/shell.rb +++ b/lib/solargraph/shell.rb @@ -258,6 +258,7 @@ def list def pin path api_map = Solargraph::ApiMap.load_with_cache('.', $stderr) is_method = path.include?('#') || path.include?('.') + # @sg-ignore Unresolved call to options if is_method && options[:stack] scope, ns, meth = if path.include? '#' [:instance, *path.split('#', 2)] From 7546f7355534c70d3ae9ddbb863304d5be557d16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lek=C3=AB=20Mula?= Date: Sun, 21 Sep 2025 17:41:33 +0200 Subject: [PATCH 074/106] Enable solargraph-rspec tests --- .github/workflows/plugins.yml | 55 ++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/.github/workflows/plugins.yml b/.github/workflows/plugins.yml index b5984f3cb..ded3be5a0 100644 --- a/.github/workflows/plugins.yml +++ b/.github/workflows/plugins.yml @@ -105,30 +105,37 @@ jobs: - name: Ensure specs still run run: bundle exec rake spec - # run_solargraph_rspec_specs: - # # check out solargraph-rspec as well as this project, and point the former to use the latter as a local gem - # runs-on: ubuntu-latest - # steps: - # - uses: actions/checkout@v3 - # - name: clone https://github.com/lekemula/solargraph-rspec/ - # run: | - # cd .. - # git clone https://github.com/lekemula/solargraph-rspec.git - # cd solargraph-rspec - # - name: Set up Ruby - # uses: ruby/setup-ruby@v1 - # with: - # ruby-version: '3.0' - # bundler-cache: false - # - name: Install gems - # run: | - # cd ../solargraph-rspec - # echo "gem 'solargraph', path: '../solargraph'" >> Gemfile - # bundle install - # - name: Run specs - # run: | - # cd ../solargraph-rspec - # bundle exec rake spec + run_solargraph_rspec_specs: + # check out solargraph-rspec as well as this project, and point the former to use the latter as a local gem + runs-on: ubuntu-latest + env: + SOLARGRAPH_CACHE: ${{ github.workspace }}/solargraph-rspec/vendor/solargraph/cache + steps: + - uses: actions/checkout@v3 + - name: clone https://github.com/lekemula/solargraph-rspec/ + run: | + cd .. + git clone https://github.com/lekemula/solargraph-rspec.git + cd solargraph-rspec + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.4 + bundler-cache: true + - name: Install gems + run: | + cd ../solargraph-rspec + echo "gem 'solargraph', path: '../solargraph'" >> Gemfile + bundle install + - name: Solargraph generate RSpec gems YARD and RBS pins + run: | + cd ../solargraph-rspec + rspec_gems=$(bundle exec ruby -r './lib/solargraph-rspec' -e 'puts Solargraph::Rspec::Gems.gem_names.join(" ")' 2>/dev/null | tail -n1) + bundle exec solargraph gems $rspec_gems + - name: Run specs + run: | + cd ../solargraph-rspec + bundle exec rspec run_solargraph_rails_specs: # check out solargraph-rails as well as this project, and point the former to use the latter as a local gem From 9c79e5b3a01ac3fd8d84b35b94e4cb4110f91b2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lek=C3=AB=20Mula?= Date: Sun, 21 Sep 2025 19:40:15 +0200 Subject: [PATCH 075/106] Fix rspec gems specs --- .github/workflows/plugins.yml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/plugins.yml b/.github/workflows/plugins.yml index ded3be5a0..1c633fda0 100644 --- a/.github/workflows/plugins.yml +++ b/.github/workflows/plugins.yml @@ -109,7 +109,8 @@ jobs: # check out solargraph-rspec as well as this project, and point the former to use the latter as a local gem runs-on: ubuntu-latest env: - SOLARGRAPH_CACHE: ${{ github.workspace }}/solargraph-rspec/vendor/solargraph/cache + SOLARGRAPH_CACHE: ${{ github.workspace }}/../solargraph-rspec/vendor/solargraph/cache + BUNDLE_PATH: ${{ github.workspace }}/../solargraph-rspec/vendor/bundle steps: - uses: actions/checkout@v3 - name: clone https://github.com/lekemula/solargraph-rspec/ @@ -121,12 +122,17 @@ jobs: uses: ruby/setup-ruby@v1 with: ruby-version: 3.4 - bundler-cache: true + bundler-cache: false - name: Install gems run: | cd ../solargraph-rspec echo "gem 'solargraph', path: '../solargraph'" >> Gemfile - bundle install + bundle config path ${{ env.BUNDLE_PATH }} + bundle install --jobs 4 --retry 3 + - name: Configure .solargraph.yml + run: | + cd ../solargraph-rspec + cp .solargraph.yml.example .solargraph.yml - name: Solargraph generate RSpec gems YARD and RBS pins run: | cd ../solargraph-rspec @@ -135,7 +141,7 @@ jobs: - name: Run specs run: | cd ../solargraph-rspec - bundle exec rspec + bundle exec rspec --format progress run_solargraph_rails_specs: # check out solargraph-rails as well as this project, and point the former to use the latter as a local gem From 5d4bbc3b37c01eadfac7c60b17035e7412346e77 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 27 Sep 2025 22:09:31 -0400 Subject: [PATCH 076/106] Closure merging fixes 1) Prefer closures with more gates, to maximize compatibility 2) Look at basename of location, to make choice consistent --- lib/solargraph/pin/base.rb | 11 +++++++++-- spec/pin/base_spec.rb | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/lib/solargraph/pin/base.rb b/lib/solargraph/pin/base.rb index c0eecabb2..bb6608d0f 100644 --- a/lib/solargraph/pin/base.rb +++ b/lib/solargraph/pin/base.rb @@ -353,8 +353,15 @@ def choose_pin_attr(other, attr) # :nocov: end # arbitrary way of choosing a pin - # @sg-ignore Need _1 support - [val1, val2].compact.min_by { _1.best_location.to_s } + [val1, val2].compact.max_by do |closure| + [ + # maximize number of gates, as types in other combined pins may + # depend on those gates + closure.gates.length, + # use basename so that results don't vary system to system + File.basename(closure.best_location.to_s) + ] + end end # @return [void] diff --git a/spec/pin/base_spec.rb b/spec/pin/base_spec.rb index 6bcce6cef..d1d2f0cf4 100644 --- a/spec/pin/base_spec.rb +++ b/spec/pin/base_spec.rb @@ -48,4 +48,18 @@ pin = Solargraph::Pin::Base.new(name: 'Foo', comments: '@return [undefined]') expect(pin.link_documentation).to eq('Foo') end + + it 'deals well with known closure combination issue' do + Solargraph::Shell.new.uncache('yard') + api_map = Solargraph::ApiMap.load_with_cache('.', $stderr) + pins = api_map.get_method_stack('YARD::Docstring', 'parser', scope: :class) + expect(pins.length).to eq(1) + parser_method_pin = pins.first + expect(parser_method_pin.source).to eq(:combined) + return_type = parser_method_pin.typify(api_map) + expect(parser_method_pin.closure.name).to eq("Docstring") + expect(parser_method_pin.closure.gates).to eq(["YARD::Docstring", "YARD", '']) + expect(return_type).to be_defined + expect(parser_method_pin.typify(api_map).rooted_tags).to eq('::YARD::DocstringParser') + end end From b5898e2a97b81a0219ee145769c978d1fabcb6c3 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 27 Sep 2025 22:21:02 -0400 Subject: [PATCH 077/106] Drop incidental requirement --- spec/pin/base_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/pin/base_spec.rb b/spec/pin/base_spec.rb index d1d2f0cf4..1a6cfd1e8 100644 --- a/spec/pin/base_spec.rb +++ b/spec/pin/base_spec.rb @@ -55,7 +55,6 @@ pins = api_map.get_method_stack('YARD::Docstring', 'parser', scope: :class) expect(pins.length).to eq(1) parser_method_pin = pins.first - expect(parser_method_pin.source).to eq(:combined) return_type = parser_method_pin.typify(api_map) expect(parser_method_pin.closure.name).to eq("Docstring") expect(parser_method_pin.closure.gates).to eq(["YARD::Docstring", "YARD", '']) From 12e45630867530a19b8c839c162c2ada88d03511 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 28 Sep 2025 14:19:54 -0400 Subject: [PATCH 078/106] [regression] Fix resolution of a nested type case Found in the Solargraph::Pin::DelegatedMethod class in strong typechecking in https://github.com/apiology/solargraph/pull/12 --- lib/solargraph/api_map/constants.rb | 3 ++- spec/pin/parameter_spec.rb | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/lib/solargraph/api_map/constants.rb b/lib/solargraph/api_map/constants.rb index 430303ae1..3e846e0b1 100644 --- a/lib/solargraph/api_map/constants.rb +++ b/lib/solargraph/api_map/constants.rb @@ -119,7 +119,8 @@ def complex_resolve name, gates, internal resolved = simple_resolve(name, gate, internal) return [resolved, gates[(idx + 1)..]] if resolved store.get_ancestor_references(gate).each do |ref| - return ref.name.sub(/^::/, '') if ref.name.end_with?("::#{name}") + return ref.name.sub(/^::/, '') if ref.name.end_with?("::#{name}") && ref.name.start_with?('::') + mixin = resolve(ref.name, ref.reference_gates - gates) next unless mixin resolved = simple_resolve(name, mixin, internal) diff --git a/spec/pin/parameter_spec.rb b/spec/pin/parameter_spec.rb index 082ec54c6..81d40e5db 100644 --- a/spec/pin/parameter_spec.rb +++ b/spec/pin/parameter_spec.rb @@ -473,5 +473,33 @@ def self.foo bar: 'bar' type = pin.probe(api_map) expect(type.simple_tags).to eq('String') end + + it 'infers types from kwoptarg values' do + source = Solargraph::Source.load_string(%( + module A + module B + class Method + end + end + end + + module A + module B + class C < B::Method + # @param alt [Method] + # @return [B::Method, nil] + def resolve_method alt + alt + end + end + end + end + ), 'test.rb') + api_map = Solargraph::ApiMap.new + api_map.map(source) + + clip = api_map.clip_at('test.rb', [14, 16]) + expect(clip.infer.rooted_tags).to eq('::A::B::Method') + end end end From b8174ddb186418dc0ef2feec67c514da1e977d31 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 28 Sep 2025 14:36:41 -0400 Subject: [PATCH 079/106] Fix example name --- spec/pin/parameter_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/pin/parameter_spec.rb b/spec/pin/parameter_spec.rb index 81d40e5db..14c39f3fe 100644 --- a/spec/pin/parameter_spec.rb +++ b/spec/pin/parameter_spec.rb @@ -474,7 +474,7 @@ def self.foo bar: 'bar' expect(type.simple_tags).to eq('String') end - it 'infers types from kwoptarg values' do + it 'handles a relative type name case' do source = Solargraph::Source.load_string(%( module A module B From faa57aa5b71898b899033ac1e49263fcecdb920b Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 30 Sep 2025 08:32:26 -0400 Subject: [PATCH 080/106] Add another unmerged-Yard-PR issue --- .rubocop_todo.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 4745544d0..83339e756 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -89,13 +89,6 @@ Layout/EmptyLineBetweenDefs: Layout/EmptyLines: Enabled: false -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines, beginning_only, ending_only -Layout/EmptyLinesAroundClassBody: - Exclude: - - 'lib/solargraph/rbs_map/core_map.rb' - # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle. # SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines @@ -1286,6 +1279,7 @@ YARD/MismatchName: YARD/TagTypeSyntax: Exclude: + - 'lib/solargraph/api_map/constants.rb' - 'lib/solargraph/language_server/host.rb' - 'lib/solargraph/parser/comment_ripper.rb' - 'lib/solargraph/pin/method.rb' From b9f29005c3e270a009688e72b68ae8005e99ba33 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 30 Sep 2025 09:37:05 -0400 Subject: [PATCH 081/106] Fix merge issue --- lib/solargraph/type_checker.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/solargraph/type_checker.rb b/lib/solargraph/type_checker.rb index dfabbec1a..d8bdb4424 100644 --- a/lib/solargraph/type_checker.rb +++ b/lib/solargraph/type_checker.rb @@ -462,7 +462,7 @@ def kwarg_problems_for sig, argchain, api_map, closure_pin, locals, location, pi ptype = data[:qualified] ptype = ptype.self_to_type(pin.context) unless ptype.undefined? - argtype = argchain.infer(api_map, closure_pin, locals).self_to_type(block_pin.context) + argtype = argchain.infer(api_map, closure_pin, locals).self_to_type(closure_pin.context) if argtype.defined? && ptype && !any_types_match?(api_map, ptype, argtype) result.push Problem.new(location, "Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}") end From 3df4406de77a159e1997c10a4b7d3d7532745ab2 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 30 Sep 2025 11:13:47 -0400 Subject: [PATCH 082/106] Ratchet RuboCop --- .rubocop_todo.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 4745544d0..3d48a2371 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -89,13 +89,6 @@ Layout/EmptyLineBetweenDefs: Layout/EmptyLines: Enabled: false -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines, beginning_only, ending_only -Layout/EmptyLinesAroundClassBody: - Exclude: - - 'lib/solargraph/rbs_map/core_map.rb' - # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle. # SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines From 2e6aa3f9344c299c22223265bb6d3fd7de4ba123 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 30 Sep 2025 12:25:15 -0400 Subject: [PATCH 083/106] Drop unneeded @sg-ignores --- lib/solargraph/parser/parser_gem/node_processors/send_node.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/solargraph/parser/parser_gem/node_processors/send_node.rb b/lib/solargraph/parser/parser_gem/node_processors/send_node.rb index 645baf00f..3b7ec74b1 100644 --- a/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +++ b/lib/solargraph/parser/parser_gem/node_processors/send_node.rb @@ -36,15 +36,12 @@ def process process_autoload elsif method_name == :private_constant process_private_constant - # @sg-ignore elsif method_name == :alias_method && node.children[2] && node.children[2] && node.children[2].type == :sym && node.children[3] && node.children[3].type == :sym process_alias_method - # @sg-ignore elsif method_name == :private_class_method && node.children[2].is_a?(AST::Node) # Processing a private class can potentially handle children on its own return if process_private_class_method end - # @sg-ignore elsif method_name == :require && node.children[0].to_s == '(const nil :Bundler)' pins.push Pin::Reference::Require.new(Solargraph::Location.new(region.filename, Solargraph::Range.from_to(0, 0, 0, 0)), 'bundler/require', source: :parser) end From 66abe83bd0d6d3759aa5e9bac70eff86009f098c Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 30 Sep 2025 12:26:53 -0400 Subject: [PATCH 084/106] Drop unneeded @sg-ignore --- lib/solargraph/workspace/require_paths.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/solargraph/workspace/require_paths.rb b/lib/solargraph/workspace/require_paths.rb index 67adae9e6..c8eea161b 100644 --- a/lib/solargraph/workspace/require_paths.rb +++ b/lib/solargraph/workspace/require_paths.rb @@ -76,7 +76,6 @@ def require_path_from_gemspec_file gemspec_file_path "spec = eval(File.read('#{gemspec_file_path}'), TOPLEVEL_BINDING, '#{gemspec_file_path}'); " \ 'return unless Gem::Specification === spec; ' \ 'puts({name: spec.name, paths: spec.require_paths}.to_json)'] - # @sg-ignore Unresolved call to capture3 on Module o, e, s = Open3.capture3(*cmd) if s.success? begin From c35d6a7e74831f7c3562600b111a5c861658725d Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Tue, 30 Sep 2025 12:32:45 -0400 Subject: [PATCH 085/106] Drop another @sg-ignore --- lib/solargraph/pin/delegated_method.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/solargraph/pin/delegated_method.rb b/lib/solargraph/pin/delegated_method.rb index 9483fb058..bcf5b5912 100644 --- a/lib/solargraph/pin/delegated_method.rb +++ b/lib/solargraph/pin/delegated_method.rb @@ -51,7 +51,6 @@ def type_location %i[typify realize infer probe].each do |method| # @param api_map [ApiMap] define_method(method) do |api_map| - # @sg-ignore Unresolved call to resolve_method resolve_method(api_map) # @sg-ignore Need to set context correctly in define_method blocks @resolved_method ? @resolved_method.send(method, api_map) : super(api_map) From 152dbdfe446088f8c997c55d663321e264bf5ed2 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sun, 5 Oct 2025 17:43:51 -0400 Subject: [PATCH 086/106] Annotation fixes for strong typechecking --- lib/solargraph/api_map/index.rb | 6 ++++-- lib/solargraph/doc_map.rb | 3 +-- .../parser/parser_gem/node_processors/opasgn_node.rb | 2 ++ lib/solargraph/pin/local_variable.rb | 3 --- lib/solargraph/position.rb | 1 - lib/solargraph/source_map.rb | 4 +++- lib/solargraph/source_map/mapper.rb | 2 -- lib/solargraph/workspace/config.rb | 6 ++++++ 8 files changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/solargraph/api_map/index.rb b/lib/solargraph/api_map/index.rb index 35d86446a..cb61a28eb 100644 --- a/lib/solargraph/api_map/index.rb +++ b/lib/solargraph/api_map/index.rb @@ -114,8 +114,10 @@ def catalog new_pins self end - # @param klass [Class] - # @param hash [Hash{String => Array}] + # @generic T + # @param klass [Class] + # @param hash [Hash{String => T}] + # # @return [void] def map_references klass, hash pins_by_class(klass).each do |pin| diff --git a/lib/solargraph/doc_map.rb b/lib/solargraph/doc_map.rb index 5966717f4..05f2f1647 100644 --- a/lib/solargraph/doc_map.rb +++ b/lib/solargraph/doc_map.rb @@ -128,7 +128,7 @@ def unresolved_requires @unresolved_requires ||= required_gems_map.select { |_, gemspecs| gemspecs.nil? }.keys end - # @return [Hash{Array(String, String) => Array}] Indexed by gemspec name and version + # @return [Hash{Array(String, String) => Array}] Indexed by gemspec name and version def self.all_yard_gems_in_memory @yard_gems_in_memory ||= {} end @@ -180,7 +180,6 @@ def load_serialized_gem_pins # @sg-ignore Need support for RBS duck interfaces like _ToHash # @type [Array] paths = Hash[without_gemspecs].keys - # @sg-ignore Need support for RBS duck interfaces like _ToHash # @type [Array] gemspecs = Hash[with_gemspecs].values.flatten.compact + dependencies.to_a diff --git a/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb b/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb index 0e4d7b26a..a4359af9d 100644 --- a/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +++ b/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb @@ -13,8 +13,10 @@ def process operator = node.children[1] argument = node.children[2] if target.type == :send + # @sg-ignore Need a downcast here process_send_target(target, operator, argument) elsif target.type.to_s.end_with?('vasgn') + # @sg-ignore Need a downcast here process_vasgn_target(target, operator, argument) else Solargraph.assert_or_log(:opasgn_unknown_target, diff --git a/lib/solargraph/pin/local_variable.rb b/lib/solargraph/pin/local_variable.rb index 9eae6cc6f..cb2dda140 100644 --- a/lib/solargraph/pin/local_variable.rb +++ b/lib/solargraph/pin/local_variable.rb @@ -26,9 +26,6 @@ def combine_with(other, attrs={}) assignment: assert_same(other, :assignment), presence_certain: assert_same(other, :presence_certain?), }.merge(attrs) - # @sg-ignore Wrong argument type for - # Solargraph::Pin::Base#assert_same: other expected - # Solargraph::Pin::Base, received self new_attrs[:presence] = assert_same(other, :presence) unless attrs.key?(:presence) super(other, new_attrs) diff --git a/lib/solargraph/position.rb b/lib/solargraph/position.rb index 2faa0a99b..1197038ef 100644 --- a/lib/solargraph/position.rb +++ b/lib/solargraph/position.rb @@ -58,7 +58,6 @@ def inspect # @return [Integer] def self.to_offset text, position return 0 if text.empty? - # @sg-ignore Unresolved call to + on Integer text.lines[0...position.line].sum(&:length) + position.character end diff --git a/lib/solargraph/source_map.rb b/lib/solargraph/source_map.rb index d7b6fb4fc..15b747760 100644 --- a/lib/solargraph/source_map.rb +++ b/lib/solargraph/source_map.rb @@ -41,11 +41,13 @@ def initialize source # solargraph-rails is known to use this method to get the document symbols. It should probably be removed. @document_symbols = nil self.convention_pins = conventions_environ.pins + # @type [Hash{Class => Array}] @pin_select_cache = {} end # @generic T # @param klass [Class>] + # # @return [Array>] def pins_by_class klass @pin_select_cache[klass] ||= pin_class_hash.select { |key, _| key <= klass }.values.flatten @@ -171,10 +173,10 @@ def map source private - # @return [Hash{Class => Array}] # @return [Array] attr_writer :convention_pins + # @return [Hash{Class => Array}] def pin_class_hash @pin_class_hash ||= pins.to_set.classify(&:class).transform_values(&:to_a) end diff --git a/lib/solargraph/source_map/mapper.rb b/lib/solargraph/source_map/mapper.rb index 18fdf1f88..5fdcb9fe6 100644 --- a/lib/solargraph/source_map/mapper.rb +++ b/lib/solargraph/source_map/mapper.rb @@ -70,7 +70,6 @@ def closure_at(position) # @param comment [String] # @return [void] def process_comment source_position, comment_position, comment - # @sg-ignore Wrong argument type for String#=~: object expected String::_MatchAgainst, received Regexp return unless comment.encode('UTF-8', invalid: :replace, replace: '?') =~ DIRECTIVE_REGEXP cmnt = remove_inline_comment_hashes(comment) parse = Solargraph::Source.parse_docstring(cmnt) @@ -245,7 +244,6 @@ def remove_inline_comment_hashes comment # @return [void] def process_comment_directives - # @sg-ignore Wrong argument type for String#=~: object expected String::_MatchAgainst, received Regexp return unless @code.encode('UTF-8', invalid: :replace, replace: '?') =~ DIRECTIVE_REGEXP code_lines = @code.lines @source.associated_comments.each do |line, comments| diff --git a/lib/solargraph/workspace/config.rb b/lib/solargraph/workspace/config.rb index d1e6c27b5..3e30e5d74 100644 --- a/lib/solargraph/workspace/config.rb +++ b/lib/solargraph/workspace/config.rb @@ -63,6 +63,7 @@ def calculated # namespace. It's typically used to identify available DSLs. # # @return [Array] + # @sg-ignore Need to validate config def domains raw_data['domains'] end @@ -70,6 +71,7 @@ def domains # An array of required paths to add to the workspace. # # @return [Array] + # @sg-ignore Need to validate config def required raw_data['require'] end @@ -83,6 +85,7 @@ def require_paths # An array of reporters to use for diagnostics. # + # @sg-ignore Need to validate config # @return [Array] def reporters raw_data['reporters'] @@ -90,6 +93,7 @@ def reporters # A hash of options supported by the formatter # + # @sg-ignore Need to validate config # @return [Hash] def formatter raw_data['formatter'] @@ -97,6 +101,7 @@ def formatter # An array of plugins to require. # + # @sg-ignore Need to validate config # @return [Array] def plugins raw_data['plugins'] @@ -104,6 +109,7 @@ def plugins # The maximum number of files to parse from the workspace. # + # @sg-ignore Need to validate config # @return [Integer] def max_files raw_data['max_files'] From 2240ad7aeb03bfc30cbda1b724b4e9616a3ba90f Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Thu, 9 Oct 2025 07:56:22 -0400 Subject: [PATCH 087/106] Add @sg-ignores for issues covered by future PRs --- lib/solargraph/doc_map.rb | 1 + lib/solargraph/position.rb | 1 + lib/solargraph/shell.rb | 1 + lib/solargraph/source_map/mapper.rb | 6 ++++++ lib/solargraph/type_checker.rb | 1 + 5 files changed, 10 insertions(+) diff --git a/lib/solargraph/doc_map.rb b/lib/solargraph/doc_map.rb index 05f2f1647..5dcf28552 100644 --- a/lib/solargraph/doc_map.rb +++ b/lib/solargraph/doc_map.rb @@ -180,6 +180,7 @@ def load_serialized_gem_pins # @sg-ignore Need support for RBS duck interfaces like _ToHash # @type [Array] paths = Hash[without_gemspecs].keys + # @sg-ignore Need support for RBS duck interfaces like _ToHash # @type [Array] gemspecs = Hash[with_gemspecs].values.flatten.compact + dependencies.to_a diff --git a/lib/solargraph/position.rb b/lib/solargraph/position.rb index 1197038ef..2faa0a99b 100644 --- a/lib/solargraph/position.rb +++ b/lib/solargraph/position.rb @@ -58,6 +58,7 @@ def inspect # @return [Integer] def self.to_offset text, position return 0 if text.empty? + # @sg-ignore Unresolved call to + on Integer text.lines[0...position.line].sum(&:length) + position.character end diff --git a/lib/solargraph/shell.rb b/lib/solargraph/shell.rb index a005f600b..1284e16de 100755 --- a/lib/solargraph/shell.rb +++ b/lib/solargraph/shell.rb @@ -80,6 +80,7 @@ def config(directory = '.') end end File.open(File.join(directory, '.solargraph.yml'), 'w') do |file| + # @sg-ignore Unresolved call to to_yaml file.puts conf.to_yaml end STDOUT.puts "Configuration file initialized." diff --git a/lib/solargraph/source_map/mapper.rb b/lib/solargraph/source_map/mapper.rb index 5fdcb9fe6..871f3ed5f 100644 --- a/lib/solargraph/source_map/mapper.rb +++ b/lib/solargraph/source_map/mapper.rb @@ -70,6 +70,9 @@ def closure_at(position) # @param comment [String] # @return [void] def process_comment source_position, comment_position, comment + # @sg-ignore Wrong argument type for String#=~: object + # expected String::_MatchAgainst, received + # Regexp return unless comment.encode('UTF-8', invalid: :replace, replace: '?') =~ DIRECTIVE_REGEXP cmnt = remove_inline_comment_hashes(comment) parse = Solargraph::Source.parse_docstring(cmnt) @@ -244,6 +247,9 @@ def remove_inline_comment_hashes comment # @return [void] def process_comment_directives + # @sg-ignore Wrong argument type for String#=~: object + # expected String::_MatchAgainst, received + # Regexp return unless @code.encode('UTF-8', invalid: :replace, replace: '?') =~ DIRECTIVE_REGEXP code_lines = @code.lines @source.associated_comments.each do |line, comments| diff --git a/lib/solargraph/type_checker.rb b/lib/solargraph/type_checker.rb index d8bdb4424..36263a0ce 100644 --- a/lib/solargraph/type_checker.rb +++ b/lib/solargraph/type_checker.rb @@ -463,6 +463,7 @@ def kwarg_problems_for sig, argchain, api_map, closure_pin, locals, location, pi ptype = ptype.self_to_type(pin.context) unless ptype.undefined? argtype = argchain.infer(api_map, closure_pin, locals).self_to_type(closure_pin.context) + # @sg-ignore Unresolved call to defined? if argtype.defined? && ptype && !any_types_match?(api_map, ptype, argtype) result.push Problem.new(location, "Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}") end From b0fb367852f9d4d919abb17db6fb38803cc75eb1 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Thu, 9 Oct 2025 08:07:55 -0400 Subject: [PATCH 088/106] Add @sg-ignores for issues covered by future PRs --- lib/solargraph/shell.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/solargraph/shell.rb b/lib/solargraph/shell.rb index 1284e16de..a005f600b 100755 --- a/lib/solargraph/shell.rb +++ b/lib/solargraph/shell.rb @@ -80,7 +80,6 @@ def config(directory = '.') end end File.open(File.join(directory, '.solargraph.yml'), 'w') do |file| - # @sg-ignore Unresolved call to to_yaml file.puts conf.to_yaml end STDOUT.puts "Configuration file initialized." From ed2381371b008165a1c2fdb992bcac7bda1d6a23 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Mon, 3 Nov 2025 09:25:02 -0500 Subject: [PATCH 089/106] Reproduce solargraph-rspec rspec failure --- .github/workflows/plugins.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/plugins.yml b/.github/workflows/plugins.yml index b5984f3cb..2619b9ff8 100644 --- a/.github/workflows/plugins.yml +++ b/.github/workflows/plugins.yml @@ -143,6 +143,7 @@ jobs: - name: Set up Ruby uses: ruby/setup-ruby@v1 with: + # solargraph-rails supports Ruby 3.0+ ruby-version: '3.0' bundler-cache: false From c6dbe4d0899255deaa596f08b92494f90ef2886d Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 15 Nov 2025 11:19:09 -0500 Subject: [PATCH 090/106] Trigger build --- .github/workflows/plugins.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/plugins.yml b/.github/workflows/plugins.yml index 2619b9ff8..b5984f3cb 100644 --- a/.github/workflows/plugins.yml +++ b/.github/workflows/plugins.yml @@ -143,7 +143,6 @@ jobs: - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - # solargraph-rails supports Ruby 3.0+ ruby-version: '3.0' bundler-cache: false From 9d2686301d53487871584ab3cbb690c256e44114 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 15 Nov 2025 11:22:22 -0500 Subject: [PATCH 091/106] Fix new bundler issue --- .github/workflows/rspec.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index ecc3d9771..b213c5ed0 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -35,6 +35,10 @@ jobs: uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby-version }} + # see https://github.com/castwide/solargraph/actions/runs/19391419903/job/55485410493?pr=1119 + # + # match version in Gemfile.lock and use same version below + bundler: 2.5.23 bundler-cache: false - name: Set rbs version run: echo "gem 'rbs', '${{ matrix.rbs-version }}'" >> .Gemfile @@ -46,7 +50,7 @@ jobs: run: echo "gem 'tsort'" >> .Gemfile - name: Install gems run: | - bundle install + bundle _2.5.23_ install bundle update rbs # use latest available for this Ruby version - name: Run tests run: bundle exec rake spec From 87ec9b35adfa75103bb0702282874a806ef7c054 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 15 Nov 2025 11:42:41 -0500 Subject: [PATCH 092/106] Debug --- .github/workflows/rspec.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index b213c5ed0..073594aac 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -52,6 +52,7 @@ jobs: run: | bundle _2.5.23_ install bundle update rbs # use latest available for this Ruby version + bundle list - name: Run tests run: bundle exec rake spec undercover: From 6a14bd7e09899beaaa9ee0370a42366ee81596f2 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 15 Nov 2025 12:28:38 -0500 Subject: [PATCH 093/106] Turn off warning diagnostics in CLI --- bin/solargraph | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bin/solargraph b/bin/solargraph index d85561700..248dc42fd 100755 --- a/bin/solargraph +++ b/bin/solargraph @@ -1,5 +1,8 @@ #!/usr/bin/env ruby +# turn off warning diagnostics from Ruby +$VERBOSE=nil + require 'solargraph' Solargraph::Shell.start(ARGV) From 7e7604bdfc5d76af86c5b7f5b25ade3d2201b52e Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 15 Nov 2025 13:38:08 -0500 Subject: [PATCH 094/106] Debug --- .github/workflows/rspec.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index 7b8ba9bfb..2743ca84f 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -61,6 +61,7 @@ jobs: bundle _2.5.23_ install bundle update rbs # use latest available for this Ruby version bundle list + bundle exec solargraph pin 'Bundler::Dsl#source' - name: Update types run: | bundle exec rbs collection update From 91d3cd4a981dcf651d1fa45ad78b96e2dd8bedbf Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 15 Nov 2025 18:12:51 -0500 Subject: [PATCH 095/106] Fix pin merging bug --- lib/solargraph/pin/base_variable.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/solargraph/pin/base_variable.rb b/lib/solargraph/pin/base_variable.rb index 764c1fb39..fbf22cbaa 100644 --- a/lib/solargraph/pin/base_variable.rb +++ b/lib/solargraph/pin/base_variable.rb @@ -12,8 +12,9 @@ class BaseVariable < Base attr_accessor :mass_assignment # @param return_type [ComplexType, nil] + # @param mass_assignment [::Array(Parser::AST::Node, Integer), nil] # @param assignment [Parser::AST::Node, nil] - def initialize assignment: nil, return_type: nil, **splat + def initialize assignment: nil, return_type: nil, mass_assignment: nil, **splat super(**splat) @assignment = assignment # @type [nil, ::Array(Parser::AST::Node, Integer)] @@ -22,12 +23,12 @@ def initialize assignment: nil, return_type: nil, **splat end def combine_with(other, attrs={}) - attrs.merge({ + new_attrs = attrs.merge({ assignment: assert_same(other, :assignment), mass_assignment: assert_same(other, :mass_assignment), return_type: combine_return_type(other), }) - super(other, attrs) + super(other, new_attrs) end def completion_item_kind From 652fcd218c0532455baf88c0f05295f862f3dbf3 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 15 Nov 2025 18:32:44 -0500 Subject: [PATCH 096/106] Add @sg-ignore --- lib/solargraph/pin/base_variable.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/solargraph/pin/base_variable.rb b/lib/solargraph/pin/base_variable.rb index fbf22cbaa..da1f15cb2 100644 --- a/lib/solargraph/pin/base_variable.rb +++ b/lib/solargraph/pin/base_variable.rb @@ -28,6 +28,7 @@ def combine_with(other, attrs={}) mass_assignment: assert_same(other, :mass_assignment), return_type: combine_return_type(other), }) + # @sg-ignore https://github.com/castwide/solargraph/pull/1050 super(other, new_attrs) end From fe06cf3e2fe8e22e3efefe46fe85e9adaa0913f5 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 15 Nov 2025 19:08:24 -0500 Subject: [PATCH 097/106] Add @sg-ignore --- lib/solargraph/yardoc.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/solargraph/yardoc.rb b/lib/solargraph/yardoc.rb index 09bcd4586..0afdf1482 100644 --- a/lib/solargraph/yardoc.rb +++ b/lib/solargraph/yardoc.rb @@ -23,6 +23,7 @@ def cache(yard_plugins, gemspec) yard_plugins.each { |plugin| cmd << " --plugin #{plugin}" } Solargraph.logger.debug { "Running: #{cmd}" } # @todo set these up to run in parallel + # @sg-ignore Unrecognized keyword argument chdir to Open3.capture2e stdout_and_stderr_str, status = Open3.capture2e(current_bundle_env_tweaks, cmd, chdir: gemspec.gem_dir) unless status.success? Solargraph.logger.warn { "YARD failed running #{cmd.inspect} in #{gemspec.gem_dir}" } From 9b6aa30353fb22baeee09ebaa573a96021d68db1 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 15 Nov 2025 19:13:25 -0500 Subject: [PATCH 098/106] Pull in solargraph-rspec fixes from another branch --- .github/workflows/plugins.yml | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/.github/workflows/plugins.yml b/.github/workflows/plugins.yml index 1c633fda0..fa704e2ae 100644 --- a/.github/workflows/plugins.yml +++ b/.github/workflows/plugins.yml @@ -116,19 +116,39 @@ jobs: - name: clone https://github.com/lekemula/solargraph-rspec/ run: | cd .. - git clone https://github.com/lekemula/solargraph-rspec.git + # git clone https://github.com/lekemula/solargraph-rspec.git + + # pending https://github.com/lekemula/solargraph-rspec/pull/30 + git clone https://github.com/apiology/solargraph-rspec.git cd solargraph-rspec + git checkout reset_closures - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: 3.4 + ruby-version: '3.1' + rubygems: latest bundler-cache: false - name: Install gems run: | + set -x + cd ../solargraph-rspec echo "gem 'solargraph', path: '../solargraph'" >> Gemfile bundle config path ${{ env.BUNDLE_PATH }} bundle install --jobs 4 --retry 3 + bundle exec appraisal install + # @todo some kind of appraisal/bundle conflict? + # https://github.com/castwide/solargraph/actions/runs/19038710934/job/54369767122?pr=1116 + # /home/runner/work/solargraph/solargraph-rspec/vendor/bundle/ruby/3.1.0/gems/bundler-2.6.9/lib/bundler/runtime.rb:317:in + # `check_for_activated_spec!': You have already activated date + # 3.5.0, but your Gemfile requires date 3.4.1. Prepending + # `bundle exec` to your command may solve + # this. (Gem::LoadError) + bundle exec appraisal update date + # For some reason on ruby 3.1 it defaults to an old version: 1.3.2 + # https://github.com/lekemula/solargraph-rspec/actions/runs/17814581205/job/50645370316?pr=22 + # We update manually to the latest + bundle exec appraisal update rspec-rails - name: Configure .solargraph.yml run: | cd ../solargraph-rspec @@ -136,12 +156,13 @@ jobs: - name: Solargraph generate RSpec gems YARD and RBS pins run: | cd ../solargraph-rspec - rspec_gems=$(bundle exec ruby -r './lib/solargraph-rspec' -e 'puts Solargraph::Rspec::Gems.gem_names.join(" ")' 2>/dev/null | tail -n1) - bundle exec solargraph gems $rspec_gems + bundle exec appraisal rbs collection update + rspec_gems=$(bundle exec appraisal ruby -r './lib/solargraph-rspec' -e 'puts Solargraph::Rspec::Gems.gem_names.join(" ")' 2>/dev/null | tail -n1) + bundle exec appraisal solargraph gems $rspec_gems - name: Run specs run: | cd ../solargraph-rspec - bundle exec rspec --format progress + bundle exec appraisal rspec --format progress run_solargraph_rails_specs: # check out solargraph-rails as well as this project, and point the former to use the latter as a local gem From 19eae82aa99710ddf1882abd841406b270b3ec24 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 15 Nov 2025 19:23:51 -0500 Subject: [PATCH 099/106] Drop @sg-ignores --- lib/solargraph/pin/base_variable.rb | 1 - lib/solargraph/shell.rb | 13 ------------- 2 files changed, 14 deletions(-) diff --git a/lib/solargraph/pin/base_variable.rb b/lib/solargraph/pin/base_variable.rb index da1f15cb2..fbf22cbaa 100644 --- a/lib/solargraph/pin/base_variable.rb +++ b/lib/solargraph/pin/base_variable.rb @@ -28,7 +28,6 @@ def combine_with(other, attrs={}) mass_assignment: assert_same(other, :mass_assignment), return_type: combine_return_type(other), }) - # @sg-ignore https://github.com/castwide/solargraph/pull/1050 super(other, new_attrs) end diff --git a/lib/solargraph/shell.rb b/lib/solargraph/shell.rb index 046a74296..3b1c4952d 100755 --- a/lib/solargraph/shell.rb +++ b/lib/solargraph/shell.rb @@ -241,24 +241,17 @@ def list puts "#{workspace.filenames.length} files total." end - # @sg-ignore Unresolved call to desc desc 'pin [PATH]', 'Describe a pin', hide: true - # @sg-ignore Unresolved call to option option :rbs, type: :boolean, desc: 'Output the pin as RBS', default: false - # @sg-ignore Unresolved call to option option :typify, type: :boolean, desc: 'Output the calculated return type of the pin from annotations', default: false - # @sg-ignore Unresolved call to option option :references, type: :boolean, desc: 'Show references', default: false - # @sg-ignore Unresolved call to option option :probe, type: :boolean, desc: 'Output the calculated return type of the pin from annotations and inference', default: false - # @sg-ignore Unresolved call to option option :stack, type: :boolean, desc: 'Show entire stack of a method pin by including definitions in superclasses', default: false # @param path [String] The path to the method pin, e.g. 'Class#method' or 'Class.method' # @return [void] def pin path api_map = Solargraph::ApiMap.load_with_cache('.', $stderr) is_method = path.include?('#') || path.include?('.') - # @sg-ignore Unresolved call to options if is_method && options[:stack] scope, ns, meth = if path.include? '#' [:instance, *path.split('#', 2)] @@ -280,7 +273,6 @@ def pin path $stderr.puts "Pin not found for path '#{path}'" exit 1 when Pin::Namespace - # @sg-ignore Unresolved call to options if options[:references] superclass_tag = api_map.qualify_superclass(pin.return_type.tag) superclass_pin = api_map.get_path_pins(superclass_tag).first if superclass_tag @@ -289,12 +281,9 @@ def pin path end pins.each do |pin| - # @sg-ignore Unresolved call to options if options[:typify] || options[:probe] type = ComplexType::UNDEFINED - # @sg-ignore Unresolved call to options type = pin.typify(api_map) if options[:typify] - # @sg-ignore Unresolved call to options type = pin.probe(api_map) if options[:probe] && type.undefined? print_type(type) next @@ -338,7 +327,6 @@ def do_cache gemspec, api_map # @param type [ComplexType] # @return [void] def print_type(type) - # @sg-ignore Unresolved call to options if options[:rbs] puts type.to_rbs else @@ -349,7 +337,6 @@ def print_type(type) # @param pin [Solargraph::Pin::Base] # @return [void] def print_pin(pin) - # @sg-ignore Unresolved call to options if options[:rbs] puts pin.to_rbs else From 482671b6a1ff201c292d47b9bab1b15533037bb8 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 15 Nov 2025 19:26:16 -0500 Subject: [PATCH 100/106] Add @sg-ignore --- lib/solargraph/parser/parser_gem/node_methods.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/solargraph/parser/parser_gem/node_methods.rb b/lib/solargraph/parser/parser_gem/node_methods.rb index 02f790c00..b77c4cd47 100644 --- a/lib/solargraph/parser/parser_gem/node_methods.rb +++ b/lib/solargraph/parser/parser_gem/node_methods.rb @@ -119,6 +119,7 @@ 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] From b1d0b21818319684d51cc9e303f24448de565f43 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 15 Nov 2025 20:06:28 -0500 Subject: [PATCH 101/106] Drop @sg-ignore --- lib/solargraph/yardoc.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/solargraph/yardoc.rb b/lib/solargraph/yardoc.rb index 0afdf1482..09bcd4586 100644 --- a/lib/solargraph/yardoc.rb +++ b/lib/solargraph/yardoc.rb @@ -23,7 +23,6 @@ def cache(yard_plugins, gemspec) yard_plugins.each { |plugin| cmd << " --plugin #{plugin}" } Solargraph.logger.debug { "Running: #{cmd}" } # @todo set these up to run in parallel - # @sg-ignore Unrecognized keyword argument chdir to Open3.capture2e stdout_and_stderr_str, status = Open3.capture2e(current_bundle_env_tweaks, cmd, chdir: gemspec.gem_dir) unless status.success? Solargraph.logger.warn { "YARD failed running #{cmd.inspect} in #{gemspec.gem_dir}" } From 973b512b121a23bd53fc77c3d2c6caa718c511e2 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Sat, 15 Nov 2025 20:21:11 -0500 Subject: [PATCH 102/106] Use consistent ruby versions for typechecking --- .github/workflows/plugins.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/plugins.yml b/.github/workflows/plugins.yml index fa704e2ae..c7ad72cb4 100644 --- a/.github/workflows/plugins.yml +++ b/.github/workflows/plugins.yml @@ -23,7 +23,7 @@ jobs: - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: '3.0' + ruby-version: 3.4 bundler-cache: true - uses: awalsh128/cache-apt-pkgs-action@latest with: @@ -54,7 +54,7 @@ jobs: - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: '3.0' + ruby-version: 3.4 bundler-cache: false - uses: awalsh128/cache-apt-pkgs-action@latest with: @@ -83,7 +83,7 @@ jobs: - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: '3.0' + ruby-version: 3.4 bundler-cache: false - uses: awalsh128/cache-apt-pkgs-action@latest with: From 6e558b724b75401969fd656fc35f8ffa4c4d297d Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Fri, 28 Nov 2025 13:12:03 -0500 Subject: [PATCH 103/106] Avoid ignoring valid pins in typechecking An overly-conservative check in type_checker.rb was suppressing later warnings on method parameters with no default values --- lib/solargraph/type_checker.rb | 7 ++++--- spec/type_checker/levels/strong_spec.rb | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/solargraph/type_checker.rb b/lib/solargraph/type_checker.rb index 4600767b5..262d65137 100644 --- a/lib/solargraph/type_checker.rb +++ b/lib/solargraph/type_checker.rb @@ -195,7 +195,7 @@ def variable_type_tag_problems if pin.return_type.defined? declared = pin.typify(api_map) next if declared.duck_type? - if declared.defined? + if declared.defined? && pin.assignment if rules.validate_tags? inferred = pin.probe(api_map) if inferred.undefined? @@ -216,7 +216,7 @@ def variable_type_tag_problems elsif !pin.is_a?(Pin::Parameter) && !resolved_constant?(pin) result.push Problem.new(pin.location, "Unresolved type #{pin.return_type} for variable #{pin.name}", pin: pin) end - else + elsif pin.assignment inferred = pin.probe(api_map) if inferred.undefined? && declared_externally?(pin) ignored_pins.push pin @@ -604,7 +604,8 @@ def external? pin # @param pin [Pin::BaseVariable] def declared_externally? pin - return true if pin.assignment.nil? + raise "No assignment found" if pin.assignment.nil? + chain = Solargraph::Parser.chain(pin.assignment, filename) rng = Solargraph::Range.from_node(pin.assignment) closure_pin = source_map.locate_closure_pin(rng.start.line, rng.start.column) diff --git a/spec/type_checker/levels/strong_spec.rb b/spec/type_checker/levels/strong_spec.rb index 970435dc3..5c7544f17 100644 --- a/spec/type_checker/levels/strong_spec.rb +++ b/spec/type_checker/levels/strong_spec.rb @@ -4,6 +4,21 @@ def type_checker(code) Solargraph::TypeChecker.load_string(code, 'test.rb', :strong) end + it 'provides nil checking on calls from parameters without assignments' do + pending('https://github.com/castwide/solargraph/pull/1127') + + checker = type_checker(%( + # @param baz [String, nil] + # + # @return [String] + def quux(baz) + baz.upcase # ERROR: Unresolved call to upcase on String, nil + end + )) + expect(checker.problems.map(&:message)).to eq(['#quux return type could not be inferred', + 'Unresolved call to upcase on String, nil']) + end + it 'does not complain on array dereference' do checker = type_checker(%( # @param idx [Integer, nil] an index From 890d638cb18b9f09c2f34893eb121b1d52062a33 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Fri, 28 Nov 2025 13:21:17 -0500 Subject: [PATCH 104/106] Fix newly found type issue --- lib/solargraph/shell.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/solargraph/shell.rb b/lib/solargraph/shell.rb index 046a74296..688ec90ff 100755 --- a/lib/solargraph/shell.rb +++ b/lib/solargraph/shell.rb @@ -273,6 +273,7 @@ def pin path else pins = api_map.get_path_pins path end + # @type [Hash{Symbol => Pin::Base}] references = {} pin = pins.first case pin From 40f547f0fb0fbceadb567eb447a9f06cfb801d7b Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Fri, 28 Nov 2025 15:55:08 -0500 Subject: [PATCH 105/106] Annotations needed after https://github.com/castwide/solargraph/pull/1130 --- lib/solargraph/api_map.rb | 1 + lib/solargraph/api_map/constants.rb | 12 +++---- lib/solargraph/api_map/index.rb | 34 ++++++++++++++++--- lib/solargraph/api_map/source_to_yard.rb | 3 ++ lib/solargraph/api_map/store.rb | 11 ++++-- lib/solargraph/complex_type.rb | 1 + lib/solargraph/complex_type/type_methods.rb | 1 + lib/solargraph/complex_type/unique_type.rb | 6 ++++ lib/solargraph/diagnostics/rubocop_helpers.rb | 5 ++- lib/solargraph/doc_map.rb | 3 ++ lib/solargraph/equality.rb | 1 + lib/solargraph/gem_pins.rb | 3 ++ lib/solargraph/language_server/host.rb | 1 + .../message/text_document/formatting.rb | 2 ++ lib/solargraph/location.rb | 1 + .../parser_gem/node_processors/and_node.rb | 1 + .../parser_gem/node_processors/send_node.rb | 2 ++ lib/solargraph/pin/base.rb | 2 ++ lib/solargraph/pin/base_variable.rb | 1 + lib/solargraph/pin/block.rb | 1 + lib/solargraph/pin/callable.rb | 2 ++ lib/solargraph/pin/method.rb | 18 +++++++++- lib/solargraph/pin/parameter.rb | 4 +++ lib/solargraph/pin/search.rb | 3 ++ lib/solargraph/position.rb | 1 + lib/solargraph/range.rb | 4 +++ lib/solargraph/rbs_map/conversions.rb | 13 +++++++ lib/solargraph/shell.rb | 2 ++ lib/solargraph/source/chain.rb | 2 ++ lib/solargraph/source/chain/call.rb | 1 + lib/solargraph/source/chain/if.rb | 2 +- lib/solargraph/source/chain/link.rb | 2 +- lib/solargraph/source/chain/or.rb | 2 +- lib/solargraph/type_checker.rb | 2 ++ lib/solargraph/yard_map/mapper/to_method.rb | 3 +- lib/solargraph/yard_map/to_method.rb | 3 +- solargraph.gemspec | 1 + 37 files changed, 136 insertions(+), 21 deletions(-) diff --git a/lib/solargraph/api_map.rb b/lib/solargraph/api_map.rb index c4fd49134..936f7406d 100755 --- a/lib/solargraph/api_map.rb +++ b/lib/solargraph/api_map.rb @@ -39,6 +39,7 @@ def initialize pins: [] # @param other [Object] def eql?(other) self.class == other.class && + # @sg-ignore Flow sensitive typing needs to handle self.class == other.class equality_fields == other.equality_fields end diff --git a/lib/solargraph/api_map/constants.rb b/lib/solargraph/api_map/constants.rb index 0df8d83ce..f643e2ad2 100644 --- a/lib/solargraph/api_map/constants.rb +++ b/lib/solargraph/api_map/constants.rb @@ -45,7 +45,7 @@ def dereference pin # Collect a list of all constants defined in the specified gates. # # @param gates [Array, String>] - # @return [Array] + # @return [Array] def collect(*gates) flat = gates.flatten cached_collect[flat] || collect_and_cache(flat) @@ -155,7 +155,7 @@ def simple_resolve name, gate, internal end # @param gates [Array] - # @return [Array] + # @return [Array] def collect_and_cache gates skip = Set.new cached_collect[gates] = gates.flat_map do |gate| @@ -168,7 +168,7 @@ def cached_resolve @cached_resolve ||= {} end - # @return [Hash{Array => Array}] + # @return [Hash{Array => Array}] def cached_collect @cached_collect ||= {} end @@ -213,7 +213,7 @@ def inner_qualify name, root, skip return fqns if store.namespace_exists?(fqns) incs = store.get_includes(roots.join('::')) incs.each do |inc| - foundinc = inner_qualify(name, inc.parametrized_tag.to_s, skip) + foundinc = inner_qualify(name, inc.type.to_s, skip) possibles.push foundinc unless foundinc.nil? end roots.pop @@ -221,7 +221,7 @@ def inner_qualify name, root, skip if possibles.empty? incs = store.get_includes('') incs.each do |inc| - foundinc = inner_qualify(name, inc.parametrized_tag.to_s, skip) + foundinc = inner_qualify(name, inc.type.to_s, skip) possibles.push foundinc unless foundinc.nil? end end @@ -233,7 +233,7 @@ def inner_qualify name, root, skip # @param fqns [String] # @param visibility [Array] # @param skip [Set] - # @return [Array] + # @return [Array] def inner_get_constants fqns, visibility, skip return [] if fqns.nil? || skip.include?(fqns) skip.add fqns diff --git a/lib/solargraph/api_map/index.rb b/lib/solargraph/api_map/index.rb index cb61a28eb..944f02c79 100644 --- a/lib/solargraph/api_map/index.rb +++ b/lib/solargraph/api_map/index.rb @@ -17,16 +17,22 @@ def pins # @return [Hash{String => Array}] def namespace_hash + # @param h [String] + # @param k [Array] @namespace_hash ||= Hash.new { |h, k| h[k] = [] } end # @return [Hash{String => Array}] def pin_class_hash + # @param h [String] + # @param k [Array] @pin_class_hash ||= Hash.new { |h, k| h[k] = [] } end # @return [Hash{String => Array}] def path_pin_hash + # @param h [String] + # @param k [Array] @path_pin_hash ||= Hash.new { |h, k| h[k] = [] } end @@ -42,26 +48,36 @@ def pins_by_class klass # @return [Hash{String => Array}] def include_references + # @param h [String] + # @param k [Array] @include_references ||= Hash.new { |h, k| h[k] = [] } end # @return [Hash{String => Array}] def include_reference_pins + # @param h [String] + # @param k [Array] @include_reference_pins ||= Hash.new { |h, k| h[k] = [] } end # @return [Hash{String => Array}] def extend_references + # @param h [String] + # @param k [Array] @extend_references ||= Hash.new { |h, k| h[k] = [] } end # @return [Hash{String => Array}] def prepend_references + # @param h [String] + # @param k [Array] @prepend_references ||= Hash.new { |h, k| h[k] = [] } end # @return [Hash{String => Array}] def superclass_references + # @param h [String] + # @param k [Array] @superclass_references ||= Hash.new { |h, k| h[k] = [] } end @@ -99,12 +115,18 @@ def catalog new_pins @pin_select_cache = {} pins.concat new_pins set = new_pins.to_set + # @param k [String] + # @param v [Set] set.classify(&:class) - .map { |k, v| pin_class_hash[k].concat v.to_a } + .map { |k, v| pin_class_hash[k].concat v.to_a } + # @param k [String] + # @param v [Set] set.classify(&:namespace) - .map { |k, v| namespace_hash[k].concat v.to_a } + .map { |k, v| namespace_hash[k].concat v.to_a } + # @param k [String] + # @param v [Set] set.classify(&:path) - .map { |k, v| path_pin_hash[k].concat v.to_a } + .map { |k, v| path_pin_hash[k].concat v.to_a } @namespaces = path_pin_hash.keys.compact.to_set map_references Pin::Reference::Include, include_references map_references Pin::Reference::Prepend, prepend_references @@ -115,11 +137,12 @@ def catalog new_pins end # @generic T - # @param klass [Class] - # @param hash [Hash{String => T}] + # @param klass [Class>] + # @param hash [Hash{String => generic}] # # @return [void] def map_references klass, hash + # @param pin [generic] pins_by_class(klass).each do |pin| hash[pin.namespace].push pin end @@ -127,6 +150,7 @@ def map_references klass, hash # @return [void] def map_overrides + # @param ovr [Pin::Reference::Override] pins_by_class(Pin::Reference::Override).each do |ovr| logger.debug { "ApiMap::Index#map_overrides: Looking at override #{ovr} for #{ovr.name}" } pins = path_pin_hash[ovr.name] diff --git a/lib/solargraph/api_map/source_to_yard.rb b/lib/solargraph/api_map/source_to_yard.rb index ccbed3eb6..b45754d80 100644 --- a/lib/solargraph/api_map/source_to_yard.rb +++ b/lib/solargraph/api_map/source_to_yard.rb @@ -32,11 +32,13 @@ def rake_yard store next end if pin.type == :class + # @param obj [YARD::CodeObjects::RootObject] code_object_map[pin.path] ||= YARD::CodeObjects::ClassObject.new(root_code_object, pin.path) { |obj| next if pin.location.nil? || pin.location.filename.nil? obj.add_file(pin.location.filename, pin.location.range.start.line, !pin.comments.empty?) } else + # @param obj [YARD::CodeObjects::RootObject] code_object_map[pin.path] ||= YARD::CodeObjects::ModuleObject.new(root_code_object, pin.path) { |obj| next if pin.location.nil? || pin.location.filename.nil? obj.add_file(pin.location.filename, pin.location.range.start.line, !pin.comments.empty?) @@ -65,6 +67,7 @@ def rake_yard store next end + # @param obj [YARD::CodeObjects::RootObject] code_object_map[pin.path] ||= YARD::CodeObjects::MethodObject.new(code_object_at(pin.namespace, YARD::CodeObjects::NamespaceObject), pin.name, pin.scope) { |obj| next if pin.location.nil? || pin.location.filename.nil? obj.add_file pin.location.filename, pin.location.range.start.line diff --git a/lib/solargraph/api_map/store.rb b/lib/solargraph/api_map/store.rb index c41e19c09..32fa8bfd4 100644 --- a/lib/solargraph/api_map/store.rb +++ b/lib/solargraph/api_map/store.rb @@ -17,7 +17,7 @@ def pins index.pins end - # @param pinsets [Array>] + # @param pinsets [Array>] # - pinsets[0] = core Ruby pins # - pinsets[1] = documentation/gem pins # - pinsets[2] = convention pins @@ -60,6 +60,7 @@ def inspect # @return [Enumerable] def get_constants fqns, visibility = [:public] namespace_children(fqns).select { |pin| + # @sg-ignore flow-sensitive typing not smart enough to handle this case !pin.name.empty? && (pin.is_a?(Pin::Namespace) || pin.is_a?(Pin::Constant)) && visibility.include?(pin.visibility) } end @@ -70,6 +71,7 @@ def get_constants fqns, visibility = [:public] # @return [Enumerable] def get_methods fqns, scope: :instance, visibility: [:public] all_pins = namespace_children(fqns).select do |pin| + # @sg-ignore https://github.com/castwide/solargraph/pull/1114 pin.is_a?(Pin::Method) && pin.scope == scope && visibility.include?(pin.visibility) end GemPins.combine_method_pins_by_path(all_pins) @@ -258,7 +260,7 @@ def get_ancestors(fqns) # @param fqns [String] # - # @return [Array] + # @return [Array] def get_ancestor_references(fqns) (get_prepends(fqns) + get_includes(fqns) + [get_superclass(fqns)]).compact end @@ -275,7 +277,7 @@ def index @indexes.last end - # @param pinsets [Array>] + # @param pinsets [Array>] # # @return [void] def catalog pinsets @@ -296,6 +298,9 @@ def catalog pinsets # @return [Hash{::Array(String, String) => ::Array}] def fqns_pins_map + # @param h [Hash{::Array(String, String) => ::Array}] + # @param base [String] + # @param name [String] @fqns_pins_map ||= Hash.new do |h, (base, name)| value = namespace_children(base).select { |pin| pin.name == name && pin.is_a?(Pin::Namespace) } h[[base, name]] = value diff --git a/lib/solargraph/complex_type.rb b/lib/solargraph/complex_type.rb index 669a66900..555d60947 100644 --- a/lib/solargraph/complex_type.rb +++ b/lib/solargraph/complex_type.rb @@ -324,6 +324,7 @@ def parse *strings, partial: false paren_stack = 0 base = String.new subtype_string = String.new + # @param char [String] type_string&.each_char do |char| if char == '=' #raise ComplexTypeError, "Invalid = in type #{type_string}" unless curly_stack > 0 diff --git a/lib/solargraph/complex_type/type_methods.rb b/lib/solargraph/complex_type/type_methods.rb index d8d4fc7d7..ead1559af 100644 --- a/lib/solargraph/complex_type/type_methods.rb +++ b/lib/solargraph/complex_type/type_methods.rb @@ -190,6 +190,7 @@ def scope # @param other [Object] def == other return false unless self.class == other.class + # @sg-ignore https://github.com/castwide/solargraph/pull/1114 tag == other.tag end diff --git a/lib/solargraph/complex_type/unique_type.rb b/lib/solargraph/complex_type/unique_type.rb index 05a585dcf..e490bff35 100644 --- a/lib/solargraph/complex_type/unique_type.rb +++ b/lib/solargraph/complex_type/unique_type.rb @@ -138,11 +138,17 @@ def determine_non_literal_name def eql?(other) self.class == other.class && + # @sg-ignore https://github.com/castwide/solargraph/pull/1114 @name == other.name && + # @sg-ignore https://github.com/castwide/solargraph/pull/1114 @key_types == other.key_types && + # @sg-ignore https://github.com/castwide/solargraph/pull/1114 @subtypes == other.subtypes && + # @sg-ignore https://github.com/castwide/solargraph/pull/1114 @rooted == other.rooted? && + # @sg-ignore https://github.com/castwide/solargraph/pull/1114 @all_params == other.all_params && + # @sg-ignore https://github.com/castwide/solargraph/pull/1114 @parameters_type == other.parameters_type end diff --git a/lib/solargraph/diagnostics/rubocop_helpers.rb b/lib/solargraph/diagnostics/rubocop_helpers.rb index f6f4c82c8..fc458956e 100644 --- a/lib/solargraph/diagnostics/rubocop_helpers.rb +++ b/lib/solargraph/diagnostics/rubocop_helpers.rb @@ -20,9 +20,11 @@ def require_rubocop(version = nil) gem_lib_path = File.join(gem_path, 'lib') $LOAD_PATH.unshift(gem_lib_path) unless $LOAD_PATH.include?(gem_lib_path) rescue Gem::MissingSpecVersionError => e + # @type [Array] + specs = e.specs raise InvalidRubocopVersionError, "could not find '#{e.name}' (#{e.requirement}) - "\ - "did find: [#{e.specs.map { |s| s.version.version }.join(', ')}]" + "did find: [#{specs.map { |s| s.version.version }.join(', ')}]" end require 'rubocop' end @@ -36,6 +38,7 @@ def generate_options filename, code args = ['-f', 'j', '--force-exclusion', filename] base_options = RuboCop::Options.new options, paths = base_options.parse(args) + # @sg-ignore options[:stdin] = code [options, paths] end diff --git a/lib/solargraph/doc_map.rb b/lib/solargraph/doc_map.rb index 05f2f1647..96fa13acd 100644 --- a/lib/solargraph/doc_map.rb +++ b/lib/solargraph/doc_map.rb @@ -358,13 +358,16 @@ def change_gemspec_version gemspec, version # @return [Array] def fetch_dependencies gemspec # @param spec [Gem::Dependency] + # @param deps [Set] only_runtime_dependencies(gemspec).each_with_object(Set.new) do |spec, deps| Solargraph.logger.info "Adding #{spec.name} dependency for #{gemspec.name}" dep = Gem.loaded_specs[spec.name] # @todo is next line necessary? + # @sg-ignore Unresolved call to requirement on Gem::Dependency dep ||= Gem::Specification.find_by_name(spec.name, spec.requirement) deps.merge fetch_dependencies(dep) if deps.add?(dep) rescue Gem::MissingSpecError + # @sg-ignore Unresolved call to requirement on Gem::Dependency Solargraph.logger.warn "Gem dependency #{spec.name} #{spec.requirement} for #{gemspec.name} not found in RubyGems." end.to_a end diff --git a/lib/solargraph/equality.rb b/lib/solargraph/equality.rb index 0667efacd..f8c50ff31 100644 --- a/lib/solargraph/equality.rb +++ b/lib/solargraph/equality.rb @@ -12,6 +12,7 @@ module Equality # @return [Boolean] def eql?(other) self.class.eql?(other.class) && + # @sg-ignore https://github.com/castwide/solargraph/pull/1114 equality_fields.eql?(other.equality_fields) end diff --git a/lib/solargraph/gem_pins.rb b/lib/solargraph/gem_pins.rb index a193a8a39..1c4330389 100644 --- a/lib/solargraph/gem_pins.rb +++ b/lib/solargraph/gem_pins.rb @@ -27,6 +27,8 @@ def self.combine_method_pins_by_path(pins) def self.combine_method_pins(*pins) # @type [Pin::Method, nil] combined_pin = nil + # @param memo [Pin::Method, nil] + # @param pin [Pin::Method] out = pins.reduce(combined_pin) do |memo, pin| next pin if memo.nil? if memo == pin && memo.source != :combined @@ -63,6 +65,7 @@ def self.combine(yard_pins, rbs_pins) next yard_pin unless rbs_pin && yard_pin.class == Pin::Method unless rbs_pin + # @sg-ignore https://github.com/castwide/solargraph/pull/1114 logger.debug { "GemPins.combine: No rbs pin for #{yard_pin.path} - using YARD's '#{yard_pin.inspect} (return_type=#{yard_pin.return_type}; signatures=#{yard_pin.signatures})" } next yard_pin end diff --git a/lib/solargraph/language_server/host.rb b/lib/solargraph/language_server/host.rb index 53da20175..b228bdba6 100644 --- a/lib/solargraph/language_server/host.rb +++ b/lib/solargraph/language_server/host.rb @@ -504,6 +504,7 @@ def locate_pins params name: 'new', scope: :class, location: pin.location, + # @sg-ignore Unresolved call to parameters on Solargraph::Pin::Base parameters: pin.parameters, return_type: ComplexType.try_parse(params['data']['path']), comments: pin.comments, diff --git a/lib/solargraph/language_server/message/text_document/formatting.rb b/lib/solargraph/language_server/message/text_document/formatting.rb index 821de7ffc..d67a0b414 100644 --- a/lib/solargraph/language_server/message/text_document/formatting.rb +++ b/lib/solargraph/language_server/message/text_document/formatting.rb @@ -18,6 +18,7 @@ def process require_rubocop(config['version']) options, paths = ::RuboCop::Options.new.parse(args) + # @sg-ignore Unresolved call to []= options[:stdin] = original # Ensure only one instance of RuboCop::Runner is running at @@ -28,6 +29,7 @@ def process ::RuboCop::Runner.new(options, ::RuboCop::ConfigStore.new).run(paths) end end + # @sg-ignore Unresolved call to []= result = options[:stdin] log_corrections(corrections) diff --git a/lib/solargraph/location.rb b/lib/solargraph/location.rb index 713b4fef1..df92668bf 100644 --- a/lib/solargraph/location.rb +++ b/lib/solargraph/location.rb @@ -71,6 +71,7 @@ def self.from_node(node) # @param other [BasicObject] def == other return false unless other.is_a?(Location) + # @sg-ignore https://github.com/castwide/solargraph/pull/1114 filename == other.filename and range == other.range end diff --git a/lib/solargraph/parser/parser_gem/node_processors/and_node.rb b/lib/solargraph/parser/parser_gem/node_processors/and_node.rb index d3485af7c..a761ae38c 100644 --- a/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +++ b/lib/solargraph/parser/parser_gem/node_processors/and_node.rb @@ -11,6 +11,7 @@ def process process_children position = get_node_start_position(node) + # @sg-ignore https://github.com/castwide/solargraph/pull/1114 enclosing_breakable_pin = pins.select{|pin| pin.is_a?(Pin::Breakable) && pin.location.range.contain?(position)}.last FlowSensitiveTyping.new(locals, enclosing_breakable_pin).process_and(node) end diff --git a/lib/solargraph/parser/parser_gem/node_processors/send_node.rb b/lib/solargraph/parser/parser_gem/node_processors/send_node.rb index 645baf00f..e63a23abc 100644 --- a/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +++ b/lib/solargraph/parser/parser_gem/node_processors/send_node.rb @@ -231,6 +231,7 @@ def process_module_function closure: cm, name: ivar.name, comments: ivar.comments, + # @sg-ignore https://github.com/castwide/solargraph/pull/1114 assignment: ivar.assignment, source: :parser ) @@ -239,6 +240,7 @@ def process_module_function closure: mm, name: ivar.name, comments: ivar.comments, + # @sg-ignore https://github.com/castwide/solargraph/pull/1114 assignment: ivar.assignment, source: :parser ) diff --git a/lib/solargraph/pin/base.rb b/lib/solargraph/pin/base.rb index 511c7deb7..57d083453 100644 --- a/lib/solargraph/pin/base.rb +++ b/lib/solargraph/pin/base.rb @@ -259,6 +259,7 @@ def rbs_location? def assert_same_macros(other) return unless self.source == :yardoc && other.source == :yardoc assert_same_count(other, :macros) + # @param [YARD::Tags::MacroDirective] assert_same_array_content(other, :macros) { |macro| macro.tag.name } end @@ -466,6 +467,7 @@ def nearly? other # @param other [Object] def == other return false unless nearly? other + # @sg-ignore Should add more explicit type check on other comments == other.comments && location == other.location end diff --git a/lib/solargraph/pin/base_variable.rb b/lib/solargraph/pin/base_variable.rb index da1f15cb2..93b568647 100644 --- a/lib/solargraph/pin/base_variable.rb +++ b/lib/solargraph/pin/base_variable.rb @@ -106,6 +106,7 @@ def probe api_map # @param other [Object] def == other return false unless super + # @sg-ignore Should add type check on other assignment == other.assignment end diff --git a/lib/solargraph/pin/block.rb b/lib/solargraph/pin/block.rb index 227bc0873..0c6ecd258 100644 --- a/lib/solargraph/pin/block.rb +++ b/lib/solargraph/pin/block.rb @@ -54,6 +54,7 @@ def typify_parameters(api_map) locals = clip.locals - [self] meths = chain.define(api_map, closure, locals) # @todo Convert logic to use signatures + # @param meth [Pin::Method] meths.each do |meth| next if meth.block.nil? diff --git a/lib/solargraph/pin/callable.rb b/lib/solargraph/pin/callable.rb index 207c2619b..edbc3f941 100644 --- a/lib/solargraph/pin/callable.rb +++ b/lib/solargraph/pin/callable.rb @@ -67,6 +67,8 @@ def generics # @return [Array] def choose_parameters(other) raise "Trying to combine two pins with different arities - \nself =#{inspect}, \nother=#{other.inspect}, \n\n self.arity=#{self.arity}, \nother.arity=#{other.arity}" if other.arity != arity + # @param param [Pin::Parameter] + # @param other_param [Pin::Parameter] parameters.zip(other.parameters).map do |param, other_param| if param.nil? && other_param.block? other_param diff --git a/lib/solargraph/pin/method.rb b/lib/solargraph/pin/method.rb index 011f096f6..86bf1cd09 100644 --- a/lib/solargraph/pin/method.rb +++ b/lib/solargraph/pin/method.rb @@ -34,14 +34,18 @@ 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{Array => Array}] by_arity = {} signature_pins.each do |signature_pin| by_arity[signature_pin.arity] ||= [] by_arity[signature_pin.arity] << signature_pin end by_arity.transform_values! do |same_arity_pins| + # @param memo [Pin::Signature, nil] + # @param signature [Pin::Signature] same_arity_pins.reduce(nil) do |memo, signature| next signature if memo.nil? memo.combine_with(signature) @@ -88,6 +92,7 @@ def combine_with(other, attrs = {}) end new_attrs = { visibility: combine_visibility(other), + # @sg-ignore https://github.com/castwide/solargraph/pull/1050 explicit: explicit? || other.explicit?, block: combine_blocks(other), node: choose_node(other, :node), @@ -376,11 +381,14 @@ def attribute? @attribute end - # @parm other [Method] + # @parm other [self] def nearly? other super && + # @sg-ignore https://github.com/castwide/solargraph/pull/1050 parameters == other.parameters && + # @sg-ignore https://github.com/castwide/solargraph/pull/1050 scope == other.scope && + # @sg-ignore https://github.com/castwide/solargraph/pull/1050 visibility == other.visibility end @@ -392,9 +400,12 @@ def probe api_map def overloads # Ignore overload tags with nil parameters. If it's not an array, the # tag's source is likely malformed. + + # @param tag [YARD::Tags::OverloadTag] @overloads ||= docstring.tags(:overload).select(&:parameters).map do |tag| Pin::Signature.new( generics: generics, + # @param src [Array(String, String)] parameters: tag.parameters.map do |src| name, decl = parse_overload_param(src.first) Pin::Parameter.new( @@ -507,6 +518,7 @@ def clean_param name # # @return [ComplexType] def param_type_from_name(tag, name) + # @param t [YARD::Tags::Tag] param = tag.tags(:param).select { |t| t.name == name }.first return ComplexType::UNDEFINED unless param ComplexType.try_parse(*param.types) @@ -522,8 +534,12 @@ def generate_complex_type # @param api_map [ApiMap] # @return [ComplexType, nil] def see_reference api_map + # This should actually be an intersection type + # @param ref [YARD::Tags::Tag, Solargraph::Yard::Tags::RefTag] docstring.ref_tags.each do |ref| + # @sg-ignore ref should actually be an intersection type next unless ref.tag_name == 'return' && ref.owner + # @sg-ignore ref should actually be an intersection type result = resolve_reference(ref.owner.to_s, api_map) return result unless result.nil? end diff --git a/lib/solargraph/pin/parameter.rb b/lib/solargraph/pin/parameter.rb index 947513689..91c205921 100644 --- a/lib/solargraph/pin/parameter.rb +++ b/lib/solargraph/pin/parameter.rb @@ -232,8 +232,12 @@ def typify_method_param api_map # @param skip [::Array] # @return [::Array] def see_reference heredoc, api_map, skip = [] + # This should actually be an intersection type + # @param ref [YARD::Tags::Tag, Solargraph::Yard::Tags::RefTag] heredoc.ref_tags.each do |ref| + # @sg-ignore ref should actually be an intersection type next unless ref.tag_name == 'param' && ref.owner + # @sg-ignore ref should actually be an intersection type result = resolve_reference(ref.owner.to_s, api_map, skip) return result unless result.nil? end diff --git a/lib/solargraph/pin/search.rb b/lib/solargraph/pin/search.rb index f92978a35..0f9883b65 100644 --- a/lib/solargraph/pin/search.rb +++ b/lib/solargraph/pin/search.rb @@ -42,6 +42,9 @@ def do_query Result.new(match, pin) if match > 0.7 end .compact + # @param a [self] + # @param b [self] + # @sg-ignore https://github.com/castwide/solargraph/pull/1050 .sort { |a, b| b.match <=> a.match } .map(&:pin) end diff --git a/lib/solargraph/position.rb b/lib/solargraph/position.rb index 1197038ef..eed62561b 100644 --- a/lib/solargraph/position.rb +++ b/lib/solargraph/position.rb @@ -111,6 +111,7 @@ def self.normalize object def == other return false unless other.is_a?(Position) + # @sg-ignore https://github.com/castwide/solargraph/pull/1114 line == other.line and character == other.character end end diff --git a/lib/solargraph/range.rb b/lib/solargraph/range.rb index 7a9bc0e30..86452d646 100644 --- a/lib/solargraph/range.rb +++ b/lib/solargraph/range.rb @@ -27,9 +27,12 @@ def initialize start, ending # @param other [BasicObject] def <=>(other) return nil unless other.is_a?(Range) + # @sg-ignore https://github.com/castwide/solargraph/pull/1114 if start == other.start + # @sg-ignore https://github.com/castwide/solargraph/pull/1114 ending <=> other.ending else + # @sg-ignore https://github.com/castwide/solargraph/pull/1114 start <=> other.start end end @@ -98,6 +101,7 @@ def self.from_expr expr def == other return false unless other.is_a?(Range) + # @sg-ignore https://github.com/castwide/solargraph/pull/1114 start == other.start && ending == other.ending end diff --git a/lib/solargraph/rbs_map/conversions.rb b/lib/solargraph/rbs_map/conversions.rb index 3e777f726..54bca0f73 100644 --- a/lib/solargraph/rbs_map/conversions.rb +++ b/lib/solargraph/rbs_map/conversions.rb @@ -65,6 +65,7 @@ def convert_decl_to_pin decl, closure # STDERR.puts "Skipping interface #{decl.name.relative!}" interface_decl_to_pin decl, closure when RBS::AST::Declarations::TypeAlias + # @sg-ignore https://github.com/castwide/solargraph/pull/1114 type_aliases[decl.name.to_s] = decl when RBS::AST::Declarations::Module module_decl_to_pin decl @@ -426,6 +427,7 @@ def method_def_to_pin decl, closure, context # @param pin [Pin::Method] # @return [void] def method_def_to_sigs decl, pin + # @param overload [RBS::AST::Members::MethodDefinition::Overload] decl.overloads.map do |overload| type_location = location_decl_to_pin_location(overload.method_type.location) generics = overload.method_type.type_params.map(&:name).map(&:to_s) @@ -466,12 +468,16 @@ def parts_of_function type, pin parameters = [] arg_num = -1 type.type.required_positionals.each do |param| + # @sg-ignore RBS generic type understanding issue name = param.name ? param.name.to_s : "arg_#{arg_num += 1}" + # @sg-ignore RBS generic type understanding issue parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin, return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted, source: :rbs, type_location: type_location) end type.type.optional_positionals.each do |param| + # @sg-ignore RBS generic type understanding issue name = param.name ? param.name.to_s : "arg_#{arg_num += 1}" parameters.push Solargraph::Pin::Parameter.new(decl: :optarg, name: name, closure: pin, + # @sg-ignore RBS generic type understanding issue return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted, type_location: type_location, source: :rbs) @@ -489,18 +495,23 @@ def parts_of_function type, pin return_type: rest_positional_type,) end type.type.trailing_positionals.each do |param| + # @sg-ignore RBS generic type understanding issue name = param.name ? param.name.to_s : "arg_#{arg_num += 1}" parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin, source: :rbs, type_location: type_location) end type.type.required_keywords.each do |orig, param| + # @sg-ignore RBS generic type understanding issue name = orig ? orig.to_s : "arg_#{arg_num += 1}" parameters.push Solargraph::Pin::Parameter.new(decl: :kwarg, name: name, closure: pin, + # @sg-ignore RBS generic type understanding issue return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted, source: :rbs, type_location: type_location) end type.type.optional_keywords.each do |orig, param| + # @sg-ignore RBS generic type understanding issue name = orig ? orig.to_s : "arg_#{arg_num += 1}" parameters.push Solargraph::Pin::Parameter.new(decl: :kwoptarg, name: name, closure: pin, + # @sg-ignore RBS generic type understanding issue return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted, type_location: type_location, source: :rbs) @@ -792,7 +803,9 @@ def other_type_to_tag type # @param namespace [Pin::Namespace] # @return [void] def add_mixins decl, namespace + # @param mixin [RBS::AST::Members::Include, RBS::AST::Members::Members::Extend, RBS::AST::Members::Members::Prepend] decl.each_mixin do |mixin| + # @todo are we handling prepend correctly? klass = mixin.is_a?(RBS::AST::Members::Include) ? Pin::Reference::Include : Pin::Reference::Extend type = build_type(mixin.name, mixin.args) generic_values = type.all_params.map(&:to_s) diff --git a/lib/solargraph/shell.rb b/lib/solargraph/shell.rb index 046a74296..bd0e5026d 100755 --- a/lib/solargraph/shell.rb +++ b/lib/solargraph/shell.rb @@ -79,6 +79,7 @@ def config(directory = '.') conf['extensions'].push m end end + # @param file [File] File.open(File.join(directory, '.solargraph.yml'), 'w') do |file| file.puts conf.to_yaml end @@ -273,6 +274,7 @@ def pin path else pins = api_map.get_path_pins path end + # @type [Hash{Symbol => Pin::Base}] references = {} pin = pins.first case pin diff --git a/lib/solargraph/source/chain.rb b/lib/solargraph/source/chain.rb index c08d04878..f7a03b552 100644 --- a/lib/solargraph/source/chain.rb +++ b/lib/solargraph/source/chain.rb @@ -264,6 +264,8 @@ def infer_from_definitions pins, context, api_map, locals ComplexType::UNDEFINED elsif types.length > 1 # Move nil to the end by convention + + # @param a [ComplexType::UniqueType] sorted = types.flat_map(&:items).sort { |a, _| a.tag == 'nil' ? 1 : 0 } ComplexType.new(sorted.uniq) else diff --git a/lib/solargraph/source/chain/call.rb b/lib/solargraph/source/chain/call.rb index 24d10656d..194771c1f 100644 --- a/lib/solargraph/source/chain/call.rb +++ b/lib/solargraph/source/chain/call.rb @@ -266,6 +266,7 @@ def yield_pins api_map, name_pin method_pin = find_method_pin(name_pin) return [] unless method_pin + # @param signature_pin [Pin::Signature] method_pin.signatures.map(&:block).compact.map do |signature_pin| return_type = signature_pin.return_type.qualify(api_map, *name_pin.gates) signature_pin.proxy(return_type) diff --git a/lib/solargraph/source/chain/if.rb b/lib/solargraph/source/chain/if.rb index c14d00ddf..3a7fa0ca9 100644 --- a/lib/solargraph/source/chain/if.rb +++ b/lib/solargraph/source/chain/if.rb @@ -8,7 +8,7 @@ def word '' end - # @param links [::Array] + # @param links [::Array] def initialize links @links = links end diff --git a/lib/solargraph/source/chain/link.rb b/lib/solargraph/source/chain/link.rb index bcd9eb196..344f7affd 100644 --- a/lib/solargraph/source/chain/link.rb +++ b/lib/solargraph/source/chain/link.rb @@ -38,7 +38,7 @@ def constant? # @param api_map [ApiMap] # @param name_pin [Pin::Base] - # @param locals [::Enumerable] + # @param locals [::Array] # @return [::Array] def resolve api_map, name_pin, locals [] diff --git a/lib/solargraph/source/chain/or.rb b/lib/solargraph/source/chain/or.rb index 1e3a70f40..9264d4107 100644 --- a/lib/solargraph/source/chain/or.rb +++ b/lib/solargraph/source/chain/or.rb @@ -8,7 +8,7 @@ def word '' end - # @param links [::Array] + # @param links [::Array] def initialize links @links = links end diff --git a/lib/solargraph/type_checker.rb b/lib/solargraph/type_checker.rb index 4600767b5..996830c4d 100644 --- a/lib/solargraph/type_checker.rb +++ b/lib/solargraph/type_checker.rb @@ -460,7 +460,9 @@ def kwarg_problems_for sig, argchain, api_map, closure_pin, locals, location, pi else ptype = data[:qualified] unless ptype.undefined? + # @sg-ignore https://github.com/castwide/solargraph/pull/1127 argtype = argchain.infer(api_map, closure_pin, locals) + # @sg-ignore Unresolved call to defined? if argtype.defined? && ptype && !any_types_match?(api_map, ptype, argtype) result.push Problem.new(location, "Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}") end diff --git a/lib/solargraph/yard_map/mapper/to_method.rb b/lib/solargraph/yard_map/mapper/to_method.rb index d8e3b8b43..0838b9f4f 100644 --- a/lib/solargraph/yard_map/mapper/to_method.rb +++ b/lib/solargraph/yard_map/mapper/to_method.rb @@ -11,7 +11,7 @@ module ToMethod ["Rails::Engine", :class, "find_root_with_flag"] => :public } - # @param code_object [YARD::CodeObjects::Base] + # @param code_object [YARD::CodeObjects::MethodObject] # @param name [String, nil] # @param scope [Symbol, nil] # @param visibility [Symbol, nil] @@ -85,6 +85,7 @@ def get_parameters code_object, location, comments, pin # HACK: Skip `nil` and `self` parameters that are sometimes emitted # for methods defined in C # See https://github.com/castwide/solargraph/issues/345 + # @sg-ignore https://github.com/castwide/solargraph/pull/1114 code_object.parameters.select { |a| a[0] && a[0] != 'self' }.map do |a| Solargraph::Pin::Parameter.new( location: location, diff --git a/lib/solargraph/yard_map/to_method.rb b/lib/solargraph/yard_map/to_method.rb index 3ecb7ac26..010db89a5 100644 --- a/lib/solargraph/yard_map/to_method.rb +++ b/lib/solargraph/yard_map/to_method.rb @@ -15,6 +15,7 @@ def get_parameters code_object, location, comments # HACK: Skip `nil` and `self` parameters that are sometimes emitted # for methods defined in C # See https://github.com/castwide/solargraph/issues/345 + # @sg-ignore https://github.com/castwide/solargraph/pull/1114 code_object.parameters.select { |a| a[0] && a[0] != 'self' }.map do |a| Solargraph::Pin::Parameter.new( location: location, @@ -57,7 +58,7 @@ def arg_type a include Helpers - # @param code_object [YARD::CodeObjects::Base] + # @param code_object [YARD::CodeObjects::MethodObject] # @param name [String, nil] # @param scope [Symbol, nil] # @param visibility [Symbol, nil] diff --git a/solargraph.gemspec b/solargraph.gemspec index 49265f9c6..0414f27d8 100755 --- a/solargraph.gemspec +++ b/solargraph.gemspec @@ -2,6 +2,7 @@ $LOAD_PATH.unshift File.dirname(__FILE__) + '/lib' require 'solargraph/version' require 'date' +# @param s [Gem::Specification] Gem::Specification.new do |s| s.name = 'solargraph' s.version = Solargraph::VERSION From 1594b958e2362d2a03c0e31d6bb178327cc7d6f2 Mon Sep 17 00:00:00 2001 From: Vince Broz Date: Fri, 28 Nov 2025 16:15:19 -0500 Subject: [PATCH 106/106] Annotations needed after https://github.com/castwide/solargraph/pull/1130 --- lib/solargraph/api_map/store.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/solargraph/api_map/store.rb b/lib/solargraph/api_map/store.rb index 32fa8bfd4..f86080d12 100644 --- a/lib/solargraph/api_map/store.rb +++ b/lib/solargraph/api_map/store.rb @@ -247,6 +247,7 @@ def get_ancestors(fqns) # Add includes, prepends, and extends [get_includes(current), get_prepends(current), get_extends(current)].each do |refs| next if refs.nil? + # @param ref [String] refs.map(&:parametrized_tag).map(&:to_s).each do |ref| next if ref.nil? || ref.empty? || visited.include?(ref) ancestors << ref