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
@@ -107,7 +107,7 @@ module Solargraph
107
107
  # @return [Array<Solargraph::Plugin::Base>]
108
108
  def load_runners
109
109
  result = []
110
- api_map.config.plugins.each do |name|
110
+ api_map.workspace.config.plugins.each do |name|
111
111
  r = @@plugin_registry[name].new(api_map)
112
112
  result.push r
113
113
  end
@@ -0,0 +1,61 @@
1
+ require 'ostruct'
2
+ require 'tilt'
3
+ require 'redcarpet'
4
+ require 'htmlentities'
5
+ require 'coderay'
6
+
7
+ module Solargraph
8
+ class Page
9
+ class SolargraphRenderer < Redcarpet::Render::HTML
10
+ def normal_text text
11
+ HTMLEntities.new.encode(text, :named)
12
+ end
13
+ def block_code code, language
14
+ CodeRay.scan(code, language || :ruby).div
15
+ end
16
+ end
17
+ private_constant :SolargraphRenderer
18
+
19
+ class Binder < OpenStruct
20
+ def initialize locals, render_method
21
+ super(locals)
22
+ define_singleton_method :render do |template, layout: false, locals: {}|
23
+ render_method.call(template, layout: layout, locals: locals)
24
+ end
25
+ define_singleton_method :erb do |template, layout: false, locals: {}|
26
+ render_method.call(template, layout: layout, locals: locals)
27
+ end
28
+ end
29
+
30
+ def htmlify text
31
+ helper = Solargraph::Pin::Helper.new
32
+ html = helper.html_markup_rdoc(text)
33
+ conv = ReverseMarkdown.convert(html, github_flavored: true)
34
+ markdown = Redcarpet::Markdown.new(SolargraphRenderer.new(prettify: true), fenced_code_blocks: true)
35
+ markdown.render(conv)
36
+ end
37
+
38
+ def ruby_to_html code
39
+ code
40
+ end
41
+ end
42
+ private_constant :Binder
43
+
44
+ def initialize directory
45
+ @render_method = proc { |template, layout: false, locals: {}|
46
+ binder = Binder.new(locals, @render_method)
47
+ if layout
48
+ Tilt::ERBTemplate.new(File.join(directory, 'layout.erb')).render(binder) do
49
+ Tilt::ERBTemplate.new(File.join(directory, "#{template}.erb")).render(binder)
50
+ end
51
+ else
52
+ Tilt::ERBTemplate.new(File.join(directory, "#{template}.erb")).render(binder)
53
+ end
54
+ }
55
+ end
56
+
57
+ def render template, layout: true, locals: {}
58
+ @render_method.call(template, layout: layout, locals: locals)
59
+ end
60
+ end
61
+ end
@@ -1,5 +1,7 @@
1
1
  module Solargraph
2
2
  module Pin
3
+ autoload :Helper, 'solargraph/pin/helper'
4
+ autoload :Conversions, 'solargraph/pin/conversions'
3
5
  autoload :Base, 'solargraph/pin/base'
4
6
  autoload :Method, 'solargraph/pin/method'
5
7
  autoload :Attribute, 'solargraph/pin/attribute'
@@ -12,5 +14,10 @@ module Solargraph
12
14
  autoload :Symbol, 'solargraph/pin/symbol'
13
15
  autoload :Directed, 'solargraph/pin/directed'
14
16
  autoload :Namespace, 'solargraph/pin/namespace'
17
+ autoload :YardObject, 'solargraph/pin/yard_object'
18
+ autoload :Keyword, 'solargraph/pin/keyword'
19
+ autoload :Parameter, 'solargraph/pin/parameter'
20
+ autoload :MethodParameter, 'solargraph/pin/method_parameter'
21
+ autoload :BlockParameter, 'solargraph/pin/block_parameter'
15
22
  end
16
23
  end
@@ -1,6 +1,7 @@
1
1
  module Solargraph
