solargraph 0.31.3 → 0.32.0

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: a18d1986bcaf5c2f39fb6f7adf604a2275382a87eaa7d292d0a48ee4d65bf40e
4
- data.tar.gz: 8bd096eb42b1b573b1433b6fa1bad9adbbda95c24cde405422a489f69ead949c
3
+ metadata.gz: 5509f89d971f0a22e8256a0492ce0acd036c2bc1fa01f55b3ca9fb08ff358030
4
+ data.tar.gz: 53f76eccd7206efdb918507752201c4a61aeabd2c67d69ad64686e6bae4bec41
5
5
  SHA512:
6
- metadata.gz: 3b0c25b798781b5ff29c16d1728e1b03108a8bbcc55cc20d407fd6b1e4f16fe0e45d1f730b1de6c6ba1cc661091cd0f4e8e993186cca721e68d9e341ec2f12ed
7
- data.tar.gz: e711f3d5b03207e7a6bff18fa68768ae3d9d8efc6a54e2225d25b4f37033bcbba916c60ce3a379e4d2e1fe20d1c03cad294fc3cfe3411f6568c13bbe4681c52e
6
+ metadata.gz: 140976ad7f59ab810812bcc7ebc6ea141c07337effd78e025c3fda5112e4b130996b7697835b64fc16aca8e4457b0255a55cd3c1c8906479af08af6c78e29ec2
7
+ data.tar.gz: 1af8ccbb0d7e16bb8a49e2f8c5214deb0bbcd33164e704434bd33b6be8b909397385e615b1d2bad34a179303aa2c258f642bf28d2790018b60d00de519955817
@@ -580,22 +580,24 @@ module Solargraph
580
580
  return inner_qualify(root, '', skip)
581
581
  end
582
582
  else
583
- if root == ''
584
- return name if store.namespace_exists?(name)
585
- else
586
- roots = root.to_s.split('::')
587
- while roots.length > 0
588
- fqns = roots.join('::') + '::' + name
589
- return fqns if store.namespace_exists?(fqns)
590
- incs = store.get_includes(roots.join('::'))
591
- incs.each do |inc|
592
- foundinc = inner_qualify(name, inc, skip)
593
- return foundinc unless foundinc.nil?
594
- end
595
- roots.pop
583
+ return name if root == '' && store.namespace_exists?(name)
584
+ roots = root.to_s.split('::')
585
+ while roots.length > 0
586
+ fqns = roots.join('::') + '::' + name
587
+ return fqns if store.namespace_exists?(fqns)
588
+ incs = store.get_includes(roots.join('::'))
589
+ incs.each do |inc|
590
+ foundinc = inner_qualify(name, inc, skip)
591
+ return foundinc unless foundinc.nil?
596
592
  end
597
- return name if store.namespace_exists?(name)
593
+ roots.pop
594
+ end
595
+ incs = store.get_includes('')
596
+ incs.each do |inc|
597
+ foundinc = inner_qualify(name, inc, skip)
598
+ return foundinc unless foundinc.nil?
598
599
  end
600
+ return name if store.namespace_exists?(name)
599
601
  end
600
602
  # live_map.get_fqns(name, root)
601
603
  end
@@ -11,7 +11,7 @@ module Solargraph
11
11
  METHODS_RETURNING_SELF = %w[
12
12
  Array#select Array#reject Array#keep_if Array#delete_if
13
13
  Enumerable#select
14
- Object#clone Object#dup Object#freeze Object#taint Object#untaint
14
+ Object#clone Object#dup Object#freeze Object#taint Object#untaint Object#tap
15
15
  String#freeze
16
16
  ].freeze
17
17
 
@@ -19,6 +19,10 @@ module Solargraph
19
19
  Array#[] Array#first Array#last
20
20
  ].freeze
21
21
 
22
+ METHODS_WITH_YIELDPARAM_SELF = %w[
23
+ Object#tap
24
+ ].freeze
25
+
22
26
  METHODS_WITH_YIELDPARAM_SUBTYPES = %w[
23
27
  Array#each Array#map Array#any? Array#all? Array#index
24
28
  Enumerable#each_entry Enumerable#map Enumerable#any? Enumerable#all?
@@ -660,7 +660,7 @@ module Solargraph
660
660
  referencesProvider: true
661
661
  },
662
662
  'textDocument/rename' => {
663
- renameProvider: true
663
+ renameProvider: {prepareProvider: true}
664
664
  },
