solargraph 0.58.3 → 0.59.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 (206) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +3 -0
  3. data/.github/workflows/linting.yml +6 -5
  4. data/.github/workflows/plugins.yml +46 -34
  5. data/.github/workflows/rspec.yml +15 -28
  6. data/.github/workflows/typecheck.yml +3 -2
  7. data/.rubocop.yml +38 -6
  8. data/.rubocop_todo.yml +53 -966
  9. data/CHANGELOG.md +12 -0
  10. data/Gemfile +3 -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 +29 -18
  17. data/lib/solargraph/api_map/source_to_yard.rb +22 -9
  18. data/lib/solargraph/api_map/store.rb +39 -28
  19. data/lib/solargraph/api_map.rb +156 -72
  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 +30 -18
  23. data/lib/solargraph/complex_type/unique_type.rb +216 -57
  24. data/lib/solargraph/complex_type.rb +171 -58
  25. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +1 -1
  26. data/lib/solargraph/convention/data_definition/data_definition_node.rb +7 -5
  27. data/lib/solargraph/convention/data_definition.rb +5 -2
  28. data/lib/solargraph/convention/gemfile.rb +1 -1
  29. data/lib/solargraph/convention/gemspec.rb +1 -1
  30. data/lib/solargraph/convention/rakefile.rb +1 -1
  31. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +2 -1
  32. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +4 -3
  33. data/lib/solargraph/convention/struct_definition.rb +8 -4
  34. data/lib/solargraph/convention.rb +2 -2
  35. data/lib/solargraph/converters/dd.rb +2 -0
  36. data/lib/solargraph/converters/dl.rb +2 -0
  37. data/lib/solargraph/converters/dt.rb +2 -0
  38. data/lib/solargraph/converters/misc.rb +2 -0
  39. data/lib/solargraph/diagnostics/require_not_found.rb +1 -0
  40. data/lib/solargraph/diagnostics/rubocop.rb +11 -10
  41. data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
  42. data/lib/solargraph/diagnostics/type_check.rb +11 -10
  43. data/lib/solargraph/diagnostics/update_errors.rb +4 -8
  44. data/lib/solargraph/doc_map.rb +38 -39
  45. data/lib/solargraph/equality.rb +4 -4
  46. data/lib/solargraph/gem_pins.rb +6 -6
  47. data/lib/solargraph/language_server/error_codes.rb +10 -10
  48. data/lib/solargraph/language_server/host/diagnoser.rb +1 -1
  49. data/lib/solargraph/language_server/host/dispatch.rb +3 -3
  50. data/lib/solargraph/language_server/host/message_worker.rb +4 -3
  51. data/lib/solargraph/language_server/host/sources.rb +2 -1
  52. data/lib/solargraph/language_server/host.rb +30 -22
  53. data/lib/solargraph/language_server/message/base.rb +1 -1
  54. data/lib/solargraph/language_server/message/client/register_capability.rb +1 -3
  55. data/lib/solargraph/language_server/message/completion_item/resolve.rb +6 -8
  56. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +12 -18
  57. data/lib/solargraph/language_server/message/extended/document.rb +1 -0
  58. data/lib/solargraph/language_server/message/extended/document_gems.rb +7 -7
  59. data/lib/solargraph/language_server/message/extended/download_core.rb +2 -1
  60. data/lib/solargraph/language_server/message/extended/search.rb +1 -1
  61. data/lib/solargraph/language_server/message/initialize.rb +20 -14
  62. data/lib/solargraph/language_server/message/text_document/completion.rb +10 -8
  63. data/lib/solargraph/language_server/message/text_document/definition.rb +41 -32
  64. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +17 -10
  65. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +29 -19
  66. data/lib/solargraph/language_server/message/text_document/formatting.rb +8 -6
  67. data/lib/solargraph/language_server/message/text_document/hover.rb +5 -5
  68. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +13 -6
  69. data/lib/solargraph/language_server/message/text_document/references.rb +17 -10
  70. data/lib/solargraph/language_server/message/text_document/rename.rb +20 -13
  71. data/lib/solargraph/language_server/message/text_document/signature_help.rb +3 -2
  72. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -17
  73. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +34 -28
  74. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +38 -30
  75. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +23 -17
  76. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +27 -17
  77. data/lib/solargraph/language_server/message.rb +1 -1
  78. data/lib/solargraph/language_server/request.rb +4 -2
  79. data/lib/solargraph/language_server/transport/data_reader.rb +11 -13
  80. data/lib/solargraph/language_server/uri_helpers.rb +2 -2
  81. data/lib/solargraph/library.rb +57 -38
  82. data/lib/solargraph/location.rb +17 -14
  83. data/lib/solargraph/logging.rb +22 -4
  84. data/lib/solargraph/page.rb +1 -1
  85. data/lib/solargraph/parser/comment_ripper.rb +19 -4
  86. data/lib/solargraph/parser/flow_sensitive_typing.rb +324 -108
  87. data/lib/solargraph/parser/node_processor/base.rb +34 -4
  88. data/lib/solargraph/parser/node_processor.rb +8 -7
  89. data/lib/solargraph/parser/parser_gem/class_methods.rb +30 -14
  90. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -1
  91. data/lib/solargraph/parser/parser_gem/node_chainer.rb +50 -25
  92. data/lib/solargraph/parser/parser_gem/node_methods.rb +91 -70
  93. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +4 -4
  94. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +13 -11
  95. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +9 -0
  96. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +11 -12
  97. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +10 -3
  98. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +9 -8
  99. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +36 -6
  100. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +5 -3
  101. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +1 -0
  102. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +3 -1
  103. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +3 -3
  104. data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
  105. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -1
  106. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
  107. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -5
  108. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +124 -113
  109. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +1 -1
  110. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
  111. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +6 -2
  112. data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
  113. data/lib/solargraph/parser/parser_gem.rb +2 -0
  114. data/lib/solargraph/parser/region.rb +9 -3
  115. data/lib/solargraph/parser/snippet.rb +3 -1
  116. data/lib/solargraph/parser.rb +2 -0
  117. data/lib/solargraph/pin/base.rb +124 -80
  118. data/lib/solargraph/pin/base_variable.rb +273 -24
  119. data/lib/solargraph/pin/block.rb +29 -6
  120. data/lib/solargraph/pin/breakable.rb +7 -1
  121. data/lib/solargraph/pin/callable.rb +65 -21
  122. data/lib/solargraph/pin/closure.rb +7 -10
  123. data/lib/solargraph/pin/common.rb +24 -6
  124. data/lib/solargraph/pin/compound_statement.rb +55 -0
  125. data/lib/solargraph/pin/constant.rb +3 -5
  126. data/lib/solargraph/pin/conversions.rb +10 -4
  127. data/lib/solargraph/pin/delegated_method.rb +19 -8
  128. data/lib/solargraph/pin/documenting.rb +4 -2
  129. data/lib/solargraph/pin/instance_variable.rb +5 -1
  130. data/lib/solargraph/pin/keyword.rb +0 -4
  131. data/lib/solargraph/pin/local_variable.rb +15 -59
  132. data/lib/solargraph/pin/method.rb +156 -104
  133. data/lib/solargraph/pin/method_alias.rb +8 -0
  134. data/lib/solargraph/pin/namespace.rb +19 -12
  135. data/lib/solargraph/pin/parameter.rb +100 -36
  136. data/lib/solargraph/pin/proxy_type.rb +4 -1
  137. data/lib/solargraph/pin/reference/override.rb +1 -1
  138. data/lib/solargraph/pin/reference/superclass.rb +2 -0
  139. data/lib/solargraph/pin/reference/type_alias.rb +16 -0
  140. data/lib/solargraph/pin/reference.rb +20 -0
  141. data/lib/solargraph/pin/search.rb +3 -2
  142. data/lib/solargraph/pin/signature.rb +15 -12
  143. data/lib/solargraph/pin/symbol.rb +2 -1
  144. data/lib/solargraph/pin/until.rb +2 -4
  145. data/lib/solargraph/pin/while.rb +2 -4
  146. data/lib/solargraph/pin.rb +2 -0
  147. data/lib/solargraph/pin_cache.rb +22 -19
  148. data/lib/solargraph/position.rb +17 -10
  149. data/lib/solargraph/range.rb +16 -15
  150. data/lib/solargraph/rbs_map/conversions.rb +358 -229
  151. data/lib/solargraph/rbs_map/core_fills.rb +18 -11
  152. data/lib/solargraph/rbs_map/core_map.rb +24 -17
  153. data/lib/solargraph/rbs_map/stdlib_map.rb +33 -5
  154. data/lib/solargraph/rbs_map.rb +76 -32
  155. data/lib/solargraph/server_methods.rb +1 -1
  156. data/lib/solargraph/shell.rb +258 -66
  157. data/lib/solargraph/source/chain/array.rb +4 -2
  158. data/lib/solargraph/source/chain/call.rb +96 -56
  159. data/lib/solargraph/source/chain/class_variable.rb +1 -1
  160. data/lib/solargraph/source/chain/constant.rb +5 -1
  161. data/lib/solargraph/source/chain/global_variable.rb +1 -1
  162. data/lib/solargraph/source/chain/hash.rb +8 -5
  163. data/lib/solargraph/source/chain/if.rb +12 -10
  164. data/lib/solargraph/source/chain/instance_variable.rb +24 -1
  165. data/lib/solargraph/source/chain/link.rb +12 -22
  166. data/lib/solargraph/source/chain/literal.rb +9 -6
  167. data/lib/solargraph/source/chain/or.rb +10 -4
  168. data/lib/solargraph/source/chain/q_call.rb +2 -0
  169. data/lib/solargraph/source/chain/variable.rb +3 -1
  170. data/lib/solargraph/source/chain/z_super.rb +1 -3
  171. data/lib/solargraph/source/chain.rb +51 -38
  172. data/lib/solargraph/source/change.rb +12 -5
  173. data/lib/solargraph/source/cursor.rb +23 -17
  174. data/lib/solargraph/source/encoding_fixes.rb +6 -7
  175. data/lib/solargraph/source/source_chainer.rb +56 -32
  176. data/lib/solargraph/source/updater.rb +5 -1
  177. data/lib/solargraph/source.rb +59 -35
  178. data/lib/solargraph/source_map/clip.rb +48 -29
  179. data/lib/solargraph/source_map/data.rb +4 -1
  180. data/lib/solargraph/source_map/mapper.rb +69 -42
  181. data/lib/solargraph/source_map.rb +21 -9
  182. data/lib/solargraph/type_checker/problem.rb +3 -1
  183. data/lib/solargraph/type_checker/rules.rb +81 -8
  184. data/lib/solargraph/type_checker.rb +195 -121
  185. data/lib/solargraph/version.rb +1 -1
  186. data/lib/solargraph/workspace/config.rb +14 -11
  187. data/lib/solargraph/workspace/gemspecs.rb +367 -0
  188. data/lib/solargraph/workspace/require_paths.rb +1 -0
  189. data/lib/solargraph/workspace.rb +50 -28
  190. data/lib/solargraph/yard_map/helpers.rb +8 -3
  191. data/lib/solargraph/yard_map/mapper/to_method.rb +13 -7
  192. data/lib/solargraph/yard_map/mapper/to_namespace.rb +2 -1
  193. data/lib/solargraph/yard_map/mapper.rb +13 -8
  194. data/lib/solargraph/yard_map.rb +17 -18
  195. data/lib/solargraph/yard_tags.rb +2 -2
  196. data/lib/solargraph/yardoc.rb +7 -4
  197. data/lib/solargraph.rb +31 -8
  198. data/rbs/fills/rubygems/0/dependency.rbs +193 -0
  199. data/rbs/fills/tuple/tuple.rbs +28 -0
  200. data/rbs/shims/ast/0/node.rbs +1 -1
  201. data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
  202. data/solargraph.gemspec +37 -35
  203. metadata +41 -41
  204. data/lib/solargraph/type_checker/checks.rb +0 -124
  205. data/lib/solargraph/type_checker/param_def.rb +0 -37
  206. data/lib/solargraph/yard_map/to_method.rb +0 -89
