solargraph 0.58.2 → 0.59.0.dev.2

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 (203) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +3 -0
  3. data/.github/workflows/linting.yml +4 -5
  4. data/.github/workflows/plugins.yml +41 -34
  5. data/.github/workflows/rspec.yml +44 -23
  6. data/.github/workflows/typecheck.yml +2 -2
  7. data/.rubocop.yml +32 -5
  8. data/.rubocop_todo.yml +50 -966
  9. data/Gemfile +3 -1
  10. data/README.md +3 -3
  11. data/Rakefile +26 -23
  12. data/bin/solargraph +2 -1
  13. data/lib/solargraph/api_map/cache.rb +3 -3
  14. data/lib/solargraph/api_map/constants.rb +13 -3
  15. data/lib/solargraph/api_map/index.rb +23 -18
  16. data/lib/solargraph/api_map/source_to_yard.rb +22 -9
  17. data/lib/solargraph/api_map/store.rb +33 -28
  18. data/lib/solargraph/api_map.rb +150 -82
  19. data/lib/solargraph/bench.rb +44 -45
  20. data/lib/solargraph/complex_type/conformance.rb +176 -0
  21. data/lib/solargraph/complex_type/type_methods.rb +28 -17
  22. data/lib/solargraph/complex_type/unique_type.rb +218 -57
  23. data/lib/solargraph/complex_type.rb +170 -57
  24. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -61
  25. data/lib/solargraph/convention/data_definition/data_definition_node.rb +7 -5
  26. data/lib/solargraph/convention/data_definition.rb +5 -2
  27. data/lib/solargraph/convention/gemfile.rb +15 -15
  28. data/lib/solargraph/convention/gemspec.rb +23 -23
  29. data/lib/solargraph/convention/rakefile.rb +17 -17
  30. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +2 -1
  31. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +4 -3
  32. data/lib/solargraph/convention/struct_definition.rb +8 -4
  33. data/lib/solargraph/convention.rb +78 -78
  34. data/lib/solargraph/converters/dd.rb +19 -17
  35. data/lib/solargraph/converters/dl.rb +17 -15
  36. data/lib/solargraph/converters/dt.rb +17 -15
  37. data/lib/solargraph/converters/misc.rb +3 -1
  38. data/lib/solargraph/diagnostics/require_not_found.rb +1 -0
  39. data/lib/solargraph/diagnostics/rubocop.rb +11 -10
  40. data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
  41. data/lib/solargraph/diagnostics/type_check.rb +11 -10
  42. data/lib/solargraph/diagnostics/update_errors.rb +37 -41
  43. data/lib/solargraph/doc_map.rb +133 -373
  44. data/lib/solargraph/equality.rb +4 -4
  45. data/lib/solargraph/gem_pins.rb +21 -20
  46. data/lib/solargraph/language_server/error_codes.rb +20 -20
  47. data/lib/solargraph/language_server/host/diagnoser.rb +1 -1
  48. data/lib/solargraph/language_server/host/dispatch.rb +3 -3
  49. data/lib/solargraph/language_server/host/message_worker.rb +4 -3
  50. data/lib/solargraph/language_server/host/sources.rb +2 -1
  51. data/lib/solargraph/language_server/host.rb +30 -22
  52. data/lib/solargraph/language_server/message/base.rb +97 -97
  53. data/lib/solargraph/language_server/message/client/register_capability.rb +13 -15
  54. data/lib/solargraph/language_server/message/completion_item/resolve.rb +58 -60
  55. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +12 -18
  56. data/lib/solargraph/language_server/message/extended/document.rb +1 -0
  57. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
  58. data/lib/solargraph/language_server/message/extended/download_core.rb +20 -19
  59. data/lib/solargraph/language_server/message/extended/search.rb +20 -20
  60. data/lib/solargraph/language_server/message/initialize.rb +197 -191
  61. data/lib/solargraph/language_server/message/text_document/completion.rb +10 -8
  62. data/lib/solargraph/language_server/message/text_document/definition.rb +41 -32
  63. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +23 -16
  64. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +29 -19
  65. data/lib/solargraph/language_server/message/text_document/formatting.rb +8 -6
  66. data/lib/solargraph/language_server/message/text_document/hover.rb +5 -5
  67. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +18 -11
  68. data/lib/solargraph/language_server/message/text_document/references.rb +23 -16
  69. data/lib/solargraph/language_server/message/text_document/rename.rb +26 -19
  70. data/lib/solargraph/language_server/message/text_document/signature_help.rb +3 -2
  71. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -17
  72. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +41 -35
  73. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +48 -40
  74. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +32 -26
  75. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +27 -17
  76. data/lib/solargraph/language_server/message.rb +94 -94
  77. data/lib/solargraph/language_server/request.rb +29 -27
  78. data/lib/solargraph/language_server/transport/data_reader.rb +72 -74
  79. data/lib/solargraph/language_server/uri_helpers.rb +49 -49
  80. data/lib/solargraph/library.rb +85 -44
  81. data/lib/solargraph/location.rb +17 -14
  82. data/lib/solargraph/logging.rb +24 -4
  83. data/lib/solargraph/page.rb +92 -92
  84. data/lib/solargraph/parser/comment_ripper.rb +19 -4
  85. data/lib/solargraph/parser/flow_sensitive_typing.rb +326 -108
  86. data/lib/solargraph/parser/node_processor/base.rb +34 -4
  87. data/lib/solargraph/parser/node_processor.rb +8 -7
  88. data/lib/solargraph/parser/parser_gem/class_methods.rb +32 -14
  89. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +19 -19
  90. data/lib/solargraph/parser/parser_gem/node_chainer.rb +50 -25
  91. data/lib/solargraph/parser/parser_gem/node_methods.rb +91 -70
  92. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +4 -4
  93. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +13 -11
  94. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +9 -0
  95. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +12 -12
  96. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +10 -3
  97. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +38 -37
  98. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +36 -6
  99. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +5 -3
  100. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +1 -0
  101. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +3 -1
  102. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +3 -3
  103. data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
  104. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -1
  105. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
  106. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -5
  107. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +124 -113
  108. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -29
  109. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
  110. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +6 -2
  111. data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
  112. data/lib/solargraph/parser/parser_gem.rb +14 -12
  113. data/lib/solargraph/parser/region.rb +9 -3
  114. data/lib/solargraph/parser/snippet.rb +3 -1
  115. data/lib/solargraph/parser.rb +25 -23
  116. data/lib/solargraph/pin/base.rb +126 -80
  117. data/lib/solargraph/pin/base_variable.rb +273 -24
  118. data/lib/solargraph/pin/block.rb +29 -6
  119. data/lib/solargraph/pin/breakable.rb +7 -1
  120. data/lib/solargraph/pin/callable.rb +65 -21
  121. data/lib/solargraph/pin/closure.rb +7 -10
  122. data/lib/solargraph/pin/common.rb +24 -6
  123. data/lib/solargraph/pin/compound_statement.rb +55 -0
  124. data/lib/solargraph/pin/constant.rb +43 -45
  125. data/lib/solargraph/pin/conversions.rb +10 -4
  126. data/lib/solargraph/pin/delegated_method.rb +19 -8
  127. data/lib/solargraph/pin/documenting.rb +4 -2
  128. data/lib/solargraph/pin/instance_variable.rb +5 -1
  129. data/lib/solargraph/pin/keyword.rb +0 -4
  130. data/lib/solargraph/pin/local_variable.rb +15 -59
  131. data/lib/solargraph/pin/method.rb +153 -104
  132. data/lib/solargraph/pin/method_alias.rb +8 -0
  133. data/lib/solargraph/pin/namespace.rb +19 -12
  134. data/lib/solargraph/pin/parameter.rb +100 -36
  135. data/lib/solargraph/pin/proxy_type.rb +4 -1
  136. data/lib/solargraph/pin/reference/override.rb +1 -1
  137. data/lib/solargraph/pin/reference/superclass.rb +2 -0
  138. data/lib/solargraph/pin/reference.rb +19 -0
  139. data/lib/solargraph/pin/search.rb +3 -2
  140. data/lib/solargraph/pin/signature.rb +15 -12
  141. data/lib/solargraph/pin/symbol.rb +2 -1
  142. data/lib/solargraph/pin/until.rb +2 -4
  143. data/lib/solargraph/pin/while.rb +2 -4
  144. data/lib/solargraph/pin.rb +2 -0
  145. data/lib/solargraph/pin_cache.rb +490 -73
  146. data/lib/solargraph/position.rb +14 -10
  147. data/lib/solargraph/range.rb +16 -15
  148. data/lib/solargraph/rbs_map/conversions.rb +343 -214
  149. data/lib/solargraph/rbs_map/core_fills.rb +91 -84
  150. data/lib/solargraph/rbs_map/core_map.rb +24 -17
  151. data/lib/solargraph/rbs_map/stdlib_map.rb +33 -5
  152. data/lib/solargraph/rbs_map.rb +77 -32
  153. data/lib/solargraph/server_methods.rb +16 -16
  154. data/lib/solargraph/shell.rb +128 -73
  155. data/lib/solargraph/source/chain/array.rb +39 -37
  156. data/lib/solargraph/source/chain/call.rb +96 -56
  157. data/lib/solargraph/source/chain/class_variable.rb +13 -13
  158. data/lib/solargraph/source/chain/constant.rb +5 -1
  159. data/lib/solargraph/source/chain/global_variable.rb +13 -13
  160. data/lib/solargraph/source/chain/hash.rb +8 -5
  161. data/lib/solargraph/source/chain/if.rb +12 -10
  162. data/lib/solargraph/source/chain/instance_variable.rb +24 -1
  163. data/lib/solargraph/source/chain/link.rb +99 -109
  164. data/lib/solargraph/source/chain/literal.rb +9 -6
  165. data/lib/solargraph/source/chain/or.rb +10 -4
  166. data/lib/solargraph/source/chain/q_call.rb +13 -11
  167. data/lib/solargraph/source/chain/variable.rb +15 -13
  168. data/lib/solargraph/source/chain/z_super.rb +28 -30
  169. data/lib/solargraph/source/chain.rb +49 -38
  170. data/lib/solargraph/source/change.rb +12 -5
  171. data/lib/solargraph/source/cursor.rb +23 -17
  172. data/lib/solargraph/source/encoding_fixes.rb +6 -7
  173. data/lib/solargraph/source/source_chainer.rb +56 -32
  174. data/lib/solargraph/source/updater.rb +5 -1
  175. data/lib/solargraph/source.rb +59 -35
  176. data/lib/solargraph/source_map/clip.rb +48 -29
  177. data/lib/solargraph/source_map/data.rb +4 -1
  178. data/lib/solargraph/source_map/mapper.rb +71 -42
  179. data/lib/solargraph/source_map.rb +21 -9
  180. data/lib/solargraph/type_checker/problem.rb +3 -1
  181. data/lib/solargraph/type_checker/rules.rb +81 -8
  182. data/lib/solargraph/type_checker.rb +195 -120
  183. data/lib/solargraph/version.rb +1 -1
  184. data/lib/solargraph/workspace/config.rb +13 -10
  185. data/lib/solargraph/workspace/gemspecs.rb +367 -0
  186. data/lib/solargraph/workspace/require_paths.rb +1 -0
  187. data/lib/solargraph/workspace.rb +149 -30
  188. data/lib/solargraph/yard_map/helpers.rb +8 -3
  189. data/lib/solargraph/yard_map/mapper/to_method.rb +13 -7
  190. data/lib/solargraph/yard_map/mapper/to_namespace.rb +2 -1
  191. data/lib/solargraph/yard_map/mapper.rb +13 -8
  192. data/lib/solargraph/yard_tags.rb +20 -20
  193. data/lib/solargraph/yardoc.rb +33 -23
  194. data/lib/solargraph.rb +29 -8
  195. data/rbs/fills/rubygems/0/dependency.rbs +193 -0
  196. data/rbs/fills/tuple/tuple.rbs +28 -0
  197. data/rbs/shims/ast/0/node.rbs +1 -1
  198. data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
  199. data/solargraph.gemspec +36 -34
  200. metadata +38 -33
  201. data/lib/solargraph/type_checker/checks.rb +0 -124
  202. data/lib/solargraph/type_checker/param_def.rb +0 -37
  203. data/lib/solargraph/yard_map/to_method.rb +0 -89
