Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ coverage
/Makefile
/.pryrc
/.rspec-local
vendor/cache
12 changes: 6 additions & 6 deletions lib/solargraph/api_map.rb
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,12 @@ 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
store.qualify_superclass fq_sub_tag
end

private

# A hash of source maps with filename keys.
Expand Down Expand Up @@ -804,12 +810,6 @@ def path_macros
@path_macros ||= {}
end

# @param fq_sub_tag [String]
# @return [String, nil]
def qualify_superclass fq_sub_tag
store.qualify_superclass fq_sub_tag
end

# Get the namespace's type (Class or Module).
#
# @param fqns [String] A fully qualified namespace
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,11 +7,11 @@ 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| ['normal', 'typed', 'strict', 'strong'].include?(a) }) || :normal
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
35 changes: 24 additions & 11 deletions lib/solargraph/position.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,21 @@ 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

newline_index = -1
line = -1
last_line_index = 0

while (newline_index = text.index("\n", newline_index + 1)) && line <= position.line
line += 1
break if line == position.line

line_length = newline_index - last_line_index
last_line_index = newline_index
end

last_line_index += 1 if position.line > 0
last_line_index + position.character
end

# Get a numeric offset for the specified text and a position identified
Expand All @@ -75,22 +88,22 @@ def self.line_char_to_offset text, line, character

# Get a position for the specified text and offset.
#
# @raise [InvalidOffsetError] if the offset is outside the text range
#
# @param text [String]
# @param offset [Integer]
# @return [Position]
def self.from_offset text, offset
raise InvalidOffsetError if offset > text.length

cursor = 0
line = 0
character = nil
text.lines.each do |l|
line_length = l.length
char_length = l.chomp.length
if cursor + char_length >= offset
character = offset - cursor
break
end
cursor += line_length
character = offset
newline_index = -1

while (newline_index = text.index("\n", newline_index + 1)) && newline_index < offset
line += 1
character = offset - newline_index - 1
end
character = 0 if character.nil? and (cursor - offset).between?(0, 1)
raise InvalidOffsetError if character.nil?
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion rbs_collection.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
sources:
- type: local
name: shims
path: sig/shims
path: rbs/shims

- type: git
name: ruby/gem_rbs_collection
Expand Down
3 changes: 1 addition & 2 deletions spec/api_map_method_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,7 @@ class B
end

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

context 'with stdlib that has vital dependencies' do
let(:external_requires) { ['yaml'] }
Expand Down
17 changes: 10 additions & 7 deletions spec/language_server/message/extended/check_gem_version_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,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 = Solargraph::LanguageServer::Message::Extended::CheckGemVersion.new(host, {}, current: Gem::Version.new('0.0.1'))
message.process
Expand All @@ -42,13 +46,12 @@
response = data
end
reader.receive host.flush
expect {
action = {
"id" => response['id'],
"result" => response['params']['actions'].first
}
host.receive action
}.not_to raise_error
action = {
"id" => response['id'],
"result" => response['params']['actions'].first
}
host.receive action
expect(Open3).to have_received(:capture2).with('gem update solargraph')
end

it 'uses bundler' do
Expand Down
4 changes: 4 additions & 0 deletions spec/language_server/protocol_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -432,9 +432,13 @@ def bar baz
end

it "handles $/solargraph/documentGems" do
status = instance_double(Process::Status)
allow(status).to receive(:==).with(0).and_return(true)
allow(Open3).to receive(:capture2).with('solargraph', 'gems').and_return(['', status])
@protocol.request '$/solargraph/documentGems', {}
response = @protocol.response
expect(response['error']).to be_nil
expect(Open3).to have_received(:capture2).with('solargraph', 'gems')
end

it "handles textDocument/formatting" do
Expand Down
6 changes: 4 additions & 2 deletions spec/pin/base_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@
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 ''
bench = Solargraph::Bench.new(external_requires: ['yard'])
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
29 changes: 29 additions & 0 deletions spec/position_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,38 @@
expect(orig).to be(norm)
end

