solargraph 0.17.4 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/lib/solargraph.rb +16 -12
  3. data/lib/solargraph/api_map.rb +516 -588
  4. data/lib/solargraph/api_map/completion.rb +16 -0
  5. data/lib/solargraph/api_map/source_to_yard.rb +2 -2
  6. data/lib/solargraph/language_server.rb +12 -0
  7. data/lib/solargraph/language_server/completion_item_kinds.rb +31 -0
  8. data/lib/solargraph/language_server/error_codes.rb +16 -0
  9. data/lib/solargraph/language_server/host.rb +305 -0
  10. data/lib/solargraph/language_server/message.rb +70 -0
  11. data/lib/solargraph/language_server/message/base.rb +64 -0
  12. data/lib/solargraph/language_server/message/cancel_request.rb +11 -0
  13. data/lib/solargraph/language_server/message/client.rb +5 -0
  14. data/lib/solargraph/language_server/message/client/register_capability.rb +13 -0
  15. data/lib/solargraph/language_server/message/completion_item.rb +9 -0
  16. data/lib/solargraph/language_server/message/completion_item/resolve.rb +23 -0
  17. data/lib/solargraph/language_server/message/exit_notification.rb +12 -0
  18. data/lib/solargraph/language_server/message/extended.rb +15 -0
  19. data/lib/solargraph/language_server/message/extended/document.rb +18 -0
  20. data/lib/solargraph/language_server/message/extended/search.rb +18 -0
  21. data/lib/solargraph/language_server/message/initialize.rb +39 -0
  22. data/lib/solargraph/language_server/message/initialized.rb +10 -0
  23. data/lib/solargraph/language_server/message/method_not_found.rb +14 -0
  24. data/lib/solargraph/language_server/message/method_not_implemented.rb +12 -0
  25. data/lib/solargraph/language_server/message/shutdown.rb +11 -0
  26. data/lib/solargraph/language_server/message/text_document.rb +21 -0
  27. data/lib/solargraph/language_server/message/text_document/base.rb +17 -0
  28. data/lib/solargraph/language_server/message/text_document/completion.rb +69 -0
  29. data/lib/solargraph/language_server/message/text_document/definition.rb +38 -0
  30. data/lib/solargraph/language_server/message/text_document/did_change.rb +15 -0
  31. data/lib/solargraph/language_server/message/text_document/did_close.rb +12 -0
  32. data/lib/solargraph/language_server/message/text_document/did_open.rb +13 -0
  33. data/lib/solargraph/language_server/message/text_document/did_save.rb +15 -0
  34. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +31 -0
  35. data/lib/solargraph/language_server/message/text_document/formatting.rb +36 -0
  36. data/lib/solargraph/language_server/message/text_document/hover.rb +19 -0
  37. data/lib/solargraph/language_server/message/text_document/on_type_formatting.rb +29 -0
  38. data/lib/solargraph/language_server/message/text_document/signature_help.rb +23 -0
  39. data/lib/solargraph/language_server/message/workspace.rb +11 -0
  40. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +9 -0
  41. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +30 -0
  42. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +31 -0
  43. data/lib/solargraph/language_server/symbol_kinds.rb +32 -0
  44. data/lib/solargraph/language_server/transport.rb +7 -0
  45. data/lib/solargraph/language_server/transport/socket.rb +66 -0
  46. data/lib/solargraph/language_server/uri_helpers.rb +21 -0
  47. data/lib/solargraph/library.rb +225 -0
  48. data/lib/solargraph/live_map.rb +1 -1
  49. data/lib/solargraph/page.rb +61 -0
  50. data/lib/solargraph/pin.rb +7 -0
  51. data/lib/solargraph/pin/attribute.rb +9 -0
  52. data/lib/solargraph/pin/base.rb +76 -6
  53. data/lib/solargraph/pin/base_variable.rb +29 -7
  54. data/lib/solargraph/pin/block_parameter.rb +53 -0
  55. data/lib/solargraph/pin/constant.rb +6 -2
  56. data/lib/solargraph/pin/conversions.rb +65 -0
  57. data/lib/solargraph/pin/directed/attribute.rb +4 -0
  58. data/lib/solargraph/pin/directed/method.rb +6 -1
  59. data/lib/solargraph/pin/helper.rb +35 -0
  60. data/lib/solargraph/pin/keyword.rb +22 -0
  61. data/lib/solargraph/pin/local_variable.rb +0 -1
  62. data/lib/solargraph/pin/method.rb +55 -2
  63. data/lib/solargraph/pin/method_parameter.rb +19 -0
  64. data/lib/solargraph/pin/namespace.rb +7 -2
  65. data/lib/solargraph/pin/parameter.rb +23 -0
  66. data/lib/solargraph/pin/plugin/method.rb +3 -2
  67. data/lib/solargraph/pin/yard_object.rb +101 -0
  68. data/lib/solargraph/server.rb +82 -135
  69. data/lib/solargraph/shell.rb +20 -1
  70. data/lib/solargraph/source.rb +709 -0
  71. data/lib/solargraph/source/flawed_builder.rb +10 -0
  72. data/lib/solargraph/source/fragment.rb +319 -0
  73. data/lib/solargraph/source/position.rb +26 -0
  74. data/lib/solargraph/source/range.rb +39 -0
  75. data/lib/solargraph/suggestion.rb +29 -4
  76. data/lib/solargraph/version.rb +1 -1
  77. data/lib/solargraph/workspace.rb +105 -0
  78. data/lib/solargraph/{api_map → workspace}/config.rb +1 -1
  79. data/lib/solargraph/yard_map.rb +59 -37
  80. metadata +168 -5
  81. data/lib/solargraph/api_map/source.rb +0 -470
  82. data/lib/solargraph/code_map.rb +0 -868