@@ -4,11 +4,12 @@ module Solargraph
4
4
  # A container for type data based on YARD type tags.
5
5
  #
6
6
  class ComplexType
7
- GENERIC_TAG_NAME = 'generic'.freeze
7
+ GENERIC_TAG_NAME = 'generic'
8
8
  # @!parse
9
9
  # include TypeMethods
10
10
  include Equality
11
11
 
12
+ autoload :Conformance, 'solargraph/complex_type/conformance'
12
13
  autoload :TypeMethods, 'solargraph/complex_type/type_methods'
13
14
  autoload :UniqueType, 'solargraph/complex_type/unique_type'
14
15
 
@@ -18,25 +19,24 @@ module Solargraph
18
19
  # @type [Array<UniqueType>]
19
20
  items = types.flat_map(&:items).uniq(&:to_s)
20
21
  if items.any? { |i| i.name == 'false' } && items.any? { |i| i.name == 'true' }
21
- items.delete_if { |i| i.name == 'false' || i.name == 'true' }
22
- items.unshift(ComplexType::BOOLEAN)
22
+ items.delete_if { |i| %w[false true].include?(i.name) }
23
+ items.unshift(UniqueType::BOOLEAN)
23
24
  end
25
+ # @type [Array<UniqueType>]
24
26
  items = [UniqueType::UNDEFINED] if items.any?(&:undefined?)
