solargraph 0.55.1 → 0.56.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 (102) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/plugins.yml +2 -0
  3. data/.github/workflows/typecheck.yml +3 -1
  4. data/.gitignore +2 -0
  5. data/CHANGELOG.md +26 -0
  6. data/README.md +13 -3
  7. data/lib/solargraph/api_map/index.rb +23 -15
  8. data/lib/solargraph/api_map/store.rb +8 -4
  9. data/lib/solargraph/api_map.rb +151 -58
  10. data/lib/solargraph/complex_type/type_methods.rb +6 -1
  11. data/lib/solargraph/complex_type/unique_type.rb +10 -2
  12. data/lib/solargraph/convention/base.rb +3 -3
  13. data/lib/solargraph/convention.rb +3 -3
  14. data/lib/solargraph/doc_map.rb +255 -69
  15. data/lib/solargraph/gem_pins.rb +53 -37
  16. data/lib/solargraph/language_server/host.rb +11 -2
  17. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +2 -0
  18. data/lib/solargraph/language_server/message/extended/document.rb +5 -2
  19. data/lib/solargraph/language_server/message/extended/document_gems.rb +3 -3
  20. data/lib/solargraph/library.rb +6 -3
  21. data/lib/solargraph/location.rb +13 -0
  22. data/lib/solargraph/logging.rb +1 -0
  23. data/lib/solargraph/parser/comment_ripper.rb +1 -0
  24. data/lib/solargraph/parser/flow_sensitive_typing.rb +5 -4
  25. data/lib/solargraph/parser/node_processor.rb +3 -1
  26. data/lib/solargraph/parser/parser_gem/class_methods.rb +5 -8
  27. data/lib/solargraph/parser/parser_gem/node_methods.rb +1 -1
  28. data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +2 -1
  29. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +4 -2
  30. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +4 -2
  31. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +4 -3
  32. data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +2 -1
  33. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +6 -3
  34. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +2 -1
  35. data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +2 -1
  36. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +4 -2
  37. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +2 -1
  38. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +6 -4
  39. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
  40. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -3
  41. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +28 -16
  42. data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +2 -1
  43. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +1 -0
  44. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +1 -0
  45. data/lib/solargraph/parser/region.rb +1 -1
  46. data/lib/solargraph/pin/base.rb +295 -28
  47. data/lib/solargraph/pin/base_variable.rb +9 -8
  48. data/lib/solargraph/pin/callable.rb +74 -3
  49. data/lib/solargraph/pin/closure.rb +18 -1
  50. data/lib/solargraph/pin/common.rb +5 -0
  51. data/lib/solargraph/pin/delegated_method.rb +2 -0
  52. data/lib/solargraph/pin/documenting.rb +16 -0
  53. data/lib/solargraph/pin/keyword.rb +7 -2
  54. data/lib/solargraph/pin/local_variable.rb +8 -5
  55. data/lib/solargraph/pin/method.rb +147 -25
  56. data/lib/solargraph/pin/namespace.rb +7 -2
  57. data/lib/solargraph/pin/parameter.rb +47 -6
  58. data/lib/solargraph/pin/proxy_type.rb +3 -3
  59. data/lib/solargraph/pin/reference/override.rb +10 -6
  60. data/lib/solargraph/pin/reference/require.rb +2 -2
  61. data/lib/solargraph/pin/signature.rb +42 -0
  62. data/lib/solargraph/pin/singleton.rb +1 -1
  63. data/lib/solargraph/pin/symbol.rb +3 -2
  64. data/lib/solargraph/pin.rb +1 -1
  65. data/lib/solargraph/pin_cache.rb +185 -0
  66. data/lib/solargraph/position.rb +9 -0
  67. data/lib/solargraph/range.rb +9 -0
  68. data/lib/solargraph/rbs_map/conversions.rb +183 -56
  69. data/lib/solargraph/rbs_map/core_fills.rb +24 -15
  70. data/lib/solargraph/rbs_map/core_map.rb +34 -11
  71. data/lib/solargraph/rbs_map/stdlib_map.rb +15 -5
  72. data/lib/solargraph/rbs_map.rb +74 -17
  73. data/lib/solargraph/shell.rb +17 -18
  74. data/lib/solargraph/source/chain/array.rb +7 -4
  75. data/lib/solargraph/source/chain/block_symbol.rb +1 -1
  76. data/lib/solargraph/source/chain/block_variable.rb +1 -1
  77. data/lib/solargraph/source/chain/call.rb +8 -7
  78. data/lib/solargraph/source/chain/hash.rb +1 -1
  79. data/lib/solargraph/source/chain/head.rb +1 -1
  80. data/lib/solargraph/source/chain/if.rb +1 -1
  81. data/lib/solargraph/source/chain/literal.rb +2 -2
  82. data/lib/solargraph/source/chain/or.rb +1 -1
  83. data/lib/solargraph/source/chain.rb +2 -2
  84. data/lib/solargraph/source_map/mapper.rb +9 -5
  85. data/lib/solargraph/source_map.rb +0 -17
  86. data/lib/solargraph/version.rb +1 -1
  87. data/lib/solargraph/views/_method.erb +10 -10
  88. data/lib/solargraph/views/_namespace.erb +3 -3
  89. data/lib/solargraph/views/document.erb +10 -10
  90. data/lib/solargraph/workspace.rb +15 -5
  91. data/lib/solargraph/yard_map/mapper/to_constant.rb +4 -2
  92. data/lib/solargraph/yard_map/mapper/to_method.rb +14 -1
  93. data/lib/solargraph/yard_map/mapper/to_namespace.rb +4 -2
  94. data/lib/solargraph/yard_map/mapper.rb +4 -3
  95. data/lib/solargraph/yard_map/to_method.rb +4 -2
  96. data/lib/solargraph/yardoc.rb +6 -9
  97. data/lib/solargraph.rb +19 -1
  98. data/rbs/fills/tuple.rbs +150 -0
  99. data/rbs_collection.yaml +19 -0
  100. data/solargraph.gemspec +1 -0
  101. metadata +20 -7
  102. data/lib/solargraph/cache.rb +0 -77
