solargraph 0.53.4 → 0.54.1
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.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +41 -0
 - data/lib/solargraph/api_map/cache.rb +2 -12
 - data/lib/solargraph/api_map/store.rb +14 -5
 - data/lib/solargraph/api_map.rb +67 -24
 - data/lib/solargraph/complex_type/type_methods.rb +70 -39
 - data/lib/solargraph/complex_type/unique_type.rb +187 -73
 - data/lib/solargraph/complex_type.rb +105 -40
 - data/lib/solargraph/doc_map.rb +19 -3
 - data/lib/solargraph/gem_pins.rb +9 -1
 - data/lib/solargraph/language_server/host/dispatch.rb +8 -1
 - data/lib/solargraph/language_server/host/message_worker.rb +29 -3
 - data/lib/solargraph/language_server/host/sources.rb +1 -61
 - data/lib/solargraph/language_server/host.rb +21 -68
 - data/lib/solargraph/language_server/message/base.rb +1 -1
 - data/lib/solargraph/language_server/message/initialize.rb +14 -0
 - data/lib/solargraph/language_server/message/text_document/definition.rb +3 -3
 - data/lib/solargraph/language_server/message/text_document/document_symbol.rb +3 -3
 - data/lib/solargraph/language_server/message/text_document/formatting.rb +1 -0
 - data/lib/solargraph/language_server/message/text_document/hover.rb +1 -1
 - data/lib/solargraph/language_server/message/text_document/type_definition.rb +3 -3
 - data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -2
 - data/lib/solargraph/language_server/progress.rb +135 -0
 - data/lib/solargraph/language_server.rb +1 -0
 - data/lib/solargraph/library.rb +144 -113
 - data/lib/solargraph/location.rb +14 -1
 - data/lib/solargraph/parser/node_processor/base.rb +3 -2
 - data/lib/solargraph/parser/node_processor.rb +1 -0
 - data/lib/solargraph/parser/parser_gem/class_methods.rb +3 -7
 - data/lib/solargraph/parser/parser_gem/node_chainer.rb +13 -7
 - data/lib/solargraph/parser/parser_gem/node_methods.rb +1 -5
 - data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +23 -19
 - data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +2 -2
 - data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +53 -0
 - data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +6 -4
 - data/lib/solargraph/parser/parser_gem/node_processors.rb +2 -0
 - data/lib/solargraph/parser.rb +2 -5
 - data/lib/solargraph/pin/base.rb +15 -1
 - data/lib/solargraph/pin/base_variable.rb +35 -6
 - data/lib/solargraph/pin/block.rb +48 -11
 - data/lib/solargraph/pin/callable.rb +147 -0
 - data/lib/solargraph/pin/closure.rb +8 -3
 - data/lib/solargraph/pin/common.rb +2 -6
 - data/lib/solargraph/pin/conversions.rb +3 -2
 - data/lib/solargraph/pin/delegated_method.rb +5 -1
 - data/lib/solargraph/pin/documenting.rb +2 -0
 - data/lib/solargraph/pin/instance_variable.rb +2 -2
 - data/lib/solargraph/pin/method.rb +54 -32
 - data/lib/solargraph/pin/namespace.rb +4 -4
 - data/lib/solargraph/pin/parameter.rb +14 -39
 - data/lib/solargraph/pin/proxy_type.rb +1 -1
 - data/lib/solargraph/pin/signature.rb +3 -129
 - data/lib/solargraph/pin.rb +4 -1
 - data/lib/solargraph/range.rb +2 -4
 - data/lib/solargraph/rbs_map/conversions.rb +79 -42
 - data/lib/solargraph/rbs_map/core_fills.rb +6 -6
 - data/lib/solargraph/rbs_map.rb +11 -3
 - data/lib/solargraph/shell.rb +35 -15
 - data/lib/solargraph/source/chain/array.rb +6 -5
 - data/lib/solargraph/source/chain/block_symbol.rb +1 -1
 - data/lib/solargraph/source/chain/block_variable.rb +1 -1
 - data/lib/solargraph/source/chain/call.rb +78 -50
 - data/lib/solargraph/source/chain/link.rb +9 -0
 - data/lib/solargraph/source/chain/or.rb +1 -1
 - data/lib/solargraph/source/chain.rb +60 -16
 - data/lib/solargraph/source/cursor.rb +13 -2
 - data/lib/solargraph/source/updater.rb +1 -0
 - data/lib/solargraph/source.rb +102 -129
 - data/lib/solargraph/source_map/clip.rb +4 -4
 - data/lib/solargraph/source_map/data.rb +30 -0
 - data/lib/solargraph/source_map/mapper.rb +3 -2
 - data/lib/solargraph/source_map.rb +37 -15
 - data/lib/solargraph/type_checker/rules.rb +6 -1
 - data/lib/solargraph/type_checker.rb +50 -25
 - data/lib/solargraph/version.rb +1 -1
 - data/lib/solargraph/views/environment.erb +3 -5
 - data/lib/solargraph/workspace/config.rb +2 -1
 - data/lib/solargraph/workspace.rb +13 -0
 - metadata +6 -3
 - data/lib/solargraph/language_server/host/cataloger.rb +0 -57
 
| 
         @@ -17,49 +17,87 @@ module Solargraph 
     | 
|
| 
       17 
17 
     | 
    
         
             
                  #
         
     | 
| 
       18 
18 
     | 
    
         
             
                  # @param name [String] The name of the type
         
     | 
| 
       19 
19 
     | 
    
         
             
                  # @param substring [String] The substring of the type
         
     | 
| 
       20 
     | 
    
         
            -
                   
     | 
| 
      
 20 
     | 
    
         
            +
                  # @param make_rooted [Boolean, nil]
         
     | 
| 
      
 21 
     | 
    
         
            +
                  # @return [UniqueType]
         
     | 
| 
      
 22 
     | 
    
         
            +
                  def self.parse name, substring = '', make_rooted: nil
         
     | 
| 
      
 23 
     | 
    
         
            +
                    if name.start_with?(':::')
         
     | 
| 
      
 24 
     | 
    
         
            +
                      raise "Illegal prefix: #{name}"
         
     | 
| 
      
 25 
     | 
    
         
            +
                    end
         
     | 
| 
       21 
26 
     | 
    
         
             
                    if name.start_with?('::')
         
     | 
| 
       22 
     | 
    
         
            -
                       
     | 
| 
       23 
     | 
    
         
            -
                       
     | 
| 
      
 27 
     | 
    
         
            +
                      name = name[2..-1]
         
     | 
| 
      
 28 
     | 
    
         
            +
                      rooted = true
         
     | 
| 
      
 29 
     | 
    
         
            +
                    elsif !can_root_name?(name)
         
     | 
| 
      
 30 
     | 
    
         
            +
                      rooted = true
         
     | 
| 
       24 
31 
     | 
    
         
             
                    else
         
     | 
| 
       25 
     | 
    
         
            -
                       
     | 
| 
       26 
     | 
    
         
            -
                      @rooted = false
         
     | 
| 
      
 32 
     | 
    
         
            +
                      rooted = false
         
     | 
| 
       27 
33 
     | 
    
         
             
                    end
         
     | 
| 
       28 
     | 
    
         
            -
                     
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
                    # @type [Array<ComplexType>]
         
     | 
| 
       31 
     | 
    
         
            -
                    @key_types = []
         
     | 
| 
      
 34 
     | 
    
         
            +
                    rooted = make_rooted unless make_rooted.nil?
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
       32 
36 
     | 
    
         
             
                    # @type [Array<ComplexType>]
         
     | 
| 
       33 
     | 
    
         
            -
                     
     | 
| 
      
 37 
     | 
    
         
            +
                    key_types = []
         
     | 
| 
       34 
38 
     | 
    
         
             
                    # @type [Array<ComplexType>]
         
     | 
| 
       35 
     | 
    
         
            -
                     
     | 
| 
       36 
     | 
    
         
            -
                     
     | 
| 
       37 
     | 
    
         
            -
                     
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
                       
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
                       
     | 
| 
       51 
     | 
    
         
            -
                      @subtypes.concat subs[1].map { |u| ComplexType.new([u]) }
         
     | 
