solargraph 0.60.4 → 0.62.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 (127) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/linting.yml +24 -2
  3. data/.github/workflows/plugins.yml +19 -1
  4. data/.github/workflows/rspec.yml +17 -2
  5. data/.github/workflows/typecheck.yml +6 -0
  6. data/CHANGELOG.md +54 -0
  7. data/Gemfile +0 -3
  8. data/lib/solargraph/api_map/index.rb +28 -4
  9. data/lib/solargraph/api_map/store.rb +19 -0
  10. data/lib/solargraph/api_map.rb +91 -80
  11. data/lib/solargraph/cache_dir.rb +58 -0
  12. data/lib/solargraph/collection/base.rb +50 -0
  13. data/lib/solargraph/collection/core.rb +17 -0
  14. data/lib/solargraph/collection/gem.rb +59 -0
  15. data/lib/solargraph/collection/stdlib.rb +25 -0
  16. data/lib/solargraph/collection.rb +30 -0
  17. data/lib/solargraph/complex_type/unique_type.rb +13 -0
  18. data/lib/solargraph/complex_type.rb +23 -3
  19. data/lib/solargraph/convention.rb +5 -7
  20. data/lib/solargraph/diagnostics/require_not_found.rb +0 -4
  21. data/lib/solargraph/diagnostics/type_check.rb +0 -1
  22. data/lib/solargraph/external.rb +187 -0
  23. data/lib/solargraph/language_server/host/diagnoser.rb +1 -1
  24. data/lib/solargraph/language_server/host/dispatch.rb +4 -2
  25. data/lib/solargraph/language_server/host.rb +10 -2
  26. data/lib/solargraph/language_server/message/completion_item/resolve.rb +10 -3
  27. data/lib/solargraph/language_server/message/text_document/definition.rb +5 -2
  28. data/lib/solargraph/language_server/message/text_document/hover.rb +1 -2
  29. data/lib/solargraph/library.rb +26 -53
  30. data/lib/solargraph/metagem.rb +80 -0
  31. data/lib/solargraph/parser/node_processor/base.rb +6 -0
  32. data/lib/solargraph/parser/parser_gem/node_chainer.rb +22 -3
  33. data/lib/solargraph/parser/parser_gem/node_methods.rb +29 -6
  34. data/lib/solargraph/parser/parser_gem/node_processors/class_definition/class_assignment_node.rb +98 -0
  35. data/lib/solargraph/parser/parser_gem/node_processors/class_definition.rb +54 -0
  36. data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +1 -0
  37. data/lib/solargraph/parser/parser_gem/node_processors/data_definition/data_assignment_node.rb +65 -0
  38. data/lib/solargraph/parser/parser_gem/node_processors/data_definition/data_definition_node.rb +97 -0
  39. data/lib/solargraph/parser/parser_gem/node_processors/data_definition.rb +110 -0
  40. data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +1 -0
  41. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +2 -0
  42. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +1 -0
  43. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +185 -0
  44. data/lib/solargraph/parser/parser_gem/node_processors/struct_definition/struct_assignment_node.rb +66 -0
  45. data/lib/solargraph/parser/parser_gem/node_processors/struct_definition/struct_definition_node.rb +108 -0
  46. data/lib/solargraph/parser/parser_gem/node_processors/struct_definition.rb +170 -0
  47. data/lib/solargraph/parser/parser_gem/node_processors.rb +33 -29
  48. data/lib/solargraph/pin/base.rb +25 -1
  49. data/lib/solargraph/pin/base_variable.rb +31 -1
  50. data/lib/solargraph/pin/callable.rb +11 -2
  51. data/lib/solargraph/pin/closure.rb +17 -0
  52. data/lib/solargraph/pin/delegated_method.rb +5 -0
  53. data/lib/solargraph/pin/duck_method.rb +36 -16
  54. data/lib/solargraph/pin/factory_parameter.rb +84 -0
  55. data/lib/solargraph/pin/instance_variable.rb +45 -0
  56. data/lib/solargraph/pin/method.rb +10 -0
  57. data/lib/solargraph/pin/method_alias.rb +4 -0
  58. data/lib/solargraph/pin/parameter.rb +1 -1
  59. data/lib/solargraph/pin/reference/included_mixin.rb +22 -0
  60. data/lib/solargraph/pin/reference.rb +1 -0
  61. data/lib/solargraph/pin.rb +1 -0
  62. data/lib/solargraph/plugin/active_support.rb +100 -0
  63. data/lib/solargraph/plugin/addon.rb +16 -0
  64. data/lib/solargraph/plugin/base.rb +25 -0
  65. data/lib/solargraph/plugin/panel.rb +37 -0
  66. data/lib/solargraph/plugin.rb +26 -0
  67. data/lib/solargraph/rbs_collection.rb +119 -0
  68. data/lib/solargraph/rbs_map/base.rb +31 -0
  69. data/lib/solargraph/rbs_map/conversions.rb +109 -48
  70. data/lib/solargraph/rbs_map/{core_map.rb → core.rb} +18 -39
  71. data/lib/solargraph/rbs_map/core_fills.rb +1 -1
  72. data/lib/solargraph/rbs_map/gem.rb +16 -0
  73. data/lib/solargraph/rbs_map/helpers.rb +61 -0
  74. data/lib/solargraph/rbs_map/path.rb +19 -0
  75. data/lib/solargraph/rbs_map/stdlib.rb +24 -0
  76. data/lib/solargraph/rbs_map.rb +7 -198
  77. data/lib/solargraph/rbs_translator.rb +105 -70
  78. data/lib/solargraph/repo.rb +177 -0
  79. data/lib/solargraph/shell.rb +49 -99
  80. data/lib/solargraph/source/chain/call.rb +58 -14
  81. data/lib/solargraph/source/chain/literal.rb +17 -17
  82. data/lib/solargraph/source/chain/parameter.rb +79 -0
  83. data/lib/solargraph/source/chain.rb +8 -0
  84. data/lib/solargraph/source/node_map.rb +27 -0
  85. data/lib/solargraph/source/source_chainer.rb +40 -44
  86. data/lib/solargraph/source.rb +17 -0
  87. data/lib/solargraph/source_map/call.rb +18 -0
  88. data/lib/solargraph/source_map/clip.rb +5 -3
  89. data/lib/solargraph/source_map/mapper.rb +6 -2
  90. data/lib/solargraph/source_map.rb +28 -9
  91. data/lib/solargraph/type_checker/rules.rb +3 -2
  92. data/lib/solargraph/type_checker.rb +4 -1
  93. data/lib/solargraph/version.rb +1 -1
  94. data/lib/solargraph/workspace.rb +0 -1
  95. data/lib/solargraph/yard_map/cache.rb +1 -1
  96. data/lib/solargraph/yard_map/directives/attribute_directive.rb +1 -1
  97. data/lib/solargraph/yard_map/directives/domain_directive.rb +1 -1
  98. data/lib/solargraph/yard_map/directives/method_directive.rb +1 -1
  99. data/lib/solargraph/yard_map/directives/override_directive.rb +1 -1
  100. data/lib/solargraph/yard_map/directives/parse_directive.rb +1 -1
  101. data/lib/solargraph/yard_map/directives/scope_directive.rb +178 -0
  102. data/lib/solargraph/yard_map/directives/visibility_directive.rb +1 -1
  103. data/lib/solargraph/yard_map/directives.rb +5 -2
  104. data/lib/solargraph/yard_map/helpers.rb +1 -1
  105. data/lib/solargraph/yard_map/macro.rb +85 -6
  106. data/lib/solargraph/yard_map/mapper/to_constant.rb +1 -1
  107. data/lib/solargraph/yard_map/mapper/to_method.rb +1 -1
  108. data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -1
  109. data/lib/solargraph/yard_map/mapper.rb +2 -2
  110. data/lib/solargraph/yard_map.rb +1 -1
  111. data/lib/solargraph/yardoc.rb +43 -60
  112. data/lib/solargraph.rb +8 -3
  113. data/rbs/fills/boolean/0/boolean.rbs +12 -0
  114. data/solargraph.gemspec +2 -2
  115. metadata +41 -18
  116. data/lib/solargraph/convention/active_support_concern.rb +0 -111
  117. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +0 -61
  118. data/lib/solargraph/convention/data_definition/data_definition_node.rb +0 -93
  119. data/lib/solargraph/convention/data_definition.rb +0 -108
  120. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +0 -62
  121. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +0 -103
  122. data/lib/solargraph/convention/struct_definition.rb +0 -168
  123. data/lib/solargraph/doc_map.rb +0 -439
  124. data/lib/solargraph/gem_pins.rb +0 -87
  125. data/lib/solargraph/pin_cache.rb +0 -248
  126. data/lib/solargraph/rbs_map/stdlib_map.rb +0 -71
  127. data/lib/solargraph/workspace/gemspecs.rb +0 -373