@@ -10,25 +10,78 @@ module Solargraph
10
10
  autoload :CoreFills, 'solargraph/rbs_map/core_fills'
11
11
  autoload :StdlibMap, 'solargraph/rbs_map/stdlib_map'
12
12
 
13
- include Conversions
13
+ include Logging
14
14
 
15
15
  # @type [Hash{String => RbsMap}]
16
16
  @@rbs_maps_hash = {}
17
17
 
18
18
  attr_reader :library
19
19
 
20
+ attr_reader :rbs_collection_paths
21
+
22
+ attr_reader :rbs_collection_config_path
23
+
20
24
  # @param library [String]
21
25
  # @param version [String, nil]
22
- # @param directories [Array<Pathname, String>]
23
- def initialize library, version = nil, directories: []
26
+ # @param rbs_collection_paths [Array<Pathname, String>]
27
+ def initialize library, version = nil, rbs_collection_config_path: nil, rbs_collection_paths: []
28
+ if rbs_collection_config_path.nil? && !rbs_collection_paths.empty?
29
+ raise 'Please provide rbs_collection_config_path if you provide rbs_collection_paths'
30
+ end
24
31
  @library = library
25
32
  @version = version
26
- @collection = nil
27
- @directories = directories
28
- loader = RBS::EnvironmentLoader.new(core_root: nil, repository: repository)
33
+ @rbs_collection_config_path = rbs_collection_config_path
34
+ @rbs_collection_paths = rbs_collection_paths
29
35
  add_library loader, library, version
30
- return unless resolved?
31
- load_environment_to_pins(loader)
36
+ end
37
+
38
+ def loader
39
+ @loader ||= RBS::EnvironmentLoader.new(core_root: nil, repository: repository)
40
+ end
41
+
42
+ # @return string representing the version of the RBS info fetched
43
+ # for the given library. Must change when the RBS info is
44
+ # updated upstream for the same library and version. May change
45
+ # if the config for where information comes form changes.
46
+ def cache_key
47
+ @hextdigest ||= begin
48
+ data = nil
49
+ if rbs_collection_config_path
50
+ lockfile_path = RBS::Collection::Config.to_lockfile_path(Pathname.new(rbs_collection_config_path))
51
+ if lockfile_path.exist?
52
+ collection_config = RBS::Collection::Config.from_path lockfile_path
53
+ gem_config = collection_config.gem(library)
54
+ data = gem_config&.to_s
55
+ end
56
+ end
57
+ if data.nil? || data.empty?
58
+ if resolved?
59
+ # definitely came from the gem itself and not elsewhere -
60
+ # only one version per gem
61
+ 'gem-export'
62
+ else
63
+ 'unresolved'
64
+ end
65
+ else
66
+ Digest::SHA1.hexdigest(data)
67
+ end
68
+ end
69
+ end
70
+
71
+ def self.from_gemspec gemspec, rbs_collection_path, rbs_collection_config_path
72
+ rbs_map = RbsMap.new(gemspec.name, gemspec.version,
73
+ rbs_collection_paths: [rbs_collection_path].compact,
74
+ rbs_collection_config_path: rbs_collection_config_path)
75
+ return rbs_map if rbs_map.resolved?
76
+
77
+ # try any version of the gem in the collection
78
+ RbsMap.new(gemspec.name, nil,
79
+ rbs_collection_paths: [rbs_collection_path].compact,
80
+ rbs_collection_config_path: rbs_collection_config_path)
81
+ end
82
+
83
+ def pins
84
+ @pins ||= resolved? ? conversions.pins : []
32
85
  end
