solargraph 0.54.0 → 0.55.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 (105) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +58 -0
  3. data/lib/solargraph/api_map/cache.rb +10 -1
  4. data/lib/solargraph/api_map/index.rb +167 -0
  5. data/lib/solargraph/api_map/store.rb +75 -122
  6. data/lib/solargraph/api_map.rb +109 -41
  7. data/lib/solargraph/bench.rb +17 -1
  8. data/lib/solargraph/complex_type/type_methods.rb +17 -11
  9. data/lib/solargraph/complex_type/unique_type.rb +181 -17
  10. data/lib/solargraph/complex_type.rb +103 -24
  11. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +51 -0
  12. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +100 -0
  13. data/lib/solargraph/convention/struct_definition.rb +101 -0
  14. data/lib/solargraph/convention.rb +2 -0
  15. data/lib/solargraph/doc_map.rb +43 -18
  16. data/lib/solargraph/equality.rb +33 -0
  17. data/lib/solargraph/language_server/host/message_worker.rb +51 -5
  18. data/lib/solargraph/language_server/host.rb +13 -11
  19. data/lib/solargraph/language_server/message/base.rb +19 -12
  20. data/lib/solargraph/language_server/message/initialize.rb +3 -1
  21. data/lib/solargraph/language_server/message/text_document/completion.rb +0 -3
  22. data/lib/solargraph/language_server/message/text_document/definition.rb +3 -3
  23. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +3 -3
  24. data/lib/solargraph/language_server/message/text_document/formatting.rb +4 -0
  25. data/lib/solargraph/language_server/message/text_document/hover.rb +1 -1
  26. data/lib/solargraph/language_server/message/text_document/type_definition.rb +3 -3
  27. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -2
  28. data/lib/solargraph/language_server/progress.rb +19 -2
  29. data/lib/solargraph/library.rb +31 -41
  30. data/lib/solargraph/location.rb +29 -1
  31. data/lib/solargraph/parser/comment_ripper.rb +11 -6
  32. data/lib/solargraph/parser/flow_sensitive_typing.rb +226 -0
  33. data/lib/solargraph/parser/node_methods.rb +15 -1
  34. data/lib/solargraph/parser/parser_gem/class_methods.rb +11 -6
  35. data/lib/solargraph/parser/parser_gem/node_chainer.rb +10 -10
  36. data/lib/solargraph/parser/parser_gem/node_methods.rb +6 -4
  37. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +21 -0
  38. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +23 -19
  39. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +21 -1
  40. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +21 -0
  41. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +8 -2
  42. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +26 -5
  43. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +41 -0
  44. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +1 -1
  45. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +28 -0
  46. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +28 -0
  47. data/lib/solargraph/parser/parser_gem/node_processors.rb +10 -0
  48. data/lib/solargraph/parser.rb +3 -5
  49. data/lib/solargraph/pin/base.rb +47 -17
  50. data/lib/solargraph/pin/base_variable.rb +11 -4
  51. data/lib/solargraph/pin/block.rb +8 -26
  52. data/lib/solargraph/pin/breakable.rb +9 -0
  53. data/lib/solargraph/pin/callable.rb +147 -0
  54. data/lib/solargraph/pin/closure.rb +8 -3
  55. data/lib/solargraph/pin/common.rb +2 -6
  56. data/lib/solargraph/pin/conversions.rb +3 -2
  57. data/lib/solargraph/pin/instance_variable.rb +2 -2
  58. data/lib/solargraph/pin/local_variable.rb +7 -1
  59. data/lib/solargraph/pin/method.rb +76 -48
  60. data/lib/solargraph/pin/namespace.rb +14 -11
  61. data/lib/solargraph/pin/parameter.rb +24 -17
  62. data/lib/solargraph/pin/proxy_type.rb +13 -7
  63. data/lib/solargraph/pin/signature.rb +3 -129
  64. data/lib/solargraph/pin/until.rb +18 -0
  65. data/lib/solargraph/pin/while.rb +18 -0
  66. data/lib/solargraph/pin.rb +7 -1
  67. data/lib/solargraph/position.rb +7 -0
  68. data/lib/solargraph/range.rb +9 -4
  69. data/lib/solargraph/rbs_map/conversions.rb +84 -45
  70. data/lib/solargraph/rbs_map/core_fills.rb +16 -9
  71. data/lib/solargraph/rbs_map.rb +1 -0
  72. data/lib/solargraph/shell.rb +19 -2
  73. data/lib/solargraph/source/chain/array.rb +10 -8
  74. data/lib/solargraph/source/chain/block_symbol.rb +1 -1
  75. data/lib/solargraph/source/chain/block_variable.rb +1 -1
  76. data/lib/solargraph/source/chain/call.rb +125 -61
  77. data/lib/solargraph/source/chain/constant.rb +1 -1
  78. data/lib/solargraph/source/chain/hash.rb +8 -2
  79. data/lib/solargraph/source/chain/if.rb +5 -0
  80. data/lib/solargraph/source/chain/link.rb +28 -5
  81. data/lib/solargraph/source/chain/literal.rb +27 -2
  82. data/lib/solargraph/source/chain/or.rb +1 -1
  83. data/lib/solargraph/source/chain/z_super.rb +1 -1
  84. data/lib/solargraph/source/chain.rb +131 -63
  85. data/lib/solargraph/source/cursor.rb +3 -2
  86. data/lib/solargraph/source/source_chainer.rb +2 -2
  87. data/lib/solargraph/source.rb +104 -86
  88. data/lib/solargraph/source_map/clip.rb +8 -6
  89. data/lib/solargraph/source_map/data.rb +30 -0
  90. data/lib/solargraph/source_map.rb +28 -16
  91. data/lib/solargraph/type_checker/checks.rb +4 -0
  92. data/lib/solargraph/type_checker/rules.rb +6 -1
  93. data/lib/solargraph/type_checker.rb +48 -21
  94. data/lib/solargraph/version.rb +1 -1
  95. data/lib/solargraph/views/environment.erb +3 -5
  96. data/lib/solargraph/workspace/config.rb +7 -3
  97. data/lib/solargraph/workspace.rb +1 -1
  98. data/lib/solargraph/yard_map/mapper/to_constant.rb +1 -0
  99. data/lib/solargraph/yard_map/mapper/to_method.rb +42 -15
  100. data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -0
  101. data/lib/solargraph/yard_map/mapper.rb +1 -0
  102. data/lib/solargraph/yardoc.rb +1 -1
  103. data/lib/solargraph.rb +1 -0
  104. data/solargraph.gemspec +5 -5
  105. metadata +41 -25