| 
       52 
     | 
    
         
            -
                    else
         
     | 
| 
       53 
     | 
    
         
            -
                      @subtypes.concat subs
         
     | 
| 
      
 39 
     | 
    
         
            +
                    subtypes = []
         
     | 
| 
      
 40 
     | 
    
         
            +
                    parameters_type = nil
         
     | 
| 
      
 41 
     | 
    
         
            +
                    unless substring.empty?
         
     | 
| 
      
 42 
     | 
    
         
            +
                      subs = ComplexType.parse(substring[1..-2], partial: true)
         
     | 
| 
      
 43 
     | 
    
         
            +
                      parameters_type = PARAMETERS_TYPE_BY_STARTING_TAG.fetch(substring[0])
         
     | 
| 
      
 44 
     | 
    
         
            +
                      if parameters_type == :hash
         
     | 
| 
      
 45 
     | 
    
         
            +
                        raise ComplexTypeError, "Bad hash type" unless !subs.is_a?(ComplexType) and subs.length == 2 and !subs[0].is_a?(UniqueType) and !subs[1].is_a?(UniqueType)
         
     | 
| 
      
 46 
     | 
    
         
            +
                        # @todo should be able to resolve map; both types have it
         
     | 
| 
      
 47 
     | 
    
         
            +
                        #   with same return type
         
     | 
| 
      
 48 
     | 
    
         
            +
                        # @sg-ignore
         
     | 
| 
      
 49 
     | 
    
         
            +
                        key_types.concat(subs[0].map { |u| ComplexType.new([u]) })
         
     | 
| 
      
 50 
     | 
    
         
            +
                        # @sg-ignore
         
     | 
| 
      
 51 
     | 
    
         
            +
                        subtypes.concat(subs[1].map { |u| ComplexType.new([u]) })
         
     | 
| 
      
 52 
     | 
    
         
            +
                      else
         
     | 
| 
      
 53 
     | 
    
         
            +
                        subtypes.concat subs
         
     | 
| 
      
 54 
     | 
    
         
            +
                      end
         
     | 
| 
       54 
55 
     | 
    
         
             
                    end
         
     | 
| 
       55 
     | 
    
         
            -
                     
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
      
 56 
     | 
    
         
            +
                    new(name, key_types, subtypes, rooted: rooted, parameters_type: parameters_type)
         
     | 
| 
      
 57 
     | 
    
         
            +
                  end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                  # @param name [String]
         
     | 
| 
      
 60 
     | 
    
         
            +
                  # @param key_types [Array<ComplexType>]
         
     | 
| 
      
 61 
     | 
    
         
            +
                  # @param subtypes [Array<ComplexType>]
         
     | 
| 
      
 62 
     | 
    
         
            +
                  # @param rooted [Boolean]
         
     | 
| 
      
 63 
     | 
    
         
            +
                  # @param parameters_type [Symbol, nil]
         
     | 
| 
      
 64 
     | 
    
         
            +
                  def initialize(name, key_types = [], subtypes = [], rooted:, parameters_type: nil)
         
     | 
| 
      
 65 
     | 
    
         
            +
                    if parameters_type.nil?
         
     | 
| 
      
 66 
     | 
    
         
            +
                      raise "You must supply parameters_type if you provide parameters" unless key_types.empty? && subtypes.empty?
         
     | 
| 
      
 67 
     | 
    
         
            +
                    end
         
     | 
| 
      
 68 
     | 
    
         
            +
                    raise "Please remove leading :: and set rooted instead - #{name.inspect}" if name.start_with?('::')
         
     | 
| 
      
 69 
     | 
    
         
            +
                    @name = name
         
     | 
| 
      
 70 
     | 
    
         
            +
                    @key_types = key_types
         
     | 
| 
      
 71 
     | 
    
         
            +
                    @subtypes = subtypes
         
     | 
| 
      
 72 
     | 
    
         
            +
                    @rooted = rooted
         
     | 
| 
      
 73 
     | 
    
         
            +
                    @all_params = []
         
     | 
| 
      
 74 
     | 
    
         
            +
                    @all_params.concat key_types
         
     | 
| 
      
 75 
     | 
    
         
            +
                    @all_params.concat subtypes
         
     | 
| 
      
 76 
     | 
    
         
            +
                    @parameters_type = parameters_type
         
     | 
| 
       57 
77 
     | 
    
         
             
                  end
         
     | 
| 
       58 
78 
     | 
    
         | 
| 
       59 
79 
     | 
    
         
             
                  def to_s
         
     | 
| 
       60 
80 
     | 
    
         
             
                    tag
         
     | 
| 
       61 
81 
     | 
    
         
             
                  end
         
     | 
| 
       62 
82 
     | 
    
         | 
| 
      
 83 
     | 
    
         
            +
                  def eql?(other)
         
     | 
| 
      
 84 
     | 
    
         
            +
                    self.class == other.class &&
         
     | 
| 
      
 85 
     | 
    
         
            +
                      @name == other.name &&
         
     | 
| 
      
 86 
     | 
    
         
            +
                      @key_types == other.key_types &&
         
     | 
| 
      
 87 
     | 
    
         
            +
                      @subtypes == other.subtypes &&
         
     | 
| 
      
 88 
     | 
    
         
            +
                      @rooted == other.rooted? &&
         
     | 
| 
      
 89 
     | 
    
         
            +
                      @all_params == other.all_params &&
         
     | 
| 
      
 90 
     | 
    
         
            +
                      @parameters_type == other.parameters_type
         
     | 
| 
      
 91 
     | 
    
         
            +
                  end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                  def ==(other)
         
     | 
| 
      
 94 
     | 
    
         
            +
                    eql?(other)
         
     | 
| 
      
 95 
     | 
    
         
            +
                  end
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                  def hash
         
     | 
| 
      
 98 
     | 
    
         
            +
                    [self.class, @name, @key_types, @sub_types, @rooted, @all_params, @parameters_type].hash
         
     | 
| 
      
 99 
     | 
    
         
            +
                  end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
       63 
101 
     | 
    
         
             
                  # @return [Array<UniqueType>]
         
     | 
| 
       64 
102 
     | 
    
         
             
                  def items
         
     | 
| 
       65 
103 
     | 
    
         
             
                    [self]
         
     | 
| 
         @@ -76,11 +114,25 @@ module Solargraph 
     | 
|
| 
       76 
114 
     | 
    
         | 
| 
       77 
115 
     | 
    
         
             
                  # @return [String]
         
     | 
| 
       78 
116 
     | 
    
         
             
                  def to_rbs
         
     | 
| 
       79 
     | 
    
         
            -
                    if  
     | 
| 
      
 117 
     | 
    
         
            +
                    if duck_type?
         
     | 
| 
      
 118 
     | 
    
         
            +
                      'untyped'
         
     | 
| 
      
 119 
     | 
    
         
            +
                    elsif name == 'Boolean'
         
     | 
| 
      
 120 
     | 
    
         
            +
                      'bool'
         
     | 
| 
      
 121 
     | 
    
         
            +
                    elsif name.downcase == 'nil'
         
     | 
| 
      
 122 
     | 
    
         
            +
                      'nil'
         
     | 
| 
      
 123 
     | 
    
         
            +
                    elsif name == GENERIC_TAG_NAME
         
     | 
| 
      
 124 
     | 
    
         
            +
                      all_params.first.name
         
     | 
| 
      
 125 
     | 
    
         
            +
                    elsif ['Class', 'Module'].include?(name)
         
     | 
| 
      
 126 
     | 
    
         
            +
                      rbs_name
         
     | 
| 
      
 127 
     | 
    
         
            +
                    elsif ['Tuple', 'Array'].include?(name) && fixed_parameters?
         
     | 
| 
       80 
128 
     | 
    
         
             
                      # tuples don't have a name; they're just [foo, bar, baz].
         
     | 
| 
       81 
129 
     | 
    
         
             
                      if substring == '()'
         
     | 
| 
       82 
130 
     | 
    
         
             
                        # but there are no zero element tuples, so we go with an array
         
     | 
| 
       83 
     | 
    
         
            -
                         
     | 
