solargraph 0.60.4 → 0.61.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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/plugins.yml +1 -1
  3. data/.github/workflows/rspec.yml +3 -1
  4. data/CHANGELOG.md +16 -0
  5. data/Gemfile +0 -3
  6. data/lib/solargraph/api_map/index.rb +15 -2
  7. data/lib/solargraph/api_map/store.rb +13 -0
  8. data/lib/solargraph/api_map.rb +60 -81
  9. data/lib/solargraph/cache_dir.rb +58 -0
  10. data/lib/solargraph/collection/base.rb +50 -0
  11. data/lib/solargraph/collection/core.rb +17 -0
  12. data/lib/solargraph/collection/gem.rb +57 -0
  13. data/lib/solargraph/collection/rbs.rb +49 -0
  14. data/lib/solargraph/collection/stdlib.rb +25 -0
  15. data/lib/solargraph/collection.rb +31 -0
  16. data/lib/solargraph/convention.rb +5 -3
  17. data/lib/solargraph/diagnostics/require_not_found.rb +0 -4
  18. data/lib/solargraph/external.rb +159 -0
  19. data/lib/solargraph/language_server/message/text_document/definition.rb +4 -1
  20. data/lib/solargraph/language_server/message/text_document/hover.rb +1 -2
  21. data/lib/solargraph/library.rb +11 -24
  22. data/lib/solargraph/metagem.rb +80 -0
  23. data/lib/solargraph/parser/parser_gem/node_chainer.rb +22 -3
  24. data/lib/solargraph/pin/closure.rb +17 -0
  25. data/lib/solargraph/pin/factory_parameter.rb +84 -0
  26. data/lib/solargraph/pin.rb +1 -0
  27. data/lib/solargraph/rbs_map/base.rb +31 -0
  28. data/lib/solargraph/rbs_map/conversions.rb +3 -1
  29. data/lib/solargraph/rbs_map/{core_map.rb → core.rb} +18 -39
  30. data/lib/solargraph/rbs_map/core_fills.rb +1 -1
  31. data/lib/solargraph/rbs_map/gem.rb +13 -0
  32. data/lib/solargraph/rbs_map/helpers.rb +60 -0
  33. data/lib/solargraph/rbs_map/path.rb +19 -0
  34. data/lib/solargraph/rbs_map/stdlib.rb +24 -0
  35. data/lib/solargraph/rbs_map.rb +7 -198
  36. data/lib/solargraph/repo.rb +177 -0
  37. data/lib/solargraph/shell.rb +49 -99
  38. data/lib/solargraph/source/chain/call.rb +29 -4
  39. data/lib/solargraph/source/chain/literal.rb +17 -17
  40. data/lib/solargraph/source/chain/parameter.rb +79 -0
  41. data/lib/solargraph/source/chain.rb +8 -0
  42. data/lib/solargraph/source/source_chainer.rb +40 -44
  43. data/lib/solargraph/source_map/clip.rb +5 -3
  44. data/lib/solargraph/source_map/mapper.rb +6 -2
  45. data/lib/solargraph/source_map.rb +10 -5
  46. data/lib/solargraph/type_checker/rules.rb +2 -1
  47. data/lib/solargraph/version.rb +1 -1
  48. data/lib/solargraph/workspace.rb +0 -1
  49. data/lib/solargraph/yard_map/cache.rb +1 -1
  50. data/lib/solargraph/yard_map/directives/attribute_directive.rb +1 -1
  51. data/lib/solargraph/yard_map/directives/domain_directive.rb +1 -1
  52. data/lib/solargraph/yard_map/directives/method_directive.rb +1 -1
  53. data/lib/solargraph/yard_map/directives/override_directive.rb +1 -1
  54. data/lib/solargraph/yard_map/directives/parse_directive.rb +1 -1
  55. data/lib/solargraph/yard_map/directives/scope_directive.rb +178 -0
  56. data/lib/solargraph/yard_map/directives/visibility_directive.rb +1 -1
  57. data/lib/solargraph/yard_map/directives.rb +5 -2
  58. data/lib/solargraph/yard_map/helpers.rb +1 -1
  59. data/lib/solargraph/yard_map/macro.rb +34 -5
  60. data/lib/solargraph/yard_map/mapper/to_constant.rb +1 -1
  61. data/lib/solargraph/yard_map/mapper/to_method.rb +1 -1
  62. data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -1
  63. data/lib/solargraph/yard_map/mapper.rb +2 -2
  64. data/lib/solargraph/yard_map.rb +1 -1
  65. data/lib/solargraph/yardoc.rb +43 -60
  66. data/lib/solargraph.rb +6 -3
  67. data/solargraph.gemspec +1 -1
  68. metadata +22 -9
  69. data/lib/solargraph/doc_map.rb +0 -439
  70. data/lib/solargraph/gem_pins.rb +0 -87
  71. data/lib/solargraph/pin_cache.rb +0 -248
  72. data/lib/solargraph/rbs_map/stdlib_map.rb +0 -71
  73. data/lib/solargraph/workspace/gemspecs.rb +0 -373
