Module: Solargraph::GemPins

Extended by:
Logging
Defined in:
lib/solargraph/gem_pins.rb

Overview

A utility for building gem pins from a combination of YARD and RBS documentation.

Constant Summary

Constants included from Logging

Logging::DEFAULT_LOG_LEVEL, Logging::LOG_LEVELS

Class Method Summary collapse

Methods included from Logging

logger

Class Method Details

.build_yard_pins(yard_plugins, gemspec) ⇒ Array<Pin::Base>



47
48
49
50
51
# File 'lib/solargraph/gem_pins.rb', line 47

def self.build_yard_pins(yard_plugins, gemspec)
  Yardoc.cache(yard_plugins, gemspec) unless Yardoc.cached?(gemspec)
  yardoc = Yardoc.load!(gemspec)
  YardMap::Mapper.new(yardoc, gemspec).map
end

.combine(yard_pins, rbs_pins) ⇒ Array<Pin::Base>



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/solargraph/gem_pins.rb', line 57

def self.combine(yard_pins, rbs_pins)
  in_yard = Set.new
  rbs_api_map = Solargraph::ApiMap.new(pins: rbs_pins)
  combined = yard_pins.map do |yard_pin|
    in_yard.add yard_pin.path
    rbs_pin = rbs_api_map.get_path_pins(yard_pin.path).filter { |pin| pin.is_a? Pin::Method }.first
    next yard_pin unless rbs_pin && yard_pin.class == Pin::Method

    unless rbs_pin
      logger.debug { "GemPins.combine: No rbs pin for #{yard_pin.path} - using YARD's '#{yard_pin.inspect} (return_type=#{yard_pin.return_type}; signatures=#{yard_pin.signatures})" }
      next yard_pin
    end

    out = combine_method_pins(rbs_pin, yard_pin)
    logger.debug { "GemPins.combine: Combining yard.path=#{yard_pin.path} - rbs=#{rbs_pin.inspect} with yard=#{yard_pin.inspect} into #{out}" }
    out
  end
  in_rbs_only = rbs_pins.select do |pin|
    pin.path.nil? || !in_yard.include?(pin.path)
  end
  out = combined + in_rbs_only
  logger.debug { "GemPins#combine: Returning #{out.length} combined pins" }
  out
end

.combine_method_pins(*pins) ⇒ Pin::Method?



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/solargraph/gem_pins.rb', line 27

def self.combine_method_pins(*pins)
  # @type [Pin::Method, nil]

  combined_pin = nil
  out = pins.reduce(combined_pin) do |memo, pin|
    next pin if memo.nil?
    if memo == pin && memo.source != :combined
      # @todo we should track down situations where we are handled

      #   the same pin from the same source here and eliminate them -

      #   this is an efficiency workaround for now

      next memo
    end
    memo.combine_with(pin)
  end
  logger.debug { "GemPins.combine_method_pins(pins.length=#{pins.length}, pins=#{pins}) => #{out.inspect}" }
  out
end

.combine_method_pins_by_path(pins) ⇒ Array<Pin::Base>



16
17
18
19
20
21
22
23
# File 'lib/solargraph/gem_pins.rb', line 16

def self.combine_method_pins_by_path(pins)
  method_pins, alias_pins = pins.partition { |pin| pin.class == Pin::Method }
  by_path = method_pins.group_by(&:path)
  by_path.transform_values! do |pins|
    GemPins.combine_method_pins(*pins)
  end
  by_path.values + alias_pins
end