| 
      
 131 
     | 
    
         
            +
                        if rooted?
         
     | 
| 
      
 132 
     | 
    
         
            +
                          '::Array[]'
         
     | 
| 
      
 133 
     | 
    
         
            +
                        else
         
     | 
| 
      
 134 
     | 
    
         
            +
                          'Array[]'
         
     | 
| 
      
 135 
     | 
    
         
            +
                        end
         
     | 
| 
       84 
136 
     | 
    
         
             
                      else
         
     | 
| 
       85 
137 
     | 
    
         
             
                        # already generated surrounded by []
         
     | 
| 
       86 
138 
     | 
    
         
             
                        parameters_as_rbs
         
     | 
| 
         @@ -90,16 +142,37 @@ module Solargraph 
     | 
|
| 
       90 
142 
     | 
    
         
             
                    end
         
     | 
| 
       91 
143 
     | 
    
         
             
                  end
         
     | 
| 
       92 
144 
     | 
    
         | 
| 
      
 145 
     | 
    
         
            +
                  # @return [Boolean]
         
     | 
| 
      
 146 
     | 
    
         
            +
                  def parameters?
         
     | 
| 
      
 147 
     | 
    
         
            +
                    !all_params.empty?
         
     | 
| 
      
 148 
     | 
    
         
            +
                  end
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
                  # @param types [Array<UniqueType, ComplexType>]
         
     | 
| 
      
 151 
     | 
    
         
            +
                  # @return [String]
         
     | 
| 
      
 152 
     | 
    
         
            +
                  def rbs_union(types)
         
     | 
| 
      
 153 
     | 
    
         
            +
                    if types.length == 1
         
     | 
| 
      
 154 
     | 
    
         
            +
                      types.first.to_rbs
         
     | 
| 
      
 155 
     | 
    
         
            +
                    else
         
     | 
| 
      
 156 
     | 
    
         
            +
                      "(#{types.map(&:to_rbs).join(' | ')})"
         
     | 
| 
      
 157 
     | 
    
         
            +
                    end
         
     | 
| 
      
 158 
     | 
    
         
            +
                  end
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
       93 
160 
     | 
    
         
             
                  # @return [String]
         
     | 
| 
       94 
161 
     | 
    
         
             
                  def parameters_as_rbs
         
     | 
| 
       95 
     | 
    
         
            -
                     
     | 
| 
      
 162 
     | 
    
         
            +
                    return '' unless parameters?
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
                    return "[#{all_params.map(&:to_rbs).join(', ')}]" if key_types.empty?
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
                    # handle, e.g., Hash[K, V] case
         
     | 
| 
      
 167 
     | 
    
         
            +
                    key_types_str = rbs_union(key_types)
         
     | 
| 
      
 168 
     | 
    
         
            +
                    subtypes_str = rbs_union(subtypes)
         
     | 
| 
      
 169 
     | 
    
         
            +
                    "[#{key_types_str}, #{subtypes_str}]"
         
     | 
| 
       96 
170 
     | 
    
         
             
                  end
         
     | 
| 
       97 
171 
     | 
    
         | 
| 
       98 
172 
     | 
    
         
             
                  def generic?
         
     | 
| 
       99 
173 
     | 
    
         
             
                    name == GENERIC_TAG_NAME || all_params.any?(&:generic?)
         
     | 
| 
       100 
174 
     | 
    
         
             
                  end
         
     | 
| 
       101 
175 
     | 
    
         | 
| 
       102 
     | 
    
         
            -
             
     | 
| 
       103 
176 
     | 
    
         
             
                  # @param generics_to_resolve [Enumerable<String>]
         
     | 
| 
       104 
177 
     | 
    
         
             
                  # @param context_type [UniqueType, nil]
         
     | 
| 
       105 
178 
     | 
    
         
             
                  # @param resolved_generic_values [Hash{String => ComplexType}] Added to as types are encountered or resolved
         
     | 
| 
         @@ -182,39 +255,35 @@ module Solargraph 
     | 
|
| 
       182 
255 
     | 
    
         
             
                  end
         
     | 
| 
       183 
256 
     | 
    
         | 
| 
       184 
257 
     | 
    
         
             
                  # @param new_name [String, nil]
         
     | 
| 
      
 258 
     | 
    
         
            +
                  # @param make_rooted [Boolean, nil]
         
     | 
| 
       185 
259 
     | 
    
         
             
                  # @param new_key_types [Array<UniqueType>, nil]
         
     | 
| 
      
 260 
     | 
    
         
            +
                  # @param rooted [Boolean, nil]
         
     | 
| 
       186 
261 
     | 
    
         
             
                  # @param new_subtypes [Array<UniqueType>, nil]
         
     | 
| 
       187 
262 
     | 
    
         
             
                  # @return [self]
         
     | 
| 
       188 
     | 
    
         
            -
                  def recreate(new_name: nil, new_key_types: nil, new_subtypes: nil)
         
     | 
| 
      
 263 
     | 
    
         
            +
                  def recreate(new_name: nil, make_rooted: nil, new_key_types: nil, new_subtypes: nil)
         
     | 
| 
      
 264 
     | 
    
         
            +
                    raise "Please remove leading :: and set rooted instead - #{new_name}" if new_name&.start_with?('::')
         
     | 
| 
      
 265 
     | 
    
         
            +
             
     | 
| 
       189 
266 
     | 
    
         
             
                    new_name ||= name
         
     | 
| 
       190 
267 
     | 
    
         
             
                    new_key_types ||= @key_types
         
     | 
| 
       191 
268 
     | 
    
         
             
                    new_subtypes ||= @subtypes
         
     | 
| 
       192 
     | 
    
         
            -
                     
     | 
| 
       193 
     | 
    
         
            -
             
     | 
| 
       194 
     | 
    
         
            -
             
     | 
| 
       195 
     | 
    
         
            -
             
     | 
| 
       196 
     | 
    
         
            -
             
     | 
| 
       197 
     | 
    
         
            -
             
     | 
| 
       198 
     | 
    
         
            -
             
     | 
| 
       199 
     | 
    
         
            -
             
     | 
| 
       200 
     | 
    
         
            -
             
     | 
| 
       201 
     | 
    
         
            -
             
     | 
| 
       202 
     | 
    
         
            -
             
     | 
| 
       203 
     | 
    
         
            -
             
     | 
| 
       204 
     | 
    
         
            -
             
     | 
| 
       205 
     | 
    
         
            -
             
     | 
| 
       206 
     | 
    
         
            -
             
     | 
| 
       207 
     | 
    
         
            -
             
     | 
| 
       208 
     | 
    
         
            -
             
     | 
| 
       209 
     | 
    
         
            -
                       
     | 
| 
       210 
     | 
    
         
            -
                      #   Array<(String), Integer> is not ambiguous if we accept
         
     | 
| 
       211 
     | 
    
         
            -
                      #     (String) as a tuple type, but not currently understood
         
     | 
| 
       212 
     | 
    
         
            -
                      #     by Solargraph.
         
     | 
| 
       213 
     | 
    
         
            -
                      UniqueType.new(new_name, "<(#{new_subtypes.join(', ')})>")
         
     | 
| 
       214 
     | 
    
         
            -
                    elsif fixed_parameters?
         
     | 
| 
       215 
     | 
    
         
            -
                      UniqueType.new(new_name, "(#{new_subtypes.join(', ')})")
         
     | 
| 
       216 
     | 
    
         
            -
                    else
         
     | 
| 
       217 
     | 
    
         
            -
                      UniqueType.new(new_name, "<#{new_subtypes.join(', ')}>")
         
     | 
| 
      
 269 
     | 
    
         
            +
                    make_rooted = @rooted if make_rooted.nil?
         
     | 
| 
      
 270 
     | 
    
         
            +
                    UniqueType.new(new_name, new_key_types, new_subtypes, rooted: make_rooted, parameters_type: parameters_type)
         
     | 
| 
      
 271 
     | 
    
         
            +
                  end
         
     | 
| 
      
 272 
     | 
    
         
            +
             
     | 
| 
      
 273 
     | 
    
         
            +
                  # @return [String]
         
     | 