33
86
 
34
87
  # @generic T
@@ -52,9 +105,10 @@ module Solargraph
52
105
 
53
106
  def repository
54
107
  @repository ||= RBS::Repository.new(no_stdlib: false).tap do |repo|
55
- # @todo Temporarily ignoring external directories due to issues with
56
- # incomplete/broken gem_rbs_collection installations
57
- # @directories.each { |dir| repo.add(Pathname.new(dir)) }
108
+ @rbs_collection_paths.each do |dir|
109
+ dir_path = Pathname.new(dir)
110
+ repo.add(dir_path) if dir_path.exist? && dir_path.directory?
111
+ end
58
112
  end
59
113
  end
60
114
 
@@ -64,12 +118,15 @@ module Solargraph
64
118
  @@rbs_maps_hash[library] ||= RbsMap.new(library)
65
119
  end
66
120
 
67
- # @param gemspec [Gem::Specification]
68
- def self.from_gemspec(gemspec)
69
- RbsMap.new(gemspec.name, gemspec.version)
121
+ private
122
+
123
+ def loader
124
+ @loader ||= RBS::EnvironmentLoader.new(core_root: nil, repository: repository)
70
125
  end
71
126
 
72
- private
127
+ def conversions
128
+ @conversions ||= Conversions.new(loader: loader)
129
+ end
73
130
 
74
131
  # @param loader [RBS::EnvironmentLoader]
75
132
  # @param library [String]
@@ -77,10 +134,10 @@ module Solargraph
77
134
  def add_library loader, library, version
78
135
  @resolved = if loader.has_library?(library: library, version: version)
79
136
  loader.add library: library, version: version
80
- Solargraph.logger.info "#{short_name} successfully loaded library #{library}"
137
+ logger.debug { "#{short_name} successfully loaded library #{library}:#{version}" }
81
138
  true
82
139
  else
83
- Solargraph.logger.info "#{short_name} failed to load library #{library}"
140
+ logger.info { "#{short_name} did not find data for library #{library}:#{version}" }
84
141
  false
85
142
  end
86
143
  end
@@ -90,19 +90,20 @@ module Solargraph
90
90
  # @return [void]
91
91
  def clear
92
92
  puts "Deleting all cached documentation (gems, core and stdlib)"
93
- Solargraph::Cache.clear
93
+ Solargraph::PinCache.clear
94
94
  end
95
95
  map 'clear-cache' => :clear
96
96
  map 'clear-cores' => :clear
97
97
 
98
98
  desc 'cache', 'Cache a gem', hide: true
99
+ option :rebuild, type: :boolean, desc: 'Rebuild existing documentation', default: false
99
100
  # @return [void]
100
101
  # @param gem [String]
101
102
  # @param version [String, nil]
102
103
  def cache gem, version = nil
104
+ api_map = Solargraph::ApiMap.load(Dir.pwd)
103
105
  spec = Gem::Specification.find_by_name(gem, version)
104
- pins = GemPins.build(spec)
105
- Cache.save('gems', "#{spec.name}-#{spec.version}.ser", pins)
106
+ api_map.cache_gem(spec, rebuild: options[:rebuild], out: $stdout)
106
107
  end
107
108
 
108
109
  desc 'uncache GEM [...GEM]', "Delete specific cached gem documentation"
@@ -117,18 +118,17 @@ module Solargraph
117
118
  raise ArgumentError, 'No gems specified.' if gems.empty?
118
119
  gems.each do |gem|
119
120
  if gem == 'core'
120
- Cache.uncache("core.ser")
121
+ PinCache.uncache_core
121
122
  next
122
123
  end
123
124
 
124
125
  if gem == 'stdlib'
125
- Cache.uncache("stdlib")
126
+ PinCache.uncache_stdlib
126
127
  next
127
128
  end
128
129
 
129
130
  spec = Gem::Specification.find_by_name(gem)
130
- Cache.uncache('gems', "#{spec.name}-#{spec.version}.ser")
131
- Cache.uncache('gems', "#{spec.name}-#{spec.version}.yardoc")
131
+ PinCache.uncache_gem(spec, out: $stdout)
132
132
  end
133
133
  end
134
134
 
@@ -137,15 +137,18 @@ module Solargraph
137
137
  # @param names [Array<String>]
138
138
  # @return [void]
139
139
  def gems *names
