solargraph 0.29.4 → 0.29.5

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: 60d754493bfc4ef0b40c6fd5b7c872b67e9ee5caa83930f9ede99389bb4b9007
4
- data.tar.gz: '077452469bb99c0b6b7fede9bcadf8fb115d1b9889733c52170800f4b2a953f3'
3
+ metadata.gz: ef270f7fed3e6a6b8cae0214c0bcdd41e239bfe151951875895a5b6fa76b46f7
4
+ data.tar.gz: 5be38dd7aaee4533e5c60abe980176f30225e63393fb1858913c8fb4d9938802
5
5
  SHA512:
6
- metadata.gz: 066a7d0a1b04ba6c9cba7cac8cbb8339a2c2b5a47bd387ab8fdc11b40a6b9ec3cd076c8f2672efb08be8d90db5df32575fea5cf3516e0d0d9e844a169b778580
7
- data.tar.gz: 16a58b9ffc792406b3c95b4ab7d0b5835334a8851c6bb9ab89657606bde490c5184ca7bc5228dc122d39d70a71cb94d459d8a868bde0501c0ebba3cf6804c906
6
+ metadata.gz: 67036eaaafe01c834b8ce7ca20b7ec00cf302653b4dcc45221d15e64121477c938f36027990d2eed1e206f1d037a69aa835c84882753b55fec43dab402ead4e5
7
+ data.tar.gz: d30834378eab843bee9b637dcfe0809189100bedce3c9c71f575da5a9a361153eedb9a1b15b48b4907d4b3776b67e3da12b12c9777ff75ac0ee46a7d147dd3d2
@@ -117,9 +117,10 @@ module Solargraph
117
117
  end
118
118
 
119
119
  # @param filename [String]
120
- # @param position [Position]
120
+ # @param position [Position, Array(Integer, Integer)]
121
121
  # @return [Source::Cursor]
122
122
  def cursor_at filename, position
123
+ position = Position.normalize(position)
123
124
  raise "File not found: #{filename}" unless source_map_hash.has_key?(filename)
124
125
  source_map_hash[filename].cursor_at(position)
125
126
  end
@@ -127,9 +128,10 @@ module Solargraph
127
128
  # Get a clip by filename and position.
128
129
  #
129
130
  # @param filename [String]
130
- # @param position [Position]
131
+ # @param position [Position, Array(Integer, Integer)]
131
132
  # @return [SourceMap::Clip]
132
133
  def clip_at filename, position
134
+ position = Position.normalize(position)
133
135
  SourceMap::Clip.new(self, cursor_at(filename, position))
134
136
  end
135
137
 
@@ -509,6 +511,7 @@ module Solargraph
509
511
  result.concat inner_get_methods(fqim, scope, visibility, deep, skip, true) unless fqim.nil?
510
512
  end
511
513
  result.concat inner_get_methods('Object', :instance, [:public], deep, skip, no_core)
514
+ result.concat inner_get_methods('BasicObject', :instance, [:public], deep, skip, no_core)
512
515
  else
513
516
  store.get_extends(fqns).reverse.each do |em|
514
517
  fqem = qualify(em, fqns)
@@ -4,58 +4,61 @@ module Solargraph
4
4
 
5
5
  # Get the YARD CodeObject at the specified path.
6
6
  #
7
+ # @param path [String]
7
8
  # @return [YARD::CodeObjects::Base]
8
9
  def code_object_at path
9
10
  code_object_map[path]
10
11
  end
11
12
 
13
+ # @return [Array<String>]
12
14
  def code_object_paths
13
15
  code_object_map.keys
14
16
  end
15
17
 
16
- # @param sources [Array<Solargraph::Source>] Sources for code objects
18
+ # @param store [Array<Store>] ApiMap pin store
19
+ # @return [void]
17
20
  def rake_yard store
18
21
  code_object_map.clear