| 
      
 274 
     | 
    
         
            +
                  def rooted_tags
         
     | 
| 
      
 275 
     | 
    
         
            +
                    rooted_tag
         
     | 
| 
      
 276 
     | 
    
         
            +
                  end
         
     | 
| 
      
 277 
     | 
    
         
            +
             
     | 
| 
      
 278 
     | 
    
         
            +
                  # @return [String]
         
     | 
| 
      
 279 
     | 
    
         
            +
                  def tags
         
     | 
| 
      
 280 
     | 
    
         
            +
                    tag
         
     | 
| 
      
 281 
     | 
    
         
            +
                  end
         
     | 
| 
      
 282 
     | 
    
         
            +
             
     | 
| 
      
 283 
     | 
    
         
            +
                  # @return [self]
         
     | 
| 
      
 284 
     | 
    
         
            +
                  def force_rooted
         
     | 
| 
      
 285 
     | 
    
         
            +
                    transform do |t|
         
     | 
| 
      
 286 
     | 
    
         
            +
                      t.recreate(make_rooted: true)
         
     | 
| 
       218 
287 
     | 
    
         
             
                    end
         
     | 
| 
       219 
288 
     | 
    
         
             
                  end
         
     | 
| 
       220 
289 
     | 
    
         | 
| 
         @@ -225,19 +294,35 @@ module Solargraph 
     | 
|
| 
       225 
294 
     | 
    
         
             
                  # @yieldreturn [self]
         
     | 
| 
       226 
295 
     | 
    
         
             
                  # @return [self]
         
     | 
| 
       227 
296 
     | 
    
         
             
                  def transform(new_name = nil, &transform_type)
         
     | 
| 
       228 
     | 
    
         
            -
                     
     | 
| 
       229 
     | 
    
         
            -
                     
     | 
| 
       230 
     | 
    
         
            -
             
     | 
| 
      
 297 
     | 
    
         
            +
                    raise "Please remove leading :: and set rooted with recreate() instead - #{new_name}" if new_name&.start_with?('::')
         
     | 
| 
      
 298 
     | 
    
         
            +
                    if name == ComplexType::GENERIC_TAG_NAME
         
     | 
| 
      
 299 
     | 
    
         
            +
                      # doesn't make sense to manipulate the name of the generic
         
     | 
| 
      
 300 
     | 
    
         
            +
                      new_key_types = @key_types
         
     | 
| 
      
 301 
     | 
    
         
            +
                      new_subtypes = @subtypes
         
     | 
| 
      
 302 
     | 
    
         
            +
                    else
         
     | 
| 
      
 303 
     | 
    
         
            +
                      new_key_types = @key_types.flat_map { |ct| ct.items.map { |ut| ut.transform(&transform_type) } }
         
     | 
| 
      
 304 
     | 
    
         
            +
                      new_subtypes = @subtypes.flat_map { |ct| ct.items.map { |ut| ut.transform(&transform_type) } }
         
     | 
| 
      
 305 
     | 
    
         
            +
                    end
         
     | 
| 
      
 306 
     | 
    
         
            +
                    new_type = recreate(new_name: new_name || name, new_key_types: new_key_types, new_subtypes: new_subtypes, make_rooted: @rooted)
         
     | 
| 
       231 
307 
     | 
    
         
             
                    yield new_type
         
     | 
| 
       232 
308 
     | 
    
         
             
                  end
         
     | 
| 
       233 
309 
     | 
    
         | 
| 
       234 
     | 
    
         
            -
                  #  
     | 
| 
       235 
     | 
    
         
            -
                  # 
     | 
| 
       236 
     | 
    
         
            -
                  # @ 
     | 
| 
       237 
     | 
    
         
            -
                   
     | 
| 
      
 310 
     | 
    
         
            +
                  # Generate a ComplexType that fully qualifies this type's namespaces.
         
     | 
| 
      
 311 
     | 
    
         
            +
                  #
         
     | 
| 
      
 312 
     | 
    
         
            +
                  # @param api_map [ApiMap] The ApiMap that performs qualification
         
     | 
| 
      
 313 
     | 
    
         
            +
                  # @param context [String] The namespace from which to resolve names
         
     | 
| 
      
 314 
     | 
    
         
            +
                  # @return [self, ComplexType, UniqueType] The generated ComplexType
         
     | 
| 
      
 315 
     | 
    
         
            +
                  def qualify api_map, context = ''
         
     | 
| 
       238 
316 
     | 
    
         
             
                    transform do |t|
         
     | 
| 
       239 
     | 
    
         
            -
                      next t if t.name  
     | 
| 
       240 
     | 
    
         
            -
                      t. 
     | 
| 
      
 317 
     | 
    
         
            +
                      next t if t.name == GENERIC_TAG_NAME
         
     | 
| 
      
 318 
     | 
    
         
            +
                      next t if t.duck_type? || t.void? || t.undefined?
         
     | 
| 
      
 319 
     | 
    
         
            +
                      recon = (t.rooted? ? '' : context)
         
     | 
| 
      
 320 
     | 
    
         
            +
                      fqns = api_map.qualify(t.name, recon)
         
     | 
| 
      
 321 
     | 
    
         
            +
                      if fqns.nil?
         
     | 
| 
      
 322 
     | 
    
         
            +
                        next UniqueType::BOOLEAN if t.tag == 'Boolean'
         
     | 
| 
      
 323 
     | 
    
         
            +
                        next UniqueType::UNDEFINED
         
     | 
| 
      
 324 
     | 
    
         
            +
                      end
         
     | 
| 
      
 325 
     | 
    
         
            +
                      t.recreate(new_name: fqns, make_rooted: true)
         
     | 
| 
       241 
326 
     | 
    
         
             
                    end
         
     | 
| 
       242 
327 
     | 
    
         
             
                  end
         
     | 
| 
       243 
328 
     | 
    
         | 
| 
         @@ -245,8 +330,37 @@ module Solargraph 
     | 
|
| 
       245 
330 
     | 
    
         
             
                    @name == 'self' || @key_types.any?(&:selfy?) || @subtypes.any?(&:selfy?)
         
     | 
| 
       246 
331 
     | 
    
         
             
                  end
         
     | 
| 
       247 
332 
     | 
    
         | 
| 
       248 
     | 
    
         
            -
                   
     | 
| 
       249 
     | 
    
         
            -
                   
     | 
| 
      
 333 
     | 
    
         
            +
                  # @param dst [ComplexType]
         
     | 
| 
      
 334 
     | 
    
         
            +
                  # @return [self]
         
     | 
| 
      
 335 
     | 
    
         
            +
                  def self_to_type dst
         
     | 
| 
      
 336 
     | 
    
         
            +
                    object_type_dst = dst.reduce_class_type
         
     | 
| 
      
 337 
     | 
    
         
            +
                    transform do |t|
         
     | 
| 
      
 338 
     | 
    
         
            +
                      next t if t.name != 'self'
         
     | 
| 
      
 339 
     | 
    
         
            +
                      object_type_dst
         
     | 
| 
      
 340 
     | 
    
         
            +
                    end
         
     | 
| 
      
 341 
     | 
    
         
            +
                  end
         
     | 
| 
      
 342 
     | 
    
         
            +
             
     | 
| 
      
 343 
     | 
    
         
            +
                  def all_rooted?
         
     | 
| 
      
 344 
     | 
    
         
            +
                    return true if name == GENERIC_TAG_NAME
         
     | 
| 
      
 345 
     | 
    
         
            +
                    rooted? && all_params.all?(&:rooted?)
         
     | 
| 
      
 346 
     | 
    
         
            +
                  end
         
     | 
| 
      
 347 
     | 
    
         
            +
             
     | 
| 
      
 348 
     | 
    
         
            +
                  def rooted?
         
     | 
| 
      
 349 
     | 
    
         
            +
                    !can_root_name? || @rooted
         
     | 
| 
      
 350 
     | 
    
         
            +
                  end
         
     | 
| 
      
 351 
     | 
    
         
            +
             
     | 
| 
      
 352 
     | 
    
         
            +
                  def can_root_name?(name_to_check = name)
         
     | 