@@ -0,0 +1,35 @@
1
+ require 'yard'
2
+ require 'yard/templates/helpers/markup_helper'
3
+ require 'yard/templates/helpers/html_helper'
4
+
5
+ module Solargraph
6
+ module Pin
7
+ class Helper
8
+ include YARD::Templates::Helpers::HtmlHelper
9
+
10
+ attr_accessor :object
11
+ attr_accessor :serializer
12
+
13
+ def initialize object = nil
14
+ @object = object
15
+ end
16
+
17
+ def url_for(object)
18
+ '.'
19
+ end
20
+
21
+ def options
22
+ if @options.nil?
23
+ @options = YARD::Templates::TemplateOptions.new
24
+ @options.type = :rdoc
25
+ end
26
+ @options
27
+ end
28
+
29
+ # HACK: The linkify method just returns the arguments as plain text
30
+ def linkify *args
31
+ args.join(', ')
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,22 @@
1
+ module Solargraph
2
+ module Pin
3
+ class Keyword < Base
4
+ def initialize name
5
+ @name = name
6
+ end
7
+
8
+ def name
9
+ @name
10
+ end
11
+
12
+ def completion_item_kind
13
+ Solargraph::LanguageServer::CompletionItemKinds::KEYWORD
14
+ end
15
+
16
+ def identifier
17
+ # HACK: A cheap way to make keyword identifiers unique
18
+ object_id
19
+ end
20
+ end
21
+ end
22
+ end
@@ -7,7 +7,6 @@ module Solargraph
7
7
  ancestors.each do |parent|
8
8
  if [:block, :def, :defs, :class, :module, :source].include? parent.type
9
9
  @tree.push parent
10
- break unless parent.type == :block
11
10
  end
12
11
  end
13
12
  end
@@ -8,6 +8,11 @@ module Solargraph
8
8
  super(source, node, namespace)
9
9
  @scope = scope
10
10
  @visibility = visibility
11
+ # Exception for initialize methods
12
+ if name == 'initialize' and scope == :instance
13
+ @visibility = :private
14
+ end
15
+ @fully_resolved = false
11
16
  end
12
17
 
13
18
  def name
@@ -18,13 +23,17 @@ module Solargraph
18
23
  @path ||= namespace + (scope == :instance ? '#' : '.') + name
19
24
  end
20
25
 
21
- def kind
22
- Solargraph::Suggestion::METHOD
26
+ def completion_item_kind
27
+ Solargraph::LanguageServer::CompletionItemKinds::METHOD
23
28
  end
24
29
 
25
30
  def return_type
26
31
  if @return_type.nil? and !docstring.nil?
27
32
  tag = docstring.tag(:return)
33
+ if tag.nil?
34
+ ol = docstring.tag(:overload)
35
+ tag = ol.tag(:return) unless ol.nil?
36
+ end
28
37
  @return_type = tag.types[0] unless tag.nil? or tag.types.nil?