@@ -370,6 +370,13 @@ module Solargraph
370
370
  @explicit
371
371
  end
372
372
 
373
+ # False for method pins synthesized from a class-body statement rather than parsed from a def.
374
+ #
375
+ # @return [Boolean]
376
+ def body?
377
+ !attribute?
378
+ end
379
+
373
380
  def attribute?
374
381
  @attribute
375
382
  end
@@ -387,6 +394,9 @@ module Solargraph
387
394
 
388
395
  def probe api_map
389
396
  attribute? ? infer_from_iv(api_map) : infer_from_return_nodes(api_map)
397
+ rescue FileNotFoundError
398
+ # @todo Necessary for pins from source maps that are not part of the workspace
399
+ ComplexType::UNDEFINED
390
400
  end
391
401
 
392
402
  # @return [::Array<Pin::Signature>]
@@ -7,6 +7,10 @@ module Solargraph
7
7
  # methods from included modules.
8
8
  #
9
9
  class MethodAlias < Method
10
+ # @return [Boolean]
11
+ def body?
12
+ false
13
+ end
10
14
  # @return [::Symbol]
11
15
  attr_reader :scope
12
16
 
@@ -115,7 +115,7 @@ module Solargraph
115
115
  end
116
116
 
117
117
  def rest?
118
- %i[restarg kwrestarg].include?(decl)
118
+ %i[restarg kwrestarg forward_args].include?(decl)
119
119
  end