@@ -5,13 +5,14 @@ require 'yard'
5
5
  require 'solargraph/yard_tags'
6
6
 
7
7
  module Solargraph
8
- # An aggregate provider for information about workspaces, sources, gems, and
8
+ # An aggregate provider for information about Workspaces, Sources, gems, and
9
9
  # the Ruby core.
10
10
  #
11
11
  class ApiMap
12
12
  autoload :Cache, 'solargraph/api_map/cache'
13
13
  autoload :SourceToYard, 'solargraph/api_map/source_to_yard'
14
14
  autoload :Store, 'solargraph/api_map/store'
15
+ autoload :Index, 'solargraph/api_map/index'
15
16
 
16
17
  # @return [Array<String>]
17
18
  attr_reader :unresolved_requires
@@ -48,6 +49,15 @@ module Solargraph
48
49
  equality_fields.hash
49
50
  end
50
51
 
52
+ def to_s
53
+ self.class.to_s
54
+ end
55
+
56
+ # avoid enormous dump
57
+ def inspect
58
+ to_s
59
+ end
60
+
51
61
  # @param pins [Array<Pin::Base>]
52
62
  # @return [self]
53
63
  def index pins
@@ -56,7 +66,7 @@ module Solargraph
56
66
  @source_map_hash = {}
57
67
  implicit.clear
58
68
  cache.clear
59
- @store = Store.new(@@core_map.pins + pins)
69
+ store.update @@core_map.pins, pins
60
70
  self
61
71
  end
62
72
 
@@ -75,10 +85,9 @@ module Solargraph
75
85
  # @param bench [Bench]
76
86
  # @return [self]
77
87
  def catalog bench
78
- old_api_hash = @source_map_hash&.values&.map(&:api_hash)
79
- need_to_uncache = (old_api_hash != bench.source_maps.map(&:api_hash))
80
- @source_map_hash = bench.source_maps.map { |s| [s.filename, s] }.to_h
81
- pins = bench.source_maps.flat_map(&:pins).flatten
88
+ @source_map_hash = bench.source_map_hash
89
+ iced_pins = bench.icebox.flat_map(&:pins)
90
+ live_pins = bench.live_map&.pins || []
82
91
  implicit.clear