| 
      
 353 
     | 
    
         
            +
                    self.class.can_root_name?(name_to_check)
         
     | 
| 
      
 354 
     | 
    
         
            +
                  end
         
     | 
| 
      
 355 
     | 
    
         
            +
             
     | 
| 
      
 356 
     | 
    
         
            +
                  # @param name [String]
         
     | 
| 
      
 357 
     | 
    
         
            +
                  def self.can_root_name?(name)
         
     | 
| 
      
 358 
     | 
    
         
            +
                    # name is not lowercase
         
     | 
| 
      
 359 
     | 
    
         
            +
                    !name.empty? && name != name.downcase
         
     | 
| 
      
 360 
     | 
    
         
            +
                  end
         
     | 
| 
      
 361 
     | 
    
         
            +
             
     | 
| 
      
 362 
     | 
    
         
            +
                  UNDEFINED = UniqueType.new('undefined', rooted: false)
         
     | 
| 
      
 363 
     | 
    
         
            +
                  BOOLEAN = UniqueType.new('Boolean', rooted: true)
         
     | 
| 
       250 
364 
     | 
    
         
             
                end
         
     | 
| 
       251 
365 
     | 
    
         
             
              end
         
     | 
| 
       252 
366 
     | 
    
         
             
            end
         
     | 
| 
         @@ -11,20 +11,34 @@ module Solargraph 
     | 
|
| 
       11 
11 
     | 
    
         
             
                autoload :TypeMethods, 'solargraph/complex_type/type_methods'
         
     | 
| 
       12 
12 
     | 
    
         
             
                autoload :UniqueType,  'solargraph/complex_type/unique_type'
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
                # @param types [Array< 
     | 
| 
      
 14 
     | 
    
         
            +
                # @param types [Array<UniqueType, ComplexType>]
         
     | 
| 
       15 
15 
     | 
    
         
             
                def initialize types = [UniqueType::UNDEFINED]
         
     | 
| 
       16 
16 
     | 
    
         
             
                  # @todo @items here should not need an annotation
         
     | 
| 
       17 
17 
     | 
    
         
             
                  # @type [Array<UniqueType>]
         
     | 
| 
       18 
18 
     | 
    
         
             
                  @items = types.flat_map(&:items).uniq(&:to_s)
         
     | 
| 
       19 
19 
     | 
    
         
             
                end
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
      
 21 
     | 
    
         
            +
                def eql?(other)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  self.class == other.class &&
         
     | 
| 
      
 23 
     | 
    
         
            +
                    @items == other.items
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                def ==(other)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  self.eql?(other)
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                def hash
         
     | 
| 
      
 31 
     | 
    
         
            +
                  [self.class, @items].hash
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
       21 
34 
     | 
    
         
             
                # @param api_map [ApiMap]
         
     | 
| 
       22 
35 
     | 
    
         
             
                # @param context [String]
         
     | 
| 
       23 
36 
     | 
    
         
             
                # @return [ComplexType]
         
     | 
| 
       24 
37 
     | 
    
         
             
                def qualify api_map, context = ''
         
     | 
| 
       25 
38 
     | 
    
         
             
                  red = reduce_object
         
     | 
| 
       26 
39 
     | 
    
         
             
                  types = red.items.map do |t|
         
     | 
| 
       27 
     | 
    
         
            -
                    next t if [' 
     | 
| 
      
 40 
     | 
    
         
            +
                    next t if ['nil', 'void', 'undefined'].include?(t.name)
         
     | 
| 
      
 41 
     | 
    
         
            +
                    next t if ['::Boolean'].include?(t.rooted_name)
         
     | 
| 
       28 
42 
     | 
    
         
             
                    t.qualify api_map, context
         
     | 
| 
       29 
43 
     | 
    
         
             
                  end
         
     | 
| 
       30 
44 
     | 
    
         
             
                  ComplexType.new(types).reduce_object
         
     | 
| 
         @@ -52,6 +66,16 @@ module Solargraph 
     | 
|
| 
       52 
66 
     | 
    
         
             
                   (@items.length > 1 ? ')' : ''))
         
     | 
| 
       53 
67 
     | 
    
         
             
                end
         
     | 
| 
       54 
68 
     | 
    
         | 
| 
      
 69 
     | 
    
         
            +
                # @param dst [ComplexType]
         
     | 
| 
      
 70 
     | 
    
         
            +
                # @return [ComplexType]
         
     | 
| 
      
 71 
     | 
    
         
            +
                def self_to_type dst
         
     | 
| 
      
 72 
     | 
    
         
            +
                  object_type_dst = dst.reduce_class_type
         
     | 
| 
      
 73 
     | 
    
         
            +
                  transform do |t|
         
     | 
| 
      
 74 
     | 
    
         
            +
                    next t if t.name != 'self'
         
     | 
| 
      
 75 
     | 
    
         
            +
                    object_type_dst
         
     | 
| 
      
 76 
     | 
    
         
            +
                  end
         
     | 
| 
      
 77 
     | 
    
         
            +
                end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
       55 
79 
     | 
    
         
             
                # @yieldparam [UniqueType]
         
     | 
| 
       56 
80 
     | 
    
         
             
                # @return [Array]
         
     | 
| 
       57 
81 
     | 
    
         
             
                def map &block
         
     | 
| 
         @@ -86,6 +110,10 @@ module Solargraph 
     | 
|
| 
       86 
110 
     | 
    
         
             
                  @items
         
     | 
| 
       87 
111 
     | 
    
         
             
                end
         
     | 
| 
       88 
112 
     | 
    
         | 
| 
      
 113 
     | 
    
         
            +
                def tags
         
     | 
| 
      
 114 
     | 
    
         
            +
                  @items.map(&:tag).join(', ')
         
     | 
| 
      
 115 
     | 
    
         
            +
                end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
       89 
117 
     | 
    
         
             
                # @param index [Integer]
         
     | 
| 
       90 
118 
     | 
    
         
             
                # @return [UniqueType]
         
     | 
| 
       91 
119 
     | 
    
         
             
                def [](index)
         
     | 
| 
         @@ -126,6 +154,10 @@ module Solargraph 
     | 
|
| 
       126 
154 
     | 
    
         
             
                  map(&:tag).join(', ')
         
     | 
| 
       127 
155 
     | 
    
         
             
                end
         
     | 
| 
       128 
156 
     | 
    
         | 
| 
      
 157 
     | 
    
         
            +
                def rooted_tags
         
     | 
| 
      
 158 
     | 
    
         
            +
                  map(&:rooted_tag).join(', ')
         
     | 
| 
      
 159 
     | 
    
         
            +
                end
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
       129 
161 
     | 
    
         
             
                def all? &block
         
     | 
| 
       130 
162 
     | 
    
         
             
                  @items.all? &block
         
     | 
| 
       131 
163 
     | 
    
         
             
                end
         
     | 
| 
         @@ -147,24 +179,23 @@ module Solargraph 
     | 
|
| 
       147 
179 
     | 
    
         
             
                # @yieldreturn [UniqueType]
         
     | 
| 
       148 
180 
     | 
    
         
             
                # @return [ComplexType]
         
     | 
| 
       149 
181 
     | 
    
         
             
                def transform(new_name = nil, &transform_type)
         
     | 
| 
      
 182 
     | 
    
         
            +
                  raise "Please remove leading :: and set rooted with recreate() instead - #{new_name}" if new_name&.start_with?('::')
         
     | 
| 
       150 
183 
     | 
    
         
             
                  ComplexType.new(map { |ut| ut.transform(new_name, &transform_type) })
         
     | 
| 
       151 
184 
     | 
    
         
             
                end
         
     | 
| 
       152 
185 
     | 
    
         | 
| 
      
 186 
     | 
    
         
            +
                # @return [self]
         
     | 
| 
      
 187 
     | 
    
         
            +
                def force_rooted
         
     | 
| 
      
 188 
     | 
    
         
            +
                  transform do |t|
         
     | 
| 
      
 189 
     | 
    
         
            +
                    t.recreate(make_rooted: true)
         
     | 
| 
      
 190 
     | 
    
         
            +
                  end
         
     | 
| 
      
 191 
     | 
    
         
            +
                end
         
     | 
