solargraph 0.52.0 → 0.53.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 (155) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/plugins.yml +40 -0
  3. data/.github/workflows/rspec.yml +1 -3
  4. data/.github/workflows/typecheck.yml +34 -0
  5. data/CHANGELOG.md +30 -0
  6. data/README.md +13 -16
  7. data/SPONSORS.md +1 -7
  8. data/lib/solargraph/api_map/cache.rb +59 -21
  9. data/lib/solargraph/api_map/store.rb +45 -9
  10. data/lib/solargraph/api_map.rb +152 -93
  11. data/lib/solargraph/bench.rb +2 -2
  12. data/lib/solargraph/cache.rb +29 -5
  13. data/lib/solargraph/complex_type/type_methods.rb +53 -8
  14. data/lib/solargraph/complex_type/unique_type.rb +149 -59
  15. data/lib/solargraph/complex_type.rb +62 -9
  16. data/lib/solargraph/convention.rb +0 -1
  17. data/lib/solargraph/converters/dd.rb +5 -0
  18. data/lib/solargraph/converters/dl.rb +3 -0
  19. data/lib/solargraph/converters/dt.rb +3 -0
  20. data/lib/solargraph/diagnostics/rubocop.rb +8 -7
  21. data/lib/solargraph/diagnostics/rubocop_helpers.rb +1 -0
  22. data/lib/solargraph/diagnostics/type_check.rb +1 -0
  23. data/lib/solargraph/diagnostics.rb +2 -2
  24. data/lib/solargraph/doc_map.rb +146 -0
  25. data/lib/solargraph/gem_pins.rb +64 -0
  26. data/lib/solargraph/language_server/host/cataloger.rb +1 -0
  27. data/lib/solargraph/language_server/host/diagnoser.rb +2 -2
  28. data/lib/solargraph/language_server/host/dispatch.rb +10 -4
  29. data/lib/solargraph/language_server/host/message_worker.rb +4 -0
  30. data/lib/solargraph/language_server/host/sources.rb +7 -4
  31. data/lib/solargraph/language_server/host.rb +15 -6
  32. data/lib/solargraph/language_server/message/completion_item/resolve.rb +3 -1
  33. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +13 -1
  34. data/lib/solargraph/language_server/message/initialize.rb +5 -2
  35. data/lib/solargraph/language_server/message/text_document/hover.rb +2 -0
  36. data/lib/solargraph/language_server/message/text_document.rb +0 -1
  37. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +5 -0
  38. data/lib/solargraph/language_server/transport/adapter.rb +16 -1
  39. data/lib/solargraph/language_server/transport/data_reader.rb +2 -0
  40. data/lib/solargraph/library.rb +58 -11
  41. data/lib/solargraph/location.rb +1 -0
  42. data/lib/solargraph/parser/comment_ripper.rb +3 -0
  43. data/lib/solargraph/parser/node_methods.rb +47 -8
  44. data/lib/solargraph/parser/node_processor/base.rb +9 -0
  45. data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +29 -3
  46. data/lib/solargraph/parser/{legacy → parser_gem}/flawed_builder.rb +3 -1
  47. data/lib/solargraph/parser/{legacy → parser_gem}/node_chainer.rb +42 -34
  48. data/lib/solargraph/parser/{legacy → parser_gem}/node_methods.rb +201 -29
  49. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/alias_node.rb +1 -1
  50. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/args_node.rb +4 -1
  51. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/begin_node.rb +1 -1
  52. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/block_node.rb +3 -2
  53. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/casgn_node.rb +2 -2
  54. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/cvasgn_node.rb +1 -1
  55. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/def_node.rb +1 -1
  56. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/defs_node.rb +2 -2
  57. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/gvasgn_node.rb +1 -1
  58. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/ivasgn_node.rb +2 -2
  59. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/lvasgn_node.rb +2 -2
  60. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/namespace_node.rb +2 -2
  61. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/orasgn_node.rb +1 -1
  62. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/resbody_node.rb +3 -3
  63. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/sclass_node.rb +1 -1
  64. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +2 -2
  65. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/sym_node.rb +1 -1
  66. data/lib/solargraph/parser/parser_gem/node_processors.rb +54 -0
  67. data/lib/solargraph/parser/parser_gem.rb +12 -0
  68. data/lib/solargraph/parser/snippet.rb +2 -0
  69. data/lib/solargraph/parser.rb +8 -11
  70. data/lib/solargraph/pin/base.rb +63 -8
  71. data/lib/solargraph/pin/base_variable.rb +6 -2
  72. data/lib/solargraph/pin/block.rb +11 -6
  73. data/lib/solargraph/pin/closure.rb +17 -2
  74. data/lib/solargraph/pin/common.rb +7 -3
  75. data/lib/solargraph/pin/conversions.rb +33 -3
  76. data/lib/solargraph/pin/documenting.rb +25 -34
  77. data/lib/solargraph/pin/instance_variable.rb +4 -0
  78. data/lib/solargraph/pin/local_variable.rb +13 -1
  79. data/lib/solargraph/pin/method.rb +109 -15
  80. data/lib/solargraph/pin/namespace.rb +16 -10
  81. data/lib/solargraph/pin/parameter.rb +41 -10
  82. data/lib/solargraph/pin/reference/override.rb +2 -2
  83. data/lib/solargraph/pin/reference.rb +8 -0
  84. data/lib/solargraph/pin/search.rb +3 -3
  85. data/lib/solargraph/pin/signature.rb +114 -2
  86. data/lib/solargraph/pin.rb +0 -1
  87. data/lib/solargraph/range.rb +2 -2
  88. data/lib/solargraph/rbs_map/conversions.rb +212 -25
  89. data/lib/solargraph/rbs_map/core_fills.rb +4 -26
  90. data/lib/solargraph/rbs_map/core_map.rb +1 -0
  91. data/lib/solargraph/rbs_map/core_signs.rb +2 -0
  92. data/lib/solargraph/rbs_map/stdlib_map.rb +2 -8
  93. data/lib/solargraph/rbs_map.rb +19 -9
  94. data/lib/solargraph/shell.rb +62 -59
  95. data/lib/solargraph/source/chain/array.rb +4 -1
  96. data/lib/solargraph/source/chain/block_symbol.rb +13 -0
  97. data/lib/solargraph/source/chain/call.rb +95 -26
  98. data/lib/solargraph/source/chain/constant.rb +15 -1
  99. data/lib/solargraph/source/chain/if.rb +23 -0
  100. data/lib/solargraph/source/chain/link.rb +7 -1
  101. data/lib/solargraph/source/chain/or.rb +1 -1
  102. data/lib/solargraph/source/chain/z_super.rb +2 -2
  103. data/lib/solargraph/source/chain.rb +20 -4
  104. data/lib/solargraph/source/change.rb +3 -0
  105. data/lib/solargraph/source/cursor.rb +2 -0
  106. data/lib/solargraph/source/source_chainer.rb +6 -5
  107. data/lib/solargraph/source.rb +15 -16
  108. data/lib/solargraph/source_map/clip.rb +11 -7
  109. data/lib/solargraph/source_map/mapper.rb +10 -0
  110. data/lib/solargraph/source_map.rb +13 -3
  111. data/lib/solargraph/type_checker/checks.rb +10 -2
  112. data/lib/solargraph/type_checker.rb +74 -19
  113. data/lib/solargraph/version.rb +1 -1
  114. data/lib/solargraph/workspace/config.rb +8 -6
  115. data/lib/solargraph/workspace.rb +1 -1
  116. data/lib/solargraph/yard_map/cache.rb +6 -0
  117. data/lib/solargraph/yard_map/helpers.rb +1 -1
  118. data/lib/solargraph/yard_map/mapper/to_method.rb +11 -1
  119. data/lib/solargraph/yard_map/to_method.rb +11 -4
  120. data/lib/solargraph/yard_map.rb +0 -292
  121. data/lib/solargraph/yardoc.rb +52 -0
  122. data/lib/solargraph.rb +4 -1
  123. data/solargraph.gemspec +2 -2
  124. metadata +35 -57
  125. data/lib/solargraph/api_map/bundler_methods.rb +0 -22
  126. data/lib/solargraph/documentor.rb +0 -76
  127. data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +0 -23
  128. data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
  129. data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +0 -18
  130. data/lib/solargraph/parser/legacy/node_processors.rb +0 -55
  131. data/lib/solargraph/parser/legacy.rb +0 -12
  132. data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -151
  133. data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -163
  134. data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -317
  135. data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +0 -85
  136. data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +0 -42
  137. data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +0 -33
  138. data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +0 -23
  139. data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +0 -75
  140. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -68
  141. data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +0 -23
  142. data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +0 -38
  143. data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +0 -39
  144. data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +0 -20
  145. data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +0 -27
  146. data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +0 -39
  147. data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +0 -26
  148. data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +0 -15
  149. data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +0 -51
  150. data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -32
  151. data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
  152. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -279
  153. data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -64
  154. data/lib/solargraph/parser/rubyvm/node_wrapper.rb +0 -47
  155. data/lib/solargraph/parser/rubyvm.rb +0 -40