140
+ api_map = ApiMap.load('.')
140
141
  if names.empty?
141
- Gem::Specification.to_a.each { |spec| do_cache spec }
142
+ Gem::Specification.to_a.each { |spec| do_cache spec, api_map }
143
+ STDERR.puts "Documentation cached for all #{Gem::Specification.count} gems."
142
144
  else
143
145
  names.each do |name|
144
146
  spec = Gem::Specification.find_by_name(*name.split('='))
145
- do_cache spec
147
+ do_cache spec, api_map
146
148
  rescue Gem::MissingSpecError
147
149
  warn "Gem '#{name}' not found"
148
150
  end
151
+ STDERR.puts "Documentation cached for #{names.count} gems."
149
152
  end
150
153
  end
151
154
 
@@ -206,6 +209,7 @@ module Solargraph
206
209
  # @return [void]
207
210
  def scan
208
211
  directory = File.realpath(options[:directory])
212
+ # @type [Solargraph::ApiMap, nil]
209
213
  api_map = nil
210
214
  time = Benchmark.measure {
211
215
  api_map = Solargraph::ApiMap.load_with_cache(directory, $stdout)
@@ -255,15 +259,10 @@ module Solargraph
255
259
 
256
260
  # @param gemspec [Gem::Specification]
257
261
  # @return [void]
258
- def do_cache gemspec
259
- cached = Yardoc.cached?(gemspec)
260
- if cached && !options.rebuild
261
- puts "Cache already exists for #{gemspec.name} #{gemspec.version}"
262
- else
263
- puts "#{cached ? 'Rebuilding' : 'Caching'} gem documentation for #{gemspec.name} #{gemspec.version}"
264
- pins = GemPins.build(gemspec)
265
- Cache.save('gems', "#{gemspec.name}-#{gemspec.version}.ser", pins)
266
- end
262
+ def do_cache gemspec, api_map
263
+ # @todo if the rebuild: option is passed as a positional arg,
264
+ # typecheck doesn't complain on the below line
265
+ api_map.cache_gem(gemspec, rebuild: options.rebuild, out: $stdout)
267
266
  end
268
267
  end
269
268
  end
@@ -20,13 +20,16 @@ module Solargraph
20
20
  child_types = @children.map do |child|
21
21
  child.infer(api_map, name_pin, locals).simplify_literals
22
22
  end
23
-
24
- type = if child_types.uniq.length == 1 && child_types.first.defined?
23
+ type = if child_types.length == 0 || child_types.any?(&:undefined?)
24
+ ComplexType::UniqueType.new('Array', rooted: true)
25
+ elsif child_types.uniq.length == 1 && child_types.first.defined?
25
26
  ComplexType::UniqueType.new('Array', [], child_types.uniq, rooted: true, parameters_type: :list)
27
+ elsif child_types.length == 0
28
+ ComplexType::UniqueType.new('Array', rooted: true, parameters_type: :list)
26
29
  else
27
- ComplexType::UniqueType.new('Array', rooted: true)
30
+ ComplexType::UniqueType.new('Array', [], child_types, rooted: true, parameters_type: :fixed)
28
31
  end
29
- [Pin::ProxyType.anonymous(type)]
32
+ [Pin::ProxyType.anonymous(type, source: :chain)]
30
33
  end
31
34
  end
32
35
  end
@@ -5,7 +5,7 @@ module Solargraph
5
5
  class Chain
6
6
  class BlockSymbol < Link
7
7
  def resolve api_map, name_pin, locals
8
- [Pin::ProxyType.anonymous(ComplexType.try_parse('::Proc'))]
8
+ [Pin::ProxyType.anonymous(ComplexType.try_parse('::Proc'), source: :chain)]
9
9
  end
10
10
  end
11
11
  end
@@ -5,7 +5,7 @@ module Solargraph
5
5
  class Chain
6
6
  class BlockVariable < Link
7
7
  def resolve api_map, name_pin, locals
8
- [Pin::ProxyType.anonymous(ComplexType.try_parse('::Proc'))]
8
+ [Pin::ProxyType.anonymous(ComplexType.try_parse('::Proc'), source: :chain)]
9
9
  end
10
10
  end
11
11
  end
@@ -85,6 +85,7 @@ module Solargraph
85
85
 
86
86
  with_block, without_block = overloads.partition(&:block?)
87
87
  sorted_overloads = with_block + without_block
88
+ # @type [Pin::Signature, nil]
88
89
  new_signature_pin = nil
89
90
  sorted_overloads.each do |ol|
90
91
  next unless ol.arity_matches?(arguments, with_block?)
@@ -97,8 +98,7 @@ module Solargraph
97
98
  match = ol.parameters.any?(&:restarg?)
98
99
  break
99
100
  end
100
-
101
- atype = atypes[idx] ||= arg.infer(api_map, Pin::ProxyType.anonymous(name_pin.context), locals)
101
+ atype = atypes[idx] ||= arg.infer(api_map, Pin::ProxyType.anonymous(name_pin.context, source: :chain), locals)
102
102
  unless param.compatible_arg?(atype, api_map) || param.restarg?
103
103
  match = false
104
104
  break
@@ -114,6 +114,7 @@ module Solargraph
114
114
  blocktype = block_call_type(api_map, name_pin, locals)
115
115
  end
116
116
  end
117
+ # @type new_signature_pin [Pin::Signature]
117
118
  new_signature_pin = ol.resolve_generics_from_context_until_complete(ol.generics, atypes, nil, nil, blocktype)
118
119
  new_return_type = new_signature_pin.return_type
119
120
  if head?
@@ -181,7 +182,7 @@ module Solargraph
181
182
  result = inner_process_macro(pin, macro, api_map, context, locals)
182
183
  return result unless result.return_type.undefined?
183
184
  end
184
- Pin::ProxyType.anonymous(ComplexType::UNDEFINED)
185
+ Pin::ProxyType.anonymous(ComplexType::UNDEFINED, source: :chain)
185
186
  end
186
187
 
187
188
  # @param pin [Pin::Method]
@@ -196,7 +197,7 @@ module Solargraph
196
197
  result = inner_process_macro(pin, macro, api_map, context, locals)
197
198
  return result unless result.return_type.undefined?
198
199
  end
199
- Pin::ProxyType.anonymous ComplexType::UNDEFINED
200
+ Pin::ProxyType.anonymous ComplexType::UNDEFINED, source: :chain
200
201
  end
201
202
 
202
203
  # @param pin [Pin::Base]
@@ -206,7 +207,7 @@ module Solargraph
206
207
  # @param locals [::Array<Pin::LocalVariable, Pin::Parameter>]
207
208
  # @return [Pin::ProxyType]
208
209
  def inner_process_macro pin, macro, api_map, context, locals
209
- vals = arguments.map{ |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals)) }
210
+ vals = arguments.map{ |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals), source: :chain) }
210
211
  txt = macro.tag.text.clone