19
- #sources.each do |s|
20
- store.namespace_pins.each do |pin|
21
- next if pin.path.nil? or pin.path.empty?
22
- if pin.type == :class
23
- code_object_map[pin.path] ||= YARD::CodeObjects::ClassObject.new(root_code_object, pin.path)
24
- else
25
- code_object_map[pin.path] ||= YARD::CodeObjects::ModuleObject.new(root_code_object, pin.path)
26
- end
27
- code_object_map[pin.path].docstring = pin.docstring
28
- code_object_map[pin.path].files.push pin.location.filename unless pin.location.nil?
22
+ store.namespace_pins.each do |pin|
23
+ next if pin.path.nil? or pin.path.empty?
24
+ if pin.type == :class
25
+ code_object_map[pin.path] ||= YARD::CodeObjects::ClassObject.new(root_code_object, pin.path)
26
+ else
27
+ code_object_map[pin.path] ||= YARD::CodeObjects::ModuleObject.new(root_code_object, pin.path)
29
28
  end
30
- store.namespace_pins.each do |pin|
31
- # pin.include_references.each do |ref|
32
- store.get_includes(pin.path).each do |ref|
33
- code_object_map[pin.path].instance_mixins.push code_object_map[ref] unless code_object_map[ref].nil? or code_object_map[pin.path].nil?
34
- end
29
+ code_object_map[pin.path].docstring = pin.docstring
30
+ code_object_map[pin.path].files.push pin.location.filename unless pin.location.nil?
31
+ end
32
+ store.namespace_pins.each do |pin|
33
+ # pin.include_references.each do |ref|
34
+ store.get_includes(pin.path).each do |ref|
35
+ code_object_map[pin.path].instance_mixins.push code_object_map[ref] unless code_object_map[ref].nil? or code_object_map[pin.path].nil?
35
36
  end
36
- store.method_pins.each do |pin|
37
- code_object_map[pin.path] ||= YARD::CodeObjects::MethodObject.new(code_object_at(pin.namespace), pin.name, pin.scope)
38
- code_object_map[pin.path].docstring = pin.docstring
39
- code_object_map[pin.path].visibility = pin.visibility || :public
40
- code_object_map[pin.path].files.push pin.location.filename unless pin.location.nil?
41
- code_object_map[pin.path].parameters = pin.parameters.map do |p|
42
- n = p.match(/^[a-z0-9_]*:?/i)[0]
43
- v = nil
44
- if p.length > n.length
45
- v = p[n.length..-1].gsub(/^ = /, '')
46
- end
47
- [n, v]
37
+ end
38
+ store.method_pins.each do |pin|
39
+ code_object_map[pin.path] ||= YARD::CodeObjects::MethodObject.new(code_object_at(pin.namespace), pin.name, pin.scope)
40
+ code_object_map[pin.path].docstring = pin.docstring
41
+ code_object_map[pin.path].visibility = pin.visibility || :public
42
+ code_object_map[pin.path].files.push pin.location.filename unless pin.location.nil?
43
+ code_object_map[pin.path].parameters = pin.parameters.map do |p|
44
+ n = p.match(/^[a-z0-9_]*:?/i)[0]
45
+ v = nil
46
+ if p.length > n.length
47
+ v = p[n.length..-1].gsub(/^ = /, '')
48
48
  end
49
+ [n, v]
49
50
  end
50
- #end
51
+ end
51
52
  end
52
53
 
53
54
  private
54
55
 
56
+ # @return [Hash]
55
57
  def code_object_map
56
58
  @code_object_map ||= {}
57
59
  end
58
60
 
61
+ # @return [YARD::CodeObjects::RootObject]
59
62
  def root_code_object
60
63
  @root_code_object ||= YARD::CodeObjects::RootObject.new(nil, 'root')
61
64
  end
@@ -53,11 +53,8 @@ module Solargraph
53
53
  # @param path [String]
54
54
  # @return [Array<Solargraph::Pin::Base>]
55
55
  def get_path_pins path
