solargraph 0.39.17 → 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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -7
  3. data/CHANGELOG.md +984 -0
  4. data/SPONSORS.md +1 -0
  5. data/lib/solargraph.rb +2 -4
  6. data/lib/solargraph/api_map.rb +61 -64
  7. data/lib/solargraph/api_map/cache.rb +2 -2
  8. data/lib/solargraph/api_map/store.rb +3 -7
  9. data/lib/solargraph/{bundle.rb → bench.rb} +6 -2
  10. data/lib/solargraph/compat.rb +14 -0
  11. data/lib/solargraph/convention.rb +13 -4
  12. data/lib/solargraph/convention/base.rb +16 -8
  13. data/lib/solargraph/convention/gemfile.rb +2 -5
  14. data/lib/solargraph/convention/gemspec.rb +3 -6
  15. data/lib/solargraph/convention/rspec.rb +3 -6
  16. data/lib/solargraph/environ.rb +11 -6
  17. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +6 -1
  18. data/lib/solargraph/language_server/message/text_document/definition.rb +1 -1
  19. data/lib/solargraph/library.rb +5 -5
  20. data/lib/solargraph/parser/legacy/node_processors/ivasgn_node.rb +1 -1
  21. data/lib/solargraph/parser/legacy/node_processors/send_node.rb +34 -22
  22. data/lib/solargraph/parser/node_processor/base.rb +3 -0
  23. data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +1 -1
  24. data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +1 -1
  25. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +38 -28
  26. data/lib/solargraph/pin.rb +0 -3
  27. data/lib/solargraph/pin/common.rb +1 -1
  28. data/lib/solargraph/pin/conversions.rb +1 -1
  29. data/lib/solargraph/pin/documenting.rb +3 -9
  30. data/lib/solargraph/pin/method.rb +141 -7
  31. data/lib/solargraph/pin/method_alias.rb +1 -1
  32. data/lib/solargraph/position.rb +2 -14
  33. data/lib/solargraph/source.rb +10 -6
  34. data/lib/solargraph/source/chain.rb +3 -3
  35. data/lib/solargraph/source_map.rb +4 -1
  36. data/lib/solargraph/source_map/clip.rb +3 -2
  37. data/lib/solargraph/source_map/mapper.rb +10 -6
  38. data/lib/solargraph/type_checker.rb +35 -39
  39. data/lib/solargraph/type_checker/param_def.rb +1 -1
  40. data/lib/solargraph/version.rb +1 -1
  41. data/lib/solargraph/yard_map.rb +38 -47
  42. data/lib/solargraph/yard_map/core_fills.rb +185 -0
  43. data/lib/solargraph/yard_map/helpers.rb +16 -0
  44. data/lib/solargraph/yard_map/mapper.rb +11 -5
  45. data/lib/solargraph/{pin/yard_pin/constant.rb → yard_map/mapper/to_constant.rb} +6 -6
  46. data/lib/solargraph/yard_map/mapper/to_method.rb +78 -0
  47. data/lib/solargraph/{pin/yard_pin/namespace.rb → yard_map/mapper/to_namespace.rb} +6 -6
  48. data/lib/solargraph/yard_map/rdoc_to_yard.rb +1 -1
  49. data/lib/solargraph/yard_map/stdlib_fills.rb +43 -0
  50. data/lib/solargraph/{pin/yard_pin/method.rb → yard_map/to_method.rb} +29 -30
  51. data/solargraph.gemspec +4 -4
  52. metadata +20 -34
  53. data/lib/solargraph/core_fills.rb +0 -164
  54. data/lib/solargraph/pin/attribute.rb +0 -49
  55. data/lib/solargraph/pin/base_method.rb +0 -149
  56. data/lib/solargraph/pin/yard_pin.rb +0 -12
  57. data/lib/solargraph/pin/yard_pin/yard_mixin.rb +0 -20
  58. data/lib/solargraph/stdlib_fills.rb +0 -40
  59. data/travis-bundler.rb +0 -11