83
92
  source_map_hash.each_value do |map|
84
93
  implicit.merge map.environ
@@ -87,17 +96,17 @@ module Solargraph
87
96
  if @unresolved_requires != unresolved_requires || @doc_map&.uncached_gemspecs&.any?
88
97
  @doc_map = DocMap.new(unresolved_requires, [], bench.workspace.rbs_collection_path) # @todo Implement gem preferences
89
98
  @unresolved_requires = unresolved_requires
90
- need_to_uncache = true
91
99
  end
92
- @store = Store.new(@@core_map.pins + @doc_map.pins + implicit.pins + pins)
93
- @cache.clear if need_to_uncache
94
-
100
+ @cache.clear if store.update(@@core_map.pins, @doc_map.pins, implicit.pins, iced_pins, live_pins)
95
101
  @missing_docs = [] # @todo Implement missing docs
96
102
  self
97
103
  end
98
104
 
105
+ # @todo need to model type def statement in chains as a symbol so
106
+ # that this overload of 'protected' will typecheck @sg-ignore
107
+ # @sg-ignore
99
108
  protected def equality_fields
100
- [self.class, @source_map_hash, implicit, @doc_map, @unresolved_requires, @missing_docs]
109
+ [self.class, @source_map_hash, implicit, @doc_map, @unresolved_requires]
101
110
  end
102
111
 
103
112
  # @return [::Array<Gem::Specification>]
@@ -183,7 +192,7 @@ module Solargraph
183
192
 
184
193
  # @return [Array<Solargraph::Pin::Base>]
185
194
  def pins
186
- store.pins
195
+ store.pins.clone.freeze
187
196
  end
188
197
 
189
198
  # An array of pins based on Ruby keywords (`if`, `end`, etc.).
@@ -250,16 +259,22 @@ module Solargraph
250
259
  # @param tag [String, nil] The namespace to
251
260
  # match, complete with generic parameters set to appropriate
252
261
  # values if available
253
- # @param context_tag [String] The context in which the tag was
254
- # referenced; start from here to resolve the name
262
+ # @param context_tag [String] The fully qualified context in which
263
+ # the tag was referenced; start from here to resolve the name.
264
+ # Should not be prefixed with '::'.
255
265
  # @return [String, nil] fully qualified tag
256
266
  def qualify tag, context_tag = ''
257
- return tag if ['self', nil].include?(tag)
258
- context_type = ComplexType.try_parse(context_tag)
267
+ return tag if ['Boolean', 'self', nil].include?(tag)
268
+
269
+ context_type = ComplexType.try_parse(context_tag).force_rooted
259
270
  return unless context_type
260
271
 
261
272
  type = ComplexType.try_parse(tag)
262
273
  return unless type
274
+ return tag if type.literal?
275
+
276
+ context_type = ComplexType.try_parse(context_tag)
277
+ return unless context_type
263
278
 
264
279
  fqns = qualify_namespace(type.rooted_namespace, context_type.rooted_namespace)
265
280
  return unless fqns
@@ -308,6 +323,11 @@ module Solargraph
308
323
  result
309
324
  end
310
325
 
326
+ # @see Solargraph::Parser::FlowSensitiveTyping#visible_pins
327
+ def visible_pins(*args, **kwargs, &blk)
328
+ Solargraph::Parser::FlowSensitiveTyping.visible_pins(*args, **kwargs, &blk)
329
+ end
330
+
311
331
  # Get an array of class variable pins for a namespace.
312
332
  #
313
333
  # @param namespace [String] A fully qualified namespace
@@ -326,6 +346,11 @@ module Solargraph
326
346
  store.pins_by_class(Pin::GlobalVariable)
327
347
  end
328
348
 
349
+ # @return [Enumerable<Solargraph::Pin::Block>]
350
+ def get_block_pins
351
+ store.pins_by_class(Pin::Block)
352
+ end
353
+
329
354
  # Get an array of methods available in a particular context.
330
355
  #
331
356
  # @param rooted_tag [String] The fully qualified namespace to search for methods
@@ -334,8 +359,12 @@ module Solargraph
334
359
  # @param deep [Boolean] True to include superclasses, mixins, etc.
335
360
  # @return [Array<Solargraph::Pin::Method>]