120
120
 
121
121
  def block?
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Pin
5
+ class Reference
6
+ # A mixin that a module's +self.included+ hook applies to every class
7
+ # that includes the module, e.g. +base.extend ClassMethods+. The closure
8
+ # is the hooking module and the name is the mixed-in module.
9
+ class IncludedMixin < Reference
10
+ # @return [::Symbol] :include, :prepend or :extend
11
+ attr_reader :keyword
12
+
13
+ # @param keyword [::Symbol] :include, :prepend or :extend
14
+ # @param splat [Hash{Symbol => Object}]
15
+ def initialize keyword:, **splat
16
+ super(**splat)
17
+ @keyword = keyword
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -8,6 +8,7 @@ module Solargraph
8
8
  autoload :Include, 'solargraph/pin/reference/include'
9
9
  autoload :Prepend, 'solargraph/pin/reference/prepend'
10
10
  autoload :Extend, 'solargraph/pin/reference/extend'
11
+ autoload :IncludedMixin, 'solargraph/pin/reference/included_mixin'
11
12
  autoload :Override, 'solargraph/pin/reference/override'
12
13
  autoload :TypeAlias, 'solargraph/pin/reference/type_alias'
13
14
 
@@ -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,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Plugin
5
+ class ActiveSupport < Base
6
+ ATTRIBUTE_NAME = /\A[_A-Za-z]\w*\z/
7
+
8
+ def addon
9
+ return EMPTY_ADDON unless gem_names.include?('activesupport')
10
+
11
+ Addon.new(pins: classmethod_pins + attribute_pins)
12
+ end
13
+
14
+ private
15
+
16
+ def classmethod_pins
17
+ pins_by_class(Pin::Reference::Include).map do |inc|
18
+ Pin::Reference::Extend.new(name: "#{inc.name}::ClassMethods", closure: inc.closure)
19
+ end
20
+ end
21
+
22
+ def attribute_pins
23
+ source_maps.flat_map { |map| map.calls(:class_attribute, :mattr_accessor, :cattr_accessor, :mattr_reader, :cattr_reader, :mattr_writer, :cattr_writer, :config_accessor) }
24
+ .select { |call| call.closure.is_a?(Pin::Namespace) }
25
+ .flat_map { |call| generate_call_pins(call) }
26
+ .compact
27
+ end
28
+
29
+ # @param call [SourceMap::Call]
30
+ def generate_call_pins call
31
+ options = option_hash(call.chain.links.last.arguments.last)
32
+ method_names = call.chain.links.last.arguments.select(&:literal?).map { |arg| arg.links.last.value }.compact
33
+ .grep(ATTRIBUTE_NAME)
34
+ case call.chain.links.last.word
35
+ when 'class_attribute'
36
+ class_suffixes = ['', '=']
37
+ class_suffixes.push '?' if options[:instance_predicate]
38
+ instance_suffixes = []
39
+ instance_suffixes.push '' if options[:instance_accessor] && options[:instance_reader]
40
+ instance_suffixes.push '=' if options[:instance_accessor] && options[:instance_writer]
41
+ instance_suffixes.push '?' if options[:instance_accessor] && options[:instance_predicate]
42
+ method_names.flat_map { |name| method_pins(name, class_suffixes, instance_suffixes, call) }
43
+ when 'mattr_accessor', 'cattr_accessor', 'config_accessor'
44
+ class_suffixes = ['', '=']
45
+ instance_suffixes = []
46
+ instance_suffixes.push '' if options[:instance_accessor] && options[:instance_reader]
47
+ instance_suffixes.push '=' if options[:instance_accessor] && options[:instance_writer]
48
+ method_names.flat_map { |name| method_pins(name, class_suffixes, instance_suffixes, call) }
49
+ when 'mattr_reader', 'cattr_reader'
50
+ class_suffixes = ['']
51
+ instance_suffixes = []
52
+ instance_suffixes.push '' if options[:instance_accessor] && options[:instance_reader]
53
+ method_names.flat_map { |name| method_pins(name, class_suffixes, instance_suffixes, call) }
54
+ when 'mattr_writer', 'cattr_writer'
55
+ class_suffixes = ['=']
56
+ instance_suffixes = []
57
+ instance_suffixes.push '=' if options[:instance_accessor] && options[:instance_writer]
58
+ method_names.flat_map { |name| method_pins(name, class_suffixes, instance_suffixes, call) }
59
+ else
60
+ []
61
+ end
62
+ end
63
+
64
+ def option_hash args
65
+ defaults = {
66
+ instance_reader: true,
67
+ instance_writer: true,
68
+ instance_accessor: true,
69
+ instance_predicate: true
70
+ }
71
+ kwargs = Parser::ParserGem::NodeMethods.convert_hash(args.node)
72
+ .select { |_, val| val.literal? }
73
+ .transform_values { |val| val.links.last.value }
74
+ return defaults unless kwargs.is_a?(Hash)
75
+ defaults.merge(kwargs)
76
+ end
77
+
78
+ # @param call [SourceMap::Call]
79
+ # @param name [String]
80
+ # @param class_suffixes [Array<String>]
81
+ # @param instance_suffixes [Array<String>]
82
+ def method_pins name, class_suffixes, instance_suffixes, call
83
+ comments = call.source_map.source.comments_for(call.chain.node)
84
+ location = Solargraph::Location.new(call.closure.filename, Solargraph::Range.from_node(call.chain.node))
85
+ class_suffixes.map do |sfx|
86
+ Pin::Method.new(name: "#{name}#{sfx}", closure: call.closure, scope: :class, attribute: true, location: location, comments: comments).tap do |pin|
87
+ next unless sfx == '='
88
+ pin.parameters.push Pin::Parameter.new(name: 'value', closure: pin)
89
+ end
90
+ end +
91
+ instance_suffixes.map do |sfx|
92
+ Pin::Method.new(name: "#{name}#{sfx}", closure: call.closure, scope: :instance, attribute: true, location: location, comments: comments).tap do |pin|
93
+ next unless sfx == '='
94
+ pin.parameters.push Pin::Parameter.new(name: 'value', closure: pin)
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Plugin
5
+ class Addon
6
+ attr_reader :gem_names, :pins
7
+
8
+ # @param gem_names [Array<String>]
9
+ # @param pins [Array<Pin::Base>]
10
+ def initialize gem_names: [], pins: []
11
+ @gem_names = gem_names
12
+ @pins = pins
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ module Solargraph
6
+ module Plugin
7
+ class Base
8
+ extend Forwardable
9
+
10
+ attr_reader :panel
11
+
12
+ def_delegators :@panel, :pins, :pins_by_class, :pins_by_path, :gem_names, :source_maps
13
+
14
+ # @param panel [Panel]
15
+ def initialize panel
16
+ @panel = panel
17
+ end
18
+
19
+ # @return [Addon]
20
+ def addon
21
+ EMPTY_ADDON
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Plugin
5
+ class Panel
6
+ attr_reader :source_maps, :live_map, :gem_names
7
+
8
+ def initialize source_maps: [], live_map: nil, gem_names: []
9
+ @source_maps = source_maps
10
+ @live_map = live_map
11
+ @gem_names = gem_names
12
+ end
13
+
14
+ def pins
15
+ @pins ||= source_maps.flat_map(&:pins)
16
+ end
17
+
18
+ def pins_by_class klass
19
+ pin_class_hash[klass] || []
20
+ end
21
+
22
+ def pins_by_path path
23
+ pin_path_hash[path] || []
24
+ end
25
+
26
+ private
27
+
28
+ def pin_class_hash
29
+ @pin_class_hash ||= pins.to_set.classify(&:class)
30
+ end
31
+
32
+ def pin_path_hash
33
+ @pin_path_hash ||= pins.to_set.classify(&:path)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Plugin
5
+ autoload :Addon, 'solargraph/plugin/addon'
6
+ autoload :Base, 'solargraph/plugin/base'
7
+ autoload :Panel, 'solargraph/plugin/panel'
8
+ autoload :ActiveSupport, 'solargraph/plugin/active_support'
9
+
10
+ EMPTY_ADDON = Addon.new.freeze
11
+
12
+ def self.registry
13
+ @registry ||= Set.new
14
+ end
15
+
16
+ def self.register klass
17
+ registry.add klass
18
+ end
19
+
20
+ def self.unregister klass
21
+ registry.delete klass
22
+ end
23
+
24
+ Plugin.register ActiveSupport
25
+ end
26
+ end
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ # The RBS collection declared by a project's rbs_collection.lock.yaml.
5
+ #
6
+ class RbsCollection
7
+ attr_reader :lockfile
8
+
9
+ def initialize lockfile
10
+ @lockfile = File.expand_path(lockfile) if lockfile
11
+ end
12
+
13
+ # @param metagem [Metagem]
14
+ # @return [Array<Pin::Base>]
15
+ def load metagem
16
+ key = best_key(metagem)
17
+ return [] unless key
18
+ mem_cache[key] ||= RbsMap::Path.pins(gem_path_map[key])
19
+ end
20
+
21
+ def gem_keys
22
+ gem_path_map.keys
23
+ end
24
+
25
+ # The names of the stdlib signature sets declared by the collection.
26
+ #
27
+ # +rbs collection install+ resolves these to the signatures which ship
28
+ # with the rbs gem instead of copying them into the collection directory,
29
+ # so they can never be located by a gem name/version lookup.
30
+ #
31
+ # @return [Array<String>]
32
+ def stdlib_names
33
+ @stdlib_names ||= raw_data[:gems].select { |gem| gem.dig(:source, :type).to_s == 'stdlib' }
34
+ .map { |gem| gem[:name].to_s }.uniq
35
+ end
36
+
37
+ private
38
+
39
+ def gem_path_map
40
+ @gem_path_map ||= raw_data[:gems].to_h { |gem| ["#{gem[:name]}-#{gem[:version]}", gem_source_path(gem)] }
41
+ end
42
+
43
+ # The versions available in the collection for each gem name.
44
+ #
45
+ # @return [Hash{String => Array<String>}]
46
+ def versions_by_name
47
+ @versions_by_name ||= raw_data[:gems].group_by { |gem| gem[:name].to_s }
48
+ .transform_values { |gems| gems.map { |gem| gem[:version].to_s } }
49
+ end
50
+
51
+ def best_key metagem
52
+ key = "#{metagem.name}-#{metagem.version}"
53
+ return key if gem_path_map.key?(key)
54
+
55
+ full_key = "#{metagem.name}-#{metagem.version}."
56
+ zero_key = "#{metagem.name}-0"
57
+ found = gem_path_map.find { |key, _| full_key.start_with?("#{key}.") } ||
58
+ gem_path_map.find { |key, _| key == zero_key }
59
+ found&.first || closest_key(metagem)
60
+ end
61
+
62
+ # Signature collections version their directories independently from the
63
+ # gems they describe. gem_rbs_collection, for example, provides
64
+ # +actionpack/6.0+ for every Rails 6 and 7 release and +devise/4.9+ for
65
+ # Devise 4 and 5. When no directory matches a gem's version, fall back to
66
+ # the closest version the collection provides for that gem, preferring the
67
+ # highest one that does not exceed the gem's version.
68
+ #
69
+ # @param metagem [Metagem]
70
+ # @return [String, nil]
71
+ def closest_key metagem
72
+ versions = versions_by_name[metagem.name.to_s]
73
+ return nil if versions.nil? || versions.empty?
74
+ return "#{metagem.name}-#{versions.first}" if versions.size == 1
75
+ parsed = versions.map { |version| [version, parse_version(version)] }
76
+ usable = parsed.compact
77
+ gem_version = parse_version(metagem.version)
78
+ chosen = if gem_version
79
+ usable.reject { |_, parsed_version| parsed_version > gem_version }.max_by { |_, parsed_version| parsed_version }
80
+ end
81
+ chosen ||= usable.min_by { |_, parsed_version| parsed_version }
82
+ chosen ||= parsed.first
83
+ "#{metagem.name}-#{chosen[0]}"
84
+ end
85
+
86
+ # @param value [Object]
87
+ # @return [Gem::Version, nil]
88
+ def parse_version value
89
+ Gem::Version.new value.to_s
90
+ rescue ArgumentError
91
+ nil
92
+ end
93
+
94
+ # @param gem_hash [Hash]
95
+ def gem_source_path gem_hash
96
+ root_path = gem_hash.dig(:source, :path) || raw_data[:path]
97
+ return unless root_path
98
+ gem_path = File.join(root_path, gem_hash[:name], gem_hash[:version])
99
+ File.expand_path(gem_path, File.dirname(lockfile))
100
+ end
101
+
102
+ def gem_rbs_collection_path
103
+ @gem_rbs_collection_path ||= File.expand_path(raw_data[:path]) if raw_data[:path]
104
+ end
105
+
106
+ # @return [Hash]
107
+ def raw_data
108
+ @raw_data ||= if lockfile && File.file?(lockfile)
109
+ YAML.load_file(lockfile, symbolize_names: true)
110
+ else
111
+ { gems: [] }
112
+ end
113
+ end
114
+
115
+ def mem_cache
116
+ @mem_cache ||= {}
117
+ end
118
+ end
119
+ end
@@ -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