solargraph 0.39.12 → 0.39.17

Sign up to get free protection for your applications and to get access to all the features.
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