27
+ # @todo shouldn't need this cast - if statement above adds an 'Array' type
28
+ # @type [Array<UniqueType>]
25
29
  @items = items
26
30
  end
27
31
 
28
- # @sg-ignore Fix "Not enough arguments to Module#protected"
29
- protected def equality_fields
30
- [self.class, items]
31
- end
32
-
33
32
  # @param api_map [ApiMap]
34
- # @param context [String]
33
+ # @param gates [Array<String>]
34
+ #
35
35
  # @return [ComplexType]
36
36
  def qualify api_map, *gates
37
37
  red = reduce_object
38
38
  types = red.items.map do |t|
39
- next t if ['nil', 'void', 'undefined'].include?(t.name)
39
+ next t if %w[nil void undefined].include?(t.name)
40
40
  next t if ['::Boolean'].include?(t.rooted_name)
41
41
  t.qualify api_map, *gates
42
42
  end
@@ -44,13 +44,16 @@ module Solargraph
44
44
  end
45
45
 
46
46
  # @param generics_to_resolve [Enumerable<String>]]
47
- # @param context_type [UniqueType, nil]
47
+ # @param context_type [ComplexType, ComplexType::UniqueType, nil]
48
48
  # @param resolved_generic_values [Hash{String => ComplexType}] Added to as types are encountered or resolved
49
49
  # @return [self]