336
361
  def get_methods rooted_tag, scope: :instance, visibility: [:public], deep: true
362
+ rooted_type = ComplexType.try_parse(rooted_tag)
363
+ fqns = rooted_type.namespace
364
+ namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first
337
365
  cached = cache.get_methods(rooted_tag, scope, visibility, deep)
338
366
  return cached.clone unless cached.nil?
367
+ # @type [Array<Solargraph::Pin::Method>]
339
368
  result = []
340
369
  skip = Set.new
341
370
  if rooted_tag == ''
@@ -356,7 +385,7 @@ module Solargraph
356
385
  init_pin = get_method_stack(rooted_tag, 'initialize').first
357
386
  next pin unless init_pin
358
387
 
359
- type = ComplexType.try_parse(ComplexType.try_parse(rooted_tag).namespace)
388
+ type = ComplexType::SELF
360
389
  Pin::Method.new(
361
390
  name: 'new',
362
391
  scope: :class,
@@ -365,17 +394,21 @@ module Solargraph
365
394
  signatures: init_pin.signatures.map { |sig| sig.proxy(type) },
366
395
  return_type: type,
367
396
  comments: init_pin.comments,
368
- closure: init_pin.closure
369
- # @todo Hack to force TypeChecker#internal_or_core?
370
- ).tap { |pin| pin.source = :rbs }
397
+ closure: init_pin.closure,
398
+ source: init_pin.source,
399
+ type_location: init_pin.type_location,
400
+ )
371
401
  end
372
402
  end
373
403
  result.concat inner_get_methods('Kernel', :instance, [:public], deep, skip) if visibility.include?(:private)
374
404
  result.concat inner_get_methods('Module', scope, visibility, deep, skip) if scope == :module
375
405
  end
376
- resolved = resolve_method_aliases(result, visibility)
377
- cache.set_methods(rooted_tag, scope, visibility, deep, resolved)
378
- resolved
406
+ result = resolve_method_aliases(result, visibility)
407
+ if namespace_pin && rooted_tag != rooted_type.name
408
+ result = result.map { |method_pin| method_pin.resolve_generics(namespace_pin, rooted_type) }
409
+ end
410
+ cache.set_methods(rooted_tag, scope, visibility, deep, result)
411
+ result
379
412
  end
380
413
 
381
414
  # Get an array of method pins for a complex type.
@@ -431,8 +464,13 @@ module Solargraph
431
464
  # @param name [String] Method name to look up
432
465
  # @param scope [Symbol] :instance or :class
433
466
  # @return [Array<Solargraph::Pin::Method>]
434
- def get_method_stack rooted_tag, name, scope: :instance
435
- get_methods(rooted_tag, scope: scope, visibility: [:private, :protected, :public]).select { |p| p.name == name }
467
+ def get_method_stack rooted_tag, name, scope: :instance, visibility: [:private, :protected, :public], preserve_generics: false
468
+ rooted_type = ComplexType.parse(rooted_tag)
469
+ fqns = rooted_type.namespace
470
+ namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first
471
+ methods = get_methods(rooted_tag, scope: scope, visibility: visibility).select { |p| p.name == name }
472
+ methods = erase_generics(namespace_pin, rooted_type, methods) unless preserve_generics
473
+ methods
436
474
  end
437
475
 
438
476
  # Get an array of all suggestions that match the specified path.
@@ -591,9 +629,10 @@ module Solargraph
591
629
  # @param no_core [Boolean] Skip core classes if true
592
630
  # @return [Array<Pin::Base>]
593
631
  def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false
594
- rooted_type = ComplexType.parse(rooted_tag)
632
+ rooted_type = ComplexType.parse(rooted_tag).force_rooted
595
633
  fqns = rooted_type.namespace
596
634
  fqns_generic_params = rooted_type.all_params
635
+ namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first
597
636
  return [] if no_core && fqns =~ /^(Object|BasicObject|Class|Module)$/
598
637
  reqstr = "#{fqns}|#{scope}|#{visibility.sort}|#{deep}"
599
638
  return [] if skip.include?(reqstr)
@@ -608,15 +647,7 @@ module Solargraph
608
647
  # Store#get_methods doesn't know about full tags, just
609
648
  # namespaces; resolving the generics in the method pins is this
610
649
  # class' responsibility
