solargraph 0.31.3 → 0.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml 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