solargraph 0.58.3 → 0.59.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/.envrc +3 -0
- data/.github/workflows/linting.yml +6 -5
- data/.github/workflows/plugins.yml +46 -34
- data/.github/workflows/rspec.yml +15 -28
- data/.github/workflows/typecheck.yml +3 -2
- data/.rubocop.yml +38 -6
- data/.rubocop_todo.yml +53 -966
- data/CHANGELOG.md +12 -0
- data/Gemfile +3 -1
- data/README.md +3 -3
- data/Rakefile +26 -23
- data/bin/solargraph +2 -1
- data/lib/solargraph/api_map/cache.rb +3 -3
- data/lib/solargraph/api_map/constants.rb +12 -3
- data/lib/solargraph/api_map/index.rb +29 -18
- data/lib/solargraph/api_map/source_to_yard.rb +22 -9
- data/lib/solargraph/api_map/store.rb +39 -28
- data/lib/solargraph/api_map.rb +156 -72
- data/lib/solargraph/bench.rb +2 -3
- data/lib/solargraph/complex_type/conformance.rb +176 -0
- data/lib/solargraph/complex_type/type_methods.rb +30 -18
- data/lib/solargraph/complex_type/unique_type.rb +216 -57
- data/lib/solargraph/complex_type.rb +171 -58
- data/lib/solargraph/convention/data_definition/data_assignment_node.rb +1 -1
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +7 -5
- data/lib/solargraph/convention/data_definition.rb +5 -2
- data/lib/solargraph/convention/gemfile.rb +1 -1
- data/lib/solargraph/convention/gemspec.rb +1 -1
- data/lib/solargraph/convention/rakefile.rb +1 -1
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +2 -1
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +4 -3
- data/lib/solargraph/convention/struct_definition.rb +8 -4
- data/lib/solargraph/convention.rb +2 -2
- data/lib/solargraph/converters/dd.rb +2 -0
- data/lib/solargraph/converters/dl.rb +2 -0
- data/lib/solargraph/converters/dt.rb +2 -0
- data/lib/solargraph/converters/misc.rb +2 -0
- data/lib/solargraph/diagnostics/require_not_found.rb +1 -0
- data/lib/solargraph/diagnostics/rubocop.rb +11 -10
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
- data/lib/solargraph/diagnostics/type_check.rb +11 -10
- data/lib/solargraph/diagnostics/update_errors.rb +4 -8
- data/lib/solargraph/doc_map.rb +38 -39
- data/lib/solargraph/equality.rb +4 -4
- data/lib/solargraph/gem_pins.rb +6 -6
- data/lib/solargraph/language_server/error_codes.rb +10 -10
- data/lib/solargraph/language_server/host/diagnoser.rb +1 -1
- data/lib/solargraph/language_server/host/dispatch.rb +3 -3
- data/lib/solargraph/language_server/host/message_worker.rb +4 -3
- data/lib/solargraph/language_server/host/sources.rb +2 -1
- data/lib/solargraph/language_server/host.rb +30 -22
- data/lib/solargraph/language_server/message/base.rb +1 -1
- data/lib/solargraph/language_server/message/client/register_capability.rb +1 -3
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +6 -8
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +12 -18
- data/lib/solargraph/language_server/message/extended/document.rb +1 -0
- data/lib/solargraph/language_server/message/extended/document_gems.rb +7 -7
- data/lib/solargraph/language_server/message/extended/download_core.rb +2 -1
- data/lib/solargraph/language_server/message/extended/search.rb +1 -1
- data/lib/solargraph/language_server/message/initialize.rb +20 -14
- data/lib/solargraph/language_server/message/text_document/completion.rb +10 -8
- data/lib/solargraph/language_server/message/text_document/definition.rb +41 -32
- data/lib/solargraph/language_server/message/text_document/document_highlight.rb +17 -10
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +29 -19
- data/lib/solargraph/language_server/message/text_document/formatting.rb +8 -6
- data/lib/solargraph/language_server/message/text_document/hover.rb +5 -5
- data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +13 -6
- data/lib/solargraph/language_server/message/text_document/references.rb +17 -10
- data/lib/solargraph/language_server/message/text_document/rename.rb +20 -13
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +3 -2
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -17
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +34 -28
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +38 -30
- data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +23 -17
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +27 -17
- data/lib/solargraph/language_server/message.rb +1 -1
- data/lib/solargraph/language_server/request.rb +4 -2
- data/lib/solargraph/language_server/transport/data_reader.rb +11 -13
- data/lib/solargraph/language_server/uri_helpers.rb +2 -2
- data/lib/solargraph/library.rb +57 -38
- data/lib/solargraph/location.rb +17 -14
- data/lib/solargraph/logging.rb +22 -4
- data/lib/solargraph/page.rb +1 -1
- data/lib/solargraph/parser/comment_ripper.rb +19 -4
- data/lib/solargraph/parser/flow_sensitive_typing.rb +324 -108
- data/lib/solargraph/parser/node_processor/base.rb +34 -4
- data/lib/solargraph/parser/node_processor.rb +8 -7
- data/lib/solargraph/parser/parser_gem/class_methods.rb +30 -14
- data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +50 -25
- data/lib/solargraph/parser/parser_gem/node_methods.rb +91 -70
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +4 -4
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +13 -11
- data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +9 -0
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +11 -12
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +10 -3
- data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +9 -8
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +36 -6
- data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +5 -3
- data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +3 -1
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +3 -3
- data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
- data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -5
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +124 -113
- data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
- data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +6 -2
- data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
- data/lib/solargraph/parser/parser_gem.rb +2 -0
- data/lib/solargraph/parser/region.rb +9 -3
- data/lib/solargraph/parser/snippet.rb +3 -1
- data/lib/solargraph/parser.rb +2 -0
- data/lib/solargraph/pin/base.rb +124 -80
- data/lib/solargraph/pin/base_variable.rb +273 -24
- data/lib/solargraph/pin/block.rb +29 -6
- data/lib/solargraph/pin/breakable.rb +7 -1
- data/lib/solargraph/pin/callable.rb +65 -21
- data/lib/solargraph/pin/closure.rb +7 -10
- data/lib/solargraph/pin/common.rb +24 -6
- data/lib/solargraph/pin/compound_statement.rb +55 -0
- data/lib/solargraph/pin/constant.rb +3 -5
- data/lib/solargraph/pin/conversions.rb +10 -4
- data/lib/solargraph/pin/delegated_method.rb +19 -8
- data/lib/solargraph/pin/documenting.rb +4 -2
- data/lib/solargraph/pin/instance_variable.rb +5 -1
- data/lib/solargraph/pin/keyword.rb +0 -4
- data/lib/solargraph/pin/local_variable.rb +15 -59
- data/lib/solargraph/pin/method.rb +156 -104
- data/lib/solargraph/pin/method_alias.rb +8 -0
- data/lib/solargraph/pin/namespace.rb +19 -12
- data/lib/solargraph/pin/parameter.rb +100 -36
- data/lib/solargraph/pin/proxy_type.rb +4 -1
- data/lib/solargraph/pin/reference/override.rb +1 -1
- data/lib/solargraph/pin/reference/superclass.rb +2 -0
- data/lib/solargraph/pin/reference/type_alias.rb +16 -0
- data/lib/solargraph/pin/reference.rb +20 -0
- data/lib/solargraph/pin/search.rb +3 -2
- data/lib/solargraph/pin/signature.rb +15 -12
- data/lib/solargraph/pin/symbol.rb +2 -1
- data/lib/solargraph/pin/until.rb +2 -4
- data/lib/solargraph/pin/while.rb +2 -4
- data/lib/solargraph/pin.rb +2 -0
- data/lib/solargraph/pin_cache.rb +22 -19
- data/lib/solargraph/position.rb +17 -10
- data/lib/solargraph/range.rb +16 -15
- data/lib/solargraph/rbs_map/conversions.rb +358 -229
- data/lib/solargraph/rbs_map/core_fills.rb +18 -11
- data/lib/solargraph/rbs_map/core_map.rb +24 -17
- data/lib/solargraph/rbs_map/stdlib_map.rb +33 -5
- data/lib/solargraph/rbs_map.rb +76 -32
- data/lib/solargraph/server_methods.rb +1 -1
- data/lib/solargraph/shell.rb +258 -66
- data/lib/solargraph/source/chain/array.rb +4 -2
- data/lib/solargraph/source/chain/call.rb +96 -56
- data/lib/solargraph/source/chain/class_variable.rb +1 -1
- data/lib/solargraph/source/chain/constant.rb +5 -1
- data/lib/solargraph/source/chain/global_variable.rb +1 -1
- data/lib/solargraph/source/chain/hash.rb +8 -5
- data/lib/solargraph/source/chain/if.rb +12 -10
- data/lib/solargraph/source/chain/instance_variable.rb +24 -1
- data/lib/solargraph/source/chain/link.rb +12 -22
- data/lib/solargraph/source/chain/literal.rb +9 -6
- data/lib/solargraph/source/chain/or.rb +10 -4
- data/lib/solargraph/source/chain/q_call.rb +2 -0
- data/lib/solargraph/source/chain/variable.rb +3 -1
- data/lib/solargraph/source/chain/z_super.rb +1 -3
- data/lib/solargraph/source/chain.rb +51 -38
- data/lib/solargraph/source/change.rb +12 -5
- data/lib/solargraph/source/cursor.rb +23 -17
- data/lib/solargraph/source/encoding_fixes.rb +6 -7
- data/lib/solargraph/source/source_chainer.rb +56 -32
- data/lib/solargraph/source/updater.rb +5 -1
- data/lib/solargraph/source.rb +59 -35
- data/lib/solargraph/source_map/clip.rb +48 -29
- data/lib/solargraph/source_map/data.rb +4 -1
- data/lib/solargraph/source_map/mapper.rb +69 -42
- data/lib/solargraph/source_map.rb +21 -9
- data/lib/solargraph/type_checker/problem.rb +3 -1
- data/lib/solargraph/type_checker/rules.rb +81 -8
- data/lib/solargraph/type_checker.rb +195 -121
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +14 -11
- data/lib/solargraph/workspace/gemspecs.rb +367 -0
- data/lib/solargraph/workspace/require_paths.rb +1 -0
- data/lib/solargraph/workspace.rb +50 -28
- data/lib/solargraph/yard_map/helpers.rb +8 -3
- data/lib/solargraph/yard_map/mapper/to_method.rb +13 -7
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +2 -1
- data/lib/solargraph/yard_map/mapper.rb +13 -8
- data/lib/solargraph/yard_map.rb +17 -18
- data/lib/solargraph/yard_tags.rb +2 -2
- data/lib/solargraph/yardoc.rb +7 -4
- data/lib/solargraph.rb +31 -8
- data/rbs/fills/rubygems/0/dependency.rbs +193 -0
- data/rbs/fills/tuple/tuple.rbs +28 -0
- data/rbs/shims/ast/0/node.rbs +1 -1
- data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
- data/solargraph.gemspec +37 -35
- metadata +41 -41
- data/lib/solargraph/type_checker/checks.rb +0 -124
- data/lib/solargraph/type_checker/param_def.rb +0 -37
- data/lib/solargraph/yard_map/to_method.rb +0 -89
data/lib/solargraph/api_map.rb
CHANGED
|
@@ -24,12 +24,26 @@ module Solargraph
|
|
|
24
24
|
attr_reader :missing_docs
|
|
25
25
|
|
|
26
26
|
# @param pins [Array<Solargraph::Pin::Base>]
|
|
27
|
-
|
|
27
|
+
# @param loose_unions [Boolean] if true, a potential type can be
|
|
28
|
+
# inferred if ANY of the UniqueTypes in the base chain's
|
|
29
|
+
# ComplexType match it. If false, every single UniqueTypes in
|
|
30
|
+
# the base must be ALL able to independently provide this
|
|
31
|
+
# type. The former is useful during completion, but the
|
|
32
|
+
# latter is best for typechecking at higher levels.
|
|
33
|
+
#
|
|
34
|
+
def initialize pins: [], loose_unions: true
|
|
28
35
|
@source_map_hash = {}
|
|
29
36
|
@cache = Cache.new
|
|
37
|
+
@loose_unions = loose_unions
|
|
30
38
|
index pins
|
|
31
39
|
end
|
|
32
40
|
|
|
41
|
+
# @param out [StringIO, IO, nil] output stream for logging
|
|
42
|
+
# @return [void]
|
|
43
|
+
def self.reset_core out: nil
|
|
44
|
+
@@core_map = RbsMap::CoreMap.new
|
|
45
|
+
end
|
|
46
|
+
|
|
33
47
|
#
|
|
34
48
|
# This is a mutable object, which is cached in the Chain class -
|
|
35
49
|
# if you add any fields which change the results of calls (not
|
|
@@ -37,21 +51,24 @@ module Solargraph
|
|
|
37
51
|
#
|
|
38
52
|
|
|
39
53
|
# @param other [Object]
|
|
40
|
-
def eql?
|
|
54
|
+
def eql? other
|
|
41
55
|
self.class == other.class &&
|
|
42
|
-
# @sg-ignore
|
|
56
|
+
# @sg-ignore flow sensitive typing needs to handle self.class == other.class
|
|
43
57
|
equality_fields == other.equality_fields
|
|
44
58
|
end
|
|
45
59
|
|
|
46
60
|
# @param other [Object]
|
|
47
|
-
def ==
|
|
48
|
-
|
|
61
|
+
def == other
|
|
62
|
+
eql?(other)
|
|
49
63
|
end
|
|
50
64
|
|
|
65
|
+
# @return [Integer]
|
|
51
66
|
def hash
|
|
52
67
|
equality_fields.hash
|
|
53
68
|
end
|
|
54
69
|
|
|
70
|
+
attr_reader :loose_unions
|
|
71
|
+
|
|
55
72
|
def to_s
|
|
56
73
|
self.class.to_s
|
|
57
74
|
end
|
|
@@ -98,11 +115,12 @@ module Solargraph
|
|
|
98
115
|
end
|
|
99
116
|
unresolved_requires = (bench.external_requires + conventions_environ.requires + bench.workspace.config.required).to_a.compact.uniq
|
|
100
117
|
recreate_docmap = @unresolved_requires != unresolved_requires ||
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
118
|
+
# @sg-ignore Unresolved call to rbs_collection_path on Solargraph::Workspace, nil
|
|
119
|
+
workspace.rbs_collection_path != bench.workspace.rbs_collection_path ||
|
|
120
|
+
@doc_map.uncached_gemspecs.any?
|
|
121
|
+
|
|
104
122
|
if recreate_docmap
|
|
105
|
-
@doc_map = DocMap.new(unresolved_requires,
|
|
123
|
+
@doc_map = DocMap.new(unresolved_requires, bench.workspace, out: nil) # @todo Implement gem preferences
|
|
106
124
|
@unresolved_requires = @doc_map.unresolved_requires
|
|
107
125
|
end
|
|
108
126
|
@cache.clear if store.update(@@core_map.pins, @doc_map.pins, conventions_environ.pins, iced_pins, live_pins)
|
|
@@ -110,21 +128,14 @@ module Solargraph
|
|
|
110
128
|
self
|
|
111
129
|
end
|
|
112
130
|
|
|
113
|
-
# @todo need to model type def statement in chains as a symbol so
|
|
114
|
-
# that this overload of 'protected' will typecheck @sg-ignore
|
|
115
|
-
# @sg-ignore
|
|
116
|
-
protected def equality_fields
|
|
117
|
-
[self.class, @source_map_hash, conventions_environ, @doc_map, @unresolved_requires]
|
|
118
|
-
end
|
|
119
|
-
|
|
120
131
|
# @return [DocMap]
|
|
121
132
|
def doc_map
|
|
122
|
-
@doc_map ||= DocMap.new([],
|
|
133
|
+
@doc_map ||= DocMap.new([], Workspace.new('.'))
|
|
123
134
|
end
|
|
124
135
|
|
|
125
136
|
# @return [::Array<Gem::Specification>]
|
|
126
137
|
def uncached_gemspecs
|
|
127
|
-
|
|
138
|
+
doc_map.uncached_gemspecs || []
|
|
128
139
|
end
|
|
129
140
|
|
|
130
141
|
# @return [::Array<Gem::Specification>]
|
|
@@ -142,9 +153,10 @@ module Solargraph
|
|
|
142
153
|
@@core_map.pins
|
|
143
154
|
end
|
|
144
155
|
|
|
145
|
-
# @param name [String]
|
|
156
|
+
# @param name [String, nil]
|
|
146
157
|
# @return [YARD::Tags::MacroDirective, nil]
|
|
147
158
|
def named_macro name
|
|
159
|
+
# @sg-ignore Need to add nil check here
|
|
148
160
|
store.named_macros[name]
|
|
149
161
|
end
|
|
150
162
|
|
|
@@ -180,10 +192,11 @@ module Solargraph
|
|
|
180
192
|
# Create an ApiMap with a workspace in the specified directory.
|
|
181
193
|
#
|
|
182
194
|
# @param directory [String]
|
|
195
|
+
# @param loose_unions [Boolean] See #initialize
|
|
183
196
|
#
|
|
184
197
|
# @return [ApiMap]
|
|
185
|
-
def self.load directory
|
|
186
|
-
api_map = new
|
|
198
|
+
def self.load directory, loose_unions: true
|
|
199
|
+
api_map = new(loose_unions: loose_unions)
|
|
187
200
|
workspace = Solargraph::Workspace.new(directory)
|
|
188
201
|
# api_map.catalog Bench.new(workspace: workspace)
|
|
189
202
|
library = Library.new(workspace)
|
|
@@ -192,18 +205,19 @@ module Solargraph
|
|
|
192
205
|
api_map
|
|
193
206
|
end
|
|
194
207
|
|
|
195
|
-
# @param out [IO, nil]
|
|
208
|
+
# @param out [StringIO, IO, nil]
|
|
209
|
+
# @param rebuild [Boolean] whether to rebuild the pins even if they are cached
|
|
196
210
|
# @return [void]
|
|
197
|
-
def
|
|
198
|
-
|
|
211
|
+
def cache_all_for_doc_map! out: $stderr, rebuild: false
|
|
212
|
+
doc_map.cache_all!(out, rebuild: rebuild)
|
|
199
213
|
end
|
|
200
214
|
|
|
201
215
|
# @param gemspec [Gem::Specification]
|
|
202
216
|
# @param rebuild [Boolean]
|
|
203
|
-
# @param out [IO, nil]
|
|
217
|
+
# @param out [StringIO, IO, nil]
|
|
204
218
|
# @return [void]
|
|
205
|
-
def cache_gem
|
|
206
|
-
|
|
219
|
+
def cache_gem gemspec, rebuild: false, out: nil
|
|
220
|
+
doc_map.cache(gemspec, rebuild: rebuild, out: out)
|
|
207
221
|
end
|
|
208
222
|
|
|
209
223
|
class << self
|
|
@@ -215,18 +229,19 @@ module Solargraph
|
|
|
215
229
|
#
|
|
216
230
|
#
|
|
217
231
|
# @param directory [String]
|
|
218
|
-
# @param out [IO] The output stream for messages
|
|
232
|
+
# @param out [IO, StringIO, nil] The output stream for messages
|
|
233
|
+
# @param loose_unions [Boolean] See #initialize
|
|
219
234
|
#
|
|
220
235
|
# @return [ApiMap]
|
|
221
|
-
def self.load_with_cache directory, out
|
|
222
|
-
api_map = load(directory)
|
|
236
|
+
def self.load_with_cache directory, out = $stderr, loose_unions: true
|
|
237
|
+
api_map = load(directory, loose_unions: loose_unions)
|
|
223
238
|
if api_map.uncached_gemspecs.empty?
|
|
224
239
|
logger.info { "All gems cached for #{directory}" }
|
|
225
240
|
return api_map
|
|
226
241
|
end
|
|
227
242
|
|
|
228
|
-
api_map.
|
|
229
|
-
load(directory)
|
|
243
|
+
api_map.cache_all_for_doc_map!(out: out)
|
|
244
|
+
load(directory, loose_unions: loose_unions)
|
|
230
245
|
end
|
|
231
246
|
|
|
232
247
|
# @return [Array<Solargraph::Pin::Base>]
|
|
@@ -241,6 +256,12 @@ module Solargraph
|
|
|
241
256
|
store.pins_by_class(Pin::Keyword)
|
|
242
257
|
end
|
|
243
258
|
|
|
259
|
+
# @param name [String]
|
|
260
|
+
# @return [ComplexType, nil]
|
|
261
|
+
def unalias name
|
|
262
|
+
store.unalias(name)
|
|
263
|
+
end
|
|
264
|
+
|
|
244
265
|
# True if the namespace exists.
|
|
245
266
|
#
|
|
246
267
|
# @param name [String] The namespace to match
|
|
@@ -306,19 +327,19 @@ module Solargraph
|
|
|
306
327
|
#
|
|
307
328
|
# @param pin [Pin::Reference]
|
|
308
329
|
# @return [String, nil]
|
|
309
|
-
def dereference
|
|
330
|
+
def dereference pin
|
|
310
331
|
store.constants.dereference(pin)
|
|
311
332
|
end
|
|
312
333
|
|
|
313
334
|
# @param fqns [String]
|
|
314
335
|
# @return [Array<Pin::Reference::Extend>]
|
|
315
|
-
def get_extends
|
|
336
|
+
def get_extends fqns
|
|
316
337
|
store.get_extends(fqns)
|
|
317
338
|
end
|
|
318
339
|
|
|
319
340
|
# @param fqns [String]
|
|
320
341
|
# @return [Array<Pin::Reference::Include>]
|
|
321
|
-
def get_includes
|
|
342
|
+
def get_includes fqns
|
|
322
343
|
store.get_includes(fqns)
|
|
323
344
|
end
|
|
324
345
|
|
|
@@ -328,29 +349,47 @@ module Solargraph
|
|
|
328
349
|
# @param namespace [String] A fully qualified namespace
|
|
329
350
|
# @param scope [Symbol] :instance or :class
|
|
330
351
|
# @return [Array<Solargraph::Pin::InstanceVariable>]
|
|
331
|
-
def get_instance_variable_pins
|
|
352
|
+
def get_instance_variable_pins namespace, scope = :instance
|
|
332
353
|
result = []
|
|
333
|
-
|
|
354
|
+
[namespace]
|
|
334
355
|
result.concat store.get_instance_variables(namespace, scope)
|
|
335
356
|
sc_fqns = namespace
|
|
336
357
|
while (sc = store.get_superclass(sc_fqns))
|
|
358
|
+
# @sg-ignore flow sensitive typing needs to handle "if foo = bar"
|
|
337
359
|
sc_fqns = store.constants.dereference(sc)
|
|
338
360
|
result.concat store.get_instance_variables(sc_fqns, scope)
|
|
339
361
|
end
|
|
340
362
|
result
|
|
341
363
|
end
|
|
342
364
|
|
|
343
|
-
#
|
|
344
|
-
#
|
|
345
|
-
|
|
346
|
-
|
|
365
|
+
# Find a variable pin by name and where it is used.
|
|
366
|
+
#
|
|
367
|
+
# Resolves our most specific view of this variable's type by
|
|
368
|
+
# preferring pins created by flow-sensitive typing when we have
|
|
369
|
+
# them based on the Closure and Location.
|
|
370
|
+
#
|
|
371
|
+
# @param candidates [Array<Pin::BaseVariable>]
|
|
372
|
+
# @param name [String]
|
|
373
|
+
# @param closure [Pin::Closure]
|
|
374
|
+
# @param location [Location]
|
|
375
|
+
#
|
|
376
|
+
# @return [Pin::BaseVariable, nil]
|
|
377
|
+
def var_at_location candidates, name, closure, location
|
|
378
|
+
with_correct_name = candidates.select { |pin| pin.name == name }
|
|
379
|
+
vars_at_location = with_correct_name.reject do |pin|
|
|
380
|
+
# visible_at? excludes the starting position, but we want to
|
|
381
|
+
# include it for this purpose
|
|
382
|
+
!pin.visible_at?(closure, location) && !pin.starts_at?(location)
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
vars_at_location.inject(&:combine_with)
|
|
347
386
|
end
|
|
348
387
|
|
|
349
388
|
# Get an array of class variable pins for a namespace.
|
|
350
389
|
#
|
|
351
390
|
# @param namespace [String] A fully qualified namespace
|
|
352
391
|
# @return [Enumerable<Solargraph::Pin::ClassVariable>]
|
|
353
|
-
def get_class_variable_pins
|
|
392
|
+
def get_class_variable_pins namespace
|
|
354
393
|
prefer_non_nil_variables(store.get_class_variables(namespace))
|
|
355
394
|
end
|
|
356
395
|
|
|
@@ -417,7 +456,7 @@ module Solargraph
|
|
|
417
456
|
comments: init_pin.comments,
|
|
418
457
|
closure: init_pin.closure,
|
|
419
458
|
source: init_pin.source,
|
|
420
|
-
type_location: init_pin.type_location
|
|
459
|
+
type_location: init_pin.type_location
|
|
421
460
|
)
|
|
422
461
|
new_pin.parameters = init_pin.parameters.map do |init_param|
|
|
423
462
|
param = init_param.clone
|
|
@@ -476,7 +515,7 @@ module Solargraph
|
|
|
476
515
|
result = Set.new
|
|
477
516
|
complex_type.each do |type|
|
|
478
517
|
if type.duck_type?
|
|
479
|
-
result.add Pin::DuckMethod.new(name: type.to_s[1
|
|
518
|
+
result.add Pin::DuckMethod.new(name: type.to_s[1..], source: :api_map)
|
|
480
519
|
result.merge get_methods('Object')
|
|
481
520
|
else
|
|
482
521
|
unless type.nil? || type.name == 'void'
|
|
@@ -507,12 +546,14 @@ module Solargraph
|
|
|
507
546
|
# @param preserve_generics [Boolean] True to preserve any
|
|
508
547
|
# unresolved generic parameters, false to erase them
|
|
509
548
|
# @return [Array<Solargraph::Pin::Method>]
|
|
510
|
-
def get_method_stack rooted_tag, name, scope: :instance, visibility: [
|
|
549
|
+
def get_method_stack rooted_tag, name, scope: :instance, visibility: %i[private protected public],
|
|
550
|
+
preserve_generics: false
|
|
511
551
|
rooted_type = ComplexType.parse(rooted_tag)
|
|
512
552
|
fqns = rooted_type.namespace
|
|
513
553
|
namespace_pin = store.get_path_pins(fqns).first
|
|
514
554
|
methods = if namespace_pin.is_a?(Pin::Constant)
|
|
515
|
-
type = namespace_pin.
|
|
555
|
+
type = namespace_pin.typify(self)
|
|
556
|
+
type = namespace_pin.probe(self) unless type.defined?
|
|
516
557
|
if type.defined?
|
|
517
558
|
namespace_pin = store.get_path_pins(type.namespace).first
|
|
518
559
|
get_methods(type.namespace, scope: scope, visibility: visibility).select { |p| p.name == name }
|
|
@@ -630,18 +671,22 @@ module Solargraph
|
|
|
630
671
|
# @param sup [String] The superclass
|
|
631
672
|
# @param sub [String] The subclass
|
|
632
673
|
# @return [Boolean]
|
|
633
|
-
def super_and_sub?
|
|
674
|
+
def super_and_sub? sup, sub
|
|
634
675
|
sup = ComplexType.try_parse(sup)
|
|
635
676
|
sub = ComplexType.try_parse(sub)
|
|
636
677
|
# @todo If two literals are different values of the same type, it would
|
|
637
678
|
# make more sense for super_and_sub? to return true, but there are a
|
|
638
679
|
# few callers that currently expect this to be false.
|
|
680
|
+
# @sg-ignore flow-sensitive typing should be able to handle redefinition
|
|
639
681
|
return false if sup.literal? && sub.literal? && sup.to_s != sub.to_s
|
|
682
|
+
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
640
683
|
sup = sup.simplify_literals.to_s
|
|
684
|
+
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
641
685
|
sub = sub.simplify_literals.to_s
|
|
642
686
|
return true if sup == sub
|
|
643
687
|
sc_fqns = sub
|
|
644
688
|
while (sc = store.get_superclass(sc_fqns))
|
|
689
|
+
# @sg-ignore flow sensitive typing needs to handle "if foo = bar"
|
|
645
690
|
sc_new = store.constants.dereference(sc)
|
|
646
691
|
# Cyclical inheritance is invalid
|
|
647
692
|
return false if sc_new == sc_fqns
|
|
@@ -658,24 +703,32 @@ module Solargraph
|
|
|
658
703
|
# @param module_ns [String] The module namespace (no type parameters)
|
|
659
704
|
#
|
|
660
705
|
# @return [Boolean]
|
|
661
|
-
def type_include?
|
|
706
|
+
def type_include? host_ns, module_ns
|
|
662
707
|
store.get_includes(host_ns).map { |inc_tag| inc_tag.type.name }.include?(module_ns)
|
|
663
708
|
end
|
|
664
709
|
|
|
665
710
|
# @param pins [Enumerable<Pin::Base>]
|
|
666
711
|
# @param visibility [Enumerable<Symbol>]
|
|
667
712
|
# @return [Array<Pin::Base>]
|
|
668
|
-
def resolve_method_aliases pins, visibility = [
|
|
713
|
+
def resolve_method_aliases pins, visibility = %i[public private protected]
|
|
669
714
|
with_resolved_aliases = pins.map do |pin|
|
|
670
715
|
next pin unless pin.is_a?(Pin::MethodAlias)
|
|
671
716
|
resolved = resolve_method_alias(pin)
|
|
717
|
+
# @sg-ignore Need to add nil check here
|
|
672
718
|
next nil if resolved.respond_to?(:visibility) && !visibility.include?(resolved.visibility)
|
|
673
719
|
resolved
|
|
674
720
|
end.compact
|
|
675
|
-
logger.debug
|
|
721
|
+
logger.debug do
|
|
722
|
+
"ApiMap#resolve_method_aliases(pins=#{pins.map(&:name)}, visibility=#{visibility}) => #{with_resolved_aliases.map(&:name)}"
|
|
723
|
+
end
|
|
676
724
|
GemPins.combine_method_pins_by_path(with_resolved_aliases)
|
|
677
725
|
end
|
|
678
726
|
|
|
727
|
+
# @return [Workspace, nil]
|
|
728
|
+
def workspace
|
|
729
|
+
doc_map.workspace
|
|
730
|
+
end
|
|
731
|
+
|
|
679
732
|
# @param fq_reference_tag [String] A fully qualified whose method should be pulled in
|
|
680
733
|
# @param namespace_pin [Pin::Base] Namespace pin for the rooted_type
|
|
681
734
|
# parameter - used to pull generics information
|
|
@@ -687,7 +740,7 @@ module Solargraph
|
|
|
687
740
|
# @param skip [Set<String>]
|
|
688
741
|
# @param no_core [Boolean] Skip core classes if true
|
|
689
742
|
# @return [Array<Pin::Base>]
|
|
690
|
-
def inner_get_methods_from_reference
|
|
743
|
+
def inner_get_methods_from_reference fq_reference_tag, namespace_pin, type, scope, visibility, deep, skip, no_core
|
|
691
744
|
logger.debug { "ApiMap#add_methods_from_reference(type=#{type}) starting" }
|
|
692
745
|
|
|
693
746
|
# Ensure the types returned by the methods in the referenced
|
|
@@ -743,7 +796,7 @@ module Solargraph
|
|
|
743
796
|
def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false
|
|
744
797
|
rooted_type = ComplexType.parse(rooted_tag).force_rooted
|
|
745
798
|
fqns = rooted_type.namespace
|
|
746
|
-
|
|
799
|
+
rooted_type.all_params
|
|
747
800
|
namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first
|
|
748
801
|
return [] if no_core && fqns =~ /^(Object|BasicObject|Class|Module)$/
|
|
749
802
|
reqstr = "#{fqns}|#{scope}|#{visibility.sort}|#{deep}"
|
|
@@ -754,7 +807,9 @@ module Solargraph
|
|
|
754
807
|
# ensure we start out with any immediate methods in this
|
|
755
808
|
# namespace so we roughly match the same ordering of get_methods
|
|
756
809
|
# and obey the 'deep' instruction
|
|
757
|
-
direct_convention_methods, convention_methods_by_reference = environ.pins.partition
|
|
810
|
+
direct_convention_methods, convention_methods_by_reference = environ.pins.partition do |p|
|
|
811
|
+
p.namespace == rooted_tag
|
|
812
|
+
end
|
|
758
813
|
result.concat direct_convention_methods
|
|
759
814
|
|
|
760
815
|
if deep && scope == :instance
|
|
@@ -766,8 +821,10 @@ module Solargraph
|
|
|
766
821
|
# Store#get_methods doesn't know about full tags, just
|
|
767
822
|
# namespaces; resolving the generics in the method pins is this
|
|
768
823
|
# class' responsibility
|
|
769
|
-
methods = store.get_methods(fqns, scope: scope, visibility: visibility).sort{ |a, b| a.name <=> b.name }
|
|
770
|
-
logger.info
|
|
824
|
+
methods = store.get_methods(fqns, scope: scope, visibility: visibility).sort { |a, b| a.name <=> b.name }
|
|
825
|
+
logger.info do
|
|
826
|
+
"ApiMap#inner_get_methods(rooted_tag=#{rooted_tag.inspect}, scope=#{scope.inspect}, visibility=#{visibility.inspect}, deep=#{deep.inspect}, skip=#{skip.inspect}, fqns=#{fqns}) - added from store: #{methods}"
|
|
827
|
+
end
|
|
771
828
|
result.concat methods
|
|
772
829
|
if deep
|
|
773
830
|
result.concat convention_methods_by_reference
|
|
@@ -775,21 +832,27 @@ module Solargraph
|
|
|
775
832
|
if scope == :instance
|
|
776
833
|
store.get_includes(fqns).reverse.each do |ref|
|
|
777
834
|
in_tag = dereference(ref)
|
|
778
|
-
|
|
835
|
+
# @sg-ignore Need to add nil check here
|
|
836
|
+
result.concat inner_get_methods_from_reference(in_tag, namespace_pin, rooted_type, scope, visibility, deep,
|
|
837
|
+
skip, true)
|
|
779
838
|
end
|
|
780
839
|
rooted_sc_tag = qualify_superclass(rooted_tag)
|
|
781
840
|
unless rooted_sc_tag.nil?
|
|
782
|
-
result.concat inner_get_methods_from_reference(rooted_sc_tag, namespace_pin, rooted_type, scope,
|
|
841
|
+
result.concat inner_get_methods_from_reference(rooted_sc_tag, namespace_pin, rooted_type, scope,
|
|
842
|
+
visibility, true, skip, no_core)
|
|
783
843
|
end
|
|
784
844
|
else
|
|
785
|
-
logger.info
|
|
845
|
+
logger.info do
|
|
846
|
+
"ApiMap#inner_get_methods(#{fqns}, #{scope}, #{visibility}, #{deep}, #{skip}) - looking for get_extends() from #{fqns}"
|
|
847
|
+
end
|
|
786
848
|
store.get_extends(fqns).reverse.each do |em|
|
|
787
849
|
fqem = dereference(em)
|
|
788
850
|
result.concat inner_get_methods(fqem, :instance, visibility, deep, skip, true) unless fqem.nil?
|
|
789
851
|
end
|
|
790
852
|
rooted_sc_tag = qualify_superclass(rooted_tag)
|
|
791
853
|
unless rooted_sc_tag.nil?
|
|
792
|
-
result.concat inner_get_methods_from_reference(rooted_sc_tag, namespace_pin, rooted_type, scope,
|
|
854
|
+
result.concat inner_get_methods_from_reference(rooted_sc_tag, namespace_pin, rooted_type, scope,
|
|
855
|
+
visibility, true, skip, true)
|
|
793
856
|
end
|
|
794
857
|
unless no_core || fqns.empty?
|
|
795
858
|
type = get_namespace_type(fqns)
|
|
@@ -817,7 +880,7 @@ module Solargraph
|
|
|
817
880
|
def get_namespace_type fqns
|
|
818
881
|
return nil if fqns.nil?
|
|
819
882
|
# @type [Pin::Namespace, nil]
|
|
820
|
-
pin = store.get_path_pins(fqns).select{|p| p.is_a?(Pin::Namespace)}.first
|
|
883
|
+
pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first
|
|
821
884
|
return nil if pin.nil?
|
|
822
885
|
pin.type
|
|
823
886
|
end
|
|
@@ -841,18 +904,21 @@ module Solargraph
|
|
|
841
904
|
|
|
842
905
|
include Logging
|
|
843
906
|
|
|
844
|
-
private
|
|
845
|
-
|
|
846
907
|
# @param alias_pin [Pin::MethodAlias]
|
|
847
908
|
# @return [Pin::Method, nil]
|
|
848
|
-
def resolve_method_alias
|
|
909
|
+
def resolve_method_alias alias_pin
|
|
849
910
|
ancestors = store.get_ancestors(alias_pin.full_context.reduce_class_type.tag)
|
|
911
|
+
# @type [Pin::Method, nil]
|
|
850
912
|
original = nil
|
|
851
913
|
|
|
852
914
|
# Search each ancestor for the original method
|
|
853
915
|
ancestors.each do |ancestor_fqns|
|
|
854
916
|
next if ancestor_fqns.nil?
|
|
855
|
-
ancestor_method_path =
|
|
917
|
+
ancestor_method_path = if alias_pin.original == 'new' && alias_pin.scope == :class
|
|
918
|
+
"#{ancestor_fqns}#initialize"
|
|
919
|
+
else
|
|
920
|
+
"#{ancestor_fqns}#{alias_pin.scope == :instance ? '#' : '.'}#{alias_pin.original}"
|
|
921
|
+
end
|
|
856
922
|
|
|
857
923
|
# Search for the original method in the ancestor
|
|
858
924
|
original = store.get_path_pins(ancestor_method_path).find do |candidate_pin|
|
|
@@ -864,21 +930,29 @@ module Solargraph
|
|
|
864
930
|
break resolved if resolved
|
|
865
931
|
end
|
|
866
932
|
|
|
867
|
-
candidate_pin.is_a?(Pin::Method)
|
|
933
|
+
candidate_pin.is_a?(Pin::Method)
|
|
868
934
|
end
|
|
869
935
|
|
|
870
936
|
break if original
|
|
871
937
|
end
|
|
938
|
+
if original.nil?
|
|
939
|
+
# :nocov:
|
|
940
|
+
Solargraph.assert_or_log(:alias_target_missing) do
|
|
941
|
+
"Rejecting alias - target is missing while looking for #{alias_pin.full_context.tag} #{alias_pin.original} in #{alias_pin.scope} scope = #{alias_pin.inspect}"
|
|
942
|
+
end
|
|
943
|
+
return nil
|
|
944
|
+
# :nocov:
|
|
945
|
+
end
|
|
872
946
|
|
|
873
947
|
# @sg-ignore ignore `received nil` for original
|
|
874
|
-
create_resolved_alias_pin(alias_pin, original)
|
|
948
|
+
create_resolved_alias_pin(alias_pin, original)
|
|
875
949
|
end
|
|
876
950
|
|
|
877
951
|
# Fast path for creating resolved alias pins without individual method stack lookups
|
|
878
952
|
# @param alias_pin [Pin::MethodAlias] The alias pin to resolve
|
|
879
953
|
# @param original [Pin::Method] The original method pin that was already found
|
|
880
954
|
# @return [Pin::Method] The resolved method pin
|
|
881
|
-
def create_resolved_alias_pin
|
|
955
|
+
def create_resolved_alias_pin alias_pin, original
|
|
882
956
|
# Build the resolved method pin directly (same logic as resolve_method_alias but without lookup)
|
|
883
957
|
args = {
|
|
884
958
|
location: alias_pin.location,
|
|
@@ -894,7 +968,7 @@ module Solargraph
|
|
|
894
968
|
return_type: original.return_type,
|
|
895
969
|
source: :resolve_method_alias
|
|
896
970
|
}
|
|
897
|
-
resolved_pin = Pin::Method.new
|
|
971
|
+
resolved_pin = Pin::Method.new(**args)
|
|
898
972
|
|
|
899
973
|
# Clone signatures and parameters
|
|
900
974
|
resolved_pin.signatures.each do |sig|
|
|
@@ -916,7 +990,7 @@ module Solargraph
|
|
|
916
990
|
# @param rooted_type [ComplexType]
|
|
917
991
|
# @param pins [Enumerable<Pin::Base>]
|
|
918
992
|
# @return [Array<Pin::Base>]
|
|
919
|
-
def erase_generics
|
|
993
|
+
def erase_generics namespace_pin, rooted_type, pins
|
|
920
994
|
return pins unless should_erase_generics_when_done?(namespace_pin, rooted_type)
|
|
921
995
|
|
|
922
996
|
logger.debug("Erasing generics on namespace_pin=#{namespace_pin} / rooted_type=#{rooted_type}")
|
|
@@ -927,19 +1001,29 @@ module Solargraph
|
|
|
927
1001
|
|
|
928
1002
|
# @param namespace_pin [Pin::Namespace]
|
|
929
1003
|
# @param rooted_type [ComplexType]
|
|
930
|
-
def should_erase_generics_when_done?
|
|
1004
|
+
def should_erase_generics_when_done? namespace_pin, rooted_type
|
|
931
1005
|
has_generics?(namespace_pin) && !can_resolve_generics?(namespace_pin, rooted_type)
|
|
932
1006
|
end
|
|
933
1007
|
|
|
934
1008
|
# @param namespace_pin [Pin::Namespace, Pin::Constant]
|
|
935
|
-
def has_generics?
|
|
1009
|
+
def has_generics? namespace_pin
|
|
936
1010
|
namespace_pin.is_a?(Pin::Namespace) && !namespace_pin.generics.empty?
|
|
937
1011
|
end
|
|
938
1012
|
|
|
939
1013
|
# @param namespace_pin [Pin::Namespace]
|
|
940
1014
|
# @param rooted_type [ComplexType]
|
|
941
|
-
def can_resolve_generics?
|
|
1015
|
+
def can_resolve_generics? namespace_pin, rooted_type
|
|
942
1016
|
has_generics?(namespace_pin) && !rooted_type.all_params.empty?
|
|
943
1017
|
end
|
|
1018
|
+
|
|
1019
|
+
protected
|
|
1020
|
+
|
|
1021
|
+
# @todo need to model type def statement in chains as a symbol so
|
|
1022
|
+
# that this overload of 'protected' will typecheck @sg-ignore
|
|
1023
|
+
# @sg-ignore
|
|
1024
|
+
def equality_fields
|
|
1025
|
+
[self.class, @source_map_hash, conventions_environ, @doc_map, @unresolved_requires, @missing_docs,
|
|
1026
|
+
@loose_unions]
|
|
1027
|
+
end
|
|
944
1028
|
end
|
|
945
1029
|
end
|
data/lib/solargraph/bench.rb
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
3
|
module Solargraph
|
|
5
4
|
# A container of source maps and workspace data to be cataloged in an ApiMap.
|
|
6
5
|
#
|
|
@@ -30,11 +29,11 @@ module Solargraph
|
|
|
30
29
|
.to_set
|
|
31
30
|
end
|
|
32
31
|
|
|
32
|
+
# @sg-ignore flow sensitive typing needs better handling of ||= on lvars
|
|
33
33
|
# @return [Hash{String => SourceMap}]
|
|
34
34
|
def source_map_hash
|
|
35
35
|
# @todo Work around #to_h bug in current Ruby head (3.5) with #map#to_h
|
|
36
|
-
@source_map_hash ||= source_maps.
|
|
37
|
-
.to_h
|
|
36
|
+
@source_map_hash ||= source_maps.to_h { |s| [s.filename, s] }
|
|
38
37
|
end
|
|
39
38
|
|
|
40
39
|
# @return [Set<SourceMap>]
|