665
665
  'textDocument/documentSymbol' => {
666
666
  documentSymbolProvider: true
@@ -70,6 +70,7 @@ module Solargraph
70
70
  register 'textDocument/documentSymbol', TextDocument::DocumentSymbol
71
71
  register 'textDocument/references', TextDocument::References
72
72
  register 'textDocument/rename', TextDocument::Rename
73
+ register 'textDocument/prepareRename', TextDocument::PrepareRename
73
74
  register 'textDocument/foldingRange', TextDocument::FoldingRange
74
75
  register 'workspace/didChangeWatchedFiles', Workspace::DidChangeWatchedFiles
75
76
  register 'workspace/didChangeConfiguration', Workspace::DidChangeConfiguration
@@ -21,7 +21,16 @@ module Solargraph
21
21
  .map { |pin| pin.resolve_completion_item[:documentation] }
22
22
  params
23
23
  .merge(pins.first.resolve_completion_item)
24
- .merge(documentation: docs.join("\n\n"))
24
+ .merge(documentation: markup_content(docs.join("\n\n")))
25
+ end
26
+
27
+ # @param text [String]
28
+ # @return [Hash{Symbol => String}]
29
+ def markup_content text
30
+ {
31
+ kind: 'markdown',
32
+ value: text
33
+ }
25
34
  end
26
35
  end
27
36
  end
@@ -108,7 +108,7 @@ module Solargraph
108
108
 
109
109
  def static_rename
110
110
  {
111
- renameProvider: true
111
+ renameProvider: {prepareProvider: true}
112
112
  }
113
113
  end
114
114
 
@@ -12,6 +12,7 @@ module Solargraph
12
12
  textDocument/definition
13
13
  textDocument/references
14
14
  textDocument/rename
15
+ textDocument/prepareRename
15
16
  textDocument/foldingRange
16
17
  workspace/symbol
17
18
  ]
@@ -17,6 +17,7 @@ module Solargraph
17
17
  autoload :Formatting, 'solargraph/language_server/message/text_document/formatting'
18
18
  autoload :References, 'solargraph/language_server/message/text_document/references'
19
19
  autoload :Rename, 'solargraph/language_server/message/text_document/rename'
20
+ autoload :PrepareRename, 'solargraph/language_server/message/text_document/prepare_rename'
20
21
  autoload :FoldingRange, 'solargraph/language_server/message/text_document/folding_range'
21
22
  end
22
23
  end
@@ -0,0 +1,9 @@
1
+ module Solargraph::LanguageServer::Message::TextDocument
2
+ class PrepareRename < Base
3
+ def process
4
+ line = params['position']['line']
5
+ col = params['position']['character']
6
+ set_result host.sources.find(params['textDocument']['uri']).cursor_at(Solargraph::Position.new(line, col)).range.to_hash
7
+ end
8
+ end
9
+ end
@@ -21,9 +21,12 @@ module Solargraph
21
21
  end
22
22
 
23
23
  # @param data [String]
24
- def sending data
24
+ def receiving data
25
25
  @data_reader.receive data
26
26
  end
27
+ # @todo Temporary alias to avoid problems due to a breaking change in
28
+ # the Backport API
29
+ alias sending receiving
27
30
 
28
31
  private
29
32
 
@@ -111,7 +111,7 @@ module Solargraph
111
111
  # @return [YARD::Docstring]
112
112
  def docstring
113
113
  parse_comments unless defined?(@docstring)
114
- @docstring ||= YARD::Docstring.parser.parse('').to_docstring
114
+ @docstring ||= Solargraph::Source.parse_docstring('').to_docstring
115
115
  end
116
116
 
117
117
  # @return [Array<YARD::Tags::Directive>]
@@ -225,7 +225,9 @@ module Solargraph
225
225
  @docstring = nil
226
226
  @directives = []
227
227
  else
228
- parse = YARD::Docstring.parser.parse(comments)
228
+ # HACK: Pass a dummy code object to the parser for plugins that
229
+ # expect it not to be nil
230
+ parse = Solargraph::Source.parse_docstring(comments)
229
231
  @docstring = parse.to_docstring
230
232
  @directives = parse.directives
231
233
  end
@@ -270,7 +272,7 @@ module Solargraph
270
272
  # @return [Array<YARD::Tags::Handlers::Directive>]
271
273
  def collect_macros
272
274
  return [] unless maybe_directives?
273
- parse = YARD::Docstring.parser.parse(comments)
275
+ parse = Solargraph::Source.parse_docstring(comments)
274
276
  parse.directives.select{ |d| d.tag.tag_name == 'macro' }
275
277
  end
276
278
  end