@@ -27,18 +27,27 @@ module Solargraph
27
27
  end
28
28
  @substring = substring
29
29
  @tag = @name + substring
30
+ # @type [Array<ComplexType>]
30
31
  @key_types = []
32
+ # @type [Array<ComplexType>]
31
33
  @subtypes = []
34
+ # @type [Array<ComplexType>]
32
35
  @all_params = []
33
36
  return unless parameters?
34
- if @substring.start_with?('<(') && @substring.end_with?(')>')
35
- subs = ComplexType.parse(substring[2..-3], partial: true)
36
- else
37
- subs = ComplexType.parse(substring[1..-2], partial: true)
38
- end
37
+ # @todo we should be able to probe the type of 'subs' without
38
+ # hoisting the definition outside of the if statement
39
+ subs = if @substring.start_with?('<(') && @substring.end_with?(')>')
40
+ ComplexType.parse(substring[2..-3], partial: true)
41
+ else
42
+ ComplexType.parse(substring[1..-2], partial: true)
43
+ end
39
44
  if hash_parameters?
40
45
  raise ComplexTypeError, "Bad hash type" unless !subs.is_a?(ComplexType) and subs.length == 2 and !subs[0].is_a?(UniqueType) and !subs[1].is_a?(UniqueType)
46
+ # @todo should be able to resolve map; both types have it
47
+ # with same return type
48
+ # @sg-ignore
41
49
  @key_types.concat subs[0].map { |u| ComplexType.new([u]) }
