solargraph 0.17.4 → 0.18.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.
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