solargraph 0.39.10 → 0.39.15

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: 9d4f1258688f603e08ed6d5ed023579fbdd3e1829ae3d4e96fa093b08bf7377c
4
- data.tar.gz: 817c20ca0469e682338f40e10edd3c3b21d23e5a4969c519d590ec1c995ae08b
3
+ metadata.gz: 7e70e17b5895de1eea7c7455249afbcf26bb1cb59eb4d47ae93d7e37b53e653d
4
+ data.tar.gz: ba947a023fcc459c489e84afce5d7af0ccce1d3b0b0ba6a6f4b89c72e6693a8e
5
5
  SHA512:
6
- metadata.gz: 2b553ee5d770a0f3ab3fb4c4c5b386ab5dde03ba74cdffe0eb718e0d64cccd8c9e4bbfcf4b35540b2323a1c0553de4d335ca839a269887f6a6615093e5957971
7
- data.tar.gz: 4d2b2bae341dc7102f130f04cec657766a02803ecd2f4f74a23246cdac1ef5d2f6c1d53127b4034780b949b2be3ecc3fc1969662c31329c00e4fdd7e5bb43d6a
6
+ metadata.gz: 1c869730843c3b6f3ad7ea20646c5aed3c22e36b61a8d31e550b13f44de966f8837f9bf35463a9353e755eb6a8352ad2b9c110e5e07a8fd2ad8c6445af1dec83
7
+ data.tar.gz: 3abeace1fea2e9ae611c43bc222968f73bcfb3822761bea46935168d398774cb66fa87528fa851ef080e84dc2cd9d577cada3f5478ad0af4896d02595c16d04f
@@ -4,6 +4,11 @@ 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
14
+ - Tom de Grunt
@@ -423,7 +423,7 @@ module Solargraph
423
423
  # api_map.document('String#split')
424
424
  #
425
425
  # @param path [String] The path to find
426
- # @return [Array<YARD::CodeObject::Base>]
426
+ # @return [Array<YARD::CodeObjects::Base>]
427
427
  def document path
428
428
  rake_yard(store)
429
429
  docs = []
@@ -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
@@ -66,6 +66,7 @@ module Solargraph
66
66
  @return_single_parameter
67
67
  )),
68
68
  Override.method_return('Array#uniq', 'self'),
69
+ Override.method_return('Array#zip', 'Array, nil'),
69
70
 
