solargraph 0.54.0 → 0.55.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 (105) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +58 -0
  3. data/lib/solargraph/api_map/cache.rb +10 -1
  4. data/lib/solargraph/api_map/index.rb +167 -0
  5. data/lib/solargraph/api_map/store.rb +75 -122
  6. data/lib/solargraph/api_map.rb +109 -41
  7. data/lib/solargraph/bench.rb +17 -1
  8. data/lib/solargraph/complex_type/type_methods.rb +17 -11
  9. data/lib/solargraph/complex_type/unique_type.rb +181 -17
  10. data/lib/solargraph/complex_type.rb +103 -24
  11. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +51 -0
  12. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +100 -0
  13. data/lib/solargraph/convention/struct_definition.rb +101 -0
  14. data/lib/solargraph/convention.rb +2 -0
  15. data/lib/solargraph/doc_map.rb +43 -18
  16. data/lib/solargraph/equality.rb +33 -0
  17. data/lib/solargraph/language_server/host/message_worker.rb +51 -5
  18. data/lib/solargraph/language_server/host.rb +13 -11
  19. data/lib/solargraph/language_server/message/base.rb +19 -12
  20. data/lib/solargraph/language_server/message/initialize.rb +3 -1
  21. data/lib/solargraph/language_server/message/text_document/completion.rb +0 -3
  22. data/lib/solargraph/language_server/message/text_document/definition.rb +3 -3
  23. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +3 -3
  24. data/lib/solargraph/language_server/message/text_document/formatting.rb +4 -0
  25. data/lib/solargraph/language_server/message/text_document/hover.rb +1 -1
  26. data/lib/solargraph/language_server/message/text_document/type_definition.rb +3 -3
  27. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -2
  28. data/lib/solargraph/language_server/progress.rb +19 -2
  29. data/lib/solargraph/library.rb +31 -41
  30. data/lib/solargraph/location.rb +29 -1
  31. data/lib/solargraph/parser/comment_ripper.rb +11 -6
  32. data/lib/solargraph/parser/flow_sensitive_typing.rb +226 -0
  33. data/lib/solargraph/parser/node_methods.rb +15 -1
  34. data/lib/solargraph/parser/parser_gem/class_methods.rb +11 -6
  35. data/lib/solargraph/parser/parser_gem/node_chainer.rb +10 -10
  36. data/lib/solargraph/parser/parser_gem/node_methods.rb +6 -4
  37. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +21 -0
  38. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +23 -19
  39. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +21 -1
  40. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +21 -0
  41. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +8 -2
  42. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +26 -5
  43. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +41 -0
  44. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +1 -1
  45. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +28 -0
  46. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +28 -0
  47. data/lib/solargraph/parser/parser_gem/node_processors.rb +10 -0
  48. data/lib/solargraph/parser.rb +3 -5
  49. data/lib/solargraph/pin/base.rb +47 -17
  50. data/lib/solargraph/pin/base_variable.rb +11 -4
  51. data/lib/solargraph/pin/block.rb +8 -26
  52. data/lib/solargraph/pin/breakable.rb +9 -0
  53. data/lib/solargraph/pin/callable.rb +147 -0
  54. data/lib/solargraph/pin/closure.rb +8 -3
  55. data/lib/solargraph/pin/common.rb +2 -6
  56. data/lib/solargraph/pin/conversions.rb +3 -2
  57. data/lib/solargraph/pin/instance_variable.rb +2 -2
  58. data/lib/solargraph/pin/local_variable.rb +7 -1
  59. data/lib/solargraph/pin/method.rb +76 -48
  60. data/lib/solargraph/pin/namespace.rb +14 -11
  61. data/lib/solargraph/pin/parameter.rb +24 -17
  62. data/lib/solargraph/pin/proxy_type.rb +13 -7
  63. data/lib/solargraph/pin/signature.rb +3 -129
  64. data/lib/solargraph/pin/until.rb +18 -0
  65. data/lib/solargraph/pin/while.rb +18 -0
  66. data/lib/solargraph/pin.rb +7 -1
  67. data/lib/solargraph/position.rb +7 -0
  68. data/lib/solargraph/range.rb +9 -4
  69. data/lib/solargraph/rbs_map/conversions.rb +84 -45
  70. data/lib/solargraph/rbs_map/core_fills.rb +16 -9
  71. data/lib/solargraph/rbs_map.rb +1 -0
  72. data/lib/solargraph/shell.rb +19 -2
  73. data/lib/solargraph/source/chain/array.rb +10 -8
  74. data/lib/solargraph/source/chain/block_symbol.rb +1 -1
  75. data/lib/solargraph/source/chain/block_variable.rb +1 -1
  76. data/lib/solargraph/source/chain/call.rb +125 -61
  77. data/lib/solargraph/source/chain/constant.rb +1 -1
  78. data/lib/solargraph/source/chain/hash.rb +8 -2
  79. data/lib/solargraph/source/chain/if.rb +5 -0
  80. data/lib/solargraph/source/chain/link.rb +28 -5
  81. data/lib/solargraph/source/chain/literal.rb +27 -2
  82. data/lib/solargraph/source/chain/or.rb +1 -1
  83. data/lib/solargraph/source/chain/z_super.rb +1 -1
  84. data/lib/solargraph/source/chain.rb +131 -63
  85. data/lib/solargraph/source/cursor.rb +3 -2
  86. data/lib/solargraph/source/source_chainer.rb +2 -2
  87. data/lib/solargraph/source.rb +104 -86
  88. data/lib/solargraph/source_map/clip.rb +8 -6
  89. data/lib/solargraph/source_map/data.rb +30 -0
  90. data/lib/solargraph/source_map.rb +28 -16
  91. data/lib/solargraph/type_checker/checks.rb +4 -0
  92. data/lib/solargraph/type_checker/rules.rb +6 -1
  93. data/lib/solargraph/type_checker.rb +48 -21
  94. data/lib/solargraph/version.rb +1 -1
  95. data/lib/solargraph/views/environment.erb +3 -5
  96. data/lib/solargraph/workspace/config.rb +7 -3
  97. data/lib/solargraph/workspace.rb +1 -1
  98. data/lib/solargraph/yard_map/mapper/to_constant.rb +1 -0
  99. data/lib/solargraph/yard_map/mapper/to_method.rb +42 -15
  100. data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -0
  101. data/lib/solargraph/yard_map/mapper.rb +1 -0
  102. data/lib/solargraph/yardoc.rb +1 -1
  103. data/lib/solargraph.rb +1 -0
  104. data/solargraph.gemspec +5 -5
  105. metadata +41 -25
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Solargraph
4
4
  class SourceMap