@@ -12,3 +12,4 @@ The following people and organizations provide funding or other resources. [Beco
12
12
 
13
13
  - Emily Strickland
14
14
  - Tom de Grunt
15
+ - Akira Yamada
@@ -27,15 +27,13 @@ module Solargraph
27
27
  autoload :YardMap, 'solargraph/yard_map'
28
28
  autoload :Pin, 'solargraph/pin'
29
29
  autoload :ServerMethods, 'solargraph/server_methods'
30
- autoload :CoreFills, 'solargraph/core_fills'
31
- autoload :StdlibFills, 'solargraph/stdlib_fills'
32
30
  autoload :LanguageServer, 'solargraph/language_server'
33
31
  autoload :Workspace, 'solargraph/workspace'
34
32
  autoload :Page, 'solargraph/page'
35
33
  autoload :Library, 'solargraph/library'
36
34
  autoload :Diagnostics, 'solargraph/diagnostics'
37
35
  autoload :ComplexType, 'solargraph/complex_type'
38
- autoload :Bundle, 'solargraph/bundle'
36
+ autoload :Bench, 'solargraph/bench'
39
37
  autoload :Logging, 'solargraph/logging'
40
38
  autoload :TypeChecker, 'solargraph/type_checker'
41
39
  autoload :Environ, 'solargraph/environ'
@@ -56,7 +54,7 @@ module Solargraph
56
54
  end
57
55
 
58
56
  # A helper method that runs Bundler.with_unbundled_env or falls back to
59
- # Bundler.with_clean env for earlier versions of Bundler.
57
+ # Bundler.with_clean_env for earlier versions of Bundler.
60
58
  #
61
59
  def self.with_clean_env &block
62
60
  meth = if Bundler.respond_to?(:with_unbundled_env)
@@ -33,11 +33,7 @@ module Solargraph
33
33
  # @param pins [Array<Pin::Base>]
34
34
  # @return [self]
35
35
  def index pins
36
- @source_map_hash.clear
37
- @cache.clear
38
- @store = Store.new(pins + YardMap.new.pins)
39
- @unresolved_requires = []
40
- workspace_filenames.clear
36
+ catalog Bench.new(pins: pins)
41
37
  self
42
38
  end
43
39
 
@@ -46,7 +42,7 @@ module Solargraph
46
42
  # @param source [Source]
47
43
  # @return [self]
48
44
  def map source
49
- catalog Bundle.new(opened: [source])
45
+ catalog Bench.new(opened: [source])
50
46
  self
51
47
  end
52
48
 
@@ -56,17 +52,19 @@ module Solargraph
56
52
  store.named_macros[name]
57
53
  end
58
54
 
59
- # Catalog a bundle.
55
+ # Catalog a bench.
60
56
  #
61
- # @param bundle [Bundle]
57
+ # @param bench [Bench]
62
58
  # @return [self]
63
- def catalog bundle
59
+ def catalog bench
64
60
  new_map_hash = {}
65
- # Bundle always needs to be merged if it adds or removes sources
66
- merged = (bundle.sources.length == source_map_hash.values.length)
67
- 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|
68
64
  if source_map_hash.key?(source.filename)
69
- 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?
70
68
  new_map_hash[source.filename] = source_map_hash[source.filename]
71
69
  elsif !source.synchronized?
72
70
  new_map_hash[source.filename] = source_map_hash[source.filename]
@@ -87,23 +85,28 @@ module Solargraph
87
85
  merged = false
88
86
  end
89
87
  end
90
- return self if merged
88
+ return self if bench.pins.empty? && @store && merged
91
89
  implicit.clear
92
90
  pins = []
93
91
  reqs = Set.new
94
92
  # @param map [SourceMap]
95
- new_map_hash.values.each do |map|
96
- implicit.merge map.environ
93
+ new_map_hash.each_value do |map|
97
94
  pins.concat map.pins
98
95
  reqs.merge map.requires.map(&:name)
99
96
  end
100
- 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)
101
104
  local_path_hash.clear
102
- unless bundle.workspace.require_paths.empty?
105
+ unless bench.workspace.require_paths.empty?
103
106
  file_keys = new_map_hash.keys