611
- raw_methods = store.get_methods(fqns, scope: scope, visibility: visibility).sort{ |a, b| a.name <=> b.name }
612
- namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first
613
- methods = if namespace_pin && rooted_tag != fqns
614
- methods = raw_methods.map do |method_pin|
615
- method_pin.resolve_generics(namespace_pin, rooted_type)
616
- end
617
- else
618
- raw_methods
619
- end
650
+ methods = store.get_methods(fqns, scope: scope, visibility: visibility).sort{ |a, b| a.name <=> b.name }
620
651
  result.concat methods
621
652
  if deep
622
653
  if scope == :instance
@@ -629,7 +660,7 @@ module Solargraph
629
660
  # @todo perform the same translation in the other areas
630
661
  # here after adding a spec and handling things correctly
631
662
  # in ApiMap::Store and RbsMap::Conversions
632
- resolved_include_type = ComplexType.parse(rooted_include_tag).resolve_generics(namespace_pin, rooted_type)
663
+ resolved_include_type = ComplexType.parse(rooted_include_tag).force_rooted.resolve_generics(namespace_pin, rooted_type)
633
664
  methods = inner_get_methods(resolved_include_type.tag, scope, visibility, deep, skip, true)
634
665
  result.concat methods
635
666
  end
@@ -690,7 +721,7 @@ module Solargraph
690
721
 
691
722
  # @param namespace [String]
692
723
  # @param context [String]
693
- # @return [String]
724
+ # @return [String, nil]
694
725
  def qualify_lower namespace, context
695
726
  qualify namespace, context.split('::')[0..-2].join('::')
696
727
  end
@@ -761,8 +792,8 @@ module Solargraph
761
792
 
762
793
  # Sort an array of pins to put nil or undefined variables last.
763
794
  #
764
- # @param pins [Enumerable<Solargraph::Pin::Base>]
765
- # @return [Enumerable<Solargraph::Pin::Base>]
795
+ # @param pins [Enumerable<Pin::BaseVariable>]
796
+ # @return [Enumerable<Pin::BaseVariable>]
766
797
  def prefer_non_nil_variables pins
767
798
  result = []
768
799
  nil_pins = []
@@ -793,7 +824,7 @@ module Solargraph
793
824
  return pin unless pin.is_a?(Pin::MethodAlias)
794
825
  return nil if @method_alias_stack.include?(pin.path)
795
826
  @method_alias_stack.push pin.path
796
- origin = get_method_stack(pin.full_context.tag, pin.original, scope: pin.scope).first
827
+ origin = get_method_stack(pin.full_context.tag, pin.original, scope: pin.scope, preserve_generics: true).first
797
828
  @method_alias_stack.pop
798
829
  return nil if origin.nil?
799
830
  args = {
@@ -802,11 +833,48 @@ module Solargraph
802
833
  name: pin.name,
803
834
  comments: origin.comments,
804
835
  scope: origin.scope,
836
+ # context: pin.context,
805
837
  visibility: origin.visibility,
806
838
  signatures: origin.signatures,
807
- attribute: origin.attribute?
839
+ attribute: origin.attribute?,
840
+ generics: origin.generics,
841
+ return_type: origin.return_type,
808
842
  }
809
843
  Pin::Method.new **args
810
844
  end
845
+
846
+ include Logging
847
+
848
+ private
849
+
850
+ # @param namespace_pin [Pin::Namespace]
851
+ # @param rooted_type [ComplexType]
852
+ # @param pins [Enumerable<Pin::Base>]
853
+ # @return [Array<Pin::Base>]
854
+ def erase_generics(namespace_pin, rooted_type, pins)
855
+ return pins unless should_erase_generics_when_done?(namespace_pin, rooted_type)
856
+
857
+ logger.debug("Erasing generics on namespace_pin=#{namespace_pin} / rooted_type=#{rooted_type}")
858
+ pins.map do |method_pin|
859
+ method_pin.erase_generics(namespace_pin.generics)
860
+ end
861
+ end
862
+
863
+ # @param namespace_pin [Pin::Namespace]
864
+ # @param rooted_type [ComplexType]
865
+ def should_erase_generics_when_done?(namespace_pin, rooted_type)
866
+ has_generics?(namespace_pin) && !can_resolve_generics?(namespace_pin, rooted_type)
867
+ end
868
+
869
+ # @param namespace_pin [Pin::Namespace]
870
+ def has_generics?(namespace_pin)
871
+ namespace_pin && !namespace_pin.generics.empty?
872
+ end
873
+
874
+ # @param namespace_pin [Pin::Namespace]
875
+ # @param rooted_type [ComplexType]
876
+ def can_resolve_generics?(namespace_pin, rooted_type)
877
+ has_generics?(namespace_pin) && !rooted_type.all_params.empty?
878
+ end
811
879
  end
