Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/plugins.yml
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ jobs:
# solargraph-rails supports Ruby 3.0+
# This job uses 3.2 due to a problem compiling sqlite3 in earlier versions
ruby-version: '3.2'
bundler-cache: false
bundler-cache: true
# https://github.com/apiology/solargraph/actions/runs/19400815835/job/55508092473?pr=17
rubygems: latest
bundler: latest
Expand Down
17 changes: 17 additions & 0 deletions .github/workflows/rspec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ jobs:
with:
ruby-version: ${{ matrix.ruby-version }}
bundler-cache: true
# Without this pin, ruby/setup-ruby uses whatever bundler ships
# with each matrix Ruby version individually, rather than one
# consistent version across the matrix. Confirmed by removing
# it: stdlib/default-gem resolution changed enough that
# Workspace::Gemspecs#resolve_require('yaml') started returning
# nil, failing spec/api_map_method_spec.rb's YAML test across
# most of the matrix. Keep this in sync with Gemfile.lock's
# BUNDLED WITH version, and with the same pin below.
bundler: 2.5.23
- 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:
Expand Down Expand Up @@ -67,7 +76,15 @@ jobs:
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.4'
# See the matching pin in the rspec matrix job above for why
# this is needed - keep both in sync with Gemfile.lock's
# BUNDLED WITH version.
bundler: 2.5.23
bundler-cache: true
- name: Install gems
run: |
bundle _2.5.23_ install
bundle update rbs # use latest available for this Ruby version
- name: Update types
run: bundle exec rbs collection update
- name: Run tests
Expand Down
6 changes: 6 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ Metrics/PerceivedComplexity:
Max: 40
RSpec/ExampleLength:
Max: 310
# Autocorrect mangles short-style Hash tags with nested generics/parens
# (e.g. Hash{Array(String, Array<String>) => String}) into invalid syntax.
# Confirmed broken through rubocop-yard 1.3.0 (latest as of this writing),
# against yard 0.9.45 (also latest as of this writing).
YARD/CollectionStyle:
Enabled: false

plugins:
- rubocop-rspec
Expand Down
9 changes: 9 additions & 0 deletions lib/solargraph/api_map.rb
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,15 @@ def qualify_superclass fq_sub_tag
store.qualify_superclass fq_sub_tag
end

# @param require_path [String]
#
# @return [Array<Gem::Specification>, nil]
def resolve_require require_path
raise "Unable to resolve require '#{require_path}' without a workspace" if workspace.nil?

Workspace::Gemspecs.new(workspace.directory).resolve_require require_path
Comment thread
apiology marked this conversation as resolved.
end

private

# A hash of source maps with filename keys.
Expand Down
3 changes: 2 additions & 1 deletion lib/solargraph/diagnostics/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ def initialize *args
#
# @param source [Solargraph::Source]
# @param api_map [Solargraph::ApiMap]
# @param workspace [Solargraph::Workspace, nil]
# @return [Array<Hash>]
def diagnose source, api_map
def diagnose source, api_map, workspace: nil
[]
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/solargraph/diagnostics/type_check.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ module Diagnostics
#
class TypeCheck < Base
# @return [Array<Hash>]
def diagnose source, api_map
def diagnose source, api_map, workspace: nil
# return [] unless args.include?('always') || api_map.workspaced?(source.filename)
severity = Diagnostics::Severities::ERROR
level = args.reverse.find { |a| %w[normal typed strict strong].include?(a) } || :normal
# @sg-ignore sensitive typing needs to handle || on nil types
checker = Solargraph::TypeChecker.new(source.filename, api_map: api_map, level: level.to_sym)
checker = Solargraph::TypeChecker.new(source.filename, api_map: api_map, level: level.to_sym, workspace: workspace)
checker.problems
.sort { |a, b| a.location.range.start.line <=> b.location.range.start.line }
.map do |problem|
Expand Down
6 changes: 3 additions & 3 deletions lib/solargraph/workspace/gemspecs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -342,12 +342,12 @@ def preference_map
@preference_map ||= preferences.to_h { |gemspec| [gemspec.name, gemspec] }
end

# @param gemspec [Gem::Specification]
# @param gemspec [Gem::Specification, Bundler::LazySpecification, Bundler::StubSpecification]
#
# @return [Gem::Specification]
def gemspec_or_preference gemspec
return gemspec unless preference_map.key?(gemspec.name)
return gemspec if gemspec.version == preference_map[gemspec.name].version
return to_gem_specification(gemspec) unless preference_map.key?(gemspec.name)
return to_gem_specification(gemspec) if gemspec.version == preference_map[gemspec.name].version

change_gemspec_version gemspec, preference_map[gemspec.name].version
end
Expand Down
20 changes: 18 additions & 2 deletions spec/api_map_method_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,21 @@ class B
end

describe '#get_method_stack' do
let(:out) { StringIO.new }
let(:api_map) { described_class.load_with_cache(Dir.pwd, out) }
let(:api_map) { described_class.load('') }

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
# catalog first so doc_map registers 'yaml' as required before we
# try to cache it - cache_gem is a no-op for gems doc_map doesn't
# yet know it needs
api_map.catalog bench
specs = api_map.resolve_require('yaml')
specs.each { |spec| api_map.cache_gem(spec) }
api_map.catalog bench

