solargraph 0.57.0 → 0.58.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 (98) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/linting.yml +4 -2
  3. data/.github/workflows/plugins.yml +61 -27
  4. data/.github/workflows/rspec.yml +19 -4
  5. data/.github/workflows/typecheck.yml +2 -2
  6. data/.rubocop.yml +1 -1
  7. data/.rubocop_todo.yml +90 -1438
  8. data/CHANGELOG.md +27 -0
  9. data/Rakefile +1 -1
  10. data/bin/solargraph +8 -5
  11. data/lib/solargraph/api_map/constants.rb +107 -46
  12. data/lib/solargraph/api_map/index.rb +32 -8
  13. data/lib/solargraph/api_map/source_to_yard.rb +5 -2
  14. data/lib/solargraph/api_map/store.rb +22 -12
  15. data/lib/solargraph/api_map.rb +27 -33
  16. data/lib/solargraph/complex_type/type_methods.rb +5 -0
  17. data/lib/solargraph/complex_type/unique_type.rb +12 -5
  18. data/lib/solargraph/complex_type.rb +19 -2
  19. data/lib/solargraph/convention/active_support_concern.rb +1 -1
  20. data/lib/solargraph/convention/data_definition/data_definition_node.rb +1 -1
  21. data/lib/solargraph/diagnostics/rubocop_helpers.rb +4 -2
  22. data/lib/solargraph/doc_map.rb +9 -6
  23. data/lib/solargraph/environ.rb +1 -1
  24. data/lib/solargraph/equality.rb +1 -0
  25. data/lib/solargraph/gem_pins.rb +4 -0
  26. data/lib/solargraph/language_server/host.rb +10 -4
  27. data/lib/solargraph/language_server/message/text_document/definition.rb +2 -2
  28. data/lib/solargraph/language_server/message/text_document/formatting.rb +4 -1
  29. data/lib/solargraph/language_server/message/text_document/type_definition.rb +1 -1
  30. data/lib/solargraph/language_server/progress.rb +1 -1
  31. data/lib/solargraph/language_server/request.rb +3 -1
  32. data/lib/solargraph/library.rb +3 -3
  33. data/lib/solargraph/location.rb +1 -0
  34. data/lib/solargraph/page.rb +0 -1
  35. data/lib/solargraph/parser/flow_sensitive_typing.rb +1 -1
  36. data/lib/solargraph/parser/parser_gem/class_methods.rb +2 -12
  37. data/lib/solargraph/parser/parser_gem/node_methods.rb +1 -14
  38. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +1 -0
  39. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +64 -8
  40. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +12 -3
  41. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +4 -5
  42. data/lib/solargraph/pin/base.rb +29 -8
  43. data/lib/solargraph/pin/base_variable.rb +5 -3
  44. data/lib/solargraph/pin/block.rb +3 -2
  45. data/lib/solargraph/pin/callable.rb +6 -2
  46. data/lib/solargraph/pin/closure.rb +3 -7
  47. data/lib/solargraph/pin/delegated_method.rb +0 -1
  48. data/lib/solargraph/pin/local_variable.rb +0 -4
  49. data/lib/solargraph/pin/method.rb +20 -4
  50. data/lib/solargraph/pin/parameter.rb +6 -2
  51. data/lib/solargraph/pin/proxy_type.rb +4 -1
  52. data/lib/solargraph/pin/reference.rb +2 -11
  53. data/lib/solargraph/pin/search.rb +3 -0
  54. data/lib/solargraph/pin_cache.rb +5 -5
  55. data/lib/solargraph/position.rb +1 -0
  56. data/lib/solargraph/range.rb +4 -0
  57. data/lib/solargraph/rbs_map/conversions.rb +22 -1
  58. data/lib/solargraph/rbs_map/core_fills.rb +18 -0
  59. data/lib/solargraph/rbs_map/core_map.rb +11 -7
  60. data/lib/solargraph/rbs_map.rb +2 -2
  61. data/lib/solargraph/shell.rb +82 -1
  62. data/lib/solargraph/source/chain/call.rb +7 -3
  63. data/lib/solargraph/source/chain/constant.rb +3 -66
  64. data/lib/solargraph/source/chain/if.rb +1 -1
  65. data/lib/solargraph/source/chain/link.rb +1 -1
  66. data/lib/solargraph/source/chain/or.rb +1 -1
  67. data/lib/solargraph/source/chain.rb +2 -0
  68. data/lib/solargraph/source.rb +1 -1
  69. data/lib/solargraph/source_map/clip.rb +17 -25
  70. data/lib/solargraph/source_map/mapper.rb +0 -2
  71. data/lib/solargraph/source_map.rb +8 -3
  72. data/lib/solargraph/type_checker/rules.rb +23 -9
  73. data/lib/solargraph/type_checker.rb +133 -71
  74. data/lib/solargraph/version.rb +1 -1
  75. data/lib/solargraph/workspace/config.rb +21 -3
  76. data/lib/solargraph/workspace/require_paths.rb +0 -1
  77. data/lib/solargraph/workspace.rb +14 -19
  78. data/lib/solargraph/yard_map/mapper/to_method.rb +2 -1
  79. data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -0
  80. data/lib/solargraph/yard_map/to_method.rb +2 -1
  81. data/lib/solargraph/yardoc.rb +27 -4
  82. data/rbs/fills/bundler/0/bundler.rbs +4271 -0
  83. data/rbs/fills/open3/0/open3.rbs +172 -0
  84. data/rbs/fills/rubygems/0/basic_specification.rbs +326 -0
  85. data/rbs/fills/rubygems/0/errors.rbs +364 -0
  86. data/rbs/fills/rubygems/0/spec_fetcher.rbs +107 -0
  87. data/rbs/fills/rubygems/0/specification.rbs +1753 -0
  88. data/rbs_collection.yaml +4 -4
  89. data/sig/shims/ast/0/node.rbs +5 -0
  90. data/sig/shims/ast/2.4/.rbs_meta.yaml +9 -0
  91. data/sig/shims/ast/2.4/ast.rbs +73 -0
  92. data/sig/shims/parser/3.2.0.1/manifest.yaml +7 -0
  93. data/sig/shims/parser/3.2.0.1/parser.rbs +201 -0
  94. data/sig/shims/parser/3.2.0.1/polyfill.rbs +4 -0
  95. data/solargraph.gemspec +15 -4
  96. metadata +66 -12
  97. data/lib/solargraph/parser/node_methods.rb +0 -97
  98. /data/rbs/fills/{tuple.rbs → tuple/tuple.rbs} +0 -0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,30 @@