@@ -0,0 +1,176 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class ComplexType
5
+ # Checks whether a type can be used in a given situation
6
+ class Conformance
7
+ # @param api_map [ApiMap]
8
+ # @param inferred [ComplexType::UniqueType]
9
+ # @param expected [ComplexType::UniqueType]
10
+ # @param situation [:method_call, :return_type]
11
+ # @param rules [Array<:allow_subtype_skew, :allow_empty_params, :allow_reverse_match,
12
+ # :allow_any_match, :allow_undefined, :allow_unresolved_generic,
13
+ # :allow_unmatched_interface>]
14
+ # @param variance [:invariant, :covariant, :contravariant]
15
+ def initialize api_map, inferred, expected,
16
+ situation = :method_call, rules = [],
17
+ variance: inferred.erased_variance(situation)
18
+ @api_map = api_map
19
+ @inferred = inferred
20
+ @expected = expected
21
+ @situation = situation
22
+ @rules = rules
23
+ @variance = variance
24
+ # :nocov:
25
+ unless expected.is_a?(UniqueType)
26
+ # @sg-ignore This should never happen and the typechecker is angry about it
27
+ raise "Expected type must be a UniqueType, got #{expected.class} in #{expected.inspect}"
28
+ end
29
+ # :nocov:
30
+ return if inferred.is_a?(UniqueType)
31
+ # :nocov:
32
+ # @sg-ignore This should never happen and the typechecker is angry about it
33
+ raise "Inferred type must be a UniqueType, got #{inferred.class} in #{inferred.inspect}"
34
+ # :nocov:
35
+ end
36
+
37
+ def conforms_to_unique_type?
38
+ unless expected.is_a?(UniqueType)
39
+ # :nocov:
40
+ raise "Expected type must be a UniqueType, got #{expected.class} in #{expected.inspect}"
41
+ # :nocov:
42
+ end
43
+
44
+ return true if ignore_interface?
45
+ return true if conforms_via_reverse_match?
46
+
47
+ downcast_inferred = inferred.downcast_to_literal_if_possible
48
+ downcast_expected = expected.downcast_to_literal_if_possible
49
+ if (downcast_inferred.name != inferred.name) || (downcast_expected.name != expected.name)
50
+ return with_new_types(downcast_inferred, downcast_expected).conforms_to_unique_type?
51
+ end
52
+
53
+ if rules.include?(:allow_subtype_skew) && !expected.all_params.empty?
54
+ # parameters are not considered in this case
55
+ return with_new_types(inferred, expected.erase_parameters).conforms_to_unique_type?
56
+ end
57
+
58
+ return with_new_types(inferred.erase_parameters, expected).conforms_to_unique_type? if only_inferred_parameters?
59
+
60
+ return conforms_via_stripped_expected_parameters? if can_strip_expected_parameters?
61
+
62
+ return true if inferred == expected
63
+
64
+ return false unless erased_type_conforms?
65
+
66
+ return true if inferred.all_params.empty? && rules.include?(:allow_empty_params)
67
+
68
+ # at this point we know the erased type is fine - time to look at parameters
69
+
70
+ # there's an implicit 'any' on the expectation parameters
71
+ # if there are none specified
72
+ return true if expected.all_params.empty?
73
+
74
+ return false unless key_types_conform?
75
+
76
+ subtypes_conform?
77
+ end
78
+
79
+ private
80
+
81
+ def only_inferred_parameters?
82
+ !expected.parameters? && inferred.parameters?
83
+ end
84
+
85
+ def conforms_via_stripped_expected_parameters?
86
+ with_new_types(inferred, expected.erase_parameters).conforms_to_unique_type?
87
+ end
88
+
89
+ def ignore_interface?
90
+ (expected.any?(&:interface?) && rules.include?(:allow_unmatched_interface)) ||
91
+ (inferred.interface? && rules.include?(:allow_unmatched_interface))
92
+ end
93
+
94
+ def can_strip_expected_parameters?
95
+ expected.parameters? && !inferred.parameters? && rules.include?(:allow_empty_params)
96
+ end
97
+
98
+ def conforms_via_reverse_match?
99
+ return false unless rules.include? :allow_reverse_match
100
+
101
+ expected.conforms_to?(api_map, inferred, situation,
102
+ rules - [:allow_reverse_match],
103
+ variance: variance)
104
+ end
105
+
106
+ def erased_type_conforms?
107
+ case variance
108
+ when :invariant
109
+ return false unless inferred.name == expected.name
110
+ when :covariant
111
+ # covariant: we can pass in a more specific type
112
+ # we contain the expected mix-in, or we have a more specific type
113
+ return false unless api_map.type_include?(inferred.name, expected.name) ||
114
+ api_map.super_and_sub?(expected.name, inferred.name) ||
115
+ inferred.name == expected.name
116
+ when :contravariant
117
+ # contravariant: we can pass in a more general type
118
+ # we contain the expected mix-in, or we have a more general type
119
+ return false unless api_map.type_include?(inferred.name, expected.name) ||
120
+ api_map.super_and_sub?(inferred.name, expected.name) ||
121
+ inferred.name == expected.name
122
+ else
123
+ # :nocov:
124
+ raise "Unknown variance: #{variance.inspect}"
125
+ # :nocov:
126
+ end
127
+ true
128
+ end
129
+
130
+ def key_types_conform?
131
+ return true if expected.key_types.empty?
132
+
133
+ return false if inferred.key_types.empty?
134
+
135
+ unless ComplexType.new(inferred.key_types).conforms_to?(api_map,
136
+ ComplexType.new(expected.key_types),
137
+ situation,
138
+ rules,
139
+ variance: inferred.parameter_variance(situation))
140
+ return false
141
+ end
142
+
143
+ true
144
+ end
145
+
146
+ def subtypes_conform?
147
+ return true if expected.subtypes.empty?
148
+
149
+ return true if expected.subtypes.any?(&:undefined?) && rules.include?(:allow_undefined)
150
+
151
+ return true if inferred.subtypes.any?(&:undefined?) && rules.include?(:allow_undefined)
152
+
153
+ return true if inferred.subtypes.all?(&:generic?) && rules.include?(:allow_unresolved_generic)
154
+
155
+ return true if expected.subtypes.all?(&:generic?) && rules.include?(:allow_unresolved_generic)
156
+
157
+ return false if inferred.subtypes.empty?
158
+
159
+ ComplexType.new(inferred.subtypes).conforms_to?(api_map,
160
+ ComplexType.new(expected.subtypes),
161
+ situation,
162
+ rules,
163
+ variance: inferred.parameter_variance(situation))
164
+ end
165
+
166
+ # @return [self]
167
+ # @param inferred [ComplexType::UniqueType]
168
+ # @param expected [ComplexType::UniqueType]
169
+ def with_new_types inferred, expected
170
+ self.class.new(api_map, inferred, expected, situation, rules, variance: variance)
171
+ end
172
+
173
+ attr_reader :api_map, :inferred, :expected, :situation, :rules, :variance
174
+ end
175
+ end
176
+ end
@@ -43,8 +43,9 @@ module Solargraph
43
43
  @rooted_tag ||= rooted_name + rooted_substring
