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
@@ -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