@@ -34,23 +34,40 @@ module Solargraph
34
34
  ComplexType.try_parse *tag.types
35
35
  end
36
36
 
37
- # @param [ApiMap]
37
+ # @param api_map [ApiMap]
38
+ # @return [ComplexType]
38
39
  def see_reference api_map
39
40
  docstring.ref_tags.each do |ref|
40
41
  next unless ref.tag_name == 'return' && ref.owner
41
- parts = ref.owner.to_s.split(/[\.#]/)
42
- if parts.first.empty?
43
- path = "#{namespace}#{ref.owner.to_s}"
44
- else
45
- fqns = api_map.qualify(parts.first, namespace)
46
- return ComplexType::UNDEFINED if fqns.nil?
47
- path = fqns + ref.owner.to_s[parts.first.length] + parts.last
48
- end
49
- pins = api_map.get_path_pins(path)
50
- pins.each do |pin|
51
- type = pin.typify(api_map)
52
- return type unless type.undefined?
53
- end
42
+ result = resolve_reference(ref.owner.to_s, api_map)
43
+ return result unless result.nil?
44
+ end
45
+ match = comments.match(/\(see (.*)\)/)
46
+ return nil if match.nil?
47
+ resolve_reference match[1], api_map
48
+ end
49
+
50
+ # @param ref [String]
51
+ # @param api_map [ApiMap]
52
+ # @return [ComplexType]
53
+ def resolve_reference ref, api_map
54
+ parts = ref.split(/[\.#]/)
55
+ if parts.first.empty?
56
+ path = "#{namespace}#{ref}"
57
+ else
58
+ fqns = api_map.qualify(parts.first, namespace)
59
+ return ComplexType::UNDEFINED if fqns.nil?
60
+ path = fqns + ref[parts.first.length] + parts.last
61
+ end
62
+ pins = api_map.get_path_pins(path)
63
+ pins.each do |pin|
64
+ type = pin.typify(api_map)
65
+ return type unless type.undefined?
66
+ end
67
+ pins = api_map.get_path_pins(path)
68
+ pins.each do |pin|
69
+ type = pin.typify(api_map)
70
+ return type unless type.undefined?
54
71
  end
55
72
  nil
56
73
  end
@@ -85,6 +85,10 @@ module Solargraph
85
85
  bmeth = chain.base.define(api_map, context, locals).first
86
86
  return ComplexType::UNDEFINED if bmeth.nil? or bmeth.return_complex_type.undefined? or bmeth.return_complex_type.subtypes.empty?
87
87
  return bmeth.return_complex_type.subtypes.first.qualify(api_map, bmeth.context.namespace)
88
+ elsif (Solargraph::CoreFills::METHODS_WITH_YIELDPARAM_SELF.include?(meth.path))
89
+ bmeth = chain.base.define(api_map, context, locals).first
90
+ return ComplexType::UNDEFINED if bmeth.nil?
91
+ return bmeth.typify(api_map)
88
92
  else
89
93
  yps = meth.docstring.tags(:yieldparam)
90
94
  unless yps[index].nil? or yps[index].types.nil? or yps[index].types.empty?
@@ -1,4 +1,5 @@
1
1
  require 'parser/current'
2
+ require 'yard'
2
3
 
3
4
  module Solargraph
4
5
  # A Ruby file that has been parsed into an AST.
@@ -327,7 +328,7 @@ module Solargraph
327
328
  last_line = nil
328
329
  comments.each { |l|
329
330
  # Trim the comment and minimum leading whitespace
330
- p = l.text.gsub(/^#/, '')
331
+ p = l.text.gsub(/^#+/, '')
331
332
  if num.nil? and !p.strip.empty?
332
333
  num = p.index(/[^ ]/)
333
334
  started = true
@@ -465,7 +466,7 @@ module Solargraph
465
466
  # @param filename [String]
466
467
  # @return [Solargraph::Source]
467
468
  def load filename
468
- file = File.open(filename, 'rb')
469
+ file = File.open(filename)
469
470
  code = file.read
470
471
  file.close
471
472
  Source.load_string(code, filename)
@@ -484,7 +485,7 @@ module Solargraph
484
485
  # @return [Array(Parser::AST::Node, Array<Parser::Source::Comment>)]
485
486
  def parse_with_comments code, filename = nil
486
487
  buffer = Parser::Source::Buffer.new(filename, 0)
487
- buffer.source = code.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '_')
488
+ buffer.source = code
488
489
  parser.parse_with_comments(buffer)
489
490
  end
490
491
 
@@ -494,7 +495,7 @@ module Solargraph
494
495
  # @return [Parser::AST::Node]
495
496
  def parse code, filename = nil, line = 0
496
497
  buffer = Parser::Source::Buffer.new(filename, line)
497
- buffer.source = code.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '_')
498
+ buffer.source = code
498
499
  parser.parse(buffer)
499
500
  end
500
501
 
@@ -507,6 +508,14 @@ module Solargraph
507
508
  parser.diagnostics.ignore_warnings = true
508
509
  parser
509
510
  end
511
+
512
+ # @param comments [String]
513
+ # @return [YARD::DocstringParser]
514
+ def parse_docstring comments
515
+ # HACK: Pass a dummy code object to the parser for plugins that
516
+ # expect it not to be nil
517
+ YARD::Docstring.parser.parse(comments, YARD::CodeObjects::Base.new(:root, 'stub'))
518
+ end
510
519
  end
511
520
  end
512
521
  end
@@ -94,7 +94,7 @@ module Solargraph
94
94
  txt.gsub!(/\$#{i}/, v.context.namespace)
95
95
  i += 1
96
96
  end
97
- docstring = YARD::Docstring.parser.parse(txt).to_docstring
97
+ docstring = Solargraph::Source.parse_docstring(txt).to_docstring
98
98
  tag = docstring.tag(:return)
99
99
  unless tag.nil? || tag.types.nil?
100
100
  return Pin::ProxyType.anonymous(ComplexType.try_parse(*tag.types))
@@ -157,6 +157,7 @@ module Solargraph
157
157
  end
158
158
  if brackets.zero? and parens.zero? and squares.zero?
159
159
  break if ['"', "'", ',', ';', '%'].include?(char)
160
+ break if !signature.empty? && ['!', '?'].include?(char)
160
161
  signature = char + signature if char.match(/[a-z0-9:\._@\$\?\!]/i) and @source.code[index - 1] != '%'
161
162
  break if char == '$'
162
163
  if char == '@'
@@ -21,10 +21,14 @@ module Solargraph
21
21
  @filename = source.filename
22
22
  @code = source.code
23
23
  @comments = source.comments
24
- @pins = Solargraph::SourceMap::NodeProcessor.process(source.node, Solargraph::SourceMap::Region.new(source: source), [])
24
+ @pins = NodeProcessor.process(source.node, Region.new(source: source))
25
25
  process_comment_directives
26
26
  locals = @pins.select{|p| [Pin::LocalVariable, Pin::MethodParameter, Pin::BlockParameter].include?(p.class)}
27
27
  [@pins - locals, locals]
28
+ rescue Exception => e
29
+ Solargraph.logger.warn "Error mapping #{source.filename}: [#{e.class}] #{e.message}"
30
+ Solargraph.logger.warn e.backtrace
31
+ [[], []]
28
32
  end
29
33
 
30
34
  def unmap filename, code
@@ -62,14 +66,14 @@ module Solargraph
62
66
  def process_comment source_position, comment_position, comment
63
67
  return unless comment =~ MACRO_REGEXP
64
68
  cmnt = remove_inline_comment_hashes(comment)
65
- parse = YARD::Docstring.parser.parse(cmnt)
69
+ parse = Solargraph::Source.parse_docstring(cmnt)
66
70
  parse.directives.each { |d| process_directive(source_position, comment_position, d) }
67
71
  end
68
72
 
69
73
  # @param position [Position]
70
74
  # @param directive [YARD::Tags::Directive]
71
75
  def process_directive source_position, comment_position, directive
72
- docstring = YARD::Docstring.parser.parse(directive.tag.text).to_docstring
76
+ docstring = Solargraph::Source.parse_docstring(directive.tag.text).to_docstring
73
77
  location = Location.new(@filename, Range.new(comment_position, comment_position))
74
78
  case directive.tag.tag_name
75
79
  when 'method'
@@ -147,8 +147,8 @@ module Solargraph
147
147
  if node.children[2].type == :sym || node.children[2].type == :str
148
148
  ref = pins.select{|p| [Solargraph::Pin::Method, Solargraph::Pin::Attribute].include?(p.class) && p.namespace == region.namespace && p.name == node.children[2].children[0].to_s}.first
149
149
  unless ref.nil?
150
- pins.delete ref
151
- pins.push Solargraph::Pin::Method.new(ref.location, ref.namespace, ref.name, ref.comments, ref.scope, :private, ref.parameters, ref.node)
150
+ # HACK: Smelly instance variable access
151
+ ref.instance_variable_set(:@visibility, :private)
152
152
  end
153
153
  false
154
154
  else
@@ -1,3 +1,3 @@
1
1
  module Solargraph
2
- VERSION = '0.31.3'
2
+ VERSION = '0.32.0'
3
3
  end
@@ -123,9 +123,9 @@ module Solargraph
123
123
 
124
124
  # @param code_object [YARD::CodeObjects::Base]
125
125
  # @return [Solargraph::Pin::Base]
126
- def generate_pins code_object
126
+ def generate_pins code_object, spec = nil
127
127
  result = []
128
- location = object_location(code_object)
128
+ location = object_location(code_object, spec)
129
129
  if code_object.is_a?(YARD::CodeObjects::NamespaceObject)
130
130
  result.push Solargraph::Pin::YardPin::Namespace.new(code_object, location)
131
131
  if code_object.is_a?(YARD::CodeObjects::ClassObject) and !code_object.superclass.nil?
@@ -186,7 +186,7 @@ module Solargraph
186
186
  @gem_paths[spec.name] = spec.full_gem_path
187
187
  unless yardocs.include?(yd)
188
188
  yardocs.unshift yd
189
- result.concat process_yardoc yd
189
+ result.concat process_yardoc yd, spec
190
190
  result.concat add_gem_dependencies(spec) if with_dependencies?
191
191
  end
192
192
  rescue Gem::LoadError => e
@@ -248,7 +248,7 @@ module Solargraph
248
248
  else
249
249
  next if yardocs.include?(gy)
250
250
  yardocs.unshift gy
251
- result.concat process_yardoc gy
251
+ result.concat process_yardoc gy, depspec
252
252
  result.concat add_gem_dependencies(depspec)
253
253
  end
254
254
  rescue Gem::LoadError
@@ -261,7 +261,7 @@ module Solargraph
261
261
 
262
262
  # @param y [String, nil]
263
263
  # @return [Array<Pin::Base>]
264
- def process_yardoc y
264
+ def process_yardoc y, spec = nil
265
265
  return [] if y.nil?
266
266
  size = Dir.glob(File.join(y, '**', '*'))
267
267
  .map{ |f| File.size(f) }
@@ -273,20 +273,26 @@ module Solargraph
273
273
  result = []
274
274
  load_yardoc y
275
275
  YARD::Registry.each do |o|
276
- result.concat generate_pins(o)
276
+ result.concat generate_pins(o, spec)
277
277
  end
278
278
  result
279
279
  end
280
280
 
281
281
  # @param obj [YARD::CodeObjects::Base]
282
282
  # @return [Solargraph::Location]
283
- def object_location obj
284
- return nil if obj.file.nil? or obj.line.nil?
285
- @gem_paths.values.each do |path|
286
- file = File.join(path, obj.file)
287
- return Solargraph::Location.new(file, Solargraph::Range.from_to(obj.line, 0, obj.line, 0)) if File.exist?(file)
283
+ def object_location obj, spec = nil
284
+ @object_file_cache ||= {}
285
+ return nil if spec.nil? || obj.file.nil? || obj.line.nil?
286
+ file = nil
287
+ if @object_file_cache.key?(obj.file)
288
+ file = @object_file_cache[obj.file]
289
+ else
290
+ tmp = File.join(spec.full_gem_path, obj.file)
291
+ file = tmp if File.exist?(tmp)
292
+ @object_file_cache[obj.file] = file
288
293
  end
289
- nil
294
+ return nil if file.nil?
295
+ Solargraph::Location.new(file, Solargraph::Range.from_to(obj.line - 1, 0, obj.line - 1, 0))
290
296
  end
291
297
  end
292
298
  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.31.3
4
+ version: 0.32.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fred Snyder
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-11 00:00:00.000000000 Z
11
+ date: 2019-04-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backport
@@ -16,14 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.3'
19
+ version: '1.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.3'
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.17.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 1.17.2
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: htmlentities
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -286,6 +300,7 @@ files:
286
300
  - lib/solargraph/language_server/message/text_document/formatting.rb
287
301
  - lib/solargraph/language_server/message/text_document/hover.rb
288
302
  - lib/solargraph/language_server/message/text_document/on_type_formatting.rb
303
+ - lib/solargraph/language_server/message/text_document/prepare_rename.rb
289
304
  - lib/solargraph/language_server/message/text_document/references.rb
290
305
  - lib/solargraph/language_server/message/text_document/rename.rb
291
306
  - lib/solargraph/language_server/message/text_document/signature_help.rb