5
- # A static analysis tool for obtaining definitions, completions,
6
- # signatures, and type inferences from a cursor.
5
+ # A static analysis tool for obtaining definitions, Completions,
6
+ # signatures, and type inferences from a Cursor.
7
7
  #
8
8
  class Clip
9
9
  # @param api_map [ApiMap]
@@ -11,7 +11,9 @@ module Solargraph
11
11
  def initialize api_map, cursor
12
12
  @api_map = api_map
13
13
  @cursor = cursor
14
- block.rebind(api_map) if block.is_a?(Pin::Block)
14
+ block_pin = block
15
+ block_pin.rebind(api_map) if block_pin.is_a?(Pin::Block) && !Solargraph::Range.from_node(block_pin.receiver).contain?(cursor.range.start)
16
+ @in_block = nil
15
17
  end
16
18
 
17
19
  # @return [Array<Pin::Base>] Relevant pins for infering the type of the Cursor's position
@@ -40,7 +42,7 @@ module Solargraph
40
42
  end
41
43
  end
42
44
 
43
- # @return [Array<Pin::Base>]
45
+ # @return [Array<Pin::Method>]
44
46
  def signify
45
47
  return [] unless cursor.argument?
46
48
  chain = Parser.chain(cursor.recipient_node, cursor.filename)
@@ -53,10 +55,10 @@ module Solargraph
53
55
  if result.tag == 'Class'
54
56
  # HACK: Exception to return BasicObject from Class#new
55
57
  dfn = cursor.chain.define(api_map, block, locals).first
56
- return ComplexType.try_parse('BasicObject') if dfn && dfn.path == 'Class#new'
58
+ return ComplexType.try_parse('::BasicObject') if dfn && dfn.path == 'Class#new'
57
59
  end
58
60
  return result unless result.tag == 'self'
59
- ComplexType.try_parse(cursor.chain.base.infer(api_map, block, locals).tag)
61
+ cursor.chain.base.infer(api_map, block, locals)
60
62
  end
61
63
 
