solargraph 0.29.5 → 0.30.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/lib/solargraph.rb +1 -0
  3. data/lib/solargraph/api_map.rb +22 -13
  4. data/lib/solargraph/language_server/host.rb +121 -33
  5. data/lib/solargraph/language_server/host/cataloger.rb +5 -4
  6. data/lib/solargraph/language_server/message.rb +3 -0
  7. data/lib/solargraph/language_server/message/extended.rb +5 -4
  8. data/lib/solargraph/language_server/message/extended/document.rb +1 -1
  9. data/lib/solargraph/language_server/message/extended/environment.rb +20 -0
  10. data/lib/solargraph/language_server/message/extended/search.rb +1 -1
  11. data/lib/solargraph/language_server/message/initialize.rb +28 -4
  12. data/lib/solargraph/language_server/message/initialized.rb +1 -0
  13. data/lib/solargraph/language_server/message/text_document.rb +1 -0
  14. data/lib/solargraph/language_server/message/text_document/folding_range.rb +24 -0
  15. data/lib/solargraph/language_server/message/text_document/formatting.rb +1 -0
  16. data/lib/solargraph/language_server/message/workspace.rb +4 -3
  17. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +1 -0
  18. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +3 -6
  19. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +24 -0
  20. data/lib/solargraph/language_server/transport.rb +1 -2
  21. data/lib/solargraph/language_server/transport/{socket.rb → adapter.rb} +8 -10
  22. data/lib/solargraph/library.rb +29 -3
  23. data/lib/solargraph/logging.rb +25 -0
  24. data/lib/solargraph/page.rb +14 -4
  25. data/lib/solargraph/pin/documenting.rb +1 -1
  26. data/lib/solargraph/shell.rb +9 -10
  27. data/lib/solargraph/source.rb +59 -5
  28. data/lib/solargraph/source/encoding_fixes.rb +1 -1
  29. data/lib/solargraph/source_map/mapper.rb +14 -8
  30. data/lib/solargraph/version.rb +1 -1
  31. data/lib/solargraph/views/_method.erb +3 -0
  32. data/lib/solargraph/views/environment.erb +50 -0
  33. data/lib/solargraph/views/layout.erb +6 -0
  34. data/lib/solargraph/yard_map.rb +8 -8
  35. metadata +11 -13
  36. data/lib/solargraph/language_server/transport/stdio.rb +0 -63
@@ -16,7 +16,7 @@ module Solargraph
16
16
  entity_output: :symbolic,
17
17
  syntax_highlighter: nil
18
18
  ).to_html
19
- ReverseMarkdown.convert(html, github_flavored: true)
19
+ ReverseMarkdown.convert(html, github_flavored: true).lines.map(&:rstrip).join("\n")
20
20
  end
21
21
  end
22
22
 
@@ -3,7 +3,7 @@ require 'json'
3
3
  require 'fileutils'
4
4
  require 'rubygems/package'
5
5
  require 'zlib'
6
- require 'eventmachine'
6
+ require 'backport'
7
7
 
8
8
  module Solargraph
9
9
  class Shell < Thor
@@ -22,29 +22,28 @@ module Solargraph
22
22
  def socket
23
23
  port = options[:port]
24
24
  port = available_port if port.zero?
25
- EventMachine.run do
25
+ Backport.run do
26
26
  Signal.trap("INT") do
27
- EventMachine.stop
27
+ Backport.stop
28
28
  end
29
29
  Signal.trap("TERM") do
30
- EventMachine.stop
30
+ Backport.stop
31
31
  end
32
- EventMachine.start_server options[:host], port, Solargraph::LanguageServer::Transport::Socket
33
- # Emitted for the benefit of clients that start the process on port 0
32
+ Backport.prepare_tcp_server host: options[:host], port: port, adapter: Solargraph::LanguageServer::Transport::Adapter
34
33
  STDERR.puts "Solargraph is listening PORT=#{port} PID=#{Process.pid}"
35
34
  end
36
35
  end
37
36
 
38
37
  desc 'stdio', 'Run a Solargraph stdio server'
39
38
  def stdio
40
- EventMachine.run do
39
+ Backport.run do
41
40
  Signal.trap("INT") do