56
- # return [] if path.nil? # @todo Should be '' instead?
57
- path ||= ''
58
- base = path.sub(/(#|\.|::)[a-z0-9_]*(\?|\!)?$/i, '')
59
- base = '' if base == path
60
- namespace_children(base).select{ |pin| pin.path == path }
56
+ return [] if path.nil? # @todo Should be '' instead?
57
+ pins.select { |pin| pin.path == path }
61
58
  end
62
59
 
63
60
  # @param fqns [String]
@@ -109,6 +106,7 @@ module Solargraph
109
106
  result
110
107
  end
111
108
 
109
+ # @return [Hash]
112
110
  def named_macros
113
111
  @named_macros ||= begin
114
112
  result = {}
@@ -157,7 +155,7 @@ module Solargraph
157
155
  end
158
156
 
159
157
  # @param name [String]
160
- # @return [Array<Solargraph::Pin::Namespace>]
158
+ # @return [Array<Solargraph::Pin::Base>]
161
159
  def namespace_children name
162
160
  namespace_map[name] || []
163
161
  end
@@ -93,7 +93,11 @@ module Solargraph
93
93
  def qualify api_map, context = ''
94
94
  return ComplexType.parse(tag) if duck_type? or void? or undefined?
95
95
  fqns = api_map.qualify(name, context)
96
- return ComplexType::UNDEFINED if fqns.nil?
96
+ # return ComplexType::UNDEFINED if fqns.nil?
97
+ if fqns.nil?
98
+ return ComplexType.parse('Boolean') if tag == 'Boolean'
99
+ return ComplexType::UNDEFINED
100
+ end
97
101
  ltypes = key_types.map do |t|
98
102
  t.qualify api_map, context
99
103
  end
@@ -18,7 +18,7 @@ module Solargraph
18
18
  private
19
19
 
20
20
  def check_return_type pin, api_map, source
21
- return [] if (pin.name == 'initialize' and pin.scope == :instance) or (pin.name == 'new' and pin.scope == :class)
21
+ return [] if (pin.name == 'initialize' && pin.scope == :instance) || (pin.name == 'new' && pin.scope == :class)
22
22
  result = []
23
23
  unless defined_return_type?(pin, api_map)
24
24
  result.push(
@@ -9,44 +9,76 @@ module Solargraph
9
9
  # is true, notify the client when the gem is up to date.
10
10
  #
11
11
  class CheckGemVersion < Base
12
+ GEM_ZERO = Gem::Version.new('0.0.0')
13
+
14
+ def initialize host, request, current: Gem::Version.new(Solargraph::VERSION), available: nil
15
+ super(host, request)
16
+ @current = current
17
+ @available = available
18
+ end
19
+
12
20
  def process
13
- begin
14
- fetcher = Gem::SpecFetcher.new
15
- tuple = fetcher.search_for_dependency(Gem::Dependency.new('solargraph')).flatten.first
16
- if tuple.nil?
17
- msg = 'An error occurred checking the Solargraph gem version.'
18
- STDERR.puts msg
19
- host.show_message(msg, MessageTypes::ERROR)
20
- else
21
- available = Gem::Version.new(tuple.version)
22
- current = Gem::Version.new(Solargraph::VERSION)
23
- if available > current
24
- host.show_message_request "Solargraph gem version #{available} is available.",
25
- LanguageServer::MessageTypes::INFO,
26
- ['Update now'] do |result|
27
- next unless result == 'Update now'
28
- o, s = Open3.capture2("gem update solargraph")
29
- if s == 0
30
- host.show_message 'Successfully updated the Solargraph gem.', LanguageServer::MessageTypes::INFO
31
- host.send_notification '$/solargraph/restart', {}
32
- else
33
- host.show_message 'An error occurred while updating the gem.', LanguageServer::MessageTypes::ERROR
34
- end
21
+ if available > GEM_ZERO
22
+ if available > current
23
+ host.show_message_request "Solargraph gem version #{available} is available. (Current version: #{current})",
24
+ LanguageServer::MessageTypes::INFO,
25
+ ['Update now'] do |result|
26
+ next unless result == 'Update now'
27
+ o, s = Open3.capture2("gem update solargraph")
28
+ if s == 0
29
+ host.show_message 'Successfully updated the Solargraph gem.', LanguageServer::MessageTypes::INFO
30
+ host.send_notification '$/solargraph/restart', {}
31
+ else
32
+ host.show_message 'An error occurred while updating the gem.', LanguageServer::MessageTypes::ERROR
35
33
  end
36
- elsif params['verbose']
37
- host.show_message "The Solargraph gem is up to date (version #{Solargraph::VERSION})."
34
+ end
35
+ elsif params['verbose']
36
+ host.show_message "The Solargraph gem is up to date (version #{Solargraph::VERSION})."
37
+ end
38
+ elsif fetched?
39
+ STDERR.puts error
40
+ host.show_message(error, MessageTypes::ERROR) if params['verbose']
41
+ end
42
+ set_result({
43
+ installed: current,
44
+ available: available
45
+ })
46
+ end
47
+
48
+ private
49
+
50
+ # @return [Gem::Version]
51
+ attr_reader :current
52
+
53
+ # @return [Gem::Version]
54
+ def available
55
+ if !@available && !@fetched
56
+ @fetched = true
57
+ begin
58
+ @available ||= begin
59
+ fetcher = Gem::SpecFetcher.new
60
+ tuple = fetcher.search_for_dependency(Gem::Dependency.new('solargraph')).flatten.first
61
+ if tuple.nil?
62
+ @error = 'An error occurred fetching the gem data'
63
+ GEM_ZERO
64
+ else
65
+ tuple.version
66
+ end
38
67
  end
39
- set_result({
40
- installed: current,
41
- available: available
42
- })
68
+ rescue Errno::EADDRNOTAVAIL => e
69
+ @error = "Unable to connect to gem source: #{e.message}"
70
+ GEM_ZERO
43
71
  end
44
- rescue Errno::EADDRNOTAVAIL => e
45
- msg = "Unable to connect to gem source: #{e.message}"
46
- STDERR.puts msg
47
- host.show_message(msg, MessageTypes::ERROR) if params['verbose']
48
72
  end
73
+ @available
49
74
  end
75
+
76
+ def fetched?
77
+ @fetched ||= false
78
+ end
79
+
80
+ # @return [String, nil]
81
+ attr_reader :error
50
82
  end
51
83
  end
52
84
  end
@@ -2,9 +2,11 @@ module Solargraph
2
2
  # A Library handles coordination between a Workspace and an ApiMap.
3
3
  #
4
4
  class Library
5
+ # @return [Solargraph::Workspace]
6
+ attr_reader :workspace
7
+
5
8
  # @param workspace [Solargraph::Workspace]
6
9
  def initialize workspace = Solargraph::Workspace.new
7
- @mutex = Mutex.new
8
10
  @workspace = workspace
9
11
  api_map.catalog bundle
10
12
  @synchronized = true
@@ -30,7 +32,8 @@ module Solargraph
30
32
  source = Solargraph::Source.load_string(text, filename, version)
31
33
  workspace.merge source
32
34
  open_file_hash[filename] = source
33
- catalog #unless api_map.try_merge!(source)
35
+ checkout filename
36
+ catalog
34
37
  end
35
38
  end
36
39
 
@@ -51,8 +54,8 @@ module Solargraph
51
54
  workspace.has_file?(filename)
52
55
  end
53
56
 
54
- # Create a source to be added to the workspace. The file is ignored if the
55
- # workspace is not configured to include the file.
57
+ # Create a source to be added to the workspace. The file is ignored if it is
58
+ # neither open in the library nor included in the workspace.
56
59
  #
57
60
  # @param filename [String]
58
61
  # @param text [String] The contents of the file
@@ -60,28 +63,30 @@ module Solargraph
60
63
  def create filename, text
61
64
  result = false
62
65
  mutex.synchronize do
63
- next unless workspace.would_merge?(filename)
66
+ next unless contain?(filename) || open?(filename) || workspace.would_merge?(filename)
64
67
  source = Solargraph::Source.load_string(text, filename)
65
68
  workspace.merge(source)
66
- catalog #unless api_map.try_merge!(source)
69
+ catalog
67
70
  result = true
68
71
  end
69
72
  result
70
73
  end
71
74
 
72
- # Create a file source from a file on disk. The file is ignored if the
73
- # workspace is not configured to include the file.
75
+ # Create a file source from a file on disk. The file is ignored if it is
76
+ # neither open in the library nor included in the workspace.
74
77
  #
75
78
  # @param filename [String]
76
79
  # @return [Boolean] True if the file was added to the workspace.
77
80
  def create_from_disk filename
78
81
  result = false
79
82
  mutex.synchronize do
80
- next if File.directory?(filename) or !File.exist?(filename)
81
- next unless workspace.would_merge?(filename)
83
+ next if File.directory?(filename) || !File.exist?(filename)
84
+ next unless contain?(filename) || open?(filename) || workspace.would_merge?(filename)
82
85
  source = Solargraph::Source.load_string(File.read(filename), filename)
83
86
  workspace.merge(source)
84
- catalog #unless api_map.try_merge!(source)
87
+ open_file_hash[filename] = source if open_file_hash.key?(filename)
88
+ @current = source if @current && @current.filename == source.filename
89
+ catalog
85
90
  result = true
86
91
  end
87
92
  result
@@ -179,9 +184,9 @@ module Solargraph
179
184
  Solargraph::Location.new(loc.filename, Solargraph::Range.from_to(loc.range.start.line, loc.range.start.column + match[0].length, loc.range.ending.line, loc.range.ending.column))
180
185
  end
181
186
  end
182
- result.concat(found.sort{ |a, b|
187
+ result.concat(found.sort do |a, b|
183
188
  a.range.start.line <=> b.range.start.line
184
- })
189
+ end)
185
190
  end
186
191
  end
187
192
  result
@@ -214,7 +219,9 @@ module Solargraph
214
219
  # @param filename [String]
215
220
  # @return [Source]
216
221
  def checkout filename
217
- read filename
222
+ @current = read(filename)
223
+ catalog
224
+ @current
218
225
  end
219
226
 
220
227
  # @param query [String]
@@ -246,7 +253,7 @@ module Solargraph
246
253
  # @param filename [String]
247
254
  # @return [Array<Solargraph::Pin::Base>]
248
255
  def document_symbols filename
249
- return [] unless open_file_hash.has_key?(filename)
256
+ return [] unless open_file_hash.key?(filename)
250
257
  api_map.document_symbols(filename)
251
258
  end
252
259
 
@@ -274,6 +281,7 @@ module Solargraph
274
281
  raise FileNotFoundError, "Unable to update #{updater.filename}" unless open?(updater.filename)
275
282
  open_file_hash[updater.filename] = open_file_hash[updater.filename].synchronize(updater)
276
283
  end
284
+ @current = open_file_hash[updater.filename] if @current && @current.filename == updater.filename
277
285
  @synchronized = false
278
286
  end
279
287
  end
@@ -325,31 +333,23 @@ module Solargraph
325
333
  private
326
334
 
327
335
  # @return [Mutex]
328
- attr_reader :mutex
336
+ def mutex
337
+ @mutex ||= Mutex.new
338
+ end
329
339
 
330
340
  # @return [ApiMap]
331
341
  def api_map
332
342
  @api_map ||= Solargraph::ApiMap.new
333
343
  end
334
344
 
335
- # @return [YardMap]
336
- def yard_map
337
- @yard_map ||= Solargraph::YardMap.new
338
- end
339
-
340
345
  # @return [Bundle]
341
346
  def bundle
342
347
  Bundle.new(
343
348
  workspace: workspace,
344
- opened: open_file_hash.values
349
+ opened: @current ? [@current] : []
345
350
  )
346
351
  end
347
352
 
348
- # @return [Solargraph::Workspace]
349
- def workspace
350
- @workspace
351
- end
352
-
353
353
  # A collection of files that are currently open in the library. Open
354
354
  # files do not need to be in the workspace.
355
355
  #
@@ -367,7 +367,7 @@ module Solargraph
367
367
  # @param filename [String]
368
368
  # @return [Solargraph::Source]
369
369
  def read filename
370
- return open_file_hash[filename] if open_file_hash.has_key?(filename)
370
+ return open_file_hash[filename] if open_file_hash.key?(filename)
371
371
  raise FileNotFoundError, "File not found: #{filename}" unless workspace.has_file?(filename)
372
372
  workspace.source(filename)
373
373
  end