29
38
  end
30
39
  @return_type
@@ -34,10 +43,52 @@ module Solargraph
34
43
  @parameters ||= get_method_args
35
44
  end
36
45
 
46
+ # @todo This method was temporarily migrated directly from Suggestion
47
+ # @return [Array<String>]
48
+ def params
49
+ if @params.nil?
50
+ @params = []
51
+ return @params if docstring.nil?
52
+ param_tags = docstring.tags(:param)
53
+ unless param_tags.empty?
54
+ param_tags.each do |t|
55
+ txt = t.name.to_s
56
+ txt += " [#{t.types.join(',')}]" unless t.types.nil? or t.types.empty?
57
+ txt += " #{t.text}" unless t.text.nil? or t.text.empty?
58
+ @params.push txt
59
+ end
60
+ end
61
+ end
62
+ @params
63
+ end
64
+
65
+ def resolve api_map
66
+ if return_type.nil?
67
+ sc = api_map.superclass_of(namespace)
68
+ until sc.nil?
69
+ sc_path = "#{sc}#{scope == :instance ? '#' : '.'}#{name}"
70
+ sugg = api_map.get_path_suggestions(sc_path).first
71
+ break if sugg.nil?
72
+ @return_type = api_map.find_fully_qualified_namespace(sugg.return_type, sugg.namespace) unless sugg.return_type.nil?
73
+ break unless @return_type.nil?
74
+ sc = api_map.superclass_of(sc)
75
+ end
76
+ end
77
+ unless return_type.nil? or @fully_resolved
78
+ @fully_resolved = true
79
+ @return_type = api_map.find_fully_qualified_namespace(@return_type, namespace)
80
+ end
81
+ end
82
+
83
+ def method?
84
+ true
85
+ end
86
+
37
87
  private
38
88
 
39
89
  # @return [Array<String>]
40
90
  def get_method_args
91
+ return [] if node.nil?
41
92
  list = nil
42
93
  args = []
43
94
  node.children.each { |c|
@@ -58,6 +109,8 @@ module Solargraph
58
109
  args.push "#{c.children[0]}:"
59
110
  elsif c.type == :kwoptarg
60
111
  args.push "#{c.children[0]}: #{source.code_for(c.children[1])}"
112
+ elsif c.type == :blockarg
113
+ args.push "&#{c.children[0]}"
61
114
  end
62
115
  }
63
116
  args
@@ -0,0 +1,19 @@
1
+ module Solargraph
2
+ module Pin
3
+ class MethodParameter < LocalVariable
4
+ def initialize source, node, namespace, ancestors
5
+ super
6
+ # Look for the return type in the method's @param tags
7
+ docstring = source.docstring_for(ancestors.first)
8
+ unless docstring.nil?
9
+ tags = docstring.tags(:param)
10
+ tags.each do |tag|
11
+ if tag.name == name and !tag.types.nil? and !tag.types.empty?
12
+ @return_type = tag.types[0]
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -18,8 +18,13 @@ module Solargraph
18
18
  @path ||= (namespace.empty? ? '' : "#{namespace}::") + name
19
19
  end
20
20
 
21
- def kind
22
- @kind ||= (node.type == :class ? Solargraph::Suggestion::CLASS : Solargraph::Suggestion::MODULE)
21
+ def completion_item_kind
22
+ @kind ||= (node.type == :class ? Solargraph::LanguageServer::CompletionItemKinds::CLASS : Solargraph::LanguageServer::CompletionItemKinds::MODULE)
23
+ end
24
+
25
+ # @return [Symbol] :class or :module
26
+ def type
27
+ node.type
23
28
  end
24
29
 
25
30
  def return_type
@@ -0,0 +1,23 @@
1
+ module Solargraph
2
+ module Pin
3
+ class Parameter < Base
4
+ def initialize source, node, namespace, name, return_type
5
+ super(source, node, namespace)
6
+ @name = name
7
+ @return_type = return_type
8
+ end
9
+
10
+ def name
11
+ @name
12
+ end
13
+
14
+ def return_type
15
+ @return_type
16
+ end
17
+
18
+ def completion_item_kind
19
+ Solargraph::LanguageServer::CompletionItemKinds::PROPERTY
20
+ end
21
+ end
22
+ end
23
+ end
@@ -16,8 +16,9 @@ module Solargraph
16
16
  @parameters = parameters