2
2
  module Pin
3
3
  class Attribute < Base
4
+ # @return [Symbol] :reader or :writer
4
5
  attr_reader :access
5
6
 
6
7
  def initialize source, node, namespace, access, docstring
@@ -24,6 +25,14 @@ module Solargraph
24
25
  end
25
26
  @return_type
26
27
  end
28
+
29
+ def completion_item_kind
30
+ Solargraph::LanguageServer::CompletionItemKinds::PROPERTY
31
+ end
32
+
33
+ def method?
34
+ true
35
+ end
27
36
  end
28
37
  end
29
38
  end
@@ -1,7 +1,11 @@
1
+ require 'reverse_markdown'
2
+
1
3
  module Solargraph
2
4
  module Pin
3
5
  class Base
4
- # @return [Solargraph::ApiMap::Source]
6
+ include Conversions
7
+
8
+ # @return [Solargraph::Source]
5
9
  attr_reader :source
6
10
 
7
11
  # @return [Parser::AST::Node]
@@ -16,9 +20,23 @@ module Solargraph
16
20
  @namespace = namespace
17
21
  end
18
22
 
23
+ def contain?(index)
24
+ if index >= node.loc.expression.begin_pos
25
+ if node.respond_to?(:end)
26
+ if index < node.end.end_pos
27
+ return true
28
+ end
29
+ elsif index < node.loc.expression.end_pos
30
+ return true
31
+ end
32
+ end
33
+ false
34
+ end
35
+
19
36
  # @return [YARD::Docstring]
20
37
  def docstring
21
- @docstring ||= source.docstring_for(node)
38
+ @docstring ||= source.docstring_for(node) unless source.nil?
39
+ @docstring
22
40
  end
23
41
 
24
42
  # @return [String]
@@ -31,9 +49,17 @@ module Solargraph
31
49
  nil
32
50
  end
33
51
 
34
- # @return [String]
52
+ # @return [Integer]
53
+ def completion_item_kind
54
+ end
55
+
56
+ # @return [Integer]
57
+ def symbol_kind
58
+ end
59
+
60
+ # @return [Integer]
35
61
  def kind
36
- nil
62
+ completion_item_kind
37
63
  end
38
64
 
39
65
  # @return [String]
@@ -56,13 +82,57 @@ module Solargraph
56
82
  []
57
83
  end
58
84
 
85
+ def arguments
86
+ parameters
87
+ end
88
+
59
89
  # @return [String]
60
90
  def filename
61
- source.filename
91
+ source.filename unless source.nil?
62
92
  end
63
93
 
64
94
  def location
65
- "#{source.filename}:#{node.location.expression.line - 1}:#{node.location.expression.column}"
95
+ "#{source.filename}:#{node.location.expression.line - 1}:#{node.location.expression.column}" unless source.nil? or node.nil?
96
+ end
97
+
98
+ # @return [String]
99
+ def documentation
100
+ if @documentation.nil? and !docstring.nil?
101
+ @documentation = ReverseMarkdown.convert(helper.html_markup_rdoc(docstring), github_flavored: true)
102
+ end
103
+ @documentation
104
+ end
105
+
106
+ # True if the suggestion has documentation.
107
+ # Useful for determining whether a client should resolve a suggestion's
108
+ # path to retrieve more information about it.
109
+ #
110
+ # @return [Boolean]
111
+ def has_doc?
112
+ !docstring.nil? and !docstring.all.empty?
113
+ end
114
+
115
+ def helper
116
+ @helper ||= Solargraph::Pin::Helper.new
117
+ end
118
+
119
+ def to_s
120
+ name.to_s
121
+ end
122
+
123
+ def resolve api_map
124
+ end
125
+
126
+ def identifier
127
+ @identifier ||= "#{path || location}"
128
+ end
129
+
130
+ def variable?
131
+ false
132
+ end
133
+
134
+ def method?
135
+ false
66
136
  end
