solargraph 0.48.0 → 0.50.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.
- checksums.yaml +4 -4
 - data/.github/FUNDING.yml +1 -0
 - data/.github/workflows/rspec.yml +1 -1
 - data/CHANGELOG.md +29 -0
 - data/LICENSE +1 -1
 - data/README.md +2 -4
 - data/SPONSORS.md +4 -4
 - data/lib/solargraph/api_map/store.rb +13 -1
 - data/lib/solargraph/api_map.rb +30 -12
 - data/lib/solargraph/cache.rb +53 -0
 - data/lib/solargraph/complex_type/type_methods.rb +3 -6
 - data/lib/solargraph/complex_type/unique_type.rb +57 -0
 - data/lib/solargraph/complex_type.rb +22 -3
 - data/lib/solargraph/convention/rakefile.rb +17 -0
 - data/lib/solargraph/convention.rb +2 -0
 - data/lib/solargraph/diagnostics/rubocop.rb +15 -2
 - data/lib/solargraph/diagnostics/rubocop_helpers.rb +3 -1
 - data/lib/solargraph/language_server/host/cataloger.rb +1 -1
 - data/lib/solargraph/language_server/host.rb +22 -18
 - data/lib/solargraph/language_server/message/extended/download_core.rb +1 -5
 - data/lib/solargraph/language_server/message/initialize.rb +2 -0
 - data/lib/solargraph/language_server/message/text_document/formatting.rb +1 -1
 - data/lib/solargraph/language_server/message/text_document/signature_help.rb +1 -6
 - data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +10 -3
 - data/lib/solargraph/library.rb +25 -20
 - data/lib/solargraph/parser/rubyvm/class_methods.rb +6 -1
 - data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +20 -8
 - data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +14 -3
 - data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +4 -2
 - data/lib/solargraph/parser/rubyvm/node_wrapper.rb +47 -0
 - data/lib/solargraph/pin/base.rb +5 -2
 - data/lib/solargraph/pin/base_variable.rb +1 -1
 - data/lib/solargraph/pin/conversions.rb +2 -6
 - data/lib/solargraph/pin/method.rb +84 -10
 - data/lib/solargraph/pin/namespace.rb +4 -1
 - data/lib/solargraph/pin/parameter.rb +8 -3
 - data/lib/solargraph/pin/signature.rb +23 -0
 - data/lib/solargraph/pin.rb +1 -0
 - data/lib/solargraph/rbs_map/conversions.rb +394 -0
 - data/lib/solargraph/rbs_map/core_fills.rb +61 -0
 - data/lib/solargraph/rbs_map/core_map.rb +38 -0
 - data/lib/solargraph/rbs_map/core_signs.rb +33 -0
 - data/lib/solargraph/rbs_map/stdlib_map.rb +36 -0
 - data/lib/solargraph/rbs_map.rb +73 -0
 - data/lib/solargraph/shell.rb +50 -32
 - data/lib/solargraph/source/chain/call.rb +31 -23
 - data/lib/solargraph/source/chain.rb +22 -7
 - data/lib/solargraph/source_map/clip.rb +5 -0
 - data/lib/solargraph/source_map/mapper.rb +8 -4
 - data/lib/solargraph/type_checker.rb +71 -65
 - data/lib/solargraph/version.rb +1 -1
 - data/lib/solargraph/views/environment.erb +2 -2
 - data/lib/solargraph/workspace.rb +11 -14
 - data/lib/solargraph/yard_map/mapper/to_method.rb +7 -4
 - data/lib/solargraph/yard_map.rb +10 -151
 - data/lib/solargraph.rb +2 -2
 - data/solargraph.gemspec +11 -6
 - metadata +46 -37
 - data/.travis.yml +0 -19
 - data/lib/solargraph/compat.rb +0 -37
 - data/lib/solargraph/yard_map/core_docs.rb +0 -170
 - data/lib/solargraph/yard_map/core_fills.rb +0 -208
 - data/lib/solargraph/yard_map/core_gen.rb +0 -76
 - data/lib/solargraph/yard_map/rdoc_to_yard.rb +0 -143
 - data/lib/solargraph/yard_map/stdlib_fills.rb +0 -43
 - data/yardoc/2.2.2.tar.gz +0 -0
 
    
        data/lib/solargraph/shell.rb
    CHANGED
    
    | 
         @@ -71,43 +71,46 @@ module Solargraph 
     | 
|
| 
       71 
71 
     | 
    
         
             
                  STDOUT.puts "Configuration file initialized."
         
     | 
| 
       72 
72 
     | 
    
         
             
                end
         
     | 
| 
       73 
73 
     | 
    
         | 
| 
       74 
     | 
    
         
            -
                desc 'download-core [VERSION]', 'Download core documentation'
         
     | 
| 
       75 
     | 
    
         
            -
                 
     | 
| 
       76 
     | 
    
         
            -
                   
     | 
| 
       77 
     | 
    
         
            -
                   
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
                   
     | 
| 
       82 
     | 
    
         
            -
                   
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
                 
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
                   
     | 
| 
       88 
     | 
    
         
            -
                   
     | 
| 
       89 
     | 
    
         
            -
                 
     | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
       91 
     | 
    
         
            -
                desc 'list-cores', 'List the local documentation versions'
         
     | 
| 
      
 74 
     | 
    
         
            +
                desc 'download-core [VERSION]', 'Download core documentation [deprecated]', hide: true
         
     | 
| 
      
 75 
     | 
    
         
            +
                long_desc %(
         
     | 
| 
      
 76 
     | 
    
         
            +
                  The `download-core` command is deprecated. Current versions of Solargraph
         
     | 
| 
      
 77 
     | 
    
         
            +
                  use RBS for core and stdlib documentation.
         
     | 
| 
      
 78 
     | 
    
         
            +
                )
         
     | 
| 
      
 79 
     | 
    
         
            +
                # @deprecated
         
     | 
| 
      
 80 
     | 
    
         
            +
                def download_core _version = nil
         
     | 
| 
      
 81 
     | 
    
         
            +
                  puts 'The `download-core` command is deprecated.'
         
     | 
| 
      
 82 
     | 
    
         
            +
                  puts 'Current versions of Solargraph use RBS for core and stdlib documentation.'
         
     | 
| 
      
 83 
     | 
    
         
            +
                end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                desc 'list-cores', 'List the local documentation versions [deprecated]', hide: true
         
     | 
| 
      
 86 
     | 
    
         
            +
                long_desc %(
         
     | 
| 
      
 87 
     | 
    
         
            +
                  The `list-cores` command is deprecated. Current versions of Solargraph use
         
     | 
| 
      
 88 
     | 
    
         
            +
                  RBS for core and stdlib documentation.
         
     | 
| 
      
 89 
     | 
    
         
            +
                )
         
     | 
| 
      
 90 
     | 
    
         
            +
                # @deprecated
         
     | 
| 
       92 
91 
     | 
    
         
             
                def list_cores
         
     | 
| 
       93 
     | 
    
         
            -
                  puts  
     | 
| 
      
 92 
     | 
    
         
            +
                  puts 'The `list-cores` command is deprecated.'
         
     | 
| 
      
 93 
     | 
    
         
            +
                  puts 'Current versions of Solargraph use RBS for core and stdlib documentation.'
         
     | 
| 
       94 
94 
     | 
    
         
             
                end
         
     | 
| 
       95 
95 
     | 
    
         | 
| 
       96 
     | 
    
         
            -
                desc 'available-cores', 'List available documentation versions'
         
     | 
| 
      
 96 
     | 
    
         
            +
                desc 'available-cores', 'List available documentation versions [deprecated]', hide: true
         
     | 
| 
      
 97 
     | 
    
         
            +
                long_desc %(
         
     | 
| 
      
 98 
     | 
    
         
            +
                  The `available-cores` command is deprecated. Current versions of Solargraph
         
     | 
| 
      
 99 
     | 
    
         
            +
                  use RBS for core and stdlib documentation.
         
     | 
| 
      
 100 
     | 
    
         
            +
                )
         
     | 