17
17
  end
18
18
 
19
- def kind
20
- Solargraph::Suggestion::METHOD
19
+ def completion_item_kind
20
+ # Solargraph::Suggestion::METHOD
21
+ Solargraph::LanguageServer::CompletionItemKinds::METHOD
21
22
  end
22
23
  end
23
24
  end
@@ -0,0 +1,101 @@
1
+ module Solargraph
2
+ module Pin
3
+ class YardObject < Base
4
+ COMPLETION_ITEM_KIND_MAP = {
5
+ YARD::CodeObjects::ClassObject => Solargraph::LanguageServer::CompletionItemKinds::CLASS,
6
+ YARD::CodeObjects::ModuleObject => Solargraph::LanguageServer::CompletionItemKinds::MODULE,
7
+ YARD::CodeObjects::MethodObject => Solargraph::LanguageServer::CompletionItemKinds::METHOD,
8
+ YARD::CodeObjects::ConstantObject => Solargraph::LanguageServer::CompletionItemKinds::CONSTANT
9
+ }
10
+
11
+ # @return [YARD::CodeObjects::Base]
12
+ attr_reader :code_object
13
+
14
+ def initialize code_object, location
15
+ # (c.to_s.split('::').last, detail: c.to_s, kind: kind, docstring: c.docstring, return_type: return_type, location: object_location(c))
16
+ @code_object = code_object
17
+ @location = location
18
+ end
19
+
20
+ def name
21
+ # @name ||= code_object.to_s.split('::').last
22
+ @name ||= code_object.name.to_s
23
+ end
24
+
25
+ def completion_item_kind
26
+ @completion_item_kind ||= COMPLETION_ITEM_KIND_MAP[code_object.class] || Solargraph::LanguageServer::CompletionItemKinds::KEYWORD
27
+ end
28
+
29
+ def docstring
30
+ code_object.docstring
31
+ end
32
+
33
+ def return_type
34
+ # @todo Get the return type
35
+ if @return_type.nil?
36
+ if code_object.kind_of?(YARD::CodeObjects::ClassObject)
37
+ @return_type ||= "Class<#{path}>"
38
+ return @return_type
39
+ end
40
+ if code_object.kind_of?(YARD::CodeObjects::ModuleObject)
41
+ @return_type ||= "Module<#{path}>"
42
+ return @return_type
43
+ end
44
+ if Solargraph::CoreFills::CUSTOM_RETURN_TYPES.has_key?(path)
45
+ @return_type = Solargraph::CoreFills::CUSTOM_RETURN_TYPES[path]
46
+ else
47
+ return nil if docstring.nil?
48
+ tags = docstring.tags(:return)
49
+ if tags.empty?
50
+ overload = docstring.tag(:overload)
51
+ return nil if overload.nil?
52
+ tags = overload.tags(:return)
53
+ end
54
+ return nil if tags.empty?
55
+ return nil if tags[0].types.nil?
56
+ @return_type = tags[0].types[0]
57
+ end
58
+ end
59
+ @return_type
60
+ end
61
+
62
+ def location
63
+ # @todo Get the location
64
+ @location
65
+ end
66
+
67
+ def path
68
+ code_object.path
69
+ end
70
+
71
+ def namespace
72
+ # @todo Is this right?
73
+ code_object.namespace.to_s
74
+ end
75
+
76
+ def parameters
77
+ @parameters ||= get_method_args
78
+ end
79
+
80
+ def method?
81
+ completion_item_kind == Solargraph::LanguageServer::CompletionItemKinds::METHOD
82
+ end
83
+
84
+ private
85
+
86
+ def get_method_args
87
+ return [] unless code_object.kind_of?(YARD::CodeObjects::MethodObject)
88
+ args = []
89
+ code_object.parameters.each { |a|
90
+ p = a[0]
91
+ unless a[1].nil?
92
+ p += ' =' unless p.end_with?(':')
93
+ p += " #{a[1]}"
94
+ end
95
+ args.push p
96
+ }
97
+ args
98
+ end
99
+ end
100
+ end
101
+ end
@@ -1,6 +1,8 @@
1
1
  require 'sinatra/base'