812
880
  end
@@ -11,18 +11,34 @@ module Solargraph
11
11
  # @return [Workspace]
12
12
  attr_reader :workspace
13
13
 
14
+ # @return [SourceMap]
15
+ attr_reader :live_map
16
+
14
17
  # @return [Set<String>]
15
18
  attr_reader :external_requires
16
19
 
17
20
  # @param source_maps [Array<SourceMap>, Set<SourceMap>]
18
21
  # @param workspace [Workspace]
22
+ # @param live_map [SourceMap, nil]
19
23
  # @param external_requires [Array<String>, Set<String>]
20
- def initialize source_maps: [], workspace: Workspace.new, external_requires: []
24
+ def initialize source_maps: [], workspace: Workspace.new, live_map: nil, external_requires: []
21
25
  @source_maps = source_maps.to_set
22
26
  @workspace = workspace
27
+ @live_map = live_map
23
28
  @external_requires = external_requires.reject { |path| workspace.would_require?(path) }
24
29
  .compact
25
30
  .to_set
26
31
  end
32
+
33
+ # @return [Hash{String => SourceMap}]
34
+ def source_map_hash
35
+ # @todo Work around #to_h bug in current Ruby head (3.5) with #map#to_h
36
+ @source_map_hash ||= source_maps.map { |s| [s.filename, s] }
37
+ .to_h
38
+ end
39
+
40
+ def icebox
41
+ @icebox ||= (source_maps - [live_map])
42
+ end
27
43
  end
28
44
  end
@@ -12,12 +12,20 @@ module Solargraph
12
12
  # @rooted: boolish
13
13
  # methods:
14
14
  # transform()
15
+ # all_params()
16
+ # rooted?()
17
+ # can_root_name?()
15
18
  module TypeMethods
16
19
  # @!method transform(new_name = nil, &transform_type)
17
20
  # @param new_name [String, nil]
18
21
  # @yieldparam t [UniqueType]
19
22
  # @yieldreturn [UniqueType]
20
23
  # @return [UniqueType, nil]
24
+ # @!method all_params
25
+ # @return [Array<ComplexType>]
26
+ # @!method rooted?
27
+ # @!method can_root_name?(name_to_check = nil)
28
+ # @param name_to_check [String, nil]
21
29
 
22
30
  # @return [String]
23
31
  attr_reader :name
@@ -45,11 +53,6 @@ module Solargraph
45
53
  @nil_type ||= (name.casecmp('nil') == 0)
46
54
  end
47
55
 
48
- # @return [Boolean]
49
- def parameters?
50
- !substring.empty?
51
- end
52
-
53
56
  def tuple?
54
57
  @tuple_type ||= (name == 'Tuple') || (name == 'Array' && subtypes.length >= 1 && fixed_parameters?)
55
58
  end
@@ -126,15 +129,22 @@ module Solargraph
126
129
  end.call
127
130
  end
128
131
 
132
+ def namespace_type
133
+ return ComplexType.parse('::Object') if duck_type?
134
+ return ComplexType.parse('::NilClass') if nil_type?
135
+ return subtypes.first if (name == 'Class' || name == 'Module') && !subtypes.empty?
136
+ self
137
+ end
138
+
129
139
  # @return [String]
130
140
  def rooted_namespace
131
- return namespace unless rooted?
141
+ return namespace unless rooted? && can_root_name?(namespace)
132
142
  "::#{namespace}"
133
143
  end
134
144
 
135
145
  # @return [String]
136
146
  def rooted_name
137
- return name unless rooted?
147
+ return name unless @rooted && can_root_name?
138
148
  "::#{name}"
139
149
  end
140
150
 
@@ -177,10 +187,6 @@ module Solargraph
177
187
  tag == other.tag
178
188
  end
179
189
 
180
- def rooted?
181
- @rooted
182
- end
183
-
184
190
  # Generate a ComplexType that fully qualifies this type's namespaces.
185
191
  #
186
192
  # @param api_map [ApiMap] The ApiMap that performs qualification