211
212
  if txt.empty? && macro.tag.name
212
213
  named = api_map.named_macro(macro.tag.name)
@@ -220,9 +221,9 @@ module Solargraph
220
221
  docstring = Solargraph::Source.parse_docstring(txt).to_docstring
221
222
  tag = docstring.tag(:return)
222
223
  unless tag.nil? || tag.types.nil?
223
- return Pin::ProxyType.anonymous(ComplexType.try_parse(*tag.types))
224
+ return Pin::ProxyType.anonymous(ComplexType.try_parse(*tag.types), source: :chain)
224
225
  end
225
- Pin::ProxyType.anonymous(ComplexType::UNDEFINED)
226
+ Pin::ProxyType.anonymous(ComplexType::UNDEFINED, source: :chain)
226
227
  end
227
228
 
228
229
  # @param docstring [YARD::Docstring]
@@ -22,7 +22,7 @@ module Solargraph
22
22
  end
23
23
 
24
24
  def resolve api_map, name_pin, locals
25
- [Pin::ProxyType.anonymous(@complex_type)]
25
+ [Pin::ProxyType.anonymous(@complex_type, source: :chain)]
26
26
  end
27
27
 
28
28
  def splatted?
@@ -9,7 +9,7 @@ module Solargraph
9
9
  # @note Chain::Head is only intended to handle `self` and `super`.
10
10
  class Head < Link
11
11
  def resolve api_map, name_pin, locals
12
- return [Pin::ProxyType.anonymous(name_pin.binder)] if word == 'self'
12
+ return [Pin::ProxyType.anonymous(name_pin.binder, source: :chain)] if word == 'self'
13
13
  # return super_pins(api_map, name_pin) if word == 'super'
14
14
  []
15
15
  end
@@ -20,7 +20,7 @@ module Solargraph
20
20
 
21
21
  def resolve api_map, name_pin, locals
22
22
  types = @links.map { |link| link.infer(api_map, name_pin, locals) }
23
- [Solargraph::Pin::ProxyType.anonymous(Solargraph::ComplexType.try_parse(types.map(&:tag).uniq.join(', ')))]
23
+ [Solargraph::Pin::ProxyType.anonymous(Solargraph::ComplexType.try_parse(types.map(&:tag).uniq.join(', ')), source: :chain)]
24
24
  end
25
25
  end
26
26
  end
@@ -36,10 +36,10 @@ module Solargraph
36
36
 
37
37
  def resolve api_map, name_pin, locals