2
2
  require 'thread'
3
3
  require 'yard'
4
+ require 'open3'
5
+ require 'shellwords'
4
6
 
5
7
  module Solargraph
6
8
  class Server < Sinatra::Base
@@ -8,9 +10,11 @@ module Solargraph
8
10
  set :port, 7657
9
11
  set :server, :webrick
10
12
 
11
- @@api_hash = {}
13
+ # @@api_hash = {}
12
14
  @@semaphore = Mutex.new
13
15
 
16
+ @@library = Solargraph::Library.new
17
+
14
18
  after do
15
19
  GC.start
16
20
  end
@@ -20,10 +24,57 @@ module Solargraph
20
24
  @@semaphore.unlock
21
25
  end
22
26
 
27
+ post '/diagnostics' do
28
+ content_type :json
29
+ severities = {
30
+ 'refactor' => 4,
31
+ 'convention' => 3,
32
+ 'warning' => 2,
33
+ 'error' => 1,
34
+ 'fatal' => 1
35
+ }
36
+ begin
37
+ filename = params['filename']
38
+ text = params['text']
39
+ o, e, s = Open3.capture3("bundle exec rubocop -f j -s #{Shellwords.escape(filename)}", stdin_data: text)
40
+ STDERR.puts e unless e.nil? or e.empty?
41
+ resp = JSON.parse(o)
42
+ diagnostics = []
43
+ if resp['summary']['offense_count'] > 0
44
+ resp['files'].each do |file|
45
+ file['offenses'].each do |off|
46
+ diag = {
47
+ range: {
48
+ start: {
49
+ line: off['location']['start_line'] - 1,
50
+ character: off['location']['start_column'] - 1
51
+ },
52
+ end: {
53
+ line: off['location']['last_line'] - 1,
54
+ character: off['location']['last_column']
55
+ }
56
+ },
57
+ # 1 = Error, 2 = Warning, 3 = Information, 4 = Hint
58
+ severity: severities[off['severity']],
59
+ source: off['cop_name'],
60
+ message: off['message'].gsub(/^#{off['cop_name']}\:/, '')
61
+ }
62
+ diagnostics.push diag
63
+ end
64
+ end
65
+ end
66
+ { "status" => "ok", "data" => diagnostics }.to_json
67
+ rescue Exception => e
68
+ send_exception e
69
+ end
70
+ end
71
+
23
72
  post '/prepare' do
24
73
  content_type :json
25
74
  begin
26
- Server.prepare_workspace params['workspace']
75
+ workspace = params['workspace'].to_s.gsub(/\\/, '/')
76
+ STDERR.puts "Preparing #{workspace}"
77
+ @@library = Solargraph::Library.load(workspace) unless workspace.empty?
27
78
  { "status" => "ok"}.to_json
28
79
  rescue Exception => e
29
80
  send_exception e
@@ -33,12 +84,8 @@ module Solargraph
33
84
  post '/update' do
34
85
  content_type :json
35
86
  begin
36
- workspace = find_local_workspace(params['filename'], params['workspace'])
37
- # @type [Solargraph::ApiMap]
38
- api_map = get_api_map(workspace)
39
- unless api_map.nil?
40
- api_map.update params['filename']
41
- end
87
+ filename = params['filename'].to_s.gsub(/\\/, '/')
88
+ @@library.open filename, File.read(filename), 0
42
89
  { "status" => "ok"}.to_json
43
90
  rescue Exception => e
44
91
  send_exception e
@@ -48,14 +95,13 @@ module Solargraph
48
95
  post '/suggest' do
49
96
  content_type :json
50
97
  begin
51
- sugg = []
52
- workspace = find_local_workspace(params['filename'], params['workspace'])
53
- api_map = get_api_map(workspace)
98
+ filename = params['filename'].to_s.gsub(/\\/, '/')
99
+ @@library.open filename, params['text'], 0
100
+ @@library.checkout filename
101
+ @@library.refresh
54
102
  with_all = params['all'] == '1' ? true : false
55
- code_map = CodeMap.new(code: params['text'], filename: params['filename'], api_map: api_map, cursor: [params['line'].to_i, params['column'].to_i])
56
- offset = code_map.get_offset(params['line'].to_i, params['column'].to_i)
57
- sugg = code_map.suggest_at(offset, filtered: true)
58
- JSON.generate({ "status" => "ok", "suggestions" => sugg.map{|s| s.as_json(all: with_all)} })
103
+ completion = @@library.completions_at(filename, params['line'].to_i, params['column'].to_i)
104
+ JSON.generate({ "status" => "ok", "suggestions" => completion.pins.map{|s| Suggestion.pull(s).as_json(all: with_all)} })
59
105
  rescue Exception => e
60
106
  send_exception e
61
107
  end
@@ -64,13 +110,12 @@ module Solargraph
64
110
  post '/signify' do
65
111
  content_type :json
66
112
  begin
67
- sugg = []
68
- workspace = find_local_workspace(params['filename'], params['workspace'])
69
- api_map = get_api_map(workspace)
70
- code_map = CodeMap.new(code: params['text'], filename: params['filename'], api_map: api_map, cursor: [params['line'].to_i, params['column'].to_i])
71
- offset = code_map.get_offset(params['line'].to_i, params['column'].to_i)
72
- sugg = code_map.signatures_at(offset)
73
- { "status" => "ok", "suggestions" => sugg.map{|s| s.as_json(all: true)} }.to_json
113
+ filename = params['filename'].to_s.gsub(/\\/, '/')
114
+ @@library.open filename, params['text'], 0
115
+ @@library.checkout filename
116
+ @@library.refresh
117
+ sugg = @@library.signatures_at(filename, params['line'].to_i, params['column'].to_i)
118
+ { "status" => "ok", "suggestions" => sugg.map{|s| Suggestion.pull(s).as_json(all: true)} }.to_json
74
119
  rescue Exception => e
75
120
  send_exception e
76
121
  end
@@ -79,14 +124,8 @@ module Solargraph
79
124
  post '/resolve' do
80
125
  content_type :json
81
126
  begin
82
- workspace = find_local_workspace(params['filename'], params['workspace'])
83
- result = []
84
- api_map = get_api_map(workspace)
85
- unless api_map.nil?
86
- # @todo Get suggestions that match the path
87
- result.concat api_map.get_path_suggestions(params['path'])
88
- end
89
- { "status" => "ok", "suggestions" => result.map{|s| s.as_json(all: true)} }.to_json
127
+ result = @@library.get_path_pins(params['path'])
128
+ { "status" => "ok", "suggestions" => result.map{|s| Suggestion.pull(s).as_json(all: true)} }.to_json
90
129
  rescue Exception => e
91
130
  send_exception e
92
131
  end
@@ -95,13 +134,11 @@ module Solargraph
95
134
  post '/define' do
96
135
  content_type :json
97
136
  begin
98
- sugg = []
99
- workspace = find_local_workspace(params['filename'], params['workspace'])
100
- api_map = get_api_map(workspace)
101
- code_map = CodeMap.new(code: params['text'], filename: params['filename'], api_map: api_map, cursor: [params['line'].to_i, params['column'].to_i])
102
- offset = code_map.get_offset(params['line'].to_i, params['column'].to_i)
103
- sugg = code_map.define_symbol_at(offset)
104
- { "status" => "ok", "suggestions" => sugg }.to_json
137
+ filename = params['filename'].to_s.gsub(/\\/, '/')
138
+ @@library.open filename, params['text'], 0
139
+ @@library.checkout filename
140
+ sugg = @@library.definitions_at(filename, params['line'].to_i, params['column'].to_i)
141
+ { "status" => "ok", "suggestions" => sugg.map{|s| Suggestion.pull(s).as_json(all: true)} }.to_json
105
142
  rescue Exception => e
106
143
  send_exception e
107
144
  end
@@ -111,48 +148,27 @@ module Solargraph
111
148
  post '/hover' do
112
149
  content_type :json
113
150
  begin
114
- sugg = []
115
- workspace = find_local_workspace(params['filename'], params['workspace'])
116
- api_map = get_api_map(workspace)
117
- code_map = CodeMap.new(code: params['text'], filename: params['filename'], api_map: @@api_hash[workspace], cursor: [params['line'].to_i, params['column'].to_i])
118
- offset = code_map.get_offset(params['line'].to_i, params['column'].to_i)
119
- sugg = code_map.resolve_object_at(offset)
120
- { "status" => "ok", "suggestions" => sugg }.to_json
151
+ filename = params['filename'].to_s.gsub(/\\/, '/')
152
+ @@library.open filename, params['text'], 0
153
+ @@library.refresh
154
+ @@library.checkout filename
155
+ sugg = @@library.definitions_at(filename, params['line'].to_i, params['column'].to_i)
156
+ { "status" => "ok", "suggestions" => sugg.map{|s| Suggestion.pull(s).as_json(all: true)} }.to_json
121
157
  rescue Exception => e
122
158
  send_exception e
123
159
  end
124
160
  end
125
161
 
126
162
  get '/search' do
127
- workspace = params['workspace']
128
- api_map = get_api_map(workspace) || Solargraph::ApiMap.new
129
- @results = api_map.search(params['query'])
163
+ @results = @@library.search(params['query'])
130
164
  erb :search
131
165
  end
132
166
 
133
167
  get '/document' do
134
- workspace = params['workspace']
135
- workspace.gsub!(/\\/, '/') unless workspace.nil?
136
- api_map = get_api_map(workspace) || Solargraph::ApiMap.new
137
- @objects = api_map.document(params['query'])
168
+ @objects = @@library.document(params['query'])
138
169
  erb :document
139
170
  end
140
171
 
141
- # @return [Solargraph::ApiMap]
142
- def self.get_api_map workspace
143
- api_map = nil
144
- @@semaphore.synchronize {
145
- @@api_hash[nil] ||= Solargraph::ApiMap.new if workspace.nil?
146
- api_map = @@api_hash[workspace]
147
- }
148
- api_map
149
- end
150
-
151
- # @return [Solargraph::ApiMap]
152
- def get_api_map workspace
153
- Server.get_api_map workspace
154
- end
155
-
156
172
  def htmlify text
157
173
  rdoc_to_html text
158
174
  end
@@ -173,75 +189,6 @@ module Solargraph
173
189
  { "status" => "err", "message" => e.message + "\n" + e.backtrace.join("\n") }.to_json
174
190
  end
175
191
 
176
- def find_local_workspace file, workspace
177
- return nil if workspace.nil? or workspace.empty?
178
- workspace.gsub!(/\\/, '/') unless workspace.nil?
179
- unless file.nil? or workspace.nil?
180
- file.gsub!(/\\/, '/') unless file.nil?
181
- return nil unless file.start_with?(workspace)
182
- dir = File.dirname(file)
183
- while dir.start_with?(workspace)
184
- return dir if @@api_hash.has_key?(dir)
185
- dir = File.dirname(dir)
186
- end
187
- end
188
- workspace
189
- end
190
-
191
- class << self
192
- def prepare_workspace directory
193
- return if directory.nil?
194
- #Thread.new do
195
- directory.gsub!(/\\/, '/')
196
- STDERR.puts "Preparing #{directory}"
197
- configs = Dir[File.join(directory, '**', '.solargraph.yml')]
198
- resolved = []
199
- configs.each do |cf|
200
- dir = File.dirname(cf)
201
- generate_api_map dir
202
- resolved.push dir
203
- end
204
- generate_api_map directory unless resolved.include?(directory)
205
- #end
206
- end
207
-
208
- def generate_api_map(directory)
209
- api_map = Solargraph::ApiMap.new(directory)
210
- @@semaphore.synchronize do
211
- @@api_hash[directory] = api_map
212
- end
213
- end
214
-
215
- def run!
216
- # @todo The thread for checking workspaces is temporarily disabled due
217
- # to high CPU cost. We need to determine whether the process should
218
- # be optimized or eliminated altogether.
219
- #
220
- # Thread.new do
221
- # while true
222
- # check_workspaces
223
- # sleep 1
224
- # end
225
- # end
226
- super
227
- end
228
-
229
- def check_workspaces
230
- @@semaphore.synchronize do
231
- changed = {}
232
- @@api_hash.each_pair do |w, a|
233
- next unless a.changed?
234
- STDERR.puts "Reloading changed workspace #{w}"
235
- n = Solargraph::ApiMap.new(w)
236
- changed[w] = n
237
- end
238
- changed.each_pair do |w, a|
239
- @@api_hash[w] = a
240
- end
241
- end
242
- end
243
- end
244
-
245
192
  class Helpers
246
193
  include YARD::Templates::Helpers::HtmlHelper
247
194