50
50
  def resolve_generics_from_context generics_to_resolve, context_type, resolved_generic_values: {}
51
51
  return self unless generic?
52
52
 
53
- ComplexType.new(@items.map { |i| i.resolve_generics_from_context(generics_to_resolve, context_type, resolved_generic_values: resolved_generic_values) })
53
+ ComplexType.new(@items.map do |i|
54
+ i.resolve_generics_from_context(generics_to_resolve, context_type,
55
+ resolved_generic_values: resolved_generic_values)
56
+ end)
54
57
  end
55
58
 
56
59
  # @return [UniqueType]
@@ -65,7 +68,7 @@ module Solargraph
65
68
  (@items.length > 1 ? ')' : ''))
66
69
  end
67
70
 
68
- # @param dst [ComplexType]
71
+ # @param dst [ComplexType, ComplexType::UniqueType]
69
72
  # @return [ComplexType]
70
73
  def self_to_type dst
71
74
  object_type_dst = dst.reduce_class_type
@@ -76,15 +79,19 @@ module Solargraph
76
79
  end
77
80
 
78
81
  # @yieldparam [UniqueType]
82
+ # @yieldreturn [UniqueType]
79
83
  # @return [Array<UniqueType>]
84
+ # @sg-ignore Declared return type
85
+ # ::Array<::Solargraph::ComplexType::UniqueType> does not match
86
+ # inferred type ::Array<::Proc> for Solargraph::ComplexType#map
80
87
  def map &block
81
- @items.map &block
88
+ @items.map(&block)
82
89
  end
83
90
 
84
91
  # @yieldparam [UniqueType]
85
92
  # @return [Enumerable<UniqueType>]
86
93
  def each &block
87
- @items.each &block
94
+ @items.each(&block)
88
95
  end
89
96
 
90
97
  # @yieldparam [UniqueType]
@@ -95,23 +102,17 @@ module Solargraph
95
102
  return enum_for(__method__) unless block_given?
96
103
 
97
104
  @items.each do |item|
98
- item.each_unique_type &block
105
+ item.each_unique_type(&block)
99
106
  end
100
107
  end
101
108
 
102
- # @param atype [ComplexType] type which may be assigned to this type
103
- # @param api_map [ApiMap] The ApiMap that performs qualification
104
- def can_assign?(api_map, atype)
105
- any? { |ut| ut.can_assign?(api_map, atype) }
106
- end
107
-
108
109
  # @param new_name [String, nil]
109
110
  # @param make_rooted [Boolean, nil]
110
111
  # @param new_key_types [Array<ComplexType>, nil]
111
- # @param rooted [Boolean, nil]
112
+ # @param make_rooted [Boolean, nil]
112
113
  # @param new_subtypes [Array<ComplexType>, nil]
113
114
  # @return [self]