expect(method_stack).not_to be_empty
end
end
Expand All @@ -135,6 +142,15 @@ class B
let(:method_stack) { api_map.get_method_stack('Thor', 'desc', scope: :class) }

it 'handles finding Thor.desc' do
# catalog first so doc_map registers 'thor' as required before we
# try to cache it - cache_gem is a no-op for gems doc_map doesn't
# yet know it needs
api_map.catalog bench
specs = api_map.resolve_require('thor')
specs.each { |spec| api_map.cache_gem(spec) }
api_map.catalog bench

# if this fails you may not have an rbs collection installed
expect(method_stack).not_to be_empty
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
end

it 'responds to update actions' do
status = instance_double(Process::Status)
allow(status).to receive(:==).with(0).and_return(true)
allow(Open3).to receive(:capture2).with('gem update solargraph').and_return(['', status])

host = Solargraph::LanguageServer::Host.new
message = described_class.new(host, {}, current: Gem::Version.new('0.0.1'))
message.process
Expand All @@ -52,6 +56,7 @@
}
host.receive action
end.not_to raise_error
expect(Open3).to have_received(:capture2).with('gem update solargraph')
end

it 'uses bundler' do
Expand Down
2 changes: 1 addition & 1 deletion spec/library_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def foo(adapter)
end

it 'returns a Completion' do
library = described_class.new(Solargraph::Workspace.new(Dir.pwd,
library = described_class.new(Solargraph::Workspace.new('',
Solargraph::Workspace::Config.new))
library.attach Solargraph::Source.load_string(%(
require 'backport'
Expand Down
14 changes: 12 additions & 2 deletions spec/pin/base_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,18 @@
end

it 'deals well with known closure combination issue' do
Solargraph::Shell.new.uncache('yard')
api_map = Solargraph::ApiMap.load_with_cache('.', $stderr)
# if this fails you might not have an rbs collection installed
api_map = Solargraph::ApiMap.load ''

# catalog first so doc_map registers 'yard' as required before we
# try to cache it - cache_gem is a no-op for gems doc_map doesn't
# yet know it needs
bench = Solargraph::Bench.new(external_requires: ['yard'])
api_map.catalog bench
spec = Gem::Specification.find_by_name('yard')
api_map.cache_gem(spec)
api_map.catalog bench

pins = api_map.get_method_stack('YARD::Docstring', 'parser', scope: :class)
expect(pins.length).to eq(1)
parser_method_pin = pins.first
Expand Down
4 changes: 3 additions & 1 deletion spec/pin/method_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,9 @@ class Foo
# on type. Let's make sure we combine those with anything else
# found (e.g., additions from the BigDecimal RBS collection)
# without collapsing signatures
api_map = Solargraph::ApiMap.load_with_cache(Dir.pwd, nil)
api_map = Solargraph::ApiMap.load(Dir.pwd)
bench = Solargraph::Bench.new external_requires: ['bigdecimal']
api_map.catalog(bench)
method = api_map.get_method_stack('Integer', '+', scope: :instance).first
expect(method.signatures.count).to be > 3
end
Expand Down
2 changes: 0 additions & 2 deletions spec/position_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# frozen_string_literal: true

describe Solargraph::Position do
it 'normalizes arrays into positions' do
pos = described_class.normalize([0, 1])
Expand Down
11 changes: 9 additions & 2 deletions spec/rbs_map/conversions_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,12 @@ def bar: () -> untyped

context 'with standard loads for solargraph project' do
before :all do # rubocop:disable RSpec/BeforeAfterAll
@api_map = Solargraph::ApiMap.load_with_cache('.')
@api_map = Solargraph::ApiMap.load('.')
gems = %w[parser ast open3]
bench = Solargraph::Bench.new(workspace: @api_map.workspace, external_requires: gems)
@api_map.catalog(bench)
@api_map.cache_all_for_doc_map!
@api_map.catalog(bench)
end

let(:api_map) { @api_map }
Expand Down Expand Up @@ -160,7 +165,9 @@ class Sub < Hash[Symbol, untyped]
if Gem::Version.new(RBS::VERSION) >= Gem::Version.new('3.9.1')
context 'with method pin for Open3.capture2e' do
it 'accepts chdir kwarg' do
api_map = Solargraph::ApiMap.load_with_cache('.', $stdout)
api_map = Solargraph::ApiMap.load('.')
bench = Solargraph::Bench.new(external_requires: ['open3'])
api_map.catalog(bench)

method_pin = api_map.pins.find do |pin|
pin.is_a?(Solargraph::Pin::Method) && pin.path == 'Open3.capture2e'
Expand Down
7 changes: 0 additions & 7 deletions spec/yard_map/mapper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,6 @@ def pins_with require
expect(pins.map(&:return_type).uniq.map(&:to_s)).to eq(['self'])
end

it 'marks correct return type from RuboCop::Options.new' do
# Using rubocop because it's a known dependency
pins = pins_with('rubocop').select { |pin| pin.path == 'RuboCop::Options.new' }
expect(pins.map(&:return_type).uniq.map(&:to_s)).to eq(['self'])
expect(pins.flat_map(&:signatures).map(&:return_type).uniq.map(&:to_s)).to eq(['self'])
end

it 'marks non-explicit methods' do
# Using rspec-expectations because it's a known dependency
pin = pins_with('rspec/expectations').find { |pin| pin.path == 'RSpec::Matchers#expect' }
Expand Down
Loading