44
44
  end
45
45
 
46
+ # Whether this is an RBS interface like _ToAry or Hash::_Key.
46
47
  def interface?
47
- name.start_with?('_')
48
+ name.start_with?('_') || name.include?('::_')
48
49
  end
49
50
 
50
51
  # @return [Boolean]
@@ -54,11 +55,11 @@ module Solargraph
54
55
 
55
56
  # @return [Boolean]
56
57
  def nil_type?
57
- @nil_type ||= (name.casecmp('nil') == 0)
58
+ @nil_type ||= name.casecmp('nil').zero?
58
59
  end
59
60
 
60
61
  def tuple?
61
- @tuple_type ||= (name == 'Tuple') || (name == 'Array' && subtypes.length >= 1 && fixed_parameters?)
62
+ @tuple ||= (name == 'Tuple') || (name == 'Array' && subtypes.length >= 1 && fixed_parameters?)
62
63
  end
63
64
 
64
65
  def void?
@@ -73,9 +74,21 @@ module Solargraph
73
74
  name == 'undefined'
74
75
  end
75
76
 
77
+ # Variance of the type ignoring any type parameters
78
+ # @return [Symbol]
79
+ # @param situation [Symbol] The situation in which the variance is being considered.
80
+ def erased_variance situation = :method_call
81
+ # :nocov:
82
+ unless %i[method_call return_type assignment].include?(situation)
83
+ raise "Unknown situation: #{situation.inspect}"
84
+ end
85
+ # :nocov:
86
+ :covariant
87
+ end
88
+
76
89
  # @param generics_to_erase [Enumerable<String>]