| 
      
 101 
     | 
    
         
            +
                # @deprecated
         
     | 
| 
       97 
102 
     | 
    
         
             
                def available_cores
         
     | 
| 
       98 
     | 
    
         
            -
                  puts  
     | 
| 
      
 103 
     | 
    
         
            +
                  puts 'The `available-cores` command is deprecated.'
         
     | 
| 
      
 104 
     | 
    
         
            +
                  puts 'Current versions of Solargraph use RBS for core and stdlib documentation.'
         
     | 
| 
       99 
105 
     | 
    
         
             
                end
         
     | 
| 
       100 
106 
     | 
    
         | 
| 
       101 
107 
     | 
    
         
             
                desc 'clear', 'Delete all cached documentation'
         
     | 
| 
       102 
108 
     | 
    
         
             
                long_desc %(
         
     | 
| 
       103 
109 
     | 
    
         
             
                  This command will delete all core and gem documentation from the cache.
         
     | 
| 
       104 
     | 
    
         
            -
                  You can also delete specific gem caches with the `uncache` command or
         
     | 
| 
       105 
     | 
    
         
            -
                  update documentation for specific Ruby versions with the `download-core`
         
     | 
| 
       106 
     | 
    
         
            -
                  command.
         
     | 
| 
       107 
110 
     | 
    
         
             
                )
         
     | 
| 
       108 
111 
     | 
    
         
             
                def clear
         
     | 
| 
       109 
112 
     | 
    
         
             
                  puts "Deleting the cached documentation"
         
     | 
| 
       110 
     | 
    
         
            -
                  Solargraph:: 
     | 
| 
      
 113 
     | 
    
         
            +
                  Solargraph::Cache.clear
         
     | 
| 
       111 
114 
     | 
    
         
             
                end
         
     | 
| 
       112 
115 
     | 
    
         
             
                map 'clear-cache' => :clear
         
     | 
| 
       113 
116 
     | 
    
         
             
                map 'clear-cores' => :clear
         
     | 
| 
         @@ -191,18 +194,33 @@ module Solargraph 
     | 
|
| 
       191 
194 
     | 
    
         
             
                  puts "Scanned #{directory} (#{api_map.pins.length} pins) in #{time.real} seconds."
         
     | 
| 
       192 
195 
     | 
    
         
             
                end
         
     | 
| 
       193 
196 
     | 
    
         | 
| 
       194 
     | 
    
         
            -
                desc ' 
     | 
| 
      
 197 
     | 
    
         
            +
                desc 'list', 'List the files in the workspace and the total count'
         
     | 
| 
      
 198 
     | 
    
         
            +
                option :count, type: :boolean, aliases: :c, desc: 'Display the file count only', default: false
         
     | 
| 
      
 199 
     | 
    
         
            +
                option :directory, type: :string, aliases: :d, desc: 'The directory to read', default: '.'
         
     | 
| 
      
 200 
     | 
    
         
            +
                def list
         
     | 
| 
      
 201 
     | 
    
         
            +
                  workspace = Solargraph::Workspace.new(options[:directory])
         
     | 
| 
      
 202 
     | 
    
         
            +
                  unless options[:count]
         
     | 
| 
      
 203 
     | 
    
         
            +
                    workspace.filenames.each { |f| puts f }
         
     | 
| 
      
 204 
     | 
    
         
            +
                  end
         
     | 
| 
      
 205 
     | 
    
         
            +
                  puts "#{workspace.filenames.length} files total."
         
     | 
| 
      
 206 
     | 
    
         
            +
                end
         
     | 
| 
      
 207 
     | 
    
         
            +
             
     | 
| 
      
 208 
     | 
    
         
            +
                desc 'bundle', 'Generate documentation for bundled gems [deprecated]', hide: true
         
     | 
| 
      
 209 
     | 
    
         
            +
                long_desc %(
         
     | 
| 
      
 210 
     | 
    
         
            +
                  The `bundle` command is deprecated. Solargraph currently uses RBS instead.
         
     | 
| 
      
 211 
     | 
    
         
            +
                )
         
     | 
| 
       195 
212 
     | 
    
         
             
                option :directory, type: :string, aliases: :d, desc: 'The workspace directory', default: '.'
         
     | 
| 
       196 
213 
     | 
    
         
             
                option :rebuild, type: :boolean, aliases: :r, desc: 'Rebuild existing documentation', default: false
         
     | 
| 
       197 
214 
     | 
    
         
             
                def bundle
         
     | 
| 
       198 
     | 
    
         
            -
                   
     | 
| 
      
 215 
     | 
    
         
            +
                  puts 'The `bundle` command is deprecated. Solargraph currently uses RBS instead.'
         
     | 
| 
       199 
216 
     | 
    
         
             
                end
         
     | 
| 
       200 
217 
     | 
    
         | 
| 
       201 
     | 
    
         
            -
                desc 'rdoc GEM [VERSION]', 'Use RDoc to cache documentation'
         
     | 
| 
       202 
     | 
    
         
            -
                 
     | 
| 
       203 
     | 
    
         
            -
                   
     | 
| 
       204 
     | 
    
         
            -
             
     | 
| 
       205 
     | 
    
         
            -
             
     | 
| 
      
 218 
     | 
    
         
            +
                desc 'rdoc GEM [VERSION]', 'Use RDoc to cache documentation [deprecated]', hide: true
         
     | 
| 
      
 219 
     | 
    
         
            +
                long_desc %(
         
     | 
| 
      
 220 
     | 
    
         
            +
                  The `rdoc` command is deprecated. Solargraph currently uses RBS instead.
         
     | 
| 
      
 221 
     | 
    
         
            +
                )
         
     | 
| 
      
 222 
     | 
    
         
            +
                def rdoc _gem, _version = '>= 0'
         
     | 
| 
      
 223 
     | 
    
         
            +
                  puts 'The `rdoc` command is deprecated. Solargraph currently uses RBS instead.'
         
     | 
| 
       206 
224 
     | 
    
         
             
                end
         
     | 
| 
       207 
225 
     | 
    
         | 
| 
       208 
226 
     | 
    
         
             
                private
         
     | 
| 
         @@ -52,36 +52,32 @@ module Solargraph 
     | 
|
| 
       52 
52 
     | 
    
         
             
                    # @return [Array<Pin::Base>]
         
     | 
| 
       53 
53 
     | 
    
         
             
                    def inferred_pins pins, api_map, context, locals
         
     | 
| 
       54 
54 
     | 
    
         
             
                      result = pins.map do |p|
         
     | 
| 
       55 
     | 
    
         
            -
                         
     | 
| 
      
 55 
     | 
    
         
            +
                        next p unless p.is_a?(Pin::Method)
         
     | 
| 
      
 56 
     | 
    
         
            +
                        overloads = p.signatures
         
     | 
| 
       56 
57 
     | 
    
         
             
                        # next p if overloads.empty?
         
     | 
| 
       57 
58 
     | 
    
         
             
                        type = ComplexType::UNDEFINED
         
     | 
| 
       58 
     | 
    
         
            -
                        # @param [YARD::Tags::OverloadTag]
         
     | 
| 
       59 
59 
     | 
    
         
             
                        overloads.each do |ol|
         
     | 
