solargraph 0.39.12 → 0.39.17

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 94e2150b6575ab34c7a13a51616cdbce7e21e13bff1b6cc2e6f4307960501acb
4
- data.tar.gz: 474e22c2f716481a1410a8ba5199ce94b9d912573a29e077c29cea075fb8fd3d
3
+ metadata.gz: 1848998bad3115b797b00dc04fb88b25da2f4db11faf957ca939d5701d8adcc4
4
+ data.tar.gz: 07e255512496a029a4e7b58b04e080404a73ebd53a588a30a0028ab0a0c0b98e
5
5
  SHA512:
6
- metadata.gz: ded8a57414921d2fc45616d9f8d10c8c6581d1769657968bd3b40e3b59d199f4090e9e086319cbea26dd9f4cab0d7231ebfd2b58b7f8f15524de745fc351ea88
7
- data.tar.gz: f6fabb492847eb4091b0d642d9b41a28abb1b39e983f338828b17baf3a79aad1006244ef2dafbbd51757e11e4ac91eb721431151afe0e61ee11dc792e3d045f5
6
+ metadata.gz: 1b98d066a55f938ccc7634ddd89a9fcb93c3748ebc01ad80bcf0b6f9ff8c125784cf5e799300ed1fadb8b3909efa4063ce8584f375d58a9e1934665554bd3a60
7
+ data.tar.gz: 42f01bf895f7649f24b9d0573af731f629b8a0428a4c91cc4641877c539b54ce3c9077a337148bd2fc0b8df22ace77447bab5bebacb33577418be9f4b48378b5
data/Rakefile CHANGED
@@ -11,4 +11,15 @@ end
11
11
  desc "Open a Pry session preloaded with this library"
12
12
  task :console do
13
13
  sh "pry -I lib -r solargraph.rb"
