solargraph 0.54.0 → 0.58.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 +127 -0
- data/.github/workflows/plugins.yml +184 -6
- data/.github/workflows/rspec.yml +55 -5
- 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 +1279 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +171 -0
- data/README.md +20 -6
- data/Rakefile +125 -13
- data/bin/solargraph +8 -5
- data/lib/solargraph/api_map/cache.rb +13 -3
- data/lib/solargraph/api_map/constants.rb +279 -0
- data/lib/solargraph/api_map/index.rb +193 -0
- data/lib/solargraph/api_map/source_to_yard.rb +13 -4
- data/lib/solargraph/api_map/store.rb +207 -132
- data/lib/solargraph/api_map.rb +394 -261
- data/lib/solargraph/bench.rb +18 -1
- data/lib/solargraph/complex_type/type_methods.rb +29 -12
- data/lib/solargraph/complex_type/unique_type.rb +205 -26
- data/lib/solargraph/complex_type.rb +126 -26
- 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 +36 -4
- data/lib/solargraph/diagnostics/rubocop.rb +6 -1
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
- data/lib/solargraph/doc_map.rb +316 -64
- data/lib/solargraph/environ.rb +9 -2
- data/lib/solargraph/equality.rb +34 -0
- data/lib/solargraph/gem_pins.rb +64 -38
- data/lib/solargraph/language_server/host/dispatch.rb +2 -0
- data/lib/solargraph/language_server/host/message_worker.rb +54 -5
- data/lib/solargraph/language_server/host.rb +36 -18
- data/lib/solargraph/language_server/message/base.rb +20 -12
- 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/initialize.rb +3 -1
- data/lib/solargraph/language_server/message/text_document/completion.rb +0 -3
- data/lib/solargraph/language_server/message/text_document/definition.rb +5 -3
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +3 -3
- data/lib/solargraph/language_server/message/text_document/formatting.rb +23 -2
- data/lib/solargraph/language_server/message/text_document/hover.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +4 -3
- data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +2 -0
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -2
- data/lib/solargraph/language_server/progress.rb +27 -2
- data/lib/solargraph/language_server/request.rb +4 -1
- data/lib/solargraph/library.rb +83 -73
- data/lib/solargraph/location.rb +45 -1
- data/lib/solargraph/logging.rb +12 -2
- data/lib/solargraph/page.rb +3 -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_processor/base.rb +10 -5
- data/lib/solargraph/parser/node_processor.rb +26 -8
- data/lib/solargraph/parser/parser_gem/class_methods.rb +10 -18
- 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 +10 -19
- data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -0
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +26 -20
- 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 +14 -2
- data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +8 -7
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -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 +16 -6
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +64 -32
- 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 +3 -5
- data/lib/solargraph/pin/base.rb +417 -42
- data/lib/solargraph/pin/base_variable.rb +21 -12
- data/lib/solargraph/pin/block.rb +9 -26
- data/lib/solargraph/pin/breakable.rb +9 -0
- data/lib/solargraph/pin/callable.rb +231 -0
- data/lib/solargraph/pin/closure.rb +30 -10
- data/lib/solargraph/pin/common.rb +12 -7
- data/lib/solargraph/pin/constant.rb +2 -0
- data/lib/solargraph/pin/conversions.rb +3 -2
- data/lib/solargraph/pin/delegated_method.rb +20 -1
- data/lib/solargraph/pin/documenting.rb +16 -0
- data/lib/solargraph/pin/instance_variable.rb +2 -2
- data/lib/solargraph/pin/keyword.rb +7 -2
- data/lib/solargraph/pin/local_variable.rb +15 -7
- data/lib/solargraph/pin/method.rb +241 -70
- data/lib/solargraph/pin/method_alias.rb +3 -0
- data/lib/solargraph/pin/namespace.rb +21 -13
- data/lib/solargraph/pin/parameter.rb +94 -32
- data/lib/solargraph/pin/proxy_type.rb +17 -7
- 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 +17 -0
- data/lib/solargraph/pin/search.rb +6 -1
- data/lib/solargraph/pin/signature.rb +39 -121
- 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 +8 -2
- data/lib/solargraph/pin_cache.rb +245 -0
- data/lib/solargraph/position.rb +19 -0
- data/lib/solargraph/range.rb +23 -4
- data/lib/solargraph/rbs_map/conversions.rb +315 -99
- data/lib/solargraph/rbs_map/core_fills.rb +50 -16
- data/lib/solargraph/rbs_map/core_map.rb +41 -11
- data/lib/solargraph/rbs_map/stdlib_map.rb +15 -5
- data/lib/solargraph/rbs_map.rb +87 -16
- data/lib/solargraph/shell.rb +117 -17
- data/lib/solargraph/source/chain/array.rb +13 -8
- 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 +135 -66
- data/lib/solargraph/source/chain/constant.rb +3 -66
- data/lib/solargraph/source/chain/hash.rb +9 -3
- data/lib/solargraph/source/chain/head.rb +1 -1
- data/lib/solargraph/source/chain/if.rb +7 -2
- data/lib/solargraph/source/chain/link.rb +38 -6
- data/lib/solargraph/source/chain/literal.rb +27 -2
- data/lib/solargraph/source/chain/or.rb +2 -2
- data/lib/solargraph/source/chain/z_super.rb +1 -1
- data/lib/solargraph/source/chain.rb +140 -63
- data/lib/solargraph/source/change.rb +2 -2
- data/lib/solargraph/source/cursor.rb +4 -4
- data/lib/solargraph/source/source_chainer.rb +3 -3
- data/lib/solargraph/source.rb +110 -89
- data/lib/solargraph/source_map/clip.rb +22 -28
- data/lib/solargraph/source_map/data.rb +34 -0
- data/lib/solargraph/source_map/mapper.rb +11 -7
- data/lib/solargraph/source_map.rb +50 -43
- 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 +35 -8
- data/lib/solargraph/type_checker.rb +331 -189
- 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/views/environment.erb +3 -5
- data/lib/solargraph/workspace/config.rb +25 -5
- data/lib/solargraph/workspace/require_paths.rb +97 -0
- data/lib/solargraph/workspace.rb +53 -72
- data/lib/solargraph/yard_map/helpers.rb +29 -1
- data/lib/solargraph/yard_map/mapper/to_constant.rb +8 -5
- data/lib/solargraph/yard_map/mapper/to_method.rb +55 -19
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +11 -7
- data/lib/solargraph/yard_map/mapper.rb +5 -3
- data/lib/solargraph/yard_map/to_method.rb +6 -3
- data/lib/solargraph/yardoc.rb +45 -10
- data/lib/solargraph.rb +35 -1
- data/rbs/fills/bundler/0/bundler.rbs +4271 -0
- data/rbs/fills/open3/0/open3.rbs +172 -0
- data/rbs/fills/rubygems/0/basic_specification.rbs +326 -0
- data/rbs/fills/rubygems/0/errors.rbs +364 -0
- data/rbs/fills/rubygems/0/spec_fetcher.rbs +107 -0
- data/rbs/fills/rubygems/0/specification.rbs +1753 -0
- data/rbs/fills/tuple/tuple.rbs +149 -0
- data/rbs_collection.yaml +19 -0
- data/sig/shims/ast/0/node.rbs +5 -0
- data/sig/shims/ast/2.4/.rbs_meta.yaml +9 -0
- data/sig/shims/ast/2.4/ast.rbs +73 -0
- data/sig/shims/parser/3.2.0.1/builders/default.rbs +195 -0
- data/sig/shims/parser/3.2.0.1/manifest.yaml +7 -0
- data/sig/shims/parser/3.2.0.1/parser.rbs +201 -0
- data/sig/shims/parser/3.2.0.1/polyfill.rbs +4 -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 +32 -10
- metadata +237 -37
- data/lib/.rubocop.yml +0 -22
- data/lib/solargraph/cache.rb +0 -77
- data/lib/solargraph/parser/node_methods.rb +0 -83
data/lib/solargraph/pin/base.rb
CHANGED
|
@@ -8,13 +8,17 @@ module Solargraph
|
|
|
8
8
|
include Common
|
|
9
9
|
include Conversions
|
|
10
10
|
include Documenting
|
|
11
|
+
include Logging
|
|
11
12
|
|
|
12
13
|
# @return [YARD::CodeObjects::Base]
|
|
13
14
|
attr_reader :code_object
|
|
14
15
|
|
|
15
|
-
# @return [Solargraph::Location]
|
|
16
|
+
# @return [Solargraph::Location, nil]
|
|
16
17
|
attr_reader :location
|
|
17
18
|
|
|
19
|
+
# @return [Solargraph::Location, nil]
|
|
20
|
+
attr_reader :type_location
|
|
21
|
+
|
|
18
22
|
# @return [String]
|
|
19
23
|
attr_reader :name
|
|
20
24
|
|
|
@@ -24,15 +28,346 @@ module Solargraph
|
|
|
24
28
|
# @return [::Symbol]
|
|
25
29
|
attr_accessor :source
|
|
26
30
|
|
|
31
|
+
# @type [::Numeric, nil] A priority for determining if pins should be combined or not
|
|
32
|
+
# A nil priority is considered the be the lowest. All code, yard & rbs pins have nil priority
|
|
33
|
+
# Between 2 pins, the one with the higher priority gets chosen. If the priorities are equal, they are combined.
|
|
34
|
+
attr_reader :combine_priority
|
|
35
|
+
|
|
36
|
+
def presence_certain?
|
|
37
|
+
true
|
|
38
|
+
end
|
|
39
|
+
|
|
27
40
|
# @param location [Solargraph::Location, nil]
|
|
41
|
+
# @param type_location [Solargraph::Location, nil]
|
|
28
42
|
# @param closure [Solargraph::Pin::Closure, nil]
|
|
29
43
|
# @param name [String]
|
|
30
44
|
# @param comments [String]
|
|
31
|
-
|
|
45
|
+
# @param source [Symbol, nil]
|
|
46
|
+
# @param docstring [YARD::Docstring, nil]
|
|
47
|
+
# @param directives [::Array<YARD::Tags::Directive>, nil]
|
|
48
|
+
# @param combine_priority [::Numeric, nil] See attr_reader for combine_priority
|
|
49
|
+
def initialize location: nil, type_location: nil, closure: nil, source: nil, name: '', comments: '', docstring: nil, directives: nil, combine_priority: nil
|
|
32
50
|
@location = location
|
|
51
|
+
@type_location = type_location
|
|
33
52
|
@closure = closure
|
|
34
53
|
@name = name
|
|
35
54
|
@comments = comments
|
|
55
|
+
@source = source
|
|
56
|
+
@identity = nil
|
|
57
|
+
@docstring = docstring
|
|
58
|
+
@directives = directives
|
|
59
|
+
@combine_priority = combine_priority
|
|
60
|
+
|
|
61
|
+
assert_source_provided
|
|
62
|
+
assert_location_provided
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# @return [void]
|
|
66
|
+
def assert_location_provided
|
|
67
|
+
return unless best_location.nil? && %i[yardoc source rbs].include?(source)
|
|
68
|
+
|
|
69
|
+
Solargraph.assert_or_log(:best_location, "Neither location nor type_location provided - #{path} #{source} #{self.class}")
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# @return [Pin::Closure, nil]
|
|
73
|
+
def closure
|
|
74
|
+
Solargraph.assert_or_log(:closure, "Closure not set on #{self.class} #{name.inspect} from #{source.inspect}") unless @closure
|
|
75
|
+
# @type [Pin::Closure, nil]
|
|
76
|
+
@closure
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# @param other [self]
|
|
80
|
+
# @param attrs [Hash{::Symbol => Object}]
|
|
81
|
+
#
|
|
82
|
+
# @return [self]
|
|
83
|
+
def combine_with(other, attrs={})
|
|
84
|
+
raise "tried to combine #{other.class} with #{self.class}" unless other.class == self.class
|
|
85
|
+
priority_choice = choose_priority(other)
|
|
86
|
+
return priority_choice unless priority_choice.nil?
|
|
87
|
+
|
|
88
|
+
type_location = choose(other, :type_location)
|
|
89
|
+
location = choose(other, :location)
|
|
90
|
+
combined_name = combine_name(other)
|
|
91
|
+
new_attrs = {
|
|
92
|
+
location: location,
|
|
93
|
+
type_location: type_location,
|
|
94
|
+
name: combined_name,
|
|
95
|
+
closure: choose_pin_attr_with_same_name(other, :closure),
|
|
96
|
+
comments: choose_longer(other, :comments),
|
|
97
|
+
source: :combined,
|
|
98
|
+
docstring: choose(other, :docstring),
|
|
99
|
+
directives: combine_directives(other),
|
|
100
|
+
combine_priority: combine_priority
|
|
101
|
+
}.merge(attrs)
|
|
102
|
+
assert_same_macros(other)
|
|
103
|
+
logger.debug { "Base#combine_with(path=#{path}) - other.comments=#{other.comments.inspect}, self.comments = #{self.comments}" }
|
|
104
|
+
out = self.class.new(**new_attrs)
|
|
105
|
+
out.reset_generated!
|
|
106
|
+
out
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# @param other [self]
|
|
110
|
+
# @return [self, nil] Returns either the pin chosen based on priority or nil
|
|
111
|
+
# A nil return means that the combination process must proceed
|
|
112
|
+
def choose_priority(other)
|
|
113
|
+
if combine_priority.nil? && !other.combine_priority.nil?
|
|
114
|
+
return other
|
|
115
|
+
elsif other.combine_priority.nil? && !combine_priority.nil?
|
|
116
|
+
return self
|
|
117
|
+
elsif !combine_priority.nil? && !other.combine_priority.nil?
|
|
118
|
+
if combine_priority > other.combine_priority
|
|
119
|
+
return self
|
|
120
|
+
elsif combine_priority < other.combine_priority
|
|
121
|
+
return other
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
nil
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# @param other [self]
|
|
129
|
+
# @param attr [::Symbol]
|
|
130
|
+
# @sg-ignore
|
|
131
|
+
# @return [undefined]
|
|
132
|
+
def choose_longer(other, attr)
|
|
133
|
+
# @type [undefined]
|
|
134
|
+
val1 = send(attr)
|
|
135
|
+
# @type [undefined]
|
|
136
|
+
val2 = other.send(attr)
|
|
137
|
+
return val1 if val1 == val2
|
|
138
|
+
return val2 if val1.nil?
|
|
139
|
+
val1.length > val2.length ? val1 : val2
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# @param other [self]
|
|
143
|
+
# @return [::Array<YARD::Tags::Directive>, nil]
|
|
144
|
+
def combine_directives(other)
|
|
145
|
+
return self.directives if other.directives.empty?
|
|
146
|
+
return other.directives if directives.empty?
|
|
147
|
+
[directives + other.directives].uniq
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# @param other [self]
|
|
151
|
+
# @return [String]
|
|
152
|
+
def combine_name(other)
|
|
153
|
+
if needs_consistent_name? || other.needs_consistent_name?
|
|
154
|
+
assert_same(other, :name)
|
|
155
|
+
else
|
|
156
|
+
choose(other, :name)
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# @return [void]
|
|
161
|
+
def reset_generated!
|
|
162
|
+
# @return_type doesn't go here as subclasses tend to assign it
|
|
163
|
+
# themselves in constructors, and they will deal with setting
|
|
164
|
+
# it in any methods that call this
|
|
165
|
+
#
|
|
166
|
+
# @docstring also doesn't go here, as there is code which
|
|
167
|
+
# directly manipulates docstring without editing comments
|
|
168
|
+
# (e.g., Api::Map::Store#index processes overrides that way
|
|
169
|
+
#
|
|
170
|
+
# Same with @directives, @macros, @maybe_directives, which
|
|
171
|
+
# regenerate docstring
|
|
172
|
+
@deprecated = nil
|
|
173
|
+
reset_conversions
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def needs_consistent_name?
|
|
177
|
+
true
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# @sg-ignore def should infer as symbol - "Not enough arguments to Module#protected"
|
|
181
|
+
protected def equality_fields
|
|
182
|
+
[name, location, type_location, closure, source]
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# @param other [self]
|
|
186
|
+
# @return [ComplexType]
|
|
187
|
+
def combine_return_type(other)
|
|
188
|
+
if return_type.undefined?
|
|
189
|
+
other.return_type
|
|
190
|
+
elsif other.return_type.undefined?
|
|
191
|
+
return_type
|
|
192
|
+
elsif dodgy_return_type_source? && !other.dodgy_return_type_source?
|
|
193
|
+
other.return_type
|
|
194
|
+
elsif other.dodgy_return_type_source? && !dodgy_return_type_source?
|
|
195
|
+
return_type
|
|
196
|
+
else
|
|
197
|
+
all_items = return_type.items + other.return_type.items
|
|
198
|
+
if all_items.any? { |item| item.selfy? } && all_items.any? { |item| item.rooted_tag == context.reduce_class_type.rooted_tag }
|
|
199
|
+
# assume this was a declaration that should have said 'self'
|
|
200
|
+
all_items.delete_if { |item| item.rooted_tag == context.reduce_class_type.rooted_tag }
|
|
201
|
+
end
|
|
202
|
+
ComplexType.new(all_items)
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def dodgy_return_type_source?
|
|
207
|
+
# uses a lot of 'Object' instead of 'self'
|
|
208
|
+
location&.filename&.include?('core_ext/object/')
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# when choices are arbitrary, make sure the choice is consistent
|
|
212
|
+
#
|
|
213
|
+
# @param other [Pin::Base]
|
|
214
|
+
# @param attr [::Symbol]
|
|
215
|
+
#
|
|
216
|
+
# @return [Object, nil]
|
|
217
|
+
def choose(other, attr)
|
|
218
|
+
results = [self, other].map(&attr).compact
|
|
219
|
+
# true and false are different classes and can't be sorted
|
|
220
|
+
return true if results.any? { |r| r == true || r == false }
|
|
221
|
+
results.min
|
|
222
|
+
rescue
|
|
223
|
+
STDERR.puts("Problem handling #{attr} for \n#{self.inspect}\n and \n#{other.inspect}\n\n#{self.send(attr).inspect} vs #{other.send(attr).inspect}")
|
|
224
|
+
raise
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# @param other [self]
|
|
228
|
+
# @param attr [::Symbol]
|
|
229
|
+
# @sg-ignore
|
|
230
|
+
# @return [undefined]
|
|
231
|
+
def choose_node(other, attr)
|
|
232
|
+
if other.object_id < attr.object_id
|
|
233
|
+
other.send(attr)
|
|
234
|
+
else
|
|
235
|
+
send(attr)
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# @param other [self]
|
|
240
|
+
# @param attr [::Symbol]
|
|
241
|
+
# @sg-ignore
|
|
242
|
+
# @return [undefined]
|
|
243
|
+
def prefer_rbs_location(other, attr)
|
|
244
|
+
if rbs_location? && !other.rbs_location?
|
|
245
|
+
self.send(attr)
|
|
246
|
+
elsif !rbs_location? && other.rbs_location?
|
|
247
|
+
other.send(attr)
|
|
248
|
+
else
|
|
249
|
+
choose(other, attr)
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def rbs_location?
|
|
254
|
+
type_location&.rbs?
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
# @param other [self]
|
|
258
|
+
# @return [void]
|
|
259
|
+
def assert_same_macros(other)
|
|
260
|
+
return unless self.source == :yardoc && other.source == :yardoc
|
|
261
|
+
assert_same_count(other, :macros)
|
|
262
|
+
# @param [YARD::Tags::MacroDirective]
|
|
263
|
+
assert_same_array_content(other, :macros) { |macro| macro.tag.name }
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# @param other [self]
|
|
267
|
+
# @param attr [::Symbol]
|
|
268
|
+
# @return [void]
|
|
269
|
+
# @todo strong typechecking should complain when there are no block-related tags
|
|
270
|
+
def assert_same_array_content(other, attr, &block)
|
|
271
|
+
arr1 = send(attr)
|
|
272
|
+
raise "Expected #{attr} on #{self} to be an Enumerable, got #{arr1.class}" unless arr1.is_a?(::Enumerable)
|
|
273
|
+
# @type arr1 [::Enumerable]
|
|
274
|
+
arr2 = other.send(attr)
|
|
275
|
+
raise "Expected #{attr} on #{other} to be an Enumerable, got #{arr2.class}" unless arr2.is_a?(::Enumerable)
|
|
276
|
+
# @type arr2 [::Enumerable]
|
|
277
|
+
|
|
278
|
+
# @type [undefined]
|
|
279
|
+
values1 = arr1.map(&block)
|
|
280
|
+
# @type [undefined]
|
|
281
|
+
values2 = arr2.map(&block)
|
|
282
|
+
# @sg-ignore
|
|
283
|
+
return arr1 if values1 == values2
|
|
284
|
+
Solargraph.assert_or_log("combine_with_#{attr}".to_sym,
|
|
285
|
+
"Inconsistent #{attr.inspect} values between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self values = #{values1}\nother values =#{attr} = #{values2}")
|
|
286
|
+
arr1
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
# @param other [self]
|
|
290
|
+
# @param attr [::Symbol]
|
|
291
|
+
#
|
|
292
|
+
# @return [::Enumerable]
|
|
293
|
+
def assert_same_count(other, attr)
|
|
294
|
+
# @type [::Enumerable]
|
|
295
|
+
arr1 = self.send(attr)
|
|
296
|
+
raise "Expected #{attr} on #{self} to be an Enumerable, got #{arr1.class}" unless arr1.is_a?(::Enumerable)
|
|
297
|
+
# @type [::Enumerable]
|
|
298
|
+
arr2 = other.send(attr)
|
|
299
|
+
raise "Expected #{attr} on #{other} to be an Enumerable, got #{arr2.class}" unless arr2.is_a?(::Enumerable)
|
|
300
|
+
return arr1 if arr1.count == arr2.count
|
|
301
|
+
Solargraph.assert_or_log("combine_with_#{attr}".to_sym,
|
|
302
|
+
"Inconsistent #{attr.inspect} count value between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self.#{attr} = #{arr1.inspect}\nother.#{attr} = #{arr2.inspect}")
|
|
303
|
+
arr1
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# @param other [self]
|
|
307
|
+
# @param attr [::Symbol]
|
|
308
|
+
#
|
|
309
|
+
# @sg-ignore
|
|
310
|
+
# @return [undefined]
|
|
311
|
+
def assert_same(other, attr)
|
|
312
|
+
return false if other.nil?
|
|
313
|
+
val1 = send(attr)
|
|
314
|
+
val2 = other.send(attr)
|
|
315
|
+
return val1 if val1 == val2
|
|
316
|
+
Solargraph.assert_or_log("combine_with_#{attr}".to_sym,
|
|
317
|
+
"Inconsistent #{attr.inspect} values between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self.#{attr} = #{val1.inspect}\nother.#{attr} = #{val2.inspect}")
|
|
318
|
+
val1
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
# @param other [self]
|
|
322
|
+
# @param attr [::Symbol]
|
|
323
|
+
# @sg-ignore
|
|
324
|
+
# @return [undefined]
|
|
325
|
+
def choose_pin_attr_with_same_name(other, attr)
|
|
326
|
+
# @type [Pin::Base, nil]
|
|
327
|
+
val1 = send(attr)
|
|
328
|
+
# @type [Pin::Base, nil]
|
|
329
|
+
val2 = other.send(attr)
|
|
330
|
+
raise "Expected pin for #{attr} on\n#{self.inspect},\ngot #{val1.inspect}" unless val1.nil? || val1.is_a?(Pin::Base)
|
|
331
|
+
raise "Expected pin for #{attr} on\n#{other.inspect},\ngot #{val2.inspect}" unless val2.nil? || val2.is_a?(Pin::Base)
|
|
332
|
+
if val1&.name != val2&.name
|
|
333
|
+
Solargraph.assert_or_log("combine_with_#{attr}_name".to_sym,
|
|
334
|
+
"Inconsistent #{attr.inspect} name values between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self.#{attr} = #{val1.inspect}\nother.#{attr} = #{val2.inspect}")
|
|
335
|
+
end
|
|
336
|
+
choose_pin_attr(other, attr)
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
# @param other [self]
|
|
340
|
+
# @param attr [::Symbol]
|
|
341
|
+
#
|
|
342
|
+
# @sg-ignore Missing @return tag for Solargraph::Pin::Base#choose_pin_attr
|
|
343
|
+
# @return [undefined]
|
|
344
|
+
def choose_pin_attr(other, attr)
|
|
345
|
+
# @type [Pin::Base, nil]
|
|
346
|
+
val1 = send(attr)
|
|
347
|
+
# @type [Pin::Base, nil]
|
|
348
|
+
val2 = other.send(attr)
|
|
349
|
+
if val1.class != val2.class
|
|
350
|
+
# :nocov:
|
|
351
|
+
Solargraph.assert_or_log("combine_with_#{attr}_class".to_sym,
|
|
352
|
+
"Inconsistent #{attr.inspect} class values between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self.#{attr} = #{val1.inspect}\nother.#{attr} = #{val2.inspect}")
|
|
353
|
+
return val1
|
|
354
|
+
# :nocov:
|
|
355
|
+
end
|
|
356
|
+
# arbitrary way of choosing a pin
|
|
357
|
+
[val1, val2].compact.max_by do |closure|
|
|
358
|
+
[
|
|
359
|
+
# maximize number of gates, as types in other combined pins may
|
|
360
|
+
# depend on those gates
|
|
361
|
+
closure.gates.length,
|
|
362
|
+
# use basename so that results don't vary system to system
|
|
363
|
+
File.basename(closure.best_location.to_s)
|
|
364
|
+
]
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
# @return [void]
|
|
369
|
+
def assert_source_provided
|
|
370
|
+
Solargraph.assert_or_log(:source, "source not provided - #{@path} #{@source} #{self.class}") if source.nil?
|
|
36
371
|
end
|
|
37
372
|
|
|
38
373
|
# @return [String]
|
|
@@ -66,11 +401,14 @@ module Solargraph
|
|
|
66
401
|
# @param context_type [ComplexType] The receiver type
|
|
67
402
|
# @return [self]
|
|
68
403
|
def resolve_generics definitions, context_type
|
|
69
|
-
|
|
70
|
-
|
|
404
|
+
transform_types { |t| t.resolve_generics(definitions, context_type) if t }
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
def all_rooted?
|
|
408
|
+
!return_type || return_type.all_rooted?
|
|
71
409
|
end
|
|
72
410
|
|
|
73
|
-
# @param generics_to_erase [
|
|
411
|
+
# @param generics_to_erase [::Array<String>]
|
|
74
412
|
# @return [self]
|
|
75
413
|
def erase_generics(generics_to_erase)
|
|
76
414
|
return self if generics_to_erase.empty?
|
|
@@ -94,7 +432,7 @@ module Solargraph
|
|
|
94
432
|
end
|
|
95
433
|
|
|
96
434
|
def to_s
|
|
97
|
-
|
|
435
|
+
desc
|
|
98
436
|
end
|
|
99
437
|
|
|
100
438
|
# @return [Boolean]
|
|
@@ -102,12 +440,9 @@ module Solargraph
|
|
|
102
440
|
false
|
|
103
441
|
end
|
|
104
442
|
|
|
105
|
-
#
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
def == other
|
|
109
|
-
return false unless nearly? other
|
|
110
|
-
comments == other.comments and location == other.location
|
|
443
|
+
# @return [Location, nil]
|
|
444
|
+
def best_location
|
|
445
|
+
location || type_location
|
|
111
446
|
end
|
|
112
447
|
|
|
113
448
|
# True if the specified pin is a near match to this one. A near match
|
|
@@ -126,6 +461,16 @@ module Solargraph
|
|
|
126
461
|
)
|
|
127
462
|
end
|
|
128
463
|
|
|
464
|
+
# Pin equality is determined using the #nearly? method and also
|
|
465
|
+
# requiring both pins to have the same location.
|
|
466
|
+
#
|
|
467
|
+
# @param other [Object]
|
|
468
|
+
def == other
|
|
469
|
+
return false unless nearly? other
|
|
470
|
+
# @sg-ignore Should add more explicit type check on other
|
|
471
|
+
comments == other.comments && location == other.location
|
|
472
|
+
end
|
|
473
|
+
|
|
129
474
|
# The pin's return type.
|
|
130
475
|
#
|
|
131
476
|
# @return [ComplexType]
|
|
@@ -135,13 +480,13 @@ module Solargraph
|
|
|
135
480
|
|
|
136
481
|
# @return [YARD::Docstring]
|
|
137
482
|
def docstring
|
|
138
|
-
parse_comments unless
|
|
483
|
+
parse_comments unless @docstring
|
|
139
484
|
@docstring ||= Solargraph::Source.parse_docstring('').to_docstring
|
|
140
485
|
end
|
|
141
486
|
|
|
142
487
|
# @return [::Array<YARD::Tags::Directive>]
|
|
143
488
|
def directives
|
|
144
|
-
parse_comments unless
|
|
489
|
+
parse_comments unless @directives
|
|
145
490
|
@directives
|
|
146
491
|
end
|
|
147
492
|
|
|
@@ -159,7 +504,7 @@ module Solargraph
|
|
|
159
504
|
#
|
|
160
505
|
# @return [Boolean]
|
|
161
506
|
def maybe_directives?
|
|
162
|
-
return !@directives.empty? if defined?(@directives)
|
|
507
|
+
return !@directives.empty? if defined?(@directives) && @directives
|
|
163
508
|
@maybe_directives ||= comments.include?('@!')
|
|
164
509
|
end
|
|
165
510
|
|
|
@@ -177,7 +522,7 @@ module Solargraph
|
|
|
177
522
|
# @param api_map [ApiMap]
|
|
178
523
|
# @return [ComplexType]
|
|
179
524
|
def typify api_map
|
|
180
|
-
return_type.qualify(api_map,
|
|
525
|
+
return_type.qualify(api_map, *(closure&.gates || ['']))
|
|
181
526
|
end
|
|
182
527
|
|
|
183
528
|
# Infer the pin's return type via static code analysis.
|
|
@@ -198,26 +543,6 @@ module Solargraph
|
|
|
198
543
|
probe api_map
|
|
199
544
|
end
|
|
200
545
|
|
|
201
|
-
# Try to merge data from another pin. Merges are only possible if the
|
|
202
|
-
# pins are near matches (see the #nearly? method). The changes should
|
|
203
|
-
# not have any side effects on the API surface.
|
|
204
|
-
#
|
|
205
|
-
# @param pin [Pin::Base] The pin to merge into this one
|
|
206
|
-
# @return [Boolean] True if the pins were merged
|
|
207
|
-
def try_merge! pin
|
|
208
|
-
return false unless nearly?(pin)
|
|
209
|
-
@location = pin.location
|
|
210
|
-
@closure = pin.closure
|
|
211
|
-
return true if comments == pin.comments
|
|
212
|
-
@comments = pin.comments
|
|
213
|
-
@docstring = pin.docstring
|
|
214
|
-
@return_type = pin.return_type
|
|
215
|
-
@documentation = nil
|
|
216
|
-
@deprecated = nil
|
|
217
|
-
reset_conversions
|
|
218
|
-
true
|
|
219
|
-
end
|
|
220
|
-
|
|
221
546
|
def proxied?
|
|
222
547
|
@proxied ||= false
|
|
223
548
|
end
|
|
@@ -252,9 +577,22 @@ module Solargraph
|
|
|
252
577
|
result
|
|
253
578
|
end
|
|
254
579
|
|
|
580
|
+
# @deprecated
|
|
255
581
|
# @return [String]
|
|
256
582
|
def identity
|
|
257
|
-
@identity ||= "#{closure
|
|
583
|
+
@identity ||= "#{closure&.path}|#{name}|#{location}"
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
# The namespaces available for resolving the current namespace. Each gate
|
|
587
|
+
# should be a fully qualified namespace or the root namespace (i.e., an
|
|
588
|
+
# empty string.)
|
|
589
|
+
#
|
|
590
|
+
# Example: Given the name 'Bar' and the gates ['Foo', ''],
|
|
591
|
+
# the fully qualified namespace should be 'Foo::Bar' or 'Bar'.
|
|
592
|
+
#
|
|
593
|
+
# @return [Array<String>]
|
|
594
|
+
def gates
|
|
595
|
+
@gates ||= closure&.gates || ['']
|
|
258
596
|
end
|
|
259
597
|
|
|
260
598
|
# @return [String, nil]
|
|
@@ -263,20 +601,53 @@ module Solargraph
|
|
|
263
601
|
end
|
|
264
602
|
|
|
265
603
|
# @return [String, nil]
|
|
266
|
-
def
|
|
604
|
+
def type_desc
|
|
605
|
+
rbs = to_rbs
|
|
606
|
+
# RBS doesn't have a way to represent a Class<x> type
|
|
607
|
+
rbs = return_type.rooted_tags if return_type.name == 'Class'
|
|
267
608
|
if path
|
|
268
|
-
if
|
|
269
|
-
path + ' ' +
|
|
609
|
+
if rbs
|
|
610
|
+
path + ' ' + rbs
|
|
270
611
|
else
|
|
271
612
|
path
|
|
272
613
|
end
|
|
273
614
|
else
|
|
274
|
-
|
|
615
|
+
rbs
|
|
275
616
|
end
|
|
276
617
|
end
|
|
277
618
|
|
|
619
|
+
# @return [String]
|
|
620
|
+
def inner_desc
|
|
621
|
+
closure_info = closure&.desc
|
|
622
|
+
binder_info = binder&.desc
|
|
623
|
+
"name=#{name.inspect} return_type=#{type_desc}, context=#{context.rooted_tags}, closure=#{closure_info}, binder=#{binder_info}"
|
|
624
|
+
end
|
|
625
|
+
|
|
626
|
+
# @return [String]
|
|
627
|
+
def desc
|
|
628
|
+
"[#{inner_desc}]"
|
|
629
|
+
end
|
|
630
|
+
|
|
631
|
+
# @return [String]
|
|
278
632
|
def inspect
|
|
279
|
-
"#<#{self.class} `#{self.
|
|
633
|
+
"#<#{self.class} `#{self.inner_desc}`#{all_location_text} via #{source.inspect}>"
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
# @return [String]
|
|
637
|
+
def all_location_text
|
|
638
|
+
if location.nil? && type_location.nil?
|
|
639
|
+
''
|
|
640
|
+
elsif !location.nil? && type_location.nil?
|
|
641
|
+
" at #{location.inspect})"
|
|
642
|
+
elsif !type_location.nil? && location.nil?
|
|
643
|
+
" at #{type_location.inspect})"
|
|
644
|
+
else
|
|
645
|
+
" at (#{location.inspect} and #{type_location.inspect})"
|
|
646
|
+
end
|
|
647
|
+
end
|
|
648
|
+
|
|
649
|
+
# @return [void]
|
|
650
|
+
def reset_generated!
|
|
280
651
|
end
|
|
281
652
|
|
|
282
653
|
protected
|
|
@@ -290,6 +661,10 @@ module Solargraph
|
|
|
290
661
|
# @return [ComplexType]
|
|
291
662
|
attr_writer :return_type
|
|
292
663
|
|
|
664
|
+
attr_writer :docstring
|
|
665
|
+
|
|
666
|
+
attr_writer :directives
|
|
667
|
+
|
|
293
668
|
private
|
|
294
669
|
|
|
295
670
|
# @return [void]
|
|
@@ -3,20 +3,32 @@
|
|
|
3
3
|
module Solargraph
|
|
4
4
|
module Pin
|
|
5
5
|
class BaseVariable < Base
|
|
6
|
-
include Solargraph::Parser::NodeMethods
|
|
7
6
|
# include Solargraph::Source::NodeMethods
|
|
7
|
+
include Solargraph::Parser::NodeMethods
|
|
8
8
|
|
|
9
9
|
# @return [Parser::AST::Node, nil]
|
|
10
10
|
attr_reader :assignment
|
|
11
11
|
|
|
12
12
|
attr_accessor :mass_assignment
|
|
13
13
|
|
|
14
|
+
# @param return_type [ComplexType, nil]
|
|
15
|
+
# @param mass_assignment [::Array(Parser::AST::Node, Integer), nil]
|
|
14
16
|
# @param assignment [Parser::AST::Node, nil]
|
|
15
|
-
def initialize assignment: nil, **splat
|
|
17
|
+
def initialize assignment: nil, return_type: nil, mass_assignment: nil, **splat
|
|
16
18
|
super(**splat)
|
|
17
19
|
@assignment = assignment
|
|
18
20
|
# @type [nil, ::Array(Parser::AST::Node, Integer)]
|
|
19
21
|
@mass_assignment = nil
|
|
22
|
+
@return_type = return_type
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def combine_with(other, attrs={})
|
|
26
|
+
new_attrs = attrs.merge({
|
|
27
|
+
assignment: assert_same(other, :assignment),
|
|
28
|
+
mass_assignment: assert_same(other, :mass_assignment),
|
|
29
|
+
return_type: combine_return_type(other),
|
|
30
|
+
})
|
|
31
|
+
super(other, new_attrs)
|
|
20
32
|
end
|
|
21
33
|
|
|
22
34
|
def completion_item_kind
|
|
@@ -33,6 +45,8 @@ module Solargraph
|
|
|
33
45
|
end
|
|
34
46
|
|
|
35
47
|
def nil_assignment?
|
|
48
|
+
# this will always be false - should it be return_type ==
|
|
49
|
+
# ComplexType::NIL or somesuch?
|
|
36
50
|
return_type.nil?
|
|
37
51
|
end
|
|
38
52
|
|
|
@@ -57,7 +71,7 @@ module Solargraph
|
|
|
57
71
|
# Use the return node for inference. The clip might infer from the
|
|
58
72
|
# first node in a method call instead of the entire call.
|
|
59
73
|
chain = Parser.chain(node, nil, nil)
|
|
60
|
-
result = chain.infer(api_map, closure, clip.locals).
|
|
74
|
+
result = chain.infer(api_map, closure, clip.locals).self_to_type(closure.context)
|
|
61
75
|
types.push result unless result.undefined?
|
|
62
76
|
end
|
|
63
77
|
end
|
|
@@ -88,20 +102,15 @@ module Solargraph
|
|
|
88
102
|
ComplexType::UNDEFINED
|
|
89
103
|
end
|
|
90
104
|
|
|
105
|
+
# @param other [Object]
|
|
91
106
|
def == other
|
|
92
107
|
return false unless super
|
|
108
|
+
# @sg-ignore Should add type check on other
|
|
93
109
|
assignment == other.assignment
|
|
94
110
|
end
|
|
95
111
|
|
|
96
|
-
def
|
|
97
|
-
|
|
98
|
-
@assignment = pin.assignment
|
|
99
|
-
@return_type = pin.return_type
|
|
100
|
-
true
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def desc
|
|
104
|
-
"#{to_rbs} = #{assignment&.type.inspect}"
|
|
112
|
+
def type_desc
|
|
113
|
+
"#{super} = #{assignment&.type.inspect}"
|
|
105
114
|
end
|
|
106
115
|
|
|
107
116
|
private
|