@@ -38,12 +38,14 @@ module Solargraph
38
38
  result
39
39
  end
40
40
 
41
- # @param doc_map [DocMap]
41
+ # @todo Determine what argument needs to be passed here
42
+ #
43
+ # @param object [Object]
42
44
  # @return [Environ]
43
- def self.for_global doc_map
45
+ def self.for_global object
44
46
  result = Environ.new
45
47
  @@conventions.each do |conv|
46
- result.merge conv.global(doc_map)
48
+ result.merge conv.global(object)
47
49
  end
48
50
  result
49
51
  end
@@ -13,10 +13,6 @@ module Solargraph
13
13
  # @sg-ignore Need to add nil check here
14
14
  map = api_map.source_map(source.filename)
15
15
  map.requires.each { |ref| refs[ref.name] = ref }
16
- api_map.missing_docs.each do |r|
17
- next unless refs.key?(r)
18
- result.push docs_error(r, refs[r].location)
19
- end
20
16
  api_map.unresolved_requires.each do |r|
21
17
  next unless refs.key?(r)
22
18
  result.push require_error(r, refs[r].location)
@@ -0,0 +1,159 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'set'
4
+
5
+ module Solargraph
6
+ # @todo This class might need a way to track changes to the repo, e.g.,
7
+ # bundle or dependency updates
8
+ #
9
+ class External
10
+ # @return [String]
11
+ attr_reader :directory
12
+
13
+ # @return [Array<String>]
14
+ attr_reader :requires
15
+
16
+ # @param directory [String]
17
+ # @param requires [Array<String>]
18
+ def initialize directory, requires
19
+ @repo = Repo.new(directory)
20
+ @directory = directory
21
+ @requires = requires
22
+ update!
23
+ end
24
+
25
+ def unresolved_requires
26
+ @unresolved_requires ||= []
27
+ end
28
+
29
+ def unresolved_dependencies
30
+ @unresolved_dependencies ||= []
31
+ end
32
+
33
+ def loaded_gems
34
+ @loaded_gems ||= Set.new
35
+ end
36
+
37
+ def unloaded_gems
38
+ @unloaded_gems ||= Set.new
39
+ end
40
+
41
+ def pins
42
+ @pins ||= []
43
+ end
44
+
45
+ # @return [Integer] incremented whenever the external pin set is rebuilt
46
+ def generation
47
+ @generation ||= 0
48
+ end
49
+
50
+ # @param new_requires [Array<String>]
51
+ # @return [Boolean]
52
+ def update new_requires
53
+ return false if requires == new_requires && !cache_changed?
54
+
55
+ requires.replace new_requires
56
+ update!
57
+ true
58
+ end
59
+
60
+ # @return [Array<String>]
61
+ def rbs_collection_paths
62
+ @rbs_collection_paths ||= read_rbs_collection_paths
63
+ end
64
+
65
+ # @return [String, nil]
66
+ def rbs_collection_config_path
67
+ # @todo Get rid of the '*' case
68
+ @rbs_collection_config_path ||= unless directory.nil? || directory.empty? || directory == '*'
69
+ yaml_file = File.join(directory, 'rbs_collection.yaml')
70
+ yaml_file if File.file?(yaml_file)
71
+ end
72
+ end
73
+
74
+ private
75
+
76
+ def update!
77
+ @generation = generation + 1
78
+ clear_all
79
+ load_requires
80
+ load_rbs_collection
81
+ end
82
+
83
+ def cache_changed?
84
+ unloaded_gems.any? { |gem| Collection::Gem.cached?(gem) }
85
+ end
86
+
87
+ def load_requires
88
+ bundler_require = false
89
+
90
+ requires.uniq.each do |path|
91
+ if path == 'bundler/require'
92
+ bundler_require = true
93
+ end
94
+ if RbsMap::Stdlib.has?(path)
95
+ pins.concat Collection::Stdlib.load(path)
96
+ else
97
+ metagem = @repo.find_by_path(path)
98
+ next unresolved_requires.push(path) unless metagem
99
+ process_gem metagem
100
+ end
101
+ end
102
+
103
+ return unless bundler_require
104
+
105
+ @repo.find_by_group(:default).each { |metagem| process_gem metagem }
106
+ end
107
+
108
+ def load_rbs_collection
109
+ rbs_collection_pins = rbs_collection_paths.flat_map { |path| Collection::Rbs.load(path) }
110
+ pins.replace RbsMap::Helpers.combine(pins, rbs_collection_pins)
111
+ end
112
+
113
+ def clear_all
114
+ pins.clear
115
+ unresolved_requires.clear
116
+ unresolved_dependencies.clear
117
+ loaded_gems.clear
118
+ unloaded_gems.clear
119
+ end
120
+
121
+ def process_gem metagem
122
+ return if loaded_gems.include?(metagem) || unloaded_gems.include?(metagem)
123
+
124
+ if metagem.cacheable?
125
+ if Collection::Gem.cached?(metagem)
126
+ loaded_gems.add metagem
127
+ pins.concat Collection::Gem.load(metagem)
128
+ else
129
+ unloaded_gems.add metagem
130
+ end
131
+ else
132
+ loaded_gems.add metagem
133
+ pins.concat Collection::Gem.load(metagem)
134
+ end
135
+ load_dependencies metagem
136
+ end
137
+
138
+ def load_dependencies parent
139
+ parent.dependencies.each do |name|
140
+ next if loaded_gems.map(&:name).include?(name) || unloaded_gems.map(&:name).include?(name)
141
+ metagem = @repo.find_by_name(name)
142
+ next unresolved_dependencies.push(name) unless metagem
143
+ process_gem metagem
144
+ end
145
+ end
146
+
147
+ # @return [Array<String>]
148
+ def read_rbs_collection_paths
149
+ return [] unless rbs_collection_config_path
150
+
151
+ yaml = YAML.load_file(rbs_collection_config_path)
152
+ [File.expand_path(yaml.fetch('path'), directory)].concat(
153
+ yaml.fetch('sources', [])
154
+ .select { |source| source['type'] == 'local' && source['path'] }
155
+ .map { |source| File.expand_path(source['path'], directory) }
156
+ ).compact
157
+ end
158
+ end
159
+ end
@@ -29,7 +29,10 @@ module Solargraph
29
29
 