1
+ ## 0.58.0 - January 1, 2026
2
+ - Faster constant resolution (#1083)
3
+ - [regression] Handle RBS static method aliases (#1094)
4
+ - More type fills and shims (#1005)
5
+ - Fix resolution in blocks in type checker (#890)
6
+ - Annotation fixes for strong typechecking (#1057)
7
+ - Remove dead code (#1077)
8
+ - Fix flakey spec (#1080)
9
+ - Fix bad sexpr generation in op_asgn (#1089)
10
+ - Opt-in for MFA requirement (#730)
11
+ - [regression] Fix resolution issues with namespaces from YARD (#1097)
12
+ - Improve a pin combination case around selfy types (#1024)
13
+ - Rescue reference errors in hosts (#1105)
14
+ - Relax bundler runtime dependency version constraint to support newer versions (#1125)
15
+ - Remove stale Pathname test (#1135)
16
+ - Enable strong type checking in CI (#928)
17
+ - Stale sg-ignore
18
+ - Use rbs 3.9.5 in tests (#1136)
19
+ - Drop broken 'namespaces' method (#1065)
20
+ - Add ActiveRecord example from RBS (#1074)
21
+ - Keep workspace directories as absolute paths (#1076)
22
+ - Handle bad gem_dir from gemspec object (#1079)
23
+ - Test for absolute require paths (#1137)
24
+ - [regression] Fix resolution of ambiguous argument types (#1098)
25
+ - Remove sg-ignore for String#=~ (#1138)
26
+ - Allow levels to be changed for typechecking rules in .solargraph.yml (#1126)
27
+
1
28
  ## 0.57.0 - September 16, 2025
2
29
  - Support ActiveSupport::Concern pattern for class methods (#948)
3
30
  - More CI checks (#996)
data/Rakefile CHANGED
@@ -9,7 +9,7 @@ task :console do
9
9
  end
10
10
 
11
11
  desc "Run the type checker"
12
- task typecheck: [:typecheck_typed]
12
+ task typecheck: [:typecheck_strong]
13
13
 
14
14
  desc "Run the type checker at typed level - return code issues provable without annotations being correct"
15
15
  task :typecheck_typed do
data/bin/solargraph CHANGED
@@ -1,5 +1,8 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'solargraph'
4
-
5
- Solargraph::Shell.start(ARGV)
1
+ #!/usr/bin/env ruby
2
+
3
+ # turn off warning diagnostics from Ruby
4
+ $VERBOSE=nil
5
+
6
+ require 'solargraph'
7
+
8
+ Solargraph::Shell.start(ARGV)
@@ -12,15 +12,35 @@ module Solargraph
12
12
 
13
13
  # Resolve a name to a fully qualified namespace or constant.
14
14
  #
15
- # @param name [String]
16
- # @param gates [Array<Array<String>, String>]
17
- # @return [String, nil]
15
+ # `Constants#resolve` finds fully qualified (absolute)
16
+ # namespaces based on relative names and the open gates
17
+ # (namespaces) provided. Names must be runtime-visible (erased)
18
+ # non-literal types, non-duck, non-signature types - e.g.,
19
+ # TrueClass, NilClass, Integer and Hash instead of true, nil,
20
+ # 96, or Hash{String => Symbol}
21
+ #
22
+ # Note: You may want to be using #qualify. Notably, #resolve:
23
+ # - does not handle anything with type parameters
24
+ # - will not gracefully handle nil, self and Boolean
25
+ # - will return a constant name instead of following its assignment
26
+ #
27
+ # @param name [String] Namespace which may relative and not be rooted.
28
+ # @param gates [Array<Array<String>, String>] Namespaces to search while resolving the name
29
+ #
30
+ # @return [String, nil] fully qualified namespace (i.e., is
31
+ # absolute, but will not start with ::)
18
32
  def resolve(name, *gates)
19
33
  return store.get_path_pins(name[2..]).first&.path if name.start_with?('::')
20
34
 
21
35
  flat = gates.flatten
22
36
  flat.push '' if flat.empty?
23
- cached_resolve[[name, flat]] || resolve_and_cache(name, flat)
37
+ if cached_resolve.include? [name, flat]
38
+ cached_result = cached_resolve[[name, flat]]
39
+ # don't recurse
40
+ return nil if cached_result == :in_process
41
+ return cached_result
42
+ end
43
+ resolve_and_cache(name, flat)
24
44
  end
25
45
 
26
46
  # Get a fully qualified namespace from a reference pin.
@@ -28,47 +48,49 @@ module Solargraph
28
48
  # @param pin [Pin::Reference]
29
49
  # @return [String, nil]
30
50
  def dereference pin
31
- resolve(pin.name, pin.reference_gates)
51
+ qualify_type(pin.type, *pin.reference_gates)&.tag
32
52
  end
33
53
 
34
54
  # Collect a list of all constants defined in the specified gates.
35
55
  #
36
56
  # @param gates [Array<Array<String>, String>]
37
- # @return [Array<Pin::Base>]
57
+ # @return [Array<Solargraph::Pin::Namespace, Solargraph::Pin::Constant>]
38
58
  def collect(*gates)
39
59
  flat = gates.flatten
40
60
  cached_collect[flat] || collect_and_cache(flat)
41
61
  end
42
62
 
43
- # Determine fully qualified tag for a given tag used inside the
44
- # definition of another tag ("context"). This method will start
45
- # the search in the specified context until it finds a match for
46
- # the tag.
63
+ # Determine a fully qualified namespace for a given tag
64
+ # referenced from the specified open gates. This method will
65
+ # search in each gate until it finds a match for the name.
47
66
  #
48
- # Does not recurse into qualifying the type parameters, but
49
- # returns any which were passed in unchanged.
50
- #
51
- # @param tag [String, nil] The namespace to
52
- # match, complete with generic parameters set to appropriate
53
- # values if available
54
- # @param context_tag [String] The fully qualified context in which
55
- # the tag was referenced; start from here to resolve the name.
56
- # Should not be prefixed with '::'.
67
+ # @param tag [String, nil] The type to match
68
+ # @param gates [Array<String>]
57
69
  # @return [String, nil] fully qualified tag
58
- def qualify tag, context_tag = ''
59
- return tag if ['Boolean', 'self', nil].include?(tag)
60
-
70
+ def qualify tag, *gates
61
71
  type = ComplexType.try_parse(tag)
62
- return unless type.defined?
63
- return tag if type.literal?
72
+ qualify_type(type, *gates)&.tag
73
+ end
64
74
 
65
- context_type = ComplexType.try_parse(context_tag)
66
- return unless context_type.defined?
75
+ # @param type [ComplexType, nil] The type to match
76
+ # @param gates [Array<String>]
77
+ #
78
+ # @return [ComplexType, nil] A new rooted ComplexType
79
+ def qualify_type type, *gates
80
+ return nil if type.nil?
81
+ return type if type.selfy? || type.literal? || type.tag == 'nil' || type.interface? ||
82
+ type.tag == 'Boolean'
67
83
 
68
- fqns = qualify_namespace(type.rooted_namespace, context_type.rooted_namespace)
84
+ gates.push '' unless gates.include?('')
85
+ fqns = resolve(type.rooted_namespace, *gates)
69
86
  return unless fqns
70
-
71
- fqns + type.substring
87
+ pin = store.get_path_pins(fqns).first
88
+ if pin.is_a?(Pin::Constant)
89
+ const = Solargraph::Parser::NodeMethods.unpack_name(pin.assignment)
90
+ return unless const
91
+ fqns = resolve(const, *pin.gates)
92
+ end
93
+ type.recreate(new_name: fqns, make_rooted: true)
72
94
  end
73
95
 
74
96
  # @return [void]
@@ -85,6 +107,7 @@ module Solargraph
85
107
  # @param gates [Array<String>]
86
108
  # @return [String, nil]
87
109
  def resolve_and_cache name, gates
110
+ cached_resolve[[name, gates]] = :in_process
88
111
  cached_resolve[[name, gates]] = resolve_uncached(name, gates)
89
112
  end
90
113
 
@@ -92,28 +115,66 @@ module Solargraph
92
115
  # @param gates [Array<String>]
93
116
  # @return [String, nil]
94
117
  def resolve_uncached name, gates
118
+ resolved = nil
119
+ base = gates
95
120
  parts = name.split('::')
96
- here = parts.shift
97
- resolved = simple_resolve(here, gates)
98
- return resolved if parts.empty? || resolved.nil?
99
-
100
- final = "#{resolved}::#{parts.join('::')}".sub(/^::/, '')
101
- final if store.namespace_exists?(final)
121
+ first = nil
122
+ parts.each.with_index do |nam, idx|
123
+ resolved, remainder = complex_resolve(nam, base, idx != parts.length - 1)
124
+ first ||= remainder
125
+ if resolved
126
+ base = [resolved]
127
+ else
128
+ return resolve(name, first) unless first.empty?
129
+ end
130
+ end
131
+ resolved
102
132
  end
103
133
 
134
+ # @todo I'm not sure of a better way to express the return value in YARD.
135
+ # It's a tuple where the first element is a nullable string. Something
136
+ # like `Array(String|nil, Array<String>)` would be more accurate.
137
+ #
104
138
  # @param name [String]
105
139
  # @param gates [Array<String>]
140
+ # @param internal [Boolean] True if the name is not the last in the namespace
141
+ # @return [Array(Object, Array<String>)]
142
+ def complex_resolve name, gates, internal
143
+ resolved = nil
144
+ gates.each.with_index do |gate, idx|
145
+ resolved = simple_resolve(name, gate, internal)
146
+ return [resolved, gates[(idx + 1)..]] if resolved
147
+ store.get_ancestor_references(gate).each do |ref|
148
+ return ref.name.sub(/^::/, '') if ref.name.end_with?("::#{name}") && ref.name.start_with?('::')
149
+
150
+ mixin = resolve(ref.name, ref.reference_gates)
151
+ next unless mixin
152
+
153
+ resolved = simple_resolve(name, mixin, internal)
154
+ return [resolved, gates[(idx + 1)..]] if resolved
155
+ end
156
+ end
157
+ [nil, []]
158
+ end
159
+
160
+ # @param name [String]
161
+ # @param gate [String]
162
+ # @param internal [Boolean] True if the name is not the last in the namespace
106
163
  # @return [String, nil]
107
- def simple_resolve name, gates
108
- gates.each do |gate|
109
- here = "#{gate}::#{name}".sub(/^::/, '').sub(/::$/, '')
110
- return here if store.namespace_exists?(here)
164
+ def simple_resolve name, gate, internal
165
+ here = "#{gate}::#{name}".sub(/^::/, '').sub(/::$/, '')
166
+ pin = store.get_path_pins(here).first
167
+ if pin.is_a?(Pin::Constant) && internal
168
+ const = Solargraph::Parser::NodeMethods.unpack_name(pin.assignment)
169
+ return unless const
170
+ resolve(const, pin.gates)
171
+ else
172
+ pin&.path
111
173
  end
112
- nil
113
174
  end
114
175
 
115
176
  # @param gates [Array<String>]
116
- # @return [Array<Pin::Base>]
177
+ # @return [Array<Solargraph::Pin::Namespace, Solargraph::Pin::Constant>]
117
178
  def collect_and_cache gates
118
179
  skip = Set.new
119
180
  cached_collect[gates] = gates.flat_map do |gate|
@@ -121,12 +182,12 @@ module Solargraph
121
182
  end
122
183
  end
123
184
 
124
- # @return [Hash{Array(Name, Array<String>) => String, nil}]
185
+ # @return [Hash{Array(String, Array<String>) => String, :in_process, nil}]
125
186
  def cached_resolve
126
187
  @cached_resolve ||= {}
127
188
  end
128
189
 
129
- # @return [Hash{Array<String> => Array<Pin::Base>}]
190
+ # @return [Hash{Array<String> => Array<Solargraph::Pin::Namespace, Solargraph::Pin::Constant>}]
130
191
  def cached_collect
131
192
  @cached_collect ||= {}
132
193
  end
@@ -171,7 +232,7 @@ module Solargraph
171
232
  return fqns if store.namespace_exists?(fqns)
172
233
  incs = store.get_includes(roots.join('::'))
173
234
  incs.each do |inc|
174
- foundinc = inner_qualify(name, inc.parametrized_tag.to_s, skip)
235
+ foundinc = inner_qualify(name, inc.type.to_s, skip)
175
236
  possibles.push foundinc unless foundinc.nil?
176
237
  end
177
238
  roots.pop
@@ -179,7 +240,7 @@ module Solargraph
179
240
  if possibles.empty?
180
241
  incs = store.get_includes('')
181
242
  incs.each do |inc|
182
- foundinc = inner_qualify(name, inc.parametrized_tag.to_s, skip)
243
+ foundinc = inner_qualify(name, inc.type.to_s, skip)
183
244
  possibles.push foundinc unless foundinc.nil?
184
245
  end
185
246
  end
@@ -191,7 +252,7 @@ module Solargraph
191
252
  # @param fqns [String]
192
253
  # @param visibility [Array<Symbol>]
193
254
  # @param skip [Set<String>]
194
- # @return [Array<Pin::Base>]
255
+ # @return [Array<Solargraph::Pin::Namespace, Solargraph::Pin::Constant>]
195
256
  def inner_get_constants fqns, visibility, skip
196
257
  return [] if fqns.nil? || skip.include?(fqns)
197
258
  skip.add fqns
@@ -15,21 +15,24 @@ module Solargraph
15
15
  @pins ||= []
16
16
  end
17
17
 
18
- # @return [Set<String>]
19
- attr_reader :namespaces
20
-
21
18
  # @return [Hash{String => Array<Pin::Namespace>}]
22
19
  def namespace_hash
20
+ # @param h [String]
21
+ # @param k [Array<Pin::Namespace>]
23
22
  @namespace_hash ||= Hash.new { |h, k| h[k] = [] }
24
23
  end
25
24
 
26
25
  # @return [Hash{String => Array<Pin::Base>}]
27
26
  def pin_class_hash
27
+ # @param h [String]
28
+ # @param k [Array<Pin::Base>]
28
29
  @pin_class_hash ||= Hash.new { |h, k| h[k] = [] }
29
30
  end
30
31
 
31
32
  # @return [Hash{String => Array<Pin::Base>}]
32
33
  def path_pin_hash
34
+ # @param h [String]
35
+ # @param k [Array<Pin::Base>]
33
36
  @path_pin_hash ||= Hash.new { |h, k| h[k] = [] }
34
37
  end
35
38
 
@@ -45,26 +48,36 @@ module Solargraph
45
48
 
46
49
  # @return [Hash{String => Array<String>}]
47
50
  def include_references
51
+ # @param h [String]
52
+ # @param k [Array<String>]
48
53
  @include_references ||= Hash.new { |h, k| h[k] = [] }
49
54
  end
50
55
 
51
56
  # @return [Hash{String => Array<Pin::Reference::Include>}]
52
57
  def include_reference_pins
58
+ # @param h [String]
59
+ # @param k [Array<Pin::Reference::Include>]
53
60
  @include_reference_pins ||= Hash.new { |h, k| h[k] = [] }
54
61
  end
55
62
 
56
63
  # @return [Hash{String => Array<String>}]
57
64
  def extend_references
65
+ # @param h [String]
66
+ # @param k [Array<String>]
58
67
  @extend_references ||= Hash.new { |h, k| h[k] = [] }
59
68
  end
60
69
 
61
70
  # @return [Hash{String => Array<String>}]
62
71
  def prepend_references
72
+ # @param h [String]
73
+ # @param k [Array<String>]
63
74
  @prepend_references ||= Hash.new { |h, k| h[k] = [] }
64
75
  end
65
76
 
66
77
  # @return [Hash{String => Array<String>}]
67
78
  def superclass_references
79
+ # @param h [String]
80
+ # @param k [Array<String>]
68
81
  @superclass_references ||= Hash.new { |h, k| h[k] = [] }
69
82
  end
70
83
 
@@ -95,18 +108,25 @@ module Solargraph
95
108
  end
96
109
 
97
110
  # @param new_pins [Enumerable<Pin::Base>]
111
+ #
98
112
  # @return [self]
99
113
  def catalog new_pins
100
114
  # @type [Hash{Class<generic<T>> => Set<generic<T>>}]
101
115
  @pin_select_cache = {}
102
116
  pins.concat new_pins
103
117
  set = new_pins.to_set
118
+ # @param k [String]
119
+ # @param v [Set<Pin::Base>]
104
120
  set.classify(&:class)
105
- .map { |k, v| pin_class_hash[k].concat v.to_a }
121
+ .map { |k, v| pin_class_hash[k].concat v.to_a }
122
+ # @param k [String]
123
+ # @param v [Set<Pin::Namespace>]
106
124
  set.classify(&:namespace)
107
- .map { |k, v| namespace_hash[k].concat v.to_a }
125
+ .map { |k, v| namespace_hash[k].concat v.to_a }
126
+ # @param k [String]
127
+ # @param v [Set<Pin::Base>]
108
128
  set.classify(&:path)
109
- .map { |k, v| path_pin_hash[k].concat v.to_a }
129
+ .map { |k, v| path_pin_hash[k].concat v.to_a }
110
130
  @namespaces = path_pin_hash.keys.compact.to_set
111
131
  map_references Pin::Reference::Include, include_references
112
132
  map_references Pin::Reference::Prepend, prepend_references
@@ -116,10 +136,13 @@ module Solargraph
116
136
  self
117
137
  end
118
138
 
119
- # @param klass [Class<Pin::Reference>]
120
- # @param hash [Hash{String => Array<Pin::Reference>}]
139
+ # @generic T
140
+ # @param klass [Class<generic<T>>]
141
+ # @param hash [Hash{String => generic<T>}]
142
+ #
121
143
  # @return [void]
122
144
  def map_references klass, hash
145
+ # @param pin [generic<T>]
123
146
  pins_by_class(klass).each do |pin|
124
147
  hash[pin.namespace].push pin
125
148
  end
@@ -127,6 +150,7 @@ module Solargraph
127
150
 
128
151
  # @return [void]
129
152
  def map_overrides
153
+ # @param ovr [Pin::Reference::Override]
130
154
  pins_by_class(Pin::Reference::Override).each do |ovr|
131
155
  logger.debug { "ApiMap::Index#map_overrides: Looking at override #{ovr} for #{ovr.name}" }
132
156
  pins = path_pin_hash[ovr.name]
@@ -32,11 +32,13 @@ module Solargraph
32
32
  next
33
33
  end
34
34
  if pin.type == :class
35
+ # @param obj [YARD::CodeObjects::RootObject]
35
36
  code_object_map[pin.path] ||= YARD::CodeObjects::ClassObject.new(root_code_object, pin.path) { |obj|
36
37
  next if pin.location.nil? || pin.location.filename.nil?
37
38
  obj.add_file(pin.location.filename, pin.location.range.start.line, !pin.comments.empty?)
38
39
  }
39
40
  else
41
+ # @param obj [YARD::CodeObjects::RootObject]
40
42
  code_object_map[pin.path] ||= YARD::CodeObjects::ModuleObject.new(root_code_object, pin.path) { |obj|
41
43
  next if pin.location.nil? || pin.location.filename.nil?
42
44
  obj.add_file(pin.location.filename, pin.location.range.start.line, !pin.comments.empty?)
@@ -46,13 +48,13 @@ module Solargraph
46
48
  store.get_includes(pin.path).each do |ref|
47
49
  include_object = code_object_at(pin.path, YARD::CodeObjects::ClassObject)
48
50
  unless include_object.nil? || include_object.nil?
49
- include_object.instance_mixins.push code_object_map[ref.parametrized_tag.to_s]
51
+ include_object.instance_mixins.push code_object_map[ref.type.to_s]
50
52
  end
51
53
  end
52
54
  store.get_extends(pin.path).each do |ref|
53
55
  extend_object = code_object_at(pin.path, YARD::CodeObjects::ClassObject)
54
56
  next unless extend_object
55
- code_object = code_object_map[ref.parametrized_tag.to_s]
57
+ code_object = code_object_map[ref.type.to_s]
56
58
  next unless code_object
57
59
  extend_object.class_mixins.push code_object
58
60
  # @todo add spec showing why this next line is necessary
@@ -65,6 +67,7 @@ module Solargraph
65
67
  next
66
68
  end
67
69
 
70
+ # @param obj [YARD::CodeObjects::RootObject]
68
71
  code_object_map[pin.path] ||= YARD::CodeObjects::MethodObject.new(code_object_at(pin.namespace, YARD::CodeObjects::NamespaceObject), pin.name, pin.scope) { |obj|
69
72
  next if pin.location.nil? || pin.location.filename.nil?
70
73
  obj.add_file pin.location.filename, pin.location.range.start.line
@@ -17,7 +17,7 @@ module Solargraph
17
17
  index.pins
18
18
  end
19
19
 
20
- # @param pinsets [Array<Enumerable<Pin::Base>>]
20
+ # @param pinsets [Array<Array<Pin::Base>>]
21
21
  # - pinsets[0] = core Ruby pins
22
22
  # - pinsets[1] = documentation/gem pins
23
23
  # - pinsets[2] = convention pins
@@ -57,9 +57,10 @@ module Solargraph
57
57
 
58
58
  # @param fqns [String]
59
59
  # @param visibility [Array<Symbol>]
60
- # @return [Enumerable<Solargraph::Pin::Base>]
60
+ # @return [Enumerable<Solargraph::Pin::Namespace, Solargraph::Pin::Constant>]
61
61
  def get_constants fqns, visibility = [:public]
62
62
  namespace_children(fqns).select { |pin|
63
+ # @sg-ignore flow-sensitive typing not smart enough to handle this case
63
64
  !pin.name.empty? && (pin.is_a?(Pin::Namespace) || pin.is_a?(Pin::Constant)) && visibility.include?(pin.visibility)
64
65
  }
65
66
  end
@@ -70,6 +71,7 @@ module Solargraph
70
71
  # @return [Enumerable<Solargraph::Pin::Method>]
71
72
  def get_methods fqns, scope: :instance, visibility: [:public]
72
73
  all_pins = namespace_children(fqns).select do |pin|
74
+ # @sg-ignore https://github.com/castwide/solargraph/pull/1114
73
75
  pin.is_a?(Pin::Method) && pin.scope == scope && visibility.include?(pin.visibility)
74
76
  end
75
77
  GemPins.combine_method_pins_by_path(all_pins)
@@ -97,7 +99,7 @@ module Solargraph
97
99
  return unless ref
98
100
  res = constants.dereference(ref)
99
101
  return unless res
100
- res + type.substring
102
+ res
101
103
  end
102
104
 
103
105
  # @param fqns [String]
@@ -134,7 +136,8 @@ module Solargraph
134
136
  end
135
137
 
136
138
  # @param fqns [String]
137
- # @return [Enumerable<Solargraph::Pin::Base>]
139
+ #
140
+ # @return [Enumerable<Solargraph::Pin::ClassVariable>]
138
141
  def get_class_variables(fqns)
139
142
  namespace_children(fqns).select { |pin| pin.is_a?(Pin::ClassVariable)}
140
143
  end
@@ -150,11 +153,6 @@ module Solargraph
150
153
  fqns_pins(fqns).any?
151
154
  end
152
155
 
153
- # @return [Set<String>]
154
- def namespaces
155
- index.namespaces
156
- end
157
-
158
156
  # @return [Enumerable<Solargraph::Pin::Namespace>]
159
157
  def namespace_pins
160
158
  pins_by_class(Solargraph::Pin::Namespace)
@@ -244,7 +242,8 @@ module Solargraph
244
242
  # Add includes, prepends, and extends
245
243
  [get_includes(current), get_prepends(current), get_extends(current)].each do |refs|
246
244
  next if refs.nil?
247
- refs.map(&:parametrized_tag).map(&:to_s).each do |ref|
245
+ # @param ref [String]
246
+ refs.map(&:type).map(&:to_s).each do |ref|
248
247
  next if ref.nil? || ref.empty? || visited.include?(ref)
249
248
  ancestors << ref
250
249
  queue << ref
@@ -255,6 +254,13 @@ module Solargraph
255
254
  ancestors.compact.uniq
256
255
  end
257
256
 
257
+ # @param fqns [String]
258
+ #
259
+ # @return [Array<Solargraph::Pin::Reference>]
260
+ def get_ancestor_references(fqns)
261
+ (get_prepends(fqns) + get_includes(fqns) + [get_superclass(fqns)]).compact
262
+ end
263
+
258
264
  # @return [Constants]
259
265
  def constants
260
266
  @constants ||= Constants.new(self)
@@ -267,8 +273,9 @@ module Solargraph
267
273
  @indexes.last
268
274
  end
269
275
 
270
- # @param pinsets [Array<Enumerable<Pin::Base>>]
271
- # @return [Boolean]
276
+ # @param pinsets [Array<Array<Pin::Base>>]
277
+ #
278
+ # @return [void]
272
279
  def catalog pinsets
273
280
  @pinsets = pinsets
274
281
  # @type [Array<Index>]
@@ -287,6 +294,9 @@ module Solargraph
287
294
 
288
295
  # @return [Hash{::Array(String, String) => ::Array<Pin::Namespace>}]
289
296
  def fqns_pins_map
297
+ # @param h [Hash{::Array(String, String) => ::Array<Pin::Namespace>}]
298
+ # @param base [String]
299
+ # @param name [String]
290
300
  @fqns_pins_map ||= Hash.new do |h, (base, name)|
291
301
  value = namespace_children(base).select { |pin| pin.name == name && pin.is_a?(Pin::Namespace) }
292
302
  h[[base, name]] = value