62
64
  # Get an array of all the locals that are visible from the cursors's
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class SourceMap
5
+ class Data
6
+ def initialize source
7
+ @source = source
8
+ end
9
+
10
+ def pins
11
+ generate
12
+ @pins || []
13
+ end
14
+
15
+ def locals
16
+ generate
17
+ @locals || []
18
+ end
19
+
20
+ private
21
+
22
+ def generate
23
+ return if @generated
24
+
25
+ @generated = true
26
+ @pins, @locals = Mapper.map(@source)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -4,40 +4,41 @@ require 'yard'
4
4
  require 'solargraph/yard_tags'
5
5
 
6
6
  module Solargraph
7
- # An index of pins and other ApiMap-related data for a Source.
7
+ # An index of Pins and other ApiMap-related data for a single Source
8
+ # that can be queried.
8
9
  #
9
10
  class SourceMap
10
11
  autoload :Mapper, 'solargraph/source_map/mapper'
11
12
  autoload :Clip, 'solargraph/source_map/clip'
12
13
  autoload :Completion, 'solargraph/source_map/completion'
14
+ autoload :Data, 'solargraph/source_map/data'
13
15
 
14
16
  # @return [Source]
15
17
  attr_reader :source
16
18
 
17
19
  # @return [Array<Pin::Base>]
18
- attr_reader :pins
20
+ def pins
21
+ data.pins
22
+ end
19
23
 
20
24
  # @return [Array<Pin::LocalVariable>]
21
- attr_reader :locals
25
+ def locals
26
+ data.locals
27
+ end
22
28
 
23
29
  # @param source [Source]
24
- # @param pins [Array<Pin::Base>]
25
- # @param locals [Array<Pin::Base>]
26
- def initialize source, pins, locals
27
- # HACK: Keep the library from changing this
28
- @source = source.dup
29
- @pins = pins
30
- @locals = locals
30
+ def initialize source
31
+ @source = source
32
+
31
33
  environ.merge Convention.for_local(self) unless filename.nil?
32
34
  self.convention_pins = environ.pins
33
- @pin_class_hash = pins.to_set.classify(&:class).transform_values(&:to_a)
34
35
  @pin_select_cache = {}
35
36
  end
36
37
 
37
38
  # @param klass [Class]
38
39
  # @return [Array<Pin::Base>]
39
40
  def pins_by_class klass
40
- @pin_select_cache[klass] ||= @pin_class_hash.select { |key, _| key <= klass }.values.flatten
41
+ @pin_select_cache[klass] ||= pin_class_hash.select { |key, _| key <= klass }.values.flatten
41
42
  end
42
43
 
43
44
  # A hash representing the state of the source map's API.
@@ -47,7 +48,7 @@ module Solargraph
47
48
  #
48
49
  # @return [Integer]
49
50
  def api_hash
50
- @api_hash ||= (pins_by_class(Pin::Constant) + pins_by_class(Pin::Namespace).select { |pin| pin.namespace.to_s > '' } + pins_by_class(Pin::Reference) + pins_by_class(Pin::Method).map(&:node)).hash
51
+ @api_hash ||= (pins_by_class(Pin::Constant) + pins_by_class(Pin::Namespace).select { |pin| pin.namespace.to_s > '' } + pins_by_class(Pin::Reference) + pins_by_class(Pin::Method).map(&:node) + locals).hash
51
52
  end
52
53
 
53
54
  # @return [String]
@@ -117,10 +118,13 @@ module Solargraph
117
118
  _locate_pin line, character, Pin::Namespace, Pin::Method, Pin::Block
118
119
  end
119
120
 
121
+ # @todo Candidate for deprecation
122
+ #
120
123
  # @param other_map [SourceMap]
121
124
  # @return [Boolean]
122
125
  def try_merge! other_map
123
126
  return false if pins.length != other_map.pins.length || locals.length != other_map.locals.length || requires.map(&:name).uniq.sort != other_map.requires.map(&:name).uniq.sort
127
+
124
128
  pins.each_index do |i|
125
129
  return false unless pins[i].try_merge!(other_map.pins[i])
126
130
  end
@@ -161,16 +165,24 @@ module Solargraph
161
165
  SourceMap.map(source)
162
166
  end
163
167
 
168
+ # @deprecated
164
169
  # @param source [Source]
165
170
  # @return [SourceMap]
166
171
  def map source
167
- result = SourceMap::Mapper.map(source)
168
- new(source, *result)
172
+ new(source)
169
173
  end
170
174
  end
171
175
 
172
176
  private
173
177
 
178
+ def pin_class_hash
179
+ @pin_class_hash ||= pins.to_set.classify(&:class).transform_values(&:to_a)
180
+ end
181
+
182
+ def data
183
+ @data ||= Data.new(source)
184
+ end
185
+
174
186
  # @return [Array<Pin::Base>]
