solargraph 0.39.0 → 0.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +2 -7
- data/CHANGELOG.md +984 -0
- data/Rakefile +12 -1
- data/SPONSORS.md +6 -0
- data/lib/.rubocop.yml +21 -0
- data/lib/solargraph/api_map/cache.rb +4 -0
- data/lib/solargraph/api_map/store.rb +35 -51
- data/lib/solargraph/api_map.rb +94 -87
- data/lib/solargraph/{bundle.rb → bench.rb} +6 -2
- data/lib/solargraph/compat.rb +23 -0
- data/lib/solargraph/complex_type.rb +2 -2
- 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/convention.rb +14 -5
- data/lib/solargraph/diagnostics/rubocop.rb +2 -1
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +4 -1
- data/lib/solargraph/documentor.rb +4 -0
- data/lib/solargraph/environ.rb +11 -6
- data/lib/solargraph/language_server/host.rb +1 -1
- 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 +7 -3
- data/lib/solargraph/language_server/uri_helpers.rb +23 -3
- data/lib/solargraph/library.rb +22 -8
- data/lib/solargraph/parser/legacy/class_methods.rb +4 -0
- data/lib/solargraph/parser/legacy/node_chainer.rb +10 -7
- data/lib/solargraph/parser/legacy/node_methods.rb +16 -3
- data/lib/solargraph/parser/legacy/node_processors/ivasgn_node.rb +1 -1
- data/lib/solargraph/parser/legacy/node_processors/send_node.rb +48 -23
- data/lib/solargraph/parser/node_processor/base.rb +3 -0
- data/lib/solargraph/parser/rubyvm/class_methods.rb +6 -2
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +11 -9
- data/lib/solargraph/parser/rubyvm/node_methods.rb +6 -1
- data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +35 -11
- data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +1 -1
- data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +6 -1
- data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +6 -1
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +52 -67
- data/lib/solargraph/parser/rubyvm/node_processors.rb +2 -0
- data/lib/solargraph/pin/base.rb +2 -2
- data/lib/solargraph/pin/base_variable.rb +1 -1
- data/lib/solargraph/pin/block.rb +28 -14
- data/lib/solargraph/pin/closure.rb +1 -1
- data/lib/solargraph/pin/common.rb +1 -1
- data/lib/solargraph/pin/constant.rb +1 -1
- data/lib/solargraph/pin/conversions.rb +3 -4
- data/lib/solargraph/pin/documenting.rb +6 -11
- data/lib/solargraph/pin/local_variable.rb +1 -1
- data/lib/solargraph/pin/method.rb +143 -9
- data/lib/solargraph/pin/method_alias.rb +2 -2
- data/lib/solargraph/pin/namespace.rb +1 -1
- data/lib/solargraph/pin/parameter.rb +2 -2
- data/lib/solargraph/pin/proxy_type.rb +1 -1
- data/lib/solargraph/pin.rb +0 -3
- data/lib/solargraph/position.rb +2 -14
- data/lib/solargraph/shell.rb +2 -1
- data/lib/solargraph/source/chain/call.rb +9 -0
- data/lib/solargraph/source/chain/head.rb +14 -8
- data/lib/solargraph/source/chain/z_super.rb +30 -0
- data/lib/solargraph/source/chain.rb +19 -36
- data/lib/solargraph/source/source_chainer.rb +2 -1
- data/lib/solargraph/source.rb +24 -9
- data/lib/solargraph/source_map/clip.rb +78 -44
- data/lib/solargraph/source_map/mapper.rb +41 -21
- data/lib/solargraph/source_map.rb +20 -2
- data/lib/solargraph/type_checker/param_def.rb +1 -1
- data/lib/solargraph/type_checker.rb +61 -42
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/_name_type_tag.erb +1 -1
- data/lib/solargraph/workspace.rb +1 -1
- data/lib/solargraph/yard_map/core_fills.rb +185 -0
- data/lib/solargraph/yard_map/helpers.rb +16 -0
- 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/mapper.rb +17 -8
- data/lib/solargraph/yard_map/rdoc_to_yard.rb +26 -15
- data/lib/solargraph/yard_map/stdlib_fills.rb +43 -0
- data/lib/solargraph/yard_map/to_method.rb +79 -0
- data/lib/solargraph/yard_map.rb +140 -92
- data/lib/solargraph.rb +5 -4
- data/solargraph.gemspec +5 -5
- data/yardoc/2.2.2.tar.gz +0 -0
- metadata +29 -41
- data/.rubocop.yml +0 -6
- data/lib/solargraph/core_fills.rb +0 -159
- data/lib/solargraph/pin/attribute.rb +0 -49
- data/lib/solargraph/pin/base_method.rb +0 -141
- data/lib/solargraph/pin/yard_pin/method.rb +0 -65
- data/lib/solargraph/pin/yard_pin/yard_mixin.rb +0 -26
- data/lib/solargraph/pin/yard_pin.rb +0 -12
- data/lib/solargraph/stdlib_fills.rb +0 -32
- data/travis-bundler.rb +0 -11
|
@@ -11,22 +11,27 @@ module Solargraph
|
|
|
11
11
|
extend ApiMap::SourceToYard
|
|
12
12
|
|
|
13
13
|
# @param spec [Gem::Specification]
|
|
14
|
-
|
|
14
|
+
# @param cache_dir [String]
|
|
15
|
+
# @return [void]
|
|
16
|
+
def self.run spec, cache_dir: nil
|
|
15
17
|
Dir.mktmpdir do |tmpdir|
|
|
16
|
-
rdir = File.join(tmpdir, '
|
|
17
|
-
Dir.
|
|
18
|
+
rdir = File.join(tmpdir, 'sg_tmp_rdoc')
|
|
19
|
+
FileUtils.cp_r Dir.glob(File.join(spec.full_gem_path, '*')), tmpdir
|
|
20
|
+
Dir.chdir tmpdir do
|
|
18
21
|
pins = []
|
|
19
22
|
pins.push Solargraph::Pin::ROOT_PIN
|
|
20
23
|
name_hash = {}
|
|
21
|
-
|
|
24
|
+
|
|
25
|
+
argv = ['-q', '-r', '-N', '-o', rdir]
|
|
22
26
|
spec.load_paths.each do |path|
|
|
23
|
-
|
|
27
|
+
argv.concat ['-i', path]
|
|
24
28
|
end
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
rdoc = RDoc::RDoc.new
|
|
30
|
+
rdoc.document argv
|
|
31
|
+
# @type [RDoc::Store]
|
|
32
|
+
store = rdoc.store
|
|
33
|
+
store.path = rdir
|
|
28
34
|
store.cache[:modules].each do |mod|
|
|
29
|
-
# store.load_class(mod)
|
|
30
35
|
# @type [RDoc::NormalClass]
|
|
31
36
|
mod = store.find_class_or_module(mod)
|
|
32
37
|
closure = pins.select { |pin| pin.path == mod.full_name.split('::')[0..-2].join('::') }.first || pins.first
|
|
@@ -46,7 +51,7 @@ module Solargraph
|
|
|
46
51
|
closure: namepin
|
|
47
52
|
)
|
|
48
53
|
end
|
|
49
|
-
# @param
|
|
54
|
+
# @param ext [RDoc::Extend]
|
|
50
55
|
mod.extends.each do |ext|
|
|
51
56
|
pins.push Solargraph::Pin::Reference::Extend.new(
|
|
52
57
|
location: locate(ext),
|
|
@@ -58,13 +63,13 @@ module Solargraph
|
|
|
58
63
|
name_hash[mod.full_name] = namepin
|
|
59
64
|
# @param met [RDoc::AnyMethod]
|
|
60
65
|
mod.each_method do |met|
|
|
61
|
-
pin = Solargraph::SourceMap.load_string("def Object.tmp#{met.param_seq};end").first_pin('Object.tmp') || Solargraph::Pin::
|
|
66
|
+
pin = Solargraph::SourceMap.load_string("def Object.tmp#{met.param_seq};end").first_pin('Object.tmp') || Solargraph::Pin::Method.new
|
|
62
67
|
pins.push Solargraph::Pin::Method.new(
|
|
63
68
|
name: met.name,
|
|
64
69
|
closure: namepin,
|
|
65
70
|
comments: commentary(met.comment),
|
|
66
71
|
scope: met.type.to_sym,
|
|
67
|
-
|
|
72
|
+
parameters: pin.parameters,
|
|
68
73
|
visibility: met.visibility,
|
|
69
74
|
location: locate(met)
|
|
70
75
|
)
|
|
@@ -85,11 +90,13 @@ module Solargraph
|
|
|
85
90
|
code_object_map.values.each do |co|
|
|
86
91
|
YARD::Registry.register(co)
|
|
87
92
|
end
|
|
88
|
-
cache_dir
|
|
93
|
+
cache_dir ||= File.join(Solargraph::YardMap::CoreDocs.cache_dir, 'gems', "#{spec.name}-#{spec.version}", "yardoc")
|
|
89
94
|
FileUtils.remove_entry_secure cache_dir if File.exist?(cache_dir)
|
|
90
95
|
FileUtils.mkdir_p cache_dir
|
|
91
96
|
# @todo Should merge be true?
|
|
92
97
|
YARD::Registry.save true, cache_dir
|
|
98
|
+
# Clear the serialized cache if it exists
|
|
99
|
+
FileUtils.safe_unlink File.join(CoreDocs.cache_dir, 'gems', "#{spec.name}-#{spec.version}.ser")
|
|
93
100
|
end
|
|
94
101
|
end
|
|
95
102
|
end
|
|
@@ -98,7 +105,11 @@ module Solargraph
|
|
|
98
105
|
mod.full_name.split('::')[0..-2].join('::')
|
|
99
106
|
end
|
|
100
107
|
|
|
108
|
+
# @param cmnt [RDoc::Comment]
|
|
109
|
+
# @return [String]
|
|
101
110
|
def self.commentary cmnt
|
|
111
|
+
return cmnt if cmnt.is_a?(String)
|
|
112
|
+
return cmnt.text if cmnt.is_a?(RDoc::Comment)
|
|
102
113
|
result = []
|
|
103
114
|
cmnt.parts.each do |part|
|
|
104
115
|
result.push RDoc::Markup::ToHtml.new({}).to_html(part.text) if part.respond_to?(:text)
|
|
@@ -119,9 +130,9 @@ module Solargraph
|
|
|
119
130
|
|
|
120
131
|
def self.find_file obj
|
|
121
132
|
if obj.respond_to?(:in_files) && !obj.in_files.empty?
|
|
122
|
-
[obj.in_files.first.to_s.sub(/^file /, ''), obj.
|
|
133
|
+
[obj.in_files.first.to_s.sub(/^file /, ''), obj.line]
|
|
123
134
|
else
|
|
124
|
-
[obj.
|
|
135
|
+
[obj.file, obj.line]
|
|
125
136
|
end
|
|
126
137
|
end
|
|
127
138
|
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Solargraph
|
|
2
|
+
class YardMap
|
|
3
|
+
module StdlibFills
|
|
4
|
+
Override = Pin::Reference::Override
|
|
5
|
+
|
|
6
|
+
LIBS = {
|
|
7
|
+
'benchmark' => [
|
|
8
|
+
Override.method_return('Benchmark.measure', 'Benchmark::Tms')
|
|
9
|
+
],
|
|
10
|
+
|
|
11
|
+
'pathname' => [
|
|
12
|
+
Override.method_return('Pathname#join', 'Pathname'),
|
|
13
|
+
Override.method_return('Pathname#basename', 'Pathname'),
|
|
14
|
+
Override.method_return('Pathname#dirname', 'Pathname'),
|
|
15
|
+
Override.method_return('Pathname#cleanpath', 'Pathname'),
|
|
16
|
+
Override.method_return('Pathname#children', 'Array<Pathname>'),
|
|
17
|
+
Override.method_return('Pathname#entries', 'Array<Pathname>')
|
|
18
|
+
],
|
|
19
|
+
|
|
20
|
+
'set' => [
|
|
21
|
+
Override.method_return('Enumerable#to_set', 'Set'),
|
|
22
|
+
Override.method_return('Set#add', 'self'),
|
|
23
|
+
Override.method_return('Set#add?', 'self, nil'),
|
|
24
|
+
Override.method_return('Set#classify', 'Hash'),
|
|
25
|
+
Override.from_comment('Set#each', '@yieldparam_single_parameter'),
|
|
26
|
+
],
|
|
27
|
+
|
|
28
|
+
'tempfile' => [
|
|
29
|
+
Override.from_comment('Tempfile.open', %(
|
|
30
|
+
@yieldparam [Tempfile]
|
|
31
|
+
@return [Tempfile]
|
|
32
|
+
))
|
|
33
|
+
]
|
|
34
|
+
}.freeze
|
|
35
|
+
|
|
36
|
+
# @param path [String]
|
|
37
|
+
# @return [Array<Pin::Reference::Override>]
|
|
38
|
+
def self.get path
|
|
39
|
+
LIBS[path] || []
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class YardMap
|
|
5
|
+
class ToMethod
|
|
6
|
+
module InnerMethods
|
|
7
|
+
module_function
|
|
8
|
+
|
|
9
|
+
# @param code_object [YARD::CodeObjects::Base]
|
|
10
|
+
# @return [Array<Solargraph::Pin::Parameter>]
|
|
11
|
+
def get_parameters code_object, location, comments
|
|
12
|
+
return [] unless code_object.is_a?(YARD::CodeObjects::MethodObject)
|
|
13
|
+
# HACK: Skip `nil` and `self` parameters that are sometimes emitted
|
|
14
|
+
# for methods defined in C
|
|
15
|
+
# See https://github.com/castwide/solargraph/issues/345
|
|
16
|
+
code_object.parameters.select { |a| a[0] && a[0] != 'self' }.map do |a|
|
|
17
|
+
Solargraph::Pin::Parameter.new(
|
|
18
|
+
location: location,
|
|
19
|
+
closure: self,
|
|
20
|
+
comments: comments,
|
|
21
|
+
name: arg_name(a),
|
|
22
|
+
presence: nil,
|
|
23
|
+
decl: arg_type(a),
|
|
24
|
+
asgn_code: a[1]
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @param a [Array]
|
|
30
|
+
# @return [String]
|
|
31
|
+
def arg_name a
|
|
32
|
+
a[0].gsub(/[^a-z0-9_]/i, '')
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# @param a [Array]
|
|
36
|
+
# @return [::Symbol]
|
|
37
|
+
def arg_type a
|
|
38
|
+
if a[0].start_with?('**')
|
|
39
|
+
:kwrestarg
|
|
40
|
+
elsif a[0].start_with?('*')
|
|
41
|
+
:restarg
|
|
42
|
+
elsif a[0].start_with?('&')
|
|
43
|
+
:blockarg
|
|
44
|
+
elsif a[0].end_with?(':')
|
|
45
|
+
a[1] ? :kwoptarg : :kwarg
|
|
46
|
+
elsif a[1]
|
|
47
|
+
:optarg
|
|
48
|
+
else
|
|
49
|
+
:arg
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
private_constant :InnerMethods
|
|
54
|
+
|
|
55
|
+
# include YardMixin
|
|
56
|
+
# extend YardMixin
|
|
57
|
+
extend Helpers
|
|
58
|
+
|
|
59
|
+
def make code_object, name = nil, scope = nil, visibility = nil, closure = nil, spec = nil
|
|
60
|
+
closure ||= Solargraph::Pin::Namespace.new(
|
|
61
|
+
name: code_object.namespace.to_s,
|
|
62
|
+
gates: [code_object.namespace.to_s]
|
|
63
|
+
)
|
|
64
|
+
location = object_location(code_object, spec)
|
|
65
|
+
comments = code_object.docstring ? code_object.docstring.all.to_s : ''
|
|
66
|
+
Pin::Method.new(
|
|
67
|
+
location: location,
|
|
68
|
+
closure: closure,
|
|
69
|
+
name: name || code_object.name.to_s,
|
|
70
|
+
comments: comments,
|
|
71
|
+
scope: scope || code_object.scope,
|
|
72
|
+
visibility: visibility || code_object.visibility,
|
|
73
|
+
parameters: InnerMethods.get_parameters(code_object, location, comments),
|
|
74
|
+
explicit: code_object.is_explicit?
|
|
75
|
+
)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
data/lib/solargraph/yard_map.rb
CHANGED
|
@@ -3,17 +3,22 @@
|
|
|
3
3
|
require 'yard'
|
|
4
4
|
require 'yard-solargraph'
|
|
5
5
|
require 'rubygems/package'
|
|
6
|
+
require 'set'
|
|
6
7
|
|
|
7
8
|
module Solargraph
|
|
8
9
|
# The YardMap provides access to YARD documentation for the Ruby core, the
|
|
9
10
|
# stdlib, and gems.
|
|
10
11
|
#
|
|
11
12
|
class YardMap
|
|
12
|
-
autoload :Cache,
|
|
13
|
-
autoload :CoreDocs,
|
|
14
|
-
autoload :CoreGen,
|
|
15
|
-
autoload :Mapper,
|
|
16
|
-
autoload :RdocToYard,
|
|
13
|
+
autoload :Cache, 'solargraph/yard_map/cache'
|
|
14
|
+
autoload :CoreDocs, 'solargraph/yard_map/core_docs'
|
|
15
|
+
autoload :CoreGen, 'solargraph/yard_map/core_gen'
|
|
16
|
+
autoload :Mapper, 'solargraph/yard_map/mapper'
|
|
17
|
+
autoload :RdocToYard, 'solargraph/yard_map/rdoc_to_yard'
|
|
18
|
+
autoload :CoreFills, 'solargraph/yard_map/core_fills'
|
|
19
|
+
autoload :StdlibFills, 'solargraph/yard_map/stdlib_fills'
|
|
20
|
+
autoload :Helpers, 'solargraph/yard_map/helpers'
|
|
21
|
+
autoload :ToMethod, 'solargraph/yard_map/to_method'
|
|
17
22
|
|
|
18
23
|
CoreDocs.require_minimum
|
|
19
24
|
|
|
@@ -49,6 +54,8 @@ module Solargraph
|
|
|
49
54
|
def initialize(required: [], gemset: {}, with_dependencies: true)
|
|
50
55
|
# HACK: YardMap needs its own copy of this array
|
|
51
56
|
@required = required.clone
|
|
57
|
+
# HACK: Hardcoded YAML handling
|
|
58
|
+
@required.push 'psych' if @required.include?('yaml')
|
|
52
59
|
@with_dependencies = with_dependencies
|
|
53
60
|
@gem_paths = {}
|
|
54
61
|
@stdlib_namespaces = []
|
|
@@ -56,6 +63,7 @@ module Solargraph
|
|
|
56
63
|
@source_gems = []
|
|
57
64
|
process_requires
|
|
58
65
|
yardocs.uniq!
|
|
66
|
+
@pin_select_cache = {}
|
|
59
67
|
end
|
|
60
68
|
|
|
61
69
|
# @return [Array<Solargraph::Pin::Base>]
|
|
@@ -72,6 +80,8 @@ module Solargraph
|
|
|
72
80
|
# @param new_gemset [Hash{String => String}]
|
|
73
81
|
# @return [Boolean]
|
|
74
82
|
def change new_requires, new_gemset, source_gems = []
|
|
83
|
+
# HACK: Hardcoded YAML handling
|
|
84
|
+
new_requires.push 'psych' if new_requires.include?('yaml')
|
|
75
85
|
if new_requires.uniq.sort == required.uniq.sort && new_gemset == gemset && @source_gems.uniq.sort == source_gems.uniq.sort
|
|
76
86
|
false
|
|
77
87
|
else
|
|
@@ -80,10 +90,22 @@ module Solargraph
|
|
|
80
90
|
@gemset = new_gemset
|
|
81
91
|
@source_gems = source_gems
|
|
82
92
|
process_requires
|
|
93
|
+
@rebindable_method_names = nil
|
|
94
|
+
@pin_class_hash = nil
|
|
95
|
+
@pin_select_cache = {}
|
|
83
96
|
true
|
|
84
97
|
end
|
|
85
98
|
end
|
|
86
99
|
|
|
100
|
+
# @return [Set<String>]
|
|
101
|
+
def rebindable_method_names
|
|
102
|
+
@rebindable_method_names ||= pins_by_class(Pin::Method)
|
|
103
|
+
.select { |pin| pin.comments && pin.comments.include?('@yieldself') }
|
|
104
|
+
.map(&:name)
|
|
105
|
+
.concat(['instance_eval', 'instance_exec', 'class_eval', 'class_exec', 'module_eval', 'module_exec'])
|
|
106
|
+
.to_set
|
|
107
|
+
end
|
|
108
|
+
|
|
87
109
|
# @return [Array<String>]
|
|
88
110
|
def yardocs
|
|
89
111
|
@yardocs ||= []
|
|
@@ -102,7 +124,7 @@ module Solargraph
|
|
|
102
124
|
else
|
|
103
125
|
YARD::Registry.load! y
|
|
104
126
|
end
|
|
105
|
-
rescue
|
|
127
|
+
rescue StandardError => e
|
|
106
128
|
Solargraph::Logging.logger.warn "Error loading yardoc '#{y}' #{e.class} #{e.message}"
|
|
107
129
|
yardocs.delete y
|
|
108
130
|
nil
|
|
@@ -110,58 +132,14 @@ module Solargraph
|
|
|
110
132
|
|
|
111
133
|
# @return [Array<Solargraph::Pin::Base>]
|
|
112
134
|
def core_pins
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
ser = File.join(File.dirname(yd), 'core.ser')
|
|
116
|
-
result = []
|
|
117
|
-
if File.file?(ser)
|
|
118
|
-
file = File.open(ser, 'rb')
|
|
119
|
-
dump = file.read
|
|
120
|
-
file.close
|
|
121
|
-
result.concat Marshal.load(dump)
|
|
122
|
-
else
|
|
123
|
-
load_yardoc CoreDocs.yardoc_file
|
|
124
|
-
result.concat Mapper.new(YARD::Registry.all).map
|
|
125
|
-
# HACK: Assume core methods with a single `args` parameter accept restarg
|
|
126
|
-
result.select { |pin| pin.is_a?(Solargraph::Pin::BaseMethod )}.each do |pin|
|
|
127
|
-
if pin.parameters.length == 1 && pin.parameters.first.name == 'args' && pin.parameters.first.decl == :arg
|
|
128
|
-
# @todo Smelly instance variable access
|
|
129
|
-
pin.parameters.first.instance_variable_set(:@decl, :restarg)
|
|
130
|
-
end
|
|
131
|
-
end
|
|
132
|
-
# HACK: Set missing parameters on `==` methods, e.g., `Symbol#==`
|
|
133
|
-
result.select { |pin| pin.name == '==' && pin.parameters.empty? }.each do |pin|
|
|
134
|
-
pin.parameters.push Pin::Parameter.new(decl: :arg, name: 'obj2')
|
|
135
|
-
end
|
|
136
|
-
dump = Marshal.dump(result)
|
|
137
|
-
file = File.open(ser, 'wb')
|
|
138
|
-
file.write dump
|
|
139
|
-
file.close
|
|
140
|
-
end
|
|
141
|
-
# HACK: Add Errno exception classes
|
|
142
|
-
errno = result.select{ |pin| pin.path == 'Errno' }.first
|
|
143
|
-
Errno.constants.each do |const|
|
|
144
|
-
result.push Solargraph::Pin::Namespace.new(type: :class, name: const.to_s, closure: errno)
|
|
145
|
-
result.push Solargraph::Pin::Reference::Superclass.new(closure: result.last, name: 'SystemCallError')
|
|
146
|
-
end
|
|
147
|
-
CoreFills::OVERRIDES.each do |ovr|
|
|
148
|
-
pin = result.select { |p| p.path == ovr.name }.first
|
|
149
|
-
next if pin.nil?
|
|
150
|
-
(ovr.tags.map(&:tag_name) + ovr.delete).uniq.each do |tag|
|
|
151
|
-
pin.docstring.delete_tags tag.to_sym
|
|
152
|
-
end
|
|
153
|
-
ovr.tags.each do |tag|
|
|
154
|
-
pin.docstring.add_tag(tag)
|
|
155
|
-
end
|
|
156
|
-
end
|
|
157
|
-
result
|
|
158
|
-
end
|
|
135
|
+
# Using a class variable to reduce loads
|
|
136
|
+
@@core_pins ||= load_core_pins
|
|
159
137
|
end
|
|
160
138
|
|
|
161
139
|
# @param path [String]
|
|
162
140
|
# @return [Pin::Base]
|
|
163
141
|
def path_pin path
|
|
164
|
-
pins.select{ |p| p.path == path }.first
|
|
142
|
+
pins.select { |p| p.path == path }.first
|
|
165
143
|
end
|
|
166
144
|
|
|
167
145
|
# Get the location of a file referenced by a require path.
|
|
@@ -181,6 +159,10 @@ module Solargraph
|
|
|
181
159
|
nil
|
|
182
160
|
end
|
|
183
161
|
|
|
162
|
+
def stdlib_pins
|
|
163
|
+
@stdlib_pins ||= []
|
|
164
|
+
end
|
|
165
|
+
|
|
184
166
|
private
|
|
185
167
|
|
|
186
168
|
# @return [YardMap::Cache]
|
|
@@ -188,6 +170,16 @@ module Solargraph
|
|
|
188
170
|
@cache ||= YardMap::Cache.new
|
|
189
171
|
end
|
|
190
172
|
|
|
173
|
+
# @return [Hash]
|
|
174
|
+
def pin_class_hash
|
|
175
|
+
@pin_class_hash ||= pins.to_set.classify(&:class).transform_values(&:to_a)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# @return [Array<Pin::Base>]
|
|
179
|
+
def pins_by_class klass
|
|
180
|
+
@pin_select_cache[klass] ||= pin_class_hash.select { |key, _| key <= klass }.values.flatten
|
|
181
|
+
end
|
|
182
|
+
|
|
191
183
|
# @param ns [YARD::CodeObjects::NamespaceObject]
|
|
192
184
|
# @return [Array<YARD::CodeObjects::Base>]
|
|
193
185
|
def recurse_namespace_object ns
|
|
@@ -201,12 +193,13 @@ module Solargraph
|
|
|
201
193
|
|
|
202
194
|
# @return [void]
|
|
203
195
|
def process_requires
|
|
204
|
-
pins.
|
|
196
|
+
pins.replace core_pins
|
|
205
197
|
unresolved_requires.clear
|
|
206
|
-
|
|
198
|
+
stdlib_pins.clear
|
|
199
|
+
environ = Convention.for_global(self)
|
|
207
200
|
done = []
|
|
208
201
|
from_std = []
|
|
209
|
-
required.each do |r|
|
|
202
|
+
(required + environ.requires).each do |r|
|
|
210
203
|
next if r.nil? || r.empty? || done.include?(r)
|
|
211
204
|
done.push r
|
|
212
205
|
cached = cache.get_path_pins(r)
|
|
@@ -231,37 +224,17 @@ module Solargraph
|
|
|
231
224
|
yardocs.unshift yd
|
|
232
225
|
result.concat process_yardoc yd, spec
|
|
233
226
|
result.concat add_gem_dependencies(spec) if with_dependencies?
|
|
234
|
-
stdlib_fill r, result
|
|
235
227
|
end
|
|
236
228
|
rescue Gem::LoadError => e
|
|
237
229
|
base = r.split('/').first
|
|
238
230
|
next if from_std.include?(base)
|
|
239
231
|
from_std.push base
|
|
240
|
-
stdtmp =
|
|
241
|
-
ser = File.join(File.dirname(CoreDocs.yardoc_stdlib_file), "#{base}.ser")
|
|
242
|
-
if File.file?(ser)
|
|
243
|
-
Solargraph.logger.info "Loading #{base} stdlib from cache"
|
|
244
|
-
file = File.open(ser, 'rb')
|
|
245
|
-
dump = file.read
|
|
246
|
-
file.close
|
|
247
|
-
stdtmp.concat Marshal.load(dump)
|
|
248
|
-
else
|
|
249
|
-
if stdlib_paths[base]
|
|
250
|
-
Solargraph.logger.info "Loading #{base} stdlib from yardoc"
|
|
251
|
-
stdtmp.concat Mapper.new(stdlib_paths[base]).map
|
|
252
|
-
next if stdtmp.empty?
|
|
253
|
-
dump = Marshal.dump(stdtmp)
|
|
254
|
-
file = File.open(ser, 'wb')
|
|
255
|
-
file.write dump
|
|
256
|
-
file.close
|
|
257
|
-
end
|
|
258
|
-
end
|
|
232
|
+
stdtmp = load_stdlib_pins(base)
|
|
259
233
|
if stdtmp.empty?
|
|
260
234
|
unresolved_requires.push r
|
|
261
235
|
else
|
|
262
|
-
|
|
236
|
+
stdlib_pins.concat stdtmp
|
|
263
237
|
result.concat stdtmp
|
|
264
|
-
# stdnames[r] = stdtmp
|
|
265
238
|
end
|
|
266
239
|
end
|
|
267
240
|
result.delete_if(&:nil?)
|
|
@@ -270,8 +243,13 @@ module Solargraph
|
|
|
270
243
|
pins.concat result
|
|
271
244
|
end
|
|
272
245
|
end
|
|
273
|
-
|
|
274
|
-
|
|
246
|
+
if required.include?('yaml') && required.include?('psych')
|
|
247
|
+
# HACK: Hardcoded YAML handling
|
|
248
|
+
# @todo Why can't this be handled with an override or a virtual pin?
|
|
249
|
+
pin = path_pin('YAML')
|
|
250
|
+
pin.instance_variable_set(:@return_type, ComplexType.parse('Module<Psych>')) unless pin.nil?
|
|
251
|
+
end
|
|
252
|
+
pins.concat environ.pins
|
|
275
253
|
end
|
|
276
254
|
|
|
277
255
|
# @param spec [Gem::Specification]
|
|
@@ -316,7 +294,12 @@ module Solargraph
|
|
|
316
294
|
file = File.open(ser, 'rb')
|
|
317
295
|
dump = file.read
|
|
318
296
|
file.close
|
|
319
|
-
|
|
297
|
+
begin
|
|
298
|
+
return Marshal.load(dump)
|
|
299
|
+
rescue StandardError => e
|
|
300
|
+
Solargraph.logger.warn "Error loading pin cache: [#{e.class}] #{e.message}"
|
|
301
|
+
File.unlink ser
|
|
302
|
+
end
|
|
320
303
|
end
|
|
321
304
|
end
|
|
322
305
|
if !size.nil? && size > 20_000_000
|
|
@@ -364,20 +347,85 @@ module Solargraph
|
|
|
364
347
|
spec
|
|
365
348
|
end
|
|
366
349
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
350
|
+
def load_core_pins
|
|
351
|
+
yd = CoreDocs.yardoc_file
|
|
352
|
+
ser = File.join(File.dirname(yd), 'core.ser')
|
|
353
|
+
result = if File.file?(ser)
|
|
354
|
+
file = File.open(ser, 'rb')
|
|
355
|
+
dump = file.read
|
|
356
|
+
file.close
|
|
357
|
+
begin
|
|
358
|
+
Marshal.load(dump)
|
|
359
|
+
rescue StandardError => e
|
|
360
|
+
Solargraph.logger.warn "Error loading core pin cache: [#{e.class}] #{e.message}"
|
|
361
|
+
File.unlink ser
|
|
362
|
+
read_core_and_save_cache(yd, ser)
|
|
376
363
|
end
|
|
377
|
-
|
|
378
|
-
|
|
364
|
+
else
|
|
365
|
+
read_core_and_save_cache(yd, ser)
|
|
366
|
+
end
|
|
367
|
+
ApiMap::Store.new(result + CoreFills::ALL).pins.reject { |pin| pin.is_a?(Pin::Reference::Override) }
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
def read_core_and_save_cache yd, ser
|
|
371
|
+
result = []
|
|
372
|
+
load_yardoc yd
|
|
373
|
+
result.concat Mapper.new(YARD::Registry.all).map
|
|
374
|
+
# HACK: Assume core methods with a single `args` parameter accept restarg
|
|
375
|
+
result.select { |pin| pin.is_a?(Solargraph::Pin::Method )}.each do |pin|
|
|
376
|
+
if pin.parameters.length == 1 && pin.parameters.first.name == 'args' && pin.parameters.first.decl == :arg
|
|
377
|
+
# @todo Smelly instance variable access
|
|
378
|
+
pin.parameters.first.instance_variable_set(:@decl, :restarg)
|
|
379
379
|
end
|
|
380
380
|
end
|
|
381
|
+
# HACK: Set missing parameters on `==` methods, e.g., `Symbol#==`
|
|
382
|
+
result.select { |pin| pin.name == '==' && pin.parameters.empty? }.each do |pin|
|
|
383
|
+
pin.parameters.push Pin::Parameter.new(decl: :arg, name: 'obj2')
|
|
384
|
+
end
|
|
385
|
+
dump = Marshal.dump(result)
|
|
386
|
+
file = File.open(ser, 'wb')
|
|
387
|
+
file.write dump
|
|
388
|
+
file.close
|
|
389
|
+
result
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
def load_stdlib_pins base
|
|
393
|
+
ser = File.join(File.dirname(CoreDocs.yardoc_stdlib_file), "#{base}.ser")
|
|
394
|
+
result = if File.file?(ser)
|
|
395
|
+
Solargraph.logger.info "Loading #{base} stdlib from cache"
|
|
396
|
+
file = File.open(ser, 'rb')
|
|
397
|
+
dump = file.read
|
|
398
|
+
file.close
|
|
399
|
+
begin
|
|
400
|
+
Marshal.load(dump)
|
|
401
|
+
rescue StandardError => e
|
|
402
|
+
Solargraph.logger.warn "Error loading #{base} stdlib pin cache: [#{e.class}] #{e.message}"
|
|
403
|
+
File.unlink ser
|
|
404
|
+
read_stdlib_and_save_cache(base, ser)
|
|
405
|
+
end
|
|
406
|
+
else
|
|
407
|
+
read_stdlib_and_save_cache(base, ser)
|
|
408
|
+
end
|
|
409
|
+
fills = StdlibFills.get(base)
|
|
410
|
+
unless fills.empty?
|
|
411
|
+
result = ApiMap::Store.new(result + fills).pins.reject { |pin| pin.is_a?(Pin::Reference::Override) }
|
|
412
|
+
end
|
|
413
|
+
result
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
def read_stdlib_and_save_cache base, ser
|
|
417
|
+
result = []
|
|
418
|
+
if stdlib_paths[base]
|
|
419
|
+
Solargraph.logger.info "Loading #{base} stdlib from yardoc"
|
|
420
|
+
result.concat Mapper.new(stdlib_paths[base]).map
|
|
421
|
+
unless result.empty?
|
|
422
|
+
dump = Marshal.dump(result)
|
|
423
|
+
file = File.open(ser, 'wb')
|
|
424
|
+
file.write dump
|
|
425
|
+
file.close
|
|
426
|
+
end
|
|
427
|
+
end
|
|
428
|
+
result
|
|
381
429
|
end
|
|
382
430
|
end
|
|
383
431
|
end
|
data/lib/solargraph.rb
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
Encoding.default_external = 'UTF-8'
|
|
4
|
+
|
|
5
|
+
require 'solargraph/compat'
|
|
3
6
|
require 'solargraph/version'
|
|
4
7
|
|
|
5
8
|
# The top-level namespace for the Solargraph code mapping, documentation,
|
|
@@ -24,15 +27,13 @@ module Solargraph
|
|
|
24
27
|
autoload :YardMap, 'solargraph/yard_map'
|
|
25
28
|
autoload :Pin, 'solargraph/pin'
|
|
26
29
|
autoload :ServerMethods, 'solargraph/server_methods'
|
|
27
|
-
autoload :CoreFills, 'solargraph/core_fills'
|
|
28
|
-
autoload :StdlibFills, 'solargraph/stdlib_fills'
|
|
29
30
|
autoload :LanguageServer, 'solargraph/language_server'
|
|
30
31
|
autoload :Workspace, 'solargraph/workspace'
|
|
31
32
|
autoload :Page, 'solargraph/page'
|
|
32
33
|
autoload :Library, 'solargraph/library'
|
|
33
34
|
autoload :Diagnostics, 'solargraph/diagnostics'
|
|
34
35
|
autoload :ComplexType, 'solargraph/complex_type'
|
|
35
|
-
autoload :
|
|
36
|
+
autoload :Bench, 'solargraph/bench'
|
|
36
37
|
autoload :Logging, 'solargraph/logging'
|
|
37
38
|
autoload :TypeChecker, 'solargraph/type_checker'
|
|
38
39
|
autoload :Environ, 'solargraph/environ'
|
|
@@ -53,7 +54,7 @@ module Solargraph
|
|
|
53
54
|
end
|
|
54
55
|
|
|
55
56
|
# A helper method that runs Bundler.with_unbundled_env or falls back to
|
|
56
|
-
# Bundler.
|
|
57
|
+
# Bundler.with_clean_env for earlier versions of Bundler.
|
|
57
58
|
#
|
|
58
59
|
def self.with_clean_env &block
|
|
59
60
|
meth = if Bundler.respond_to?(:with_unbundled_env)
|
data/solargraph.gemspec
CHANGED
|
@@ -17,18 +17,18 @@ Gem::Specification.new do |s|
|
|
|
17
17
|
s.license = 'MIT'
|
|
18
18
|
s.executables = ['solargraph']
|
|
19
19
|
|
|
20
|
-
s.required_ruby_version = '>= 2.
|
|
20
|
+
s.required_ruby_version = '>= 2.4'
|
|
21
21
|
|
|
22
22
|
s.add_runtime_dependency 'backport', '~> 1.1'
|
|
23
23
|
s.add_runtime_dependency 'benchmark'
|
|
24
24
|
s.add_runtime_dependency 'bundler', '>= 1.17.2'
|
|
25
25
|
s.add_runtime_dependency 'e2mmap'
|
|
26
26
|
s.add_runtime_dependency 'jaro_winkler', '~> 1.5'
|
|
27
|
-
s.add_runtime_dependency '
|
|
28
|
-
s.add_runtime_dependency '
|
|
27
|
+
s.add_runtime_dependency 'kramdown', '~> 2.3'
|
|
28
|
+
s.add_runtime_dependency 'kramdown-parser-gfm', '~> 1.1'
|
|
29
29
|
s.add_runtime_dependency 'parser', '~> 2.3'
|
|
30
|
-
s.add_runtime_dependency 'reverse_markdown', '
|
|
31
|
-
s.add_runtime_dependency 'rubocop', '
|
|
30
|
+
s.add_runtime_dependency 'reverse_markdown', '>= 1.0.5', '< 3'
|
|
31
|
+
s.add_runtime_dependency 'rubocop', '>= 0.52'
|
|
32
32
|
s.add_runtime_dependency 'thor', '~> 1.0'
|
|
33
33
|
s.add_runtime_dependency 'tilt', '~> 2.0'
|
|
34
34
|
s.add_runtime_dependency 'yard', '~> 0.9', '>= 0.9.24'
|
data/yardoc/2.2.2.tar.gz
CHANGED
|
Binary file
|