| 
       60 
     | 
    
         
            -
                          next unless arguments_match(arguments, ol 
     | 
| 
       61 
     | 
    
         
            -
                          next if ol.parameters.last && ol.parameters.last.first.start_with?('&') && ol.parameters.last.last.nil? && !with_block?
         
     | 
| 
      
 60 
     | 
    
         
            +
                          next unless arguments_match(arguments, ol)
         
     | 
| 
      
 61 
     | 
    
         
            +
                          # next if ol.parameters.last && ol.parameters.last.first.start_with?('&') && ol.parameters.last.last.nil? && !with_block?
         
     | 
| 
       62 
62 
     | 
    
         
             
                          match = true
         
     | 
| 
       63 
63 
     | 
    
         
             
                          arguments.each_with_index do |arg, idx|
         
     | 
| 
       64 
     | 
    
         
            -
                            achain = arguments[idx]
         
     | 
| 
       65 
     | 
    
         
            -
                            next if achain.nil?
         
     | 
| 
       66 
64 
     | 
    
         
             
                            param = ol.parameters[idx]
         
     | 
| 
       67 
65 
     | 
    
         
             
                            if param.nil?
         
     | 
| 
       68 
     | 
    
         
            -
                              match = false unless ol.parameters. 
     | 
| 
      
 66 
     | 
    
         
            +
                              match = false unless ol.parameters.any?(&:restarg?)
         
     | 
| 
       69 
67 
     | 
    
         
             
                              break
         
     | 
| 
       70 
68 
     | 
    
         
             
                            end
         
     | 
| 
       71 
     | 
    
         
            -
                             
     | 
| 
       72 
     | 
    
         
            -
                            next if par.nil? || par.types.nil? || par.types.empty?
         
     | 
| 
       73 
     | 
    
         
            -
                            atype = achain.infer(api_map, Pin::ProxyType.anonymous(context), locals)
         
     | 
| 
       74 
     | 
    
         
            -
                            other = ComplexType.try_parse(*par.types)
         
     | 
| 
      
 69 
     | 
    
         
            +
                            atype = arg.infer(api_map, Pin::ProxyType.anonymous(context), locals)
         
     | 
| 
       75 
70 
     | 
    
         
             
                            # @todo Weak type comparison
         
     | 
| 
       76 
     | 
    
         
            -
                            unless atype.tag ==  
     | 
| 
      
 71 
     | 
    
         
            +
                            # unless atype.tag == param.return_type.tag || api_map.super_and_sub?(param.return_type.tag, atype.tag)
         
     | 
| 
      
 72 
     | 
    
         
            +
                            unless param.return_type.undefined? || atype.name == param.return_type.name || api_map.super_and_sub?(param.return_type.name, atype.name)
         
     | 
| 
       77 
73 
     | 
    
         
             
                              match = false
         
     | 
| 
       78 
74 
     | 
    
         
             
                              break
         
     | 
| 
       79 
75 
     | 
    
         
             
                            end
         
     | 
| 
       80 
76 
     | 
    
         
             
                          end
         
     | 
| 
       81 
77 
     | 
    
         
             
                          if match
         
     | 
| 
       82 
     | 
    
         
            -
                            type = extra_return_type( 
     | 
| 
      
 78 
     | 
    
         
            +
                            type = extra_return_type(p.docstring, context)
         
     | 
| 
       83 
79 
     | 
    
         
             
                            break if type
         
     | 
| 
       84 
     | 
    
         
            -
                            type =  
     | 
| 
      
 80 
     | 
    
         
            +
                            type = with_params(ol.return_type.self_to(context.to_s), context).qualify(api_map, context.namespace) if ol.return_type.defined?
         
     | 
| 
       85 
81 
     | 
    
         
             
                            type ||= ComplexType::UNDEFINED
         
     | 
| 
       86 
82 
     | 
    
         
             
                          end
         
     | 
| 
       87 
83 
     | 
    
         
             
                          break if type.defined?
         
     | 
| 
         @@ -110,9 +106,13 @@ module Solargraph 
     | 
|
| 
       110 
106 
     | 
    
         
             
                        p
         
     | 
| 
       111 
107 
     | 
    
         
             
                      end
         
     | 
| 
       112 
108 
     | 
    
         
             
                      result.map do |pin|
         
     | 
| 
       113 
     | 
    
         
            -
                         
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
       115 
     | 
    
         
            -
                         
     | 
| 
      
 109 
     | 
    
         
            +
                        if pin.path == 'Class#new' && context.tag != 'Class'
         
     | 
| 
      
 110 
     | 
    
         
            +
                          pin.proxy(ComplexType.try_parse(context.namespace))
         
     | 
| 
      
 111 
     | 
    
         
            +
                        else
         
     | 
| 
      
 112 
     | 
    
         
            +
                          next pin if pin.return_type.undefined?
         
     | 
| 
      
 113 
     | 
    
         
            +
                          selfy = pin.return_type.self_to(context.tag)
         
     | 
| 
      
 114 
     | 
    
         
            +
                          selfy == pin.return_type ? pin : pin.proxy(selfy)
         
     | 
| 
      
 115 
     | 
    
         
            +
                        end
         
     | 
| 
       116 
116 
     | 
    
         
             
                      end
         
     | 
| 
       117 
117 
     | 
    
         
             
                    end
         
     | 
| 
       118 
118 
     | 
    
         | 
| 
         @@ -183,14 +183,15 @@ module Solargraph 
     | 
|
| 
       183 
183 
     | 
    
         
             
                    end
         
     | 
| 
       184 
184 
     | 
    
         | 
| 
       185 
185 
     | 
    
         
             
                    # @param arguments [Array<Chain>]
         
     | 
| 
       186 
     | 
    
         
            -
                    # @param  
     | 
| 
      
 186 
     | 
    
         
            +
                    # @param signature [Pin::Signature]
         
     | 
| 
       187 
187 
     | 
    
         
             
                    # @return [Boolean]
         
     | 
| 
       188 
     | 
    
         
            -
                    def arguments_match arguments,  
     | 
| 
      
 188 
     | 
    
         
            +
                    def arguments_match arguments, signature
         
     | 
| 
      
 189 
     | 
    
         
            +
                      parameters = signature.parameters
         
     | 
| 
       189 
190 
     | 
    
         
             
                      argcount = arguments.length
         
     | 
| 
       190 
     | 
    
         
            -
                      # argcount -= 1 if !arguments.empty? && arguments.last.links.first.word.start_with?('&')
         
     | 
| 
       191 
191 
     | 
    
         
             
                      parcount = parameters.length
         
     | 
| 
       192 
     | 
    
         
            -
                      parcount -= 1 if !parameters.empty? && parameters.last. 
     | 
| 
       193 
     | 
    
         
            -
                      return false if  
     | 
| 
      
 192 
     | 
    
         
            +
                      parcount -= 1 if !parameters.empty? && parameters.last.block?
         
     | 
| 
      
 193 
     | 
    
         
            +
                      return false if signature.block? && !with_block?
         
     | 
| 
      
 194 
     | 
    
         
            +
                      return false if argcount < parcount && !(argcount == parcount - 1 && parameters.last.restarg?)
         
     | 
| 
       194 
195 
     | 
    
         
             
                      true
         
     | 
| 
       195 
196 
     | 
    
         
             
                    end
         
     | 
| 
       196 
197 
     | 
    
         | 
| 
         @@ -198,9 +199,16 @@ module Solargraph 
     | 
|
| 
       198 
199 
     | 
    
         
             
                    # @param name_pin [Pin::Base]
         
     | 
| 
       199 
200 
     | 
    
         
             
                    # @return [Array<Pin::Base>]
         
     | 
| 
       200 
201 
     | 
    
         
             
                    def super_pins api_map, name_pin
         
     | 
| 
       201 
     | 
    
         
            -
                      pins = api_map.get_method_stack(name_pin.namespace, name_pin.name, scope: name_pin.scope)
         
     | 
| 
      
 202 
     | 
    
         
            +
                      pins = api_map.get_method_stack(name_pin.namespace, name_pin.name, scope: name_pin.context.scope)
         
     | 
| 
       202 
203 
     | 
    
         
             
                      pins.reject{|p| p.path == name_pin.path}
         
     | 
| 
       203 
204 
     | 
    
         
             
                    end
         
     | 
| 
      
 205 
     | 
    
         
            +
             
     | 
| 
      
 206 
     | 
    
         
            +
                    # @param type [ComplexType]
         
     | 
| 
      
 207 
     | 
    
         
            +
                    # @param context [ComplexType]
         
     | 
| 
      
 208 
     | 
    
         
            +
                    def with_params type, context
         
     | 
| 
      
 209 
     | 
    
         
            +
                      return type unless type.to_s.include?('$')
         
     | 
| 
      
 210 
     | 
    
         
            +
                      ComplexType.try_parse(type.to_s.gsub('$', context.value_types.map(&:tag).join(', ')).gsub('<>', ''))
         
     | 
| 
      
 211 
     | 
    
         
            +
                    end
         
     | 
| 
       204 
212 
     | 
    
         
             
                  end
         
     | 
| 
       205 
213 
     | 
    
         
             
                end
         
     | 
| 
       206 
214 
     | 
    
         
             
              end
         
     | 
| 
         @@ -63,11 +63,11 @@ module Solargraph 
     | 
|
| 
       63 
63 
     | 
    
         
             
                    working_pin = name_pin
         
     | 
| 
       64 
64 
     | 
    
         
             
                    links[0..-2].each do |link|
         
     | 
| 
       65 
65 
     | 
    
         
             
                      pins = link.resolve(api_map, working_pin, locals)
         
     | 
| 
       66 
     | 
    
         
            -
                      type = infer_first_defined(pins, working_pin, api_map)
         
     | 
| 
      
 66 
     | 
    
         
            +
                      type = infer_first_defined(pins, working_pin, api_map, locals)
         
     | 
| 
       67 
67 
     | 
    
         
             
                      return [] if type.undefined?
         
     | 
| 
       68 
68 
     | 
    
         
             
                      working_pin = Pin::ProxyType.anonymous(type)
         
     | 
| 
       69 
69 
     | 
    
         
             
                    end
         
     | 
| 
       70 
     | 
    
         
            -
                    links.last.last_context =  
     | 
| 
      
 70 
     | 
    
         
            +
                    links.last.last_context = name_pin
         
     | 
| 
       71 
71 
     | 
    
         
             
                    links.last.resolve(api_map, working_pin, locals)
         
     | 
| 
       72 
72 
     | 
    
         
             
                  end
         
     | 
| 
       73 
73 
     | 
    
         | 
| 
         @@ -76,8 +76,12 @@ module Solargraph 
     | 
|
| 
       76 
76 
     | 
    
         
             
                  # @param locals [Array<Pin::Base>]
         
     | 
| 
       77 
77 
     | 
    
         
             
                  # @return [ComplexType]
         
     | 
| 
       78 
78 
     | 
    
         
             
                  def infer api_map, name_pin, locals
         
     | 
| 
      
 79 
     | 
    
         
            +
                    from_here = base.infer(api_map, name_pin, locals) unless links.length == 1
         
     | 
| 
      
 80 
     | 
    
         
            +
                    if from_here
         
     | 
| 
      
 81 
     | 
    
         
            +
                      name_pin = name_pin.proxy(from_here)
         
     | 
| 
      
 82 
     | 
    
         
            +
                    end
         
     | 
| 
       79 
83 
     | 
    
         
             
                    pins = define(api_map, name_pin, locals)
         
     | 
| 
       80 
     | 
    
         
            -
                    type = infer_first_defined(pins, links.last.last_context, api_map)
         
     | 
| 
      
 84 
     | 
    
         
            +
                    type = infer_first_defined(pins, links.last.last_context, api_map, locals)
         
     | 
| 
       81 
85 
     | 
    
         
             
                    maybe_nil(type)
         
     | 
| 
       82 
86 
     | 
    
         
             
                  end
         
     | 
| 
       83 
87 
     | 
    
         | 
| 
         @@ -110,9 +114,10 @@ module Solargraph 
     | 
|
| 
       110 
114 
     | 
    
         
             
                  private
         
     | 
| 
       111 
115 
     | 
    
         | 
| 
       112 
116 
     | 
    
         
             
                  # @param pins [Array<Pin::Base>]
         
     | 
| 
      
 117 
     | 
    
         
            +
                  # @param context [Pin::Base]
         
     | 
| 
       113 
118 
     | 
    
         
             
                  # @param api_map [ApiMap]
         
     | 
| 
       114 
119 
     | 
    
         
             
                  # @return [ComplexType]
         
     | 
| 
       115 
     | 
    
         
            -
                  def infer_first_defined pins, context, api_map
         
     | 
| 
      
 120 
     | 
    
         
            +
                  def infer_first_defined pins, context, api_map, locals
         
     | 
| 
       116 
121 
     | 
    
         
             
                    possibles = []
         
     | 
| 
       117 
122 
     | 
    
         
             
                    pins.each do |pin|
         
     | 
| 
       118 
123 
     | 
    
         
             
                      # Avoid infinite recursion
         
     | 
| 
         @@ -121,8 +126,18 @@ module Solargraph 
     | 
|
| 
       121 
126 
     | 
    
         
             
                      type = pin.typify(api_map)
         
     | 
| 
       122 
127 
     | 
    
         
             
                      @@inference_stack.pop
         
     | 
| 
       123 
128 
     | 
    
         
             
                      if type.defined?
         
     | 
| 
       124 
     | 
    
         
            -
                         
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
      
 129 
     | 
    
         
            +
                        if type.parameterized?
         
     | 
| 
      
 130 
     | 
    
         
            +
                          type = type.resolve_parameters(pin.closure, context)
         
     | 
| 
      
 131 
     | 
    
         
            +
                          # idx = pin.closure.parameters.index(type.subtypes.first.name)
         
     | 
| 
      
 132 
     | 
    
         
            +
                          # next if idx.nil?
         
     | 
| 
      
 133 
     | 
    
         
            +
                          # param_type = context.return_type.all_params[idx]
         
     | 
| 
      
 134 
     | 
    
         
            +
                          # next unless param_type
         
     | 
| 
      
 135 
     | 
    
         
            +
                          # type = ComplexType.try_parse(param_type.to_s)
         
     | 
| 
      
 136 
     | 
    
         
            +
                        end
         
     | 
| 
      
 137 
     | 
    
         
            +
                        if type.defined?
         
     | 
| 
      
 138 
     | 
    
         
            +
                          possibles.push type
         
     | 
| 
      
 139 
     | 
    
         
            +
                          break if pin.is_a?(Pin::Method)
         
     | 
| 
      
 140 
     | 
    
         
            +
                        end
         
     | 
| 
       126 
141 
     | 
    
         
             
                      end
         
     | 
| 
       127 
142 
     | 
    
         
             
                    end
         
     | 
| 
       128 
143 
     | 
    
         
             
                    if possibles.empty?
         
     | 
| 
         @@ -147,7 +162,7 @@ module Solargraph 
     | 
|
| 
       147 
162 
     | 
    
         
             
                      sorted = possibles.map { |t| t.rooted? ? "::#{t}" : t.to_s }.sort { |a, _| a == 'nil' ? 1 : 0 }
         
     | 
| 
       148 
163 
     | 
    
         
             
                      ComplexType.parse(*sorted)
         
     | 
| 
       149 
164 
     | 
    
         
             
                    else
         
     | 
| 
       150 
     | 
    
         
            -
                      possibles. 
     | 
| 
      
 165 
     | 
    
         
            +
                      ComplexType.parse(possibles.map(&:to_s).join(', '))
         
     | 
| 
       151 
166 
     | 
    
         
             
                    end
         
     | 
| 
       152 
167 
     | 
    
         
             
                    return type if context.nil? || context.return_type.undefined?
         
     | 
| 
       153 
168 
     | 
    
         
             
                    type.self_to(context.return_type.namespace)
         
     | 
| 
         @@ -43,6 +43,11 @@ module Solargraph 
     | 
|
| 
       43 
43 
     | 
    
         
             
                  # @return [ComplexType]
         
     | 
| 
       44 
44 
     | 
    
         
             
                  def infer
         
     | 
| 
       45 
45 
     | 
    
         
             
                    result = cursor.chain.infer(api_map, block, locals)
         
     | 
| 
      
 46 
     | 
    
         
            +
                    if result.tag == 'Class'
         
     | 
| 
      
 47 
     | 
    
         
            +
                      # HACK: Exception to return Object from Class#new
         
     | 
| 
      
 48 
     | 
    
         
            +
                      dfn = cursor.chain.define(api_map, block, locals).first
         
     | 
| 
      
 49 
     | 
    
         
            +
                      return ComplexType.try_parse('Object') if dfn && dfn.path == 'Class#new'
         
     | 
| 
      
 50 
     | 
    
         
            +
                    end
         
     | 
| 
       46 
51 
     | 
    
         
             
                    return result unless result.tag == 'self'
         
     | 
| 
       47 
52 
     | 
    
         
             
                    ComplexType.try_parse(cursor.chain.base.infer(api_map, block, locals).namespace)
         
     | 
| 
       48 
53 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -12,7 +12,7 @@ module Solargraph 
     | 
|
| 
       12 
12 
     | 
    
         | 
| 
       13 
13 
     | 
    
         
             
                  private_class_method :new
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
                   
     | 
| 
      
 15 
     | 
    
         
            +
                  DIRECTIVE_REGEXP = /(@\!method|@\!attribute|@\!visibility|@\!domain|@\!macro|@\!parse|@\!override)/.freeze
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
17 
     | 
    
         
             
                  # Generate the data.
         
     | 
| 
       18 
18 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -24,6 +24,8 @@ module Solargraph 
     | 
|
| 
       24 
24 
     | 
    
         
             
                    @code = source.code
         
     | 
| 
       25 
25 
     | 
    
         
             
                    @comments = source.comments
         
     | 
| 
       26 
26 
     | 
    
         
             
                    @pins, @locals = Parser.map(source)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    @pins.each { |p| p.source = :code }
         
     | 
| 
      
 28 
     | 
    
         
            +
                    @locals.each { |l| l.source = :code }
         
     | 
| 
       27 
29 
     | 
    
         
             
                    process_comment_directives
         
     | 
| 
       28 
30 
     | 
    
         
             
                    [@pins, @locals]
         
     | 
| 
       29 
31 
     | 
    
         
             
                  # rescue Exception => e
         
     | 
| 
         @@ -63,7 +65,7 @@ module Solargraph 
     | 
|
| 
       63 
65 
     | 
    
         
             
                  end
         
     | 
| 
       64 
66 
     | 
    
         | 
| 
       65 
67 
     | 
    
         
             
                  def process_comment source_position, comment_position, comment
         
     | 
| 
       66 
     | 
    
         
            -
                    return unless comment.encode('UTF-8', invalid: :replace, replace: '?') =~  
     | 
| 
      
 68 
     | 
    
         
            +
                    return unless comment.encode('UTF-8', invalid: :replace, replace: '?') =~ DIRECTIVE_REGEXP
         
     | 
| 
       67 
69 
     | 
    
         
             
                    cmnt = remove_inline_comment_hashes(comment)
         
     | 
| 
       68 
70 
     | 
    
         
             
                    parse = Solargraph::Source.parse_docstring(cmnt)
         
     | 
| 
       69 
71 
     | 
    
         
             
                    last_line = 0
         
     | 
| 
         @@ -196,6 +198,8 @@ module Solargraph 
     | 
|
| 
       196 
198 
     | 
    
         
             
                      namespace.domains.concat directive.tag.types unless directive.tag.types.nil?
         
     | 
| 
       197 
199 
     | 
    
         
             
                    when 'override'
         
     | 
| 
       198 
200 
     | 
    
         
             
                      pins.push Pin::Reference::Override.new(location, directive.tag.name, docstring.tags)
         
     | 
| 
      
 201 
     | 
    
         
            +
                    when 'macro'
         
     | 
| 
      
 202 
     | 
    
         
            +
                      # @todo Handle macros
         
     | 
| 
       199 
203 
     | 
    
         
             
                    end
         
     | 
| 
       200 
204 
     | 
    
         
             
                  end
         
     | 
| 
       201 
205 
     | 
    
         | 
| 
         @@ -209,7 +213,7 @@ module Solargraph 
     | 
|
| 
       209 
213 
     | 
    
         
             
                    started = false
         
     | 
| 
       210 
214 
     | 
    
         
             
                    comment.lines.each { |l|
         
     | 
| 
       211 
215 
     | 
    
         
             
                      # Trim the comment and minimum leading whitespace
         
     | 
| 
       212 
     | 
    
         
            -
                      p = l.encode('UTF-8', invalid: :replace, replace: '?').gsub( 
     | 
| 
      
 216 
     | 
    
         
            +
                      p = l.encode('UTF-8', invalid: :replace, replace: '?').gsub(/^#+/, '')
         
     | 
| 
       213 
217 
     | 
    
         
             
                      if num.nil? && !p.strip.empty?
         
     | 
| 
       214 
218 
     | 
    
         
             
                        num = p.index(/[^ ]/)
         
     | 
| 
       215 
219 
     | 
    
         
             
                        started = true
         
     | 
| 
         @@ -224,7 +228,7 @@ module Solargraph 
     | 
|
| 
       224 
228 
     | 
    
         | 
| 
       225 
229 
     | 
    
         
             
                  # @return [void]
         
     | 
| 
       226 
230 
     | 
    
         
             
                  def process_comment_directives
         
     | 
| 
       227 
     | 
    
         
            -
                    return unless @code.encode('UTF-8', invalid: :replace, replace: '?') =~  
     | 
| 
      
 231 
     | 
    
         
            +
                    return unless @code.encode('UTF-8', invalid: :replace, replace: '?') =~ DIRECTIVE_REGEXP
         
     | 
| 
       228 
232 
     | 
    
         
             
                    code_lines = @code.lines
         
     | 
| 
       229 
233 
     | 
    
         
             
                    @source.associated_comments.each do |line, comments|
         
     | 
| 
       230 
234 
     | 
    
         
             
                      src_pos = line ? Position.new(line, code_lines[line].to_s.chomp.index(/[^\s]/) || 0) : Position.new(code_lines.length, 0)
         
     | 
| 
         @@ -120,12 +120,10 @@ module Solargraph 
     | 
|
| 
       120 
120 
     | 
    
         
             
                # @param pin [Pin::Base]
         
     | 
| 
       121 
121 
     | 
    
         
             
                # @return [Boolean]
         
     | 
| 
       122 
122 
     | 
    
         
             
                def resolved_constant? pin
         
     | 
| 
       123 
     | 
    
         
            -
                   
     | 
| 
      
 123 
     | 
    
         
            +
                  return true if pin.typify(api_map).defined?
         
     | 
| 
      
 124 
     | 
    
         
            +
                  api_map.get_constants('', *pin.closure.gates)
         
     | 
| 
       124 
125 
     | 
    
         
             
                    .select { |p| p.name == pin.return_type.namespace }
         
     | 
| 
       125 
     | 
    
         
            -
                    .any?  
     | 
| 
       126 
     | 
    
         
            -
                      inferred = p.infer(api_map)
         
     | 
| 
       127 
     | 
    
         
            -
                      ['Class', 'Module'].include?(inferred.name)
         
     | 
| 
       128 
     | 
    
         
            -
                    end
         
     | 
| 
      
 126 
     | 
    
         
            +
                    .any? { |p| p.infer(api_map).defined? }
         
     | 
| 
       129 
127 
     | 
    
         
             
                end
         
     | 
| 
       130 
128 
     | 
    
         | 
| 
       131 
129 
     | 
    
         
             
                def virtual_pin? pin
         
     | 
| 
         @@ -139,10 +137,12 @@ module Solargraph 
     | 
|
| 
       139 
137 
     | 
    
         
             
                  params = first_param_hash(stack)
         
     | 
| 
       140 
138 
     | 
    
         
             
                  result = []
         
     | 
| 
       141 
139 
     | 
    
         
             
                  if rules.require_type_tags?
         
     | 
| 
       142 
     | 
    
         
            -
                    pin. 
     | 
| 
       143 
     | 
    
         
            -
                       
     | 
| 
       144 
     | 
    
         
            -
             
     | 
| 
       145 
     | 
    
         
            -
                         
     | 
| 
      
 140 
     | 
    
         
            +
                    pin.signatures.each do |sig|
         
     | 
| 
      
 141 
     | 
    
         
            +
                      sig.parameters.each do |par|
         
     | 
| 
      
 142 
     | 
    
         
            +
                        break if par.decl == :restarg || par.decl == :kwrestarg || par.decl == :blockarg
         
     | 
| 
      
 143 
     | 
    
         
            +
                        unless params[par.name]
         
     | 
| 
      
 144 
     | 
    
         
            +
                          result.push Problem.new(pin.location, "Missing @param tag for #{par.name} on #{pin.path}", pin: pin)
         
     | 
| 
      
 145 
     | 
    
         
            +
                        end
         
     | 
| 
       146 
146 
     | 
    
         
             
                      end
         
     | 
| 
       147 
147 
     | 
    
         
             
                    end
         
     | 
| 
       148 
148 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -184,7 +184,7 @@ module Solargraph 
     | 
|
| 
       184 
184 
     | 
    
         
             
                        elsif declared_externally?(pin)
         
     | 
| 
       185 
185 
     | 
    
         
             
                          ignored_pins.push pin
         
     | 
| 
       186 
186 
     | 
    
         
             
                        end
         
     | 
| 
       187 
     | 
    
         
            -
                      elsif !pin.is_a?(Pin::Parameter)
         
     | 
| 
      
 187 
     | 
    
         
            +
                      elsif !pin.is_a?(Pin::Parameter) && !resolved_constant?(pin)
         
     | 
| 
       188 
188 
     | 
    
         
             
                        result.push Problem.new(pin.location, "Unresolved type #{pin.return_type} for variable #{pin.name}", pin: pin)
         
     | 
| 
       189 
189 
     | 
    
         
             
                      end
         
     | 
| 
       190 
190 
     | 
    
         
             
                    else
         
     | 
| 
         @@ -243,7 +243,7 @@ module Solargraph 
     | 
|
| 
       243 
243 
     | 
    
         
             
                      end
         
     | 
| 
       244 
244 
     | 
    
         
             
                      closest = found.typify(api_map) if found
         
     | 
| 
       245 
245 
     | 
    
         
             
                      if !found || found.is_a?(Pin::BaseVariable) || (closest.defined? && internal_or_core?(found))
         
     | 
| 
       246 
     | 
    
         
            -
                        unless ignored_pins.include?(found)
         
     | 
| 
      
 246 
     | 
    
         
            +
                        unless closest.parameterized? || ignored_pins.include?(found)
         
     | 
| 
       247 
247 
     | 
    
         
             
                          result.push Problem.new(location, "Unresolved call to #{missing.links.last.word}")
         
     | 
| 
       248 
248 
     | 
    
         
             
                          @marked_ranges.push rng
         
     | 
| 
       249 
249 
     | 
    
         
             
                        end
         
     | 
| 
         @@ -273,34 +273,44 @@ module Solargraph 
     | 
|
| 
       273 
273 
     | 
    
         
             
                      end
         
     | 
| 
       274 
274 
     | 
    
         
             
                      break unless rules.validate_calls?
         
     | 
| 
       275 
275 
     | 
    
         
             
                      params = first_param_hash(pins)
         
     | 
| 
       276 
     | 
    
         
            -
             
     | 
| 
       277 
     | 
    
         
            -
             
     | 
| 
       278 
     | 
    
         
            -
             
     | 
| 
       279 
     | 
    
         
            -
             
     | 
| 
       280 
     | 
    
         
            -
             
     | 
| 
       281 
     | 
    
         
            -
             
     | 
| 
       282 
     | 
    
         
            -
             
     | 
| 
       283 
     | 
    
         
            -
             
     | 
| 
       284 
     | 
    
         
            -
                             
     | 
| 
       285 
     | 
    
         
            -
             
     | 
| 
       286 
     | 
    
         
            -
                           
     | 
| 
       287 
     | 
    
         
            -
                             
     | 
| 
       288 
     | 
    
         
            -
             
     | 
| 
       289 
     | 
    
         
            -
                               
     | 
| 
      
 276 
     | 
    
         
            +
             
     | 
| 
      
 277 
     | 
    
         
            +
                      all_errors = []
         
     | 
| 
      
 278 
     | 
    
         
            +
                      pin.signatures.sort { |sig| sig.parameters.length }.each do |sig|
         
     | 
| 
      
 279 
     | 
    
         
            +
                        errors = []
         
     | 
| 
      
 280 
     | 
    
         
            +
                        sig.parameters.each_with_index do |par, idx|
         
     | 
| 
      
 281 
     | 
    
         
            +
                          argchain = base.links.last.arguments[idx]
         
     | 
| 
      
 282 
     | 
    
         
            +
                          if argchain.nil? && par.decl == :arg
         
     | 
| 
      
 283 
     | 
    
         
            +
                            errors.push Problem.new(location, "Not enough arguments to #{pin.path}")
         
     | 
| 
      
 284 
     | 
    
         
            +
                            next
         
     | 
| 
      
 285 
     | 
    
         
            +
                          end
         
     | 
| 
      
 286 
     | 
    
         
            +
                          if argchain
         
     | 
| 
      
 287 
     | 
    
         
            +
                            if par.decl != :arg
         
     | 
| 
      
 288 
     | 
    
         
            +
                              errors.concat kwarg_problems_for argchain, api_map, block_pin, locals, location, pin, params, idx
         
     | 
| 
      
 289 
     | 
    
         
            +
                              next
         
     | 
| 
       290 
290 
     | 
    
         
             
                            else
         
     | 
| 
       291 
     | 
    
         
            -
                               
     | 
| 
       292 
     | 
    
         
            -
                              if  
     | 
| 
       293 
     | 
    
         
            -
                                 
     | 
| 
      
 291 
     | 
    
         
            +
                              ptype = params.key?(par.name) ? params[par.name][:qualified] : ComplexType::UNDEFINED
         
     | 
| 
      
 292 
     | 
    
         
            +
                              if ptype.nil?
         
     | 
| 
      
 293 
     | 
    
         
            +
                                # @todo Some level (strong, I guess) should require the param here
         
     | 
| 
      
 294 
     | 
    
         
            +
                              else
         
     | 
| 
      
 295 
     | 
    
         
            +
                                argtype = argchain.infer(api_map, block_pin, locals)
         
     | 
| 
      
 296 
     | 
    
         
            +
                                if argtype.defined? && ptype.defined? && !any_types_match?(api_map, ptype, argtype)
         
     | 
| 
      
 297 
     | 
    
         
            +
                                  errors.push Problem.new(location, "Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}")
         
     | 
| 
      
 298 
     | 
    
         
            +
                                  next
         
     | 
| 
      
 299 
     | 
    
         
            +
                                end
         
     | 
| 
       294 
300 
     | 
    
         
             
                              end
         
     | 
| 
       295 
301 
     | 
    
         
             
                            end
         
     | 
| 
      
 302 
     | 
    
         
            +
                          elsif par.decl == :kwarg
         
     | 
| 
      
 303 
     | 
    
         
            +
                            errors.push Problem.new(location, "Call to #{pin.path} is missing keyword argument #{par.name}")
         
     | 
| 
      
 304 
     | 
    
         
            +
                            next
         
     | 
| 
       296 
305 
     | 
    
         
             
                          end
         
     | 
| 
       297 
     | 
    
         
            -
                         
     | 
| 
       298 
     | 
    
         
            -
             
     | 
| 
       299 
     | 
    
         
            -
             
     | 
| 
       300 
     | 
    
         
            -
                          result.push Problem.new(location, "Call to #{pin.path} is missing keyword argument #{par.name}")
         
     | 
| 
      
 306 
     | 
    
         
            +
                        end
         
     | 
| 
      
 307 
     | 
    
         
            +
                        if errors.empty?
         
     | 
| 
      
 308 
     | 
    
         
            +
                          all_errors.clear
         
     | 
| 
       301 
309 
     | 
    
         
             
                          break
         
     | 
| 
       302 
310 
     | 
    
         
             
                        end
         
     | 
| 
      
 311 
     | 
    
         
            +
                        all_errors.concat errors
         
     | 
| 
       303 
312 
     | 
    
         
             
                      end
         
     | 
| 
      
 313 
     | 
    
         
            +
                      result.concat all_errors
         
     | 
| 
       304 
314 
     | 
    
         
             
                    end
         
     | 
| 
       305 
315 
     | 
    
         
             
                    base = base.base
         
     | 
| 
       306 
316 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -310,7 +320,7 @@ module Solargraph 
     | 
|
| 
       310 
320 
     | 
    
         
             
                def kwarg_problems_for argchain, api_map, block_pin, locals, location, pin, params, first
         
     | 
| 
       311 
321 
     | 
    
         
             
                  result = []
         
     | 
| 
       312 
322 
     | 
    
         
             
                  kwargs = convert_hash(argchain.node)
         
     | 
| 
       313 
     | 
    
         
            -
                  pin.parameters[first..-1].each_with_index do |par, cur|
         
     | 
| 
      
 323 
     | 
    
         
            +
                  pin.signatures.first.parameters[first..-1].each_with_index do |par, cur|
         
     | 
| 
       314 
324 
     | 
    
         
             
                    idx = first + cur
         
     | 
| 
       315 
325 
     | 
    
         
             
                    argchain = kwargs[par.name.to_sym]
         
     | 
| 
       316 
326 
     | 
    
         
             
                    if par.decl == :kwrestarg || (par.decl == :optarg && idx == pin.parameters.length - 1 && par.asgn_code == '{}')
         
     | 
| 
         @@ -381,8 +391,10 @@ module Solargraph 
     | 
|
| 
       381 
391 
     | 
    
         
             
                  pin.location && api_map.bundled?(pin.location.filename)
         
     | 
| 
       382 
392 
     | 
    
         
             
                end
         
     | 
| 
       383 
393 
     | 
    
         | 
| 
      
 394 
     | 
    
         
            +
                # True if the pin is either internal (part of the workspace) or from the core/stdlib
         
     | 
| 
       384 
395 
     | 
    
         
             
                def internal_or_core? pin
         
     | 
| 
       385 
     | 
    
         
            -
                   
     | 
| 
      
 396 
     | 
    
         
            +
                  # @todo RBS pins are not necessarily core/stdlib pins
         
     | 
| 
      
 397 
     | 
    
         
            +
                  internal?(pin) || pin.source == :rbs
         
     | 
| 
       386 
398 
     | 
    
         
             
                end
         
     | 
| 
       387 
399 
     | 
    
         | 
| 
       388 
400 
     | 
    
         
             
                # @param pin [Pin::Base]
         
     | 
| 
         @@ -417,20 +429,20 @@ module Solargraph 
     | 
|
| 
       417 
429 
     | 
    
         
             
                  true
         
     | 
| 
       418 
430 
     | 
    
         
             
                end
         
     | 
| 
       419 
431 
     | 
    
         | 
| 
       420 
     | 
    
         
            -
                 
     | 
| 
       421 
     | 
    
         
            -
             
     | 
| 
       422 
     | 
    
         
            -
             
     | 
| 
       423 
     | 
    
         
            -
                     
     | 
| 
       424 
     | 
    
         
            -
                     
     | 
| 
       425 
     | 
    
         
            -
             
     | 
| 
       426 
     | 
    
         
            -
                   
     | 
| 
      
 432 
     | 
    
         
            +
                def arity_problems_for pin, arguments, location
         
     | 
| 
      
 433 
     | 
    
         
            +
                  results = pin.signatures.map do |sig|
         
     | 
| 
      
 434 
     | 
    
         
            +
                    r = parameterized_arity_problems_for(pin, sig.parameters, arguments, location)
         
     | 
| 
      
 435 
     | 
    
         
            +
                    return [] if r.empty?
         
     | 
| 
      
 436 
     | 
    
         
            +
                    r
         
     | 
| 
      
 437 
     | 
    
         
            +
                  end
         
     | 
| 
      
 438 
     | 
    
         
            +
                  results.first
         
     | 
| 
       427 
439 
     | 
    
         
             
                end
         
     | 
| 
       428 
440 
     | 
    
         | 
| 
       429 
     | 
    
         
            -
                 
     | 
| 
       430 
     | 
    
         
            -
                def pin_arity_problems_for(pin, arguments, location)
         
     | 
| 
      
 441 
     | 
    
         
            +
                def parameterized_arity_problems_for(pin, parameters, arguments, location)
         
     | 
| 
       431 
442 
     | 
    
         
             
                  return [] unless pin.explicit?
         
     | 
| 
       432 
     | 
    
         
            -
                  return [] if  
     | 
| 
       433 
     | 
    
         
            -
                  if pin. 
     | 
| 
      
 443 
     | 
    
         
            +
                  return [] if parameters.empty? && arguments.empty?
         
     | 
| 
      
 444 
     | 
    
         
            +
                  return [] if pin.anon_splat?
         
     | 
| 
      
 445 
     | 
    
         
            +
                  if parameters.empty?
         
     | 
| 
       434 
446 
     | 
    
         
             
                    # Functions tagged param_tuple accepts two arguments (e.g., Hash#[]=)
         
     | 
| 
       435 
447 
     | 
    
         
             
                    return [] if pin.docstring.tag(:param_tuple) && arguments.length == 2
         
     | 
| 
       436 
448 
     | 
    
         
             
                    return [] if arguments.length == 1 && arguments.last.links.last.is_a?(Source::Chain::BlockVariable)
         
     | 
| 
         @@ -438,21 +450,21 @@ module Solargraph 
     | 
|
| 
       438 
450 
     | 
    
         
             
                  end
         
     | 
| 
       439 
451 
     | 
    
         
             
                  unchecked = arguments.clone
         
     | 
| 
       440 
452 
     | 
    
         
             
                  add_params = 0
         
     | 
| 
       441 
     | 
    
         
            -
                  if unchecked.empty? &&  
     | 
| 
      
 453 
     | 
    
         
            +
                  if unchecked.empty? && parameters.any? { |param| param.decl == :kwarg }
         
     | 
| 
       442 
454 
     | 
    
         
             
                    return [Problem.new(location, "Missing keyword arguments to #{pin.path}")]
         
     | 
| 
       443 
455 
     | 
    
         
             
                  end
         
     | 
| 
       444 
456 
     | 
    
         
             
                  settled_kwargs = 0
         
     | 
| 
       445 
457 
     | 
    
         
             
                  unless unchecked.empty?
         
     | 
| 
       446 
458 
     | 
    
         
             
                    if any_splatted_call?(unchecked.map(&:node))
         
     | 
| 
       447 
     | 
    
         
            -
                      settled_kwargs =  
     | 
| 
      
 459 
     | 
    
         
            +
                      settled_kwargs = parameters.count(&:keyword?)
         
     | 
| 
       448 
460 
     | 
    
         
             
                    else
         
     | 
| 
       449 
461 
     | 
    
         
             
                      kwargs = convert_hash(unchecked.last.node)
         
     | 
| 
       450 
     | 
    
         
            -
                      if  
     | 
| 
      
 462 
     | 
    
         
            +
                      if parameters.any? { |param| [:kwarg, :kwoptarg].include?(param.decl) || param.kwrestarg? }
         
     | 
| 
       451 
463 
     | 
    
         
             
                        if kwargs.empty?
         
     | 
| 
       452 
464 
     | 
    
         
             
                          add_params += 1
         
     | 
| 
       453 
465 
     | 
    
         
             
                        else
         
     | 
| 
       454 
466 
     | 
    
         
             
                          unchecked.pop
         
     | 
| 
       455 
     | 
    
         
            -
                           
     | 
| 
      
 467 
     | 
    
         
            +
                          parameters.each do |param|
         
     | 
| 
       456 
468 
     | 
    
         
             
                            next unless param.keyword?
         
     | 
| 
       457 
469 
     | 
    
         
             
                            if kwargs.key?(param.name.to_sym)
         
     | 
| 
       458 
470 
     | 
    
         
             
                              kwargs.delete param.name.to_sym
         
     | 
| 
         @@ -462,7 +474,7 @@ module Solargraph 
     | 
|
| 
       462 
474 
     | 
    
         
             
                              return [Problem.new(location, "Missing keyword argument #{param.name} to #{pin.path}")]
         
     | 
| 
       463 
475 
     | 
    
         
             
                            end
         
     | 
| 
       464 
476 
     | 
    
         
             
                          end
         
     | 
| 
       465 
     | 
    
         
            -
                          kwargs.clear if  
     | 
| 
      
 477 
     | 
    
         
            +
                          kwargs.clear if parameters.any?(&:kwrestarg?)
         
     | 
| 
       466 
478 
     | 
    
         
             
                          unless kwargs.empty?
         
     | 
| 
       467 
479 
     | 
    
         
             
                            return [Problem.new(location, "Unrecognized keyword argument #{kwargs.keys.first} to #{pin.path}")]
         
     | 
| 
       468 
480 
     | 
    
         
             
                          end
         
     | 
| 
         @@ -470,18 +482,18 @@ module Solargraph 
     | 
|
| 
       470 
482 
     | 
    
         
             
                      end
         
     | 
| 
       471 
483 
     | 
    
         
             
                    end
         
     | 
| 
       472 
484 
     | 
    
         
             
                  end
         
     | 
| 
       473 
     | 
    
         
            -
                  req = required_param_count( 
     | 
| 
      
 485 
     | 
    
         
            +
                  req = required_param_count(parameters)
         
     | 
| 
       474 
486 
     | 
    
         
             
                  if req + add_params < unchecked.length
         
     | 
| 
       475 
     | 
    
         
            -
                    return [] if  
     | 
| 
       476 
     | 
    
         
            -
                    opt = optional_param_count( 
     | 
| 
      
 487 
     | 
    
         
            +
                    return [] if parameters.any?(&:rest?)
         
     | 
| 
      
 488 
     | 
    
         
            +
                    opt = optional_param_count(parameters)
         
     | 
| 
       477 
489 
     | 
    
         
             
                    return [] if unchecked.length <= req + opt
         
     | 
| 
       478 
490 
     | 
    
         
             
                    if unchecked.length == req + opt + 1 && unchecked.last.links.last.is_a?(Source::Chain::BlockVariable)
         
     | 
| 
       479 
491 
     | 
    
         
             
                      return []
         
     | 
| 
       480 
492 
     | 
    
         
             
                    end
         
     | 
| 
       481 
     | 
    
         
            -
                    if req + add_params + 1 == unchecked.length && any_splatted_call?(unchecked.map(&:node)) && ( 
     | 
| 
      
 493 
     | 
    
         
            +
                    if req + add_params + 1 == unchecked.length && any_splatted_call?(unchecked.map(&:node)) && (parameters.map(&:decl) & [:kwarg, :kwoptarg, :kwrestarg]).any?
         
     | 
| 
       482 
494 
     | 
    
         
             
                      return []
         
     | 
| 
       483 
495 
     | 
    
         
             
                    end
         
     | 
| 
       484 
     | 
    
         
            -
                    return [] if arguments.length - req ==  
     | 
| 
      
 496 
     | 
    
         
            +
                    return [] if arguments.length - req == parameters.select { |p| [:optarg, :kwoptarg].include?(p.decl) }.length
         
     | 
| 
       485 
497 
     | 
    
         
             
                    return [Problem.new(location, "Too many arguments to #{pin.path}")]
         
     | 
| 
       486 
498 
     | 
    
         
             
                  elsif unchecked.length < req - settled_kwargs && (arguments.empty? || (!arguments.last.splat? && !arguments.last.links.last.is_a?(Solargraph::Source::Chain::Hash)))
         
     | 
| 
       487 
499 
     | 
    
         
             
                    # HACK: Kernel#raise signature is incorrect in Ruby 2.7 core docs.
         
     | 
| 
         @@ -493,19 +505,13 @@ module Solargraph 
     | 
|
| 
       493 
505 
     | 
    
         
             
                  []
         
     | 
| 
       494 
506 
     | 
    
         
             
                end
         
     | 
| 
       495 
507 
     | 
    
         | 
| 
       496 
     | 
    
         
            -
                 
     | 
| 
       497 
     | 
    
         
            -
             
     | 
| 
       498 
     | 
    
         
            -
                  pin.parameters.sum { |param| %i[arg kwarg].include?(param.decl) ? 1 : 0 }
         
     | 
| 
      
 508 
     | 
    
         
            +
                def required_param_count(parameters)
         
     | 
| 
      
 509 
     | 
    
         
            +
                  parameters.sum { |param| %i[arg kwarg].include?(param.decl) ? 1 : 0 }
         
     | 
| 
       499 
510 
     | 
    
         
             
                end
         
     | 
| 
       500 
511 
     | 
    
         | 
| 
       501 
512 
     | 
    
         
             
                # @param pin [Pin::Method]
         
     | 
| 
       502 
     | 
    
         
            -
                def optional_param_count( 
     | 
| 
       503 
     | 
    
         
            -
                   
     | 
| 
       504 
     | 
    
         
            -
                  pin.parameters.each do |param|
         
     | 
| 
       505 
     | 
    
         
            -
                    next unless param.decl == :optarg
         
     | 
| 
       506 
     | 
    
         
            -
                    count += 1
         
     | 
| 
       507 
     | 
    
         
            -
                  end
         
     | 
| 
       508 
     | 
    
         
            -
                  count
         
     | 
| 
      
 513 
     | 
    
         
            +
                def optional_param_count(parameters)
         
     | 
| 
      
 514 
     | 
    
         
            +
                  parameters.select { |p| p.decl == :optarg }.length
         
     | 
| 
       509 
515 
     | 
    
         
             
                end
         
     | 
| 
       510 
516 
     | 
    
         | 
| 
       511 
517 
     | 
    
         
             
                def abstract? pin
         
     | 
    
        data/lib/solargraph/version.rb
    CHANGED
    
    
| 
         @@ -30,10 +30,10 @@ 
     | 
|
| 
       30 
30 
     | 
    
         
             
                  Solargraph Version: <%= Solargraph::VERSION %>
         
     | 
| 
       31 
31 
     | 
    
         
             
                </li>
         
     | 
| 
       32 
32 
     | 
    
         
             
                <li>
         
     | 
| 
       33 
     | 
    
         
            -
                  Core Documentation Version:  
     | 
| 
      
 33 
     | 
    
         
            +
                  Core Documentation Version: N/A <%# @todo Fix %>
         
     | 
| 
       34 
34 
     | 
    
         
             
                </li>
         
     | 
| 
       35 
35 
     | 
    
         
             
                <li>
         
     | 
| 
       36 
     | 
    
         
            -
                  Core Cache Directory:  
     | 
| 
      
 36 
     | 
    
         
            +
                  Core Cache Directory: N/A <%# @todo Fix %>
         
     | 
| 
       37 
37 
     | 
    
         
             
                </li>
         
     | 
| 
       38 
38 
     | 
    
         
             
                <% unless Solargraph::Parser.rubyvm? %>
         
     | 
| 
       39 
39 
     | 
    
         
             
                  <li>
         
     |