175
187
  def convention_pins
176
188
  @convention_pins || []
@@ -179,7 +191,7 @@ module Solargraph
179
191
  # @param pins [Array<Pin::Base>]
180
192
  # @return [Array<Pin::Base>]
181
193
  def convention_pins=(pins)
182
- # unmemoizing the document_symbols in case it was called from any of convnetions
194
+ # unmemoizing the document_symbols in case it was called from any of conventions
183
195
  @document_symbols = nil
184
196
  @convention_pins = pins
185
197
  end
@@ -50,6 +50,8 @@ module Solargraph
50
50
  # @param inferred [ComplexType]
51
51
  # @return [Boolean]
52
52
  def any_types_match? api_map, expected, inferred
53
+ expected = expected.downcast_to_literal_if_possible
54
+ inferred = inferred.downcast_to_literal_if_possible
53
55
  return duck_types_match?(api_map, expected, inferred) if expected.duck_type?
54
56
  # walk through the union expected type and see if any members
55
57
  # of the union match the inferred type
@@ -71,6 +73,8 @@ module Solargraph
71
73
  # @param expected [ComplexType]
72
74
  # @return [Boolean]
73
75
  def all_types_match? api_map, inferred, expected
76
+ expected = expected.downcast_to_literal_if_possible
77
+ inferred = inferred.downcast_to_literal_if_possible
74
78
  return duck_types_match?(api_map, expected, inferred) if expected.duck_type?
75
79
  inferred.each do |inf|
76
80
  next if inf.duck_type?
@@ -9,7 +9,8 @@ module Solargraph
9
9
  normal: 0,
10
10
  typed: 1,
11
11
  strict: 2,
12
- strong: 3
12
+ strong: 3,
13
+ alpha: 4
13
14
  }.freeze
14
15
 
15
16
  # @return [Symbol]
@@ -52,6 +53,10 @@ module Solargraph
52
53
  def validate_tags?
53
54
  rank > LEVELS[:normal]
54
55
  end
56
+
57
+ def require_all_return_types_match_inferred?
58
+ rank >= LEVELS[:alpha]
59
+ end
55
60
  end
56
61
  end
57
62
  end
@@ -29,6 +29,7 @@ module Solargraph
29
29
  # @todo Smarter directory resolution
30
30
  @api_map = api_map || Solargraph::ApiMap.load(File.dirname(filename))
31
31
  @rules = Rules.new(level)
32
+ # @type [Array<Range>]
32
33
  @marked_ranges = []
33
34
  end
34
35
 
@@ -90,11 +91,11 @@ module Solargraph
90
91
  def method_return_type_problems_for pin
91
92
  return [] if pin.is_a?(Pin::MethodAlias)
92
93
  result = []
93
- declared = pin.typify(api_map).self_to(pin.full_context.namespace)
94
+ declared = pin.typify(api_map).self_to_type(pin.full_context).qualify(api_map, pin.full_context.tag)
94
95
  if declared.undefined?
95
96
  if pin.return_type.undefined? && rules.require_type_tags?
96
97
  if pin.attribute?
97
- inferred = pin.probe(api_map).self_to(pin.full_context.namespace)
98
+ inferred = pin.probe(api_map).self_to_type(pin.full_context)
98
99
  result.push Problem.new(pin.location, "Missing @return tag for #{pin.path}", pin: pin) unless inferred.defined?
99
100
  else
100
101
  result.push Problem.new(pin.location, "Missing @return tag for #{pin.path}", pin: pin)
@@ -106,14 +107,14 @@ module Solargraph
106
107
  end
107
108
  elsif rules.validate_tags?
108
109
  unless pin.node.nil? || declared.void? || virtual_pin?(pin) || abstract?(pin)
109
- inferred = pin.probe(api_map).self_to(pin.full_context.namespace)
110
+ inferred = pin.probe(api_map).self_to_type(pin.full_context)
110
111
  if inferred.undefined?
111
112
  unless rules.ignore_all_undefined? || external?(pin)
112
113
  result.push Problem.new(pin.location, "#{pin.path} return type could not be inferred", pin: pin)
113
114
  end
114
115
  else