50
+ # @sg-ignore
42
51
  @subtypes.concat subs[1].map { |u| ComplexType.new([u]) }
43
52
  else
44
53
  @subtypes.concat subs
@@ -51,80 +60,161 @@ module Solargraph
51
60
  tag
52
61
  end
53
62
 
63
+ # @return [Array<UniqueType>]
54
64
  def items
55
65
  [self]
56
66
  end
57
67
 
68
+ # @return [String]
69
+ def rbs_name
70
+ if name == 'undefined'
71
+ 'untyped'
72
+ else
73
+ rooted_name
74
+ end
75
+ end
76
+
77
+ # @return [String]
58
78
  def to_rbs
59
- "#{namespace}#{parameters? ? "[#{subtypes.map { |s| s.to_rbs }.join(', ')}]" : ''}"
79
+ if ['Tuple', 'Array'].include?(name) && fixed_parameters?
80
+ # tuples don't have a name; they're just [foo, bar, baz].
81
+ if substring == '()'
82
+ # but there are no zero element tuples, so we go with an array
83
+ 'Array[]'
84
+ else
85
+ # already generated surrounded by []
86
+ parameters_as_rbs
87
+ end
88
+ else
89
+ "#{rbs_name}#{parameters_as_rbs}"
90
+ end
91
+ end
92
+
93
+ # @return [String]
94
+ def parameters_as_rbs
95
+ parameters? ? "[#{all_params.map { |s| s.to_rbs }.join(', ')}]" : ''
60
96
  end
61
97
 
62
98
  def generic?
63
99
  name == GENERIC_TAG_NAME || all_params.any?(&:generic?)
64
100
  end
65
101
 
66
- # @param definitions [Pin::Namespace]
67
- # @param context_type [ComplexType]
68
- # @return [UniqueType]
69
- def resolve_generics definitions, context_type
70
- new_name = if name == GENERIC_TAG_NAME
71
- idx = definitions.generics.index(subtypes.first&.name)
72
- return ComplexType::UNDEFINED if idx.nil?
73
- param_type = context_type.all_params[idx]
74
- return ComplexType::UNDEFINED unless param_type
75
- param_type.to_s
76
- else
77
- name
78
- end
79
- new_key_types = if name != GENERIC_TAG_NAME
80
- @key_types.map { |t| t.resolve_generics(definitions, context_type) }.select(&:defined?)
81
- else
82
- []
83
- end
84
- new_subtypes = if name != GENERIC_TAG_NAME
85
- @subtypes.map { |t| t.resolve_generics(definitions, context_type) }.select(&:defined?)
86
- else
87
- []
88
- end
89
- if name != GENERIC_TAG_NAME && !(new_key_types.empty? && new_subtypes.empty?)
90
- if hash_parameters?
91
- UniqueType.new(new_name, "{#{new_key_types.join(', ')} => #{new_subtypes.join(', ')}}")
92
- elsif parameters?
93
- if @substring.start_with?'<('
94
- UniqueType.new(new_name, "<(#{new_subtypes.join(', ')})>")
95
- else
96
- UniqueType.new(new_name, "<#{new_subtypes.join(', ')}>")
102
+
103
+ # @param generics_to_resolve [Enumerable<String>]
104
+ # @param context_type [UniqueType, nil]
105
+ # @param resolved_generic_values [Hash{String => ComplexType}] Added to as types are encountered or resolved
106
+ # @return [UniqueType, ComplexType]
107
+ def resolve_generics_from_context generics_to_resolve, context_type, resolved_generic_values: {}
108
+ transform(name) do |t|
109
+ next t unless t.name == ComplexType::GENERIC_TAG_NAME
110
+
111
+ new_binding = false
112
+
113
+ type_param = t.subtypes.first&.name
114
+ next t unless generics_to_resolve.include? type_param
115
+ unless context_type.nil? || !resolved_generic_values[type_param].nil?
116
+ new_binding = true
117
+ resolved_generic_values[type_param] = context_type
118
+ end
119
+ if new_binding
120
+ resolved_generic_values.transform_values! do |complex_type|
121
+ complex_type.resolve_generics_from_context(generics_to_resolve, nil, resolved_generic_values: resolved_generic_values)
97
122
  end
123
+ end
124
+ resolved_generic_values[type_param] || t
125
+ end
126
+ end
127
+
128
+ # Probe the concrete type for each of the generic type
129
+ # parameters used in this type, and return a new type if
130
+ # possible.
131
+ #
132
+ # @param definitions [Pin::Namespace, Pin::Method] The module/class/method which uses generic types
133
+ # @param context_type [ComplexType] The receiver type
134
+ # @return [UniqueType, ComplexType]
135
+ def resolve_generics definitions, context_type
136
+ return self if definitions.nil? || definitions.generics.empty?
137
+
138
+ transform(name) do |t|
139
+ if t.name == GENERIC_TAG_NAME
140
+ idx = definitions.generics.index(t.subtypes.first&.name)
141
+ next t if idx.nil?
142
+ context_type.all_params[idx] || ComplexType::UNDEFINED
98
143
  else
99
- UniqueType.new(new_name)
144
+ t
100
145
  end
101
- else
102
- UniqueType.new(new_name)
103
146
  end
147
+ end
104
148
 
105
- # idx = definitions.parameters.index(subtypes.first.name)
106
- # STDERR.puts "Index: #{idx}"
107
- # return ComplexType::UNDEFINED if idx.nil?
108
- # param_type = context.return_type.all_params[idx]
109
- # return ComplexType::UNDEFINED unless param_type
110
- # ComplexType.try_parse(param_type.to_s)
149
+ # @yieldparam t [self]
150
+ # @yieldreturn [self]
151
+ # @return [Array<self>]
152
+ def map &block
153
+ [block.yield(self)]
111
154
  end
112
155
 
113
- def self_to dst
114
- return self unless selfy?
115
- new_name = (@name == 'self' ? dst : @name)
116
- new_key_types = @key_types.map { |t| t.self_to dst }
117
- new_subtypes = @subtypes.map { |t| t.self_to dst }
118
- if hash_parameters?
156
+ # @return [Array<UniqueType>]
157
+ def to_a
158
+ [self]
159
+ end
160
+
161
+ # @param new_name [String, nil]
162
+ # @param new_key_types [Array<UniqueType>, nil]
163
+ # @param new_subtypes [Array<UniqueType>, nil]
164
+ # @return [self]
165
+ def recreate(new_name: nil, new_key_types: nil, new_subtypes: nil)
166
+ new_name ||= name
167
+ new_key_types ||= @key_types
168
+ new_subtypes ||= @subtypes
169
+ if new_key_types.none?(&:defined?) && new_subtypes.none?(&:defined?)
170
+ # if all subtypes are undefined, erase down to the non-parametric type
171
+ UniqueType.new(new_name)
172
+ elsif new_key_types.empty? && new_subtypes.empty?
173
+ UniqueType.new(new_name)
174
+ elsif hash_parameters?
119
175
  UniqueType.new(new_name, "{#{new_key_types.join(', ')} => #{new_subtypes.join(', ')}}")
120
- elsif parameters?
121
- if @substring.start_with?'<('
122
- UniqueType.new(new_name, "<(#{new_subtypes.join(', ')})>")
123
- else
124
- UniqueType.new(new_name, "<#{new_subtypes.join(', ')}>")
125
- end
176
+ elsif @substring.start_with?('<(')
177
+ # @todo This clause is probably wrong, and if so, fixing it
178
+ # will be some level of breaking change. Probably best
179
+ # handled before real tuple support is rolled out and
180
+ # folks start relying on it more.
181
+ #
182
+ # (String) is a one element tuple in https://yardoc.org/types
183
+ # <String> is an array of zero or more Strings in https://yardoc.org/types
184
+ # Array<(String)> could be an Array of one-element tuples or a
185
+ # one element tuple. https://yardoc.org/types treats it
186
+ # as the former.
187
+ # Array<(String), Integer> is not ambiguous if we accept
188
+ # (String) as a tuple type, but not currently understood
189
+ # by Solargraph.
190
+ UniqueType.new(new_name, "<(#{new_subtypes.join(', ')})>")
191
+ elsif fixed_parameters?
192
+ UniqueType.new(new_name, "(#{new_subtypes.join(', ')})")
126
193
  else
127
- UniqueType.new(new_name)
194
+ UniqueType.new(new_name, "<#{new_subtypes.join(', ')}>")
195
+ end
196
+ end
197
+
198
+ # Apply the given transformation to each subtype and then finally to this type
199
+ #
200
+ # @param new_name [String, nil]
201
+ # @yieldparam t [UniqueType]
202
+ # @yieldreturn [self]
203
+ # @return [self]
204
+ def transform(new_name = nil, &transform_type)
205
+ new_key_types = @key_types.flat_map { |ct| ct.map { |ut| ut.transform(&transform_type) } }.compact
206
+ new_subtypes = @subtypes.flat_map { |ct| ct.map { |ut| ut.transform(&transform_type) } }.compact
207
+ new_type = recreate(new_name: new_name || rooted_name, new_key_types: new_key_types, new_subtypes: new_subtypes)
208
+ yield new_type
209
+ end
210
+
211
+ # Transform references to the 'self' type to the specified concrete namespace
212
+ # @param dst [String]
213
+ # @return [UniqueType]
214
+ def self_to dst
215
+ transform do |t|
216
+ next t if t.name != 'self'
217
+ t.recreate(new_name: dst, new_key_types: [], new_subtypes: [])
128
218
  end
129
219
  end
130
220
 
@@ -13,6 +13,8 @@ module Solargraph
13
13
 
14
14
  # @param types [Array<[UniqueType, ComplexType]>]
15
15
  def initialize types = [UniqueType::UNDEFINED]
16
+ # @todo @items here should not need an annotation
17
+ # @type [Array<UniqueType>]
16
18
  @items = types.flat_map(&:items).uniq(&:to_s)
17
19
  end
18
20
 
@@ -28,28 +30,44 @@ module Solargraph
28
30
  ComplexType.new(types).reduce_object
29
31
  end
30
32
 
33
+ # @param generics_to_resolve [Enumerable<String>]]
34
+ # @param context_type [UniqueType, nil]
35
+ # @param resolved_generic_values [Hash{String => ComplexType}] Added to as types are encountered or resolved
36
+ # @return [self]
37
+ def resolve_generics_from_context generics_to_resolve, context_type, resolved_generic_values: {}
38
+ return self unless generic?
39
+
40
+ ComplexType.new(@items.map { |i| i.resolve_generics_from_context(generics_to_resolve, context_type, resolved_generic_values: resolved_generic_values) })
41
+ end
42
+
43
+ # @return [UniqueType]
31
44
  def first
32
45
  @items.first
33
46
  end
34
47
 
48
+ # @return [String]
35
49
  def to_rbs
36
- ((@items.length > 1 ? '(' : '') + @items.map do |item|
37
- "#{item.namespace}#{item.parameters? ? "[#{item.subtypes.map { |s| s.to_rbs }.join(', ')}]" : ''}"
38
- end.join(' | ') + (@items.length > 1 ? ')' : '')).gsub(/undefined/, 'untyped')
50
+ ((@items.length > 1 ? '(' : '') +
51
+ @items.map(&:to_rbs).join(' | ') +
52
+ (@items.length > 1 ? ')' : ''))
39
53
  end
40
54
 
55
+ # @yieldparam [UniqueType]
56
+ # @return [Array]
41
57
  def map &block
42
58
  @items.map &block
43
59
  end
44
60
 
45
61
  # @yieldparam [UniqueType]
46
- # @return [Enumerator<UniqueType>]
62
+ # @return [Enumerable<UniqueType>]
47
63
  def each &block
48
64
  @items.each &block
49
65
  end
50
66
 
51
67
  # @yieldparam [UniqueType]
52
- # @return [Enumerator<UniqueType>]
68
+ # @return [void]
69
+ # @overload each_unique_type()
70
+ # @return [Enumerator<UniqueType>]
53
71
  def each_unique_type &block
54
72
  return enum_for(__method__) unless block_given?
55
73
 
@@ -58,14 +76,23 @@ module Solargraph
58
76
  end
59
77
  end
60
78
 
79
+ # @return [Integer]
61
80
  def length
62
81
  @items.length
63
82
  end
64
83
 
84
+ # @return [Array<UniqueType>]
85
+ def to_a
86
+ @items
87
+ end
88
+
89
+ # @param index [Integer]
90
+ # @return [UniqueType]
65
91
  def [](index)
66
92
  @items[index]
67
93
  end
68
94
 
95
+ # @return [Array<UniqueType>]
69
96
  def select &block
70
97
  @items.select &block
71
98
  end
@@ -81,12 +108,16 @@ module Solargraph
81
108
  @items.map(&:namespace)
82
109
  end
83
110
 
111
+ # @param name [Symbol]
112
+ # @return [Object, nil]
84
113
  def method_missing name, *args, &block
85
114
  return if @items.first.nil?
86
115
  return @items.first.send(name, *args, &block) if respond_to_missing?(name)
87
116
  super
88
117
  end
89
118
 
119
+ # @param name [Symbol]
120
+ # @param include_private [Boolean]
90
121
  def respond_to_missing?(name, include_private = false)
91
122
  TypeMethods.public_instance_methods.include?(name) || super
92
123
  end
@@ -111,7 +142,15 @@ module Solargraph
111
142
  any?(&:generic?)
112
143
  end
113
144
 
114
- # @param definitions [Pin::Namespace]
145
+ # @param new_name [String, nil]
146
+ # @yieldparam t [UniqueType]
147
+ # @yieldreturn [UniqueType]
148
+ # @return [ComplexType]
149
+ def transform(new_name = nil, &transform_type)
150
+ ComplexType.new(map { |ut| ut.transform(new_name, &transform_type) })
151
+ end
152
+
153
+ # @param definitions [Pin::Namespace, Pin::Method]
115
154
  # @param context_type [ComplexType]
116
155
  # @return [ComplexType]
117
156
  def resolve_generics definitions, context_type
@@ -132,6 +171,7 @@ module Solargraph
132
171
  @items.any?(&:nil_type?)
133
172
  end
134
173
 
174
+ # @return [Array<ComplexType>]
135
175
  def all_params
136
176
  @items.first.all_params || []
137
177
  end
@@ -140,11 +180,16 @@ module Solargraph
140
180
 
141
181
  protected
142
182
 
183
+ # @return [ComplexType]
143
184
  def reduce_object
144
185
  return self if name != 'Object' || subtypes.empty?
145
186
  ComplexType.try_parse(reduce_class(subtypes.join(', ')))
146
187
  end
147
188
 
189
+ def bottom?
190
+ @items.all?(&:bot?)
191
+ end
192
+
148
193
  private
149
194
 
150
195
  # @todo This is a quick and dirty hack that forces `self` keywords
@@ -174,9 +219,13 @@ module Solargraph
174
219
  # used internally.
175
220
  #
176
221
  # @param *strings [Array<String>] The type definitions to parse
177
- # @param partial [Boolean] True if the string is part of a another type
178
- # @return [ComplexType, Array, nil]
222
+ # @return [ComplexType]
223
+ # @overload parse(*strings, partial: false)
224
+ # @todo Need ability to use a literal true as a type below
225
+ # @param partial [Boolean] True if the string is part of a another type
226
+ # @return [Array<UniqueType>]
179
227
  def parse *strings, partial: false
228
+ # @type [Hash{Array<String> => ComplexType}]
180
229
  @cache ||= {}
181
230
  unless partial
182
231
  cached = @cache[strings]
@@ -202,6 +251,9 @@ module Solargraph
202
251
  raise ComplexTypeError, "Invalid hash thing" unless key_types.nil?
203
252
  # types.push ComplexType.new([UniqueType.new(base[0..-2].strip)])
204
253
  types.push UniqueType.new(base[0..-2].strip)
254
+ # @todo this should either expand key_type's type
255
+ # automatically or complain about not being
256
+ # compatible with key_type's type in type checking
205
257
  key_types = types
206
258
  types = []
207
259
  base.clear
@@ -224,7 +276,7 @@ module Solargraph
224
276
  paren_stack += 1
225
277
  elsif char == ')'
226
278
  paren_stack -= 1
227
- subtype_string += char if paren_stack == 0
279
+ subtype_string += char
228
280
  raise ComplexTypeError, "Invalid close in type #{type_string}" if paren_stack < 0
229
281
  next
230
282
  elsif char == ',' && point_stack == 0 && curly_stack == 0 && paren_stack == 0
@@ -271,5 +323,6 @@ module Solargraph
271
323
  NIL = ComplexType.parse('nil')
272
324
  SELF = ComplexType.parse('self')
273
325
  BOOLEAN = ComplexType.parse('Boolean')
326
+ BOT = ComplexType.parse('bot')
274
327
  end
275
328
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
3
 
5
4
  module Solargraph
6
5
  # Conventions provide a way to modify an ApiMap based on expectations about
@@ -1,6 +1,11 @@
1
+ require 'nokogiri'
2
+
1
3
  module ReverseMarkdown
2
4
  module Converters
3
5
  class Dd < Base
6
+ # @return [String]
7
+ # @param node [Nokogiri::XML::Element]
8
+ # @param state [Hash]
4
9
  def convert node, state = {}
5
10
  content = treat_children(node, state)
6
11
  ": #{content.strip}\n"
@@ -1,6 +1,9 @@
1
1
  module ReverseMarkdown
2
2
  module Converters
3
3
  class Dl < Base
4
+ # @return [String]
5
+ # @param node [Nokogiri::XML::Element]
6
+ # @param state [Hash]
4
7
  def convert node, state = {}
5
8
  content = treat_children(node, state).strip
6
9
  "\n\n#{content}\n"
@@ -1,6 +1,9 @@
1
1
  module ReverseMarkdown
2
2
  module Converters
3
3
  class Dt < Base
4
+ # @return [String]
5
+ # @param node [Nokogiri::XML::Element]
6
+ # @param state [Hash]
4
7
  def convert node, state = {}
5
8
  content = treat_children(node, state)
6
9
  "\n#{content.strip}\n"
@@ -29,9 +29,9 @@ module Solargraph
29
29
  store = RuboCop::ConfigStore.new
30
30
  runner = RuboCop::Runner.new(options, store)
31
31
  result = redirect_stdout{ runner.run(paths) }
32
-
32
+
33
33
  return [] if result.empty?
34
-
34
+
35
35
  make_array JSON.parse(result)
36
36
  rescue RuboCop::ValidationError, RuboCop::ConfigNotFoundError => e
37
37
  raise DiagnosticsError, "Error in RuboCop configuration: #{e.message}"
@@ -48,7 +48,7 @@ module Solargraph
48
48
  args.find { |a| a =~ /version=/ }.to_s.split('=').last
49
49
  end
50
50
 
51
- # @param resp [Hash]
51
+ # @param resp [Hash{String => Array<Hash{String => Array<Hash{String => undefined}>}>}]
52
52
  # @return [Array<Hash>]
53
53
  def make_array resp
54
54
  diagnostics = []
@@ -62,8 +62,8 @@ module Solargraph
62
62
 
63
63
  # Convert a RuboCop offense to an LSP diagnostic
64
64
  #
65
- # @param off [Hash] Offense received from Rubocop
66
- # @return [Hash] LSP diagnostic
65
+ # @param off [Hash{String => unknown}] Offense received from Rubocop
66
+ # @return [Hash{Symbol => Hash, String, Integer}] LSP diagnostic
67
67
  def offense_to_diagnostic off
68
68
  {
69
69
  range: offense_range(off).to_hash,
@@ -81,19 +81,20 @@ module Solargraph
81
81
  Range.new(offense_start_position(off), offense_ending_position(off))
82
82
  end
83
83
 
84
- # @param off [Hash]
84
+ # @param off [Hash{String => Hash{String => Integer}}]
85
85
  # @return [Position]
86
86
  def offense_start_position off
87
87
  Position.new(off['location']['start_line'] - 1, off['location']['start_column'] - 1)
88
88
  end
89
89
 
90
- # @param off [Hash]
90
+ # @param off [Hash{String => Hash{String => Integer}}]
91
91
  # @return [Position]
92
92
  def offense_ending_position off
93
93
  if off['location']['start_line'] != off['location']['last_line']
94
94
  Position.new(off['location']['start_line'], 0)
95
95
  else
96
96
  start_line = off['location']['start_line'] - 1
97
+ # @type [Integer]
97
98
  last_column = off['location']['last_column']
98
99
  line = @source.code.lines[start_line]
99
100
  col_off = if line.nil? || line.empty?
@@ -12,6 +12,7 @@ module Solargraph
12
12
  #
13
13
  # @param version [String, nil]
14
14
  # @raise [InvalidRubocopVersionError] if _version_ is not installed
15
+ # @return [void]
15
16
  def require_rubocop(version = nil)
16
17
  begin
17
18
  gem_path = Gem::Specification.find_by_name('rubocop', version).full_gem_path
@@ -6,6 +6,7 @@ module Solargraph
6
6
  # parameters, and invalid param tags.
7
7
  #
8
8
  class TypeCheck < Base
9
+ # @return [Array<Hash>]
9
10
  def diagnose source, api_map
10
11
  # return [] unless args.include?('always') || api_map.workspaced?(source.filename)
11
12
  severity = Diagnostics::Severities::ERROR
@@ -33,14 +33,14 @@ module Solargraph
33
33
  # Find a reporter by name.
34
34
  #
35
35
  # @param name [String] The name with which the reporter was registered
36
- # @return [Class<Solargraph::Diagnostics::Base>]
36
+ # @return [Class<Solargraph::Diagnostics::Base>, nil]
37
37
  def reporter name
38
38
  reporter_hash[name]
39
39
  end
40
40
 
41
41
  private
42
42
 
43
- # @return [Hash]
43
+ # @return [Hash{String => Class<Solargraph::Diagnostics::Base>}]
44
44
  def reporter_hash
45
45
  @reporter_hash ||= {}
46
46
  end