104
- workspace_path = Pathname.new(bundle.workspace.directory)
107
+ workspace_path = Pathname.new(bench.workspace.directory)
105
108
  reqs.delete_if do |r|
106
- bundle.workspace.require_paths.any? do |base|
109
+ bench.workspace.require_paths.any? do |base|
107
110
  pn = workspace_path.join(base, "#{r}.rb").to_s
108
111
  if file_keys.include? pn
109
112
  local_path_hash[r] = pn
@@ -115,22 +118,25 @@ module Solargraph
115
118
  end
116
119
  end
117
120
  reqs.merge implicit.requires
118
- pins.concat implicit.overrides
119
- br = reqs.include?('bundler/require') ? require_from_bundle(bundle.workspace.directory) : {}
121
+ br = reqs.include?('bundler/require') ? require_from_bundle(bench.workspace.directory) : {}
120
122
  reqs.merge br.keys
121
- yard_map.change(reqs.to_a, br, bundle.workspace.gemnames)
122
- new_store = Store.new(pins + yard_map.pins)
123
+ yard_map.change(reqs.to_a, br, bench.workspace.gemnames)
124
+ new_store = Store.new(yard_map.pins + implicit.pins + pins)
123
125
  @cache.clear
124
126
  @source_map_hash = new_map_hash
125
127
  @store = new_store
126
128
  @unresolved_requires = yard_map.unresolved_requires
127
129
  workspace_filenames.clear
128
- workspace_filenames.concat bundle.workspace.filenames
130
+ workspace_filenames.concat bench.workspace.filenames
129
131
  @rebindable_method_names = nil
130
132
  store.block_pins.each { |blk| blk.rebind(self) }
131
133
  self
132
134
  end
133
135
 
136
+ def required
137
+ @required ||= Set.new
138
+ end
139
+
134
140
  # @return [Environ]
135
141
  def implicit
136
142
  @implicit ||= Environ.new
@@ -146,7 +152,7 @@ module Solargraph
146
152
  # @return [Source::Cursor]
147
153
  def cursor_at filename, position
148
154
  position = Position.normalize(position)
149
- 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)
150
156
  source_map_hash[filename].cursor_at(position)
151
157
  end
152
158
 
@@ -165,9 +171,9 @@ module Solargraph
165
171
  # @param directory [String]
166
172
  # @return [ApiMap]
167
173
  def self.load directory
168
- api_map = self.new
174
+ api_map = new
169
175
  workspace = Solargraph::Workspace.new(directory)
170
- api_map.catalog Bundle.new(workspace: workspace)
176
+ api_map.catalog Bench.new(workspace: workspace)
171
177
  api_map
172
178
  end
173
179
 
@@ -189,10 +195,8 @@ module Solargraph
189
195
  # An array of pins based on Ruby keywords (`if`, `end`, etc.).
190
196
  #
191
197
  # @return [Array<Solargraph::Pin::Keyword>]
192
- def self.keywords
193
- @keywords ||= CoreFills::KEYWORDS.map{ |s|
194
- Pin::Keyword.new(s)
195
- }.freeze
198
+ def keyword_pins
199
+ store.pins_by_class(Pin::Keyword)
196
200
  end
197
201
 
198
202
  # An array of namespace names defined in the ApiMap.
@@ -296,7 +300,7 @@ module Solargraph
296
300
  # @param scope [Symbol] :class or :instance
297
301
  # @param visibility [Array<Symbol>] :public, :protected, and/or :private
298
302
  # @param deep [Boolean] True to include superclasses, mixins, etc.
299
- # @return [Array<Solargraph::Pin::BaseMethod>]
303
+ # @return [Array<Solargraph::Pin::Method>]
300
304
  def get_methods fqns, scope: :instance, visibility: [:public], deep: true
301
305
  cached = cache.get_methods(fqns, scope, visibility, deep)
302
306
  return cached.clone unless cached.nil?
@@ -373,9 +377,9 @@ module Solargraph
373
377
  # @param fqns [String]