115
- unless (rules.rank > 1 ? all_types_match?(api_map, inferred, declared) : any_types_match?(api_map, declared, inferred))
116
- result.push Problem.new(pin.location, "Declared return type #{declared} does not match inferred type #{inferred} for #{pin.path}", pin: pin)
116
+ unless (rules.require_all_return_types_match_inferred? ? all_types_match?(api_map, inferred, declared) : any_types_match?(api_map, declared, inferred))
117
+ result.push Problem.new(pin.location, "Declared return type #{declared.rooted_tags} does not match inferred type #{inferred.rooted_tags} for #{pin.path}", pin: pin)
117
118
  end
118
119
  end
119
120
  end
@@ -154,7 +155,7 @@ module Solargraph
154
155
  break if par.decl == :restarg || par.decl == :kwrestarg || par.decl == :blockarg
155
156
  unless params[par.name]
156
157
  if pin.attribute?
157
- inferred = pin.probe(api_map).self_to(pin.full_context.namespace)
158
+ inferred = pin.probe(api_map).self_to_type(pin.full_context)
158
159
  if inferred.undefined?
159
160
  result.push Problem.new(pin.location, "Missing @param tag for #{par.name} on #{pin.path}", pin: pin)
160
161
  end
@@ -377,7 +378,7 @@ module Solargraph
377
378
  break
378
379
  end
379
380
  ptype = params.key?(par.name) ? params[par.name][:qualified] : ComplexType::UNDEFINED
380
- ptype = ptype.self_to(par.context.namespace)
381
+ ptype = ptype.self_to_type(par.context)
381
382
  if ptype.nil?
382
383
  # @todo Some level (strong, I guess) should require the param here
383
384
  else
@@ -413,7 +414,7 @@ module Solargraph
413
414
  # @param locals [Array<Pin::LocalVariable>]
414
415
  # @param location [Location]
415
416
  # @param pin [Pin::Method]
416
- # @param params [Hash{String => [nil, Hash]}]
417
+ # @param params [Hash{String => Hash{Symbol => String, Solargraph::ComplexType}}]
417
418
  # @param idx [Integer]
418
419
  #
419
420
  # @return [Array<Problem>]
@@ -467,13 +468,24 @@ module Solargraph
467
468
  end
468
469
 
469
470
  # @param pin [Pin::Method]
470
- # @return [Hash{String => Hash{Symbol => BaseObject}}]
471
+ # @return [Hash{String => Hash{Symbol => String, ComplexType}}]
471
472
  def param_hash(pin)
472
- tags = pin.docstring.tags(:param)
473
- return {} if tags.empty?
473
+ # @type [Hash{String => Hash{Symbol => String, ComplexType}}]
474
474
  result = {}
475
+ pin.parameters.each do |param|
476
+ type = param.typify(api_map)
477
+ next if type.nil? || type.undefined?
478
+ result[param.name.to_s] = {
479
+ tagged: type.tags,
480
+ qualified: type
481
+ }
482
+ end
483
+ # see if we have additional tags to pay attention to from YARD -
484
+ # e.g., kwargs in a **restkwargs splat
485
+ tags = pin.docstring.tags(:param)
475
486
  tags.each do |tag|