it 'finds offset from position' do
text = "\n class Foo\n def bar baz, boo = 'boo'\n end\n end\n "
expect(Solargraph::Position.to_offset(text, Solargraph::Position.new(0, 0))).to eq(0)
expect(Solargraph::Position.to_offset(text, Solargraph::Position.new(0, 4))).to eq(4)
expect(Solargraph::Position.to_offset(text, Solargraph::Position.new(2, 12))).to eq(29)
expect(Solargraph::Position.to_offset(text, Solargraph::Position.new(2, 27))).to eq(44)
expect(Solargraph::Position.to_offset(text, Solargraph::Position.new(3, 8))).to eq(58)
end

it 'constructs position from offset' do
text = "\n class Foo\n def bar baz, boo = 'boo'\n end\n end\n "
expect(Solargraph::Position.from_offset(text, 0)).to eq(Solargraph::Position.new(0, 0))
expect(Solargraph::Position.from_offset(text, 4)).to eq(Solargraph::Position.new(1, 3))
expect(Solargraph::Position.from_offset(text, 29)).to eq(Solargraph::Position.new(2, 12))
expect(Solargraph::Position.from_offset(text, 44)).to eq(Solargraph::Position.new(2, 27))
end

it "raises an error for objects that cannot be normalized" do
expect {
Solargraph::Position.normalize('0, 1')
}.to raise_error(ArgumentError)
end

it 'avoids fencepost errors' do
text = " class Foo\n def bar baz, boo = 'boo'\n end\n end\n "
offset = Solargraph::Position.to_offset(text, Solargraph::Position.new(3, 6))
expect(offset).to eq(67)
end

it 'avoids fencepost errors with multiple blank lines' do
text = " class Foo\n def bar baz, boo = 'boo'\n\n end\n end\n "
offset = Solargraph::Position.to_offset(text, Solargraph::Position.new(4, 6))
expect(offset).to eq(68)
end
end
32 changes: 31 additions & 1 deletion spec/shell_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,37 @@ def bundle_exec(*cmd)
end
end

describe 'pin' do
describe 'pin on a class' do
let(:api_map) { instance_double(Solargraph::ApiMap) }
let(:string_pin) { instance_double(Solargraph::Pin::Namespace, name: 'String') }

before do
allow(Solargraph::ApiMap).to receive(:load_with_cache).and_return(api_map)
allow(Solargraph::Pin::Namespace).to receive(:===).with(string_pin).and_return(true)
allow(string_pin).to receive(:return_type).and_return(Solargraph::ComplexType.parse('String'))
allow(api_map).to receive(:get_path_pins).with('String').and_return([string_pin])
end

context 'with --references option' do
let(:object_pin) { instance_double(Solargraph::Pin::Namespace, name: 'Object') }

before do
allow(Solargraph::Pin::Namespace).to receive(:===).with(object_pin).and_return(true)
allow(api_map).to receive(:qualify_superclass).with('String').and_return('Object')
allow(api_map).to receive(:get_path_pins).with('Object').and_return([object_pin])
end

it 'prints a pin with info' do
out = capture_both do
shell.options = { references: true }
shell.pin('String')
end
expect(out).to include('# Superclass:')
end
end
end

describe 'pin on a method' do
let(:api_map) { instance_double(Solargraph::ApiMap) }
let(:to_s_pin) { instance_double(Solargraph::Pin::Method, return_type: Solargraph::ComplexType.parse('String')) }

Expand Down
11 changes: 0 additions & 11 deletions spec/yard_map/mapper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,6 @@
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
rubocop = Gem::Specification.find_by_name('rubocop')
Solargraph::Yardoc.cache([], rubocop)
Solargraph::Yardoc.load!(rubocop)
pins = Solargraph::YardMap::Mapper.new(YARD::Registry.all).map
pins = pins.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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is slow and doesn't describe how it tests anything different than the spec above it

it 'marks non-explicit methods' do
# Using rspec-expectations because it's a known dependency
rspec = Gem::Specification.find_by_name('rspec-expectations')
Expand Down
Loading