38
38
  if api_map.super_and_sub?(@complex_type.name, @literal_type.name)
39
- [Pin::ProxyType.anonymous(@literal_type)]
39
+ [Pin::ProxyType.anonymous(@literal_type, source: :chain)]
40
40
  else
41
41
  # we don't support this value as a literal type
42
- [Pin::ProxyType.anonymous(@complex_type)]
42
+ [Pin::ProxyType.anonymous(@complex_type, source: :chain)]
43
43
  end
44
44
  end
45
45
  end
@@ -15,7 +15,7 @@ module Solargraph
15
15
 
16
16
  def resolve api_map, name_pin, locals
17
17
  types = @links.map { |link| link.infer(api_map, name_pin, locals) }
18
- [Solargraph::Pin::ProxyType.anonymous(Solargraph::ComplexType.new(types.uniq))]
18
+ [Solargraph::Pin::ProxyType.anonymous(Solargraph::ComplexType.new(types.uniq), source: :chain)]
19
19
  end
20
20
  end
21
21
  end
@@ -122,7 +122,7 @@ module Solargraph
122
122
  # evaluation. However, we use the last link's return type
123
123
  # for the binder, as this is chaining off of it, and the
124
124
  # binder is now the lhs of the rhs we are evaluating.
125
- working_pin = Pin::ProxyType.anonymous(name_pin.context, binder: type, closure: name_pin)
125
+ working_pin = Pin::ProxyType.anonymous(name_pin.context, binder: type, closure: name_pin, source: :chain)
126
126
  logger.debug { "Chain#define(links=#{links.map(&:desc)}, name_pin=#{name_pin.inspect}, locals=#{locals}) - after processing #{link.desc}, new working_pin=#{working_pin} with binder #{working_pin.binder}" }
127
127
  end
128
128
  links.last.last_context = working_pin
@@ -130,7 +130,7 @@ module Solargraph
130
130
  end
131
131
 
132
132
  # @param api_map [ApiMap]
133
- # @param name_pin [Pin::Base]
133
+ # @param name_pin [Pin::Base] The pin for the closure in which this code runs
134
134
  # @param locals [::Array<Pin::LocalVariable>]
135
135
  # @return [ComplexType]
136
136
  # @sg-ignore
@@ -41,7 +41,7 @@ module Solargraph
41
41
  s = Position.new(0, 0)
42
42
  e = Position.from_offset(code, code.length)
43
43
  location = Location.new(filename, Range.new(s, e))
44
- [[Pin::Namespace.new(location: location, name: '')], []]
44
+ [[Pin::Namespace.new(location: location, name: '', source: :source_map)], []]
45
45
  end
46
46
 
47
47
  class << self
@@ -55,6 +55,7 @@ module Solargraph
55
55
 
56
56
  # @return [Array<Solargraph::Pin::Base>]
57
57
  def pins
58
+ # @type [Array<Solargraph::Pin::Base>]
58
59
  @pins ||= []
59
60
  end
60
61
 
@@ -140,7 +141,8 @@ module Solargraph
140
141
  scope: namespace.is_a?(Pin::Singleton) ? :class : :instance,
141
142
  visibility: :public,
142
143
  explicit: false,
143
- attribute: true
144
+ attribute: true,
145
+ source: :source_map
144
146
  )
145
147
  end
146
148
  if t.nil? || t.include?('w')
@@ -151,10 +153,11 @@ module Solargraph
151
153
  comments: docstring.all.to_s,
152
154
  scope: namespace.is_a?(Pin::Singleton) ? :class : :instance,
153
155
  visibility: :public,
154
- attribute: true
156
+ attribute: true,
157
+ source: :source_map
155
158
  )
156
159
  pins.push method_pin
157
- method_pin.parameters.push Pin::Parameter.new(name: 'value', decl: :arg, closure: pins.last)
160
+ method_pin.parameters.push Pin::Parameter.new(name: 'value', decl: :arg, closure: pins.last, source: :source_map)
158
161
  if pins.last.return_type.defined?
159
162
  pins.last.docstring.add_tag YARD::Tags::Tag.new(:param, '', pins.last.return_type.to_s.split(', '), 'value')
160
163
  end
@@ -205,7 +208,8 @@ module Solargraph
205
208
  namespace = closure_at(source_position) || Pin::ROOT_PIN
206
209
  namespace.domains.concat directive.tag.types unless directive.tag.types.nil?
207
210
  when 'override'
208
- pins.push Pin::Reference::Override.new(location, directive.tag.name, docstring.tags)
211
+ pins.push Pin::Reference::Override.new(location, directive.tag.name, docstring.tags,
212
+ source: :source_map)
209
213
  when 'macro'
