solargraph 0.39.17 → 0.40.0

Sign up to get free protection for your applications and to get access to all the features.
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