diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index cbc69c804..c3fdce6b8 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - ruby-version: ['2.6', '2.7', '3.0', '3.1'] + ruby-version: ['2.6', '2.7', '3.0', '3.3', '3.4', 'head'] steps: - uses: actions/checkout@v3 diff --git a/lib/solargraph/convention.rb b/lib/solargraph/convention.rb index db0faa7cb..056d4013d 100644 --- a/lib/solargraph/convention.rb +++ b/lib/solargraph/convention.rb @@ -9,7 +9,6 @@ module Solargraph module Convention autoload :Base, 'solargraph/convention/base' autoload :Gemfile, 'solargraph/convention/gemfile' - autoload :Rspec, 'solargraph/convention/rspec' autoload :Gemspec, 'solargraph/convention/gemspec' autoload :Rakefile, 'solargraph/convention/rakefile' @@ -43,7 +42,6 @@ def self.for_global(yard_map) register Gemfile register Gemspec - register Rspec register Rakefile end end diff --git a/lib/solargraph/convention/rspec.rb b/lib/solargraph/convention/rspec.rb deleted file mode 100644 index 426e541a7..000000000 --- a/lib/solargraph/convention/rspec.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true - -module Solargraph - module Convention - class Rspec < Base - def local source_map - return EMPTY_ENVIRON unless File.basename(source_map.filename) =~ /_spec\.rb$/ - @environ ||= Environ.new( - requires: ['rspec'], - domains: ['RSpec::Matchers', 'RSpec::ExpectationGroups'], - pins: [ - # This override is necessary due to an erroneous @return tag in - # rspec's YARD documentation. - # @todo The return types have been fixed (https://github.com/rspec/rspec-expectations/pull/1121) - Solargraph::Pin::Reference::Override.method_return('RSpec::Matchers#expect', 'RSpec::Expectations::ExpectationTarget') - ].concat(extras) - ) - end - - private - - def extras - @@extras ||= SourceMap.load_string(%( - def describe(*args); end - def it(*args); end - )).pins - end - end - end -end diff --git a/lib/solargraph/language_server/message/text_document/document_symbol.rb b/lib/solargraph/language_server/message/text_document/document_symbol.rb index 670b99469..19a64cf93 100644 --- a/lib/solargraph/language_server/message/text_document/document_symbol.rb +++ b/lib/solargraph/language_server/message/text_document/document_symbol.rb @@ -6,6 +6,8 @@ class Solargraph::LanguageServer::Message::TextDocument::DocumentSymbol < Solarg def process pins = host.document_symbols params['textDocument']['uri'] info = pins.map do |pin| + next nil unless pin.location&.filename + result = { name: pin.name, containerName: pin.namespace, @@ -17,7 +19,8 @@ def process deprecated: pin.deprecated? } result - end + end.compact + set_result info end end diff --git a/lib/solargraph/parser/rubyvm/class_methods.rb b/lib/solargraph/parser/rubyvm/class_methods.rb index a208f4e8e..2533eb79e 100644 --- a/lib/solargraph/parser/rubyvm/class_methods.rb +++ b/lib/solargraph/parser/rubyvm/class_methods.rb @@ -108,9 +108,13 @@ def is_ast_node? node end def node_range node + if node.nil? + nil + else st = Position.new(node.first_lineno - 1, node.first_column) en = Position.new(node.last_lineno - 1, node.last_column) Range.new(st, en) + end end def recipient_node tree diff --git a/lib/solargraph/pin/search.rb b/lib/solargraph/pin/search.rb index 5564fac7c..da1de116d 100644 --- a/lib/solargraph/pin/search.rb +++ b/lib/solargraph/pin/search.rb @@ -49,7 +49,7 @@ def do_query # @return [Float] def fuzzy_string_match str1, str2 return (1.0 + (str2.length.to_f / str1.length.to_f)) if str1.downcase.include?(str2.downcase) - JaroWinkler.distance(str1, str2, ignore_case: true) + JaroWinkler.similarity(str1, str2, ignore_case: true) end end end diff --git a/lib/solargraph/rbs_map/conversions.rb b/lib/solargraph/rbs_map/conversions.rb index ecd5322f2..e52c94923 100644 --- a/lib/solargraph/rbs_map/conversions.rb +++ b/lib/solargraph/rbs_map/conversions.rb @@ -40,7 +40,7 @@ def convert_decl_to_pin decl, closure when RBS::AST::Declarations::Interface # STDERR.puts "Skipping interface #{decl.name.relative!}" interface_decl_to_pin decl - when RBS::AST::Declarations::Alias + when RBS::AST::Declarations::TypeAlias type_aliases[decl.name.to_s] = decl when RBS::AST::Declarations::Module module_decl_to_pin decl @@ -222,12 +222,12 @@ def method_def_to_pin decl, closure # @param decl [RBS::AST::Members::MethodDefinition] # @param pin [Pin::Method] def method_def_to_sigs decl, pin - decl.types.map do |type| - parameters, return_type = parts_of_function(type, pin) - block = if type.block - Pin::Signature.new(*parts_of_function(type.block, pin)) + decl.overloads.map do |overload| + parameters, return_type = parts_of_function(overload.method_type, pin) + block = if overload.method_type.block + Pin::Signature.new(*parts_of_function(overload.method_type.block, pin)) end - return_type = ComplexType.try_parse(method_type_to_tag(type)) + return_type = ComplexType.try_parse(method_type_to_tag(overload.method_type)) Pin::Signature.new(parameters, return_type, block) end end diff --git a/lib/solargraph/source_map.rb b/lib/solargraph/source_map.rb index 7c7ff9f6a..60cba47c1 100644 --- a/lib/solargraph/source_map.rb +++ b/lib/solargraph/source_map.rb @@ -30,6 +30,7 @@ def initialize source, pins, locals @pins = pins @locals = locals environ.merge Convention.for_local(self) unless filename.nil? + self.convention_pins = environ.pins @pin_class_hash = pins.to_set.classify(&:class).transform_values(&:to_a) @pin_select_cache = {} end @@ -65,11 +66,12 @@ def environ @environ ||= Environ.new end + # all pins except Solargraph::Pin::Reference::Reference # @return [Array] def document_symbols - @document_symbols ||= pins.select { |pin| + @document_symbols ||= (pins + convention_pins).select do |pin| pin.path && !pin.path.empty? - } + end end # @param query [String] @@ -159,6 +161,17 @@ def map source private + # @return [Array] + def convention_pins + @convention_pins || [] + end + + def convention_pins=(pins) + # unmemoizing the document_symbols in case it was called from any of convnetions + @document_symbols = nil + @convention_pins = pins + end + # @param line [Integer] # @param character [Integer] # @param klasses [Array] diff --git a/lib/solargraph/yard_map.rb b/lib/solargraph/yard_map.rb index 89208a2bb..04be84aac 100755 --- a/lib/solargraph/yard_map.rb +++ b/lib/solargraph/yard_map.rb @@ -288,7 +288,7 @@ def spec_for_require path # Avoid loading the spec again if it's going to be skipped anyway return spec if @source_gems.include?(spec.name) # Avoid loading the spec again if it's already the correct version - if @gemset[spec.name] && @gemset[spec.name] != spec.version + if @gemset[spec.name] && spec.version != @gemset[spec.name] begin return Gem::Specification.find_by_name(spec.name, "= #{@gemset[spec.name]}") rescue Gem::LoadError diff --git a/solargraph.gemspec b/solargraph.gemspec index b35ffe2e9..46449358b 100755 --- a/solargraph.gemspec +++ b/solargraph.gemspec @@ -27,12 +27,14 @@ Gem::Specification.new do |s| s.add_runtime_dependency 'benchmark' s.add_runtime_dependency 'bundler', '~> 2.0' s.add_runtime_dependency 'diff-lcs', '~> 1.4' - s.add_runtime_dependency 'e2mmap' - s.add_runtime_dependency 'jaro_winkler', '~> 1.5' + s.add_runtime_dependency 'jaro_winkler', '~> 1.6' s.add_runtime_dependency 'kramdown', '~> 2.3' s.add_runtime_dependency 'kramdown-parser-gfm', '~> 1.1' + s.add_runtime_dependency 'logger', '~> 1.6' + s.add_runtime_dependency 'observer', '~> 0.1' + s.add_runtime_dependency 'ostruct', '~> 0.6' s.add_runtime_dependency 'parser', '~> 3.0' - s.add_runtime_dependency 'rbs', '~> 2.0' + s.add_runtime_dependency 'rbs', '~> 3.0' s.add_runtime_dependency 'reverse_markdown', '>= 2.0', '< 4' s.add_runtime_dependency 'rubocop', '~> 1.38' s.add_runtime_dependency 'thor', '~> 1.0' @@ -41,6 +43,7 @@ Gem::Specification.new do |s| s.add_development_dependency 'pry' 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 'simplecov', '~> 0.14' s.add_development_dependency 'webmock', '~> 3.6' diff --git a/spec/rbs_map/stdlib_map_spec.rb b/spec/rbs_map/stdlib_map_spec.rb index 80734530a..8a3347653 100644 --- a/spec/rbs_map/stdlib_map_spec.rb +++ b/spec/rbs_map/stdlib_map_spec.rb @@ -1,7 +1,7 @@ describe Solargraph::RbsMap::StdlibMap do it "finds stdlib require paths" do - rbs_map = Solargraph::RbsMap::StdlibMap.load('set') - pin = rbs_map.path_pin('Set#add') + rbs_map = Solargraph::RbsMap::StdlibMap.load('fileutils') + pin = rbs_map.path_pin('FileUtils#chdir') expect(pin).to be end diff --git a/spec/source_map_spec.rb b/spec/source_map_spec.rb index 8e623296b..db9789c6b 100644 --- a/spec/source_map_spec.rb +++ b/spec/source_map_spec.rb @@ -20,6 +20,49 @@ def baz_qux; end expect(map.query_symbols("bazqux")).to eq(map.document_symbols.select{ |pin_namespace| pin_namespace.name == "baz_qux" }) end + it 'returns all pins, except for references as document symbols' do + map = Solargraph::SourceMap.load_string(%( + class FooBar + require 'foo' + include SomeModule + extend SomeOtherModule + + def baz_qux; end + end + ), 'test.rb') + + expect(map.document_symbols.map(&:path)).to eq(['FooBar', 'FooBar#baz_qux']) + expect(map.document_symbols.map(&:class)).not_to include(an_instance_of(Solargraph::Pin::Reference)) + end + + it 'includes convention pins in document symbols' do + dummy_convention = Class.new(Solargraph::Convention::Base) do + def local(source_map) + source_map.document_symbols # call memoized method + + Solargraph::Environ.new( + pins: [ + Solargraph::Pin::Method.new( + closure: Solargraph::Pin::Namespace.new(name: 'FooBar', type: :class), + name: 'baz_convention', + scope: :instance + ) + ] + ) + end + end + + Solargraph::Convention.register dummy_convention + + map = Solargraph::SourceMap.load_string(%( + class FooBar + def baz_qux; end + end + ), 'test.rb') + + expect(map.document_symbols.map(&:path)).to include('FooBar#baz_convention') + end + it "locates block pins" do map = Solargraph::SourceMap.load_string(%( class Foo diff --git a/spec/type_checker/levels/strict_spec.rb b/spec/type_checker/levels/strict_spec.rb index 22bbd3631..5e8c801ae 100644 --- a/spec/type_checker/levels/strict_spec.rb +++ b/spec/type_checker/levels/strict_spec.rb @@ -300,7 +300,6 @@ def bar baz h['foo'] = 'bar' h[100] = [] )) - puts checker.problems.map(&:message) expect(checker.problems).to be_empty end @@ -473,7 +472,6 @@ def bar alias baz bar end )) - puts checker.problems.map(&:message) expect(checker.problems).to be_empty end