solargraph 0.53.1 → 0.53.3
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/CHANGELOG.md +12 -0
- data/lib/solargraph/api_map/source_to_yard.rb +17 -10
- data/lib/solargraph/api_map.rb +1 -13
- data/lib/solargraph/complex_type/unique_type.rb +32 -9
- data/lib/solargraph/doc_map.rb +44 -21
- data/lib/solargraph/gem_pins.rb +1 -1
- data/lib/solargraph/language_server/host/dispatch.rb +5 -1
- data/lib/solargraph/language_server/host.rb +2 -1
- data/lib/solargraph/library.rb +14 -2
- data/lib/solargraph/page.rb +6 -0
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +6 -19
- data/lib/solargraph/pin/base_variable.rb +1 -1
- data/lib/solargraph/pin/block.rb +10 -27
- data/lib/solargraph/rbs_map/conversions.rb +2 -39
- data/lib/solargraph/rbs_map/core_fills.rb +9 -6
- data/lib/solargraph/rbs_map/core_map.rb +2 -13
- data/lib/solargraph/rbs_map.rb +6 -4
- data/lib/solargraph/source_map/clip.rb +2 -2
- data/lib/solargraph/source_map.rb +0 -8
- data/lib/solargraph/type_checker.rb +21 -2
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace.rb +14 -1
- metadata +2 -3
- data/lib/solargraph/rbs_map/core_signs.rb +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c5f84e528dd40d7638e36189ca6b4dceccdfd1722a07bd1c1f060bf0265aa815
|
4
|
+
data.tar.gz: 39d6938ccabce6dda403c709711f6136472def5982222e73d89310eaeb906ee1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf06b94032becde9f26b7d5cedcecbc0fd7d6bde539a980c748328f11165f91398605e7ff49af502b83a70a4aa9b32406c5846cda96f5246d20c97d17220700b
|
7
|
+
data.tar.gz: bdddccf5d52efd2a9be2b00ac473065ecca21d76646d59d247c5cb93b14de137ebfc16ec4ffbc3ed0d6e9de9f271e9763808775d6aa271496e6328bf70b443bf
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
## 0.53.3 - March 29, 2025
|
2
|
+
- Remove redundant core fills (#824, #841)
|
3
|
+
- Resolve self type in variable assignments (#839)
|
4
|
+
- Eliminate splat-related false-alarms in strict typechecking (#840)
|
5
|
+
- Dynamic block binding with yieldreceiver (#842)
|
6
|
+
- Resolve generics by descending through context type (#847)
|
7
|
+
|
8
|
+
## 0.53.2 - March 27, 2025
|
9
|
+
- Fix a self-type-related false-positive in strict typechecking (#834)
|
10
|
+
- DocMap fetches gem dependencies (#835)
|
11
|
+
- Use configured command path to spawn solargraph processes (#837)
|
12
|
+
|
1
13
|
## 0.53.1 - March 26, 2025
|
2
14
|
- Reject nil requires in live code (#831)
|
3
15
|
- RbsMap adds mixins to current namespace (#832)
|
@@ -6,10 +6,13 @@ module Solargraph
|
|
6
6
|
|
7
7
|
# Get the YARD CodeObject at the specified path.
|
8
8
|
#
|
9
|
+
# @generic T
|
9
10
|
# @param path [String]
|
10
|
-
# @
|
11
|
-
|
12
|
-
|
11
|
+
# @param klass [Class<generic<T>>]
|
12
|
+
# @return [generic<T>, nil]
|
13
|
+
def code_object_at path, klass = YARD::CodeObjects::Base
|
14
|
+
obj = code_object_map[path]
|
15
|
+
obj if obj&.is_a?(klass)
|
13
16
|
end
|
14
17
|
|
15
18
|
# @return [Array<String>]
|
@@ -41,11 +44,13 @@ module Solargraph
|
|
41
44
|
end
|
42
45
|
code_object_map[pin.path].docstring = pin.docstring
|
43
46
|
store.get_includes(pin.path).each do |ref|
|
44
|
-
|
47
|
+
include_object = code_object_at(pin.path, YARD::CodeObjects::ClassObject)
|
48
|
+
include_object.instance_mixins.push code_object_map[ref] unless include_object.nil? or include_object.nil?
|
45
49
|
end
|
46
50
|
store.get_extends(pin.path).each do |ref|
|
47
|
-
|
48
|
-
|
51
|
+
extend_object = code_object_at(pin.path, YARD::CodeObjects::ClassObject)
|
52
|
+
extend_object.instance_mixins.push code_object_map[ref] unless extend_object.nil? or extend_object.nil?
|
53
|
+
extend_object.class_mixins.push code_object_map[ref] unless extend_object.nil? or extend_object.nil?
|
49
54
|
end
|
50
55
|
end
|
51
56
|
store.method_pins.each do |pin|
|
@@ -53,13 +58,15 @@ module Solargraph
|
|
53
58
|
code_object_map[pin.path] ||= pin.code_object
|
54
59
|
next
|
55
60
|
end
|
56
|
-
|
61
|
+
|
62
|
+
code_object_map[pin.path] ||= YARD::CodeObjects::MethodObject.new(code_object_at(pin.namespace, YARD::CodeObjects::NamespaceObject), pin.name, pin.scope) { |obj|
|
57
63
|
next if pin.location.nil? || pin.location.filename.nil?
|
58
64
|
obj.add_file pin.location.filename, pin.location.range.start.line
|
59
65
|
}
|
60
|
-
|
61
|
-
|
62
|
-
|
66
|
+
method_object = code_object_at(pin.path, YARD::CodeObjects::MethodObject)
|
67
|
+
method_object.docstring = pin.docstring
|
68
|
+
method_object.visibility = pin.visibility || :public
|
69
|
+
method_object.parameters = pin.parameters.map do |p|
|
63
70
|
[p.name, p.asgn_code]
|
64
71
|
end
|
65
72
|
end
|
data/lib/solargraph/api_map.rb
CHANGED
@@ -64,11 +64,10 @@ module Solargraph
|
|
64
64
|
implicit.merge map.environ
|
65
65
|
end
|
66
66
|
unresolved_requires = (bench.external_requires + implicit.requires + bench.workspace.config.required).uniq
|
67
|
-
@doc_map = DocMap.new(unresolved_requires, []) # @todo Implement gem
|
67
|
+
@doc_map = DocMap.new(unresolved_requires, []) # @todo Implement gem preferences
|
68
68
|
@store = Store.new(@@core_map.pins + @doc_map.pins + implicit.pins + pins)
|
69
69
|
@unresolved_requires = @doc_map.unresolved_requires
|
70
70
|
@missing_docs = [] # @todo Implement missing docs
|
71
|
-
@rebindable_method_names = nil
|
72
71
|
store.block_pins.each { |blk| blk.rebind(self) }
|
73
72
|
self
|
74
73
|
end
|
@@ -154,17 +153,6 @@ module Solargraph
|
|
154
153
|
store.pins
|
155
154
|
end
|
156
155
|
|
157
|
-
# @return [Set<String>]
|
158
|
-
def rebindable_method_names
|
159
|
-
@rebindable_method_names ||= begin
|
160
|
-
result = ['instance_eval', 'instance_exec', 'class_eval', 'class_exec', 'module_eval', 'module_exec', 'define_method'].to_set
|
161
|
-
source_maps.each do |map|
|
162
|
-
result.merge map.rebindable_method_names
|
163
|
-
end
|
164
|
-
result
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
156
|
# An array of pins based on Ruby keywords (`if`, `end`, etc.).
|
169
157
|
#
|
170
158
|
# @return [Enumerable<Solargraph::Pin::Keyword>]
|
@@ -8,7 +8,7 @@ module Solargraph
|
|
8
8
|
class UniqueType
|
9
9
|
include TypeMethods
|
10
10
|
|
11
|
-
attr_reader :all_params
|
11
|
+
attr_reader :all_params, :subtypes, :key_types
|
12
12
|
|
13
13
|
# Create a UniqueType with the specified name and an optional substring.
|
14
14
|
# The substring is the parameter section of a parametrized type, e.g.,
|
@@ -105,13 +105,9 @@ module Solargraph
|
|
105
105
|
# @param resolved_generic_values [Hash{String => ComplexType}] Added to as types are encountered or resolved
|
106
106
|
# @return [UniqueType, ComplexType]
|
107
107
|
def resolve_generics_from_context generics_to_resolve, context_type, resolved_generic_values: {}
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
new_binding = false
|
112
|
-
|
113
|
-
type_param = t.subtypes.first&.name
|
114
|
-
next t unless generics_to_resolve.include? type_param
|
108
|
+
if name == ComplexType::GENERIC_TAG_NAME
|
109
|
+
type_param = subtypes.first&.name
|
110
|
+
return self unless generics_to_resolve.include? type_param
|
115
111
|
unless context_type.nil? || !resolved_generic_values[type_param].nil?
|
116
112
|
new_binding = true
|
117
113
|
resolved_generic_values[type_param] = context_type
|
@@ -121,7 +117,34 @@ module Solargraph
|
|
121
117
|
complex_type.resolve_generics_from_context(generics_to_resolve, nil, resolved_generic_values: resolved_generic_values)
|
122
118
|
end
|
123
119
|
end
|
124
|
-
resolved_generic_values[type_param] ||
|
120
|
+
return resolved_generic_values[type_param] || self
|
121
|
+
end
|
122
|
+
|
123
|
+
# @todo typechecking should complain when the method being called has no @yieldparam tag
|
124
|
+
new_key_types = resolve_param_generics_from_context(generics_to_resolve, context_type, resolved_generic_values, &:key_types)
|
125
|
+
new_subtypes = resolve_param_generics_from_context(generics_to_resolve, context_type, resolved_generic_values, &:subtypes)
|
126
|
+
recreate(new_key_types: new_key_types, new_subtypes: new_subtypes)
|
127
|
+
end
|
128
|
+
|
129
|
+
# @param generics_to_resolve [Enumerable<String>]
|
130
|
+
# @param context_type [UniqueType]
|
131
|
+
# @param resolved_generic_values [Hash{String => ComplexType}]
|
132
|
+
# @yieldreturn [Array<ComplexType>]
|
133
|
+
# @return [Array<ComplexType>]
|
134
|
+
def resolve_param_generics_from_context(generics_to_resolve, context_type, resolved_generic_values)
|
135
|
+
types = yield self
|
136
|
+
types.each_with_index.flat_map do |ct, i|
|
137
|
+
ct.items.flat_map do |ut|
|
138
|
+
context_params = yield context_type if context_type
|
139
|
+
if context_params && context_params[i]
|
140
|
+
type_arg = context_params[i]
|
141
|
+
type_arg.map do |new_unique_context_type|
|
142
|
+
ut.resolve_generics_from_context generics_to_resolve, new_unique_context_type, resolved_generic_values: resolved_generic_values
|
143
|
+
end
|
144
|
+
else
|
145
|
+
ut.resolve_generics_from_context generics_to_resolve, nil, resolved_generic_values: resolved_generic_values
|
146
|
+
end
|
147
|
+
end
|
125
148
|
end
|
126
149
|
end
|
127
150
|
|
data/lib/solargraph/doc_map.rb
CHANGED
@@ -8,7 +8,7 @@ module Solargraph
|
|
8
8
|
attr_reader :requires
|
9
9
|
|
10
10
|
# @return [Array<Gem::Specification>]
|
11
|
-
attr_reader :
|
11
|
+
attr_reader :preferences
|
12
12
|
|
13
13
|
# @return [Array<Pin::Base>]
|
14
14
|
attr_reader :pins
|
@@ -17,10 +17,10 @@ module Solargraph
|
|
17
17
|
attr_reader :uncached_gemspecs
|
18
18
|
|
19
19
|
# @param requires [Array<String>]
|
20
|
-
# @param
|
21
|
-
def initialize(requires,
|
20
|
+
# @param preferences [Array<Gem::Specification>]
|
21
|
+
def initialize(requires, preferences)
|
22
22
|
@requires = requires.compact
|
23
|
-
@
|
23
|
+
@preferences = preferences.compact
|
24
24
|
generate
|
25
25
|
end
|
26
26
|
|
@@ -39,17 +39,11 @@ module Solargraph
|
|
39
39
|
@gems_in_memory ||= {}
|
40
40
|
end
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
# @return [Hash{String => Gem::Specification, nil}]
|
45
|
-
def required_gem_map
|
46
|
-
@required_gem_map ||= requires.to_h { |path| [path, resolve_path_to_gemspec(path)] }
|
42
|
+
def dependencies
|
43
|
+
@dependencies ||= (gemspecs.flat_map { |spec| fetch_dependencies(spec) } - gemspecs).to_set
|
47
44
|
end
|
48
45
|
|
49
|
-
|
50
|
-
def dependency_map
|
51
|
-
@dependency_map ||= dependencies.to_h { |gemspec| [gemspec.name, gemspec] }
|
52
|
-
end
|
46
|
+
private
|
53
47
|
|
54
48
|
# @return [void]
|
55
49
|
def generate
|
@@ -62,6 +56,17 @@ module Solargraph
|
|
62
56
|
try_stdlib_map path
|
63
57
|
end
|
64
58
|
end
|
59
|
+
dependencies.each { |dep| try_cache dep }
|
60
|
+
end
|
61
|
+
|
62
|
+
# @return [Hash{String => Gem::Specification, nil}]
|
63
|
+
def required_gem_map
|
64
|
+
@required_gem_map ||= requires.to_h { |path| [path, resolve_path_to_gemspec(path)] }
|
65
|
+
end
|
66
|
+
|
67
|
+
# @return [Hash{String => Gem::Specification}]
|
68
|
+
def preference_map
|
69
|
+
@preference_map ||= preferences.to_h { |gemspec| [gemspec.name, gemspec] }
|
65
70
|
end
|
66
71
|
|
67
72
|
# @param gemspec [Gem::Specification]
|
@@ -123,16 +128,16 @@ module Solargraph
|
|
123
128
|
nil
|
124
129
|
end
|
125
130
|
end
|
126
|
-
|
131
|
+
gemspec_or_preference gemspec
|
132
|
+
end
|
127
133
|
|
128
|
-
|
129
|
-
|
134
|
+
# @param gemspec [Gem::Specification, nil]
|
135
|
+
# @return [Gem::Specification, nil]
|
136
|
+
def gemspec_or_preference gemspec
|
137
|
+
return gemspec unless gemspec && preference_map.key?(gemspec.name)
|
138
|
+
return gemspec if gemspec.version == preference_map[gemspec.name].version
|
130
139
|
|
131
|
-
|
132
|
-
else
|
133
|
-
Solargraph.logger.warn "Gem #{gemspec.name} is not an expected dependency"
|
134
|
-
gemspec
|
135
|
-
end
|
140
|
+
change_gemspec_version gemspec, preference_map[by_path.name].version
|
136
141
|
end
|
137
142
|
|
138
143
|
# @param gemspec [Gem::Specification]
|
@@ -144,5 +149,23 @@ module Solargraph
|
|
144
149
|
Solargraph.logger.info "Gem #{gemspec.name} version #{version} not found. Using #{gemspec.version} instead"
|
145
150
|
gemspec
|
146
151
|
end
|
152
|
+
|
153
|
+
# @param gemspec [Gem::Specification]
|
154
|
+
# @return [Array<Gem::Specification>]
|
155
|
+
def fetch_dependencies gemspec
|
156
|
+
only_runtime_dependencies(gemspec).each_with_object(Set.new) do |spec, deps|
|
157
|
+
Solargraph.logger.info "Adding #{spec.name} dependency for #{gemspec.name}"
|
158
|
+
dep = Gem::Specification.find_by_name(spec.name, spec.requirement)
|
159
|
+
deps.merge fetch_dependencies(dep) if deps.add?(dep)
|
160
|
+
rescue Gem::MissingSpecError
|
161
|
+
Solargraph.logger.warn "Gem dependency #{spec.name} #{spec.requirements} for #{gemspec.name} not found."
|
162
|
+
end.to_a
|
163
|
+
end
|
164
|
+
|
165
|
+
# @param gemspec [Gem::Specification]
|
166
|
+
# @return [Array<Gem::Dependency>]
|
167
|
+
def only_runtime_dependencies gemspec
|
168
|
+
gemspec.dependencies - gemspec.development_dependencies
|
169
|
+
end
|
147
170
|
end
|
148
171
|
end
|
data/lib/solargraph/gem_pins.rb
CHANGED
@@ -20,7 +20,7 @@ module Solargraph
|
|
20
20
|
combined = yard_pins.map do |yard|
|
21
21
|
in_yard.add yard.path
|
22
22
|
next yard unless yard.is_a?(Pin::Method)
|
23
|
-
rbs = rbs_map.path_pin(yard.path)
|
23
|
+
rbs = rbs_map.path_pin(yard.path, Pin::Method)
|
24
24
|
next yard unless rbs
|
25
25
|
# @todo Could not include: attribute and anon_splat
|
26
26
|
# @sg-ignore
|
@@ -95,6 +95,10 @@ module Solargraph
|
|
95
95
|
nil
|
96
96
|
end
|
97
97
|
|
98
|
+
def options
|
99
|
+
@options ||= {}.freeze
|
100
|
+
end
|
101
|
+
|
98
102
|
# Get a generic library for the given URI and attach the corresponding
|
99
103
|
# source.
|
100
104
|
#
|
@@ -109,7 +113,7 @@ module Solargraph
|
|
109
113
|
|
110
114
|
# @return [Library]
|
111
115
|
def generic_library
|
112
|
-
@generic_library ||= Solargraph::Library.new
|
116
|
+
@generic_library ||= Solargraph::Library.new(Solargraph::Workspace.new('', nil, options), nil)
|
113
117
|
end
|
114
118
|
end
|
115
119
|
end
|
@@ -292,7 +292,8 @@ module Solargraph
|
|
292
292
|
path = ''
|
293
293
|
path = normalize_separators(directory) unless directory.nil?
|
294
294
|
begin
|
295
|
-
|
295
|
+
workspace = Solargraph::Workspace.new(path, nil, options)
|
296
|
+
lib = Solargraph::Library.new(workspace, name)
|
296
297
|
libraries.push lib
|
297
298
|
async_library_map lib
|
298
299
|
rescue WorkspaceTooLargeError => e
|
data/lib/solargraph/library.rb
CHANGED
@@ -251,7 +251,19 @@ module Solargraph
|
|
251
251
|
found = source.references(pin.name)
|
252
252
|
found.select! do |loc|
|
253
253
|
referenced = definitions_at(loc.filename, loc.range.ending.line, loc.range.ending.character).first
|
254
|
-
referenced
|
254
|
+
referenced&.path == pin.path
|
255
|
+
end
|
256
|
+
if pin.path == 'Class#new'
|
257
|
+
caller = cursor.chain.base.infer(api_map, clip.send(:block), clip.locals).first
|
258
|
+
if caller.defined?
|
259
|
+
found.select! do |loc|
|
260
|
+
clip = api_map.clip_at(loc.filename, loc.range.start)
|
261
|
+
other = clip.send(:cursor).chain.base.infer(api_map, clip.send(:block), clip.locals).first
|
262
|
+
caller == other
|
263
|
+
end
|
264
|
+
else
|
265
|
+
found.clear
|
266
|
+
end
|
255
267
|
end
|
256
268
|
# HACK: for language clients that exclude special characters from the start of variable names
|
257
269
|
if strip && match = cursor.word.match(/^[^a-z0-9_]+/i)
|
@@ -603,7 +615,7 @@ module Solargraph
|
|
603
615
|
|
604
616
|
logger.info "Caching #{spec.name} #{spec.version}"
|
605
617
|
Thread.new do
|
606
|
-
@cache_pid = Process.spawn(
|
618
|
+
@cache_pid = Process.spawn(workspace.command_path, 'cache', spec.name, spec.version.to_s)
|
607
619
|
Process.wait(@cache_pid)
|
608
620
|
logger.info "Cached #{spec.name} #{spec.version}"
|
609
621
|
@synchronized = false
|
data/lib/solargraph/page.rb
CHANGED
@@ -7,6 +7,12 @@ require 'cgi'
|
|
7
7
|
|
8
8
|
module Solargraph
|
9
9
|
class Page
|
10
|
+
# @todo This method directive is necessary because OpenStruct.new confuses
|
11
|
+
# the typechecker.
|
12
|
+
# @!method self.new(locals, render_method)
|
13
|
+
# @param locals[Hash]
|
14
|
+
# @param render_method [Proc]
|
15
|
+
# @return [Binder]
|
10
16
|
class Binder < OpenStruct
|
11
17
|
# @param locals [Hash]
|
12
18
|
# @param render_method [Proc]
|
@@ -6,31 +6,18 @@ module Solargraph
|
|
6
6
|
module NodeProcessors
|
7
7
|
class DefNode < Parser::NodeProcessor::Base
|
8
8
|
def process
|
9
|
+
name = node.children[0].to_s
|
10
|
+
scope = region.scope || (region.closure.is_a?(Pin::Singleton) ? :class : :instance)
|
9
11
|
methpin = Solargraph::Pin::Method.new(
|
10
12
|
location: get_node_location(node),
|
11
13
|
closure: region.closure,
|
12
|
-
name:
|
14
|
+
name: name,
|
13
15
|
comments: comments_for(node),
|
14
|
-
scope:
|
15
|
-
visibility: region.visibility,
|
16
|
+
scope: scope,
|
17
|
+
visibility: scope == :instance && name == 'initialize' ? :private : region.visibility,
|
16
18
|
node: node
|
17
19
|
)
|
18
|
-
if
|
19
|
-
pins.push Solargraph::Pin::Method.new(
|
20
|
-
location: methpin.location,
|
21
|
-
closure: methpin.closure,
|
22
|
-
name: 'new',
|
23
|
-
comments: methpin.comments,
|
24
|
-
scope: :class,
|
25
|
-
parameters: methpin.parameters
|
26
|
-
)
|
27
|
-
# @todo Smelly instance variable access.
|
28
|
-
pins.last.instance_variable_set(:@return_type, ComplexType::SELF)
|
29
|
-
pins.push methpin
|
30
|
-
# @todo Smelly instance variable access.
|
31
|
-
methpin.instance_variable_set(:@visibility, :private)
|
32
|
-
methpin.instance_variable_set(:@return_type, ComplexType::VOID)
|
33
|
-
elsif region.visibility == :module_function
|
20
|
+
if region.visibility == :module_function
|
34
21
|
pins.push Solargraph::Pin::Method.new(
|
35
22
|
location: methpin.location,
|
36
23
|
closure: methpin.closure,
|
@@ -51,7 +51,7 @@ module Solargraph
|
|
51
51
|
# Use the return node for inference. The clip might infer from the
|
52
52
|
# first node in a method call instead of the entire call.
|
53
53
|
chain = Parser.chain(node, nil, nil)
|
54
|
-
result = chain.infer(api_map, closure, clip.locals)
|
54
|
+
result = chain.infer(api_map, closure, clip.locals).self_to(closure.context.tag)
|
55
55
|
types.push result unless result.undefined?
|
56
56
|
end
|
57
57
|
end
|
data/lib/solargraph/pin/block.rb
CHANGED
@@ -47,36 +47,19 @@ module Solargraph
|
|
47
47
|
# @return [ComplexType, nil]
|
48
48
|
def binder_or_nil api_map
|
49
49
|
return nil unless receiver
|
50
|
-
|
51
|
-
return nil unless api_map.rebindable_method_names.include?(word)
|
50
|
+
|
52
51
|
chain = Parser.chain(receiver, location.filename)
|
53
52
|
locals = api_map.source_map(location.filename).locals_at(location)
|
54
|
-
links_last_word = chain.links.last.word
|
55
|
-
if %w[instance_eval instance_exec class_eval class_exec module_eval module_exec].include?(links_last_word)
|
56
|
-
return chain.base.infer(api_map, self, locals)
|
57
|
-
end
|
58
|
-
if 'define_method' == links_last_word and chain.define(api_map, self, locals).first&.path == 'Module#define_method' # change class type to instance type
|
59
|
-
if chain.links.size > 1 # Class.define_method
|
60
|
-
ty = chain.base.infer(api_map, self, locals)
|
61
|
-
return Solargraph::ComplexType.parse(ty.namespace)
|
62
|
-
else # define_method without self
|
63
|
-
return Solargraph::ComplexType.parse(closure.binder.namespace)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
# other case without early return, read block yieldreceiver tags
|
67
53
|
receiver_pin = chain.define(api_map, self, locals).first
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
end
|
78
|
-
end
|
79
|
-
nil
|
54
|
+
return nil unless receiver_pin
|
55
|
+
|
56
|
+
types = receiver_pin.docstring.tag(:yieldreceiver)&.types
|
57
|
+
return nil unless types&.any?
|
58
|
+
|
59
|
+
target = chain.base.infer(api_map, receiver_pin, locals)
|
60
|
+
target = full_context unless target.defined?
|
61
|
+
|
62
|
+
ComplexType.try_parse(*types).qualify(api_map, receiver_pin.context.namespace).self_to(target.to_s)
|
80
63
|
end
|
81
64
|
end
|
82
65
|
end
|
@@ -38,25 +38,6 @@ module Solargraph
|
|
38
38
|
environment = RBS::Environment.from_loader(loader).resolve_type_names
|
39
39
|
cursor = pins.length
|
40
40
|
environment.declarations.each { |decl| convert_decl_to_pin(decl, Solargraph::Pin::ROOT_PIN) }
|
41
|
-
added_pins = pins[cursor..-1]
|
42
|
-
add_back_implicit_pins(added_pins)
|
43
|
-
end
|
44
|
-
|
45
|
-
# @param added_pins [::Enumerable<Pin>]
|
46
|
-
# @return [void]
|
47
|
-
def add_back_implicit_pins(added_pins)
|
48
|
-
added_pins.each do |pin|
|
49
|
-
pin.source = :rbs
|
50
|
-
next unless pin.is_a?(Pin::Namespace) && pin.type == :class
|
51
|
-
next if pins.any? { |p| p.path == "#{pin.path}.new"}
|
52
|
-
pins.push Solargraph::Pin::Method.new(
|
53
|
-
location: nil,
|
54
|
-
closure: pin,
|
55
|
-
name: 'new',
|
56
|
-
comments: pin.comments,
|
57
|
-
scope: :class
|
58
|
-
)
|
59
|
-
end
|
60
41
|
end
|
61
42
|
|
62
43
|
# @param decl [RBS::AST::Declarations::Base]
|
@@ -303,26 +284,8 @@ module Solargraph
|
|
303
284
|
pin.signatures.concat method_def_to_sigs(decl, pin)
|
304
285
|
pins.push pin
|
305
286
|
if pin.name == 'initialize'
|
306
|
-
|
307
|
-
|
308
|
-
closure: pin.closure,
|
309
|
-
name: 'new',
|
310
|
-
comments: pin.comments,
|
311
|
-
scope: :class,
|
312
|
-
signatures: pin.signatures
|
313
|
-
)
|
314
|
-
pins.last.signatures.replace(
|
315
|
-
pin.signatures.map do |p|
|
316
|
-
Pin::Signature.new(
|
317
|
-
p.generics,
|
318
|
-
p.parameters,
|
319
|
-
ComplexType::SELF
|
320
|
-
)
|
321
|
-
end
|
322
|
-
)
|
323
|
-
# @todo Is this necessary?
|
324
|
-
# pin.instance_variable_set(:@visibility, :private)
|
325
|
-
# pin.instance_variable_set(:@return_type, ComplexType::VOID)
|
287
|
+
pin.instance_variable_set(:@visibility, :private)
|
288
|
+
pin.instance_variable_set(:@return_type, ComplexType::VOID)
|
326
289
|
end
|
327
290
|
end
|
328
291
|
if decl.singleton?
|
@@ -22,11 +22,14 @@ module Solargraph
|
|
22
22
|
closure: Solargraph::Pin::Namespace.new(name: 'Object'), comments: '@return [Class<self>]')
|
23
23
|
]
|
24
24
|
|
25
|
-
|
26
|
-
Override.
|
27
|
-
Override.
|
28
|
-
Override.
|
29
|
-
Override.
|
25
|
+
OVERRIDES = [
|
26
|
+
Override.from_comment('BasicObject#instance_eval', '@yieldreceiver [self]'),
|
27
|
+
Override.from_comment('BasicObject#instance_exec', '@yieldreceiver [self]'),
|
28
|
+
Override.from_comment('Module#define_method', '@yieldreceiver [Object<self>]'),
|
29
|
+
Override.from_comment('Module#class_eval', '@yieldreceiver [Class<self>]'),
|
30
|
+
Override.from_comment('Module#class_exec', '@yieldreceiver [Class<self>]'),
|
31
|
+
Override.from_comment('Module#module_eval', '@yieldreceiver [Module<self>]'),
|
32
|
+
Override.from_comment('Module#module_exec', '@yieldreceiver [Module<self>]')
|
30
33
|
]
|
31
34
|
|
32
35
|
# HACK: Add Errno exception classes
|
@@ -38,7 +41,7 @@ module Solargraph
|
|
38
41
|
end
|
39
42
|
ERRNOS = errnos
|
40
43
|
|
41
|
-
ALL = KEYWORDS + MISSING +
|
44
|
+
ALL = KEYWORDS + MISSING + OVERRIDES + ERRNOS
|
42
45
|
end
|
43
46
|
end
|
44
47
|
end
|
@@ -13,27 +13,16 @@ module Solargraph
|
|
13
13
|
pins.replace cache
|
14
14
|
else
|
15
15
|
loader = RBS::EnvironmentLoader.new(repository: RBS::Repository.new(no_stdlib: false))
|
16
|
-
|
16
|
+
RBS::Environment.from_loader(loader).resolve_type_names
|
17
17
|
load_environment_to_pins(loader)
|
18
18
|
pins.concat RbsMap::CoreFills::ALL
|
19
19
|
processed = ApiMap::Store.new(pins).pins.reject { |p| p.is_a?(Solargraph::Pin::Reference::Override) }
|
20
|
+
processed.each { |pin| pin.source = :rbs }
|
20
21
|
pins.replace processed
|
21
22
|
|
22
23
|
Cache.save('core.ser', pins)
|
23
24
|
end
|
24
25
|
end
|
25
|
-
|
26
|
-
def method_def_to_sigs decl, pin
|
27
|
-
stubs = CoreSigns.sign(pin.path)
|
28
|
-
return super unless stubs
|
29
|
-
stubs.map do |stub|
|
30
|
-
Pin::Signature.new(
|
31
|
-
[],
|
32
|
-
[],
|
33
|
-
ComplexType.try_parse(stub.return_type)
|
34
|
-
)
|
35
|
-
end
|
36
|
-
end
|
37
26
|
end
|
38
27
|
end
|
39
28
|
end
|
data/lib/solargraph/rbs_map.rb
CHANGED
@@ -7,7 +7,6 @@ module Solargraph
|
|
7
7
|
autoload :Conversions, 'solargraph/rbs_map/conversions'
|
8
8
|
autoload :CoreMap, 'solargraph/rbs_map/core_map'
|
9
9
|
autoload :CoreFills, 'solargraph/rbs_map/core_fills'
|
10
|
-
autoload :CoreSigns, 'solargraph/rbs_map/core_signs'
|
11
10
|
autoload :StdlibMap, 'solargraph/rbs_map/stdlib_map'
|
12
11
|
|
13
12
|
include Conversions
|
@@ -28,10 +27,13 @@ module Solargraph
|
|
28
27
|
load_environment_to_pins(loader)
|
29
28
|
end
|
30
29
|
|
30
|
+
# @generic T
|
31
31
|
# @param path [String]
|
32
|
-
# @
|
33
|
-
|
34
|
-
|
32
|
+
# @param klass [Class<generic<T>>]
|
33
|
+
# @return [generic<T>, nil]
|
34
|
+
def path_pin path, klass = Pin::Base
|
35
|
+
pin = pins.find { |p| p.path == path }
|
36
|
+
pin if pin&.is_a?(klass)
|
35
37
|
end
|
36
38
|
|
37
39
|
# @param path [String]
|
@@ -50,9 +50,9 @@ module Solargraph
|
|
50
50
|
def infer
|
51
51
|
result = cursor.chain.infer(api_map, block, locals)
|
52
52
|
if result.tag == 'Class'
|
53
|
-
# HACK: Exception to return
|
53
|
+
# HACK: Exception to return BasicObject from Class#new
|
54
54
|
dfn = cursor.chain.define(api_map, block, locals).first
|
55
|
-
return ComplexType.try_parse('
|
55
|
+
return ComplexType.try_parse('BasicObject') if dfn && dfn.path == 'Class#new'
|
56
56
|
end
|
57
57
|
return result unless result.tag == 'self'
|
58
58
|
ComplexType.try_parse(cursor.chain.base.infer(api_map, block, locals).tag)
|
@@ -40,14 +40,6 @@ module Solargraph
|
|
40
40
|
@pin_select_cache[klass] ||= @pin_class_hash.select { |key, _| key <= klass }.values.flatten
|
41
41
|
end
|
42
42
|
|
43
|
-
# @return [Set<String>]
|
44
|
-
def rebindable_method_names
|
45
|
-
@rebindable_method_names ||= pins_by_class(Pin::Method)
|
46
|
-
.select { |pin| pin.comments && pin.comments.include?('@yieldreceiver') }
|
47
|
-
.map(&:name)
|
48
|
-
.to_set
|
49
|
-
end
|
50
|
-
|
51
43
|
# @return [String]
|
52
44
|
def filename
|
53
45
|
source.filename
|
@@ -299,6 +299,14 @@ module Solargraph
|
|
299
299
|
pin = pins.first
|
300
300
|
ap = if base.links.last.is_a?(Solargraph::Source::Chain::ZSuper)
|
301
301
|
arity_problems_for(pin, fake_args_for(block_pin), location)
|
302
|
+
elsif pin.path == 'Class#new'
|
303
|
+
fqns = if base.links.one?
|
304
|
+
block_pin.namespace
|
305
|
+
else
|
306
|
+
base.base.infer(api_map, block_pin, locals).namespace
|
307
|
+
end
|
308
|
+
init = api_map.get_method_stack(fqns, 'initialize').first
|
309
|
+
init ? arity_problems_for(init, base.links.last.arguments, location) : []
|
302
310
|
else
|
303
311
|
arity_problems_for(pin, base.links.last.arguments, location)
|
304
312
|
end
|
@@ -320,8 +328,14 @@ module Solargraph
|
|
320
328
|
argchain = base.links.last.arguments[idx]
|
321
329
|
if argchain.nil?
|
322
330
|
if par.decl == :arg
|
323
|
-
|
324
|
-
|
331
|
+
last = base.links.last.arguments.last
|
332
|
+
if last && last.node.type == :splat
|
333
|
+
argchain = last
|
334
|
+
next # don't try to apply the type of the splat - unlikely to be specific enough
|
335
|
+
else
|
336
|
+
errors.push Problem.new(location, "Not enough arguments to #{pin.path}")
|
337
|
+
next
|
338
|
+
end
|
325
339
|
else
|
326
340
|
last = base.links.last.arguments.last
|
327
341
|
argchain = last if last && [:kwsplat, :hash].include?(last.node.type)
|
@@ -332,7 +346,12 @@ module Solargraph
|
|
332
346
|
errors.concat kwarg_problems_for sig, argchain, api_map, block_pin, locals, location, pin, params, idx
|
333
347
|
next
|
334
348
|
else
|
349
|
+
last = base.links.last.arguments.last
|
350
|
+
if last && last.node.type == :splat
|
351
|
+
next # don't try to apply the type of the splat - unlikely to be specific enough
|
352
|
+
end
|
335
353
|
ptype = params.key?(par.name) ? params[par.name][:qualified] : ComplexType::UNDEFINED
|
354
|
+
ptype = ptype.self_to(par.context.namespace)
|
336
355
|
if ptype.nil?
|
337
356
|
# @todo Some level (strong, I guess) should require the param here
|
338
357
|
else
|
data/lib/solargraph/version.rb
CHANGED
data/lib/solargraph/workspace.rb
CHANGED
@@ -25,9 +25,11 @@ module Solargraph
|
|
25
25
|
|
26
26
|
# @param directory [String]
|
27
27
|
# @param config [Config, nil]
|
28
|
-
|
28
|
+
# @param server [Hash]
|
29
|
+
def initialize directory = '', config = nil, server = {}
|
29
30
|
@directory = directory
|
30
31
|
@config = config
|
32
|
+
@server = server
|
31
33
|
load_sources
|
32
34
|
@gemnames = []
|
33
35
|
@require_paths = generate_require_paths
|
@@ -134,8 +136,19 @@ module Solargraph
|
|
134
136
|
source_hash[updater.filename] = source_hash[updater.filename].synchronize(updater)
|
135
137
|
end
|
136
138
|
|
139
|
+
# @return [String]
|
140
|
+
def command_path
|
141
|
+
server['commandPath'] || 'solargraph'
|
142
|
+
end
|
143
|
+
|
137
144
|
private
|
138
145
|
|
146
|
+
# The language server configuration (or an empty hash if the workspace was
|
147
|
+
# not initialized from a server).
|
148
|
+
#
|
149
|
+
# @return [Hash]
|
150
|
+
attr_reader :server
|
151
|
+
|
139
152
|
# @return [Hash{String => Solargraph::Source}]
|
140
153
|
def source_hash
|
141
154
|
@source_hash ||= {}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: solargraph
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.53.
|
4
|
+
version: 0.53.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fred Snyder
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-03-
|
11
|
+
date: 2025-03-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: backport
|
@@ -558,7 +558,6 @@ files:
|
|
558
558
|
- lib/solargraph/rbs_map/conversions.rb
|
559
559
|
- lib/solargraph/rbs_map/core_fills.rb
|
560
560
|
- lib/solargraph/rbs_map/core_map.rb
|
561
|
-
- lib/solargraph/rbs_map/core_signs.rb
|
562
561
|
- lib/solargraph/rbs_map/stdlib_map.rb
|
563
562
|
- lib/solargraph/server_methods.rb
|
564
563
|
- lib/solargraph/shell.rb
|
@@ -1,35 +0,0 @@
|
|
1
|
-
module Solargraph
|
2
|
-
class RbsMap
|
3
|
-
module CoreSigns
|
4
|
-
Override = Pin::Reference::Override
|
5
|
-
|
6
|
-
class Stub
|
7
|
-
attr_reader :parameters
|
8
|
-
|
9
|
-
attr_reader :return_type
|
10
|
-
|
11
|
-
# @param parameters [Array<Hash>]
|
12
|
-
# @param return_type [String]
|
13
|
-
def initialize parameters, return_type
|
14
|
-
@parameters = parameters
|
15
|
-
@return_type = return_type
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
SIGNATURE_MAP = {
|
20
|
-
'Object#class' => [
|
21
|
-
Stub.new(
|
22
|
-
[],
|
23
|
-
'Class<self>'
|
24
|
-
)
|
25
|
-
]
|
26
|
-
}
|
27
|
-
|
28
|
-
# @param path [String]
|
29
|
-
# @return [Array<Stub>]
|
30
|
-
def self.sign path
|
31
|
-
SIGNATURE_MAP[path]
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|