42
- EventMachine.stop
41
+ Backport.stop
43
42
  end
44
43
  Signal.trap("TERM") do
45
- EventMachine.stop
44
+ Backport.stop
46
45
  end
47
- Solargraph::LanguageServer::Transport::Stdio.run
46
+ Backport.prepare_stdio_server adapter: Solargraph::LanguageServer::Transport::Adapter
48
47
  STDERR.puts "Solargraph is listening on stdio PID=#{Process.pid}"
49
48
  end
50
49
  end
@@ -205,8 +205,43 @@ module Solargraph
205
205
  Location.new(filename, range)
206
206
  end
207
207
 
208
+ FOLDING_NODE_TYPES = %i[
209
+ class sclass module def defs if str dstr array while unless kwbegin hash
210
+ ].freeze
211
+
212
+ # Get an array of ranges that can be folded, e.g., the range of a class
213
+ # definition or an if condition.
214
+ #
215
+ # See FOLDING_NODE_TYPES for the list of node types that can be folded.
216
+ #
217
+ # @return [Array<Range>]
218
+ def folding_ranges
219
+ @folding_ranges ||= begin
220
+ result = []
221
+ inner_folding_ranges node, result
222
+ result.concat comment_block_ranges
223
+ result
224
+ end
225
+ end
226
+
208
227
  private
209
228
 
229
+ # @param top [Parser::AST::Node]
230
+ # @param result [Array<Range>]
231
+ # @return [void]
232
+ def inner_folding_ranges top, result = []
233
+ return unless top.is_a?(Parser::AST::Node)
234
+ if FOLDING_NODE_TYPES.include?(top.type)
235
+ range = Range.from_node(top)
236
+ if result.empty? || range.start.line > result.last.start.line
237
+ result.push range unless range.ending.line - range.start.line < 2
238
+ end
239
+ end
240
+ top.children.each do |child|
241
+ inner_folding_ranges(child, result)
242
+ end
243
+ end
244
+
210
245
  # Get a hash of comments grouped by the line numbers of the associated code.
211
246
  #
212
247
  # @return [Hash{Integer => Array<Parser::Source::Comment>}]
@@ -253,11 +288,32 @@ module Solargraph
253
288
 
254
289
  # @return [Array<Range>]
255
290
  def comment_ranges
256
- @comment_ranges || @comments.map do |cmnt|
291
+ @comment_ranges ||= @comments.map do |cmnt|
257
292
  Range.from_expr(cmnt.loc.expression)
258
293
  end
259
294
  end
260
295
 
296
+ def comment_block_ranges
297
+ result = []
298
+ grouped = []
299
+ # @param cmnt [Parser::Source::Comment]
300
+ @comments.each do |cmnt|
301
+ if cmnt.document?
302
+ result.push Range.from_expr(cmnt.loc.expression)
303
+ elsif code.lines[cmnt.loc.expression.line].strip.start_with?('#')
304
+ if grouped.empty? || cmnt.loc.expression.line == grouped.last.loc.expression.line + 1
305
+ grouped.push cmnt
306
+ else
307
+ result.push Range.from_to(grouped.first.loc.expression.line, 0, grouped.last.loc.expression.line, 0) unless grouped.empty?
308
+ grouped = [cmnt]
309
+ end
310
+ else
311
+ result.push Range.from_to(grouped.first.loc.expression.line, 0, grouped.last.loc.expression.line, 0) unless grouped.empty?
312
+ end
313
+ end
314
+ result
315
+ end
316
+
261
317
  def string_ranges_in n
262
318
  result = []
263
319
  if n.is_a?(Parser::AST::Node)
@@ -338,14 +394,12 @@ module Solargraph
338
394
  # @param code [String]
339
395
  # @param filename [String]
340
396
  # @return [Parser::AST::Node]
341
- def parse code, filename = nil
342
- buffer = Parser::Source::Buffer.new(filename, 0)
397
+ def parse code, filename = nil, line = 0
398
+ buffer = Parser::Source::Buffer.new(filename, line)
343
399
  buffer.source = code.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '_')
344
400
  parser.parse(buffer)