30
30
  # @return [Array<Hash>, nil]
31
31
  def require_location
32
- # @todo Terrible hack
32
+ # @todo Terrible hack - move this logic to [Solargraph::Source::Chain::Parameter]
33
+ # @example
34
+ # require 'click_me'
35
+ # ^^^^^^^^^^
33
36
  lib = host.library_for(params['textDocument']['uri'])
34
37
  rloc = Solargraph::Location.new(uri_to_file(params['textDocument']['uri']),
35
38
  Solargraph::Range.from_to(@line, @column, @line, @column))
@@ -11,8 +11,7 @@ module Solargraph
11
11
  contents = []
12
12
  suggestions = host.definitions_at(params['textDocument']['uri'], line, col)
13
13
  last_link = nil
14
- # @sg-ignore Need to add nil check here
15
- suggestions.each do |pin|
14
+ suggestions&.each do |pin|
16
15
  parts = []
17
16
  this_link = host.options['enablePages'] ? pin.link_documentation : pin.text_documentation
18
17
  parts.push this_link if !this_link.nil? && this_link != last_link
@@ -576,14 +576,8 @@ module Solargraph
576
576
  return unless source
577
577
  # @sg-ignore Wrong argument type for Solargraph::Workspace#has_file?: filename expected String, received String, nil
578
578
  return unless @current == source || workspace.has_file?(source.filename)
579
- if source_map_hash.key?(source.filename)
580
- new_map = Solargraph::SourceMap.map(source)
581
- # @sg-ignore OK if source.filename is nil
582
- source_map_hash[source.filename] = new_map
583
- else
584
- # @sg-ignore OK if source.filename is nil
585
- source_map_hash[source.filename] = Solargraph::SourceMap.map(source)
586
- end
579
+ # @sg-ignore OK if source.filename is nil
580
+ source_map_hash[source.filename] = Solargraph::SourceMap.map(source)
587
581
  end
