Skip to content
Closed
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
10 changes: 8 additions & 2 deletions lib/solargraph/doc_map.rb
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ def deserialize_yard_pin_cache gemspec
end

# @param gemspec [Gem::Specification]
# @return [void]
# @return [Array<Pin::Base>, nil]
def deserialize_combined_pin_cache gemspec
unless combined_pins_in_memory[[gemspec.name, gemspec.version]].nil?
return combined_pins_in_memory[[gemspec.name, gemspec.version]]
Expand Down Expand Up @@ -270,7 +270,13 @@ def deserialize_combined_pin_cache gemspec
combined_pins_in_memory[[gemspec.name, gemspec.version]]
else
logger.debug { "Pins not yet cached for #{gemspec.name}:#{gemspec.version}" }
nil
# Not stored in combined_pins_in_memory: that index is process-wide
# and keyed only by name and version, so a provisional set there would
# outlive the build that supersedes it. The gemspec stays on the
# uncached lists the two deserialize calls above pushed it onto.
fallback = rbs_map.fallback_pins
logger.debug { "Using fallback RBS pins for #{gemspec.name}:#{gemspec.version}" } if fallback
fallback
end
end

Expand Down
11 changes: 11 additions & 0 deletions lib/solargraph/rbs_map.rb
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,17 @@ def resolved?
@resolved
end

# A standalone substitute for the combined pins of this gem, for a
# caller that needs something before a combined cache entry exists.
# A base RbsMap has none to offer: a combined entry merges these pins
# with separately-cached YARD pins, and dropping the YARD half is not
# safe in general.
#
# @return [Array<Pin::Base>, nil]
def fallback_pins
nil
end

# @return [RBS::Repository]
def repository
@repository ||= RBS::Repository.new(no_stdlib: false).tap do |repo|
Expand Down
8 changes: 8 additions & 0 deletions lib/solargraph/rbs_map/stdlib_map.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ def resolve_dependencies?
true
end

# Stdlib pins need no merge with YARD pins, so they stand alone
# as a substitute for a combined cache entry.
#
# @return [Array<Pin::Base>, nil]
def fallback_pins
pins if resolved?
end

# @param library [String]
# @return [StdlibMap]
def self.load library
Expand Down
27 changes: 27 additions & 0 deletions spec/doc_map_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,33 @@
end
end

context 'without a combined pin cache entry for a gem' do
let(:pre_cache) { false }

# A version nothing will ever have cached on disk, so the read path
# takes the uncached branch however much of the suite ran first.
def uncached_gemspec name
Gem::Specification.new(name, '999.0.0')
end

it 'serves RBS stdlib pins as a fallback' do
pins = doc_map.send(:deserialize_combined_pin_cache, uncached_gemspec('logger'))
expect(pins.map(&:path)).to include('Logger#info')
end

it 'does not record the fallback as if it were a real build' do
gemspec = uncached_gemspec('logger')
doc_map.send(:deserialize_combined_pin_cache, gemspec)
expect(doc_map.combined_pins_in_memory).not_to have_key([gemspec.name, gemspec.version])
expect(doc_map.uncached_gemspecs).to include(gemspec)
end

it 'has no fallback for a gem outside the RBS stdlib' do
pins = doc_map.send(:deserialize_combined_pin_cache, uncached_gemspec('backport'))
expect(pins).to be_nil
end
end

context 'with convention' do
let(:pre_cache) { false }

Expand Down
12 changes: 12 additions & 0 deletions spec/rbs_map/stdlib_map_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,18 @@
end
end

it 'offers its pins as a fallback when resolved' do
map = described_class.load('yaml')
expect(map.fallback_pins).not_to be_empty
expect(map.fallback_pins).to eq(map.pins)
end

it 'offers no fallback pins when unresolved' do
map = described_class.new('not_a_stdlib_library')
expect(map).not_to be_resolved
expect(map.fallback_pins).to be_nil
end

it 'pins are marked as coming from RBS parsing' do
map = Solargraph::RbsMap::StdlibMap.load('yaml')
store = Solargraph::ApiMap::Store.new(map.pins)
Expand Down
7 changes: 7 additions & 0 deletions spec/rbs_map_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@
expect(rbs_map).not_to be_resolved
end

it 'offers no fallback pins for a gem outside the RBS stdlib' do
spec = Gem::Specification.find_by_name('rbs')
rbs_map = described_class.from_gemspec(spec, nil, nil)
expect(rbs_map).to be_resolved
expect(rbs_map.fallback_pins).to be_nil
end

it 'fails if it does not find data from name' do
rbs_map = described_class.new('lskdflaksdfjl')
expect(rbs_map.pins).to be_empty
Expand Down
Loading