374
378
  # @param name [String]
375
379
  # @param scope [Symbol] :instance or :class
376
- # @return [Array<Solargraph::Pin::BaseMethod>]
380
+ # @return [Array<Solargraph::Pin::Method>]
377
381
  def get_method_stack fqns, name, scope: :instance
378
- 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 }
379
383
  end
380
384
 
381
385
  # Get an array of all suggestions that match the specified path.
@@ -408,8 +412,9 @@ module Solargraph
408
412
  rake_yard(store)
409
413
  found = []
410
414
  code_object_paths.each do |k|
411
- if found.empty? || (query.include?('.') || query.include?('#')) || !(k.include?('.') || k.include?('#'))
412
- 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
413
418
  end
414
419
  end
415
420
  found
@@ -435,16 +440,14 @@ module Solargraph
435
440
  # @return [Array<Pin::Base>]
436
441
  def query_symbols query
437
442
  result = []
438
- source_map_hash.values.each do |s|
439
- result.concat s.query_symbols(query)
440
- end
443
+ source_map_hash.each_value { |s| result.concat s.query_symbols(query) }
441
444
  result
442
445
  end
443
446
 
444
447
  # @param location [Solargraph::Location]
445
448
  # @return [Array<Solargraph::Pin::Base>]
446
449
  def locate_pins location
447
- return [] if location.nil? || !source_map_hash.has_key?(location.filename)
450
+ return [] if location.nil? || !source_map_hash.key?(location.filename)
448
451
  resolve_method_aliases source_map_hash[location.filename].locate_pins(location)
449
452
  end
450
453
 
@@ -452,7 +455,7 @@ module Solargraph
452
455
  # @param cursor [Source::Cursor]
453
456
  # @return [SourceMap::Clip]
454
457
  def clip cursor
455
- 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)
456
459
  SourceMap::Clip.new(self, cursor)
457
460
  end
458
461
 
@@ -461,7 +464,7 @@ module Solargraph
461
464
  # @param filename [String]
462
465
  # @return [Array<Pin::Symbol>]
463
466
  def document_symbols filename
464
- return [] unless source_map_hash.has_key?(filename) # @todo Raise error?
467
+ return [] unless source_map_hash.key?(filename) # @todo Raise error?
465
468
  resolve_method_aliases source_map_hash[filename].document_symbols
466
469
  end
467
470
 
@@ -475,7 +478,7 @@ module Solargraph
475
478
  # @param filename [String]
476
479
  # @return [SourceMap]
477
480
  def source_map filename
478
- 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)
479
482
  source_map_hash[filename]
480
483
  end
481
484
 
@@ -498,7 +501,7 @@ module Solargraph
498
501
  # @return [Location]
499
502
  def require_reference_at location
500
503
  map = source_map(location.filename)
501
- 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
502
505
  return nil if pin.nil?
503
506
  if local_path_hash.key?(pin.name)
504
507
  return Location.new(local_path_hash[pin.name], Solargraph::Range.from_to(0, 0, 0, 0))
@@ -523,6 +526,11 @@ module Solargraph
523
526
  false
524
527
  end
525
528
 
529
+ # @return [YardMap]
530
+ def yard_map
531
+ @yard_map ||= YardMap.new
532
+ end
533
+
526
534
  private
527
535
 
528
536
  # @return [Array<String>]
@@ -530,27 +538,16 @@ module Solargraph
530
538
  @workspace_filenames ||= []
531
539
  end
532
540
 
533
- # @return [YardMap]
534
- def yard_map
535
- @yard_map ||= YardMap.new
536
- end
537
-
538
541
  # A hash of source maps with filename keys.
539
542
  #
540
543
  # @return [Hash{String => SourceMap}]
541
- def source_map_hash
542
- @source_map_hash
543
- end
544
+ attr_reader :source_map_hash
544
545
 
545
546
  # @return [ApiMap::Store]
546
- def store
547
- @store
548
- end
547
+ attr_reader :store
549
548
 
550
549
  # @return [Solargraph::ApiMap::Cache]
