solargraph 0.39.0 → 0.40.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.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -7
  3. data/CHANGELOG.md +984 -0
  4. data/Rakefile +12 -1
  5. data/SPONSORS.md +6 -0
  6. data/lib/.rubocop.yml +21 -0
  7. data/lib/solargraph/api_map/cache.rb +4 -0
  8. data/lib/solargraph/api_map/store.rb +35 -51
  9. data/lib/solargraph/api_map.rb +94 -87
  10. data/lib/solargraph/{bundle.rb → bench.rb} +6 -2
  11. data/lib/solargraph/compat.rb +23 -0
  12. data/lib/solargraph/complex_type.rb +2 -2
  13. data/lib/solargraph/convention/base.rb +16 -8
  14. data/lib/solargraph/convention/gemfile.rb +2 -5
  15. data/lib/solargraph/convention/gemspec.rb +3 -6
  16. data/lib/solargraph/convention/rspec.rb +3 -6
  17. data/lib/solargraph/convention.rb +14 -5
  18. data/lib/solargraph/diagnostics/rubocop.rb +2 -1
  19. data/lib/solargraph/diagnostics/rubocop_helpers.rb +4 -1
  20. data/lib/solargraph/documentor.rb +4 -0
  21. data/lib/solargraph/environ.rb +11 -6
  22. data/lib/solargraph/language_server/host.rb +1 -1
  23. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +6 -1
  24. data/lib/solargraph/language_server/message/text_document/definition.rb +1 -1
  25. data/lib/solargraph/language_server/message/text_document/formatting.rb +7 -3
  26. data/lib/solargraph/language_server/uri_helpers.rb +23 -3
  27. data/lib/solargraph/library.rb +22 -8
  28. data/lib/solargraph/parser/legacy/class_methods.rb +4 -0
  29. data/lib/solargraph/parser/legacy/node_chainer.rb +10 -7
  30. data/lib/solargraph/parser/legacy/node_methods.rb +16 -3
  31. data/lib/solargraph/parser/legacy/node_processors/ivasgn_node.rb +1 -1
  32. data/lib/solargraph/parser/legacy/node_processors/send_node.rb +48 -23
  33. data/lib/solargraph/parser/node_processor/base.rb +3 -0
  34. data/lib/solargraph/parser/rubyvm/class_methods.rb +6 -2
  35. data/lib/solargraph/parser/rubyvm/node_chainer.rb +11 -9
  36. data/lib/solargraph/parser/rubyvm/node_methods.rb +6 -1
  37. data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +35 -11
  38. data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +1 -1
  39. data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +6 -1
  40. data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +6 -1
  41. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +52 -67
  42. data/lib/solargraph/parser/rubyvm/node_processors.rb +2 -0
  43. data/lib/solargraph/pin/base.rb +2 -2
  44. data/lib/solargraph/pin/base_variable.rb +1 -1
  45. data/lib/solargraph/pin/block.rb +28 -14
  46. data/lib/solargraph/pin/closure.rb +1 -1
  47. data/lib/solargraph/pin/common.rb +1 -1
  48. data/lib/solargraph/pin/constant.rb +1 -1
  49. data/lib/solargraph/pin/conversions.rb +3 -4
  50. data/lib/solargraph/pin/documenting.rb +6 -11
  51. data/lib/solargraph/pin/local_variable.rb +1 -1
  52. data/lib/solargraph/pin/method.rb +143 -9
  53. data/lib/solargraph/pin/method_alias.rb +2 -2
  54. data/lib/solargraph/pin/namespace.rb +1 -1
  55. data/lib/solargraph/pin/parameter.rb +2 -2
  56. data/lib/solargraph/pin/proxy_type.rb +1 -1
  57. data/lib/solargraph/pin.rb +0 -3
  58. data/lib/solargraph/position.rb +2 -14
  59. data/lib/solargraph/shell.rb +2 -1
  60. data/lib/solargraph/source/chain/call.rb +9 -0
  61. data/lib/solargraph/source/chain/head.rb +14 -8
  62. data/lib/solargraph/source/chain/z_super.rb +30 -0
  63. data/lib/solargraph/source/chain.rb +19 -36
  64. data/lib/solargraph/source/source_chainer.rb +2 -1
  65. data/lib/solargraph/source.rb +24 -9
  66. data/lib/solargraph/source_map/clip.rb +78 -44
  67. data/lib/solargraph/source_map/mapper.rb +41 -21
  68. data/lib/solargraph/source_map.rb +20 -2
  69. data/lib/solargraph/type_checker/param_def.rb +1 -1
  70. data/lib/solargraph/type_checker.rb +61 -42
  71. data/lib/solargraph/version.rb +1 -1
  72. data/lib/solargraph/views/_name_type_tag.erb +1 -1
  73. data/lib/solargraph/workspace.rb +1 -1
  74. data/lib/solargraph/yard_map/core_fills.rb +185 -0
  75. data/lib/solargraph/yard_map/helpers.rb +16 -0
  76. data/lib/solargraph/{pin/yard_pin/constant.rb → yard_map/mapper/to_constant.rb} +6 -6
  77. data/lib/solargraph/yard_map/mapper/to_method.rb +78 -0
  78. data/lib/solargraph/{pin/yard_pin/namespace.rb → yard_map/mapper/to_namespace.rb} +6 -6
  79. data/lib/solargraph/yard_map/mapper.rb +17 -8
  80. data/lib/solargraph/yard_map/rdoc_to_yard.rb +26 -15
  81. data/lib/solargraph/yard_map/stdlib_fills.rb +43 -0
  82. data/lib/solargraph/yard_map/to_method.rb +79 -0
  83. data/lib/solargraph/yard_map.rb +140 -92
  84. data/lib/solargraph.rb +5 -4
  85. data/solargraph.gemspec +5 -5
  86. data/yardoc/2.2.2.tar.gz +0 -0
  87. metadata +29 -41
  88. data/.rubocop.yml +0 -6
  89. data/lib/solargraph/core_fills.rb +0 -159
  90. data/lib/solargraph/pin/attribute.rb +0 -49
  91. data/lib/solargraph/pin/base_method.rb +0 -141
  92. data/lib/solargraph/pin/yard_pin/method.rb +0 -65
  93. data/lib/solargraph/pin/yard_pin/yard_mixin.rb +0 -26
  94. data/lib/solargraph/pin/yard_pin.rb +0 -12
  95. data/lib/solargraph/stdlib_fills.rb +0 -32
  96. data/travis-bundler.rb +0 -11