588
582
 
589
583
  # @return [Set<Gem::Specification>]
@@ -595,10 +589,10 @@ module Solargraph
595
589
  def cache_next_gemspec
596
590
  return if @cache_progress
597
591
 
598
- spec = cacheable_specs.first
592
+ spec = api_map.unloaded_gems.first
599
593
  return end_cache_progress unless spec
600
594
 
601
- pending = api_map.uncached_gemspecs.length - cache_errors.length - 1
595
+ pending = api_map.unloaded_gems.length - cache_errors.length - 1
602
596
 
603
597
  if Yardoc.processing?(spec)
604
598
  logger.info "Enqueuing cache of #{spec.name} #{spec.version} (already being processed)"
@@ -615,7 +609,10 @@ module Solargraph
615
609
  logger.info "Caching #{spec.name} #{spec.version}"
616
610
  Thread.new do
617
611
  report_cache_progress spec.name, pending
618
- _o, e, s = Open3.capture3(workspace.command_path, 'cache', spec.name, spec.version.to_s)
612
+
613
+ cmd = [workspace.command_path, 'cache', spec.name]
614
+ cmd.push('--directory', workspace.directory) if workspace.directory
615
+ _o, e, s = Open3.capture3(*cmd)
619
616
  if s.success?
620
617
  logger.info "Cached #{spec.name} #{spec.version}"
621
618
  else
@@ -630,17 +627,6 @@ module Solargraph
630
627
  end
631
628
  end
632
629
 
633
- # @return [Array<Gem::Specification>]
634
- def cacheable_specs
635
- cacheable = api_map.uncached_yard_gemspecs +
636
- api_map.uncached_rbs_collection_gemspecs -
637
- queued_gemspec_cache -
638
- cache_errors.to_a
639
- return cacheable unless cacheable.empty?
640
-
641
- queued_gemspec_cache
642
- end
643
-
644
630
  # @return [Array<Gem::Specification>]
645
631
  def queued_gemspec_cache
646
632
  @queued_gemspec_cache ||= []
@@ -696,8 +682,9 @@ module Solargraph
696
682
  source_map_hash.each_value { |map| find_external_requires(map) }
697
683
  api_map.catalog bench
698
684
  logger.info "Catalog complete (#{api_map.source_maps.length} files, #{api_map.pins.length} pins)"
699
- logger.info "#{api_map.uncached_yard_gemspecs.length} uncached YARD gemspecs"
700
- logger.info "#{api_map.uncached_rbs_collection_gemspecs.length} uncached RBS collection gemspecs"
685
+ # @todo This needs work
686
+ # logger.info "#{api_map.uncached_yard_gemspecs.length} uncached YARD gemspecs"
687
+ # logger.info "#{api_map.uncached_rbs_collection_gemspecs.length} uncached RBS collection gemspecs"
701
688
  cache_next_gemspec
702
689
  @sync_count = 0
703
690
  end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Metagem