67
137
  end
68
138
  end
@@ -3,20 +3,30 @@ module Solargraph
3
3
  class BaseVariable < Base
4
4
  include NodeMethods
5
5
 
6
+ def initialize source, node, namespace
7
+ super
8
+ @tried_to_detect_return_type = false
9
+ end
10
+
6
11
  def name
7
12
  node.children[0].to_s
8
13
  end
9
14
 
10
- def kind
11
- Solargraph::Suggestion::VARIABLE
15
+ def completion_item_kind
16
+ Solargraph::LanguageServer::CompletionItemKinds::VARIABLE
12
17
  end
13
18
 
14
19
  def return_type
15
- if @return_type.nil? and !docstring.nil?
16
- tag = docstring.tag(:type)
17
- @return_type = tag.types[0] unless tag.nil?
20
+ if @return_type.nil? and !@tried_to_detect_return_type
21
+ @tried_to_detect_return_type = true
22
+ if docstring.nil?
23
+ @return_type ||= literal_from_assignment
24
+ else
25
+ tag = docstring.tag(:type)
26
+ @return_type = tag.types[0] unless tag.nil?
27
+ end
18
28
  end
19
- @return_type ||= literal_from_assignment
29
+ @return_type
20
30
  end
21
31
 
22
32
  def assignment_node
@@ -28,7 +38,19 @@ module Solargraph
28
38
  end
29
39
 
30
40
  def signature
31
- @signature ||= resolve_node_signature(node.children[(node.type == :casgn ? 2 : 1)])
41
+ @signature ||= resolve_node_signature(assignment_node)
42
+ end
43
+
44
+ # @param api_map [Solargraph::ApiMap]
45
+ def resolve api_map
46
+ if return_type.nil?
47
+ return nil if signature.nil? or signature.empty? or signature == name or signature.split('.').first.strip == name
48
+ @return_type = api_map.infer_signature_type(signature, namespace, call_node: node)
49
+ end
50
+ end
51
+
52
+ def variable?
53
+ true
32
54
  end
33
55
 
34
56
  private
@@ -0,0 +1,53 @@
1
+ module Solargraph
2
+ module Pin
3
+ class BlockParameter < LocalVariable
4
+ attr_reader :index
5
+
6
+ def initialize source, node, namespace, ancestors, index
7
+ super(source, node, namespace, ancestors)
8
+ @index = index
9
+ docstring = source.docstring_for(ancestors.first)
10
+ unless docstring.nil?
11
+ tags = docstring.tags(:param)
12
+ tags.each do |tag|
13
+ if tag.name == name and !tag.types.nil? and !tag.types.empty?
14
+ @return_type = tag.types[0]
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ # @param api_map [Solargraph::ApiMap]
21
+ def resolve api_map
22
+ return unless return_type.nil?
23
+ signature = resolve_node_signature(@tree[0].children[0])
24
+ meth = api_map.infer_signature_pins(signature, namespace, :class, node).first
25
+ return nil if meth.nil?
26
+ if (Solargraph::CoreFills::METHODS_WITH_YIELDPARAM_SUBTYPES.include?(meth.path))
27
+ base = signature.split('.')[0..-2].join('.')
28
+ return nil if base.nil? or base.empty?
29
+ bmeth = api_map.infer_signature_pins(base, namespace, :class, node).first
30
+ return nil if bmeth.nil?
31
+ subtypes = get_subtypes(bmeth.return_type)
32
+ @return_type = api_map.find_fully_qualified_namespace(subtypes[0], namespace)
33
+ else
34
+ unless meth.docstring.nil?
35
+ yps = meth.docstring.tags(:yieldparam)
36
+ unless yps[index].nil? or yps[index].types.nil? or yps[index].types.empty?
37
+ @return_type = yps[index].types[0]
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def get_subtypes type
46
+ return nil if type.nil?
47
+ match = type.match(/<([a-z0-9_:, ]*)>/i)
48
+ return [] if match.nil?
49
+ match[1].split(',').map(&:strip)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -12,13 +12,17 @@ module Solargraph
12
12
  @name ||= node.children[1].to_s