14
- end
14
+ end
15
+
16
+ desc "Run the type checker"
17
+ task :typecheck do
18
+ sh "bundle exec solargraph typecheck --level typed"
19
+ end
20
+
21
+ desc "Run all tests"
22
+ task :test do
23
+ Rake::Task["typecheck"].invoke
24
+ Rake::Task["spec"].invoke
25
+ end
@@ -4,6 +4,10 @@ Solargraph is developed and maintained by [Castwide Technologies](https://castwi
4
4
 
5
5
  The following people and organizations provide funding or other resources. [Become a sponsor](https://patreon.com/castwide)
6
6
 
7
+ ## Linked Sponsors
8
+
9
+ - **[Calyptix Security](https://www.calyptix.com/)**
10
+
7
11
  ## Named Sponsors
8
12
 
9
13
  - Emily Strickland
@@ -386,9 +386,7 @@ module Solargraph
386
386
  # @return [Array<Solargraph::Pin::Base>]
387
387
  def get_path_suggestions path
388
388
  return [] if path.nil?
389
- result = []
390
- result.concat store.get_path_pins(path)
391
- resolve_method_aliases(result)
389
+ resolve_method_aliases store.get_path_pins(path)
392
390
  end
393
391
 
394
392
  # Get an array of pins that match the specified path.
@@ -423,7 +421,7 @@ module Solargraph
423
421
  # api_map.document('String#split')
424
422
  #
425
423
  # @param path [String] The path to find
426
- # @return [Array<YARD::CodeObject::Base>]
424
+ # @return [Array<YARD::CodeObjects::Base>]
427
425
  def document path
428
426
  rake_yard(store)
429
427
  docs = []
@@ -447,7 +445,7 @@ module Solargraph
447
445
  # @return [Array<Solargraph::Pin::Base>]
448
446
  def locate_pins location
449
447
  return [] if location.nil? || !source_map_hash.has_key?(location.filename)
450
- source_map_hash[location.filename].locate_pins(location)
448
+ resolve_method_aliases source_map_hash[location.filename].locate_pins(location)
451
449
  end
452
450
 
453
451
  # @raise [FileNotFoundError] if the cursor's file is not in the ApiMap
@@ -464,7 +462,7 @@ module Solargraph
464
462
  # @return [Array<Pin::Symbol>]
465
463
  def document_symbols filename
466
464
  return [] unless source_map_hash.has_key?(filename) # @todo Raise error?
467
- source_map_hash[filename].document_symbols
465
+ resolve_method_aliases source_map_hash[filename].document_symbols
468
466
  end
469
467
 
470
468
  # @return [Array<SourceMap>]
@@ -659,6 +657,7 @@ module Solargraph
659
657
  return nil if name.nil?
660
658
  return nil if skip.include?(root)
661
659
  skip.add root
660
+ possibles = []
662
661
  if name == ''
663
662
  if root == ''
664
663
  return ''
@@ -674,16 +673,19 @@ module Solargraph
674
673
  incs = store.get_includes(roots.join('::'))
675
674
  incs.each do |inc|
676
675
  foundinc = inner_qualify(name, inc, skip)
677
- return foundinc unless foundinc.nil?
676
+ possibles.push foundinc unless foundinc.nil?
678
677
  end
679
678
  roots.pop
680
679
  end
681
- incs = store.get_includes('')
682
- incs.each do |inc|
683
- foundinc = inner_qualify(name, inc, skip)
684
- return foundinc unless foundinc.nil?
680
+ if possibles.empty?
681
+ incs = store.get_includes('')
682
+ incs.each do |inc|
683
+ foundinc = inner_qualify(name, inc, skip)
684
+ possibles.push foundinc unless foundinc.nil?
685
+ end
685
686
  end
686
687
  return name if store.namespace_exists?(name)
688
+ return possibles.last
687
689
  end
688
690
  end
689
691
 
@@ -723,7 +725,7 @@ module Solargraph
723
725
  result = []
724
726
  pins.each do |pin|
725
727
  resolved = resolve_method_alias(pin)
726
- next unless visibility.include?(resolved.visibility)
728
+ next if resolved.respond_to?(:visibility) && !visibility.include?(resolved.visibility)
727
729
  result.push resolved
728
730
  end
729
731
  result
@@ -737,15 +739,17 @@ module Solargraph
737
739
  origin = get_method_stack(pin.full_context.namespace, pin.original, scope: pin.scope).first
738
740
  @method_alias_stack.pop
739
741
  return pin if origin.nil?
740
- Pin::Method.new(
742
+ args = {
741
743
  location: pin.location,
742
744
  closure: pin.closure,
743
745
  name: pin.name,
744
746
  comments: origin.comments,
745
747
  scope: origin.scope,
746
- visibility: origin.visibility,
747
- parameters: origin.parameters
748
- )
748
+ visibility: origin.visibility
749
+ }
750
+ args[:parameters] = origin.parameters unless origin.is_a?(Pin::Attribute)
751
+ klass = origin.is_a?(Pin::Attribute) ? Pin::Attribute : Pin::Method
752
+ klass.new **args
749
753
  end
750
754
  end
751
755
  end
@@ -218,7 +218,7 @@ module Solargraph
218
218
  @pin_select_cache = {}
219
219
  @namespace_map = set.classify(&:namespace).transform_values(&:to_a)
220
220
  @path_pin_hash = set.classify(&:path).transform_values(&:to_a)
221
- @namespaces = @path_pin_hash.keys.compact
221
+ @namespaces = @path_pin_hash.keys.compact.to_set
222
222
  pins_by_class(Pin::Reference::Include).each do |pin|
223
223
  include_references[pin.namespace] ||= []
224
224
  include_references[pin.namespace].push pin.name
@@ -12,7 +12,7 @@ module Solargraph
12
12
 
13
13
  # @param types [Array<UniqueType>]
14
14
  def initialize types = [UniqueType::UNDEFINED]
15
- @items = types
15
+ @items = types.uniq(&:to_s)
16
16
  end
17
17
 
18
18
  # @param api_map [ApiMap]
@@ -113,7 +113,7 @@ module Solargraph
113
113
  #
114
114
  # @param *strings [Array<String>] The type definitions to parse
115
115
  # @param partial [Boolean] True if the string is part of a another type
116
- # @return [ComplexType]
116
+ # @return [ComplexType, Array, nil]
117
117
  def parse *strings, partial: false
118
118
  @cache ||= {}
119
119
  unless partial
@@ -15,7 +15,7 @@ module Solargraph
15
15
  @@conventions = Set.new
16
16
 
17
17
  # @param convention [Class<Convention::Base>]
18
- # @return [Convention::Base]
18
+ # @return [void]
19
19
  def self.register convention
20
20
  @@conventions.add convention.new
21
21
  end
@@ -53,6 +53,7 @@ module Solargraph
53
53
  @return_single_parameter
54
54
  @return_single_parameter
55
55
  )),
56
+ Override.method_return('Array#concat', 'Array'),
56
57
  Override.from_comment('Array#first', %(
57
58
  @overload first(num)
58
59
  @param num [Integer]
@@ -65,7 +66,9 @@ module Solargraph
65
66
  @return [self]
66
67
  @return_single_parameter
67
68
  )),
69
+ Override.method_return('Array#map', 'Array'),
68
70
  Override.method_return('Array#uniq', 'self'),
71
+ Override.method_return('Array#zip', 'Array, nil'),
69
72
 
70
73
  Override.from_comment('BasicObject#==', %(
71
74
  @param other [BasicObject]
@@ -101,6 +104,8 @@ module Solargraph
101
104
  @param_tuple
102
105
  )),
103
106
 
107
+ Override.method_return('Hash#merge', 'Hash'),
108
+
104
109
  Override.from_comment('Integer#+', %(
105
110
  @param y [Numeric]
106
111
  @return [Numeric]
@@ -108,10 +113,6 @@ module Solargraph
108
113
 
109
114
  Override.method_return('Kernel#puts', 'nil'),
110
115
 
111
- # Override.method_return('Module#attr_reader', 'void'),
112
- # Override.method_return('Module#attr_writer', 'void'),
113
- # Override.method_return('Module#attr_accessor', 'void'),
114
-
115
116
  Override.from_comment('Numeric#+', %(
116
117
  @param y [Numeric]
117
118
  @return [Numeric]
@@ -147,6 +148,10 @@ module Solargraph
147
148
  Override.method_return('String#lines', 'Array<String>'),
148
149
  Override.from_comment('String#each_line', %(
149
150
  @yieldparam [String]
151
+ )),
152
+ Override.from_comment('String.new', %(
153
+ @overload new(*)
154
+ @return [self]
150
155
  ))
151
156
  ].concat(
152
157
  methods_with_yieldparam_subtypes.map do |path|
@@ -55,6 +55,8 @@ module Solargraph
55
55
  false
56
56
  end
57
57
 
58
+ # @param directory [String]
59
+ # @return [Hash]
58
60
  def self.specs_from_bundle directory
59
61
  Solargraph.with_clean_env do
60
62
  Dir.chdir directory do
@@ -174,10 +174,10 @@ module Solargraph
174
174
  if cursor.comment?
175
175
  source = read(filename)
176
176
  offset = Solargraph::Position.to_offset(source.code, Solargraph::Position.new(line, column))
177
- lft = source.code[0..offset-1].match(/\[([a-z0-9_:]*)\z/i)
178
- rgt = source.code[offset..-1].match(/^([a-z0-9_]*)(:[a-z0-9_:]*)?\]/i)
177
+ lft = source.code[0..offset-1].match(/\[[a-z0-9_:<, ]*?([a-z0-9_:]*)\z/i)
178
+ rgt = source.code[offset..-1].match(/^([a-z0-9_]*)(:[a-z0-9_:]*)?[\]>, ]/i)
179
179
  if lft && rgt
180
- tag = lft[1] + rgt[1]
180
+ tag = (lft[1] + rgt[1]).sub(/:+$/, '')
181
181
  clip = api_map.clip(cursor)
182
182
  clip.translate tag
183
183
  else
@@ -259,7 +259,7 @@ module Solargraph
259
259
  end
260
260
 
261
261
  # @param query [String]
262
- # @return [Array<YARD::CodeObject::Base>]
262
+ # @return [Array<YARD::CodeObjects::Base>]
263
263
  def document query
264
264
  catalog
265
265
  api_map.document query
@@ -14,7 +14,7 @@ module Solargraph
14
14
  def initialize node, filename = nil, in_block = false
15
15
  @node = node
16
16
  @filename = filename
17
- @in_block = in_block
17
+ @in_block = in_block ? 1 : 0
18
18
  end
19
19
 
20
20
  # @return [Source::Chain]
@@ -51,9 +51,9 @@ module Solargraph
51
51
  return generate_links(n.children[0]) if n.type == :splat
52
52
  result = []
53
53
  if n.type == :block
54
- @in_block = true
54
+ @in_block += 1
55
55
  result.concat generate_links(n.children[0])
56
- @in_block = false
56
+ @in_block -= 1
57
57
  elsif n.type == :send
58
58
  if n.children[0].is_a?(::Parser::AST::Node)
59
59
  result.concat generate_links(n.children[0])
@@ -61,23 +61,23 @@ module Solargraph
61
61
  n.children[2..-1].each do |c|
62
62
  args.push NodeChainer.chain(c)
63
63
  end
64
- result.push Chain::Call.new(n.children[1].to_s, args, @in_block || block_passed?(n))
64
+ result.push Chain::Call.new(n.children[1].to_s, args, @in_block > 0 || block_passed?(n))
65
65
  elsif n.children[0].nil?
66
66
  args = []
67
67
  n.children[2..-1].each do |c|
68
68
  args.push NodeChainer.chain(c)
69
69
  end
70
- result.push Chain::Call.new(n.children[1].to_s, args, @in_block || block_passed?(n))
70
+ result.push Chain::Call.new(n.children[1].to_s, args, @in_block > 0 || block_passed?(n))
71
71
  else
72
72
  raise "No idea what to do with #{n}"
73
73
  end
74
74
  elsif n.type == :self
75
75
  result.push Chain::Head.new('self')
76
76
  elsif n.type == :zsuper
77
- result.push Chain::ZSuper.new('super', @in_block || block_passed?(n))
77
+ result.push Chain::ZSuper.new('super', @in_block > 0 || block_passed?(n))
78
78
  elsif n.type == :super
79
79
  args = n.children.map { |c| NodeChainer.chain(c) }
80
- result.push Chain::Call.new('super', args, @in_block || block_passed?(n))
80
+ result.push Chain::Call.new('super', args, @in_block > 0 || block_passed?(n))
81
81
  elsif n.type == :const
82
82
  const = unpack_name(n)
83
83
  result.push Chain::Constant.new(const)
@@ -90,7 +90,8 @@ module Solargraph
90
90
  if node.children[2].is_a?(AST::Node) && node.children[2].type == :const
91
91
  cp = region.closure
92
92
  node.children[2..-1].each do |i|
93
- pins.push Pin::Reference::Include.new(
93
+ type = region.scope == :class ? Pin::Reference::Extend : Pin::Reference::Include
94
+ pins.push type.new(
94
95
  location: get_node_location(i),
95
96
  closure: cp,
96
97
  name: unpack_name(i)
@@ -15,7 +15,7 @@ module Solargraph
15
15
  def initialize node, filename = nil, in_block = false
16
16
  @node = node
17
17
  @filename = filename
18
- @in_block = in_block
18
+ @in_block = in_block ? 1 : 0
19
19
  end
20
20
 
21
21
  # @return [Source::Chain]
@@ -52,27 +52,27 @@ module Solargraph
52
52
  return generate_links(n.children[0]) if n.type == :SPLAT
53
53
  result = []
54
54
  if n.type == :ITER
55
- @in_block = true
55
+ @in_block += 1
56
56
  result.concat generate_links(n.children[0])
57
- @in_block = false
57
+ @in_block -= 1
58
58
  elsif n.type == :CALL || n.type == :OPCALL
59
59
  n.children[0..-3].each do |c|
60
60
  result.concat generate_links(c)
61
61
  end
62
- result.push Chain::Call.new(n.children[-2].to_s, node_to_argchains(n.children.last), @in_block || block_passed?(n))
62
+ result.push Chain::Call.new(n.children[-2].to_s, node_to_argchains(n.children.last), @in_block > 0 || block_passed?(n))
63
63
  elsif n.type == :ATTRASGN
64
64
  result.concat generate_links(n.children[0])
65
- result.push Chain::Call.new(n.children[1].to_s, node_to_argchains(n.children[2]), @in_block || block_passed?(n))
65
+ result.push Chain::Call.new(n.children[1].to_s, node_to_argchains(n.children[2]), @in_block > 0 || block_passed?(n))
66
66
  elsif n.type == :VCALL
67
- result.push Chain::Call.new(n.children[0].to_s, [], @in_block || block_passed?(n))
67
+ result.push Chain::Call.new(n.children[0].to_s, [], @in_block > 0 || block_passed?(n))
68
68
  elsif n.type == :FCALL
69
- result.push Chain::Call.new(n.children[0].to_s, node_to_argchains(n.children[1]), @in_block || block_passed?(n))
69
+ result.push Chain::Call.new(n.children[0].to_s, node_to_argchains(n.children[1]), @in_block > 0 || block_passed?(n))
70
70
  elsif n.type == :SELF
71
71
  result.push Chain::Head.new('self')
72
72
  elsif n.type == :ZSUPER
73
- result.push Chain::ZSuper.new('super', @in_block || block_passed?(n))
73
+ result.push Chain::ZSuper.new('super', @in_block > 0 || block_passed?(n))
74
74
  elsif n.type == :SUPER
75
- result.push Chain::Call.new('super', node_to_argchains(n.children.last), @in_block || block_passed?(n))
75
+ result.push Chain::Call.new('super', node_to_argchains(n.children.last), @in_block > 0 || block_passed?(n))
76
76
  elsif [:COLON2, :COLON3, :CONST].include?(n.type)
77
77
  const = unpack_name(n)
78
78
  result.push Chain::Constant.new(const)
@@ -197,7 +197,7 @@ module Solargraph
197
197
  result.push node
198
198
  result.concat get_return_nodes_only(node.children[1])
199
199
  elsif node.type == :CASE
200
- node.children.each do |cc|
200
+ node.children[1..-1].each do |cc|
201
201
  result.concat reduce_to_value_nodes(cc.children[1..-1])
202
202
  end
203
203
  else
@@ -54,6 +54,7 @@ module Solargraph
54
54
  register :KW_ARG, Rubyvm::NodeProcessors::KwArgNode
55
55
  register :ITER, Rubyvm::NodeProcessors::BlockNode
56
56
  register :LAMBDA, Rubyvm::NodeProcessors::BlockNode
57
+ register :FOR, Rubyvm::NodeProcessors::BlockNode
57
58
  register :OP_ASGN_OR, Rubyvm::NodeProcessors::OrasgnNode
58
59
  register :LIT, Rubyvm::NodeProcessors::LitNode
59
60
  end
@@ -7,16 +7,30 @@ module Solargraph
7
7
  class ArgsNode < Parser::NodeProcessor::Base
8
8
  def process
9
9
  if region.closure.is_a?(Pin::BaseMethod) || region.closure.is_a?(Pin::Block)
10
- node.children[0].times do |i|
11
- locals.push Solargraph::Pin::Parameter.new(
12
- location: region.closure.location,
13
- closure: region.closure,
14
- comments: comments_for(node),
15
- name: region.lvars[i].to_s,
16
- presence: region.closure.location.range,
17
- decl: :arg
18
- )
19
- region.closure.parameters.push locals.last
10
+ if region.lvars[0].nil?
11
+ node.children[0].times do |i|
12
+ locals.push Solargraph::Pin::Parameter.new(
13
+ location: region.closure.location,
14
+ closure: region.closure,
15
+ comments: comments_for(node),
16
+ name: extract_name(node.children[i + 1]),
17
+ presence: region.closure.location.range,
18
+ decl: :arg
19
+ )
20
+ region.closure.parameters.push locals.last
21
+ end
22
+ else
23
+ node.children[0].times do |i|
24
+ locals.push Solargraph::Pin::Parameter.new(
25
+ location: region.closure.location,
26
+ closure: region.closure,
27
+ comments: comments_for(node),
28
+ name: region.lvars[i].to_s,
29
+ presence: region.closure.location.range,
30
+ decl: :arg
31
+ )
32
+ region.closure.parameters.push locals.last
33
+ end
20
34
  end
21
35
  # @todo Optional args, keyword args, etc.
22
36
  if node.children[6]
@@ -55,6 +69,16 @@ module Solargraph
55
69
  end
56
70
  process_children
57
71
  end
72
+
73
+ private
74
+
75
+ def extract_name var
76
+ if Parser.is_ast_node?(var)
77
+ var.children[0].to_s
78
+ else
79
+ var.to_s
80
+ end
81
+ end
58
82
  end
59
83
  end
60
84
  end
@@ -91,7 +91,8 @@ module Solargraph
91
91
  return unless Parser.is_ast_node?(node.children.last)
92
92
  node.children.last.children[0..-2].each do |i|
93
93
  next unless [:COLON2, :COLON3, :CONST].include?(i.type)
94
- pins.push Pin::Reference::Include.new(
94
+ type = region.scope == :class ? Pin::Reference::Extend : Pin::Reference::Include
95
+ pins.push type.new(
95
96
  location: get_node_location(i),
96
97
  closure: region.closure,
97
98
  name: unpack_name(i)
@@ -84,6 +84,14 @@ module Solargraph
84
84
  @explicit
85
85
  end
86
86
 
87
+ def completion_item_kind
88
+ Solargraph::LanguageServer::CompletionItemKinds::METHOD
89
+ end
90
+
91
+ def symbol_kind
92
+ Solargraph::LanguageServer::SymbolKinds::METHOD
93
+ end
94
+
87
95
  private
88
96
 
89
97
  # @return [ComplexType]
@@ -23,16 +23,15 @@ module Solargraph
23
23
 
24
24
  # @return [Hash]
25
25
  def resolve_completion_item
26
- if @resolve_completion_item.nil?
26
+ @resolve_completion_item ||= begin
27
27
  extra = {}
28
28
  alldoc = ''
29
29
  # alldoc += link_documentation unless link_documentation.nil?
30
30
  # alldoc += "\n\n" unless alldoc.empty?
31
31
  alldoc += documentation unless documentation.nil?
32
32
  extra[:documentation] = alldoc unless alldoc.empty?
33
- @resolve_completion_item = completion_item.merge(extra)
33
+ completion_item.merge(extra)
34
34
  end
35
- @resolve_completion_item
36
35
  end
37
36
 
38
37
  # @return [Hash]
@@ -6,6 +6,12 @@ module Solargraph
6
6
  class Method < Pin::Method
7
7
  include YardMixin
8
8
 
9
+ # @param code_object [YARD::CodeObjects::Base]
10
+ # @param name [String, nil]
11
+ # @param scope [Symbol, nil]
12
+ # @param visibility [Symbol, nil]
13
+ # @param closure [Solargraph::Pin::Closure, nil]
14
+ # @param spec [Gem::Specification]
9
15
  def initialize code_object, name = nil, scope = nil, visibility = nil, closure = nil, spec = nil
10
16
  closure ||= Solargraph::Pin::Namespace.new(
11
17
  name: code_object.namespace.to_s,
@@ -25,9 +31,14 @@ module Solargraph
25
31
 
26
32
  private
27
33
 
34
+ # @param code_object [YARD::CodeObjects::Base]
35
+ # @return [Array<Solargraph::Pin::Parameter>]
28
36
  def get_parameters code_object
29
37
  return [] unless code_object.is_a?(YARD::CodeObjects::MethodObject)
30
- code_object.parameters.map do |a|
38
+ # HACK: Skip `nil` and `self` parameters that are sometimes emitted
39
+ # for methods defined in C
40
+ # See https://github.com/castwide/solargraph/issues/345
41
+ code_object.parameters.select { |a| a[0] && a[0] != 'self' }.map do |a|
31
42
  Solargraph::Pin::Parameter.new(
32
43
  location: location,
33
44
  closure: self,
@@ -40,10 +51,14 @@ module Solargraph
40
51
  end
41
52
  end
42
53
 
54
+ # @param a [Array]
55
+ # @return [String]
43
56
  def arg_name a
44
- a[0].match(/[A-Za-z0-9_]*/)[0]
57
+ a[0].gsub(/[^a-z0-9_]/i, '')
45
58
  end
46
59
 
60
+ # @param a [Array]
61
+ # @return [::Symbol]
47
62
  def arg_type a
48
63
  if a[0].start_with?('**')
49
64
  :kwrestarg
@@ -51,10 +66,10 @@ module Solargraph
51
66
  :restarg
52
67
  elsif a[0].start_with?('&')
53
68
  :blockarg
69
+ elsif a[0].end_with?(':')
70
+ a[1] ? :kwoptarg : :kwarg
54
71
  elsif a[1]
55
72
  :optarg
56
- elsif a[0].end_with?(':')
57
- a[1] ? :kwarg : :kwoptarg
58
73
  else
59
74
  :arg
60
75
  end
@@ -4,16 +4,10 @@ module Solargraph
4
4
  module Pin
5
5
  module YardPin
6
6
  module YardMixin
7
- attr_reader :code_object
8
-
9
- attr_reader :spec
10
-
11
- attr_reader :location
12
-
13
- @@gate_cache ||= {}
14
-
15
7
  private
16
8
 
9
+ # @param code_object [YARD::CodeObjects::Base]
10
+ # @param spec [Gem::Specification]
17
11
  # @return [Solargraph::Location, nil]
18
12
  def object_location code_object, spec
19
13
  return nil if spec.nil? || code_object.nil? || code_object.file.nil? || code_object.line.nil?
@@ -153,6 +153,7 @@ module Solargraph
153
153
  probcount += problems.length
154
154
  end
155
155
  puts "#{probcount} problem#{probcount != 1 ? 's' : ''} found#{files.length != 1 ? " in #{filecount} of #{files.length} files" : ''}."
156
+ exit 1 if probcount > 0
156
157
  end
157
158
 
158
159
  desc 'scan', 'Test the workspace for problems'
@@ -110,18 +110,21 @@ module Solargraph
110
110
  # @param api_map [ApiMap]
111
111
  # @return [ComplexType]
112
112
  def infer_first_defined pins, context, api_map
113
- type = ComplexType::UNDEFINED
113
+ possibles = []
114
114
  pins.each do |pin|
115
115
  # Avoid infinite recursion
116
116
  next if @@inference_stack.include?(pin.identity)
117
117
  @@inference_stack.push pin.identity
118
118
  type = pin.typify(api_map)
119
119
  @@inference_stack.pop
120
- break if type.defined?
120
+ if type.defined?
121
+ possibles.push type
122
+ break if pin.is_a?(Pin::BaseMethod)
123
+ end
121
124
  end
122
- if type.undefined?
125
+ if possibles.empty?
123
126
  # Limit method inference recursion
124
- return type if @@inference_depth >= 10 && pins.first.is_a?(Pin::BaseMethod)
127
+ return ComplexType::UNDEFINED if @@inference_depth >= 10 && pins.first.is_a?(Pin::BaseMethod)
125
128
  @@inference_depth += 1
126
129
  pins.each do |pin|
127
130
  # Avoid infinite recursion
@@ -129,10 +132,20 @@ module Solargraph
129
132
  @@inference_stack.push pin.identity
130
133
  type = pin.probe(api_map)
131
134
  @@inference_stack.pop
132
- break if type.defined?
135
+ if type.defined?
136
+ possibles.push type
137
+ break if pin.is_a?(Pin::BaseMethod)
138
+ end
133
139
  end
134
140
  @@inference_depth -= 1
135
141
  end
142
+ return ComplexType::UNDEFINED if possibles.empty?
143
+ type = if possibles.length > 1
144
+ sorted = possibles.map { |t| t.rooted? ? "::#{t}" : t.to_s }.sort { |a, _| a == 'nil' ? 1 : 0 }
145
+ ComplexType.parse(*sorted)
146
+ else
147
+ possibles.first
148
+ end
136
149
  return type if context.nil? || context.return_type.undefined?
137
150
  type.self_to(context.return_type.namespace)
138
151
  end
@@ -156,7 +156,7 @@ module Solargraph
156
156
 
157
157
  def tag_complete
158
158
  result = []
159
- match = source_map.code[0..cursor.offset-1].match(/\[([a-z0-9_:]*)\z/i)
159
+ match = source_map.code[0..cursor.offset-1].match(/[\[<, ]([a-z0-9_:]*)\z/i)
160
160
  if match
161
161
  full = match[1]
162
162
  if full.include?('::')
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Solargraph
4
- VERSION = '0.39.12'
4
+ VERSION = '0.39.17'
5
5
  end
@@ -158,10 +158,12 @@ module Solargraph
158
158
  @cache ||= YardMap::Cache.new
159
159
  end
160
160
 
161
+ # @return [Hash]
161
162
  def pin_class_hash
162
163
  @pin_class_hash ||= pins.to_set.classify(&:class).transform_values(&:to_a)
163
164
  end
164
165
 
166
+ # @return [Array<Pin::Base>]
165
167
  def pins_by_class klass
166
168
  @pin_select_cache[klass] ||= pin_class_hash.select { |key, _| key <= klass }.values.flatten
167
169
  end
@@ -35,10 +35,10 @@ module Solargraph
35
35
  # This method of superclass detection is a bit of a hack. If
36
36
  # the superclass is a Proxy, it is assumed to be undefined in its
37
37
  # yardoc and converted to a fully qualified namespace.
38
- if code_object.superclass.is_a?(YARD::CodeObjects::Proxy)
39
- superclass = "::#{code_object.superclass}"
38
+ superclass = if code_object.superclass.is_a?(YARD::CodeObjects::Proxy)
39
+ "::#{code_object.superclass}"
40
40
  else
41
- superclass = code_object.superclass.to_s
41
+ code_object.superclass.to_s
42
42
  end
43
43
  result.push Solargraph::Pin::Reference::Superclass.new(name: superclass, closure: nspin)
44
44
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solargraph
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.39.12
4
+ version: 0.39.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fred Snyder
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-18 00:00:00.000000000 Z
11
+ date: 2020-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backport