5
+ include Equality
6
+
7
+ # @return [String]
8
+ attr_reader :name
9
+
10
+ # @return [String]
11
+ attr_reader :full_path
12
+
13
+ # @return [String]
14
+ attr_reader :spec_file
15
+
16
+ # @return [String]
17
+ attr_reader :source
18
+
19
+ # @return [String]
20
+ attr_reader :version
21
+
22
+ # @return [Array<String>]
23
+ attr_reader :require_paths
24
+
25
+ # @return [Array<String>]
26
+ attr_reader :dependencies
27
+
28
+ # @return [String]
29
+ attr_reader :cache_name
30
+
31
+ def initialize name:, full_path:, spec_file:, source:, version:, require_paths:, dependencies:
32
+ @name = name
33
+ @full_path = full_path
34
+ @spec_file = spec_file
35
+ @source = source
36
+ @version = version
37
+ @require_paths = require_paths
38
+ @dependencies = dependencies
39
+ # @todo Possible change to cache names to make them more specific to sources
40
+ # @cache_name = "#{File.basename(full_path)}__#{source.gsub(/[^a-z0-9\-_]/i, '_')}" unless source.end_with?('Path')
41
+ # @todo Better path source detection
42
+ @cache_name = File.basename(full_path) unless source.start_with?('source at') || source.to_s.end_with?('::Path')
43
+ end
44
+
45
+ def cacheable?
46
+ !!@cache_name
47
+ end
48
+
49
+ def require? path
50
+ require_paths.any? do |req|
51
+ File.file?(File.join(full_path, req, "#{path}.rb"))
52
+ end
53
+ end
54
+
55
+ def to_specification
56
+ Gem::Specification.load(spec_file)
57
+ end
58
+
59
+ alias full_gem_path full_path
60
+
61
+ # @return [Array]
62
+ def equality_fields
63
+ # A version arrives as a String from a bundle definition and as a
64
+ # Gem::Version from a specification, so compare its string form.
65
+ [name, version.to_s, full_path, source]
66
+ end
67
+
68
+ # @param gem [Gem::Specification]
69
+ # @return [Metagem]
70
+ def self.from_specification gem
71
+ Metagem.new(name: gem.name,
72
+ full_path: gem.full_gem_path,
73
+ spec_file: gem.spec_file,
74
+ source: gem.source.to_s,
75
+ version: gem.version,
76
+ require_paths: gem.require_paths,
77
+ dependencies: gem.runtime_dependencies.map(&:name))
78
+ end
79
+ end
80
+ end
@@ -13,10 +13,12 @@ module Solargraph
13
13
  # @param node [Parser::AST::Node]
14
14
  # @param filename [String, nil]
15
15
  # @param parent [Parser::AST::Node, nil]
16
- def initialize node, filename = nil, parent = nil
16
+ # @param tree [Array<Parser::AST::Node>, nil]
17
+ def initialize node, filename = nil, parent = nil, tree = nil
17
18
  @node = node
18
19
  @filename = filename
19
20
  @parent = parent
21
+ @tree = tree
20
22
  end
21
23
 
22
24
  # @return [Source::Chain]
@@ -29,9 +31,10 @@ module Solargraph
29
31
  # @param node [Parser::AST::Node]
30
32
  # @param filename [String, nil]
31
33
  # @param parent [Parser::AST::Node, nil]
34
+ # @param tree [Parser::AST::Node, nil]
32
35
  # @return [Source::Chain]
33
- def chain node, filename = nil, parent = nil
34
- NodeChainer.new(node, filename, parent).chain
36
+ def chain node, filename = nil, parent = nil, tree = nil
37
+ NodeChainer.new(node, filename, parent, tree).chain
35
38
  end
36
39
 
37
40
  # @param code [String]
@@ -150,6 +153,13 @@ module Solargraph
150
153
  elsif n.type == :array
151
154
  chained_children = n.children.map { |c| NodeChainer.chain(c) }
152
155
  result.push Source::Chain::Array.new(chained_children, n)
156
+ elsif inside_method_call? # If the node is inside a method call, it may be a parameter.
157
+ lit = infer_literal_node_type(n)
158
+ if lit
159
+ method_call_chain = NodeChainer.chain(send_node, @filename, nil, [])
160
+ literal = Chain::Literal.new(lit, n)
161
+ result.push Chain::Parameter.new(literal, method_call_chain)
162
+ end
153
163
  else
154
164
  lit = infer_literal_node_type(n)
155
165
  result.push(lit ? Chain::Literal.new(lit, n) : Chain::Link.new)
@@ -158,6 +168,15 @@ module Solargraph
158
168
  result
159
169
  end
160
170
 
171
+ def inside_method_call?
172
+ !send_node.nil? && send_node != @node
173
+ end
174
+
175
+ # @return [Parser::AST::Node, nil]
176
+ def send_node
177
+ @send_node ||= @tree&.find { |n| n.type == :send }
178
+ end
179
+
161
180
  # @param node [Parser::AST::Node]
162
181
  def hash_is_splatted? node
163
182
  return false unless Parser.is_ast_node?(node) && node.type == :hash
@@ -6,6 +6,23 @@ module Solargraph
6
6
  # @return [::Symbol] :class or :instance
7
7
  attr_reader :scope
8
8
 
9
+ # Override the pin's scope.
10
+ #
11
+ # Scope is normally determined by the syntax that declared the pin, but
12
+ # YARD's `@!scope` directive can change it after the fact. Any values
13
+ # derived from the scope, such as the pin's path and context, are
14
+ # recalculated.
15
+ #
16
+ # @param scope [::Symbol] :class or :instance
17
+ # @return [void]
18
+ def scope= scope
19
+ return if @scope == scope
20
+
21
+ @scope = scope
22
+ # remove cached values generated from scope
23
+ reset_generated!
24
+ end
25
+
9
26
  # @param scope [::Symbol] :class or :instance
