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