70
71
  Override.from_comment('BasicObject#==', %(
71
72
  @param other [BasicObject]
@@ -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
@@ -26,10 +26,10 @@ module Solargraph
26
26
  store = RuboCop::ConfigStore.new
27
27
  redirect_stdout { RuboCop::Runner.new(options, store).run(paths) }
28
28
  result = File.read(tempfile)
29
- File.unlink tempfile
30
29
  format original, result
31
30
  rescue RuboCop::ValidationError, RuboCop::ConfigNotFoundError => e
32
31
  set_error(Solargraph::LanguageServer::ErrorCodes::INTERNAL_ERROR, "[#{e.class}] #{e.message}")
32
+ ensure
33
33
  File.unlink tempfile
34
34
  end
35
35
  end
@@ -171,7 +171,21 @@ module Solargraph
171
171
  def definitions_at filename, line, column
172
172
  position = Position.new(line, column)
173
173
  cursor = Source::Cursor.new(read(filename), position)
174
- api_map.clip(cursor).define.map { |pin| pin.realize(api_map) }
174
+ if cursor.comment?
175
+ source = read(filename)
176
+ offset = Solargraph::Position.to_offset(source.code, Solargraph::Position.new(line, column))
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
+ if lft && rgt
180
+ tag = (lft[1] + rgt[1]).sub(/:+$/, '')
181
+ clip = api_map.clip(cursor)
182
+ clip.translate tag
183
+ else
184
+ []
185
+ end
186
+ else
187
+ api_map.clip(cursor).define.map { |pin| pin.realize(api_map) }
188
+ end
175
189
  end
176
190
 
177
191
  # Get signature suggestions for the method at the specified file and
@@ -245,7 +259,7 @@ module Solargraph
245
259
  end
246
260
 
247
261
  # @param query [String]
248
- # @return [Array<YARD::CodeObject::Base>]
262
+ # @return [Array<YARD::CodeObjects::Base>]
249
263
  def document query
250
264
  catalog
251
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)
@@ -124,7 +124,9 @@ module Solargraph
124
124
  result = []
125
125
  if node.type == :block
126
126
  result.push node
127
- node.children[0].children[2..-1].each { |child| result.concat call_nodes_from(child) }
127
+ if Parser.is_ast_node?(node.children[0]) && node.children[0].children.length > 2
128
+ node.children[0].children[2..-1].each { |child| result.concat call_nodes_from(child) }
129
+ end
128
130
  node.children[1..-1].each { |child| result.concat call_nodes_from(child) }
129
131
  elsif node.type == :send
130
132
  result.push node
@@ -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
@@ -53,13 +53,14 @@ module Solargraph
53
53
  # @param text [String]
54
54
  # @return [String]
55
55
  def escape_brackets text
56
- text.gsub(/(\[[^\]]*\])([^\(]|\z)/, '!!!`\1`!!!\2')
56
+ # text.gsub(/(\[[^\]]*\])([^\(]|\z)/, '!!!^\1^!!!\2')
57
+ text.gsub('[', '!!!!b').gsub(']', 'e!!!!')
57
58
  end
58
59
 
59
60
  # @param text [String]
60
61
  # @return [String]
61
62
  def unescape_brackets text
62
- text.gsub('!!!`[', '[').gsub(']`!!!', ']')
63
+ text.gsub('!!!!b', '[').gsub('e!!!!', ']')
63
64
  end
64
65
  end
65
66
 
@@ -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
57
  a[0].match(/[A-Za-z0-9_]*/)[0]
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
@@ -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'
@@ -18,166 +18,12 @@ module Solargraph
18
18
  super(word, [], with_block)
19
19
  end
20
20
 
21
- def with_block?
22
- @with_block
23
- end
24
-
25
21
  # @param api_map [ApiMap]
26
22
  # @param name_pin [Pin::Base]
27
23
  # @param locals [Array<Pin::Base>]
28
24
  def resolve api_map, name_pin, locals
29
25
  return super_pins(api_map, name_pin)
30
26
  end
31
-
32
- private
33
-
34
- # @param pins [Array<Pin::Base>]
35
- # @param api_map [ApiMap]
36
- # @param context [ComplexType]
37
- # @param locals [Pin::LocalVariable]
38
- # @return [Array<Pin::Base>]
39
- def inferred_pins pins, api_map, context, locals
40
- result = pins.map do |p|
41
- overloads = p.docstring.tags(:overload)
42
- # next p if overloads.empty?
43
- type = ComplexType::UNDEFINED
44
- # @param [YARD::Tags::OverloadTag]
45
- overloads.each do |ol|
46
- next unless arguments_match(arguments, ol.parameters)
47
- next if ol.parameters.last && ol.parameters.last.first.start_with?('&') && ol.parameters.last.last.nil? && !with_block?
48
- match = true
49
- arguments.each_with_index do |arg, idx|
50
- achain = arguments[idx]
51
- next if achain.nil?
52
- param = ol.parameters[idx]
53
- if param.nil?
54
- match = false unless ol.parameters.last && ol.parameters.last.first.start_with?('*')
55
- break
56
- end
57
- par = ol.tags(:param).select { |pp| pp.name == param.first }.first
58
- next if par.nil? || par.types.nil? || par.types.empty?
59
- atype = achain.infer(api_map, Pin::ProxyType.anonymous(context), locals)
60
- other = ComplexType.try_parse(*par.types)
61
- # @todo Weak type comparison
62
- unless atype.tag == other.tag || api_map.super_and_sub?(other.tag, atype.tag)
63
- match = false
64
- break
65
- end
66
- end
67
- if match
68
- type = extra_return_type(ol, context)
69
- type = ComplexType.try_parse(*ol.tag(:return).types).self_to(context.to_s).qualify(api_map, context.namespace) if ol.has_tag?(:return) && ol.tag(:return).types && !ol.tag(:return).types.empty? && (type.nil? || type.undefined?)
70
- type ||= ComplexType::UNDEFINED
71
- end
72
- break if type.defined?
73
- end
74
- next p.proxy(type) if type.defined?
75
- type = extra_return_type(p.docstring, context)
76
- if type
77
- next Solargraph::Pin::Method.new(
78
- location: p.location,
79
- closure: p.closure,
80
- name: p.name,
81
- comments: "@return [#{context.subtypes.first.to_s}]",
82
- scope: p.scope,
83
- visibility: p.visibility,
84
- parameters: p.parameters,
85
- node: p.node
86
- )
87
- end
88
- if p.is_a?(Pin::Method) && !p.macros.empty?
89
- result = process_macro(p, api_map, context, locals)
90
- next result unless result.return_type.undefined?
91
- elsif !p.directives.empty?
92
- result = process_directive(p, api_map, context, locals)
93
- next result unless result.return_type.undefined?
94
- end
95
- p
96
- end
97
- result.map do |pin|
98
- next pin if pin.return_type.undefined?
99
- selfy = pin.return_type.self_to(context.tag)
100
- selfy == pin.return_type ? pin : pin.proxy(selfy)
101
- end
102
- end
103
-
104
- # @param pin [Pin::Method]
105
- # @param api_map [ApiMap]
106
- # @param context [ComplexType]
107
- # @param locals [Pin::Base]
108
- # @return [Pin::Base]
109
- def process_macro pin, api_map, context, locals
110
- pin.macros.each do |macro|
111
- result = inner_process_macro(pin, macro, api_map, context, locals)
112
- return result unless result.return_type.undefined?
113
- end
114
- Pin::ProxyType.anonymous(ComplexType::UNDEFINED)
115
- end
116
-
117
- # @param pin [Pin::Method]
118
- # @param api_map [ApiMap]
119
- # @param context [ComplexType]
120
- # @param locals [Pin::Base]
121
- # @return [Pin::ProxyType]
122
- def process_directive pin, api_map, context, locals
123
- pin.directives.each do |dir|
124
- macro = api_map.named_macro(dir.tag.name)
125
- next if macro.nil?
126
- result = inner_process_macro(pin, macro, api_map, context, locals)
127
- return result unless result.return_type.undefined?
128
- end
129
- Pin::ProxyType.anonymous ComplexType::UNDEFINED
130
- end
131
-
132
- # @param pin [Pin]
133
- # @param macro [YARD::Tags::MacroDirective]
134
- # @param api_map [ApiMap]
135
- # @param context [ComplexType]
136
- # @param locals [Array<Pin::Base>]
137
- # @return [Pin::ProxyType]
138
- def inner_process_macro pin, macro, api_map, context, locals
139
- vals = arguments.map{ |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals)) }
140
- txt = macro.tag.text.clone
141
- if txt.empty? && macro.tag.name
142
- named = api_map.named_macro(macro.tag.name)
143
- txt = named.tag.text.clone if named
144
- end
145
- i = 1
146
- vals.each do |v|
147
- txt.gsub!(/\$#{i}/, v.context.namespace)
148
- i += 1
149
- end
150
- docstring = Solargraph::Source.parse_docstring(txt).to_docstring
151
- tag = docstring.tag(:return)
152
- unless tag.nil? || tag.types.nil?
153
- return Pin::ProxyType.anonymous(ComplexType.try_parse(*tag.types))
154
- end
155
- Pin::ProxyType.anonymous(ComplexType::UNDEFINED)
156
- end
157
-
158
- # @param docstring [YARD::Docstring]
159
- # @param context [ComplexType]
160
- # @return [ComplexType]
161
- def extra_return_type docstring, context
162
- if docstring.has_tag?(:return_single_parameter) && context.subtypes.one?
163
- return context.subtypes.first
164
- elsif docstring.has_tag?(:return_value_parameter) && context.value_types.one?
165
- return context.value_types.first
166
- end
167
- nil
168
- end
169
-
170
- # @param arguments [Array<Chain>]
171
- # @param parameters [Array<String>]
172
- # @return [Boolean]
173
- def arguments_match arguments, parameters
174
- argcount = arguments.length
175
- # argcount -= 1 if !arguments.empty? && arguments.last.links.first.word.start_with?('&')
176
- parcount = parameters.length
177
- parcount -= 1 if !parameters.empty? && parameters.last.first.start_with?('&')
178
- return false if argcount < parcount && !(argcount == parcount - 1 && parameters.last.first.start_with?('*'))
179
- true
180
- end
181
27
  end
182
28
  end
183
29
  end
@@ -25,51 +25,12 @@ module Solargraph
25
25
  def complete
26
26
  return package_completions([]) if !source_map.source.parsed? || cursor.string?
27
27
  return package_completions(api_map.get_symbols) if cursor.chain.literal? && cursor.chain.links.last.word == '<Symbol>'
28
- return Completion.new([], cursor.range) if cursor.chain.literal? || cursor.comment?
29
- result = []
30
- result.concat complete_keyword_parameters
31
- if cursor.chain.constant? || cursor.start_of_constant?
32
- full = cursor.chain.links.first.word
33
- type = if cursor.chain.undefined?
34
- cursor.chain.base.infer(api_map, context_pin, locals)
35
- else
36
- if full.include?('::') && cursor.chain.links.length == 1
37
- ComplexType.try_parse(full.split('::')[0..-2].join('::'))
38
- elsif cursor.chain.links.length > 1
39
- ComplexType.try_parse(full)
40
- else
41
- ComplexType::UNDEFINED
42
- end
43
- end
44
- if type.undefined?
45
- if full.include?('::')
46
- result.concat api_map.get_constants(full, *gates)
47
- else
48
- result.concat api_map.get_constants('', cursor.start_of_constant? ? '' : context_pin.full_context.namespace, *gates) #.select { |pin| pin.name.start_with?(full) }
49
- end
50
- else
51
- result.concat api_map.get_constants(type.namespace, cursor.start_of_constant? ? '' : context_pin.full_context.namespace, *gates)
52
- end
28
+ return Completion.new([], cursor.range) if cursor.chain.literal?
29
+ if cursor.comment?
30
+ tag_complete
53
31
  else
54
- type = cursor.chain.base.infer(api_map, block, locals)
55
- result.concat api_map.get_complex_type_methods(type, block.binder.namespace, cursor.chain.links.length == 1)
56
- if cursor.chain.links.length == 1
57
- if cursor.word.start_with?('@@')
58
- return package_completions(api_map.get_class_variable_pins(context_pin.full_context.namespace))
59
- elsif cursor.word.start_with?('@')
60
- return package_completions(api_map.get_instance_variable_pins(block.binder.namespace, block.binder.scope))
61
- elsif cursor.word.start_with?('$')
62
- return package_completions(api_map.get_global_variable_pins)
63
- end
64
- result.concat locals
65
- result.concat api_map.get_constants(context_pin.context.namespace, *gates)
66
- result.concat api_map.get_methods(block.binder.namespace, scope: block.binder.scope, visibility: [:public, :private, :protected])
67
- result.concat api_map.get_methods('Kernel')
68
- result.concat ApiMap.keywords
69
- result.concat yielded_self_pins
70
- end
32
+ code_complete
71
33
  end
72
- package_completions(result)
73
34
  end
74
35
 
75
36
  # @return [Array<Pin::Base>]
@@ -111,6 +72,13 @@ module Solargraph
111
72
  end
112
73
  end
113
74
 
75
+ # @param phrase [String]
76
+ # @return [Array<Solargraph::Pin::Base>]
77
+ def translate phrase
78
+ chain = Parser.chain(Parser.parse(phrase))
79
+ chain.define(api_map, block, locals)
80
+ end
81
+
114
82
  private
115
83
 
116
84
  # @return [ApiMap]
@@ -185,6 +153,71 @@ module Solargraph
185
153
  }