10
27
  # @param generics [::Array<Pin::String>, nil]
11
28
  # @param generic_defaults [Hash{String => ComplexType}]
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Pin
5
+ # A method parameter with a literal value used in a factory method.
6
+ #
7
+ # @example
8
+ # RSpec.shared_examples 'some examples'
9
+ #
10
+ # FactoryParameter.new(
11
+ # method_name: 'shared_examples',
12
+ # method_namespace: 'RSpec',
13
+ # method_scope: :class,
14
+ # param_name: 'name',
15
+ # value: 'some examples',
16
+ # decl: :arg,
17
+ # return_type: 'void'
18
+ # )
19
+ class FactoryParameter < Base
20
+ # @return [String]
21
+ attr_reader :method_name
22
+ # @return [String]
23
+ attr_reader :method_namespace
24
+ # @return [Symbol] :class or :instance
25
+ attr_reader :method_scope
26
+ # @return [String, nil]
27
+ attr_reader :param_name
28
+ # @return [::String, ::Symbol] The literal value
29
+ attr_reader :value
30
+ # @return [::Symbol] :arg, :optarg, :kwarg, :kwoptarg, :restarg, :kwrestarg, :block, :blockarg
31
+ attr_reader :decl
32
+ # @return [Location, nil]
33
+ attr_reader :location
34
+
35
+ # @param method_name [String] The name of the method that this parameter belongs to
36
+ # @param method_namespace [String] The class of the method that this parameter belongs to
37
+ # @param method_scope [Symbol] The scope of the method, either :class or :instance
38
+ # @param param_name [String, nil] The name of the parameter
39
+ # @param value [String, Symbol] The value of the parameter
40
+ # @param decl [::Symbol] :arg, :kwarg
41
+ # @param location [Location, nil] The location of the parameter in the source code
42
+ # @param return_type [String, nil] The return type of the method that this parameter belongs to
43
+ def initialize method_name:,
44
+ method_namespace:,
45
+ method_scope:,
46
+ param_name:,
47
+ value:,
48
+ return_type:,
49
+ decl: :arg,
50
+ location: nil
51
+ super(location: location)
52
+ @method_name = method_name
53
+ @method_namespace = method_namespace
54
+ @method_scope = method_scope
55
+ @param_name = param_name
56
+ @value = value
57
+ @decl = decl
58
+ @return_type = return_type
59
+ end
60
+
61
+ def name
62
+ param_name
63
+ end
64
+
65
+ def text_documentation
66
+ "#{method_path}(#{param_name}) = #{value.inspect}"
67
+ end
68
+
69
+ # @return [String]
70
+ def method_path
71
+ # @sg-ignore false failure on method_scope "Wrong argument type for Solargraph::Pin::Base#==: other expected
72
+ # Solargraph::Pin::Base, received :instance"
73
+ @method_path ||= "#{method_namespace}#{method_scope == :instance ? '#' : '.'}#{method_name}"
74
+ end
75
+
76
+ private
77
+
78
+ def inner_desc
79
+ "method_path=#{method_path}, value=#{value.inspect}, decl=#{decl.inspect}, " \
80
+ "return_type=#{return_type&.to_s || 'nil'}"
81
+ end
82
+ end
83
+ end
84
+ end
@@ -38,6 +38,7 @@ module Solargraph
38
38
  autoload :Until, 'solargraph/pin/until'
39
39
  autoload :While, 'solargraph/pin/while'
40
40
  autoload :Callable, 'solargraph/pin/callable'
41
+ autoload :FactoryParameter, 'solargraph/pin/factory_parameter'
41
42
  autoload :CompoundStatement,
42
43
  'solargraph/pin/compound_statement'
43
44
 
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module RbsMap
5
+ class Base
6
+ def pins
7
+ @pins ||= RbsMap::Conversions.new(loader: loader).pins
8
+ end
9
+
10
+ # @return [RBS::Repository]
11
+ def repository
12
+ @repository ||= RBS::Repository.new(no_stdlib: true)
13
+ end
14
+
15
+ # @return [RBS::EnvironmentLoader]
16
+ def loader
17
+ @loader ||= RBS::EnvironmentLoader.new(core_root: nil, repository: repository)
18
+ end
19
+
20
+ # @param path [String]
21
+ # @return [Array<Pin::Base>]
22
+ def path_pins path
23
+ pins.select { |p| p.path == path }
24
+ end
25
+
26
+ def self.pins(...)
27
+ new(...).pins
28
+ end
29
+ end
30
+ end
31
+ end
@@ -3,7 +3,7 @@
3
3
  require 'rbs'