13
13
  end
14
14
 
15
- def kind
16
- Solargraph::Suggestion::CONSTANT
15
+ def completion_item_kind
16
+ Solargraph::LanguageServer::CompletionItemKinds::CONSTANT
17
17
  end
18
18
 
19
19
  def value
20
20
  source.code_for(node.children[2])
21
21
  end
22
+
23
+ def path
24
+ "#{namespace}::#{name}"
25
+ end
22
26
  end
23
27
  end
24
28
  end
@@ -0,0 +1,65 @@
1
+ module Solargraph
2
+ module Pin
3
+ module Conversions
4
+ # @return [Hash]
5
+ def completion_item
6
+ {
7
+ label: name,
8
+ kind: kind,
9
+ detail: completion_item_detail,
10
+ data: {
11
+ path: path,
12
+ return_type: return_type,
13
+ location: location
14
+ }
15
+ }
16
+ end
17
+
18
+ # @return [Hash]
19
+ def resolve_completion_item
20
+ extra = {}
21
+ alldoc = ''
22
+ alldoc += link_documentation(path) unless path.nil?
23
+ alldoc += "\n\n" unless alldoc.empty?
24
+ alldoc += documentation unless documentation.nil?
25
+ extra[:documentation] = alldoc unless alldoc.empty?
26
+ completion_item.merge(extra)
27
+ end
28
+
29
+ # @param api_map [Solargraph::ApiMap]
30
+ def hover
31
+ info = ''
32
+ if self.kind_of?(Solargraph::Pin::BaseVariable)
33
+ info.concat link_documentation(return_type) unless return_type.nil?
34
+ else
35
+ info.concat link_documentation(path) unless path.nil?
36
+ end
37
+ info.concat "\n\n#{documentation}"
38
+ info
39
+ end
40
+
41
+ # @return [Hash]
42
+ def signature_help
43
+ {
44
+ label: name + '(' + arguments.join(', ') + ')',
45
+ documentation: documentation
46
+ }
47
+ end
48
+
49
+ private
50
+
51
+ def completion_item_detail
52
+ detail = ''
53
+ detail += "(#{parameters.join(', ')}) " unless parameters.empty?
54
+ detail += "=> #{return_type}" unless return_type.nil?
55
+ return nil if detail.empty?
56
+ detail
57
+ end
58
+
59
+ def link_documentation path
60
+ uri = "solargraph:/document?query=" + URI.encode(path)
61
+ "[#{path}](#{uri})"
62
+ end
63
+ end
64
+ end
65
+ end
@@ -10,6 +10,10 @@ module Solargraph
10
10
  def name
11
11
  @name
12
12
  end
13
+
14
+ def completion_item_kind
15
+ Solargraph::LanguageServer::CompletionItemKinds::METHOD
16
+ end
13
17
  end
14
18
  end
15
19
  end
@@ -2,15 +2,20 @@ module Solargraph
2
2
  module Pin
3
3
  module Directed
4
4
  class Method < Solargraph::Pin::Method
5
- def initialize source, node, namespace, scope, visibility, docstring, name
5
+ def initialize source, node, namespace, scope, visibility, docstring, name, return_type = nil
6
6
  super(source, node, namespace, scope, visibility)
7
7
  @docstring = docstring
8
8
  @name = name
9
+ @return_type = return_type
9
10
  end
10
11
 
11
12
  def name
12
13
  @name
13
14
  end
15
+
16
+ def completion_item_kind
17
+ Solargraph::LanguageServer::CompletionItemKinds::METHOD
18
+ end
14
19
  end
15
20
  end
16
21
  end