186
154
  Completion.new(filtered, cursor.range)
187
155
  end
156
+
157
+ def tag_complete
158
+ result = []
159
+ match = source_map.code[0..cursor.offset-1].match(/[\[<, ]([a-z0-9_:]*)\z/i)
160
+ if match
161
+ full = match[1]
162
+ if full.include?('::')
163
+ if full.end_with?('::')
164
+ result.concat api_map.get_constants(full[0..-3], *gates)
165
+ else
166
+ result.concat api_map.get_constants(full.split('::')[0..-2].join('::'), *gates)
167
+ end
168
+ else
169
+ result.concat api_map.get_constants('', full.end_with?('::') ? '' : context_pin.full_context.namespace, *gates) #.select { |pin| pin.name.start_with?(full) }
170
+ end
171
+ end
172
+ package_completions(result)
173
+ end
174
+
175
+ def code_complete
176
+ result = []
177
+ result.concat complete_keyword_parameters
178
+ if cursor.chain.constant? || cursor.start_of_constant?
179
+ full = cursor.chain.links.first.word
180
+ type = if cursor.chain.undefined?
181
+ cursor.chain.base.infer(api_map, context_pin, locals)
182
+ else
183
+ if full.include?('::') && cursor.chain.links.length == 1
184
+ ComplexType.try_parse(full.split('::')[0..-2].join('::'))
185
+ elsif cursor.chain.links.length > 1
186
+ ComplexType.try_parse(full)
187
+ else
188
+ ComplexType::UNDEFINED
189
+ end
190
+ end
191
+ if type.undefined?
192
+ if full.include?('::')
193
+ result.concat api_map.get_constants(full, *gates)
194
+ else
195
+ result.concat api_map.get_constants('', cursor.start_of_constant? ? '' : context_pin.full_context.namespace, *gates) #.select { |pin| pin.name.start_with?(full) }
196
+ end
197
+ else
198
+ result.concat api_map.get_constants(type.namespace, cursor.start_of_constant? ? '' : context_pin.full_context.namespace, *gates)
199
+ end
200
+ else
201
+ type = cursor.chain.base.infer(api_map, block, locals)
202
+ result.concat api_map.get_complex_type_methods(type, block.binder.namespace, cursor.chain.links.length == 1)
203
+ if cursor.chain.links.length == 1
204
+ if cursor.word.start_with?('@@')
205
+ return package_completions(api_map.get_class_variable_pins(context_pin.full_context.namespace))
206
+ elsif cursor.word.start_with?('@')
207
+ return package_completions(api_map.get_instance_variable_pins(block.binder.namespace, block.binder.scope))
208
+ elsif cursor.word.start_with?('$')
209
+ return package_completions(api_map.get_global_variable_pins)
210
+ end
211
+ result.concat locals
212
+ result.concat api_map.get_constants(context_pin.context.namespace, *gates)
213
+ result.concat api_map.get_methods(block.binder.namespace, scope: block.binder.scope, visibility: [:public, :private, :protected])
214
+ result.concat api_map.get_methods('Kernel')
215
+ result.concat ApiMap.keywords
216
+ result.concat yielded_self_pins
217
+ end
218
+ end
219
+ package_completions(result)
220
+ end
188
221
  end
189
222
  end
190
223
  end
@@ -202,7 +202,7 @@ module Solargraph
202
202
  code_lines = @code.lines
203
203
  @source.associated_comments.each do |line, comments|
204
204
  src_pos = line ? Position.new(line, code_lines[line].to_s.chomp.index(/[^\s]/) || 0) : Position.new(code_lines.length, 0)
205
- com_pos = Position.new(line - 1, 0)
205
+ com_pos = Position.new(line + 1 - comments.lines.length, 0)
206
206
  process_comment(src_pos, com_pos, comments)
207
207
  end
208
208
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Solargraph
4
- VERSION = '0.39.10'
4
+ VERSION = '0.39.15'
5
5
  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.10
4
+ version: 0.39.15
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-01 00:00:00.000000000 Z
11
+ date: 2020-08-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backport