solargraph 0.39.14 → 0.40.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -8
- data/CHANGELOG.md +988 -0
- data/Rakefile +12 -1
- data/SPONSORS.md +1 -0
- data/lib/solargraph.rb +2 -4
- data/lib/solargraph/api_map.rb +75 -74
- data/lib/solargraph/api_map/cache.rb +2 -2
- data/lib/solargraph/api_map/store.rb +4 -8
- data/lib/solargraph/{bundle.rb → bench.rb} +6 -2
- data/lib/solargraph/compat.rb +14 -0
- data/lib/solargraph/complex_type.rb +2 -2
- data/lib/solargraph/convention.rb +13 -4
- data/lib/solargraph/convention/base.rb +16 -8
- data/lib/solargraph/convention/gemfile.rb +2 -5
- data/lib/solargraph/convention/gemspec.rb +3 -6
- data/lib/solargraph/convention/rspec.rb +3 -6
- data/lib/solargraph/documentor.rb +2 -0
- data/lib/solargraph/environ.rb +11 -6
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +6 -1
- data/lib/solargraph/language_server/message/text_document/definition.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/formatting.rb +17 -19
- data/lib/solargraph/library.rb +8 -10
- data/lib/solargraph/parser/legacy/node_chainer.rb +7 -7
- data/lib/solargraph/parser/legacy/node_methods.rb +5 -0
- data/lib/solargraph/parser/legacy/node_processors/ivasgn_node.rb +1 -1
- data/lib/solargraph/parser/legacy/node_processors/send_node.rb +36 -23
- data/lib/solargraph/parser/node_processor/base.rb +3 -0
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +9 -9
- data/lib/solargraph/parser/rubyvm/node_methods.rb +11 -1
- data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +1 -1
- data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +1 -1
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +40 -29
- data/lib/solargraph/pin.rb +0 -3
- data/lib/solargraph/pin/common.rb +1 -1
- data/lib/solargraph/pin/conversions.rb +3 -4
- data/lib/solargraph/pin/documenting.rb +3 -9
- data/lib/solargraph/pin/method.rb +141 -7
- data/lib/solargraph/pin/method_alias.rb +1 -1
- data/lib/solargraph/position.rb +2 -14
- data/lib/solargraph/shell.rb +1 -1
- data/lib/solargraph/source.rb +10 -6
- data/lib/solargraph/source/chain.rb +18 -5
- data/lib/solargraph/source_map.rb +4 -1
- data/lib/solargraph/source_map/clip.rb +3 -2
- data/lib/solargraph/source_map/mapper.rb +10 -6
- data/lib/solargraph/type_checker.rb +35 -39
- data/lib/solargraph/type_checker/param_def.rb +1 -1
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/yard_map.rb +40 -47
- data/lib/solargraph/yard_map/core_fills.rb +185 -0
- data/lib/solargraph/yard_map/helpers.rb +16 -0
- data/lib/solargraph/yard_map/mapper.rb +14 -8
- data/lib/solargraph/{pin/yard_pin/constant.rb → yard_map/mapper/to_constant.rb} +6 -6
- data/lib/solargraph/yard_map/mapper/to_method.rb +78 -0
- data/lib/solargraph/{pin/yard_pin/namespace.rb → yard_map/mapper/to_namespace.rb} +6 -6
- data/lib/solargraph/yard_map/rdoc_to_yard.rb +1 -1
- data/lib/solargraph/yard_map/stdlib_fills.rb +43 -0
- data/lib/solargraph/yard_map/to_method.rb +79 -0
- data/solargraph.gemspec +4 -4
- metadata +20 -34
- data/lib/solargraph/core_fills.rb +0 -160
- data/lib/solargraph/pin/attribute.rb +0 -49
- data/lib/solargraph/pin/base_method.rb +0 -141
- data/lib/solargraph/pin/yard_pin.rb +0 -12
- data/lib/solargraph/pin/yard_pin/method.rb +0 -80
- data/lib/solargraph/pin/yard_pin/yard_mixin.rb +0 -20
- data/lib/solargraph/stdlib_fills.rb +0 -40
- data/travis-bundler.rb +0 -11
@@ -4,18 +4,22 @@ module Solargraph
|
|
4
4
|
# An aggregation of a workspace and additional sources to be cataloged in an
|
5
5
|
# ApiMap.
|
6
6
|
#
|
7
|
-
class
|
7
|
+
class Bench
|
8
8
|
# @return [Workspace]
|
9
9
|
attr_reader :workspace
|
10
10
|
|
11
11
|
# @return [Array<Source>]
|
12
12
|
attr_reader :opened
|
13
13
|
|
14
|
+
# @return [Array<Pin::Base>]
|
15
|
+
attr_reader :pins
|
16
|
+
|
14
17
|
# @param workspace [Workspace]
|
15
18
|
# @param opened [Array<Source>]
|
16
|
-
def initialize workspace: Workspace.new, opened: []
|
19
|
+
def initialize workspace: Workspace.new, opened: [], pins: []
|
17
20
|
@workspace = workspace
|
18
21
|
@opened = opened
|
22
|
+
@pins = pins
|
19
23
|
end
|
20
24
|
|
21
25
|
# @return [Array<Source>]
|
data/lib/solargraph/compat.rb
CHANGED
@@ -12,7 +12,7 @@ module Solargraph
|
|
12
12
|
|
13
13
|
# @param types [Array<UniqueType>]
|
14
14
|
def initialize types = [UniqueType::UNDEFINED]
|
15
|
-
@items = types
|
15
|
+
@items = types.uniq(&:to_s)
|
16
16
|
end
|
17
17
|
|
18
18
|
# @param api_map [ApiMap]
|
@@ -113,7 +113,7 @@ module Solargraph
|
|
113
113
|
#
|
114
114
|
# @param *strings [Array<String>] The type definitions to parse
|
115
115
|
# @param partial [Boolean] True if the string is part of a another type
|
116
|
-
# @return [ComplexType]
|
116
|
+
# @return [ComplexType, Array, nil]
|
117
117
|
def parse *strings, partial: false
|
118
118
|
@cache ||= {}
|
119
119
|
unless partial
|
@@ -20,13 +20,22 @@ module Solargraph
|
|
20
20
|
@@conventions.add convention.new
|
21
21
|
end
|
22
22
|
|
23
|
-
# @param
|
23
|
+
# @param source_map [SourceMap]
|
24
24
|
# @return [Environ]
|
25
|
-
def self.
|
25
|
+
def self.for_local(source_map)
|
26
26
|
result = Environ.new
|
27
|
-
return result if source.filename.nil? || source.filename.empty?
|
28
27
|
@@conventions.each do |conv|
|
29
|
-
result.merge conv.
|
28
|
+
result.merge conv.local(source_map)
|
29
|
+
end
|
30
|
+
result
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param yard_map [YardMap]
|
34
|
+
# @return [Environ]
|
35
|
+
def self.for_global(yard_map)
|
36
|
+
result = Environ.new
|
37
|
+
@@conventions.each do |conv|
|
38
|
+
result.merge conv.global(yard_map)
|
30
39
|
end
|
31
40
|
result
|
32
41
|
end
|
@@ -2,22 +2,30 @@
|
|
2
2
|
|
3
3
|
module Solargraph
|
4
4
|
module Convention
|
5
|
+
# The base class for Conventions.
|
6
|
+
#
|
7
|
+
# A Convention provides Environs that customize ApiMaps with additional
|
8
|
+
# pins and other information. Subclasses should implement the `local` and
|
9
|
+
# `global` methods as necessary.
|
10
|
+
#
|
5
11
|
class Base
|
6
12
|
EMPTY_ENVIRON = Environ.new
|
7
13
|
|
8
|
-
#
|
9
|
-
# Subclasses
|
14
|
+
# The Environ for a source map.
|
15
|
+
# Subclasses can override this method.
|
10
16
|
#
|
11
|
-
# @param
|
12
|
-
|
13
|
-
|
17
|
+
# @param source_map [SourceMap]
|
18
|
+
# @return [Environ]
|
19
|
+
def local source_map
|
20
|
+
EMPTY_ENVIRON
|
14
21
|
end
|
15
22
|
|
16
|
-
# The Environ for
|
17
|
-
# Subclasses
|
23
|
+
# The Environ for a YARD map.
|
24
|
+
# Subclasses can override this method.
|
18
25
|
#
|
26
|
+
# @param yard_map [YardMap]
|
19
27
|
# @return [Environ]
|
20
|
-
def
|
28
|
+
def global yard_map
|
21
29
|
EMPTY_ENVIRON
|
22
30
|
end
|
23
31
|
end
|
@@ -3,11 +3,8 @@
|
|
3
3
|
module Solargraph
|
4
4
|
module Convention
|
5
5
|
class Gemfile < Base
|
6
|
-
def
|
7
|
-
File.basename(
|
8
|
-
end
|
9
|
-
|
10
|
-
def environ
|
6
|
+
def local source_map
|
7
|
+
return EMPTY_ENVIRON unless File.basename(source_map.filename) == 'Gemfile'
|
11
8
|
@environ ||= Environ.new(
|
12
9
|
requires: ['bundler'],
|
13
10
|
domains: ['Bundler::Dsl']
|
@@ -3,14 +3,11 @@
|
|
3
3
|
module Solargraph
|
4
4
|
module Convention
|
5
5
|
class Gemspec < Base
|
6
|
-
def
|
7
|
-
File.basename(
|
8
|
-
end
|
9
|
-
|
10
|
-
def environ
|
6
|
+
def local source_map
|
7
|
+
return EMPTY_ENVIRON unless File.basename(source_map.filename).end_with?('.gemspec')
|
11
8
|
@environ ||= Environ.new(
|
12
9
|
requires: ['rubygems'],
|
13
|
-
|
10
|
+
pins: [
|
14
11
|
Solargraph::Pin::Reference::Override.from_comment(
|
15
12
|
'Gem::Specification.new',
|
16
13
|
%(
|
@@ -3,18 +3,15 @@
|
|
3
3
|
module Solargraph
|
4
4
|
module Convention
|
5
5
|
class Rspec < Base
|
6
|
-
def
|
7
|
-
File.basename(
|
8
|
-
end
|
9
|
-
|
10
|
-
def environ
|
6
|
+
def local source_map
|
7
|
+
return EMPTY_ENVIRON unless File.basename(source_map.filename) =~ /_spec\.rb$/
|
11
8
|
@environ ||= Environ.new(
|
12
9
|
requires: ['rspec'],
|
13
10
|
domains: ['RSpec::Matchers', 'RSpec::ExpectationGroups'],
|
14
11
|
# This override is necessary due to an erroneous @return tag in
|
15
12
|
# rspec's YARD documentation.
|
16
13
|
# @todo The return types have been fixed (https://github.com/rspec/rspec-expectations/pull/1121)
|
17
|
-
|
14
|
+
pins: [
|
18
15
|
Solargraph::Pin::Reference::Override.method_return('RSpec::Matchers#expect', 'RSpec::Expectations::ExpectationTarget')
|
19
16
|
]
|
20
17
|
)
|
data/lib/solargraph/environ.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Solargraph
|
4
|
+
# A collection of additional data, such as map pins and required paths, that
|
5
|
+
# can be added to an ApiMap.
|
6
|
+
#
|
7
|
+
# Conventions are used to add Environs.
|
8
|
+
#
|
4
9
|
class Environ
|
5
10
|
# @return [Array<String>]
|
6
11
|
attr_reader :requires
|
@@ -9,22 +14,22 @@ module Solargraph
|
|
9
14
|
attr_reader :domains
|
10
15
|
|
11
16
|
# @return [Array<Pin::Reference::Override>]
|
12
|
-
attr_reader :
|
17
|
+
attr_reader :pins
|
13
18
|
|
14
19
|
# @param requires [Array<String>]
|
15
20
|
# @param domains [Array<String>]
|
16
|
-
# @param
|
17
|
-
def initialize requires: [], domains: [],
|
21
|
+
# @param pins [Array<Pin::Base>]
|
22
|
+
def initialize requires: [], domains: [], pins: []
|
18
23
|
@requires = requires
|
19
24
|
@domains = domains
|
20
|
-
@
|
25
|
+
@pins = pins
|
21
26
|
end
|
22
27
|
|
23
28
|
# @return [self]
|
24
29
|
def clear
|
25
30
|
domains.clear
|
26
31
|
requires.clear
|
27
|
-
|
32
|
+
pins.clear
|
28
33
|
self
|
29
34
|
end
|
30
35
|
|
@@ -33,7 +38,7 @@ module Solargraph
|
|
33
38
|
def merge other
|
34
39
|
domains.concat other.domains
|
35
40
|
requires.concat other.requires
|
36
|
-
|
41
|
+
pins.concat other.pins
|
37
42
|
self
|
38
43
|
end
|
39
44
|
end
|
@@ -34,7 +34,12 @@ module Solargraph
|
|
34
34
|
LanguageServer::MessageTypes::INFO,
|
35
35
|
['Update now'] do |result|
|
36
36
|
next unless result == 'Update now'
|
37
|
-
|
37
|
+
cmd = if host.options['useBundler']
|
38
|
+
'bundle update solargraph'
|
39
|
+
else
|
40
|
+
'gem update solargraph'
|
41
|
+
end
|
42
|
+
o, s = Open3.capture2(cmd)
|
38
43
|
if s == 0
|
39
44
|
host.show_message 'Successfully updated the Solargraph gem.', LanguageServer::MessageTypes::INFO
|
40
45
|
host.send_notification '$/solargraph/restart', {}
|
@@ -13,7 +13,7 @@ module Solargraph::LanguageServer::Message::TextDocument
|
|
13
13
|
def code_location
|
14
14
|
suggestions = host.definitions_at(params['textDocument']['uri'], @line, @column)
|
15
15
|
return nil if suggestions.empty?
|
16
|
-
suggestions.reject{|pin| pin.location.nil?}.map do |pin|
|
16
|
+
suggestions.reject { |pin| pin.location.nil? || pin.location.filename.nil? }.map do |pin|
|
17
17
|
{
|
18
18
|
uri: file_to_uri(pin.location.filename),
|
19
19
|
range: pin.location.range.to_hash
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'rubocop'
|
4
4
|
require 'securerandom'
|
5
|
+
require 'tmpdir'
|
5
6
|
|
6
7
|
module Solargraph
|
7
8
|
module LanguageServer
|
@@ -12,25 +13,22 @@ module Solargraph
|
|
12
13
|
|
13
14
|
def process
|
14
15
|
filename = uri_to_file(params['textDocument']['uri'])
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
set_error(Solargraph::LanguageServer::ErrorCodes::INTERNAL_ERROR, "[#{e.class}] #{e.message}")
|
32
|
-
ensure
|
33
|
-
File.unlink tempfile
|
16
|
+
Dir.mktmpdir do |tempdir|
|
17
|
+
tempfile = File.join(tempdir, File.basename(filename))
|
18
|
+
rubocop_file = Diagnostics::RubocopHelpers.find_rubocop_file(filename)
|
19
|
+
original = host.read_text(params['textDocument']['uri'])
|
20
|
+
File.write tempfile, original
|
21
|
+
begin
|
22
|
+
args = ['-a', '-f', 'fi', tempfile]
|
23
|
+
args.unshift('-c', fix_drive_letter(rubocop_file)) unless rubocop_file.nil?
|
24
|
+
options, paths = RuboCop::Options.new.parse(args)
|
25
|
+
store = RuboCop::ConfigStore.new
|
26
|
+
redirect_stdout { RuboCop::Runner.new(options, store).run(paths) }
|
27
|
+
result = File.read(tempfile)
|
28
|
+
format original, result
|
29
|
+
rescue RuboCop::ValidationError, RuboCop::ConfigNotFoundError => e
|
30
|
+
set_error(Solargraph::LanguageServer::ErrorCodes::INTERNAL_ERROR, "[#{e.class}] #{e.message}")
|
31
|
+
end
|
34
32
|
end
|
35
33
|
end
|
36
34
|
|
data/lib/solargraph/library.rb
CHANGED
@@ -20,7 +20,7 @@ module Solargraph
|
|
20
20
|
def initialize workspace = Solargraph::Workspace.new, name = nil
|
21
21
|
@workspace = workspace
|
22
22
|
@name = name
|
23
|
-
api_map.catalog
|
23
|
+
api_map.catalog bench
|
24
24
|
@synchronized = true
|
25
25
|
@catalog_mutex = Mutex.new
|
26
26
|
end
|
@@ -174,10 +174,10 @@ module Solargraph
|
|
174
174
|
if cursor.comment?
|
175
175
|
source = read(filename)
|
176
176
|
offset = Solargraph::Position.to_offset(source.code, Solargraph::Position.new(line, column))
|
177
|
-
lft = source.code[0..offset-1].match(
|
177
|
+
lft = source.code[0..offset-1].match(/\[[a-z0-9_:<, ]*?([a-z0-9_:]*)\z/i)
|
178
178
|
rgt = source.code[offset..-1].match(/^([a-z0-9_]*)(:[a-z0-9_:]*)?[\]>, ]/i)
|
179
179
|
if lft && rgt
|
180
|
-
tag = lft[1] + rgt[1]
|
180
|
+
tag = (lft[1] + rgt[1]).sub(/:+$/, '')
|
181
181
|
clip = api_map.clip(cursor)
|
182
182
|
clip.translate tag
|
183
183
|
else
|
@@ -209,7 +209,6 @@ module Solargraph
|
|
209
209
|
# @return [Array<Solargraph::Range>]
|
210
210
|
# @todo Take a Location instead of filename/line/column
|
211
211
|
def references_from filename, line, column, strip: false
|
212
|
-
# checkout filename
|
213
212
|
cursor = api_map.cursor_at(filename, Position.new(line, column))
|
214
213
|
clip = api_map.clip(cursor)
|
215
214
|
pins = clip.define
|
@@ -222,7 +221,7 @@ module Solargraph
|
|
222
221
|
referenced = definitions_at(loc.filename, loc.range.ending.line, loc.range.ending.character)
|
223
222
|
# HACK: The additional location comparison is necessary because
|
224
223
|
# Clip#define can return proxies for parameter pins
|
225
|
-
referenced.any?{|r| r == pin || r.location == pin.location}
|
224
|
+
referenced.any? { |r| r == pin || r.location == pin.location }
|
226
225
|
end
|
227
226
|
# HACK: for language clients that exclude special characters from the start of variable names
|
228
227
|
if strip && match = cursor.word.match(/^[^a-z0-9_]+/i)
|
@@ -290,7 +289,6 @@ module Solargraph
|
|
290
289
|
# @param filename [String]
|
291
290
|
# @return [Array<Solargraph::Pin::Base>]
|
292
291
|
def document_symbols filename
|
293
|
-
# checkout filename
|
294
292
|
api_map.document_symbols(filename)
|
295
293
|
end
|
296
294
|
|
@@ -351,7 +349,7 @@ module Solargraph
|
|
351
349
|
@catalog_mutex.synchronize do
|
352
350
|
break if synchronized?
|
353
351
|
logger.info "Cataloging #{workspace.directory.empty? ? 'generic workspace' : workspace.directory}"
|
354
|
-
api_map.catalog
|
352
|
+
api_map.catalog bench
|
355
353
|
@synchronized = true
|
356
354
|
logger.info "Catalog complete (#{api_map.source_maps.length} files, #{api_map.pins.length} pins)" if logger.info?
|
357
355
|
end
|
@@ -403,9 +401,9 @@ module Solargraph
|
|
403
401
|
@api_map ||= Solargraph::ApiMap.new
|
404
402
|
end
|
405
403
|
|
406
|
-
# @return [
|
407
|
-
def
|
408
|
-
|
404
|
+
# @return [Bench]
|
405
|
+
def bench
|
406
|
+
Bench.new(
|
409
407
|
workspace: workspace,
|
410
408
|
opened: @current ? [@current] : []
|
411
409
|
)
|
@@ -14,7 +14,7 @@ module Solargraph
|
|
14
14
|
def initialize node, filename = nil, in_block = false
|
15
15
|
@node = node
|
16
16
|
@filename = filename
|
17
|
-
@in_block = in_block
|
17
|
+
@in_block = in_block ? 1 : 0
|
18
18
|
end
|
19
19
|
|
20
20
|
# @return [Source::Chain]
|
@@ -51,9 +51,9 @@ module Solargraph
|
|
51
51
|
return generate_links(n.children[0]) if n.type == :splat
|
52
52
|
result = []
|
53
53
|
if n.type == :block
|
54
|
-
@in_block
|
54
|
+
@in_block += 1
|
55
55
|
result.concat generate_links(n.children[0])
|
56
|
-
@in_block
|
56
|
+
@in_block -= 1
|
57
57
|
elsif n.type == :send
|
58
58
|
if n.children[0].is_a?(::Parser::AST::Node)
|
59
59
|
result.concat generate_links(n.children[0])
|
@@ -61,23 +61,23 @@ module Solargraph
|
|
61
61
|
n.children[2..-1].each do |c|
|
62
62
|
args.push NodeChainer.chain(c)
|
63
63
|
end
|
64
|
-
result.push Chain::Call.new(n.children[1].to_s, args, @in_block || block_passed?(n))
|
64
|
+
result.push Chain::Call.new(n.children[1].to_s, args, @in_block > 0 || block_passed?(n))
|
65
65
|
elsif n.children[0].nil?
|
66
66
|
args = []
|
67
67
|
n.children[2..-1].each do |c|
|
68
68
|
args.push NodeChainer.chain(c)
|
69
69
|
end
|
70
|
-
result.push Chain::Call.new(n.children[1].to_s, args, @in_block || block_passed?(n))
|
70
|
+
result.push Chain::Call.new(n.children[1].to_s, args, @in_block > 0 || block_passed?(n))
|
71
71
|
else
|
72
72
|
raise "No idea what to do with #{n}"
|
73
73
|
end
|
74
74
|
elsif n.type == :self
|
75
75
|
result.push Chain::Head.new('self')
|
76
76
|
elsif n.type == :zsuper
|
77
|
-
result.push Chain::ZSuper.new('super', @in_block || block_passed?(n))
|
77
|
+
result.push Chain::ZSuper.new('super', @in_block > 0 || block_passed?(n))
|
78
78
|
elsif n.type == :super
|
79
79
|
args = n.children.map { |c| NodeChainer.chain(c) }
|
80
|
-
result.push Chain::Call.new('super', args, @in_block || block_passed?(n))
|
80
|
+
result.push Chain::Call.new('super', args, @in_block > 0 || block_passed?(n))
|
81
81
|
elsif n.type == :const
|
82
82
|
const = unpack_name(n)
|
83
83
|
result.push Chain::Constant.new(const)
|
@@ -98,6 +98,7 @@ module Solargraph
|
|
98
98
|
|
99
99
|
def convert_hash node
|
100
100
|
return {} unless Parser.is_ast_node?(node) && node.type == :hash
|
101
|
+
return convert_hash(node.children[0].children[0]) if splatted_hash?(node)
|
101
102
|
result = {}
|
102
103
|
node.children.each do |pair|
|
103
104
|
result[pair.children[0].children[0]] = Solargraph::Parser.chain(pair.children[1])
|
@@ -118,6 +119,10 @@ module Solargraph
|
|
118
119
|
result
|
119
120
|
end
|
120
121
|
|
122
|
+
def splatted_hash? node
|
123
|
+
Parser.is_ast_node?(node.children[0]) && node.children[0].type == :kwsplat
|
124
|
+
end
|
125
|
+
|
121
126
|
# @todo Temporarily here for testing. Move to Solargraph::Parser.
|
122
127
|
def call_nodes_from node
|
123
128
|
return [] unless node.is_a?(::Parser::AST::Node)
|