551
- def cache
552
- @cache
553
- end
550
+ attr_reader :cache
554
551
 
555
552
  # @param fqns [String] A fully qualified namespace
556
553
  # @param scope [Symbol] :class or :instance
@@ -732,7 +729,7 @@ module Solargraph
732
729
  end
733
730
 
734
731
  # @param pin [Pin::MethodAlias, Pin::Base]
735
- # @return [Pin::BaseMethod]
732
+ # @return [Pin::Method]
736
733
  def resolve_method_alias pin
737
734
  return pin if !pin.is_a?(Pin::MethodAlias) || @method_alias_stack.include?(pin.path)
738
735
  @method_alias_stack.push pin.path
@@ -745,11 +742,11 @@ module Solargraph
745
742
  name: pin.name,
746
743
  comments: origin.comments,
747
744
  scope: origin.scope,
748
- visibility: origin.visibility
745
+ visibility: origin.visibility,
746
+ parameters: origin.parameters,
747
+ attribute: origin.attribute?
749
748
  }
750
- args[:parameters] = origin.parameters unless origin.is_a?(Pin::Attribute)
751
- klass = origin.is_a?(Pin::Attribute) ? Pin::Attribute : Pin::Method
752
- klass.new **args
749
+ Pin::Method.new **args
753
750
  end
754
751
  end
755
752
  end
@@ -10,7 +10,7 @@ module Solargraph
10
10
  @receiver_definitions = {}
11
11
  end
12
12
 
13
- # @return [Array<Pin::BaseMethod>]
13
+ # @return [Array<Pin::Method>]
14
14
  def get_methods fqns, scope, visibility, deep
15
15
  @methods[[fqns, scope, visibility.sort, deep]]
16
16
  end
@@ -41,7 +41,7 @@ module Solargraph
41
41
  @receiver_definitions.key? path
42
42
  end
43
43
 
44
- # @return [Pin::BaseMethod]
44
+ # @return [Pin::Method]
45
45
  def get_receiver_definition path
46
46
  @receiver_definitions[path]
47
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
 
@@ -102,9 +102,9 @@ module Solargraph
102
102
  pins_by_class(Solargraph::Pin::Namespace)
103
103
  end
104
104
 
105
- # @return [Array<Solargraph::Pin::BaseMethod>]
105
+ # @return [Array<Solargraph::Pin::Method>]
106
106
  def method_pins
107
- pins_by_class(Solargraph::Pin::BaseMethod)
107
+ pins_by_class(Solargraph::Pin::Method)
108
108
  end
109
109
 
110
110
  # @param fqns [String]
@@ -245,10 +245,6 @@ module Solargraph
245
245
  pin.docstring.add_tag(tag)
246
246
  end
247
247
  end
248
- # @todo This is probably not the best place for these overrides
249
- superclass_references['Integer'] = ['Numeric']
250
- superclass_references['Float'] = ['Numeric']
251
- superclass_references['File'] = ['IO']
252
248
  end
253
249
  end
254
250
  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>]
@@ -7,3 +7,17 @@ unless Hash.method_defined?(:transform_values)
7
7
  end
8
8
  end
9
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
@@ -20,13 +20,22 @@ module Solargraph
20
20
  @@conventions.add convention.new
21
21
  end
22
22
 
23
- # @param source [Source]
23
+ # @param source_map [SourceMap]
24
24
  # @return [Environ]
25
- def self.for(source)
25
+ def self.for_local(source_map)
26
26
  result = Environ.new
27
- return result if source.filename.nil? || source.filename.empty?
28
27
  @@conventions.each do |conv|
29
- result.merge conv.environ if conv.match?(source)
28
+ result.merge conv.local(source_map)
29
+ end
30
+ result
31
+ end
32
+
33
+ # @param yard_map [YardMap]
34
+ # @return [Environ]
35
+ def self.for_global(yard_map)
36
+ result = Environ.new
37
+ @@conventions.each do |conv|
38
+ result.merge conv.global(yard_map)
30
39
  end
31
40
  result
32
41
  end