476
- next if tag.types.nil? || tag.types.empty?
487
+ next if result.key? tag.name.to_s
488
+ next if tag.types.nil?
477
489
  result[tag.name.to_s] = {
478
490
  tagged: tag.types.join(', '),
479
491
  qualified: Solargraph::ComplexType.try_parse(*tag.types).qualify(api_map, pin.full_context.namespace)
@@ -483,15 +495,29 @@ module Solargraph
483
495
  end
484
496
 
485
497
  # @param pins [Array<Pin::Method>]
486
- # @return [Hash{String => Hash{Symbol => BasicObject}}]
498
+ # @return [Hash{String => Hash{Symbol => String, ComplexType}}]
487
499
  def first_param_hash(pins)
488
- pins.each do |pin|
500
+ return {} if pins.empty?
501
+ first_pin_type = pins.first.typify(api_map)
502
+ first_pin = pins.first.proxy first_pin_type
503
+ param_names = first_pin.parameter_names
504
+ results = param_hash(first_pin)
505
+ pins[1..].each do |pin|
489
506
  # @todo this assignment from parametric use of Hash should not lose its generic
490
507
  # @type [Hash{String => Hash{Symbol => BasicObject}}]
491
- result = param_hash(pin)
492
- return result unless result.empty?
508
+
509
+ # documentation of types in superclasses should fail back to
510
+ # subclasses if the subclass hasn't documented something
511
+ superclass_results = param_hash(pin)
512
+ superclass_results.each do |param_name, details|
513
+ next unless param_names.include?(param_name)
514
+
515
+ results[param_name] ||= {}
516
+ results[param_name][:tagged] ||= details[:tagged]
517
+ results[param_name][:qualified] ||= details[:qualified]
518
+ end
493
519
  end
494
- {}
520
+ results
495
521
  end
496
522
 
497
523
  # @param pin [Pin::Base]
@@ -512,7 +538,7 @@ module Solargraph
512
538
  !internal? pin
513
539
  end
514
540
 
515
- # @param pin [Pin::Base]
541
+ # @param pin [Pin::BaseVariable]
516
542
  def declared_externally? pin
517
543
  return true if pin.assignment.nil?
518
544
  chain = Solargraph::Parser.chain(pin.assignment, filename)
@@ -562,7 +588,7 @@ module Solargraph
562
588
  return [] unless pin.explicit?
563
589
  return [] if parameters.empty? && arguments.empty?
564
590
  return [] if pin.anon_splat?
565
- unchecked = arguments.clone
591
+ unchecked = arguments.dup # creates copy of and unthaws array
566
592
  add_params = 0
567
593
  if unchecked.empty? && parameters.any? { |param| param.decl == :kwarg }
568
594
  return [Problem.new(location, "Missing keyword arguments to #{pin.path}")]
@@ -584,7 +610,8 @@ module Solargraph
584
610
  kwargs.delete param.name.to_sym
585
611
  settled_kwargs += 1
586
612
  elsif param.decl == :kwarg
587
- return [] if arguments.last.links.last.is_a?(Solargraph::Source::Chain::Hash) && arguments.last.links.last.splatted?
613
+ last_arg_last_link = arguments.last.links.last
614
+ return [] if last_arg_last_link.is_a?(Solargraph::Source::Chain::Hash) && last_arg_last_link.splatted?
588
615
  return [Problem.new(location, "Missing keyword argument #{param.name} to #{pin.path}")]
589
616
  end
590
617
  end
@@ -638,7 +665,7 @@ module Solargraph
638
665
  (pin.closure && pin.closure.docstring.has_tag?('abstract'))
639
666
  end
640
667
 
641
- # @param pin [Pin::Base]
668
+ # @param pin [Pin::Method]
642
669
  # @return [Array<Source::Chain>]
643
670
  def fake_args_for(pin)
644
671
  args = []
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Solargraph
4
- VERSION = '0.54.0'
4
+ VERSION = '0.55.0'
5
5
  end
@@ -35,11 +35,9 @@
35
35
  <li>
36
36
  Core Cache Directory: N/A <%# @todo Fix %>
37
37
  </li>
38
- <% unless Solargraph::Parser.rubyvm? %>
39
- <li>
40
- Parser Target Version: <%= Solargraph::Parser.version %>
41
- </li>
42
- <% end %>
38
+ <li>
39
+ Parser Target Version: <%= Solargraph::Parser.version %>
40
+ </li>
43
41
  <li>
44
42
  Using Bundler: <%= ENV.key?('BUNDLE_BIN_PATH') %>
45
43
  </li>
@@ -15,7 +15,7 @@ module Solargraph
15
15
  attr_reader :directory
16
16
 
17
17
  # @todo To make this strongly typed we'll need a record syntax
18
- # @return [Hash{String => undefined}]
18
+ # @return [Hash{String => Array, Hash, Integer, nil}]
19
19
  attr_reader :raw_data
20
20
 
21
21
  # @param directory [String]
@@ -90,6 +90,7 @@ module Solargraph
90
90
 
91
91
  # A hash of options supported by the formatter
92
92
  #
93
+ # @sg-ignore pending https://github.com/castwide/solargraph/pull/905
93
94
  # @return [Hash]
94
95
  def formatter
95
96
  raw_data['formatter']
@@ -104,6 +105,7 @@ module Solargraph
104
105
 
105
106
  # The maximum number of files to parse from the workspace.
106
107
  #
108
+ # @sg-ignore pending https://github.com/castwide/solargraph/pull/905
107
109
  # @return [Integer]
108
110
  def max_files
109
111
  raw_data['max_files']
@@ -123,7 +125,7 @@ module Solargraph
123
125
  File.join(@directory, '.solargraph.yml')
124
126
  end
125
127
 
126
- # @return [Hash{String => Array, Hash, Integer}]
128
+ # @return [Hash{String => Array<undefined>, Hash{String => undefined}, Integer}]
127
129
  def config_data
128
130
  workspace_config = read_config(workspace_config_path)
129
131
  global_config = read_config(global_config_path)
@@ -226,7 +228,9 @@ module Solargraph
226
228
 
227
229
  # @return [Array<String>]
228
230
  def excluded_directories
229
- @raw_data['exclude']
231
+ # @type [Array<String>]
232
+ excluded = @raw_data['exclude']
233
+ excluded
230
234
  .select { |g| glob_is_directory?(g) }
231
235
  .map { |g| File.absolute_path(glob_to_directory(g), directory) }
232
236
  end
@@ -45,7 +45,7 @@ module Solargraph
45
45
  # or add it to the sources if the workspace is configured to include it.
46
46
  # The source is ignored if the configuration excludes it.
47
47
  #
48
- # @param source [Solargraph::Source]
48
+ # @param sources [Array<Solargraph::Source>]
49
49
  # @return [Boolean] True if the source was added to the workspace
50
50
  def merge *sources
51
51
  unless directory == '*' || sources.all? { |source| source_hash.key?(source.filename) }
@@ -6,6 +6,7 @@ module Solargraph
6
6
  module ToConstant
7
7
  extend YardMap::Helpers
8
8
 
9
+ # @param code_object [YARD::CodeObjects::Base]
9
10
  def self.make code_object, closure = nil, spec = nil
10
11
  closure ||= Solargraph::Pin::Namespace.new(
11
12
  name: code_object.namespace.to_s,
@@ -16,29 +16,55 @@ module Solargraph
16
16
  def self.make code_object, name = nil, scope = nil, visibility = nil, closure = nil, spec = nil
17
17
  closure ||= Solargraph::Pin::Namespace.new(
18
18
  name: code_object.namespace.to_s,
19
- gates: [code_object.namespace.to_s]
19
+ gates: [code_object.namespace.to_s],
20
+ type: code_object.namespace.is_a?(YARD::CodeObjects::ClassObject) ? :class : :module,
21
+ source: :yardoc,
20
22
  )
21
23
  location = object_location(code_object, spec)
22
24
  name ||= code_object.name.to_s
23
25
  return_type = ComplexType::SELF if name == 'new'
24
26
  comments = code_object.docstring ? code_object.docstring.all.to_s : ''
25
- pin = Pin::Method.new(
26
- location: location,
27
- closure: closure,
28
- name: name,
29
- comments: comments,
30
- scope: scope || code_object.scope,
31
- visibility: visibility || code_object.visibility,
32
- # @todo Might need to convert overloads to signatures
33
- parameters: [],
34
- explicit: code_object.is_explicit?,
35
- return_type: return_type
36
- )
37
- pin.parameters.concat get_parameters(code_object, location, comments, pin)
27
+ final_scope = scope || code_object.scope
28
+ final_visibility = visibility || code_object.visibility
29
+ if code_object.is_alias?
30
+ origin_code_object = code_object.namespace.aliases[code_object]
31
+ pin = Pin::MethodAlias.new(
32
+ name: name,
33
+ location: location,
34
+ original: origin_code_object.name.to_s,
35
+ closure: closure,
36
+ comments: comments,
37
+ scope: final_scope,
38
+ visibility: final_visibility,
39
+ explicit: code_object.is_explicit?,
40
+ return_type: return_type,
41
+ parameters: [],
42
+ source: :yardoc,
43
+ )
44
+ else
45
+ pin = Pin::Method.new(
46
+ location: location,
47
+ closure: closure,
48
+ name: name,
49
+ comments: comments,
50
+ scope: final_scope,
51
+ visibility: final_visibility,
52
+ # @todo Might need to convert overloads to signatures
53
+ explicit: code_object.is_explicit?,
54
+ return_type: return_type,
55
+ attribute: code_object.is_attribute?,
56
+ parameters: [],
57
+ source: :yardoc,
58
+ )
59
+ pin.parameters.concat get_parameters(code_object, location, comments, pin)
60
+ end
61
+ logger.debug { "ToMethod.make: Just created method pin: #{pin.inspect}" }
38
62
  pin
39
63
  end
40
64
 
41
65
  class << self
66
+ include Logging
67
+
42
68
  private
43
69
 
44
70
  # @param code_object [YARD::CodeObjects::Base]
@@ -59,7 +85,8 @@ module Solargraph
59
85
  name: arg_name(a),
60
86
  presence: nil,
61
87
  decl: arg_type(a),
62
- asgn_code: a[1]
88
+ asgn_code: a[1],
89
+ source: :yardoc,
63
90
  )
64
91
  end
65
92
  end
@@ -6,6 +6,7 @@ module Solargraph
6
6
  module ToNamespace
7
7
  extend YardMap::Helpers
8
8
 
9
+ # @param code_object [YARD::CodeObjects::NamespaceObject]
9
10
  def self.make code_object, spec, closure = nil
10
11
  closure ||= Solargraph::Pin::Namespace.new(
11
12
  name: code_object.namespace.to_s,
@@ -12,6 +12,7 @@ module Solargraph
12
12
  def initialize code_objects, spec = nil
13
13
  @code_objects = code_objects
14
14
  @spec = spec
15
+ # @type [Array<Solargraph::Pin::Base>]
15
16
  @pins = []
16
17
  @namespace_pins = {}
17
18
  end
@@ -35,7 +35,7 @@ module Solargraph
35
35
  # @param gemspec [Gem::Specification]
36
36
  # @return [String]
37
37
  def path_for(gemspec)
38
- File.join(Solargraph::Cache.work_dir, 'gems', "#{gemspec.name}-#{gemspec.version}.yardoc")
38
+ File.join(Solargraph::Cache.base_dir, "yard-#{YARD::VERSION}", "#{gemspec.name}-#{gemspec.version}.yardoc")
39
39
  end
40
40
 
41
41
  # Load a gem's yardoc and return its code objects.
data/lib/solargraph.rb CHANGED
@@ -42,6 +42,7 @@ module Solargraph
42
42
  autoload :Logging, 'solargraph/logging'
43
43
  autoload :TypeChecker, 'solargraph/type_checker'
44
44
  autoload :Environ, 'solargraph/environ'
45
+ autoload :Equality, 'solargraph/equality'
45
46
  autoload :Convention, 'solargraph/convention'
46
47
  autoload :Parser, 'solargraph/parser'
47
48
  autoload :RbsMap, 'solargraph/rbs_map'
data/solargraph.gemspec CHANGED
@@ -24,10 +24,10 @@ Gem::Specification.new do |s|
24
24
  s.required_ruby_version = '>= 3.0'
25
25
 
26
26
  s.add_runtime_dependency 'backport', '~> 1.2'
27
- s.add_runtime_dependency 'benchmark'
27
+ s.add_runtime_dependency 'benchmark', '~> 0.4'
28
28
  s.add_runtime_dependency 'bundler', '~> 2.0'
29
29
  s.add_runtime_dependency 'diff-lcs', '~> 1.4'
30
- s.add_runtime_dependency 'jaro_winkler', '~> 1.6'
30
+ s.add_runtime_dependency 'jaro_winkler', '~> 1.6', '>= 1.6.1'
31
31
  s.add_runtime_dependency 'kramdown', '~> 2.3'
32
32
  s.add_runtime_dependency 'kramdown-parser-gfm', '~> 1.1'
33
33
  s.add_runtime_dependency 'logger', '~> 1.6'
@@ -35,19 +35,19 @@ Gem::Specification.new do |s|
35
35
  s.add_runtime_dependency 'ostruct', '~> 0.6'
36
36
  s.add_runtime_dependency 'parser', '~> 3.0'
37
37
  s.add_runtime_dependency 'rbs', '~> 3.3'
38
- s.add_runtime_dependency 'reverse_markdown', '>= 2.0', '< 4'
38
+ s.add_runtime_dependency 'reverse_markdown', '~> 3.0'
39
39
  s.add_runtime_dependency 'rubocop', '~> 1.38'
40
40
  s.add_runtime_dependency 'thor', '~> 1.0'
41
41
  s.add_runtime_dependency 'tilt', '~> 2.0'
42
42
  s.add_runtime_dependency 'yard', '~> 0.9', '>= 0.9.24'
43
43
  s.add_runtime_dependency 'yard-solargraph', '~> 0.1'
44
44
 
45
- s.add_development_dependency 'pry'
45
+ s.add_development_dependency 'pry', '~> 0.15'
46
46
  s.add_development_dependency 'public_suffix', '~> 3.1'
47
47
  s.add_development_dependency 'rake', '~> 13.2'
48
48
  s.add_development_dependency 'rspec', '~> 3.5'
49
49
  s.add_development_dependency 'simplecov', '~> 0.14'
50
50
  s.add_development_dependency 'webmock', '~> 3.6'
51
51
  # work around missing yard dependency needed as of Ruby 3.5
52
- s.add_development_dependency 'irb'
52
+ s.add_development_dependency 'irb', '~> 1.15'
53
53
  end