solargraph 0.59.1 → 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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/linting.yml +6 -0
  3. data/.github/workflows/plugins.yml +8 -0
  4. data/.github/workflows/rspec.yml +4 -1
  5. data/.github/workflows/typecheck.yml +2 -0
  6. data/.rubocop.yml +1 -0
  7. data/.rubocop_todo.yml +1 -1
  8. data/CHANGELOG.md +18 -0
  9. data/Gemfile +3 -0
  10. data/lib/solargraph/api_map/index.rb +13 -2
  11. data/lib/solargraph/api_map/store.rb +22 -8
  12. data/lib/solargraph/api_map.rb +38 -8
  13. data/lib/solargraph/complex_type/type_methods.rb +1 -0
  14. data/lib/solargraph/complex_type/unique_type.rb +16 -13
  15. data/lib/solargraph/complex_type.rb +5 -0
  16. data/lib/solargraph/convention/active_support_concern.rb +111 -111
  17. data/lib/solargraph/convention/base.rb +50 -50
  18. data/lib/solargraph/diagnostics.rb +55 -55
  19. data/lib/solargraph/doc_map.rb +1 -0
  20. data/lib/solargraph/environ.rb +52 -52
  21. data/lib/solargraph/gem_pins.rb +0 -11
  22. data/lib/solargraph/language_server/message/extended/environment.rb +25 -25
  23. data/lib/solargraph/language_server/message/initialized.rb +28 -28
  24. data/lib/solargraph/language_server/message/text_document.rb +28 -28
  25. data/lib/solargraph/language_server/progress.rb +143 -143
  26. data/lib/solargraph/language_server/transport/adapter.rb +68 -68
  27. data/lib/solargraph/language_server.rb +20 -20
  28. data/lib/solargraph/parser/parser_gem/node_chainer.rb +1 -0
  29. data/lib/solargraph/parser/parser_gem/node_methods.rb +42 -0
  30. data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +24 -24
  31. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +36 -36
  32. data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +24 -24
  33. data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +24 -24
  34. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +29 -5
  35. data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +20 -20
  36. data/lib/solargraph/pin/base.rb +31 -3
  37. data/lib/solargraph/pin/callable.rb +2 -2
  38. data/lib/solargraph/pin/common.rb +12 -0
  39. data/lib/solargraph/pin/method.rb +56 -16
  40. data/lib/solargraph/pin/reference/require.rb +14 -14
  41. data/lib/solargraph/pin/singleton.rb +11 -11
  42. data/lib/solargraph/rbs_map/conversions.rb +103 -145
  43. data/lib/solargraph/rbs_translator.rb +206 -0
  44. data/lib/solargraph/shell.rb +131 -64
  45. data/lib/solargraph/source/chain/array.rb +1 -12
  46. data/lib/solargraph/source/chain/block_symbol.rb +13 -13
  47. data/lib/solargraph/source/chain/block_variable.rb +13 -13
  48. data/lib/solargraph/source/chain/call.rb +8 -76
  49. data/lib/solargraph/source/chain/head.rb +19 -19
  50. data/lib/solargraph/source/chain/literal.rb +18 -14
  51. data/lib/solargraph/source/source_chainer.rb +4 -4
  52. data/lib/solargraph/source_map/mapper.rb +5 -135
  53. data/lib/solargraph/source_map.rb +14 -0
  54. data/lib/solargraph/version.rb +19 -1
  55. data/lib/solargraph/yard_map/cache.rb +25 -25
  56. data/lib/solargraph/yard_map/directives/attribute_directive.rb +65 -0
  57. data/lib/solargraph/yard_map/directives/domain_directive.rb +30 -0
  58. data/lib/solargraph/yard_map/directives/method_directive.rb +51 -0
  59. data/lib/solargraph/yard_map/directives/override_directive.rb +30 -0
  60. data/lib/solargraph/yard_map/directives/parse_directive.rb +53 -0
  61. data/lib/solargraph/yard_map/directives/visibility_directive.rb +70 -0
  62. data/lib/solargraph/yard_map/directives.rb +35 -0
  63. data/lib/solargraph/yard_map/macro.rb +113 -0
  64. data/lib/solargraph/yard_map/mapper/to_constant.rb +28 -28
  65. data/lib/solargraph/yard_map/mapper.rb +19 -1
  66. data/lib/solargraph/yard_map.rb +2 -0
  67. data/lib/solargraph.rb +1 -0
  68. data/solargraph.gemspec +1 -0
  69. metadata +24 -2
  70. data/rbs/fills/tuple/tuple.rbs +0 -177
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9346852d9ba48c677a63c6ac2dd3bf6b7cb536309f28569c256bc8654c19c865
4
- data.tar.gz: 9fd017aedc2b705156999d93f5bc8f5f6b99cd7cc3716565ef42ab26936336eb
3
+ metadata.gz: e3eff86e8759fbaaa9526cf9cceb70827c701f3b1925d58e1575870989d60e60
4
+ data.tar.gz: a60b5c8e9598afdca808c94fa68e2551d17f970b812ca64c3f00d530d0498fff
5
5
  SHA512:
6
- metadata.gz: 5b8d3c627dec8757b70444e444a66dd024818f3e62e7c8d9ea57a638182de64524cca532c7b8ae9c5944d373cfdb2e0f3a1ede46e1e8b3e4e728d02b2f9db0e0
7
- data.tar.gz: 41321b8ad277092a434241bc099488c99c721fb7bf593cb3c41f703329ba2d90e2416b5f407ed858db69776d02eb9bb3c93025d094de6f4413fd368f933a7398
6
+ metadata.gz: 201861185888f275b0c7690887cca60a76d0bb90955c514ba4336e23f2adb9907d305f5e930b08f03c3c388d81bfd40996cd54c0f854035aab5a60703c40f954
7
+ data.tar.gz: b37cc2ed827560a2365b77af0921c0240498dcb287e1a1ba064f0879a748c2d365f0e61cec610233b11521206ab402e83aebbdec5c897a21eb3e9f7313fba602
@@ -59,6 +59,8 @@ jobs:
59
59
  run: |
60
60
  bundle exec overcommit --sign
61
61
  SOLARGRAPH_ASSERTS=on bundle exec overcommit --run --diff origin/master
62
+ # @todo Temporary, expect to revert in 0.60
63
+ continue-on-error: true
62
64
  rubocop:
63
65
  name: rubocop
64
66
  runs-on: ubuntu-latest
@@ -95,6 +97,8 @@ jobs:
95
97
 
96
98
  - name: Run rbs validate
97
99
  run: bundle exec rbs validate
100
+ # @todo Temporary, expect to revert in 0.60
101
+ continue-on-error: true
98
102
  rubocop_todo:
99
103
  name: .rubocop_todo.yml
100
104
  runs-on: ubuntu-latest
@@ -112,6 +116,8 @@ jobs:
112
116
 
113
117
  - name: Run RuboCop
114
118
  run: bundle exec rubocop -c .rubocop.yml
119
+ # @todo Temporary, expect to revert in 0.60
120
+ continue-on-error: true
115
121
 
116
122
  - name: Run RuboCop against todo file
117
123
  continue-on-error: true
@@ -45,6 +45,8 @@ jobs:
45
45
  run: bundle exec rbs collection update
46
46
  - name: Ensure typechecking still works
47
47
  run: bundle exec solargraph typecheck --level strong
48
+ # @todo Temporary, expect to revert in 0.60
49
+ continue-on-error: true
48
50
  - name: Ensure specs still run
49
51
  run: bundle exec rake spec
50
52
  rails:
@@ -78,6 +80,8 @@ jobs:
78
80
  run: bundle exec rbs collection update
79
81
  - name: Ensure typechecking still works
80
82
  run: bundle exec solargraph typecheck --level strong
83
+ # @todo Temporary, expect to revert in 0.60
84
+ continue-on-error: true
81
85
  - name: Ensure specs still run
82
86
  run: bundle exec rake spec
83
87
  rspec:
@@ -109,6 +113,8 @@ jobs:
109
113
  run: bundle exec rbs collection update
110
114
  - name: Ensure typechecking still works
111
115
  run: bundle exec solargraph typecheck --level strong
116
+ # @todo Temporary, expect to revert in 0.60
117
+ continue-on-error: true
112
118
  - name: Ensure specs still run
113
119
  run: bundle exec rake spec
114
120
 
@@ -229,3 +235,5 @@ jobs:
229
235
  ALLOW_IMPROVEMENTS=true bundle exec rake spec
230
236
  env:
231
237
  MATRIX_RAILS_VERSION: "7.0"
238
+ # @todo Temporary, expect to revert in 0.60
239
+ continue-on-error: true
@@ -21,7 +21,10 @@ jobs:
21
21
  runs-on: ubuntu-latest
22
22
  strategy:
23
23
  matrix:
24
- ruby-version: ['3.1', '3.2', '3.3', '3.4', '4.0', 'head']
24
+ # @todo Restore 'head' once ruby/setup-ruby publishes it for ubuntu-24.04.
25
+ # It currently 404s ("Unavailable version head for ruby"), failing CI:
26
+ # https://github.com/castwide/solargraph/actions/runs/25863741955/job/76000137015?pr=1187
27
+ ruby-version: ['3.1', '3.2', '3.3', '3.4', '4.0']
25
28
  rbs-version: ['3.10.0', '4.0.0', '4.0.1', '4.0.2']
26
29
  exclude:
27
30
  - ruby-version: '3.1'
@@ -38,3 +38,5 @@ jobs:
38
38
  run: bundle exec rbs collection install
39
39
  - name: Typecheck self
40
40
  run: SOLARGRAPH_ASSERTS=on bundle exec solargraph typecheck --level strong
41
+ # @todo Temporary, expect to revert in 0.60
42
+ continue-on-error: true
data/.rubocop.yml CHANGED
@@ -17,6 +17,7 @@ AllCops:
17
17
  - "spec/fixtures/invalid_byte.rb"
18
18
  - "spec/fixtures/invalid_node_comment.rb"
19
19
  - "spec/fixtures/invalid_utf8.rb"
20
+ - "spec/fixtures/gem-with-yard-macros/**/*"
20
21
  - "vendor/**/*"
21
22
  - "vendor/**/.*"
22
23
  TargetRubyVersion: 3.1
data/.rubocop_todo.yml CHANGED
@@ -118,7 +118,7 @@ Metrics/MethodLength:
118
118
 
119
119
  # Configuration parameters: CountComments, CountAsOne.
120
120
  Metrics/ModuleLength:
121
- Max: 167
121
+ Max: 195
122
122
 
123
123
  # Configuration parameters: Max, CountKeywordArgs, MaxOptionalParameters.
124
124
  Metrics/ParameterLists:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ ## 0.60.0 - June 15, 2026