4
4
 
5
5
  module Solargraph
6
- class RbsMap
6
+ module RbsMap
7
7
  # Functions for converting RBS declarations to Solargraph pins
8
8
  #
9
9
  class Conversions
@@ -49,6 +49,8 @@ module Solargraph
49
49
  return
50
50
  end
51
51
  environment.declarations.each { |decl| convert_decl_to_pin(decl, Solargraph::Pin::ROOT_PIN) }
52
+ rescue RBS::DuplicatedDeclarationError => e
53
+ Solargraph.logger.warn "RBS conversion failed due to duplicate declarations: [#{e.class}] #{e.message}"
52
54
  end
53
55
 
54
56
  # @param decl [RBS::AST::Declarations::Base]
@@ -1,39 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Solargraph
4
- class RbsMap
5
- # Ruby core pins
6
- #
7
- class CoreMap
8
- include Logging
4
+ module RbsMap
5
+ class Core < Base
6
+ FILLS_DIRECTORY = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'rbs', 'fills'))
9
7
 
10
- def resolved?
11
- true
8
+ def pins
9
+ @pins ||= generate_pins
12
10
  end
13
11
 
14
- FILLS_DIRECTORY = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'rbs', 'fills'))
15
-
16
- def initialize; end
12
+ # @return [RBS::EnvironmentLoader]
13
+ def loader
14
+ @loader ||= RBS::EnvironmentLoader.new(repository: repository)
15
+ end
17
16
 
18
- # @param out [IO, nil] output stream for logging
19
- # @return [Enumerable<Pin::Base>]
20
- def pins out: $stderr
21
- return @pins if @pins
22
- @pins = cache_core(out: out)
17
+ def repository
18
+ @repository ||= RBS::Repository.new(no_stdlib: false)
23
19
  end
24
20
 
25
- # @param out [StringIO, IO, nil] output stream for logging
21
+ private
22
+
26
23
  # @return [Array<Pin::Base>]
27
- def cache_core out: $stderr
28
- new_pins = []
29
- cache = PinCache.deserialize_core
30
- return cache if cache
31
- new_pins.concat conversions.pins
24
+ def generate_pins
25
+ new_pins = RbsMap::Conversions.new(loader: loader).pins
32
26
 
33
27
  # Avoid RBS::DuplicatedDeclarationError by loading in a different EnvironmentLoader
34
28
  fill_loader = RBS::EnvironmentLoader.new(core_root: nil, repository: RBS::Repository.new(no_stdlib: false))
35
29
  fill_loader.add(path: Pathname(FILLS_DIRECTORY))
36
- out&.puts 'Caching RBS pins for Ruby core'
37
30
  fill_conversions = Conversions.new(loader: fill_loader)
38
31
  new_pins.concat fill_conversions.pins
39
32
 
@@ -42,23 +35,9 @@ module Solargraph
42
35
 
43
36
  # process overrides, then remove any which couldn't be resolved
44
37
  processed = ApiMap::Store.new(new_pins).pins.reject { |p| p.is_a?(Solargraph::Pin::Reference::Override) }
45
- new_pins.replace processed
46
-
47
- PinCache.serialize_core new_pins
48
-
49
- new_pins
50
- end
51
-
52
- private
53
-
54
- # @return [RBS::EnvironmentLoader]
55
- def loader
56
- @loader ||= RBS::EnvironmentLoader.new(repository: RBS::Repository.new(no_stdlib: false))
57
- end
58
-
59
- # @return [Conversions]
60
- def conversions
61
- @conversions ||= Conversions.new(loader: loader)
38
+ # serial = Marshal.dump(processed)
39
+ # File.write cache_file, serial, mode: 'wb'
40
+ processed
62
41
  end
63
42
  end
64
43
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Solargraph
4
- class RbsMap
4
+ module RbsMap
5
5
  # Override pins to fill gaps in RbsMap::CoreMap coverage
6
6
  #
7
7
  module CoreFills