| 
      
 192 
     | 
    
         
            +
             
     | 
| 
       153 
193 
     | 
    
         
             
                # @param definitions [Pin::Namespace, Pin::Method]
         
     | 
| 
       154 
194 
     | 
    
         
             
                # @param context_type [ComplexType]
         
     | 
| 
       155 
195 
     | 
    
         
             
                # @return [ComplexType]
         
     | 
| 
       156 
196 
     | 
    
         
             
                def resolve_generics definitions, context_type
         
     | 
| 
       157 
197 
     | 
    
         
             
                  result = @items.map { |i| i.resolve_generics(definitions, context_type) }
         
     | 
| 
       158 
     | 
    
         
            -
                  ComplexType. 
     | 
| 
       159 
     | 
    
         
            -
                end
         
     | 
| 
       160 
     | 
    
         
            -
             
     | 
| 
       161 
     | 
    
         
            -
                # @param dst [String]
         
     | 
| 
       162 
     | 
    
         
            -
                # @return [ComplexType]
         
     | 
| 
       163 
     | 
    
         
            -
                def self_to dst
         
     | 
| 
       164 
     | 
    
         
            -
                  return self unless selfy?
         
     | 
| 
       165 
     | 
    
         
            -
                  red = reduce_class(dst)
         
     | 
| 
       166 
     | 
    
         
            -
                  result = @items.map { |i| i.self_to red }
         
     | 
| 
       167 
     | 
    
         
            -
                  ComplexType.parse(*result.map(&:tag))
         
     | 
| 
      
 198 
     | 
    
         
            +
                  ComplexType.new(result)
         
     | 
| 
       168 
199 
     | 
    
         
             
                end
         
     | 
| 
       169 
200 
     | 
    
         | 
| 
       170 
201 
     | 
    
         
             
                def nullable?
         
     | 
| 
         @@ -176,35 +207,49 @@ module Solargraph 
     | 
|
| 
       176 
207 
     | 
    
         
             
                  @items.first.all_params || []
         
     | 
| 
       177 
208 
     | 
    
         
             
                end
         
     | 
| 
       178 
209 
     | 
    
         | 
| 
      
 210 
     | 
    
         
            +
                # @return [ComplexType]
         
     | 
| 
      
 211 
     | 
    
         
            +
                def reduce_class_type
         
     | 
| 
      
 212 
     | 
    
         
            +
                  new_items = items.flat_map do |type|
         
     | 
| 
      
 213 
     | 
    
         
            +
                    next type unless ['Module', 'Class'].include?(type.name)
         
     | 
| 
      
 214 
     | 
    
         
            +
             
     | 
| 
      
 215 
     | 
    
         
            +
                    type.all_params
         
     | 
| 
      
 216 
     | 
    
         
            +
                  end
         
     | 
| 
      
 217 
     | 
    
         
            +
                  ComplexType.new(new_items)
         
     | 
| 
      
 218 
     | 
    
         
            +
                end
         
     | 
| 
      
 219 
     | 
    
         
            +
             
     | 
| 
      
 220 
     | 
    
         
            +
                # every type and subtype in this union have been resolved to be
         
     | 
| 
      
 221 
     | 
    
         
            +
                # fully qualified
         
     | 
| 
      
 222 
     | 
    
         
            +
                def all_rooted?
         
     | 
| 
      
 223 
     | 
    
         
            +
                  all?(&:all_rooted?)
         
     | 
| 
      
 224 
     | 
    
         
            +
                end
         
     | 
| 
      
 225 
     | 
    
         
            +
             
     | 
| 
      
 226 
     | 
    
         
            +
                # every top-level type has resolved to be fully qualified; see
         
     | 
| 
      
 227 
     | 
    
         
            +
                # #all_rooted? to check their subtypes as well
         
     | 
| 
      
 228 
     | 
    
         
            +
                def rooted?
         
     | 
| 
      
 229 
     | 
    
         
            +
                  all?(&:rooted?)
         
     | 
| 
      
 230 
     | 
    
         
            +
                end
         
     | 
| 
      
 231 
     | 
    
         
            +
             
     | 
| 
       179 
232 
     | 
    
         
             
                attr_reader :items
         
     | 
| 
       180 
233 
     | 
    
         | 
| 
      
 234 
     | 
    
         
            +
                def rooted?
         
     | 
| 
      
 235 
     | 
    
         
            +
                  @items.all?(&:rooted?)
         
     | 
| 
      
 236 
     | 
    
         
            +
                end
         
     | 
| 
      
 237 
     | 
    
         
            +
             
     | 
| 
       181 
238 
     | 
    
         
             
                protected
         
     | 
| 
       182 
239 
     | 
    
         | 
| 
       183 
240 
     | 
    
         
             
                # @return [ComplexType]
         
     | 
| 
       184 
241 
     | 
    
         
             
                def reduce_object
         
     | 
| 
       185 
     | 
    
         
            -
                   
     | 
| 
       186 
     | 
    
         
            -
             
     | 
| 
      
 242 
     | 
    
         
            +
                  new_items = items.flat_map do |ut|
         
     | 
| 
      
 243 
     | 
    
         
            +
                    next [ut] if ut.name != 'Object' || ut.subtypes.empty?
         
     | 
| 
      
 244 
     | 
    
         
            +
                    ut.subtypes
         
     | 
| 
      
 245 
     | 
    
         
            +
                  end
         
     | 
| 
      
 246 
     | 
    
         
            +
                  ComplexType.new(new_items)
         
     | 
| 
       187 
247 
     | 
    
         
             
                end
         
     | 
| 
       188 
248 
     | 
    
         | 
| 
       189 
249 
     | 
    
         
             
                def bottom?
         
     | 
| 
       190 
250 
     | 
    
         
             
                  @items.all?(&:bot?)
         
     | 
| 
       191 
251 
     | 
    
         
             
                end
         
     | 
| 
       192 
252 
     | 
    
         | 
| 
       193 
     | 
    
         
            -
                private
         
     | 
| 
       194 
     | 
    
         
            -
             
     | 
| 
       195 
     | 
    
         
            -
                # @todo This is a quick and dirty hack that forces `self` keywords
         
     | 
| 
       196 
     | 
    
         
            -
                #   to reference an instance of their class and never the class itself.
         
     | 
| 
       197 
     | 
    
         
            -
                #   This behavior may change depending on which result is expected
         
     | 
| 
       198 
     | 
    
         
            -
                #   from YARD conventions. See https://github.com/lsegal/yard/issues/1257
         
     | 
| 
       199 
     | 
    
         
            -
                # @param dst [String]
         
     | 
| 
       200 
     | 
    
         
            -
                # @return [String]
         
     | 
| 
       201 
     | 
    
         
            -
                def reduce_class dst
         
     | 
| 
       202 
     | 
    
         
            -
                  while dst =~ /^(Class|Module)\<(.*?)\>$/
         
     | 
| 
       203 
     | 
    
         
            -
                    dst = dst.sub(/^(Class|Module)\</, '').sub(/\>$/, '')
         
     | 
| 
       204 
     | 
    
         
            -
                  end
         
     | 
| 
       205 
     | 
    
         
            -
                  dst
         
     | 
| 
       206 
     | 
    
         
            -
                end
         
     | 
| 
       207 
     | 
    
         
            -
             
     | 
| 
       208 
253 
     | 
    
         
             
                class << self
         
     | 
| 
       209 
254 
     | 
    
         
             
                  # Parse type strings into a ComplexType.
         
     | 
| 
       210 
255 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -220,10 +265,15 @@ module Solargraph 
     | 
|
| 
       220 
265 
     | 
    
         
             
                  #
         
     | 
| 
       221 
266 
     | 
    
         
             
                  # @param *strings [Array<String>] The type definitions to parse
         
     | 
| 
       222 
267 
     | 
    
         
             
                  # @return [ComplexType]
         
     | 
| 
       223 
     | 
    
         
            -
                  # @overload parse(*strings, partial: false)
         
     | 
| 
       224 
     | 
    
         
            -
                  #  @todo Need ability to use a literal true as a type below
         
     | 