114
- def recreate(new_name: nil, make_rooted: nil, new_key_types: nil, new_subtypes: nil)
115
+ def recreate new_name: nil, make_rooted: nil, new_key_types: nil, new_subtypes: nil
115
116
  ComplexType.new(map do |ut|
116
117
  ut.recreate(new_name: new_name,
117
118
  make_rooted: make_rooted,
@@ -132,13 +133,13 @@ module Solargraph
132
133
 
133
134
  # @param index [Integer]
134
135
  # @return [UniqueType]
135
- def [](index)
136
+ def [] index
136
137
  @items[index]
137
138
  end
138
139
 
139
140
  # @return [Array<UniqueType>]
140
141
  def select &block
141
- @items.select &block
142
+ @items.select(&block)
142
143
  end
143
144
 
144
145
  # @return [String]
@@ -153,7 +154,9 @@ module Solargraph
153
154
  end
154
155
 
155
156
  # @param name [Symbol]
157
+ #
156
158
  # @return [Object, nil]
159
+ # @param [Array<Object>] args
157
160
  def method_missing name, *args, &block
158
161
  return if @items.first.nil?
159
162
  return @items.first.send(name, *args, &block) if respond_to_missing?(name)
@@ -162,7 +165,7 @@ module Solargraph
162
165
 
163
166
  # @param name [Symbol]
164
167
  # @param include_private [Boolean]
165
- def respond_to_missing?(name, include_private = false)
168
+ def respond_to_missing? name, include_private = false
166
169
  TypeMethods.public_instance_methods.include?(name) || super
167
170
  end
168
171
 
@@ -194,6 +197,65 @@ module Solargraph
194
197
  rooted_tags
195
198
  end
196
199
 
200
+ # @param api_map [ApiMap]
201
+ # @param expected [ComplexType, ComplexType::UniqueType]
202
+ # @param situation [:method_call, :return_type, :assignment]
203
+ # @param rules [Array<:allow_subtype_skew, :allow_empty_params, :allow_reverse_match, :allow_any_match, :allow_undefined, :allow_unresolved_generic, :allow_unmatched_interface>]
204
+ #
205
+ # allow_subtype_skew: if not provided, check if any subtypes of
206
+ # the expected type match the inferred type
207
+ #
208
+ # allow_reverse_match: check if any subtypes
209
+ # of the expected type match the inferred type
210
+ #
211
+ # allow_empty_params: allow a general inferred type without
212
+ # parameters to conform to a more specific expected type
213
+ #
214
+ # allow_any_match: any unique type matched in the inferred
215
+ # qualifies as a match
216
+ #
217
+ # allow_undefined: treat undefined as a wildcard that matches
218
+ # anything
219
+ #
220
+ # @param variance [:invariant, :covariant, :contravariant]
221
+ # @return [Boolean]
222
+ def conforms_to? api_map, expected,
223
+ situation,
224
+ rules = [],
225
+ variance: erased_variance(situation)
226
+ expected = expected.downcast_to_literal_if_possible
227
+ inferred = downcast_to_literal_if_possible
228
+
229
+ return duck_types_match?(api_map, expected, inferred) if expected.duck_type?
230
+
231
+ if rules.include? :allow_any_match
232
+ inferred.any? do |inf|
233
+ inf.conforms_to?(api_map, expected, situation, rules,
234
+ variance: variance)
235
+ end
236
+ else
237
+ inferred.all? do |inf|
238
+ inf.conforms_to?(api_map, expected, situation, rules,
239
+ variance: variance)
240
+ end
241
+ end
242
+ end
243
+
244
+ # @param api_map [ApiMap]
245
+ # @param expected [ComplexType, UniqueType]
246
+ # @param inferred [ComplexType, UniqueType]
247
+ # @return [Boolean]
248
+ def duck_types_match? api_map, expected, inferred
249
+ raise ArgumentError, 'Expected type must be duck type' unless expected.duck_type?
250
+ expected.each do |exp|
251
+ next unless exp.duck_type?
252
+ quack = exp.to_s[1..]
253
+ # @sg-ignore Need to add nil check here
254
+ return false if api_map.get_method_stack(inferred.namespace, quack, scope: inferred.scope).empty?
255
+ end
256
+ true
257
+ end
258
+
197
259
  # @return [String]
198
260
  def rooted_tags
199
261
  map(&:rooted_tag).join(', ')
@@ -201,14 +263,14 @@ module Solargraph
201
263
 
202
264
  # @yieldparam [UniqueType]
203
265
  def all? &block
204
- @items.all? &block
266
+ @items.all?(&block)
205
267
  end
206
268
 
207
269
  # @yieldparam [UniqueType]
208
270
  # @yieldreturn [Boolean]
209
271
  # @return [Boolean]
210
272
  def any? &block
211
- @items.compact.any? &block
273
+ @items.compact.any?(&block)
212
274
  end
213
275
 
214
276
  def selfy?
@@ -228,8 +290,10 @@ module Solargraph
228
290
  # @yieldparam t [UniqueType]
229
291
  # @yieldreturn [UniqueType]
230
292
  # @return [ComplexType]
231
- def transform(new_name = nil, &transform_type)
232
- raise "Please remove leading :: and set rooted with recreate() instead - #{new_name}" if new_name&.start_with?('::')
293
+ def transform new_name = nil, &transform_type
294
+ if new_name&.start_with?('::')
295
+ raise "Please remove leading :: and set rooted with recreate() instead - #{new_name}"
296
+ end
233
297
  ComplexType.new(map { |ut| ut.transform(new_name, &transform_type) })
234
298
  end
235
299
 
@@ -252,6 +316,13 @@ module Solargraph
252
316
  @items.any?(&:nil_type?)
253
317
  end
254
318
 
319
+ # @return [ComplexType]
320
+ def without_nil
321
+ new_items = @items.reject(&:nil_type?)
322
+ return ComplexType::UNDEFINED if new_items.empty?
323
+ ComplexType.new(new_items)
324
+ end
325
+
255
326
  # @return [Array<ComplexType>]
256
327
  def all_params
257
328
  @items.first.all_params || []
@@ -260,7 +331,7 @@ module Solargraph
260
331
  # @return [ComplexType]
261
332
  def reduce_class_type
262
333
  new_items = items.flat_map do |type|
263
- next type unless ['Module', 'Class'].include?(type.name)
334
+ next type unless %w[Module Class].include?(type.name)
264
335
  next type if type.all_params.empty?
265
336
 
266
337
  type.all_params
@@ -274,6 +345,13 @@ module Solargraph
274
345
  all?(&:all_rooted?)
275
346
  end
276
347
 
348
+ # @param other [ComplexType, UniqueType]
349
+ def erased_version_of? other
350
+ return false if items.length != 1 || other.items.length != 1
351
+
352
+ @items.first.erased_version_of?(other.items.first)
353
+ end
354
+
277
355
  # every top-level type has resolved to be fully qualified; see
278
356
  # #all_rooted? to check their subtypes as well
279
357
  def rooted?
@@ -282,12 +360,46 @@ module Solargraph
282
360
 
283
361
  attr_reader :items
284
362
 
285
- def rooted?
286
- @items.all?(&:rooted?)
363
+ # @param exclude_types [ComplexType, nil]
364
+ # @param api_map [ApiMap]
365
+ # @return [ComplexType, self]
366
+ def exclude exclude_types, api_map
367
+ return self if exclude_types.nil?
368
+
369
+ types = items - exclude_types.items
370
+ types = [ComplexType::UniqueType::UNDEFINED] if types.empty?
371
+ ComplexType.new(types)
372
+ end
373
+
374
+ # @see https://en.wikipedia.org/wiki/Intersection_type
375
+ #
376
+ # @param intersection_type [ComplexType, ComplexType::UniqueType, nil]
377
+ # @param api_map [ApiMap]
378
+ # @return [self, ComplexType::UniqueType]
379
+ def intersect_with intersection_type, api_map
380
+ return self if intersection_type.nil?
381
+ return intersection_type if undefined?
382
+ types = []
383
+ # try to find common types via conformance
384
+ items.each do |ut|
385
+ intersection_type.each do |int_type|
386
+ if int_type.conforms_to?(api_map, ut, :assignment)
387
+ types << int_type
388
+ elsif ut.conforms_to?(api_map, int_type, :assignment)
389
+ types << ut
390
+ end
391
+ end
392
+ end
393
+ types = [ComplexType::UniqueType::UNDEFINED] if types.empty?
394
+ ComplexType.new(types)
287
395
  end
288
396
 
289
397
  protected
290
398
 
399
+ def equality_fields
400
+ [self.class, items]
401
+ end
402
+
291
403
  # @return [ComplexType]
292
404
  def reduce_object
293
405
  new_items = items.flat_map do |ut|
@@ -307,30 +419,29 @@ module Solargraph
307
419
  # @example
308
420
  # ComplexType.parse 'String', 'Foo', 'nil' #=> [String, Foo, nil]
309
421
  #
310
- # @note
311
- # The `partial` parameter is used to indicate that the method is
312
- # receiving a string that will be used inside another ComplexType.
313
- # It returns arrays of ComplexTypes instead of a single cohesive one.
314
- # Consumers should not need to use this parameter; it should only be
315
- # used internally.
316
- #
422
+ # @param partial [Boolean] if true, method is receiving a string
423
+ # that will be used inside another ComplexType. It returns
424
+ # arrays of ComplexTypes instead of a single cohesive one.
425
+ # Consumers should not need to use this parameter; it should
426
+ # only be used internally.
317
427
  # @param strings [Array<String>] The type definitions to parse
318
428
  # @return [ComplexType]
319
429
  # # @overload parse(*strings, partial: false)
320
430
  # # @todo Need ability to use a literal true as a type below
321
431
  # # @param partial [Boolean] True if the string is part of a another type
322
432
  # # @return [Array<UniqueType>]
323
- # @todo To be able to select the right signature above,
433
+ # @sg-ignore To be able to select the right signature above,
324
434
  # Chain::Call needs to know the decl type (:arg, :optarg,
325
435
  # :kwarg, etc) of the arguments given, instead of just having
326
436
  # an array of Chains as the arguments.
327
437
  def parse *strings, partial: false
328
- # @type [Hash{Array<String> => ComplexType}]
438
+ # @type [Hash{Array<String> => ComplexType, Array<ComplexType::UniqueType>}]
329
439
  @cache ||= {}
330
440
  unless partial
331
441
  cached = @cache[strings]
332
442
  return cached unless cached.nil?
333
443
  end
444
+ # @types [Array<ComplexType::UniqueType>]
334
445
  types = []
335
446
  key_types = nil
336
447
  strings.each do |type_string|
@@ -342,15 +453,16 @@ module Solargraph
342
453
  # @param char [String]
343
454
  type_string&.each_char do |char|
344
455
  if char == '='
345
- #raise ComplexTypeError, "Invalid = in type #{type_string}" unless curly_stack > 0
456
+ # raise ComplexTypeError, "Invalid = in type #{type_string}" unless curly_stack > 0
346
457
  elsif char == '<'
347
458
  point_stack += 1
348
459
  elsif char == '>'
349
- if subtype_string.end_with?('=') && curly_stack > 0
460
+ if subtype_string.end_with?('=') && curly_stack.positive?
350
461
  subtype_string += char
351
462
  elsif base.end_with?('=')
352
- raise ComplexTypeError, "Invalid hash thing" unless key_types.nil?
463
+ raise ComplexTypeError, 'Invalid hash thing' unless key_types.nil?
353
464
  # types.push ComplexType.new([UniqueType.new(base[0..-2].strip)])
465
+ # @sg-ignore Need to add nil check here
354
466
  types.push UniqueType.parse(base[0..-2].strip, subtype_string)
355
467
  # @todo this should either expand key_type's type
356
468
  # automatically or complain about not being
@@ -361,7 +473,7 @@ module Solargraph
361
473
  subtype_string.clear
362
474
  next
363
475
  else
364
- raise ComplexTypeError, "Invalid close in type #{type_string}" if point_stack == 0
476
+ raise ComplexTypeError, "Invalid close in type #{type_string}" if point_stack.zero?
365
477
  point_stack -= 1
366
478
  subtype_string += char
367
479
  end
@@ -371,34 +483,37 @@ module Solargraph
371
483
  elsif char == '}'
372
484
  curly_stack -= 1
373
485
  subtype_string += char
374
- raise ComplexTypeError, "Invalid close in type #{type_string}" if curly_stack < 0
486
+ raise ComplexTypeError, "Invalid close in type #{type_string}" if curly_stack.negative?
375
487
  next
376
488
  elsif char == '('
377
489
  paren_stack += 1
378
490
  elsif char == ')'
379
491
  paren_stack -= 1
380
492
  subtype_string += char
381
- raise ComplexTypeError, "Invalid close in type #{type_string}" if paren_stack < 0
493
+ raise ComplexTypeError, "Invalid close in type #{type_string}" if paren_stack.negative?
382
494
  next
383
- elsif char == ',' && point_stack == 0 && curly_stack == 0 && paren_stack == 0
495
+ elsif char == ',' && point_stack.zero? && curly_stack.zero? && paren_stack.zero?
384
496
  # types.push ComplexType.new([UniqueType.new(base.strip, subtype_string.strip)])
385
497
  types.push UniqueType.parse(base.strip, subtype_string.strip)
386
498
  base.clear
387
499
  subtype_string.clear
388
500
  next
389
501
  end
390
- if point_stack == 0 && curly_stack == 0 && paren_stack == 0
502
+ if point_stack.zero? && curly_stack.zero? && paren_stack.zero?
391
503
  base.concat char
392
504
  else
393
505
  subtype_string.concat char
394
506
  end
395
507
  end
396
- raise ComplexTypeError, "Unclosed subtype in #{type_string}" if point_stack != 0 || curly_stack != 0 || paren_stack != 0
508
+ if point_stack != 0 || curly_stack != 0 || paren_stack != 0
509
+ raise ComplexTypeError,
510
+ "Unclosed subtype in #{type_string}"
511
+ end
397
512
  # types.push ComplexType.new([UniqueType.new(base, subtype_string)])
398
513
  types.push UniqueType.parse(base.strip, subtype_string.strip)
399
514
  end
400
515
  unless key_types.nil?
401
- raise ComplexTypeError, "Invalid use of key/value parameters" unless partial
516
+ raise ComplexTypeError, 'Invalid use of key/value parameters' unless partial
402
517
  return key_types if types.empty?
403
518
  return [key_types, types]
404
519
  end
@@ -410,7 +525,7 @@ module Solargraph
410
525
  # @param strings [Array<String>]
411
526
  # @return [ComplexType]
412
527
  def try_parse *strings
413
- parse *strings
528
+ parse(*strings)
414
529
  rescue ComplexTypeError => e
415
530
  Solargraph.logger.info "Error parsing complex type `#{strings.join(', ')}`: #{e.message}"
416
531
  ComplexType::UNDEFINED
@@ -435,9 +550,7 @@ module Solargraph
435
550
  # @param dst [String]
436
551
  # @return [String]
437
552
  def reduce_class dst
438
- while dst =~ /^(Class|Module)\<(.*?)\>$/
439
- dst = dst.sub(/^(Class|Module)\</, '').sub(/\>$/, '')
440
- end
553
+ dst = dst.sub(/^(Class|Module)</, '').sub(/>$/, '') while dst =~ /^(Class|Module)<(.*?)>$/
441
554
  dst
442
555
  end
443
556
  end
@@ -1,61 +1,61 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- module Convention
5
- module DataDefinition
6
- # A node wrapper for a Data definition via const assignment.
7
- # @example
8
- # MyData = Data.new(:bar, :baz) do
9
- # def foo
10
- # end
11
- # end
12
- class DataAssignmentNode < DataDefintionNode
13
- class << self
14
- # @example
15
- # s(:casgn, nil, :Foo,
16
- # s(:block,
17
- # s(:send,
18
- # s(:const, nil, :Data), :define,
19
- # s(:sym, :bar),
20
- # s(:sym, :baz)),
21
- # s(:args),
22
- # s(:def, :foo,
23
- # s(:args),
24
- # s(:send, nil, :bar))))
25
- # @param node [::Parser::AST::Node]
26
- def match?(node)
27
- return false unless node&.type == :casgn
28
- return false if node.children[2].nil?
29
-
30
- data_node = if node.children[2].type == :block
31
- node.children[2].children[0]
32
- else
33
- node.children[2]
34
- end
35
-
36
- data_definition_node?(data_node)
37
- end
38
- end
39
-
40
- def class_name
41
- if node.children[0]
42
- Parser::NodeMethods.unpack_name(node.children[0]) + "::#{node.children[1]}"
43
- else
44
- node.children[1].to_s
45
- end
46
- end
47
-
48
- private
49
-
50
- # @return [Parser::AST::Node]
51
- def data_node
52
- if node.children[2].type == :block
53
- node.children[2].children[0]
54
- else
55
- node.children[2]
56
- end
57
- end
58
- end
59
- end
60
- end
61
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Convention
5
+ module DataDefinition
6
+ # A node wrapper for a Data definition via const assignment.
7
+ # @example
8
+ # MyData = Data.new(:bar, :baz) do
9
+ # def foo
10
+ # end
11
+ # end
12
+ class DataAssignmentNode < DataDefintionNode
13
+ class << self
14
+ # @example
15
+ # s(:casgn, nil, :Foo,
16
+ # s(:block,
17
+ # s(:send,
18
+ # s(:const, nil, :Data), :define,
19
+ # s(:sym, :bar),
20
+ # s(:sym, :baz)),
21
+ # s(:args),
22
+ # s(:def, :foo,
23
+ # s(:args),
24
+ # s(:send, nil, :bar))))
25
+ # @param node [::Parser::AST::Node]
26
+ def match? node
27
+ return false unless node&.type == :casgn
28
+ return false if node.children[2].nil?
29
+
30
+ data_node = if node.children[2].type == :block
31
+ node.children[2].children[0]
32
+ else
33
+ node.children[2]
34
+ end
35
+
36
+ data_definition_node?(data_node)
37
+ end
38
+ end
39
+
40
+ def class_name
41
+ if node.children[0]
42
+ Parser::NodeMethods.unpack_name(node.children[0]) + "::#{node.children[1]}"
43
+ else
44
+ node.children[1].to_s
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ # @return [Parser::AST::Node]
51
+ def data_node
52
+ if node.children[2].type == :block
53
+ node.children[2].children[0]
54
+ else
55
+ node.children[2]
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -27,7 +27,7 @@ module Solargraph
27
27
  # s(:send, nil, :bar)))
28
28
  #
29
29
  # @param node [Parser::AST::Node]
30
- def match?(node)
30
+ def match? node
31
31
  return false unless node&.type == :class
32
32
 
33
33
  data_definition_node?(node.children[1])
@@ -37,7 +37,7 @@ module Solargraph
37
37
 
38
38
  # @param data_node [Parser::AST::Node]
39
39
  # @return [Boolean]
40
- def data_definition_node?(data_node)
40
+ def data_definition_node? data_node
41
41
  return false unless data_node.is_a?(::Parser::AST::Node)
42
42
  return false unless data_node&.type == :send
43
43
  return false unless data_node.children[0]&.type == :const
@@ -49,7 +49,7 @@ module Solargraph
49
49
  end
50
50
 
51
51
  # @param node [Parser::AST::Node]
52
- def initialize(node)
52
+ def initialize node
53
53
  @node = node
54
54
  end
55
55
 
@@ -66,7 +66,7 @@ module Solargraph
66
66
  end.compact
67
67
  end
68
68
 
69
- # @return [Parser::AST::Node]
69
+ # @return [Parser::AST::Node, nil]
70
70
  def body_node
71
71
  node.children[2]
72
72
  end
@@ -81,9 +81,11 @@ module Solargraph
81
81
  node.children[1]
82
82
  end
83
83
 
84
+ # @sg-ignore Need to add nil check here
84
85
  # @return [Array<Parser::AST::Node>]
85
86
  def data_attribute_nodes
86
- data_node.children[2..-1]
87
+ # @sg-ignore Need to add nil check here
88
+ data_node.children[2..]
87
89
  end
88
90
  end
89
91
  end
@@ -17,6 +17,7 @@ module Solargraph
17
17
  type: :class,
18
18
  location: loc,
19
19
  closure: region.closure,
20
+ # @sg-ignore flow sensitive typing needs to handle attrs
20
21
  name: data_definition_node.class_name,
21
22
  comments: comments_for(node),
22
23
  visibility: :public,
@@ -39,6 +40,7 @@ module Solargraph
39
40
  # Solargraph::SourceMap::Clip#complete_keyword_parameters does not seem to currently take into account [Pin::Method#signatures] hence we only one for :kwarg
40
41
  pins.push initialize_method_pin
41
42
 
43
+ # @sg-ignore flow sensitive typing needs to handle attrs
42
44
  data_definition_node.attributes.map do |attribute_node, attribute_name|
43
45
  initialize_method_pin.parameters.push(
44
46
  Pin::Parameter.new(
@@ -51,6 +53,7 @@ module Solargraph
51
53
  end
52
54
 
53
55
  # define attribute readers and instance variables
56
+ # @sg-ignore flow sensitive typing needs to handle attrs
54
57
  data_definition_node.attributes.each do |attribute_node, attribute_name|
55
58
  name = attribute_name.to_s
56
59
  method_pin = Pin::Method.new(
@@ -78,7 +81,7 @@ module Solargraph
78
81
 
79
82
  private
80
83
 
81
- # @return [DataDefintionNode, nil]
84
+ # @return [DataDefinition::DataDefintionNode, DataDefinition::DataAssignmentNode, nil]
82
85
  def data_definition_node
83
86
  @data_definition_node ||= if DataDefintionNode.match?(node)
84
87
  DataDefintionNode.new(node)
@@ -90,7 +93,7 @@ module Solargraph
90
93
  # @param attribute_node [Parser::AST::Node]
91
94
  # @param attribute_name [String]
92
95
  # @return [String, nil]
93
- def attribute_comments(attribute_node, attribute_name)
96
+ def attribute_comments attribute_node, attribute_name
94
97
  data_comments = comments_for(attribute_node)
95
98
  return if data_comments.nil? || data_comments.empty?
96
99