data/Rakefile CHANGED
@@ -11,4 +11,15 @@ end
11
11
  desc "Open a Pry session preloaded with this library"
12
12
  task :console do
13
13
  sh "pry -I lib -r solargraph.rb"
14
- end
14
+ end
15
+
16
+ desc "Run the type checker"
17
+ task :typecheck do
18
+ sh "bundle exec solargraph typecheck --level typed"
19
+ end
20
+
21
+ desc "Run all tests"
22
+ task :test do
23
+ Rake::Task["typecheck"].invoke
24
+ Rake::Task["spec"].invoke
25
+ end
data/SPONSORS.md CHANGED
@@ -4,6 +4,12 @@ Solargraph is developed and maintained by [Castwide Technologies](https://castwi
4
4
 
5
5
  The following people and organizations provide funding or other resources. [Become a sponsor](https://patreon.com/castwide)
6
6
 
7
+ ## Linked Sponsors
8
+
9
+ - **[Calyptix Security](https://www.calyptix.com/)**
10
+
7
11
  ## Named Sponsors
8
12
 
9
13
  - Emily Strickland
14
+ - Tom de Grunt
15
+ - Akira Yamada
data/lib/.rubocop.yml ADDED
@@ -0,0 +1,21 @@
1
+ Layout/EndOfLine:
2
+ EnforcedStyle: lf
3
+ Style/MethodDefParentheses:
4
+ Enabled: false
5
+ Layout/EmptyLineAfterGuardClause:
6
+ Enabled: false
7
+ Layout/SpaceAroundMethodCallOperator:
8
+ Enabled: true
9
+ Lint/RaiseException:
10
+ Enabled: true
11
+ Lint/StructNewOverride:
12
+ Enabled: true
13
+ Style/ExponentialNotation:
14
+ Enabled: true
15
+ Style/HashEachMethods:
16
+ Enabled: true
17
+ Style/HashTransformKeys:
18
+ Enabled: true
19
+ Style/HashTransformValues:
20
+ Enabled: true
21
+
@@ -10,6 +10,7 @@ module Solargraph
10
10
  @receiver_definitions = {}
11
11
  end
12
12
 
13
+ # @return [Array<Pin::Method>]
13
14
  def get_methods fqns, scope, visibility, deep
14
15
  @methods[[fqns, scope, visibility.sort, deep]]
15
16
  end
@@ -18,6 +19,7 @@ module Solargraph
18
19
  @methods[[fqns, scope, visibility.sort, deep]] = value
19
20
  end
20
21
 
22
+ # @return [Array<Pin::Base>]
21
23
  def get_constants namespace, context
22
24
  @constants[[namespace, context]]
23
25
  end
@@ -26,6 +28,7 @@ module Solargraph
26
28
  @constants[[namespace, context]] = value
27
29
  end
28
30
 
31
+ # @return [String]
29
32
  def get_qualified_namespace name, context
30
33
  @qualified_namespaces[[name, context]]
31
34
  end
@@ -38,6 +41,7 @@ module Solargraph
38
41
  @receiver_definitions.key? path
39
42
  end
40
43
 
44
+ # @return [Pin::Method]
41
45
  def get_receiver_definition path
42
46
  @receiver_definitions[path]
43
47
  end
@@ -29,7 +29,7 @@ module Solargraph
29
29
  # @return [Array<Solargraph::Pin::Base>]
30
30
  def get_methods fqns, scope: :instance, visibility: [:public]
31
31
  namespace_children(fqns).select do |pin|
32
- pin.is_a?(Pin::BaseMethod) && pin.scope == scope && visibility.include?(pin.visibility)
32
+ pin.is_a?(Pin::Method) && pin.scope == scope && visibility.include?(pin.visibility)
33
33
  end
34
34
  end
35
35
 
@@ -99,12 +99,12 @@ module Solargraph
99
99
 
100
100
  # @return [Array<Solargraph::Pin::Base>]
101
101
  def namespace_pins
102
- @namespace_pins ||= []
102
+ pins_by_class(Solargraph::Pin::Namespace)
103
103
  end
104
104
 
105
- # @return [Array<Solargraph::Pin::Base>]
105
+ # @return [Array<Solargraph::Pin::Method>]
106
106
  def method_pins
107
- @method_pins ||= []
107
+ pins_by_class(Solargraph::Pin::Method)
108
108
  end
109
109
 
110
110
  # @param fqns [String]
@@ -133,7 +133,7 @@ module Solargraph
133
133
 
134
134
  # @return [Array<Pin::Block>]
135
135
  def block_pins
136
- @block_pins ||= []
136
+ pins_by_class(Pin::Block)
137
137
  end
138
138
 
139
139
  def inspect
@@ -141,6 +141,12 @@ module Solargraph
141
141
  to_s
142
142
  end
143
143
 
144
+ # @param klass [Class]
145
+ # @return [Array<Solargraph::Pin::Base>]
146
+ def pins_by_class klass
147
+ @pin_select_cache[klass] ||= @pin_class_hash.select { |key, _| key <= klass }.values.flatten
148
+ end
149
+
144
150
  private
145
151
 
146
152
  # @param fqns [String]
@@ -167,7 +173,7 @@ module Solargraph
167
173
 
168
174
  # @return [Array<Solargraph::Pin::Symbol>]
169
175
  def symbols
170
- @symbols ||= []
176
+ pins_by_class(Pin::Symbol)
171
177
  end
172
178
 
173
179
  def superclass_references
@@ -198,7 +204,7 @@ module Solargraph
198
204
  end
199
205
 
200
206
  def all_instance_variables
201
- @all_instance_variables ||= []
207
+ pins_by_class(Pin::InstanceVariable)
202
208
  end
203
209
 
204
210
  def path_pin_hash
@@ -207,48 +213,29 @@ module Solargraph
207
213
 
208
214
  # @return [void]
209
215
  def index
210
- namespace_map.clear
211
- namespaces.clear
212
- namespace_pins.clear
213
- method_pins.clear
214
- symbols.clear
215
- block_pins.clear
216
- all_instance_variables.clear
217
- path_pin_hash.clear
218
- namespace_map[''] = []
219
- override_pins = []
220
- pins.each do |pin|
221
- namespace_map[pin.namespace] ||= []
222
- namespace_map[pin.namespace].push pin
223
- namespaces.add pin.path if pin.is_a?(Pin::Namespace) && !pin.path.empty?
224
- namespace_pins.push pin if pin.is_a?(Pin::Namespace)
225
- method_pins.push pin if pin.is_a?(Pin::BaseMethod)
226
- symbols.push pin if pin.is_a?(Pin::Symbol)
227
- if pin.is_a?(Pin::Reference::Include)
228
- include_references[pin.namespace] ||= []
229
- include_references[pin.namespace].push pin.name
230
- elsif pin.is_a?(Pin::Reference::Prepend)
231
- prepend_references[pin.namespace] ||= []
232
- prepend_references[pin.namespace].push pin.name
233
- elsif pin.is_a?(Pin::Reference::Extend)
234
- extend_references[pin.namespace] ||= []
235
- extend_references[pin.namespace].push pin.name
236
- elsif pin.is_a?(Pin::Reference::Superclass)
237
- superclass_references[pin.namespace] ||= []
238
- superclass_references[pin.namespace].push pin.name
239
- elsif pin.is_a?(Pin::Block)
240
- block_pins.push pin
241
- elsif pin.is_a?(Pin::InstanceVariable)
242
- all_instance_variables.push pin
243
- elsif pin.is_a?(Pin::Reference::Override)
244
- override_pins.push pin
245
- end
246
- if pin.path
247
- path_pin_hash[pin.path] ||= []
248
- path_pin_hash[pin.path].push pin
249
- end
216
+ set = pins.to_set
217
+ @pin_class_hash = set.classify(&:class).transform_values(&:to_a)
218
+ @pin_select_cache = {}
219
+ @namespace_map = set.classify(&:namespace).transform_values(&:to_a)
220
+ @path_pin_hash = set.classify(&:path).transform_values(&:to_a)
221
+ @namespaces = @path_pin_hash.keys.compact.to_set
222
+ pins_by_class(Pin::Reference::Include).each do |pin|
223
+ include_references[pin.namespace] ||= []
224
+ include_references[pin.namespace].push pin.name
225
+ end
226
+ pins_by_class(Pin::Reference::Prepend).each do |pin|
227
+ prepend_references[pin.namespace] ||= []
228
+ prepend_references[pin.namespace].push pin.name
229
+ end
230
+ pins_by_class(Pin::Reference::Extend).each do |pin|
231
+ extend_references[pin.namespace] ||= []
232
+ extend_references[pin.namespace].push pin.name
233
+ end
234
+ pins_by_class(Pin::Reference::Superclass).each do |pin|
235
+ superclass_references[pin.namespace] ||= []
236
+ superclass_references[pin.namespace].push pin.name
250
237
  end
251
- override_pins.each do |ovr|
238
+ pins_by_class(Pin::Reference::Override).each do |ovr|
252
239
  pin = get_path_pins(ovr.name).first
253
240
  next if pin.nil?
254
241
  (ovr.tags.map(&:tag_name) + ovr.delete).uniq.each do |tag|
@@ -258,9 +245,6 @@ module Solargraph
258
245
  pin.docstring.add_tag(tag)
259
246
  end
260
247
  end
261
- # @todo This is probably not the best place for these overrides
262
- superclass_references['Integer'] = ['Numeric']
263
- superclass_references['Float'] = ['Numeric']
264
248
  end
265
249
  end
266
250
  end
@@ -26,7 +26,6 @@ module Solargraph
26
26
  def initialize pins: []
27
27
  @source_map_hash = {}
28
28
  @cache = Cache.new
29
- @mutex = Mutex.new
30
29
  @method_alias_stack = []
31
30
  index pins
32
31
  end
@@ -34,13 +33,7 @@ module Solargraph
34
33
  # @param pins [Array<Pin::Base>]
35
34
  # @return [self]
36
35
  def index pins
37
- @mutex.synchronize {
38
- @source_map_hash.clear
39
- @cache.clear
40
- @store = Store.new(pins + YardMap.new.pins)
41
- @unresolved_requires = []
42
- workspace_filenames.clear
43
- }
36
+ catalog Bench.new(pins: pins)
44
37
  self
45
38
  end
46
39
 
@@ -49,7 +42,7 @@ module Solargraph
49
42
  # @param source [Source]
50
43
  # @return [self]
51
44
  def map source
52
- catalog Bundle.new(opened: [source])
45
+ catalog Bench.new(opened: [source])
53
46
  self
54
47
  end
55
48
 
@@ -59,17 +52,19 @@ module Solargraph
59
52
  store.named_macros[name]
60
53
  end
61
54
 
62
- # Catalog a bundle.
55
+ # Catalog a bench.
63
56
  #
64
- # @param bundle [Bundle]
57
+ # @param bench [Bench]
65
58
  # @return [self]
66
- def catalog bundle
59
+ def catalog bench
67
60
  new_map_hash = {}
68
- # Bundle always needs to be merged if it adds or removes sources
69
- merged = (bundle.sources.length == source_map_hash.values.length)
70
- bundle.sources.each do |source|
61
+ # Bench always needs to be merged if it adds or removes sources
62
+ merged = (bench.sources.length == source_map_hash.values.length)
63
+ bench.sources.each do |source|
71
64
  if source_map_hash.key?(source.filename)
72
- if source_map_hash[source.filename].code == source.code && source_map_hash[source.filename].source.synchronized? && source.synchronized?
65
+ if source_map_hash[source.filename].code == source.code &&
66
+ source_map_hash[source.filename].source.synchronized? &&
67
+ source.synchronized?
73
68
  new_map_hash[source.filename] = source_map_hash[source.filename]
74
69
  elsif !source.synchronized?
75
70
  new_map_hash[source.filename] = source_map_hash[source.filename]
@@ -90,23 +85,28 @@ module Solargraph
90
85
  merged = false
91
86
  end
92
87
  end
93
- return self if merged
88
+ return self if bench.pins.empty? && @store && merged
94
89
  implicit.clear
95
90
  pins = []
96
91
  reqs = Set.new
97
92
  # @param map [SourceMap]
98
- new_map_hash.values.each do |map|
99
- implicit.merge map.environ
93
+ new_map_hash.each_value do |map|
100
94
  pins.concat map.pins
101
95
  reqs.merge map.requires.map(&:name)
102
96
  end
103
- reqs.merge bundle.workspace.config.required
97
+ pins.concat bench.pins
98
+ reqs.merge bench.workspace.config.required
99
+ @required = reqs
100
+ bench.sources.each do |src|
101
+ implicit.merge new_map_hash[src.filename].environ
102
+ end
103
+ # implicit.merge Convention.for_global(self)
104
104
  local_path_hash.clear
105
- unless bundle.workspace.require_paths.empty?
105
+ unless bench.workspace.require_paths.empty?
106
106
  file_keys = new_map_hash.keys
107
- workspace_path = Pathname.new(bundle.workspace.directory)
107
+ workspace_path = Pathname.new(bench.workspace.directory)
108
108
  reqs.delete_if do |r|
109
- bundle.workspace.require_paths.any? do |base|
109
+ bench.workspace.require_paths.any? do |base|
110
110
  pn = workspace_path.join(base, "#{r}.rb").to_s
111
111
  if file_keys.include? pn
112
112
  local_path_hash[r] = pn
@@ -118,22 +118,25 @@ module Solargraph
118
118
  end
119
119
  end
120
120
  reqs.merge implicit.requires
121
- pins.concat implicit.overrides
122
- br = reqs.include?('bundler/require') ? require_from_bundle(bundle.workspace.directory) : {}
121
+ br = reqs.include?('bundler/require') ? require_from_bundle(bench.workspace.directory) : {}
123
122
  reqs.merge br.keys
124
- yard_map.change(reqs.to_a, br, bundle.workspace.gemnames)
125
- new_store = Store.new(pins + yard_map.pins)
126
- @mutex.synchronize {
127
- @cache.clear
128
- @source_map_hash = new_map_hash
129
- @store = new_store
130
- @unresolved_requires = yard_map.unresolved_requires
131
- workspace_filenames.clear
132
- workspace_filenames.concat bundle.workspace.filenames
133
- }
123
+ yard_map.change(reqs.to_a, br, bench.workspace.gemnames)
124
+ new_store = Store.new(yard_map.pins + implicit.pins + pins)
125
+ @cache.clear
126
+ @source_map_hash = new_map_hash
127
+ @store = new_store
128
+ @unresolved_requires = yard_map.unresolved_requires
129
+ workspace_filenames.clear
130
+ workspace_filenames.concat bench.workspace.filenames
131
+ @rebindable_method_names = nil
132
+ store.block_pins.each { |blk| blk.rebind(self) }
134
133
  self
135
134
  end
136
135
 
136
+ def required
137
+ @required ||= Set.new
138
+ end
139
+
137
140
  # @return [Environ]
138
141
  def implicit
139
142
  @implicit ||= Environ.new
@@ -149,7 +152,7 @@ module Solargraph
149
152
  # @return [Source::Cursor]
150
153
  def cursor_at filename, position
151
154
  position = Position.normalize(position)
152
- raise FileNotFoundError, "File not found: #{filename}" unless source_map_hash.has_key?(filename)
155
+ raise FileNotFoundError, "File not found: #{filename}" unless source_map_hash.key?(filename)
153
156
  source_map_hash[filename].cursor_at(position)
154
157
  end
155
158
 
@@ -168,9 +171,9 @@ module Solargraph
168
171
  # @param directory [String]
169
172
  # @return [ApiMap]
170
173
  def self.load directory
171
- api_map = self.new
174
+ api_map = new
172
175
  workspace = Solargraph::Workspace.new(directory)
173
- api_map.catalog Bundle.new(workspace: workspace)
176
+ api_map.catalog Bench.new(workspace: workspace)
174
177
  api_map
175
178
  end
176
179
 
@@ -179,13 +182,21 @@ module Solargraph
179
182
  store.pins
180
183
  end
181
184
 
185
+ def rebindable_method_names
186
+ @rebindable_method_names ||= begin
187
+ result = yard_map.rebindable_method_names
188
+ source_maps.each do |map|
189
+ result.merge map.rebindable_method_names
190
+ end
191
+ result
192
+ end
193
+ end
194
+
182
195
  # An array of pins based on Ruby keywords (`if`, `end`, etc.).
183
196
  #
184
197
  # @return [Array<Solargraph::Pin::Keyword>]
185
- def self.keywords
186
- @keywords ||= CoreFills::KEYWORDS.map{ |s|
187
- Pin::Keyword.new(s)
188
- }.freeze
198
+ def keyword_pins
199
+ store.pins_by_class(Pin::Keyword)
189
200
  end
190
201
 
191
202
  # An array of namespace names defined in the ApiMap.
@@ -280,8 +291,7 @@ module Solargraph
280
291
 
281
292
  # @return [Array<Solargraph::Pin::GlobalVariable>]
282
293
  def get_global_variable_pins
283
- # @todo Slow version
284
- pins.select{ |p| p.is_a?(Pin::GlobalVariable) }
294
+ store.pins_by_class(Pin::GlobalVariable)
285
295
  end
286
296
 
287
297
  # Get an array of methods available in a particular context.
@@ -290,7 +300,7 @@ module Solargraph
290
300
  # @param scope [Symbol] :class or :instance
291
301
  # @param visibility [Array<Symbol>] :public, :protected, and/or :private
292
302
  # @param deep [Boolean] True to include superclasses, mixins, etc.
293
- # @return [Array<Solargraph::Pin::BaseMethod>]
303
+ # @return [Array<Solargraph::Pin::Method>]
294
304
  def get_methods fqns, scope: :instance, visibility: [:public], deep: true
295
305
  cached = cache.get_methods(fqns, scope, visibility, deep)
296
306
  return cached.clone unless cached.nil?
@@ -367,9 +377,9 @@ module Solargraph
367
377
  # @param fqns [String]
368
378
  # @param name [String]
369
379
  # @param scope [Symbol] :instance or :class
370
- # @return [Array<Solargraph::Pin::BaseMethod>]
380
+ # @return [Array<Solargraph::Pin::Method>]
371
381
  def get_method_stack fqns, name, scope: :instance
372
- get_methods(fqns, scope: scope, visibility: [:private, :protected, :public]).select{|p| p.name == name}
382
+ get_methods(fqns, scope: scope, visibility: [:private, :protected, :public]).select { |p| p.name == name }
373
383
  end
374
384
 
375
385
  # Get an array of all suggestions that match the specified path.
@@ -380,9 +390,7 @@ module Solargraph
380
390
  # @return [Array<Solargraph::Pin::Base>]
381
391
  def get_path_suggestions path
382
392
  return [] if path.nil?
383
- result = []
384
- result.concat store.get_path_pins(path)
385
- resolve_method_aliases(result)
393
+ resolve_method_aliases store.get_path_pins(path)
386
394
  end
387
395
 
388
396
  # Get an array of pins that match the specified path.
@@ -404,8 +412,9 @@ module Solargraph
404
412
  rake_yard(store)
405
413
  found = []
406
414
  code_object_paths.each do |k|
407
- if found.empty? || (query.include?('.') || query.include?('#')) || !(k.include?('.') || k.include?('#'))
408
- found.push k if k.downcase.include?(query.downcase)
415
+ if (found.empty? || (query.include?('.') || query.include?('#')) || !(k.include?('.') || k.include?('#'))) &&
416
+ k.downcase.include?(query.downcase)
417
+ found.push k
409
418
  end
410
419
  end
411
420
  found
@@ -417,7 +426,7 @@ module Solargraph
417
426
  # api_map.document('String#split')
418
427
  #
419
428
  # @param path [String] The path to find
420
- # @return [Array<YARD::CodeObject::Base>]
429
+ # @return [Array<YARD::CodeObjects::Base>]
421
430
  def document path
422
431
  rake_yard(store)
423
432
  docs = []
@@ -431,24 +440,22 @@ module Solargraph
431
440
  # @return [Array<Pin::Base>]
432
441
  def query_symbols query
433
442
  result = []
434
- source_map_hash.values.each do |s|
435
- result.concat s.query_symbols(query)
436
- end
443
+ source_map_hash.each_value { |s| result.concat s.query_symbols(query) }
437
444
  result
438
445
  end
439
446
 
440
447
  # @param location [Solargraph::Location]
441
448
  # @return [Array<Solargraph::Pin::Base>]
442
449
  def locate_pins location
443
- return [] if location.nil? || !source_map_hash.has_key?(location.filename)
444
- source_map_hash[location.filename].locate_pins(location)
450
+ return [] if location.nil? || !source_map_hash.key?(location.filename)
451
+ resolve_method_aliases source_map_hash[location.filename].locate_pins(location)
445
452
  end
446
453
 
447
454
  # @raise [FileNotFoundError] if the cursor's file is not in the ApiMap
448
455
  # @param cursor [Source::Cursor]
449
456
  # @return [SourceMap::Clip]
450
457
  def clip cursor
451
- raise FileNotFoundError, "ApiMap did not catalog #{cursor.filename}" unless source_map_hash.has_key?(cursor.filename)
458
+ raise FileNotFoundError, "ApiMap did not catalog #{cursor.filename}" unless source_map_hash.key?(cursor.filename)
452
459
  SourceMap::Clip.new(self, cursor)
453
460
  end
454
461
 
@@ -457,8 +464,8 @@ module Solargraph
457
464
  # @param filename [String]
458
465
  # @return [Array<Pin::Symbol>]
459
466
  def document_symbols filename
460
- return [] unless source_map_hash.has_key?(filename) # @todo Raise error?
461
- source_map_hash[filename].document_symbols
467
+ return [] unless source_map_hash.key?(filename) # @todo Raise error?
468
+ resolve_method_aliases source_map_hash[filename].document_symbols
462
469
  end
463
470
 
464
471
  # @return [Array<SourceMap>]
@@ -471,7 +478,7 @@ module Solargraph
471
478
  # @param filename [String]
472
479
  # @return [SourceMap]
473
480
  def source_map filename
474
- raise FileNotFoundError, "Source map for `#{filename}` not found" unless source_map_hash.has_key?(filename)
481
+ raise FileNotFoundError, "Source map for `#{filename}` not found" unless source_map_hash.key?(filename)
475
482
  source_map_hash[filename]
476
483
  end
477
484
 
@@ -494,7 +501,7 @@ module Solargraph
494
501
  # @return [Location]
495
502
  def require_reference_at location
496
503
  map = source_map(location.filename)
497
- pin = map.requires.select { |pin| pin.location.range.contain?(location.range.start) }.first
504
+ pin = map.requires.select { |p| p.location.range.contain?(location.range.start) }.first
498
505
  return nil if pin.nil?
499
506
  if local_path_hash.key?(pin.name)
500
507
  return Location.new(local_path_hash[pin.name], Solargraph::Range.from_to(0, 0, 0, 0))
@@ -519,6 +526,11 @@ module Solargraph
519
526
  false
520
527
  end
521
528
 
529
+ # @return [YardMap]
530
+ def yard_map
531
+ @yard_map ||= YardMap.new
532
+ end
533
+
522
534
  private
523
535
 
524
536
  # @return [Array<String>]
@@ -526,27 +538,16 @@ module Solargraph
526
538
  @workspace_filenames ||= []
527
539
  end
528
540
 
529
- # @return [YardMap]
530
- def yard_map
531
- @yard_map ||= YardMap.new
532
- end
533
-
534
541
  # A hash of source maps with filename keys.
535
542
  #
536
543
  # @return [Hash{String => SourceMap}]
537
- def source_map_hash
538
- @mutex.synchronize { @source_map_hash }
539
- end
544
+ attr_reader :source_map_hash
540
545
 
541
546
  # @return [ApiMap::Store]
542
- def store
543
- @mutex.synchronize { @store }
544
- end
547
+ attr_reader :store
545
548
 
546
549
  # @return [Solargraph::ApiMap::Cache]
547
- def cache
548
- @mutex.synchronize { @cache }
549
- end
550
+ attr_reader :cache
550
551
 
551
552
  # @param fqns [String] A fully qualified namespace
552
553
  # @param scope [Symbol] :class or :instance
@@ -653,6 +654,7 @@ module Solargraph
653
654
  return nil if name.nil?
654
655
  return nil if skip.include?(root)
655
656
  skip.add root
657
+ possibles = []
656
658
  if name == ''
657
659
  if root == ''
658
660
  return ''
@@ -668,16 +670,19 @@ module Solargraph
668
670
  incs = store.get_includes(roots.join('::'))
669
671
  incs.each do |inc|
670
672
  foundinc = inner_qualify(name, inc, skip)
671
- return foundinc unless foundinc.nil?
673
+ possibles.push foundinc unless foundinc.nil?
672
674
  end
673
675
  roots.pop
674
676
  end
675
- incs = store.get_includes('')
676
- incs.each do |inc|
677
- foundinc = inner_qualify(name, inc, skip)
678
- return foundinc unless foundinc.nil?
677
+ if possibles.empty?
678
+ incs = store.get_includes('')
679
+ incs.each do |inc|
680
+ foundinc = inner_qualify(name, inc, skip)
681
+ possibles.push foundinc unless foundinc.nil?
682
+ end
679
683
  end
680
684
  return name if store.namespace_exists?(name)
685
+ return possibles.last
681
686
  end
682
687
  end
683
688
 
@@ -717,29 +722,31 @@ module Solargraph
717
722
  result = []
718
723
  pins.each do |pin|
719
724
  resolved = resolve_method_alias(pin)
720
- next unless visibility.include?(resolved.visibility)
725
+ next if resolved.respond_to?(:visibility) && !visibility.include?(resolved.visibility)
721
726
  result.push resolved
722
727
  end
723
728
  result
724
729
  end
725
730
 
726
731
  # @param pin [Pin::MethodAlias, Pin::Base]
727
- # @return [Pin::BaseMethod]
732
+ # @return [Pin::Method]
728
733
  def resolve_method_alias pin
729
734
  return pin if !pin.is_a?(Pin::MethodAlias) || @method_alias_stack.include?(pin.path)
730
735
  @method_alias_stack.push pin.path
731
736
  origin = get_method_stack(pin.full_context.namespace, pin.original, scope: pin.scope).first
732
737
  @method_alias_stack.pop
733
738
  return pin if origin.nil?
734
- Pin::Method.new(
739
+ args = {
735
740
  location: pin.location,
736
741
  closure: pin.closure,
737
742
  name: pin.name,
738
743
  comments: origin.comments,
739
744
  scope: origin.scope,
740
745
  visibility: origin.visibility,
741
- parameters: origin.parameters
742
- )
746
+ parameters: origin.parameters,
747
+ attribute: origin.attribute?
748
+ }
749
+ Pin::Method.new **args
743
750
  end
744
751
  end
745
752
  end
@@ -4,18 +4,22 @@ module Solargraph
4
4
  # An aggregation of a workspace and additional sources to be cataloged in an
5
5
  # ApiMap.
6
6
  #
7
- class Bundle
7
+ class Bench
8
8
  # @return [Workspace]
9
9
  attr_reader :workspace
10
10
 
11
11
  # @return [Array<Source>]
12
12
  attr_reader :opened
13
13
 
14
+ # @return [Array<Pin::Base>]
15
+ attr_reader :pins
16
+
14
17
  # @param workspace [Workspace]
15
18
  # @param opened [Array<Source>]
16
- def initialize workspace: Workspace.new, opened: []
19
+ def initialize workspace: Workspace.new, opened: [], pins: []
17
20
  @workspace = workspace
18
21
  @opened = opened
22
+ @pins = pins
19
23
  end
20
24
 
21
25
  # @return [Array<Source>]
@@ -0,0 +1,23 @@
1
+ unless Hash.method_defined?(:transform_values)
2
+ class Hash
3
+ def transform_values &block
4
+ each_pair do |k, v|
5
+ self[k] = block.call(v)
6
+ end
7
+ end
8
+ end
9
+ end
10
+
11
+ unless Array.method_defined?(:sum)
12
+ class Array
13
+ def sum &block
14
+ inject(0) do |s, x|
15
+ if block
16
+ s + block.call(x)
17
+ else
18
+ s + x
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end