| 
       225 
     | 
    
         
            -
                  #  @param partial [Boolean] True if the string is part of a another type
         
     | 
| 
       226 
     | 
    
         
            -
                  #  @return [Array<UniqueType>]
         
     | 
| 
      
 268 
     | 
    
         
            +
                  # # @overload parse(*strings, partial: false)
         
     | 
| 
      
 269 
     | 
    
         
            +
                  # #  @todo Need ability to use a literal true as a type below
         
     | 
| 
      
 270 
     | 
    
         
            +
                  # #  @param partial [Boolean] True if the string is part of a another type
         
     | 
| 
      
 271 
     | 
    
         
            +
                  # #  @return [Array<UniqueType>]
         
     | 
| 
      
 272 
     | 
    
         
            +
                  # @sg-ignore
         
     | 
| 
      
 273 
     | 
    
         
            +
                  # @todo To be able to select the right signature above,
         
     | 
| 
      
 274 
     | 
    
         
            +
                  #   Chain::Call needs to know the decl type (:arg, :optarg,
         
     | 
| 
      
 275 
     | 
    
         
            +
                  #   :kwarg, etc) of the arguments given, instead of just having
         
     | 
| 
      
 276 
     | 
    
         
            +
                  #   an array of Chains as the arguments.
         
     | 
| 
       227 
277 
     | 
    
         
             
                  def parse *strings, partial: false
         
     | 
| 
       228 
278 
     | 
    
         
             
                    # @type [Hash{Array<String> => ComplexType}]
         
     | 
| 
       229 
279 
     | 
    
         
             
                    @cache ||= {}
         
     | 
| 
         @@ -250,7 +300,7 @@ module Solargraph 
     | 
|
| 
       250 
300 
     | 
    
         
             
                          elsif base.end_with?('=')
         
     | 
| 
       251 
301 
     | 
    
         
             
                            raise ComplexTypeError, "Invalid hash thing" unless key_types.nil?
         
     | 
| 
       252 
302 
     | 
    
         
             
                            # types.push ComplexType.new([UniqueType.new(base[0..-2].strip)])
         
     | 
| 
       253 
     | 
    
         
            -
                            types.push UniqueType. 
     | 
| 
      
 303 
     | 
    
         
            +
                            types.push UniqueType.parse(base[0..-2].strip, subtype_string)
         
     | 
| 
       254 
304 
     | 
    
         
             
                            # @todo this should either expand key_type's type
         
     | 
| 
       255 
305 
     | 
    
         
             
                            #   automatically or complain about not being
         
     | 
| 
       256 
306 
     | 
    
         
             
                            #   compatible with key_type's type in type checking
         
     | 
| 
         @@ -281,7 +331,7 @@ module Solargraph 
     | 
|
| 
       281 
331 
     | 
    
         
             
                          next
         
     | 
| 
       282 
332 
     | 
    
         
             
                        elsif char == ',' && point_stack == 0 && curly_stack == 0 && paren_stack == 0
         
     | 
| 
       283 
333 
     | 
    
         
             
                          # types.push ComplexType.new([UniqueType.new(base.strip, subtype_string.strip)])
         
     | 
| 
       284 
     | 
    
         
            -
                          types.push UniqueType. 
     | 
| 
      
 334 
     | 
    
         
            +
                          types.push UniqueType.parse(base.strip, subtype_string.strip)
         
     | 
| 
       285 
335 
     | 
    
         
             
                          base.clear
         
     | 
| 
       286 
336 
     | 
    
         
             
                          subtype_string.clear
         
     | 
| 
       287 
337 
     | 
    
         
             
                          next
         
     | 
| 
         @@ -294,7 +344,7 @@ module Solargraph 
     | 
|
| 
       294 
344 
     | 
    
         
             
                      end
         
     | 
| 
       295 
345 
     | 
    
         
             
                      raise ComplexTypeError, "Unclosed subtype in #{type_string}" if point_stack != 0 || curly_stack != 0 || paren_stack != 0
         
     | 
| 
       296 
346 
     | 
    
         
             
                      # types.push ComplexType.new([UniqueType.new(base, subtype_string)])
         
     | 
| 
       297 
     | 
    
         
            -
                      types.push UniqueType. 
     | 
| 
      
 347 
     | 
    
         
            +
                      types.push UniqueType.parse(base.strip, subtype_string.strip)
         
     | 
| 
       298 
348 
     | 
    
         
             
                    end
         
     | 
| 
       299 
349 
     | 
    
         
             
                    unless key_types.nil?
         
     | 
| 
       300 
350 
     | 
    
         
             
                      raise ComplexTypeError, "Invalid use of key/value parameters" unless partial
         
     | 
| 
         @@ -311,18 +361,33 @@ module Solargraph 
     | 
|
| 
       311 
361 
     | 
    
         
             
                  def try_parse *strings
         
     | 
| 
       312 
362 
     | 
    
         
             
                    parse *strings
         
     | 
| 
       313 
363 
     | 
    
         
             
                  rescue ComplexTypeError => e
         
     | 
| 
       314 
     | 
    
         
            -
                    Solargraph.logger.info "Error parsing complex type 
     | 
| 
      
 364 
     | 
    
         
            +
                    Solargraph.logger.info "Error parsing complex type `#{strings.join(', ')}`: #{e.message}"
         
     | 
| 
       315 
365 
     | 
    
         
             
                    ComplexType::UNDEFINED
         
     | 
| 
       316 
366 
     | 
    
         
             
                  end
         
     | 
| 
       317 
367 
     | 
    
         
             
                end
         
     | 
| 
       318 
368 
     | 
    
         | 
| 
       319 
369 
     | 
    
         
             
                VOID = ComplexType.parse('void')
         
     | 
| 
       320 
370 
     | 
    
         
             
                UNDEFINED = ComplexType.parse('undefined')
         
     | 
| 
       321 
     | 
    
         
            -
                SYMBOL = ComplexType.parse('Symbol')
         
     | 
| 
       322 
     | 
    
         
            -
                ROOT = ComplexType.parse('Class<>')
         
     | 
| 
      
 371 
     | 
    
         
            +
                SYMBOL = ComplexType.parse('::Symbol')
         
     | 
| 
      
 372 
     | 
    
         
            +
                ROOT = ComplexType.parse('::Class<>')
         
     | 
| 
       323 
373 
     | 
    
         
             
                NIL = ComplexType.parse('nil')
         
     | 
| 
       324 
374 
     | 
    
         
             
                SELF = ComplexType.parse('self')
         
     | 
| 
       325 
     | 
    
         
            -
                BOOLEAN = ComplexType.parse('Boolean')
         
     | 
| 
      
 375 
     | 
    
         
            +
                BOOLEAN = ComplexType.parse('::Boolean')
         
     | 
| 
       326 
376 
     | 
    
         
             
                BOT = ComplexType.parse('bot')
         
     | 
| 
      
 377 
     | 
    
         
            +
             
     | 
| 
      
 378 
     | 
    
         
            +
                private
         
     | 
| 
      
 379 
     | 
    
         
            +
             
     | 
| 
      
 380 
     | 
    
         
            +
                # @todo This is a quick and dirty hack that forces `self` keywords
         
     | 
| 
      
 381 
     | 
    
         
            +
                #   to reference an instance of their class and never the class itself.
         
     | 
| 
      
 382 
     | 
    
         
            +
                #   This behavior may change depending on which result is expected
         
     | 
| 
      
 383 
     | 
    
         
            +
                #   from YARD conventions. See https://github.com/lsegal/yard/issues/1257
         
     | 
| 
      
 384 
     | 
    
         
            +
                # @param dst [String]
         
     | 
| 
      
 385 
     | 
    
         
            +
                # @return [String]
         
     | 
| 
      
 386 
     | 
    
         
            +
                def reduce_class dst
         
     | 
| 
      
 387 
     | 
    
         
            +
                  while dst =~ /^(Class|Module)\<(.*?)\>$/
         
     | 
| 
      
 388 
     | 
    
         
            +
                    dst = dst.sub(/^(Class|Module)\</, '').sub(/\>$/, '')
         
     | 
| 
      
 389 
     | 
    
         
            +
                  end
         
     | 
