solargraph 0.54.4 → 0.57.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/.github/workflows/linting.yml +125 -0
- data/.github/workflows/plugins.yml +149 -5
- data/.github/workflows/rspec.yml +39 -4
- data/.github/workflows/typecheck.yml +8 -3
- data/.gitignore +7 -0
- data/.overcommit.yml +72 -0
- data/.rspec +1 -0
- data/.rubocop.yml +66 -0
- data/.rubocop_todo.yml +2627 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +104 -0
- data/README.md +20 -6
- data/Rakefile +125 -13
- data/lib/solargraph/api_map/cache.rb +3 -2
- data/lib/solargraph/api_map/constants.rb +218 -0
- data/lib/solargraph/api_map/index.rb +44 -42
- data/lib/solargraph/api_map/source_to_yard.rb +10 -4
- data/lib/solargraph/api_map/store.rb +165 -32
- data/lib/solargraph/api_map.rb +319 -243
- data/lib/solargraph/bench.rb +18 -1
- data/lib/solargraph/complex_type/type_methods.rb +7 -1
- data/lib/solargraph/complex_type/unique_type.rb +105 -16
- data/lib/solargraph/complex_type.rb +40 -7
- data/lib/solargraph/convention/active_support_concern.rb +111 -0
- data/lib/solargraph/convention/base.rb +20 -3
- data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -0
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +91 -0
- data/lib/solargraph/convention/data_definition.rb +105 -0
- data/lib/solargraph/convention/gemspec.rb +3 -2
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +61 -0
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +102 -0
- data/lib/solargraph/convention/struct_definition.rb +164 -0
- data/lib/solargraph/convention.rb +35 -4
- data/lib/solargraph/diagnostics/rubocop.rb +6 -1
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +1 -1
- data/lib/solargraph/doc_map.rb +313 -65
- data/lib/solargraph/environ.rb +9 -2
- data/lib/solargraph/gem_pins.rb +60 -38
- data/lib/solargraph/language_server/host/dispatch.rb +2 -0
- data/lib/solargraph/language_server/host/message_worker.rb +13 -7
- data/lib/solargraph/language_server/host.rb +14 -3
- data/lib/solargraph/language_server/message/base.rb +2 -1
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +2 -0
- data/lib/solargraph/language_server/message/extended/document.rb +5 -2
- data/lib/solargraph/language_server/message/extended/document_gems.rb +3 -3
- data/lib/solargraph/language_server/message/text_document/definition.rb +2 -0
- data/lib/solargraph/language_server/message/text_document/formatting.rb +16 -2
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +1 -0
- data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +2 -0
- data/lib/solargraph/language_server/progress.rb +8 -0
- data/lib/solargraph/language_server/request.rb +1 -0
- data/lib/solargraph/library.rb +53 -32
- data/lib/solargraph/location.rb +23 -0
- data/lib/solargraph/logging.rb +12 -2
- data/lib/solargraph/page.rb +4 -0
- data/lib/solargraph/parser/comment_ripper.rb +20 -7
- data/lib/solargraph/parser/flow_sensitive_typing.rb +255 -0
- data/lib/solargraph/parser/node_methods.rb +16 -2
- data/lib/solargraph/parser/node_processor/base.rb +10 -5
- data/lib/solargraph/parser/node_processor.rb +26 -9
- data/lib/solargraph/parser/parser_gem/class_methods.rb +17 -15
- data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +13 -11
- data/lib/solargraph/parser/parser_gem/node_methods.rb +8 -4
- data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +21 -0
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +4 -2
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +7 -4
- data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +6 -3
- data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +23 -0
- data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +4 -2
- data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +7 -1
- data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +8 -7
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +42 -0
- data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +3 -1
- data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -3
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +63 -30
- data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +3 -1
- data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -0
- data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +29 -0
- data/lib/solargraph/parser/parser_gem/node_processors.rb +14 -0
- data/lib/solargraph/parser/region.rb +4 -1
- data/lib/solargraph/parser/snippet.rb +2 -0
- data/lib/solargraph/parser.rb +1 -0
- data/lib/solargraph/pin/base.rb +360 -30
- data/lib/solargraph/pin/base_variable.rb +16 -10
- data/lib/solargraph/pin/block.rb +2 -0
- data/lib/solargraph/pin/breakable.rb +9 -0
- data/lib/solargraph/pin/callable.rb +83 -3
- data/lib/solargraph/pin/closure.rb +20 -1
- data/lib/solargraph/pin/common.rb +10 -1
- data/lib/solargraph/pin/constant.rb +2 -0
- data/lib/solargraph/pin/delegated_method.rb +21 -1
- data/lib/solargraph/pin/documenting.rb +16 -0
- data/lib/solargraph/pin/keyword.rb +7 -2
- data/lib/solargraph/pin/local_variable.rb +18 -6
- data/lib/solargraph/pin/method.rb +175 -46
- data/lib/solargraph/pin/method_alias.rb +3 -0
- data/lib/solargraph/pin/namespace.rb +17 -9
- data/lib/solargraph/pin/parameter.rb +78 -19
- data/lib/solargraph/pin/proxy_type.rb +13 -6
- data/lib/solargraph/pin/reference/override.rb +24 -6
- data/lib/solargraph/pin/reference/require.rb +2 -2
- data/lib/solargraph/pin/reference/superclass.rb +5 -0
- data/lib/solargraph/pin/reference.rb +26 -0
- data/lib/solargraph/pin/search.rb +3 -1
- data/lib/solargraph/pin/signature.rb +44 -0
- data/lib/solargraph/pin/singleton.rb +1 -1
- data/lib/solargraph/pin/symbol.rb +8 -2
- data/lib/solargraph/pin/until.rb +18 -0
- data/lib/solargraph/pin/while.rb +18 -0
- data/lib/solargraph/pin.rb +4 -1
- data/lib/solargraph/pin_cache.rb +245 -0
- data/lib/solargraph/position.rb +11 -0
- data/lib/solargraph/range.rb +10 -0
- data/lib/solargraph/rbs_map/conversions.rb +226 -70
- data/lib/solargraph/rbs_map/core_fills.rb +32 -16
- data/lib/solargraph/rbs_map/core_map.rb +37 -11
- data/lib/solargraph/rbs_map/stdlib_map.rb +15 -5
- data/lib/solargraph/rbs_map.rb +88 -18
- data/lib/solargraph/shell.rb +20 -18
- data/lib/solargraph/source/chain/array.rb +11 -7
- data/lib/solargraph/source/chain/block_symbol.rb +1 -1
- data/lib/solargraph/source/chain/block_variable.rb +1 -1
- data/lib/solargraph/source/chain/call.rb +53 -23
- data/lib/solargraph/source/chain/constant.rb +1 -1
- data/lib/solargraph/source/chain/hash.rb +4 -3
- data/lib/solargraph/source/chain/head.rb +1 -1
- data/lib/solargraph/source/chain/if.rb +1 -1
- data/lib/solargraph/source/chain/link.rb +12 -1
- data/lib/solargraph/source/chain/literal.rb +22 -2
- data/lib/solargraph/source/chain/or.rb +1 -1
- data/lib/solargraph/source/chain/z_super.rb +1 -1
- data/lib/solargraph/source/chain.rb +84 -47
- data/lib/solargraph/source/change.rb +2 -2
- data/lib/solargraph/source/cursor.rb +2 -3
- data/lib/solargraph/source/source_chainer.rb +3 -3
- data/lib/solargraph/source.rb +5 -2
- data/lib/solargraph/source_map/clip.rb +4 -2
- data/lib/solargraph/source_map/data.rb +4 -0
- data/lib/solargraph/source_map/mapper.rb +13 -7
- data/lib/solargraph/source_map.rb +21 -31
- data/lib/solargraph/type_checker/checks.rb +4 -0
- data/lib/solargraph/type_checker/param_def.rb +2 -0
- data/lib/solargraph/type_checker/rules.rb +8 -0
- data/lib/solargraph/type_checker.rb +208 -128
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/_method.erb +10 -10
- data/lib/solargraph/views/_namespace.erb +3 -3
- data/lib/solargraph/views/document.erb +10 -10
- data/lib/solargraph/workspace/config.rb +1 -3
- data/lib/solargraph/workspace/require_paths.rb +98 -0
- data/lib/solargraph/workspace.rb +38 -52
- data/lib/solargraph/yard_map/helpers.rb +29 -1
- data/lib/solargraph/yard_map/mapper/to_constant.rb +7 -5
- data/lib/solargraph/yard_map/mapper/to_method.rb +53 -18
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +9 -7
- data/lib/solargraph/yard_map/mapper.rb +4 -3
- data/lib/solargraph/yard_map/to_method.rb +4 -2
- data/lib/solargraph/yardoc.rb +22 -10
- data/lib/solargraph.rb +34 -1
- data/rbs/fills/tuple.rbs +149 -0
- data/rbs_collection.yaml +19 -0
- data/sig/shims/parser/3.2.0.1/builders/default.rbs +195 -0
- data/sig/shims/thor/1.2.0.1/.rbs_meta.yaml +9 -0
- data/sig/shims/thor/1.2.0.1/manifest.yaml +7 -0
- data/sig/shims/thor/1.2.0.1/thor.rbs +17 -0
- data/solargraph.gemspec +15 -4
- metadata +157 -15
- data/lib/.rubocop.yml +0 -22
- data/lib/solargraph/cache.rb +0 -77
@@ -5,23 +5,49 @@ module Solargraph
|
|
5
5
|
# Ruby core pins
|
6
6
|
#
|
7
7
|
class CoreMap
|
8
|
-
include Conversions
|
9
8
|
|
10
|
-
def
|
11
|
-
|
9
|
+
def resolved?
|
10
|
+
true
|
11
|
+
end
|
12
|
+
|
13
|
+
FILLS_DIRECTORY = File.join(File.dirname(__FILE__), '..', '..', '..', 'rbs', 'fills')
|
14
|
+
|
15
|
+
def initialize; end
|
16
|
+
|
17
|
+
# @return [Enumerable<Pin::Base>]
|
18
|
+
def pins
|
19
|
+
return @pins if @pins
|
20
|
+
|
21
|
+
@pins = []
|
22
|
+
cache = PinCache.deserialize_core
|
12
23
|
if cache
|
13
|
-
pins.replace cache
|
24
|
+
@pins.replace cache
|
14
25
|
else
|
15
|
-
loader
|
16
|
-
|
17
|
-
|
18
|
-
pins.concat RbsMap::CoreFills::ALL
|
26
|
+
loader.add(path: Pathname(FILLS_DIRECTORY))
|
27
|
+
@pins = conversions.pins
|
28
|
+
@pins.concat RbsMap::CoreFills::ALL
|
19
29
|
processed = ApiMap::Store.new(pins).pins.reject { |p| p.is_a?(Solargraph::Pin::Reference::Override) }
|
20
|
-
|
21
|
-
pins.replace processed
|
30
|
+
@pins.replace processed
|
22
31
|
|
23
|
-
|
32
|
+
PinCache.serialize_core @pins
|
24
33
|
end
|
34
|
+
@pins
|
35
|
+
end
|
36
|
+
|
37
|
+
def loader
|
38
|
+
@loader ||= RBS::EnvironmentLoader.new(repository: RBS::Repository.new(no_stdlib: false))
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
# @return [RBS::EnvironmentLoader]
|
44
|
+
def loader
|
45
|
+
@loader ||= RBS::EnvironmentLoader.new(repository: RBS::Repository.new(no_stdlib: false))
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [Conversions]
|
49
|
+
def conversions
|
50
|
+
@conversions ||= Conversions.new(loader: loader)
|
25
51
|
end
|
26
52
|
end
|
27
53
|
end
|
@@ -7,19 +7,29 @@ module Solargraph
|
|
7
7
|
# Ruby stdlib pins
|
8
8
|
#
|
9
9
|
class StdlibMap < RbsMap
|
10
|
+
include Logging
|
11
|
+
|
10
12
|
# @type [Hash{String => RbsMap}]
|
11
13
|
@stdlib_maps_hash = {}
|
12
14
|
|
13
15
|
# @param library [String]
|
14
16
|
def initialize library
|
15
|
-
|
16
|
-
if
|
17
|
-
pins
|
17
|
+
cached_pins = PinCache.deserialize_stdlib_require library
|
18
|
+
if cached_pins
|
19
|
+
@pins = cached_pins
|
18
20
|
@resolved = true
|
21
|
+
@loaded = true
|
22
|
+
logger.debug { "Deserialized #{cached_pins.length} cached pins for stdlib require #{library.inspect}" }
|
19
23
|
else
|
20
24
|
super
|
21
|
-
|
22
|
-
|
25
|
+
unless resolved?
|
26
|
+
@pins = []
|
27
|
+
logger.info { "Could not resolve #{library.inspect}" }
|
28
|
+
return
|
29
|
+
end
|
30
|
+
generated_pins = pins
|
31
|
+
logger.debug { "Found #{generated_pins.length} pins for stdlib library #{library}" }
|
32
|
+
PinCache.serialize_stdlib_require library, generated_pins
|
23
33
|
end
|
24
34
|
end
|
25
35
|
|
data/lib/solargraph/rbs_map.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'digest'
|
3
4
|
require 'pathname'
|
4
5
|
require 'rbs'
|
5
6
|
|
@@ -10,25 +11,86 @@ module Solargraph
|
|
10
11
|
autoload :CoreFills, 'solargraph/rbs_map/core_fills'
|
11
12
|
autoload :StdlibMap, 'solargraph/rbs_map/stdlib_map'
|
12
13
|
|
13
|
-
include
|
14
|
+
include Logging
|
14
15
|
|
15
16
|
# @type [Hash{String => RbsMap}]
|
16
17
|
@@rbs_maps_hash = {}
|
17
18
|
|
18
19
|
attr_reader :library
|
19
20
|
|
21
|
+
attr_reader :rbs_collection_paths
|
22
|
+
|
23
|
+
attr_reader :rbs_collection_config_path
|
24
|
+
|
20
25
|
# @param library [String]
|
21
|
-
# @param version [String, nil
|
22
|
-
# @param
|
23
|
-
|
26
|
+
# @param version [String, nil
|
27
|
+
# @param rbs_collection_config_path [String, Pathname, nil]
|
28
|
+
# @param rbs_collection_paths [Array<Pathname, String>]
|
29
|
+
def initialize library, version = nil, rbs_collection_config_path: nil, rbs_collection_paths: []
|
30
|
+
if rbs_collection_config_path.nil? && !rbs_collection_paths.empty?
|
31
|
+
raise 'Please provide rbs_collection_config_path if you provide rbs_collection_paths'
|
32
|
+
end
|
24
33
|
@library = library
|
25
34
|
@version = version
|
26
|
-
@
|
27
|
-
@
|
28
|
-
loader = RBS::EnvironmentLoader.new(core_root: nil, repository: repository)
|
35
|
+
@rbs_collection_config_path = rbs_collection_config_path
|
36
|
+
@rbs_collection_paths = rbs_collection_paths
|
29
37
|
add_library loader, library, version
|
30
|
-
|
31
|
-
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [RBS::EnvironmentLoader]
|
41
|
+
def loader
|
42
|
+
@loader ||= RBS::EnvironmentLoader.new(core_root: nil, repository: repository)
|
43
|
+
end
|
44
|
+
|
45
|
+
# @return [String] representing the version of the RBS info fetched
|
46
|
+
# for the given library. Must change when the RBS info is
|
47
|
+
# updated upstream for the same library and version. May change
|
48
|
+
# if the config for where information comes form changes.
|
49
|
+
def cache_key
|
50
|
+
@hextdigest ||= begin
|
51
|
+
# @type [String, nil]
|
52
|
+
data = nil
|
53
|
+
if rbs_collection_config_path
|
54
|
+
lockfile_path = RBS::Collection::Config.to_lockfile_path(Pathname.new(rbs_collection_config_path))
|
55
|
+
if lockfile_path.exist?
|
56
|
+
collection_config = RBS::Collection::Config.from_path lockfile_path
|
57
|
+
gem_config = collection_config.gem(library)
|
58
|
+
data = gem_config&.to_s
|
59
|
+
end
|
60
|
+
end
|
61
|
+
if data.nil? || data.empty?
|
62
|
+
if resolved?
|
63
|
+
# definitely came from the gem itself and not elsewhere -
|
64
|
+
# only one version per gem
|
65
|
+
'gem-export'
|
66
|
+
else
|
67
|
+
'unresolved'
|
68
|
+
end
|
69
|
+
else
|
70
|
+
Digest::SHA1.hexdigest(data)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# @param gemspec [Gem::Specification]
|
76
|
+
# @param rbs_collection_path [String, Pathname, nil]
|
77
|
+
# @param rbs_collection_config_path [String, Pathname, nil]
|
78
|
+
# @return [RbsMap]
|
79
|
+
def self.from_gemspec gemspec, rbs_collection_path, rbs_collection_config_path
|
80
|
+
rbs_map = RbsMap.new(gemspec.name, gemspec.version,
|
81
|
+
rbs_collection_paths: [rbs_collection_path].compact,
|
82
|
+
rbs_collection_config_path: rbs_collection_config_path)
|
83
|
+
return rbs_map if rbs_map.resolved?
|
84
|
+
|
85
|
+
# try any version of the gem in the collection
|
86
|
+
RbsMap.new(gemspec.name, nil,
|
87
|
+
rbs_collection_paths: [rbs_collection_path].compact,
|
88
|
+
rbs_collection_config_path: rbs_collection_config_path)
|
89
|
+
end
|
90
|
+
|
91
|
+
# @return [Array<Pin::Base>]
|
92
|
+
def pins
|
93
|
+
@pins ||= resolved? ? conversions.pins : []
|
32
94
|
end
|
33
95
|
|
34
96
|
# @generic T
|
@@ -50,11 +112,13 @@ module Solargraph
|
|
50
112
|
@resolved
|
51
113
|
end
|
52
114
|
|
115
|
+
# @return [RBS::Repository]
|
53
116
|
def repository
|
54
117
|
@repository ||= RBS::Repository.new(no_stdlib: false).tap do |repo|
|
55
|
-
|
56
|
-
|
57
|
-
|
118
|
+
@rbs_collection_paths.each do |dir|
|
119
|
+
dir_path = Pathname.new(dir)
|
120
|
+
repo.add(dir_path) if dir_path.exist? && dir_path.directory?
|
121
|
+
end
|
58
122
|
end
|
59
123
|
end
|
60
124
|
|
@@ -64,23 +128,29 @@ module Solargraph
|
|
64
128
|
@@rbs_maps_hash[library] ||= RbsMap.new(library)
|
65
129
|
end
|
66
130
|
|
67
|
-
|
68
|
-
|
69
|
-
|
131
|
+
private
|
132
|
+
|
133
|
+
# @return [RBS::EnvironmentLoader]
|
134
|
+
def loader
|
135
|
+
@loader ||= RBS::EnvironmentLoader.new(core_root: nil, repository: repository)
|
70
136
|
end
|
71
137
|
|
72
|
-
|
138
|
+
# @return [Conversions]
|
139
|
+
def conversions
|
140
|
+
@conversions ||= Conversions.new(loader: loader)
|
141
|
+
end
|
73
142
|
|
74
143
|
# @param loader [RBS::EnvironmentLoader]
|
75
144
|
# @param library [String]
|
145
|
+
# @param version [String, nil]
|
76
146
|
# @return [Boolean] true if adding the library succeeded
|
77
147
|
def add_library loader, library, version
|
78
148
|
@resolved = if loader.has_library?(library: library, version: version)
|
79
149
|
loader.add library: library, version: version
|
80
|
-
|
150
|
+
logger.debug { "#{short_name} successfully loaded library #{library}:#{version}" }
|
81
151
|
true
|
82
152
|
else
|
83
|
-
|
153
|
+
logger.info { "#{short_name} did not find data for library #{library}:#{version}" }
|
84
154
|
false
|
85
155
|
end
|
86
156
|
end
|
data/lib/solargraph/shell.rb
CHANGED
@@ -36,6 +36,7 @@ module Solargraph
|
|
36
36
|
Signal.trap("TERM") do
|
37
37
|
Backport.stop
|
38
38
|
end
|
39
|
+
# @sg-ignore Wrong argument type for Backport.prepare_tcp_server: adapter expected Backport::Adapter, received Module<Solargraph::LanguageServer::Transport::Adapter>
|
39
40
|
Backport.prepare_tcp_server host: options[:host], port: port, adapter: Solargraph::LanguageServer::Transport::Adapter
|
40
41
|
STDERR.puts "Solargraph is listening PORT=#{port} PID=#{Process.pid}"
|
41
42
|
end
|
@@ -52,6 +53,7 @@ module Solargraph
|
|
52
53
|
Signal.trap("TERM") do
|
53
54
|
Backport.stop
|
54
55
|
end
|
56
|
+
# @sg-ignore Wrong argument type for Backport.prepare_stdio_server: adapter expected Backport::Adapter, received Module<Solargraph::LanguageServer::Transport::Adapter>
|
55
57
|
Backport.prepare_stdio_server adapter: Solargraph::LanguageServer::Transport::Adapter
|
56
58
|
STDERR.puts "Solargraph is listening on stdio PID=#{Process.pid}"
|
57
59
|
end
|
@@ -90,19 +92,20 @@ module Solargraph
|
|
90
92
|
# @return [void]
|
91
93
|
def clear
|
92
94
|
puts "Deleting all cached documentation (gems, core and stdlib)"
|
93
|
-
Solargraph::
|
95
|
+
Solargraph::PinCache.clear
|
94
96
|
end
|
95
97
|
map 'clear-cache' => :clear
|
96
98
|
map 'clear-cores' => :clear
|
97
99
|
|
98
100
|
desc 'cache', 'Cache a gem', hide: true
|
101
|
+
option :rebuild, type: :boolean, desc: 'Rebuild existing documentation', default: false
|
99
102
|
# @return [void]
|
100
103
|
# @param gem [String]
|
101
104
|
# @param version [String, nil]
|
102
105
|
def cache gem, version = nil
|
106
|
+
api_map = Solargraph::ApiMap.load(Dir.pwd)
|
103
107
|
spec = Gem::Specification.find_by_name(gem, version)
|
104
|
-
|
105
|
-
Cache.save('gems', "#{spec.name}-#{spec.version}.ser", pins)
|
108
|
+
api_map.cache_gem(spec, rebuild: options[:rebuild], out: $stdout)
|
106
109
|
end
|
107
110
|
|
108
111
|
desc 'uncache GEM [...GEM]', "Delete specific cached gem documentation"
|
@@ -117,18 +120,17 @@ module Solargraph
|
|
117
120
|
raise ArgumentError, 'No gems specified.' if gems.empty?
|
118
121
|
gems.each do |gem|
|
119
122
|
if gem == 'core'
|
120
|
-
|
123
|
+
PinCache.uncache_core
|
121
124
|
next
|
122
125
|
end
|
123
126
|
|
124
127
|
if gem == 'stdlib'
|
125
|
-
|
128
|
+
PinCache.uncache_stdlib
|
126
129
|
next
|
127
130
|
end
|
128
131
|
|
129
132
|
spec = Gem::Specification.find_by_name(gem)
|
130
|
-
|
131
|
-
Cache.uncache('gems', "#{spec.name}-#{spec.version}.yardoc")
|
133
|
+
PinCache.uncache_gem(spec, out: $stdout)
|
132
134
|
end
|
133
135
|
end
|
134
136
|
|
@@ -137,15 +139,18 @@ module Solargraph
|
|
137
139
|
# @param names [Array<String>]
|
138
140
|
# @return [void]
|
139
141
|
def gems *names
|
142
|
+
api_map = ApiMap.load('.')
|
140
143
|
if names.empty?
|
141
|
-
Gem::Specification.to_a.each { |spec| do_cache spec }
|
144
|
+
Gem::Specification.to_a.each { |spec| do_cache spec, api_map }
|
145
|
+
STDERR.puts "Documentation cached for all #{Gem::Specification.count} gems."
|
142
146
|
else
|
143
147
|
names.each do |name|
|
144
148
|
spec = Gem::Specification.find_by_name(*name.split('='))
|
145
|
-
do_cache spec
|
149
|
+
do_cache spec, api_map
|
146
150
|
rescue Gem::MissingSpecError
|
147
151
|
warn "Gem '#{name}' not found"
|
148
152
|
end
|
153
|
+
STDERR.puts "Documentation cached for #{names.count} gems."
|
149
154
|
end
|
150
155
|
end
|
151
156
|
|
@@ -206,6 +211,7 @@ module Solargraph
|
|
206
211
|
# @return [void]
|
207
212
|
def scan
|
208
213
|
directory = File.realpath(options[:directory])
|
214
|
+
# @type [Solargraph::ApiMap, nil]
|
209
215
|
api_map = nil
|
210
216
|
time = Benchmark.measure {
|
211
217
|
api_map = Solargraph::ApiMap.load_with_cache(directory, $stdout)
|
@@ -254,16 +260,12 @@ module Solargraph
|
|
254
260
|
end
|
255
261
|
|
256
262
|
# @param gemspec [Gem::Specification]
|
263
|
+
# @param api_map [ApiMap]
|
257
264
|
# @return [void]
|
258
|
-
def do_cache gemspec
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
else
|
263
|
-
puts "#{cached ? 'Rebuilding' : 'Caching'} gem documentation for #{gemspec.name} #{gemspec.version}"
|
264
|
-
pins = GemPins.build(gemspec)
|
265
|
-
Cache.save('gems', "#{gemspec.name}-#{gemspec.version}.ser", pins)
|
266
|
-
end
|
265
|
+
def do_cache gemspec, api_map
|
266
|
+
# @todo if the rebuild: option is passed as a positional arg,
|
267
|
+
# typecheck doesn't complain on the below line
|
268
|
+
api_map.cache_gem(gemspec, rebuild: options.rebuild, out: $stdout)
|
267
269
|
end
|
268
270
|
end
|
269
271
|
end
|
@@ -3,8 +3,9 @@ module Solargraph
|
|
3
3
|
class Chain
|
4
4
|
class Array < Literal
|
5
5
|
# @param children [::Array<Chain>]
|
6
|
-
|
7
|
-
|
6
|
+
# @param node [Parser::AST::Node]
|
7
|
+
def initialize children, node
|
8
|
+
super('::Array', node)
|
8
9
|
@children = children
|
9
10
|
end
|
10
11
|
|
@@ -17,15 +18,18 @@ module Solargraph
|
|
17
18
|
# @param locals [::Array<Pin::Parameter, Pin::LocalVariable>]
|
18
19
|
def resolve api_map, name_pin, locals
|
19
20
|
child_types = @children.map do |child|
|
20
|
-
child.infer(api_map, name_pin, locals)
|
21
|
+
child.infer(api_map, name_pin, locals).simplify_literals
|
21
22
|
end
|
22
|
-
|
23
|
-
|
23
|
+
type = if child_types.length == 0 || child_types.any?(&:undefined?)
|
24
|
+
ComplexType::UniqueType.new('Array', rooted: true)
|
25
|
+
elsif child_types.uniq.length == 1 && child_types.first.defined?
|
24
26
|
ComplexType::UniqueType.new('Array', [], child_types.uniq, rooted: true, parameters_type: :list)
|
27
|
+
elsif child_types.length == 0
|
28
|
+
ComplexType::UniqueType.new('Array', rooted: true, parameters_type: :list)
|
25
29
|
else
|
26
|
-
ComplexType::UniqueType.new('Array', rooted: true)
|
30
|
+
ComplexType::UniqueType.new('Array', [], child_types, rooted: true, parameters_type: :fixed)
|
27
31
|
end
|
28
|
-
[Pin::ProxyType.anonymous(type)]
|
32
|
+
[Pin::ProxyType.anonymous(type, source: :chain)]
|
29
33
|
end
|
30
34
|
end
|
31
35
|
end
|
@@ -3,12 +3,20 @@
|
|
3
3
|
module Solargraph
|
4
4
|
class Source
|
5
5
|
class Chain
|
6
|
+
#
|
7
|
+
# Handles both method calls and local variable references by
|
8
|
+
# first looking for a variable with the name 'word', then
|
9
|
+
# proceeding to method signature resolution if not found.
|
10
|
+
#
|
6
11
|
class Call < Chain::Link
|
7
12
|
include Solargraph::Parser::NodeMethods
|
8
13
|
|
9
14
|
# @return [String]
|
10
15
|
attr_reader :word
|
11
16
|
|
17
|
+
# @return [Location]
|
18
|
+
attr_reader :location
|
19
|
+
|
12
20
|
# @return [::Array<Chain>]
|
13
21
|
attr_reader :arguments
|
14
22
|
|
@@ -16,10 +24,12 @@ module Solargraph
|
|
16
24
|
attr_reader :block
|
17
25
|
|
18
26
|
# @param word [String]
|
27
|
+
# @param location [Location, nil]
|
19
28
|
# @param arguments [::Array<Chain>]
|
20
29
|
# @param block [Chain, nil]
|
21
|
-
def initialize word, arguments = [], block = nil
|
30
|
+
def initialize word, location = nil, arguments = [], block = nil
|
22
31
|
@word = word
|
32
|
+
@location = location
|
23
33
|
@arguments = arguments
|
24
34
|
@block = block
|
25
35
|
fix_block_pass
|
@@ -35,20 +45,21 @@ module Solargraph
|
|
35
45
|
end
|
36
46
|
|
37
47
|
# @param api_map [ApiMap]
|
38
|
-
# @param name_pin [Pin::Closure] name_pin.binder should give us the object on which 'word' will be invoked
|
48
|
+
# @param name_pin [Pin::Closure] name_pin.binder should give us the type of the object on which 'word' will be invoked
|
39
49
|
# @param locals [::Array<Pin::LocalVariable>]
|
40
50
|
def resolve api_map, name_pin, locals
|
41
51
|
return super_pins(api_map, name_pin) if word == 'super'
|
42
52
|
return yield_pins(api_map, name_pin) if word == 'yield'
|
43
53
|
found = if head?
|
44
|
-
locals
|
54
|
+
api_map.visible_pins(locals, word, name_pin, location)
|
45
55
|
else
|
46
56
|
[]
|
47
57
|
end
|
48
58
|
return inferred_pins(found, api_map, name_pin, locals) unless found.empty?
|
49
59
|
pins = name_pin.binder.each_unique_type.flat_map do |context|
|
50
|
-
|
51
|
-
api_map.get_method_stack(
|
60
|
+
ns_tag = context.namespace == '' ? '' : context.namespace_type.tag
|
61
|
+
stack = api_map.get_method_stack(ns_tag, word, scope: context.scope)
|
62
|
+
[stack.first].compact
|
52
63
|
end
|
53
64
|
return [] if pins.empty?
|
54
65
|
inferred_pins(pins, api_map, name_pin, locals)
|
@@ -72,7 +83,9 @@ module Solargraph
|
|
72
83
|
# use it. If we didn't pass a block, the logic below will
|
73
84
|
# reject it regardless
|
74
85
|
|
75
|
-
|
86
|
+
with_block, without_block = overloads.partition(&:block?)
|
87
|
+
sorted_overloads = with_block + without_block
|
88
|
+
# @type [Pin::Signature, nil]
|
76
89
|
new_signature_pin = nil
|
77
90
|
sorted_overloads.each do |ol|
|
78
91
|
next unless ol.arity_matches?(arguments, with_block?)
|
@@ -85,13 +98,8 @@ module Solargraph
|
|
85
98
|
match = ol.parameters.any?(&:restarg?)
|
86
99
|
break
|
87
100
|
end
|
88
|
-
atype = atypes[idx] ||= arg.infer(api_map, Pin::ProxyType.anonymous(name_pin.context), locals)
|
89
|
-
|
90
|
-
# inheritance chain if we don't have them on this pin
|
91
|
-
ptype = param.typify api_map
|
92
|
-
# @todo Weak type comparison
|
93
|
-
# unless atype.tag == param.return_type.tag || api_map.super_and_sub?(param.return_type.tag, atype.tag)
|
94
|
-
unless ptype.undefined? || atype.name == ptype.name || ptype.any? { |current_ptype| api_map.super_and_sub?(current_ptype.name, atype.name) } || ptype.generic? || param.restarg?
|
101
|
+
atype = atypes[idx] ||= arg.infer(api_map, Pin::ProxyType.anonymous(name_pin.context, source: :chain), locals)
|
102
|
+
unless param.compatible_arg?(atype, api_map) || param.restarg?
|
95
103
|
match = false
|
96
104
|
break
|
97
105
|
end
|
@@ -106,9 +114,30 @@ module Solargraph
|
|
106
114
|
blocktype = block_call_type(api_map, name_pin, locals)
|
107
115
|
end
|
108
116
|
end
|
117
|
+
# @type new_signature_pin [Pin::Signature]
|
109
118
|
new_signature_pin = ol.resolve_generics_from_context_until_complete(ol.generics, atypes, nil, nil, blocktype)
|
110
119
|
new_return_type = new_signature_pin.return_type
|
111
|
-
|
120
|
+
if head?
|
121
|
+
# If we're at the head of the chain, we called a
|
122
|
+
# method somewhere that marked itself as returning
|
123
|
+
# self. Given we didn't invoke this on an object,
|
124
|
+
# this must be a method in this same class - so we
|
125
|
+
# use our own self type
|
126
|
+
self_type = name_pin.context
|
127
|
+
else
|
128
|
+
# if we're past the head in the chain, whatever the
|
129
|
+
# type of the lhs side is what 'self' will be in its
|
130
|
+
# declaration - we can't just use the type of the
|
131
|
+
# method pin, as this might be a subclass of the
|
132
|
+
# place where the method is defined
|
133
|
+
self_type = name_pin.binder
|
134
|
+
end
|
135
|
+
# This same logic applies to the YARD work done by
|
136
|
+
# 'with_params()'.
|
137
|
+
#
|
138
|
+
# qualify(), however, happens in the namespace where
|
139
|
+
# the docs were written - from the method pin.
|
140
|
+
type = with_params(new_return_type.self_to_type(self_type), self_type).qualify(api_map, p.namespace) if new_return_type.defined?
|
112
141
|
type ||= ComplexType::UNDEFINED
|
113
142
|
end
|
114
143
|
break if type.defined?
|
@@ -124,13 +153,14 @@ module Solargraph
|
|
124
153
|
end
|
125
154
|
p
|
126
155
|
end
|
127
|
-
|
128
|
-
|
129
|
-
|
156
|
+
logger.debug { "Call#inferred_pins(name_pin.binder=#{name_pin.binder}, word=#{word}, pins=#{pins.map(&:desc)}, name_pin=#{name_pin}) - result=#{result}" }
|
157
|
+
out = result.map do |pin|
|
158
|
+
if pin.path == 'Class#new' && name_pin.binder.tag != 'Class'
|
159
|
+
reduced_context = name_pin.binder.reduce_class_type
|
130
160
|
pin.proxy(reduced_context)
|
131
161
|
else
|
132
162
|
next pin if pin.return_type.undefined?
|
133
|
-
selfy = pin.return_type.self_to_type(name_pin.
|
163
|
+
selfy = pin.return_type.self_to_type(name_pin.binder)
|
134
164
|
selfy == pin.return_type ? pin : pin.proxy(selfy)
|
135
165
|
end
|
136
166
|
end
|
@@ -152,7 +182,7 @@ module Solargraph
|
|
152
182
|
result = inner_process_macro(pin, macro, api_map, context, locals)
|
153
183
|
return result unless result.return_type.undefined?
|
154
184
|
end
|
155
|
-
Pin::ProxyType.anonymous(ComplexType::UNDEFINED)
|
185
|
+
Pin::ProxyType.anonymous(ComplexType::UNDEFINED, source: :chain)
|
156
186
|
end
|
157
187
|
|
158
188
|
# @param pin [Pin::Method]
|
@@ -167,7 +197,7 @@ module Solargraph
|
|
167
197
|
result = inner_process_macro(pin, macro, api_map, context, locals)
|
168
198
|
return result unless result.return_type.undefined?
|
169
199
|
end
|
170
|
-
Pin::ProxyType.anonymous ComplexType::UNDEFINED
|
200
|
+
Pin::ProxyType.anonymous ComplexType::UNDEFINED, source: :chain
|
171
201
|
end
|
172
202
|
|
173
203
|
# @param pin [Pin::Base]
|
@@ -177,7 +207,7 @@ module Solargraph
|
|
177
207
|
# @param locals [::Array<Pin::LocalVariable, Pin::Parameter>]
|
178
208
|
# @return [Pin::ProxyType]
|
179
209
|
def inner_process_macro pin, macro, api_map, context, locals
|
180
|
-
vals = arguments.map{ |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals)) }
|
210
|
+
vals = arguments.map{ |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals), source: :chain) }
|
181
211
|
txt = macro.tag.text.clone
|
182
212
|
if txt.empty? && macro.tag.name
|
183
213
|
named = api_map.named_macro(macro.tag.name)
|
@@ -191,9 +221,9 @@ module Solargraph
|
|
191
221
|
docstring = Solargraph::Source.parse_docstring(txt).to_docstring
|
192
222
|
tag = docstring.tag(:return)
|
193
223
|
unless tag.nil? || tag.types.nil?
|
194
|
-
return Pin::ProxyType.anonymous(ComplexType.try_parse(*tag.types))
|
224
|
+
return Pin::ProxyType.anonymous(ComplexType.try_parse(*tag.types), source: :chain)
|
195
225
|
end
|
196
|
-
Pin::ProxyType.anonymous(ComplexType::UNDEFINED)
|
226
|
+
Pin::ProxyType.anonymous(ComplexType::UNDEFINED, source: :chain)
|
197
227
|
end
|
198
228
|
|
199
229
|
# @param docstring [YARD::Docstring]
|
@@ -5,9 +5,10 @@ module Solargraph
|
|
5
5
|
class Chain
|
6
6
|
class Hash < Literal
|
7
7
|
# @param type [String]
|
8
|
+
# @param node [Parser::AST::Node]
|
8
9
|
# @param splatted [Boolean]
|
9
|
-
def initialize type, splatted = false
|
10
|
-
super(type)
|
10
|
+
def initialize type, node, splatted = false
|
11
|
+
super(type, node)
|
11
12
|
@splatted = splatted
|
12
13
|
end
|
13
14
|
|
@@ -21,7 +22,7 @@ module Solargraph
|
|
21
22
|
end
|
22
23
|
|
23
24
|
def resolve api_map, name_pin, locals
|
24
|
-
[Pin::ProxyType.anonymous(@complex_type)]
|
25
|
+
[Pin::ProxyType.anonymous(@complex_type, source: :chain)]
|
25
26
|
end
|
26
27
|
|
27
28
|
def splatted?
|
@@ -9,7 +9,7 @@ module Solargraph
|
|
9
9
|
# @note Chain::Head is only intended to handle `self` and `super`.
|
10
10
|
class Head < Link
|
11
11
|
def resolve api_map, name_pin, locals
|
12
|
-
return [Pin::ProxyType.anonymous(name_pin.binder)] if word == 'self'
|
12
|
+
return [Pin::ProxyType.anonymous(name_pin.binder, source: :chain)] if word == 'self'
|
13
13
|
# return super_pins(api_map, name_pin) if word == 'super'
|
14
14
|
[]
|
15
15
|
end
|
@@ -20,7 +20,7 @@ module Solargraph
|
|
20
20
|
|
21
21
|
def resolve api_map, name_pin, locals
|
22
22
|
types = @links.map { |link| link.infer(api_map, name_pin, locals) }
|
23
|
-
[Solargraph::Pin::ProxyType.anonymous(Solargraph::ComplexType.try_parse(types.map(&:tag).uniq.join(', ')))]
|
23
|
+
[Solargraph::Pin::ProxyType.anonymous(Solargraph::ComplexType.try_parse(types.map(&:tag).uniq.join(', ')), source: :chain)]
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|