345
401
  end
346
402
 
347
- private
348
-
349
403
  # @return [Parser::Base]
350
404
  def parser
351
405
  # @todo Consider setting an instance variable. We might not need to
@@ -9,7 +9,7 @@ module Solargraph
9
9
  # @return [String]
10
10
  def normalize string
11
11
  begin
12
- string.clone.force_encoding('UTF-8')
12
+ string.dup.force_encoding('UTF-8')
13
13
  rescue ::Encoding::CompatibilityError, ::Encoding::UndefinedConversionError, ::Encoding::InvalidByteSequenceError => e
14
14
  # @todo Improve error handling
15
15
  STDERR.puts "Normalize error: #{e.message}"
@@ -14,6 +14,7 @@ module Solargraph
14
14
  #
15
15
  # @return [Array]
16
16
  def map source
17
+ @source = source
17
18
  @filename = source.filename
18
19
  @code = source.code
19
20
  @comments = source.comments
@@ -39,11 +40,6 @@ module Solargraph
39
40
  end
40
41
  end
41
42
 
42
- # @return [String]
43
- def filename
44
- @filename
45
- end
46
-
47
43
  # @return [Array<Solargraph::Pin::Base>]
48
44
  def pins
49
45
  @pins ||= []
@@ -62,7 +58,7 @@ module Solargraph
62
58
 
63
59
  def process_comment position, comment
64
60
  cmnt = remove_inline_comment_hashes(comment)
65
- return unless cmnt =~ /(@\!method|@\!attribute|@\!domain|@\!macro)/
61
+ return unless cmnt =~ /(@\!method|@\!attribute|@\!domain|@\!macro|@\!parse)/
66
62
  parse = YARD::Docstring.parser.parse(cmnt)
67
63
  parse.directives.each { |d| process_directive(position, d) }
68
64
  end
@@ -81,13 +77,23 @@ module Solargraph
81
77
  when 'attribute'
82
78
  namespace = namespace_at(position)
83
79
  t = (directive.tag.types.nil? || directive.tag.types.empty?) ? nil : directive.tag.types.flatten.join('')
84
- if t.nil? or t.include?('r')
80
+ if t.nil? || t.include?('r')
85
81
  # location, namespace, name, docstring, access
86
82
  pins.push Solargraph::Pin::Attribute.new(location, namespace.path, directive.tag.name, docstring.all, :reader, :instance, :public)
87
83
  end
88
- if t.nil? or t.include?('w')
84
+ if t.nil? || t.include?('w')
89
85
  pins.push Solargraph::Pin::Attribute.new(location, namespace.path, "#{directive.tag.name}=", docstring.all, :writer, :instance, :public)
90
86
  end
87
+ when 'parse'
88
+ # @todo Parse and map directive.tag.text
89
+ ns = namespace_at(position)
90
+ region = Region.new(source: @source, namespace: ns.path)
91
+ begin
92
+ node = Solargraph::Source.parse(directive.tag.text, @filename, position.line)
93
+ NodeProcessor.process(node, region, @pins)
94
+ rescue Parser::SyntaxError => e
95
+ # @todo Handle parser errors in !parse directives
96
+ end
91
97
  when 'domain'
92
98
  namespace = namespace_at(position)
93
99
  namespace.domains.push directive.tag.text
@@ -1,3 +1,3 @@
1
1
  module Solargraph
2
- VERSION = '0.29.5'
2
+ VERSION = '0.30.0'
3
3
  end
@@ -8,6 +8,9 @@
8
8
  Overview:
9
9
  </h2>
10
10
  <%= htmlify object.docstring %>
11
+ <p class="document-section">
12
+ <big><strong>Visibility:</strong></big> <%= object.visibility %>
13
+ </p>
11
14
  <% unless object.tags(:param).empty? %>
12
15
  <h2>
13
16
  Parameters:
@@ -0,0 +1,50 @@
1
+ <html>
2
+ <head>
3
+ <title>Solargraph Environment</title>
4
+ </head>
5
+ <h1>
6
+ Solargraph Environment Info
7
+ </h1>
8
+ <h2>
9
+ System
10
+ </h2>
11
+ <ul>
12
+ <li>
13
+ Platform: <%= RUBY_PLATFORM %>
14
+ </li>
15
+ <li>
16
+ Shell: <%= ENV['SHELL'] %>
17
+ </li>
18
+ <li>
19
+ Ruby Version: <%= RUBY_VERSION %>
20
+ </li>
21
+ </ul>
22
+ <h2>
23
+ Solargraph
24
+ </h2>
25
+ <ul>
26
+ <li>
27
+ Solargraph Version: <%= Solargraph::VERSION %>
28
+ </li>
29
+ <li>
30
+ Core Documentation Version: <%= Solargraph::YardMap::CoreDocs.best_match %>
31
+ </li>
32
+ <li>
33
+ Parser Target Version: <%= Solargraph::Source.parser.version %>
34
+ </li>
35
+ <li>
36
+ Using Bundler: <%= ENV.key?('BUNDLE_GEMFILE') %>
37
+ </li>
38
+ </ul>
39
+ <h2>
40
+ Project
41
+ </h2>
42
+ <ul>
43
+ <li>
44
+ Config: <%= config %>
45
+ </li>
46
+ <li>
47
+ Workspace folders: <%= folders %>
48
+ </li>
49
+ </ul>
50
+ </html>
@@ -11,6 +11,9 @@
11
11
  font-size: 110%;
12
12
  margin: 1.5em 0 1em 0;
13
13
  }
14
+ big {
15
+ font-size: 110%;
16
+ }
14
17
  pre {
15
18
  margin: 1em;
16
19
  padding: 0.5em;
@@ -30,6 +33,9 @@
30
33
  font-size: 75%;
31
34
  font-weight: normal;
32
35
  }
36
+ .document-section {
37
+ margin: 1.5em 0 1em 0;
38
+ }
33
39
  </style>
34
40
  </head>
35
41
  <body>
@@ -178,15 +178,15 @@ module Solargraph
178
178
  ver = spec.version.to_s
179
179
  ver = ">= 0" if ver.empty?
180
180
  yd = YARD::Registry.yardoc_file_for_gem(spec.name, ver)
181
+ # YARD detects gems for certain libraries that do not have a yardoc
182
+ # but exist in the stdlib. `fileutils` is an example. Treat those
183
+ # cases as errors and check the stdlib yardoc.
184
+ raise Gem::LoadError if yd.nil?
181
185
  @gem_paths[spec.name] = spec.full_gem_path
182
- if yd.nil?
183
- unresolved_requires.push r
184
- else
185
- unless yardocs.include?(yd)
186
- yardocs.unshift yd
187
- result.concat process_yardoc yd
188
- result.concat add_gem_dependencies(spec) if with_dependencies?
189
- end
186
+ unless yardocs.include?(yd)
187
+ yardocs.unshift yd
188
+ result.concat process_yardoc yd
189
+ result.concat add_gem_dependencies(spec) if with_dependencies?
190
190
  end
191
191
  rescue Gem::LoadError => e
192
192
  stdtmp = []
metadata CHANGED
@@ -1,35 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solargraph
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.29.5
4
+ version: 0.30.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: 2018-12-18 00:00:00.000000000 Z
11
+ date: 2018-12-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: eventmachine
14
+ name: backport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.2'
20
- - - ">="
21
- - !ruby/object:Gem::Version
22
- version: 1.2.5
19
+ version: '0.2'
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
24
  - - "~>"
28
25
  - !ruby/object:Gem::Version
29
- version: '1.2'
30
- - - ">="
31
- - !ruby/object:Gem::Version
32
- version: 1.2.5
26
+ version: '0.2'
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: htmlentities
35
29
  requirement: !ruby/object:Gem::Requirement
@@ -255,6 +249,7 @@ files:
255
249
  - lib/solargraph/language_server/message/extended/document.rb
256
250
  - lib/solargraph/language_server/message/extended/document_gems.rb
257
251
  - lib/solargraph/language_server/message/extended/download_core.rb
252
+ - lib/solargraph/language_server/message/extended/environment.rb
258
253
  - lib/solargraph/language_server/message/extended/search.rb