210
214
  # @todo Handle macros
211
215
  end
@@ -118,23 +118,6 @@ module Solargraph
118
118
  _locate_pin line, character, Pin::Namespace, Pin::Method, Pin::Block
119
119
  end
120
120
 
121
- # @todo Candidate for deprecation
122
- #
123
- # @param other_map [SourceMap]
124
- # @return [Boolean]
125
- def try_merge! other_map
126
- return false if pins.length != other_map.pins.length || locals.length != other_map.locals.length || requires.map(&:name).uniq.sort != other_map.requires.map(&:name).uniq.sort
127
-
128
- pins.each_index do |i|
129
- return false unless pins[i].try_merge!(other_map.pins[i])
130
- end
131
- locals.each_index do |i|
132
- return false unless locals[i].try_merge!(other_map.locals[i])
133
- end
134
- @source = other_map.source
135
- true
136
- end
137
-
138
121
  # @param name [String]
139
122
  # @return [Array<Location>]
140
123
  def references name
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Solargraph
4
- VERSION = '0.55.1'
4
+ VERSION = '0.56.0'
5
5
  end
@@ -2,33 +2,33 @@
2
2
  Namespace:
3
3
  </h2>
4
4
  <p>
5
- <a href="solargraph:/document?query=<%= CGI.escape object.namespace.path %>"><%= object.namespace %></a>
5
+ <a href="solargraph:/document?query=<%= CGI.escape pin.namespace.path %>"><%= pin.namespace %></a>
6
6
  </p>
7
7
  <h2>
8
8
  Overview:
9
9
  </h2>
10
- <%= htmlify object.docstring %>
10
+ <%= htmlify pin.docstring %>
11
11
  <p class="document-section">
12
- <big><strong>Visibility:</strong></big> <%= object.visibility %>
12
+ <big><strong>Visibility:</strong></big> <%= pin.visibility %>
13
13
  </p>
14
- <% unless object.tags(:param).empty? %>
14
+ <% unless pin.docstring.tags(:param).empty? %>
15
15
  <h2>
16
16
  Parameters:
17
17
  </h2>
18
18
  <ul>
19
- <% object.tags(:param).each do |tag| %>
19
+ <% pin.docstring.tags(:param).each do |tag| %>
20
20
  <li>
21
21
  <%= erb :_name_type_tag, layout: false, locals: {tag: tag} %>
22
22
  </li>
23
23
  <% end %>
24
24
  </ul>
25
25
  <% end %>
26
- <% unless object.tags(:raise).empty? %>
26
+ <% unless pin.docstring.tags(:raise).empty? %>
27
27
  <h2>
28
28
  Raises:
29
29
  </h2>
30
30
  <ul>
31
- <% object.tags(:raise).each do |tag| %>
31
+ <% pin.docstring.tags(:raise).each do |tag| %>
32
32
  <li>
33
33
  <%= erb :_name_type_tag, layout: false, locals: {tag: tag} %>
34
34
  </li>
@@ -38,20 +38,20 @@
38
38
  <h2>
39
39
  Returns:
40
40
  </h2>
41
- <% if object.tag(:return).nil? %>
41
+ <% if pin.docstring.tag(:return).nil? %>
42
42
  <p>
43
43
  Undefined/unknown
44
44
  </p>
45
45
  <% else %>
46
46
  <ul>
47
- <% object.tags(:return).each do |tag| %>
47
+ <% pin.tags(:return).each do |tag| %>
48
48
  <li>
49
49
  <%= erb :_name_type_tag, layout: false, locals: {tag: tag} %>
50
50
  </li>
51
51
  <% end %>
52
52
  </ul>
53
53
  <% end %>
54
- <% examples = object.tags(:example) %>
54
+ <% examples = pin.docstring.tags(:example) %>
55
55
  <% unless examples.nil? %>
56
56
  <% examples.each do |example| %>
57
57
  <h2>
@@ -1,12 +1,12 @@
1
1
  <h2>
2
2
  Overview:
3
3
  </h2>
4
- <%= htmlify object.docstring %>
4
+ <%= htmlify pin.docstring %>
5
5
  <h2>
6
6
  Class Methods
7
7
  </h2>
8
8
  <ul class="doc-list">
9
- <% object.meths(scope: :class).sort{|a, b| a.name <=> b.name}.each do |meth| %>
9
+ <% api_map.get_methods(pin.path, scope: :class, deep: false).sort{|a, b| a.name <=> b.name}.each do |meth| %>
10
10
  <li>
11
11
  <a href="solargraph:/document?query=<%= CGI.escape(meth.path) %>"><%= meth.name %></a>
12
12
  </li>
@@ -16,7 +16,7 @@
16
16
  Instance Methods