77
90
  # @return [self]
78
- def erase_generics(generics_to_erase)
91
+ def erase_generics generics_to_erase
79
92
  transform do |type|
80
93
  if type.name == ComplexType::GENERIC_TAG_NAME
81
94
  if type.all_params.length == 1 && generics_to_erase.include?(type.all_params.first.to_s)
@@ -130,7 +143,7 @@ module Solargraph
130
143
  @namespace ||= lambda do
131
144
  return 'Object' if duck_type?
132
145
  return 'NilClass' if nil_type?
133
- return (name == 'Class' || name == 'Module') && !subtypes.empty? ? subtypes.first.name : name
146
+ %w[Class Module].include?(name) && !subtypes.empty? ? subtypes.first.name : name
134
147
  end.call
135
148
  end
136
149
 
@@ -138,7 +151,7 @@ module Solargraph
138
151
  def namespace_type
139
152
  return ComplexType.parse('::Object') if duck_type?
140
153
  return ComplexType.parse('::NilClass') if nil_type?
141
- return subtypes.first if (name == 'Class' || name == 'Module') && !subtypes.empty?
154
+ return subtypes.first if %w[Class Module].include?(name) && !subtypes.empty?
142
155
  self
143
156
  end
144
157
 
@@ -165,36 +178,33 @@ module Solargraph
165
178
  end