| 
      
 390 
     | 
    
         
            +
                  dst
         
     | 
| 
      
 391 
     | 
    
         
            +
                end
         
     | 
| 
       327 
392 
     | 
    
         
             
              end
         
     | 
| 
       328 
393 
     | 
    
         
             
            end
         
     | 
    
        data/lib/solargraph/doc_map.rb
    CHANGED
    
    | 
         @@ -18,9 +18,11 @@ module Solargraph 
     | 
|
| 
       18 
18 
     | 
    
         | 
| 
       19 
19 
     | 
    
         
             
                # @param requires [Array<String>]
         
     | 
| 
       20 
20 
     | 
    
         
             
                # @param preferences [Array<Gem::Specification>]
         
     | 
| 
       21 
     | 
    
         
            -
                 
     | 
| 
      
 21 
     | 
    
         
            +
                # @param rbs_path [String, Pathname, nil]
         
     | 
| 
      
 22 
     | 
    
         
            +
                def initialize(requires, preferences, rbs_path = nil)
         
     | 
| 
       22 
23 
     | 
    
         
             
                  @requires = requires.compact
         
     | 
| 
       23 
24 
     | 
    
         
             
                  @preferences = preferences.compact
         
     | 
| 
      
 25 
     | 
    
         
            +
                  @rbs_path = rbs_path
         
     | 
| 
       24 
26 
     | 
    
         
             
                  generate
         
     | 
| 
       25 
27 
     | 
    
         
             
                end
         
     | 
| 
       26 
28 
     | 
    
         | 
| 
         @@ -39,6 +41,7 @@ module Solargraph 
     | 
|
| 
       39 
41 
     | 
    
         
             
                  @gems_in_memory ||= {}
         
     | 
| 
       40 
42 
     | 
    
         
             
                end
         
     | 
| 
       41 
43 
     | 
    
         | 
| 
      
 44 
     | 
    
         
            +
                # @return [Set<Gem::Specification>]
         
     | 
| 
       42 
45 
     | 
    
         
             
                def dependencies
         
     | 
| 
       43 
46 
     | 
    
         
             
                  @dependencies ||= (gemspecs.flat_map { |spec| fetch_dependencies(spec) } - gemspecs).to_set
         
     | 
| 
       44 
47 
     | 
    
         
             
                end
         
     | 
| 
         @@ -57,6 +60,7 @@ module Solargraph 
     | 
|
| 
       57 
60 
     | 
    
         
             
                    end
         
     | 
| 
       58 
61 
     | 
    
         
             
                  end
         
     | 
| 
       59 
62 
     | 
    
         
             
                  dependencies.each { |dep| try_cache dep }
         
     | 
| 
      
 63 
     | 
    
         
            +
                  @uncached_gemspecs.uniq!
         
     | 
| 
       60 
64 
     | 
    
         
             
                end
         
     | 
| 
       61 
65 
     | 
    
         | 
| 
       62 
66 
     | 
    
         
             
                # @return [Hash{String => Gem::Specification, nil}]
         
     | 
| 
         @@ -75,7 +79,8 @@ module Solargraph 
     | 
|
| 
       75 
79 
     | 
    
         
             
                  return if try_gem_in_memory(gemspec)
         
     | 
| 
       76 
80 
     | 
    
         
             
                  cache_file = File.join('gems', "#{gemspec.name}-#{gemspec.version}.ser")
         
     | 
| 
       77 
81 
     | 
    
         
             
                  if Cache.exist?(cache_file)
         
     | 
| 
       78 
     | 
    
         
            -
                     
     | 
| 
      
 82 
     | 
    
         
            +
                    cached = Cache.load(cache_file)
         
     | 
| 
      
 83 
     | 
    
         
            +
                    gempins = update_from_collection(gemspec, cached)
         
     | 
| 
       79 
84 
     | 
    
         
             
                    self.class.gems_in_memory[gemspec] = gempins
         
     | 
| 
       80 
85 
     | 
    
         
             
                    @pins.concat gempins
         
     | 
| 
       81 
86 
     | 
    
         
             
                  else
         
     | 
| 
         @@ -93,7 +98,7 @@ module Solargraph 
     | 
|
| 
       93 
98 
     | 
    
         
             
                    @pins.concat map.pins
         
     | 
| 
       94 
99 
     | 
    
         
             
                  else
         
     | 
| 
       95 
100 
     | 
    
         
             
                    # @todo Temporarily ignoring unresolved `require 'set'`
         
     | 
| 
       96 
     | 
    
         
            -
                    Solargraph.logger. 
     | 
| 
      
 101 
     | 
    
         
            +
                    Solargraph.logger.debug "Require path #{path} could not be resolved" unless path == 'set'
         
     | 
| 
       97 
102 
     | 
    
         
             
                  end
         
     | 
| 
       98 
103 
     | 
    
         
             
                end
         
     | 
| 
       99 
104 
     | 
    
         | 
| 
         @@ -107,6 +112,17 @@ module Solargraph 
     | 
|
| 
       107 
112 
     | 
    
         
             
                  true
         
     | 
| 
       108 
113 
     | 
    
         
             
                end
         
     | 
| 
       109 
114 
     | 
    
         | 
| 
      
 115 
     | 
    
         
            +
                def update_from_collection gemspec, gempins
         
     | 
| 
      
 116 
     | 
    
         
            +
                  return gempins unless @rbs_path && File.directory?(@rbs_path)
         
     | 
| 
      
 117 
     | 
    
         
            +
                  return gempins if RbsMap.new(gemspec.name, gemspec.version).resolved?
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
                  rbs_map = RbsMap.new(gemspec.name, gemspec.version, directories: [@rbs_path])
         
     | 
| 
      
 120 
     | 
    
         
            +
                  return gempins unless rbs_map.resolved?
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                  Solargraph.logger.info "Updating #{gemspec.name} #{gemspec.version} from collection"
         
     | 
| 
      
 123 
     | 
    
         
            +
                  GemPins.combine(gempins, rbs_map)
         
     | 
| 
      
 124 
     | 
    
         
            +
                end
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
       110 
126 
     | 
    
         
             
                # @param path [String]
         
     | 
| 
       111 
127 
     | 
    
         
             
                # @return [Gem::Specification, nil]
         
     | 
| 
       112 
128 
     | 
    
         
             
                def resolve_path_to_gemspec path
         
     | 
    
        data/lib/solargraph/gem_pins.rb
    CHANGED
    
    | 
         @@ -16,13 +16,21 @@ module Solargraph 
     | 
|
| 
       16 
16 
     | 
    
         
             
                def self.build(gemspec)
         
     | 
| 
       17 
17 
     | 
    
         
             
                  yard_pins = build_yard_pins(gemspec)
         
     | 
| 
       18 
18 
     | 
    
         
             
                  rbs_map = RbsMap.from_gemspec(gemspec)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  combine yard_pins, rbs_map
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                # @param yard_pins [Array<Pin::Base>]
         
     | 
| 
      
 23 
     | 
    
         
            +
                # @param rbs_map [RbsMap]
         
     | 
| 
      
 24 
     | 
    
         
            +
                # @return [Array<Pin::Base>]
         
     | 
| 
      
 25 
     | 
    
         
            +
                def self.combine(yard_pins, rbs_map)
         
     | 
| 
       19 
26 
     | 
    
         
             
                  in_yard = Set.new
         
     | 
| 
       20 
27 
     | 
    
         
             
                  combined = yard_pins.map do |yard|
         
     | 
| 
       21 
28 
     | 
    
         
             
                    in_yard.add yard.path
         
     | 
| 
       22 
29 
     | 
    
         
             
                    next yard unless yard.is_a?(Pin::Method)
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
       23 
31 
     | 
    
         
             
                    rbs = rbs_map.path_pin(yard.path, Pin::Method)
         
     | 
| 
       24 
32 
     | 
    
         
             
                    next yard unless rbs
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
       26 
34 
     | 
    
         
             
                    # @sg-ignore
         
     | 
| 
       27 
35 
     | 
    
         
             
                    yard.class.new(
         
     | 
| 
       28 
36 
     | 
    
         
             
                      location: yard.location,
         
     |