17
17
  </h2>
18
18
  <ul class="doc-list">
19
- <% object.meths(scope: :instance).sort{|a, b| a.name <=> b.name}.each do |meth| %>
19
+ <% api_map.get_methods(pin.path, scope: :instance, deep: false).sort{|a, b| a.name <=> b.name}.each do |meth| %>
20
20
  <li>
21
21
  <a href="solargraph:/document?query=<%= CGI.escape(meth.path) %>"><%= meth.name %></a>
22
22
  </li>
@@ -1,23 +1,23 @@
1
- <% objects.reverse.each do |object| %>
1
+ <% pins.each do |pin| %>
2
2
  <h1>
3
- <%= object.name %>
4
- <% if object.is_a?(YARD::CodeObjects::MethodObject) and !object.parameters.empty? %>
5
- <small>(<%= object.parameters.map {|p| "#{p[0]}#{p[1] and p[0].end_with?(':') ? ' ' : (p[1] ? ' = ' : '')}#{p[1]}"}.join(', ') %>)</small>
3
+ <%= pin.name %>
4
+ <% if pin.is_a?(Solargraph::Pin::Method) && !pin.parameters.empty? %>
5
+ <small>(<%= pin.parameters.map {|p| "#{p[0]}#{p[1] and p[0].end_with?(':') ? ' ' : (p[1] ? ' = ' : '')}#{p[1]}"}.join(', ') %>)</small>
6
6
  <% end %>
7
7
  </h1>
8
- <% unless object.files.empty? %>
8
+ <% unless pins.map(&:location).compact.empty? %>
9
9
  <h2>
10
10
  Defined in:
11
11
  </h2>
12
12
  <ul>
13
- <% object.files.each do |f| %>
13
+ <% pins.map(&:location).compact.map(&:filename).each do |f| %>
14
14
  <li><%= f %></li>
15
15
  <% end %>
16
16
  </ul>
17
17
  <% end %>
18
- <% if object.is_a?(YARD::CodeObjects::NamespaceObject) %>
19
- <%= erb :_namespace, layout: false, locals: {object: object} %>
20
- <% elsif object.is_a?(YARD::CodeObjects::MethodObject) %>
21
- <%= erb :_method, layout: false, locals: {object: object} %>
18
+ <% if pin.is_a?(Solargraph::Pin::Namespace) %>
19
+ <%= erb :_namespace, layout: false, locals: {api_map: api_map, pin: pin} %>
20
+ <% elsif pin.is_a?(Solargraph::Pin::Method) %>
21
+ <%= erb :_method, layout: false, locals: {api_map: api_map, pin: pin} %>
22
22
  <% end %>
23
23
  <% end %>
@@ -106,7 +106,7 @@ module Solargraph
106
106
  def would_require? path
107
107
  require_paths.each do |rp|
108
108
  full = File.join rp, path
109
- return true if File.exist?(full) or File.exist?(full << ".rb")
109
+ return true if File.file?(full) || File.file?(full << ".rb")
110
110
  end
111
111
  false
112
112
  end
@@ -133,6 +133,15 @@ module Solargraph
133
133
  @gem_rbs_collection ||= read_rbs_collection_path
134
134
  end
135
135
 
136
+ def rbs_collection_config_path
137
+ @rbs_collection_config_path ||= begin
138
+ unless directory.empty? || directory == '*'
139
+ yaml_file = File.join(directory, 'rbs_collection.yaml')
140
+ yaml_file if File.file?(yaml_file)
141
+ end
142
+ end
143
+ end
144
+
136
145
  # Synchronize the workspace from the provided updater.
137
146
  #
138
147
  # @param updater [Source::Updater]
@@ -214,7 +223,7 @@ module Solargraph
214
223
  def configured_require_paths
215
224
  return ['lib'] if directory.empty?
216
225
  return [File.join(directory, 'lib')] if config.require_paths.empty?
217
- config.require_paths.map{|p| File.join(directory, p)}
226
+ config.require_paths.map { |p| File.join(directory, p) }
218
227
  end
219
228
 
220
229
  # @return [void]
@@ -230,10 +239,11 @@ module Solargraph
230
239
 
231
240
  # @return [String, nil]
232
241
  def read_rbs_collection_path
233
- yaml_file = File.join(directory, 'rbs_collection.yaml')
234
- return unless File.file?(yaml_file)
242
+ return unless rbs_collection_config_path
235
243
 
236
- YAML.load_file(yaml_file)&.fetch('path')
244
+ path = YAML.load_file(rbs_collection_config_path)&.fetch('path')
245
+ # make fully qualified
246
+ File.expand_path(path, directory)
237
247
  end
238
248
  end
239
249
  end