2
+ - Add YARD macro support for DSL methods (#1187)
3
+ - YARD macros - More typecheck fixes (#1188)
4
+ - Macro fixes (#1189)
5
+ - Unused macro methods (#1191)
6
+ - Transitive macros (#1203)
7
+ - Allow CTRL-C interruption of profile command + macro debug logs (#1206)
8
+ - Support for Inline RBS (#1173)
9
+ - Make typechecker errors vim quickfix friendly (#1072)
10
+ - Generate RBS (#812)
11
+
12
+ ## 0.59.2 - May 22, 2026
13
+ - Convert RBS implicit nil annotations (#1197)
14
+ - Temporary job stubs (#1200)
15
+ - Limit pin combination to doc maps (#1195)
16
+ - Ignore literal values in type inference (#1201)
17
+ - Fix for clips with flaky node recipients
18
+
1
19
  ## 0.59.1 - May 18, 2026
2
20
  - Fix signatureHelp bug (#1185)
3
21
  - Linting fixes for Ruby 3.1 (#1193)
data/Gemfile CHANGED
@@ -4,6 +4,9 @@ source 'https://rubygems.org'
4
4
 
5
5
  gemspec name: 'solargraph'
6
6
 
7
+ # Test fixture gems
8
+ gem 'gem-with-yard-macros', path: 'spec/fixtures/gem-with-yard-macros'
9
+
7
10
  # Local gemfile for development tools, etc.
8
11
  local_gemfile = File.expand_path('.Gemfile', __dir__)
9
12
  instance_eval File.read local_gemfile if File.exist? local_gemfile
@@ -5,6 +5,12 @@ module Solargraph
5
5
  class Index
6
6
  include Logging
7
7
 
8
+ # @return [Array<String>]
9
+ attr_reader :macro_method_names
10
+
11
+ # @return [Hash{String => Array<Pin::Method>}]
12
+ attr_reader :macro_method_name_pins
13
+
8
14
  # @param pins [Array<Pin::Base>]
9
15
  def initialize pins = []
10
16
  catalog pins
@@ -95,16 +101,18 @@ module Solargraph
95
101
  protected
96
102
 
97
103
  attr_writer :pins, :pin_select_cache, :namespace_hash, :pin_class_hash, :path_pin_hash, :include_references,
98
- :extend_references, :prepend_references, :superclass_references
104
+ :extend_references, :prepend_references, :superclass_references, :macro_method_names,
105
+ :macro_method_name_pins
99
106
 
100
107
  # @return [self]
101
108
  def deep_clone
102
109
  Index.allocate.tap do |copy|
103
110
  copy.pin_select_cache = {}
104
111
  copy.pins = pins.clone
112
+ copy.macro_method_names = macro_method_names
105
113
  %i[
106
114
  namespace_hash pin_class_hash path_pin_hash include_references extend_references prepend_references
107
- superclass_references
115
+ superclass_references macro_method_name_pins
108
116
  ].each do |sym|
109
117
  copy.send("#{sym}=", send(sym).clone)
110
118
  copy.send(sym)&.transform_values!(&:clone)
@@ -137,6 +145,9 @@ module Solargraph
137
145
  map_references Pin::Reference::Prepend, prepend_references
138
146
  map_references Pin::Reference::Extend, extend_references
139
147
  map_references Pin::Reference::Superclass, superclass_references
148
+ macro_pins = pins_by_class(Pin::Method).select { |pin| pin.macros.any? }
149
+ @macro_method_names = macro_pins.to_set(&:name)
150
+ @macro_method_name_pins = macro_pins.to_set.classify(&:name)
140
151
  map_overrides
141
152
  pins_by_class(Pin::Reference::TypeAlias).each { |pin| alias_hash[pin.name] = pin.return_type }
142
153
  self
@@ -21,11 +21,11 @@ module Solargraph
21
21
  # - pinsets[0] = core Ruby pins
22
22
  # - pinsets[1] = documentation/gem pins
23
23
  # - pinsets[2] = convention pins
24
- # - pinsets[3] = workspace source pins
24
+ # - pinsets[3] = workspace source pins (aka. "iced_pins")
25
25
  # - pinsets[4] = currently open file pins
26
26
  # @return [Boolean] True if the index was updated
27
- def update *pinsets
28
- return catalog(pinsets) if pinsets.length != @pinsets.length
27
+ def update *pinsets, &block
28
+ return catalog(pinsets, &block) if pinsets.length != @pinsets.length
29
29
 
30
30
  changed = pinsets.find_index.with_index { |pinset, idx| @pinsets[idx] != pinset }
31
31
  return false unless changed
@@ -43,6 +43,9 @@ module Solargraph
43
43
  @indexes[changed + idx - 1].merge(pins)
44
44
  end
45
45
  end
46
+ # @type [Index]
47
+ @index = @indexes.last.clone
48
+ @index = @index.merge(block.call) if block
46
49
  constants.clear
47
50
  cached_qualify_superclass.clear
48
51
  true
@@ -71,10 +74,9 @@ module Solargraph
71
74
  # @param visibility [Array<Symbol>]
72
75
  # @return [Enumerable<Solargraph::Pin::Method>]
73
76
  def get_methods fqns, scope: :instance, visibility: [:public]
74
- all_pins = namespace_children(fqns).select do |pin|
77
+ namespace_children(fqns).select do |pin|
75
78
  pin.is_a?(Pin::Method) && pin.scope == scope && visibility.include?(pin.visibility)
76
79
  end
77
- GemPins.combine_method_pins_by_path(all_pins)
78
80
  end
79
81
 
80
82
  BOOLEAN_SUPERCLASS_PIN = Pin::Reference::Superclass.new(name: 'Boolean', closure: Pin::ROOT_PIN,
@@ -175,7 +177,7 @@ module Solargraph
175
177
  result
176
178
  end
177
179
 
178
- # @return [Hash{String => YARD::Tags::MacroDirective}]
180
+ # @return [Hash{String => YardMap::Macro}]
179
181
  def named_macros
180
182
  @named_macros ||= begin
181
183
  result = {}
@@ -277,17 +279,27 @@ module Solargraph
277
279
  index.alias_hash[name]
278
280
  end
279
281
 
282
+ # @return [Array<String>]
283
+ def macro_method_names
284
+ index.macro_method_names
285
+ end
286
+
287
+ # @return [Hash{String => Array<Pin::Method>}]
288
+ def macro_method_name_pins
289
+ index.macro_method_name_pins
290
+ end
291
+
280
292
  private
281
293
 
282
294
  # @return [Index]
283
295
  def index
284
- @indexes.last
296
+ @index ||= Index.new
285
297
  end
286
298
 
287
299
  # @param pinsets [Array<Array<Pin::Base>>]
288
300
  #
289
301
  # @return [true]
290
- def catalog pinsets
302
+ def catalog pinsets, &block
291
303
  @pinsets = pinsets
292
304
  # @type [Array<Index>]
293
305
  @indexes = []
@@ -298,6 +310,8 @@ module Solargraph
298
310
  @indexes.push(@indexes.last&.merge(pins) || Solargraph::ApiMap::Index.new(pins))
299
311
  end
300
312
  end
313
+ @index = @indexes.last.clone
314
+ @index = @index.merge(block.call) if block
301
315
  constants.clear
302
316
  cached_qualify_superclass.clear
303
317
  true
@@ -107,6 +107,7 @@ module Solargraph
107
107
  # @return [self]
108
108
  def catalog bench
109
109
  @source_map_hash = bench.source_map_hash
110
+ # @type [Array<Pin::Base>]
110
111
  iced_pins = bench.icebox.flat_map(&:pins)
111
112
  live_pins = bench.live_map&.all_pins || []
112
113
  conventions_environ.clear
@@ -123,11 +124,42 @@ module Solargraph
123
124
  @doc_map = DocMap.new(unresolved_requires, bench.workspace, out: nil) # @todo Implement gem preferences
124
125
  @unresolved_requires = @doc_map.unresolved_requires
125
126
  end
126
- @cache.clear if store.update(@@core_map.pins, @doc_map.pins, conventions_environ.pins, iced_pins, live_pins)
127
+ start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
128
+ Solargraph.logger.info 'Cataloging ApiMap started'
129
+ @cache.clear if store.update(@@core_map.pins, @doc_map.pins, conventions_environ.pins, iced_pins, live_pins) { process_macros }
127
130
  @missing_docs = [] # @todo Implement missing docs
131
+ Solargraph.logger.info "Cataloging ApiMap finished in #{Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time} seconds"
128
132
  self
129
133
  end
130
134
 
135
+ # @return [Array<Pin::Base>]
136
+ def process_macros
137
+ macro_pins = []
138
+ Solargraph.logger.debug { "ApiMap#process_macros: processing macros for #{source_maps.size} source maps" }
139
+ Solargraph.logger.debug { "ApiMap#process_macros: store has #{store.macro_method_name_pins.size} macro method name pins" }
140
+ Solargraph.logger.debug { "ApiMap#process_macros: named macros: #{store.named_macros.keys.join(', ')}" }
141
+ source_maps.each do |source_map|
142
+ method_candidates = source_map.macro_method_candidates(store.macro_method_names)
143
+ Solargraph.logger.debug { "ApiMap#process_macros: processing source map for #{source_map.filename} with #{method_candidates.size} macro method candidates" }
144
+ method_candidates.each do |node|
145
+ closure = source_map.locate_closure_pin(node.location.line, node.location.column)
146
+ chain = Solargraph::Parser::ParserGem::NodeChainer.chain(node)
147
+ if node.children[0].nil? && store.macro_method_name_pins.key?(node.children[1].to_s)
148
+ match = store.macro_method_name_pins[node.children[1].to_s].find do |pin|
149
+ super_and_sub?(pin.namespace, closure.name)
150
+ end
151
+ if match
152
+ match.macros.each do |macro|
153
+ macro_pins.concat macro.generate_pins_from(chain, match, source_map)
154
+ end
155
+ next
156
+ end
157
+ end
158
+ end
159
+ end
160
+ macro_pins
161
+ end
162
+
131
163
  # @return [DocMap]
132
164
  def doc_map
133
165
  @doc_map ||= DocMap.new([], Workspace.new('.'))
@@ -154,7 +186,7 @@ module Solargraph
154
186
  end
155
187
 
156
188
  # @param name [String, nil]
157
- # @return [YARD::Tags::MacroDirective, nil]
189
+ # @return [Solargraph::YardMap::Macro, nil]
158
190
  def named_macro name
159
191
  # @sg-ignore Need to add nil check here
160
192
  store.named_macros[name]
@@ -375,6 +407,9 @@ module Solargraph
375
407
  #
376
408
  # @return [Pin::BaseVariable, nil]
377
409
  def var_at_location candidates, name, closure, location
410
+ # @todo Location can be nil if clips have trouble finding node recipients
411
+ return unless location
412
+
378
413
  with_correct_name = candidates.select { |pin| pin.name == name }
379
414
  vars_at_location = with_correct_name.reject do |pin|
380
415
  # visible_at? excludes the starting position, but we want to
@@ -416,11 +451,6 @@ module Solargraph
416
451
  # @param deep [Boolean] True to include superclasses, mixins, etc.
417
452
  # @return [Array<Solargraph::Pin::Method>]
418
453
  def get_methods rooted_tag, scope: :instance, visibility: [:public], deep: true
419
- if rooted_tag.start_with? 'Array('
420
- # Array() are really tuples - use our fill, as the RBS repo
421
- # does not give us definitions for it
422
- rooted_tag = "Solargraph::Fills::Tuple(#{rooted_tag[6..-2]})"
423
- end
424
454
  rooted_type = ComplexType.try_parse(rooted_tag)
425
455
  fqns = rooted_type.namespace
426
456
  namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first
@@ -721,7 +751,7 @@ module Solargraph
721
751
  logger.debug do
722
752
  "ApiMap#resolve_method_aliases(pins=#{pins.map(&:name)}, visibility=#{visibility}) => #{with_resolved_aliases.map(&:name)}"
723
753
  end
724
- GemPins.combine_method_pins_by_path(with_resolved_aliases)
754
+ with_resolved_aliases
725
755
  end
726
756
 
727
757
  # @return [Workspace, nil]
@@ -59,6 +59,7 @@ module Solargraph
59
59
  end
60
60
 
61
61
  def tuple?
62
+ return false
62
63
  @tuple ||= (name == 'Tuple') || (name == 'Array' && subtypes.length >= 1 && fixed_parameters?)
63
64
  end
64
65
 
@@ -147,6 +147,7 @@ module Solargraph
147
147
  end
148
148
 
149
149
  def literal?
150
+ return false
150
151
  non_literal_name != name
151
152
  end
152
153
 
@@ -228,11 +229,11 @@ module Solargraph
228
229
  # covariant
229
230
  # contravariant?: Proc - can be changed, so we can pass
230
231
  # in less specific super types
231
- if %w[Hash Tuple Array Set Enumerable].include?(name) && fixed_parameters?
232
- :covariant
233
- else
234
- default
235
- end
232
+ # if %w[Hash Tuple Array Set Enumerable].include?(name) && fixed_parameters?
233
+ # :covariant
234
+ # else
235
+ default
236
+ # end
236
237
  end
237
238
 
238
239
  # Whether this is an RBS interface like _ToAry or Hash::_Key.
@@ -374,6 +375,7 @@ module Solargraph
374
375
 
375
376
  # @return [UniqueType]
376
377
  def downcast_to_literal_if_possible
378
+ return self
377
379
  SINGLE_SUBTYPE.fetch(rooted_tag, self)
378
380
  end
379
381
 
@@ -456,15 +458,12 @@ module Solargraph
456
458
  else
457
459
  next ComplexType::UNDEFINED
458
460
  end
459
- elsif context_type.all?(&:implicit_union?)
460
- if idx.zero? && !context_type.all_params.empty?
461
- ComplexType.new(context_type.all_params)
462
- else
463
- ComplexType::UNDEFINED
464
- end
461
+ # @todo Treating parameterized classes and tuples the same for now
462
+ # elsif context_type.all?(&:implicit_union?) || true
463
+ elsif idx.zero? && !context_type.all_params.empty?
464
+ ComplexType.new(context_type.all_params)
465
465
  else
466
- # @sg-ignore Need to add nil check here
467
- context_type.all_params[idx] || definitions.generic_defaults[generic_name] || ComplexType::UNDEFINED
466
+ ComplexType::UNDEFINED
468
467
  end
469
468
  else
470
469
  t
@@ -548,6 +547,10 @@ module Solargraph
548
547
  yield new_type
549
548
  end
550
549
 
550
+ def expand named_types
551
+ named_types[name] || self
552
+ end
553
+
551
554
  # Generate a ComplexType that fully qualifies this type's namespaces.
552
555
  #
553
556
  # @param api_map [ApiMap] The ApiMap that performs qualification
@@ -189,6 +189,7 @@ module Solargraph
189
189
 
190
190
  # @return [ComplexType]
191
191
  def downcast_to_literal_if_possible
192
+ return self
192
193
  ComplexType.new(items.map(&:downcast_to_literal_if_possible))
193
194
  end
194
195
 
@@ -297,6 +298,10 @@ module Solargraph
297
298
  ComplexType.new(map { |ut| ut.transform(new_name, &transform_type) })
298
299
  end
299
300
 
301
+ def expand named_types
302
+ ComplexType.new(map { |ut| ut.expand(named_types) })
303
+ end
304
+
300
305
  # @return [self]
301
306
  def force_rooted
302
307
  transform do |t|