166
179
 
167
180
  # @return [String]
168
- def generate_substring_from(&to_str)
181
+ def generate_substring_from &to_str
169
182
  key_types_str = key_types.map(&to_str).join(', ')
170
183
  subtypes_str = subtypes.map(&to_str).join(', ')
171
- if key_types.none?(&:defined?) && subtypes.none?(&:defined?)
172
- ''
173
- elsif key_types.empty? && subtypes.empty?
184
+ if (key_types.none?(&:defined?) && subtypes.none?(&:defined?)) ||
185
+ (key_types.empty? && subtypes.empty?)
174
186
  ''
175
187
  elsif hash_parameters?
176
188
  "{#{key_types_str} => #{subtypes_str}}"
177
189
  elsif fixed_parameters?
178
190
  "(#{subtypes_str})"
191
+ elsif name == 'Hash'
192
+ "<#{key_types_str}, #{subtypes_str}>"
179
193
  else
180
- if name == 'Hash'
181
- "<#{key_types_str}, #{subtypes_str}>"
182
- else
183
- "<#{key_types_str}#{subtypes_str}>"
184
- end
194
+ "<#{key_types_str}#{subtypes_str}>"
185
195
  end
186
196
  end
187
197
 
188
198
  # @return [::Symbol] :class or :instance
189
199
  def scope
190
200
  @scope ||= :instance if duck_type? || nil_type?
191
- @scope ||= (name == 'Class' || name == 'Module') && !subtypes.empty? ? :class : :instance
201
+ @scope ||= %w[Class Module].include?(name) && !subtypes.empty? ? :class : :instance
192
202
  end
193
203
 
194
204
  # @param other [Object]
195
205
  def == other
196
206
  return false unless self.class == other.class
197
- # @sg-ignore https://github.com/castwide/solargraph/pull/1114
207
+ # @sg-ignore flow sensitive typing should support .class == .class
198
208
  tag == other.tag
199
209
  end
200
210
 
@@ -218,7 +228,9 @@ module Solargraph
218
228
  end
219
229
 
220
230
  # @yieldparam [UniqueType]
221
- # @return [Enumerator<UniqueType>]
231
+ # @return [void]
232
+ # @overload each_unique_type()
233
+ # @return [Enumerator<UniqueType>]
222
234
  def each_unique_type &block
223
235
  return enum_for(__method__) unless block_given?
224
236
  yield self