solargraph 0.51.2 → 0.54.2
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/.github/workflows/plugins.yml +40 -0
- data/.github/workflows/rspec.yml +1 -3
- data/.github/workflows/typecheck.yml +34 -0
- data/.yardopts +2 -2
- data/CHANGELOG.md +127 -5
- data/README.md +13 -16
- data/SPONSORS.md +1 -7
- data/lib/solargraph/api_map/cache.rb +50 -20
- data/lib/solargraph/api_map/source_to_yard.rb +17 -10
- data/lib/solargraph/api_map/store.rb +60 -15
- data/lib/solargraph/api_map.rb +282 -123
- data/lib/solargraph/bench.rb +3 -2
- data/lib/solargraph/cache.rb +29 -5
- data/lib/solargraph/complex_type/type_methods.rb +122 -39
- data/lib/solargraph/complex_type/unique_type.rb +310 -76
- data/lib/solargraph/complex_type.rb +166 -44
- data/lib/solargraph/convention.rb +0 -1
- data/lib/solargraph/converters/dd.rb +5 -0
- data/lib/solargraph/converters/dl.rb +3 -0
- data/lib/solargraph/converters/dt.rb +3 -0
- data/lib/solargraph/diagnostics/rubocop.rb +8 -7
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +1 -0
- data/lib/solargraph/diagnostics/type_check.rb +1 -0
- data/lib/solargraph/diagnostics.rb +2 -2
- data/lib/solargraph/doc_map.rb +187 -0
- data/lib/solargraph/gem_pins.rb +72 -0
- data/lib/solargraph/language_server/host/diagnoser.rb +2 -2
- data/lib/solargraph/language_server/host/dispatch.rb +22 -5
- data/lib/solargraph/language_server/host/message_worker.rb +49 -5
- data/lib/solargraph/language_server/host/sources.rb +8 -65
- data/lib/solargraph/language_server/host.rb +65 -84
- data/lib/solargraph/language_server/message/base.rb +19 -12
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +3 -1
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +13 -1
- data/lib/solargraph/language_server/message/initialize.rb +19 -2
- data/lib/solargraph/language_server/message/text_document/completion.rb +0 -3
- data/lib/solargraph/language_server/message/text_document/definition.rb +3 -3
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +3 -3
- data/lib/solargraph/language_server/message/text_document/formatting.rb +1 -0
- data/lib/solargraph/language_server/message/text_document/hover.rb +3 -1
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +3 -3
- data/lib/solargraph/language_server/message/text_document.rb +0 -1
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +5 -0
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -2
- data/lib/solargraph/language_server/progress.rb +135 -0
- data/lib/solargraph/language_server/transport/adapter.rb +16 -1
- data/lib/solargraph/language_server/transport/data_reader.rb +2 -0
- data/lib/solargraph/language_server.rb +1 -0
- data/lib/solargraph/library.rb +207 -111
- data/lib/solargraph/location.rb +15 -1
- data/lib/solargraph/page.rb +6 -0
- data/lib/solargraph/parser/comment_ripper.rb +4 -0
- data/lib/solargraph/parser/node_methods.rb +47 -7
- data/lib/solargraph/parser/node_processor/base.rb +11 -1
- data/lib/solargraph/parser/node_processor.rb +1 -0
- data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +31 -9
- data/lib/solargraph/parser/{legacy → parser_gem}/flawed_builder.rb +3 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_chainer.rb +62 -43
- data/lib/solargraph/parser/parser_gem/node_methods.rb +495 -0
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/alias_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +57 -0
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/begin_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/block_node.rb +3 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/casgn_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/cvasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/def_node.rb +7 -20
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/defs_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/gvasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/ivasgn_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/lvasgn_node.rb +4 -4
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +53 -0
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/namespace_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/orasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/resbody_node.rb +3 -3
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/sclass_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +8 -6
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/sym_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors.rb +56 -0
- data/lib/solargraph/parser/parser_gem.rb +12 -0
- data/lib/solargraph/parser/region.rb +1 -1
- data/lib/solargraph/parser/snippet.rb +2 -0
- data/lib/solargraph/parser.rb +8 -12
- data/lib/solargraph/pin/base.rb +78 -10
- data/lib/solargraph/pin/base_variable.rb +40 -7
- data/lib/solargraph/pin/block.rb +69 -46
- data/lib/solargraph/pin/callable.rb +147 -0
- data/lib/solargraph/pin/closure.rb +23 -3
- data/lib/solargraph/pin/common.rb +6 -6
- data/lib/solargraph/pin/conversions.rb +36 -5
- data/lib/solargraph/pin/delegated_method.rb +6 -2
- data/lib/solargraph/pin/documenting.rb +25 -32
- data/lib/solargraph/pin/instance_variable.rb +6 -2
- data/lib/solargraph/pin/local_variable.rb +13 -1
- data/lib/solargraph/pin/method.rb +205 -32
- data/lib/solargraph/pin/namespace.rb +20 -7
- data/lib/solargraph/pin/parameter.rb +41 -36
- data/lib/solargraph/pin/proxy_type.rb +1 -1
- data/lib/solargraph/pin/reference/override.rb +2 -2
- data/lib/solargraph/pin/reference.rb +8 -0
- data/lib/solargraph/pin/search.rb +3 -3
- data/lib/solargraph/pin/signature.rb +8 -14
- data/lib/solargraph/pin.rb +4 -2
- data/lib/solargraph/range.rb +4 -6
- data/lib/solargraph/rbs_map/conversions.rb +326 -76
- data/lib/solargraph/rbs_map/core_fills.rb +16 -33
- data/lib/solargraph/rbs_map/core_map.rb +3 -13
- data/lib/solargraph/rbs_map/stdlib_map.rb +2 -8
- data/lib/solargraph/rbs_map.rb +32 -13
- data/lib/solargraph/shell.rb +95 -72
- data/lib/solargraph/source/chain/array.rb +33 -0
- data/lib/solargraph/source/chain/block_symbol.rb +13 -0
- data/lib/solargraph/source/chain/block_variable.rb +1 -1
- data/lib/solargraph/source/chain/call.rb +152 -69
- data/lib/solargraph/source/chain/constant.rb +15 -1
- data/lib/solargraph/source/chain/if.rb +23 -0
- data/lib/solargraph/source/chain/link.rb +17 -2
- data/lib/solargraph/source/chain/or.rb +2 -2
- data/lib/solargraph/source/chain/z_super.rb +3 -3
- data/lib/solargraph/source/chain.rb +85 -26
- data/lib/solargraph/source/change.rb +3 -0
- data/lib/solargraph/source/cursor.rb +16 -2
- data/lib/solargraph/source/source_chainer.rb +8 -5
- data/lib/solargraph/source/updater.rb +1 -0
- data/lib/solargraph/source.rb +120 -148
- data/lib/solargraph/source_map/clip.rb +16 -27
- data/lib/solargraph/source_map/data.rb +30 -0
- data/lib/solargraph/source_map/mapper.rb +15 -3
- data/lib/solargraph/source_map.rb +48 -24
- data/lib/solargraph/type_checker/checks.rb +10 -2
- data/lib/solargraph/type_checker/rules.rb +6 -1
- data/lib/solargraph/type_checker.rb +150 -39
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/environment.erb +3 -5
- data/lib/solargraph/workspace/config.rb +9 -6
- data/lib/solargraph/workspace.rb +30 -3
- data/lib/solargraph/yard_map/cache.rb +6 -0
- data/lib/solargraph/yard_map/helpers.rb +1 -1
- data/lib/solargraph/yard_map/mapper/to_method.rb +16 -3
- data/lib/solargraph/yard_map/mapper.rb +1 -1
- data/lib/solargraph/yard_map/to_method.rb +11 -4
- data/lib/solargraph/yard_map.rb +1 -292
- data/lib/solargraph/yard_tags.rb +20 -0
- data/lib/solargraph/yardoc.rb +52 -0
- data/lib/solargraph.rb +6 -4
- data/solargraph.gemspec +7 -6
- metadata +71 -82
- data/lib/solargraph/api_map/bundler_methods.rb +0 -22
- data/lib/solargraph/documentor.rb +0 -76
- data/lib/solargraph/language_server/host/cataloger.rb +0 -56
- data/lib/solargraph/parser/legacy/node_methods.rb +0 -325
- data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +0 -23
- data/lib/solargraph/parser/legacy/node_processors/args_node.rb +0 -50
- data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
- data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +0 -18
- data/lib/solargraph/parser/legacy/node_processors.rb +0 -55
- data/lib/solargraph/parser/legacy.rb +0 -12
- data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -153
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -160
- data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -317
- data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +0 -85
- data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +0 -42
- data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +0 -33
- data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +0 -23
- data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +0 -75
- data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -68
- data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +0 -23
- data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +0 -38
- data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +0 -39
- data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +0 -20
- data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +0 -27
- data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +0 -39
- data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +0 -26
- data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +0 -15
- data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +0 -51
- data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -32
- data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -279
- data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -64
- data/lib/solargraph/parser/rubyvm/node_wrapper.rb +0 -47
- data/lib/solargraph/parser/rubyvm.rb +0 -40
- data/lib/solargraph/rbs_map/core_signs.rb +0 -33
- data/lib/yard-solargraph.rb +0 -33
@@ -35,11 +35,9 @@
|
|
35
35
|
<li>
|
36
36
|
Core Cache Directory: N/A <%# @todo Fix %>
|
37
37
|
</li>
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
</li>
|
42
|
-
<% end %>
|
38
|
+
<li>
|
39
|
+
Parser Target Version: <%= Solargraph::Parser.version %>
|
40
|
+
</li>
|
43
41
|
<li>
|
44
42
|
Using Bundler: <%= ENV.key?('BUNDLE_BIN_PATH') %>
|
45
43
|
</li>
|
@@ -14,7 +14,8 @@ module Solargraph
|
|
14
14
|
# @return [String]
|
15
15
|
attr_reader :directory
|
16
16
|
|
17
|
-
# @
|
17
|
+
# @todo To make this strongly typed we'll need a record syntax
|
18
|
+
# @return [Hash{String => undefined}]
|
18
19
|
attr_reader :raw_data
|
19
20
|
|
20
21
|
# @param directory [String]
|
@@ -41,6 +42,7 @@ module Solargraph
|
|
41
42
|
@excluded ||= process_exclusions(@raw_data['exclude'])
|
42
43
|
end
|
43
44
|
|
45
|
+
# @param filename [String]
|
44
46
|
def allow? filename
|
45
47
|
filename = File.absolute_path(filename, directory)
|
46
48
|
filename.start_with?(directory) &&
|
@@ -111,7 +113,7 @@ module Solargraph
|
|
111
113
|
|
112
114
|
# @return [String]
|
113
115
|
def global_config_path
|
114
|
-
ENV['SOLARGRAPH_GLOBAL_CONFIG'] ||
|
116
|
+
ENV['SOLARGRAPH_GLOBAL_CONFIG'] ||
|
115
117
|
File.join(Dir.home, '.config', 'solargraph', 'config.yml')
|
116
118
|
end
|
117
119
|
|
@@ -121,7 +123,7 @@ module Solargraph
|
|
121
123
|
File.join(@directory, '.solargraph.yml')
|
122
124
|
end
|
123
125
|
|
124
|
-
# @return [Hash]
|
126
|
+
# @return [Hash{String => Array, Hash, Integer}]
|
125
127
|
def config_data
|
126
128
|
workspace_config = read_config(workspace_config_path)
|
127
129
|
global_config = read_config(global_config_path)
|
@@ -136,15 +138,15 @@ module Solargraph
|
|
136
138
|
|
137
139
|
# Read a .solargraph yaml config
|
138
140
|
#
|
139
|
-
# @param
|
140
|
-
# @return [Hash, nil]
|
141
|
+
# @param config_path [String]
|
142
|
+
# @return [Hash{String => Array, Hash, Integer}, nil]
|
141
143
|
def read_config config_path = ''
|
142
144
|
return nil if config_path.empty?
|
143
145
|
return nil unless File.file?(config_path)
|
144
146
|
YAML.safe_load(File.read(config_path))
|
145
147
|
end
|
146
148
|
|
147
|
-
# @return [Hash]
|
149
|
+
# @return [Hash{String => Array, Hash, Integer}]
|
148
150
|
def default_config
|
149
151
|
{
|
150
152
|
'include' => ['**/*.rb'],
|
@@ -222,6 +224,7 @@ module Solargraph
|
|
222
224
|
glob.gsub(/(\/\*|\/\*\*\/\*\*?)$/, '')
|
223
225
|
end
|
224
226
|
|
227
|
+
# @return [Array<String>]
|
225
228
|
def excluded_directories
|
226
229
|
@raw_data['exclude']
|
227
230
|
.select { |g| glob_is_directory?(g) }
|
data/lib/solargraph/workspace.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'open3'
|
4
|
-
require 'rubygems'
|
5
4
|
require 'json'
|
6
5
|
|
7
6
|
module Solargraph
|
@@ -26,9 +25,11 @@ module Solargraph
|
|
26
25
|
|
27
26
|
# @param directory [String]
|
28
27
|
# @param config [Config, nil]
|
29
|
-
|
28
|
+
# @param server [Hash]
|
29
|
+
def initialize directory = '', config = nil, server = {}
|
30
30
|
@directory = directory
|
31
31
|
@config = config
|
32
|
+
@server = server
|
32
33
|
load_sources
|
33
34
|
@gemnames = []
|
34
35
|
@require_paths = generate_require_paths
|
@@ -104,7 +105,8 @@ module Solargraph
|
|
104
105
|
# @return [Boolean]
|
105
106
|
def would_require? path
|
106
107
|
require_paths.each do |rp|
|
107
|
-
|
108
|
+
full = File.join rp, path
|
109
|
+
return true if File.exist?(full) or File.exist?(full << ".rb")
|
108
110
|
end
|
109
111
|
false
|
110
112
|
end
|
@@ -126,6 +128,11 @@ module Solargraph
|
|
126
128
|
end
|
127
129
|
end
|
128
130
|
|
131
|
+
# @return [String, nil]
|
132
|
+
def rbs_collection_path
|
133
|
+
@gem_rbs_collection ||= read_rbs_collection_path
|
134
|
+
end
|
135
|
+
|
129
136
|
# Synchronize the workspace from the provided updater.
|
130
137
|
#
|
131
138
|
# @param updater [Source::Updater]
|
@@ -134,8 +141,19 @@ module Solargraph
|
|
134
141
|
source_hash[updater.filename] = source_hash[updater.filename].synchronize(updater)
|
135
142
|
end
|
136
143
|
|
144
|
+
# @return [String]
|
145
|
+
def command_path
|
146
|
+
server['commandPath'] || 'solargraph'
|
147
|
+
end
|
148
|
+
|
137
149
|
private
|
138
150
|
|
151
|
+
# The language server configuration (or an empty hash if the workspace was
|
152
|
+
# not initialized from a server).
|
153
|
+
#
|
154
|
+
# @return [Hash]
|
155
|
+
attr_reader :server
|
156
|
+
|
139
157
|
# @return [Hash{String => Solargraph::Source}]
|
140
158
|
def source_hash
|
141
159
|
@source_hash ||= {}
|
@@ -199,6 +217,7 @@ module Solargraph
|
|
199
217
|
config.require_paths.map{|p| File.join(directory, p)}
|
200
218
|
end
|
201
219
|
|
220
|
+
# @return [void]
|
202
221
|
def require_plugins
|
203
222
|
config.plugins.each do |plugin|
|
204
223
|
begin
|
@@ -208,5 +227,13 @@ module Solargraph
|
|
208
227
|
end
|
209
228
|
end
|
210
229
|
end
|
230
|
+
|
231
|
+
# @return [String, nil]
|
232
|
+
def read_rbs_collection_path
|
233
|
+
yaml_file = File.join(directory, 'rbs_collection.yaml')
|
234
|
+
return unless File.file?(yaml_file)
|
235
|
+
|
236
|
+
YAML.load_file(yaml_file)&.fetch('path')
|
237
|
+
end
|
211
238
|
end
|
212
239
|
end
|
@@ -4,13 +4,19 @@ module Solargraph
|
|
4
4
|
class YardMap
|
5
5
|
class Cache
|
6
6
|
def initialize
|
7
|
+
# @type [Hash{String => Array<Solargraph::Pin::Base>}]
|
7
8
|
@path_pins = {}
|
8
9
|
end
|
9
10
|
|
11
|
+
# @param path [String]
|
12
|
+
# @param pins [Array<Solargraph::Pin::Base>]
|
13
|
+
# @return [Array<Solargraph::Pin::Base>]
|
10
14
|
def set_path_pins path, pins
|
11
15
|
@path_pins[path] = pins
|
12
16
|
end
|
13
17
|
|
18
|
+
# @param path [String]
|
19
|
+
# @return [Array<Solargraph::Pin::Base>]
|
14
20
|
def get_path_pins path
|
15
21
|
@path_pins[path]
|
16
22
|
end
|
@@ -4,7 +4,7 @@ module Solargraph
|
|
4
4
|
module_function
|
5
5
|
|
6
6
|
# @param code_object [YARD::CodeObjects::Base]
|
7
|
-
# @param spec [Gem::Specification]
|
7
|
+
# @param spec [Gem::Specification, nil]
|
8
8
|
# @return [Solargraph::Location, nil]
|
9
9
|
def object_location code_object, spec
|
10
10
|
return nil if spec.nil? || code_object.nil? || code_object.file.nil? || code_object.line.nil?
|
@@ -6,23 +6,33 @@ module Solargraph
|
|
6
6
|
module ToMethod
|
7
7
|
extend YardMap::Helpers
|
8
8
|
|
9
|
+
# @param code_object [YARD::CodeObjects::Base]
|
10
|
+
# @param name [String, nil]
|
11
|
+
# @param scope [Symbol, nil]
|
12
|
+
# @param visibility [Symbol, nil]
|
13
|
+
# @param closure [Solargraph::Pin::Namespace, nil]
|
14
|
+
# @param spec [Gem::Specification, nil]
|
15
|
+
# @return [Solargraph::Pin::Method]
|
9
16
|
def self.make code_object, name = nil, scope = nil, visibility = nil, closure = nil, spec = nil
|
10
17
|
closure ||= Solargraph::Pin::Namespace.new(
|
11
18
|
name: code_object.namespace.to_s,
|
12
19
|
gates: [code_object.namespace.to_s]
|
13
20
|
)
|
14
21
|
location = object_location(code_object, spec)
|
22
|
+
name ||= code_object.name.to_s
|
23
|
+
return_type = ComplexType::SELF if name == 'new'
|
15
24
|
comments = code_object.docstring ? code_object.docstring.all.to_s : ''
|
16
25
|
pin = Pin::Method.new(
|
17
26
|
location: location,
|
18
27
|
closure: closure,
|
19
|
-
name: name
|
28
|
+
name: name,
|
20
29
|
comments: comments,
|
21
30
|
scope: scope || code_object.scope,
|
22
31
|
visibility: visibility || code_object.visibility,
|
23
32
|
# @todo Might need to convert overloads to signatures
|
24
33
|
parameters: [],
|
25
|
-
explicit: code_object.is_explicit
|
34
|
+
explicit: code_object.is_explicit?,
|
35
|
+
return_type: return_type
|
26
36
|
)
|
27
37
|
pin.parameters.concat get_parameters(code_object, location, comments, pin)
|
28
38
|
pin
|
@@ -32,6 +42,9 @@ module Solargraph
|
|
32
42
|
private
|
33
43
|
|
34
44
|
# @param code_object [YARD::CodeObjects::Base]
|
45
|
+
# @param location [Location],
|
46
|
+
# @param comments [String]
|
47
|
+
# @param pin [Pin::Base]
|
35
48
|
# @return [Array<Solargraph::Pin::Parameter>]
|
36
49
|
def get_parameters code_object, location, comments, pin
|
37
50
|
return [] unless code_object.is_a?(YARD::CodeObjects::MethodObject)
|
@@ -51,7 +64,7 @@ module Solargraph
|
|
51
64
|
end
|
52
65
|
end
|
53
66
|
|
54
|
-
# @param a [Array]
|
67
|
+
# @param a [Array<String>]
|
55
68
|
# @return [String]
|
56
69
|
def arg_name a
|
57
70
|
a[0].gsub(/[^a-z0-9_]/i, '')
|
@@ -8,7 +8,7 @@ module Solargraph
|
|
8
8
|
autoload :ToConstant, 'solargraph/yard_map/mapper/to_constant'
|
9
9
|
|
10
10
|
# @param code_objects [Array<YARD::CodeObjects::Base>]
|
11
|
-
# @param spec [Gem::Specification]
|
11
|
+
# @param spec [Gem::Specification, nil]
|
12
12
|
def initialize code_objects, spec = nil
|
13
13
|
@code_objects = code_objects
|
14
14
|
@spec = spec
|
@@ -7,6 +7,8 @@ module Solargraph
|
|
7
7
|
module_function
|
8
8
|
|
9
9
|
# @param code_object [YARD::CodeObjects::Base]
|
10
|
+
# @param location [Solargraph::Location]
|
11
|
+
# @param comments [String]
|
10
12
|
# @return [Array<Solargraph::Pin::Parameter>]
|
11
13
|
def get_parameters code_object, location, comments
|
12
14
|
return [] unless code_object.is_a?(YARD::CodeObjects::MethodObject)
|
@@ -26,7 +28,7 @@ module Solargraph
|
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
29
|
-
# @param a [Array]
|
31
|
+
# @param a [Array<String>]
|
30
32
|
# @return [String]
|
31
33
|
def arg_name a
|
32
34
|
a[0].gsub(/[^a-z0-9_]/i, '')
|
@@ -52,10 +54,15 @@ module Solargraph
|
|
52
54
|
end
|
53
55
|
private_constant :InnerMethods
|
54
56
|
|
55
|
-
|
56
|
-
# extend YardMixin
|
57
|
-
extend Helpers
|
57
|
+
include Helpers
|
58
58
|
|
59
|
+
# @param code_object [YARD::CodeObjects::Base]
|
60
|
+
# @param name [String, nil]
|
61
|
+
# @param scope [Symbol, nil]
|
62
|
+
# @param visibility [Symbol, nil]
|
63
|
+
# @param closure [Solargraph::Pin::Base, nil]
|
64
|
+
# @param spec [Solargraph::Pin::Base, nil]
|
65
|
+
# @return [Solargraph::Pin::Method]
|
59
66
|
def make code_object, name = nil, scope = nil, visibility = nil, closure = nil, spec = nil
|
60
67
|
closure ||= Solargraph::Pin::Namespace.new(
|
61
68
|
name: code_object.namespace.to_s,
|
data/lib/solargraph/yard_map.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'yard'
|
4
|
-
require '
|
5
|
-
require 'rubygems/package'
|
6
|
-
require 'set'
|
4
|
+
require 'solargraph/yard_tags'
|
7
5
|
|
8
6
|
module Solargraph
|
9
7
|
# The YardMap provides access to YARD documentation for the Ruby core, the
|
@@ -14,296 +12,7 @@ module Solargraph
|
|
14
12
|
|
15
13
|
autoload :Cache, 'solargraph/yard_map/cache'
|
16
14
|
autoload :Mapper, 'solargraph/yard_map/mapper'
|
17
|
-
autoload :RdocToYard, 'solargraph/yard_map/rdoc_to_yard'
|
18
15
|
autoload :Helpers, 'solargraph/yard_map/helpers'
|
19
16
|
autoload :ToMethod, 'solargraph/yard_map/to_method'
|
20
|
-
|
21
|
-
include ApiMap::BundlerMethods
|
22
|
-
|
23
|
-
# @return [Boolean]
|
24
|
-
attr_writer :with_dependencies
|
25
|
-
|
26
|
-
# @param required [Array<String>, Set<String>]
|
27
|
-
# @param directory [String]
|
28
|
-
# @param source_gems [Array<String>, Set<String>]
|
29
|
-
# @param with_dependencies [Boolean]
|
30
|
-
def initialize(required: [], directory: '', source_gems: [], with_dependencies: true)
|
31
|
-
@with_dependencies = with_dependencies
|
32
|
-
change required.to_set, directory, source_gems.to_set
|
33
|
-
end
|
34
|
-
|
35
|
-
# @return [Array<Solargraph::Pin::Base>]
|
36
|
-
def pins
|
37
|
-
@pins ||= []
|
38
|
-
end
|
39
|
-
|
40
|
-
def with_dependencies?
|
41
|
-
@with_dependencies ||= true unless @with_dependencies == false
|
42
|
-
@with_dependencies
|
43
|
-
end
|
44
|
-
|
45
|
-
# @param new_requires [Set<String>] Required paths to use for loading gems
|
46
|
-
# @param new_directory [String] The workspace directory
|
47
|
-
# @param new_source_gems [Set<String>] Gems under local development (i.e., part of the workspace)
|
48
|
-
# @return [Boolean]
|
49
|
-
def change new_requires, new_directory, new_source_gems
|
50
|
-
return false if new_requires == base_required && new_directory == @directory && new_source_gems == @source_gems
|
51
|
-
@gem_paths = {}
|
52
|
-
base_required.replace new_requires
|
53
|
-
required.replace new_requires
|
54
|
-
# HACK: Hardcoded YAML handling
|
55
|
-
required.add 'psych' if new_requires.include?('yaml')
|
56
|
-
@source_gems = new_source_gems
|
57
|
-
@directory = new_directory
|
58
|
-
process_requires
|
59
|
-
@rebindable_method_names = nil
|
60
|
-
@pin_class_hash = nil
|
61
|
-
@pin_select_cache = {}
|
62
|
-
pins.each { |p| p.source = :yard }
|
63
|
-
true
|
64
|
-
end
|
65
|
-
|
66
|
-
# @return [Set<String>]
|
67
|
-
def rebindable_method_names
|
68
|
-
@rebindable_method_names ||= pins_by_class(Pin::Method)
|
69
|
-
.select { |pin| pin.comments && pin.comments.include?('@yieldself') }
|
70
|
-
.map(&:name)
|
71
|
-
.concat(['instance_eval', 'instance_exec', 'class_eval', 'class_exec', 'module_eval', 'module_exec', 'define_method'])
|
72
|
-
.to_set
|
73
|
-
end
|
74
|
-
|
75
|
-
# @return [Array<String>]
|
76
|
-
def yardocs
|
77
|
-
@yardocs ||= []
|
78
|
-
end
|
79
|
-
|
80
|
-
# @return [Set<String>]
|
81
|
-
def required
|
82
|
-
@required ||= Set.new
|
83
|
-
end
|
84
|
-
|
85
|
-
# @return [Array<String>]
|
86
|
-
def unresolved_requires
|
87
|
-
@unresolved_requires ||= []
|
88
|
-
end
|
89
|
-
|
90
|
-
# @return [Array<String>]
|
91
|
-
def missing_docs
|
92
|
-
@missing_docs ||= []
|
93
|
-
end
|
94
|
-
|
95
|
-
# @param y [String]
|
96
|
-
# @return [YARD::Registry]
|
97
|
-
def load_yardoc y
|
98
|
-
if y.is_a?(Array)
|
99
|
-
YARD::Registry.load y, true
|
100
|
-
else
|
101
|
-
YARD::Registry.load! y
|
102
|
-
end
|
103
|
-
rescue StandardError => e
|
104
|
-
Solargraph::Logging.logger.warn "Error loading yardoc '#{y}' #{e.class} #{e.message}"
|
105
|
-
yardocs.delete y
|
106
|
-
nil
|
107
|
-
end
|
108
|
-
|
109
|
-
# @param path [String]
|
110
|
-
# @return [Pin::Base]
|
111
|
-
def path_pin path
|
112
|
-
pins.select { |p| p.path == path }.first
|
113
|
-
end
|
114
|
-
|
115
|
-
# Get the location of a file referenced by a require path.
|
116
|
-
#
|
117
|
-
# @param path [String]
|
118
|
-
# @return [Location]
|
119
|
-
def require_reference path
|
120
|
-
# @type [Gem::Specification]
|
121
|
-
spec = spec_for_require(path)
|
122
|
-
spec.full_require_paths.each do |rp|
|
123
|
-
file = File.join(rp, "#{path}.rb")
|
124
|
-
next unless File.file?(file)
|
125
|
-
return Solargraph::Location.new(file, Solargraph::Range.from_to(0, 0, 0, 0))
|
126
|
-
end
|
127
|
-
nil
|
128
|
-
rescue Gem::LoadError
|
129
|
-
nil
|
130
|
-
end
|
131
|
-
|
132
|
-
def base_required
|
133
|
-
@base_required ||= Set.new
|
134
|
-
end
|
135
|
-
|
136
|
-
def directory
|
137
|
-
@directory ||= ''
|
138
|
-
end
|
139
|
-
|
140
|
-
private
|
141
|
-
|
142
|
-
# @return [YardMap::Cache]
|
143
|
-
def cache
|
144
|
-
@cache ||= YardMap::Cache.new
|
145
|
-
end
|
146
|
-
|
147
|
-
# @return [Hash]
|
148
|
-
def pin_class_hash
|
149
|
-
@pin_class_hash ||= pins.to_set.classify(&:class).transform_values(&:to_a)
|
150
|
-
end
|
151
|
-
|
152
|
-
# @return [Array<Pin::Base>]
|
153
|
-
def pins_by_class klass
|
154
|
-
@pin_select_cache[klass] ||= pin_class_hash.select { |key, _| key <= klass }.values.flatten
|
155
|
-
end
|
156
|
-
|
157
|
-
# @param ns [YARD::CodeObjects::NamespaceObject]
|
158
|
-
# @return [Array<YARD::CodeObjects::Base>]
|
159
|
-
def recurse_namespace_object ns
|
160
|
-
result = []
|
161
|
-
ns.children.each do |c|
|
162
|
-
result.push c
|
163
|
-
result.concat recurse_namespace_object(c) if c.respond_to?(:children)
|
164
|
-
end
|
165
|
-
result
|
166
|
-
end
|
167
|
-
|
168
|
-
# @return [void]
|
169
|
-
def process_requires
|
170
|
-
@gemset = process_gemsets
|
171
|
-
required.merge @gemset.keys if required.include?('bundler/require')
|
172
|
-
pins.clear
|
173
|
-
unresolved_requires.clear
|
174
|
-
missing_docs.clear
|
175
|
-
environ = Convention.for_global(self)
|
176
|
-
done = []
|
177
|
-
already_errored = []
|
178
|
-
(required + environ.requires).each do |r|
|
179
|
-
next if r.nil? || r.empty? || done.include?(r)
|
180
|
-
done.push r
|
181
|
-
cached = cache.get_path_pins(r)
|
182
|
-
unless cached.nil?
|
183
|
-
pins.concat cached
|
184
|
-
next
|
185
|
-
end
|
186
|
-
result = pins_for_require r, already_errored
|
187
|
-
result.delete_if(&:nil?)
|
188
|
-
unless result.empty?
|
189
|
-
cache.set_path_pins r, result
|
190
|
-
pins.concat result
|
191
|
-
end
|
192
|
-
end
|
193
|
-
if required.include?('yaml') && required.include?('psych')
|
194
|
-
# HACK: Hardcoded YAML handling
|
195
|
-
# @todo Why can't this be handled with an override or a virtual pin?
|
196
|
-
pin = path_pin('YAML')
|
197
|
-
pin.instance_variable_set(:@return_type, ComplexType.parse('Module<Psych>')) unless pin.nil?
|
198
|
-
end
|
199
|
-
pins.concat environ.pins
|
200
|
-
end
|
201
|
-
|
202
|
-
def process_error(req, result, already_errored, yd = 1)
|
203
|
-
base = req.split('/').first
|
204
|
-
return if already_errored.include?(base)
|
205
|
-
already_errored.push base
|
206
|
-
if yd.nil?
|
207
|
-
missing_docs.push req
|
208
|
-
else
|
209
|
-
unresolved_requires.push req
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
def process_gemsets
|
214
|
-
return {} if directory.empty? || !File.file?(File.join(directory, 'Gemfile'))
|
215
|
-
require_from_bundle(directory)
|
216
|
-
end
|
217
|
-
|
218
|
-
# @param r [String]
|
219
|
-
def pins_for_require r, already_errored
|
220
|
-
result = []
|
221
|
-
begin
|
222
|
-
name = r.split('/').first.to_s
|
223
|
-
return [] if name.empty?
|
224
|
-
|
225
|
-
spec = spec_for_require(r)
|
226
|
-
return [] if @source_gems.include?(spec.name) || @gem_paths.key?(spec.name)
|
227
|
-
@gem_paths[spec.name] = spec.full_gem_path
|
228
|
-
|
229
|
-
yd = yardoc_file_for_spec(spec)
|
230
|
-
# YARD detects gems for certain libraries that do not have a yardoc
|
231
|
-
# but exist in the stdlib. `fileutils` is an example. Treat those
|
232
|
-
# cases as errors and check the stdlib yardoc.
|
233
|
-
if yd.nil?
|
234
|
-
process_error(r, result, already_errored, nil)
|
235
|
-
return []
|
236
|
-
end
|
237
|
-
unless yardocs.include?(yd)
|
238
|
-
yardocs.unshift yd
|
239
|
-
result.concat process_yardoc yd, spec
|
240
|
-
if with_dependencies?
|
241
|
-
(spec.dependencies - spec.development_dependencies).each do |dep|
|
242
|
-
result.concat pins_for_require dep.name, already_errored
|
243
|
-
end
|
244
|
-
end
|
245
|
-
end
|
246
|
-
rescue Gem::LoadError, NoYardocError
|
247
|
-
process_error(r, result, already_errored)
|
248
|
-
end
|
249
|
-
return result
|
250
|
-
end
|
251
|
-
|
252
|
-
# @param y [String, nil]
|
253
|
-
# @param spec [Gem::Specification, nil]
|
254
|
-
# @return [Array<Pin::Base>]
|
255
|
-
def process_yardoc y, spec = nil
|
256
|
-
return [] if y.nil?
|
257
|
-
if spec
|
258
|
-
cache = Solargraph::Cache.load('gems', "#{spec.name}-#{spec.version}.ser")
|
259
|
-
return cache if cache
|
260
|
-
end
|
261
|
-
size = Dir.glob(File.join(y, '**', '*'))
|
262
|
-
.map{ |f| File.size(f) }
|
263
|
-
.inject(:+)
|
264
|
-
if !size.nil? && size > 20_000_000
|
265
|
-
Solargraph::Logging.logger.warn "Yardoc at #{y} is too large to process (#{size} bytes)"
|
266
|
-
return []
|
267
|
-
end
|
268
|
-
Solargraph.logger.info "Loading #{spec.name} #{spec.version} from #{y}"
|
269
|
-
load_yardoc y
|
270
|
-
result = Mapper.new(YARD::Registry.all, spec).map
|
271
|
-
raise NoYardocError, "Yardoc at #{y} is empty" if result.empty?
|
272
|
-
if spec
|
273
|
-
Solargraph::Cache.save 'gems', "#{spec.name}-#{spec.version}.ser", result
|
274
|
-
end
|
275
|
-
result
|
276
|
-
end
|
277
|
-
|
278
|
-
# @param spec [Gem::Specification]
|
279
|
-
# @return [String]
|
280
|
-
def yardoc_file_for_spec spec
|
281
|
-
YARD::Registry.yardoc_file_for_gem(spec.name, "= #{spec.version}")
|
282
|
-
end
|
283
|
-
|
284
|
-
# @param path [String]
|
285
|
-
# @return [Gem::Specification]
|
286
|
-
def spec_for_require path
|
287
|
-
relatives = path.split('/')
|
288
|
-
spec = nil
|
289
|
-
while spec.nil? && !relatives.empty?
|
290
|
-
name = relatives.join('-')
|
291
|
-
spec = Gem::Specification.find_by_name(name, @gemset[name])
|
292
|
-
relatives.pop
|
293
|
-
end
|
294
|
-
raise Gem::LoadError if spec.nil?
|
295
|
-
|
296
|
-
# Avoid loading the spec again if it's going to be skipped anyway
|
297
|
-
return spec if @source_gems.include?(spec.name)
|
298
|
-
# Avoid loading the spec again if it's already the correct version
|
299
|
-
if @gemset[spec.name] && spec.version != @gemset[spec.name]
|
300
|
-
begin
|
301
|
-
return Gem::Specification.find_by_name(spec.name, "= #{@gemset[spec.name]}")
|
302
|
-
rescue Gem::LoadError
|
303
|
-
Solargraph.logger.warn "Unable to load #{spec.name} #{@gemset[spec.name]} specified by workspace, using #{spec.version} instead"
|
304
|
-
end
|
305
|
-
end
|
306
|
-
spec
|
307
|
-
end
|
308
17
|
end
|
309
18
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'yard'
|
4
|
+
|
5
|
+
# Change YARD log IO to avoid sending unexpected messages to STDOUT
|
6
|
+
YARD::Logger.instance.io = File.new(File::NULL, 'w')
|
7
|
+
|
8
|
+
module Solargraph
|
9
|
+
# A placeholder for the @!domain directive. It doesn't need to do anything
|
10
|
+
# for yardocs. It's only used for Solargraph API maps.
|
11
|
+
class DomainDirective < YARD::Tags::Directive
|
12
|
+
def call; end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Define a @type tag for documenting variables
|
17
|
+
YARD::Tags::Library.define_tag("Type", :type, :with_types_and_name)
|
18
|
+
|
19
|
+
# Define an @!override directive for overriding method tags
|
20
|
+
YARD::Tags::Library.define_directive("override", :with_name, Solargraph::DomainDirective)
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
# Methods for caching and loading YARD documentation for gems.
|
5
|
+
#
|
6
|
+
module Yardoc
|
7
|
+
module_function
|
8
|
+
|
9
|
+
# Build and cache a gem's yardoc and return the path. If the cache already
|
10
|
+
# exists, do nothing and return the path.
|
11
|
+
#
|
12
|
+
# @param gemspec [Gem::Specification]
|
13
|
+
# @return [String] The path to the cached yardoc.
|
14
|
+
def cache(gemspec)
|
15
|
+
path = path_for(gemspec)
|
16
|
+
return path if cached?(gemspec)
|
17
|
+
|
18
|
+
Solargraph.logger.info "Caching yardoc for #{gemspec.name} #{gemspec.version}"
|
19
|
+
Dir.chdir gemspec.gem_dir do
|
20
|
+
`yardoc --db #{path} --no-output --plugin solargraph`
|
21
|
+
end
|
22
|
+
path
|
23
|
+
end
|
24
|
+
|
25
|
+
# True if the gem yardoc is cached.
|
26
|
+
#
|
27
|
+
# @param gemspec [Gem::Specification]
|
28
|
+
def cached?(gemspec)
|
29
|
+
yardoc = File.join(path_for(gemspec), 'complete')
|
30
|
+
File.exist?(yardoc)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Get the absolute path for a cached gem yardoc.
|
34
|
+
#
|
35
|
+
# @param gemspec [Gem::Specification]
|
36
|
+
# @return [String]
|
37
|
+
def path_for(gemspec)
|
38
|
+
File.join(Solargraph::Cache.work_dir, 'gems', "#{gemspec.name}-#{gemspec.version}.yardoc")
|
39
|
+
end
|
40
|
+
|
41
|
+
# Load a gem's yardoc and return its code objects.
|
42
|
+
#
|
43
|
+
# @note This method modifies the global YARD registry.
|
44
|
+
#
|
45
|
+
# @param gemspec [Gem::Specification]
|
46
|
+
# @return [Array<YARD::CodeObjects::Base>]
|
47
|
+
def load!(gemspec)
|
48
|
+
YARD::Registry.load! path_for(gemspec)
|
49
|
+
YARD::Registry.all
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|