259
254
  - lib/solargraph/language_server/message/initialize.rb
260
255
  - lib/solargraph/language_server/message/initialized.rb
@@ -270,6 +265,7 @@ files:
270
265
  - lib/solargraph/language_server/message/text_document/did_open.rb
271
266
  - lib/solargraph/language_server/message/text_document/did_save.rb
272
267
  - lib/solargraph/language_server/message/text_document/document_symbol.rb
268
+ - lib/solargraph/language_server/message/text_document/folding_range.rb
273
269
  - lib/solargraph/language_server/message/text_document/formatting.rb
274
270
  - lib/solargraph/language_server/message/text_document/hover.rb
275
271
  - lib/solargraph/language_server/message/text_document/on_type_formatting.rb
@@ -279,19 +275,20 @@ files:
279
275
  - lib/solargraph/language_server/message/workspace.rb
280
276
  - lib/solargraph/language_server/message/workspace/did_change_configuration.rb
281
277
  - lib/solargraph/language_server/message/workspace/did_change_watched_files.rb
278
+ - lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb
282
279
  - lib/solargraph/language_server/message/workspace/workspace_symbol.rb
283
280
  - lib/solargraph/language_server/message_types.rb
284
281
  - lib/solargraph/language_server/request.rb
285
282
  - lib/solargraph/language_server/symbol_kinds.rb
286
283
  - lib/solargraph/language_server/transport.rb
284
+ - lib/solargraph/language_server/transport/adapter.rb
287
285
  - lib/solargraph/language_server/transport/data_reader.rb
288
- - lib/solargraph/language_server/transport/socket.rb
289
- - lib/solargraph/language_server/transport/stdio.rb
290
286
  - lib/solargraph/language_server/uri_helpers.rb
291
287
  - lib/solargraph/library.rb
292
288
  - lib/solargraph/live_map.rb
293
289
  - lib/solargraph/live_map/cache.rb
294
290
  - lib/solargraph/location.rb
291
+ - lib/solargraph/logging.rb
295
292
  - lib/solargraph/page.rb
296
293
  - lib/solargraph/pin.rb
297
294
  - lib/solargraph/pin/attribute.rb
@@ -383,6 +380,7 @@ files:
383
380
  - lib/solargraph/views/_name_type_tag.erb
384
381
  - lib/solargraph/views/_namespace.erb
385
382
  - lib/solargraph/views/document.erb
383
+ - lib/solargraph/views/environment.erb
386
384
  - lib/solargraph/views/layout.erb
387
385
  - lib/solargraph/views/search.erb
388
386
  - lib/solargraph/workspace.rb
@@ -1,63 +0,0 @@
1
- require 'thread'
2
-
3
- module Solargraph
4
- module LanguageServer
5
- module Transport
6
- class Stdio
7
- def initialize
8
- # binmode is necessary to avoid EOL conversions
9
- STDOUT.binmode
10
- @host = Solargraph::LanguageServer::Host.new
11
- @data_reader = Solargraph::LanguageServer::Transport::DataReader.new
12
- @data_reader.set_message_handler do |message|
13
- process message
14
- end
15
- end
16
-
17
- def run
18
- start_reader
19
- start_timers
20
- end
21
-
22
- def self.run
23
- std = Stdio.new
24
- std.run
25
- std
26
- end
27
-
28
- private
29
-
30
- def start_reader
31
- Thread.new do
32
- until @host.stopped?
33
- char = STDIN.sysread(1)
34
- break if char.nil?
35
- @data_reader.receive char
36
- STDIN.flush
37
- end
38
- end
39
- end
40
-
41
- def send_data message
42
- STDOUT.write message
43
- STDOUT.flush
44
- end
45
-
46
- def process request
47
- message = @host.start(request)
48
- message.send_response
49
- tmp = @host.flush
50
- send_data tmp unless tmp.empty?
51
- end
52
-
53
- def start_timers
54
- EventMachine.add_periodic_timer 0.1 do
55
- tmp = @host.flush
56
- send_data tmp unless tmp.empty?
57
- EventMachine.stop if @host.stopped?
58
- end
59
- end
60
- end
61
- end
62
- end
63
- end