solargraph 0.39.7

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 (252) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +28 -0
  5. data/.yardopts +2 -0
  6. data/Gemfile +7 -0
  7. data/LICENSE +21 -0
  8. data/README.md +104 -0
  9. data/Rakefile +14 -0
  10. data/SPONSORS.md +9 -0
  11. data/bin/solargraph +5 -0
  12. data/lib/.rubocop.yml +21 -0
  13. data/lib/solargraph.rb +66 -0
  14. data/lib/solargraph/api_map.rb +745 -0
  15. data/lib/solargraph/api_map/bundler_methods.rb +27 -0
  16. data/lib/solargraph/api_map/cache.rb +66 -0
  17. data/lib/solargraph/api_map/source_to_yard.rb +81 -0
  18. data/lib/solargraph/api_map/store.rb +267 -0
  19. data/lib/solargraph/bundle.rb +26 -0
  20. data/lib/solargraph/complex_type.rb +213 -0
  21. data/lib/solargraph/complex_type/type_methods.rb +127 -0
  22. data/lib/solargraph/complex_type/unique_type.rb +75 -0
  23. data/lib/solargraph/convention.rb +38 -0
  24. data/lib/solargraph/convention/base.rb +25 -0
  25. data/lib/solargraph/convention/gemfile.rb +18 -0
  26. data/lib/solargraph/convention/gemspec.rb +25 -0
  27. data/lib/solargraph/convention/rspec.rb +24 -0
  28. data/lib/solargraph/converters/dd.rb +12 -0
  29. data/lib/solargraph/converters/dl.rb +12 -0
  30. data/lib/solargraph/converters/dt.rb +12 -0
  31. data/lib/solargraph/converters/misc.rb +1 -0
  32. data/lib/solargraph/core_fills.rb +159 -0
  33. data/lib/solargraph/diagnostics.rb +55 -0
  34. data/lib/solargraph/diagnostics/base.rb +29 -0
  35. data/lib/solargraph/diagnostics/require_not_found.rb +37 -0
  36. data/lib/solargraph/diagnostics/rubocop.rb +90 -0
  37. data/lib/solargraph/diagnostics/rubocop_helpers.rb +64 -0
  38. data/lib/solargraph/diagnostics/severities.rb +15 -0
  39. data/lib/solargraph/diagnostics/type_check.rb +54 -0
  40. data/lib/solargraph/diagnostics/update_errors.rb +41 -0
  41. data/lib/solargraph/documentor.rb +76 -0
  42. data/lib/solargraph/environ.rb +40 -0
  43. data/lib/solargraph/language_server.rb +19 -0
  44. data/lib/solargraph/language_server/completion_item_kinds.rb +35 -0
  45. data/lib/solargraph/language_server/error_codes.rb +20 -0
  46. data/lib/solargraph/language_server/host.rb +741 -0
  47. data/lib/solargraph/language_server/host/cataloger.rb +56 -0
  48. data/lib/solargraph/language_server/host/diagnoser.rb +81 -0
  49. data/lib/solargraph/language_server/host/dispatch.rb +112 -0
  50. data/lib/solargraph/language_server/host/sources.rb +156 -0
  51. data/lib/solargraph/language_server/message.rb +92 -0
  52. data/lib/solargraph/language_server/message/base.rb +85 -0
  53. data/lib/solargraph/language_server/message/cancel_request.rb +13 -0
  54. data/lib/solargraph/language_server/message/client.rb +11 -0
  55. data/lib/solargraph/language_server/message/client/register_capability.rb +15 -0
  56. data/lib/solargraph/language_server/message/completion_item.rb +11 -0
  57. data/lib/solargraph/language_server/message/completion_item/resolve.rb +57 -0
  58. data/lib/solargraph/language_server/message/exit_notification.rb +13 -0
  59. data/lib/solargraph/language_server/message/extended.rb +21 -0
  60. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +95 -0
  61. data/lib/solargraph/language_server/message/extended/document.rb +20 -0
  62. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -0
  63. data/lib/solargraph/language_server/message/extended/download_core.rb +23 -0
  64. data/lib/solargraph/language_server/message/extended/environment.rb +25 -0
  65. data/lib/solargraph/language_server/message/extended/search.rb +20 -0
  66. data/lib/solargraph/language_server/message/initialize.rb +153 -0
  67. data/lib/solargraph/language_server/message/initialized.rb +26 -0
  68. data/lib/solargraph/language_server/message/method_not_found.rb +16 -0
  69. data/lib/solargraph/language_server/message/method_not_implemented.rb +14 -0
  70. data/lib/solargraph/language_server/message/shutdown.rb +13 -0
  71. data/lib/solargraph/language_server/message/text_document.rb +28 -0
  72. data/lib/solargraph/language_server/message/text_document/base.rb +19 -0
  73. data/lib/solargraph/language_server/message/text_document/code_action.rb +17 -0
  74. data/lib/solargraph/language_server/message/text_document/completion.rb +57 -0
  75. data/lib/solargraph/language_server/message/text_document/definition.rb +38 -0
  76. data/lib/solargraph/language_server/message/text_document/did_change.rb +15 -0
  77. data/lib/solargraph/language_server/message/text_document/did_close.rb +15 -0
  78. data/lib/solargraph/language_server/message/text_document/did_open.rb +15 -0
  79. data/lib/solargraph/language_server/message/text_document/did_save.rb +17 -0
  80. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +23 -0
  81. data/lib/solargraph/language_server/message/text_document/folding_range.rb +26 -0
  82. data/lib/solargraph/language_server/message/text_document/formatting.rb +78 -0
  83. data/lib/solargraph/language_server/message/text_document/hover.rb +44 -0
  84. data/lib/solargraph/language_server/message/text_document/on_type_formatting.rb +34 -0
  85. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +11 -0
  86. data/lib/solargraph/language_server/message/text_document/references.rb +16 -0
  87. data/lib/solargraph/language_server/message/text_document/rename.rb +19 -0
  88. data/lib/solargraph/language_server/message/text_document/signature_help.rb +29 -0
  89. data/lib/solargraph/language_server/message/workspace.rb +14 -0
  90. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +29 -0
  91. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +33 -0
  92. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +24 -0
  93. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -0
  94. data/lib/solargraph/language_server/message_types.rb +14 -0
  95. data/lib/solargraph/language_server/request.rb +24 -0
  96. data/lib/solargraph/language_server/symbol_kinds.rb +36 -0
  97. data/lib/solargraph/language_server/transport.rb +13 -0
  98. data/lib/solargraph/language_server/transport/adapter.rb +56 -0
  99. data/lib/solargraph/language_server/transport/data_reader.rb +72 -0
  100. data/lib/solargraph/language_server/uri_helpers.rb +49 -0
  101. data/lib/solargraph/library.rb +414 -0
  102. data/lib/solargraph/location.rb +37 -0
  103. data/lib/solargraph/logging.rb +27 -0
  104. data/lib/solargraph/page.rb +83 -0
  105. data/lib/solargraph/parser.rb +26 -0
  106. data/lib/solargraph/parser/comment_ripper.rb +52 -0
  107. data/lib/solargraph/parser/legacy.rb +12 -0
  108. data/lib/solargraph/parser/legacy/class_methods.rb +109 -0
  109. data/lib/solargraph/parser/legacy/flawed_builder.rb +16 -0
  110. data/lib/solargraph/parser/legacy/node_chainer.rb +118 -0
  111. data/lib/solargraph/parser/legacy/node_methods.rb +300 -0
  112. data/lib/solargraph/parser/legacy/node_processors.rb +54 -0
  113. data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +23 -0
  114. data/lib/solargraph/parser/legacy/node_processors/args_node.rb +35 -0
  115. data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +15 -0
  116. data/lib/solargraph/parser/legacy/node_processors/block_node.rb +22 -0
  117. data/lib/solargraph/parser/legacy/node_processors/casgn_node.rb +25 -0
  118. data/lib/solargraph/parser/legacy/node_processors/cvasgn_node.rb +23 -0
  119. data/lib/solargraph/parser/legacy/node_processors/def_node.rb +63 -0
  120. data/lib/solargraph/parser/legacy/node_processors/defs_node.rb +36 -0
  121. data/lib/solargraph/parser/legacy/node_processors/gvasgn_node.rb +23 -0
  122. data/lib/solargraph/parser/legacy/node_processors/ivasgn_node.rb +38 -0
  123. data/lib/solargraph/parser/legacy/node_processors/lvasgn_node.rb +28 -0
  124. data/lib/solargraph/parser/legacy/node_processors/namespace_node.rb +39 -0
  125. data/lib/solargraph/parser/legacy/node_processors/orasgn_node.rb +16 -0
  126. data/lib/solargraph/parser/legacy/node_processors/resbody_node.rb +36 -0
  127. data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +21 -0
  128. data/lib/solargraph/parser/legacy/node_processors/send_node.rb +234 -0
  129. data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +18 -0
  130. data/lib/solargraph/parser/node_methods.rb +43 -0
  131. data/lib/solargraph/parser/node_processor.rb +43 -0
  132. data/lib/solargraph/parser/node_processor/base.rb +77 -0
  133. data/lib/solargraph/parser/region.rb +66 -0
  134. data/lib/solargraph/parser/rubyvm.rb +40 -0
  135. data/lib/solargraph/parser/rubyvm/class_methods.rb +150 -0
  136. data/lib/solargraph/parser/rubyvm/node_chainer.rb +135 -0
  137. data/lib/solargraph/parser/rubyvm/node_methods.rb +284 -0
  138. data/lib/solargraph/parser/rubyvm/node_processors.rb +61 -0
  139. data/lib/solargraph/parser/rubyvm/node_processors/alias_node.rb +23 -0
  140. data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +62 -0
  141. data/lib/solargraph/parser/rubyvm/node_processors/begin_node.rb +15 -0
  142. data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +22 -0
  143. data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +22 -0
  144. data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +23 -0
  145. data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +64 -0
  146. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +57 -0
  147. data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +23 -0
  148. data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +38 -0
  149. data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +39 -0
  150. data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +20 -0
  151. data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +27 -0
  152. data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +39 -0
  153. data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +31 -0
  154. data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +15 -0
  155. data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +45 -0
  156. data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +21 -0
  157. data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +15 -0
  158. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +255 -0
  159. data/lib/solargraph/parser/rubyvm/node_processors/sym_node.rb +18 -0
  160. data/lib/solargraph/parser/snippet.rb +13 -0
  161. data/lib/solargraph/pin.rb +39 -0
  162. data/lib/solargraph/pin/attribute.rb +49 -0
  163. data/lib/solargraph/pin/base.rb +296 -0
  164. data/lib/solargraph/pin/base_method.rb +141 -0
  165. data/lib/solargraph/pin/base_variable.rb +84 -0
  166. data/lib/solargraph/pin/block.rb +48 -0
  167. data/lib/solargraph/pin/class_variable.rb +8 -0
  168. data/lib/solargraph/pin/closure.rb +37 -0
  169. data/lib/solargraph/pin/common.rb +70 -0
  170. data/lib/solargraph/pin/constant.rb +43 -0
  171. data/lib/solargraph/pin/conversions.rb +97 -0
  172. data/lib/solargraph/pin/documenting.rb +110 -0
  173. data/lib/solargraph/pin/duck_method.rb +16 -0
  174. data/lib/solargraph/pin/global_variable.rb +8 -0
  175. data/lib/solargraph/pin/instance_variable.rb +30 -0
  176. data/lib/solargraph/pin/keyword.rb +15 -0
  177. data/lib/solargraph/pin/keyword_param.rb +8 -0
  178. data/lib/solargraph/pin/local_variable.rb +21 -0
  179. data/lib/solargraph/pin/localized.rb +43 -0
  180. data/lib/solargraph/pin/method.rb +111 -0
  181. data/lib/solargraph/pin/method_alias.rb +31 -0
  182. data/lib/solargraph/pin/namespace.rb +85 -0
  183. data/lib/solargraph/pin/parameter.rb +206 -0
  184. data/lib/solargraph/pin/proxy_type.rb +29 -0
  185. data/lib/solargraph/pin/reference.rb +14 -0
  186. data/lib/solargraph/pin/reference/extend.rb +10 -0
  187. data/lib/solargraph/pin/reference/include.rb +10 -0
  188. data/lib/solargraph/pin/reference/override.rb +29 -0
  189. data/lib/solargraph/pin/reference/prepend.rb +10 -0
  190. data/lib/solargraph/pin/reference/require.rb +14 -0
  191. data/lib/solargraph/pin/reference/superclass.rb +10 -0
  192. data/lib/solargraph/pin/singleton.rb +11 -0
  193. data/lib/solargraph/pin/symbol.rb +47 -0
  194. data/lib/solargraph/pin/yard_pin.rb +12 -0
  195. data/lib/solargraph/pin/yard_pin/constant.rb +25 -0
  196. data/lib/solargraph/pin/yard_pin/method.rb +65 -0
  197. data/lib/solargraph/pin/yard_pin/namespace.rb +27 -0
  198. data/lib/solargraph/pin/yard_pin/yard_mixin.rb +26 -0
  199. data/lib/solargraph/position.rb +112 -0
  200. data/lib/solargraph/range.rb +95 -0
  201. data/lib/solargraph/server_methods.rb +16 -0
  202. data/lib/solargraph/shell.rb +221 -0
  203. data/lib/solargraph/source.rb +533 -0
  204. data/lib/solargraph/source/chain.rb +172 -0
  205. data/lib/solargraph/source/chain/block_variable.rb +13 -0
  206. data/lib/solargraph/source/chain/call.rb +203 -0
  207. data/lib/solargraph/source/chain/class_variable.rb +13 -0
  208. data/lib/solargraph/source/chain/constant.rb +75 -0
  209. data/lib/solargraph/source/chain/global_variable.rb +13 -0
  210. data/lib/solargraph/source/chain/head.rb +35 -0
  211. data/lib/solargraph/source/chain/instance_variable.rb +13 -0
  212. data/lib/solargraph/source/chain/link.rb +67 -0
  213. data/lib/solargraph/source/chain/literal.rb +23 -0
  214. data/lib/solargraph/source/chain/or.rb +23 -0
  215. data/lib/solargraph/source/chain/variable.rb +13 -0
  216. data/lib/solargraph/source/chain/z_super.rb +184 -0
  217. data/lib/solargraph/source/change.rb +79 -0
  218. data/lib/solargraph/source/cursor.rb +164 -0
  219. data/lib/solargraph/source/encoding_fixes.rb +23 -0
  220. data/lib/solargraph/source/source_chainer.rb +189 -0
  221. data/lib/solargraph/source/updater.rb +54 -0
  222. data/lib/solargraph/source_map.rb +170 -0
  223. data/lib/solargraph/source_map/clip.rb +190 -0
  224. data/lib/solargraph/source_map/completion.rb +23 -0
  225. data/lib/solargraph/source_map/mapper.rb +199 -0
  226. data/lib/solargraph/stdlib_fills.rb +32 -0
  227. data/lib/solargraph/type_checker.rb +498 -0
  228. data/lib/solargraph/type_checker/checks.rb +95 -0
  229. data/lib/solargraph/type_checker/param_def.rb +35 -0
  230. data/lib/solargraph/type_checker/problem.rb +32 -0
  231. data/lib/solargraph/type_checker/rules.rb +53 -0
  232. data/lib/solargraph/version.rb +5 -0
  233. data/lib/solargraph/views/_method.erb +62 -0
  234. data/lib/solargraph/views/_name_type_tag.erb +10 -0
  235. data/lib/solargraph/views/_namespace.erb +24 -0
  236. data/lib/solargraph/views/document.erb +23 -0
  237. data/lib/solargraph/views/environment.erb +58 -0
  238. data/lib/solargraph/views/layout.erb +44 -0
  239. data/lib/solargraph/views/search.erb +11 -0
  240. data/lib/solargraph/workspace.rb +209 -0
  241. data/lib/solargraph/workspace/config.rb +215 -0
  242. data/lib/solargraph/yard_map.rb +420 -0
  243. data/lib/solargraph/yard_map/cache.rb +19 -0
  244. data/lib/solargraph/yard_map/core_docs.rb +170 -0
  245. data/lib/solargraph/yard_map/core_gen.rb +76 -0
  246. data/lib/solargraph/yard_map/mapper.rb +71 -0
  247. data/lib/solargraph/yard_map/rdoc_to_yard.rb +136 -0
  248. data/lib/yard-solargraph.rb +30 -0
  249. data/solargraph.gemspec +41 -0
  250. data/travis-bundler.rb +11 -0
  251. data/yardoc/2.2.2.tar.gz +0 -0
  252. metadata +575 -0
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Pin
5
+ module YardPin
6
+ class Namespace < Pin::Namespace
7
+ include YardMixin
8
+
9
+ def initialize code_object, spec, closure = nil
10
+ closure ||= Solargraph::Pin::Namespace.new(
11
+ name: code_object.namespace.to_s,
12
+ closure: Pin::ROOT_PIN,
13
+ gates: [code_object.namespace.to_s]
14
+ )
15
+ super(
16
+ location: object_location(code_object, spec),
17
+ name: code_object.name.to_s,
18
+ comments: code_object.docstring ? code_object.docstring.all.to_s : '',
19
+ type: code_object.is_a?(YARD::CodeObjects::ClassObject) ? :class : :module,
20
+ visibility: code_object.visibility,
21
+ closure: closure
22
+ )
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Pin
5
+ module YardPin
6
+ module YardMixin
7
+ attr_reader :code_object
8
+
9
+ attr_reader :spec
10
+
11
+ attr_reader :location
12
+
13
+ @@gate_cache ||= {}
14
+
15
+ private
16
+
17
+ # @return [Solargraph::Location, nil]
18
+ def object_location code_object, spec
19
+ return nil if spec.nil? || code_object.nil? || code_object.file.nil? || code_object.line.nil?
20
+ file = File.join(spec.full_gem_path, code_object.file)
21
+ Solargraph::Location.new(file, Solargraph::Range.from_to(code_object.line - 1, 0, code_object.line - 1, 0))
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ # The zero-based line and column numbers of a position in a string.
5
+ #
6
+ class Position
7
+ # @return [Integer]
8
+ attr_reader :line
9
+
10
+ # @return [Integer]
11
+ attr_reader :character
12
+
13
+ alias column character
14
+
15
+ # @param line [Integer]
16
+ # @param character [Integer]
17
+ def initialize line, character
18
+ @line = line
19
+ @character = character
20
+ end
21
+
22
+ # Get a hash of the position. This representation is suitable for use in
23
+ # the language server protocol.
24
+ #
25
+ # @return [Hash]
26
+ def to_hash
27
+ {
28
+ line: line,
29
+ character: character
30
+ }
31
+ end
32
+
33
+ def inspect
34
+ "#<#{self.class} #{line}, #{character}>"
35
+ end
36
+
37
+ # Get a numeric offset for the specified text and position.
38
+ #
39
+ # @param text [String]
40
+ # @param position [Position]
41
+ # @return [Integer]
42
+ def self.to_offset text, position
43
+ result = 0
44
+ feed = 0
45
+ line = position.line
46
+ column = position.character
47
+ text.lines.each do |l|
48
+ line_length = l.length
49
+ if feed == line
50
+ result += column
51
+ break
52
+ end
53
+ result += line_length
54
+ feed += 1
55
+ end
56
+ result
57
+ end
58
+
59
+ # Get a numeric offset for the specified text and a position identified
60
+ # by its line and character.
61
+ #
62
+ # @param text [String]
63
+ # @param line [Integer]
64
+ # @param character [Integer]
65
+ # @return [Integer]
66
+ def self.line_char_to_offset text, line, character
67
+ to_offset(text, Position.new(line, character))
68
+ end
69
+
70
+ # Get a position for the specified text and offset.
71
+ #
72
+ # @param text [String]
73
+ # @param offset [Integer]
74
+ # @return [Position]
75
+ def self.from_offset text, offset
76
+ cursor = 0
77
+ line = 0
78
+ character = nil
79
+ text.lines.each do |l|
80
+ line_length = l.length
81
+ char_length = l.chomp.length
82
+ if cursor + char_length >= offset
83
+ character = offset - cursor
84
+ break
85
+ end
86
+ cursor += line_length
87
+ line += 1
88
+ end
89
+ character = 0 if character.nil? and (cursor - offset).between?(0, 1)
90
+ raise InvalidOffsetError if character.nil?
91
+ Position.new(line, character)
92
+ end
93
+
94
+ # A helper method for generating positions from arrays of integers. The
95
+ # original parameter is returned if it is already a position.
96
+ #
97
+ # @raise [ArgumentError] if the object cannot be converted to a position.
98
+ #
99
+ # @param object [Position, Array(Integer, Integer)]
100
+ # @return [Position]
101
+ def self.normalize object
102
+ return object if object.is_a?(Position)
103
+ return Position.new(object[0], object[1]) if object.is_a?(Array)
104
+ raise ArgumentError, "Unable to convert #{object.class} to Position"
105
+ end
106
+
107
+ def == other
108
+ return false unless other.is_a?(Position)
109
+ line == other.line and character == other.character
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ # A pair of positions that compose a section of text.
5
+ #
6
+ class Range
7
+ # @return [Position]
8
+ attr_reader :start
9
+
10
+ # @return [Position]
11
+ attr_reader :ending
12
+
13
+ # @param start [Position]
14
+ # @param ending [Position]
15
+ def initialize start, ending
16
+ @start = start
17
+ @ending = ending
18
+ end
19
+
20
+ # Get a hash of the range. This representation is suitable for use in
21
+ # the language server protocol.
22
+ #
23
+ # @return [Hash<Symbol, Position>]
24
+ def to_hash
25
+ {
26
+ start: start.to_hash,
27
+ end: ending.to_hash
28
+ }
29
+ end
30
+
31
+ # True if the specified position is inside the range.
32
+ #
33
+ # @param position [Position, Array(Integer, Integer)]
34
+ # @return [Boolean]
35
+ def contain? position
36
+ position = Position.normalize(position)
37
+ return false if position.line < start.line || position.line > ending.line
38
+ return false if position.line == start.line && position.character < start.character
39
+ return false if position.line == ending.line && position.character > ending.character
40
+ true
41
+ end
42
+
43
+ # True if the range contains the specified position and the position does not precede it.
44
+ #
45
+ # @param position [Position, Array(Integer, Integer)]
46
+ # @return [Boolean]
47
+ def include? position
48
+ position = Position.normalize(position)
49
+ contain?(position) && !(position.line == start.line && position.character == start.character)
50
+ end
51
+
52
+ # Create a range from a pair of lines and characters.
53
+ #
54
+ # @param l1 [Integer] Starting line
55
+ # @param c1 [Integer] Starting character
56
+ # @param l2 [Integer] Ending line
57
+ # @param c2 [Integer] Ending character
58
+ # @return [Range]
59
+ def self.from_to l1, c1, l2, c2
60
+ Range.new(Position.new(l1, c1), Position.new(l2, c2))
61
+ end
62
+
63
+ # Get a range from a node.
64
+ #
65
+ # @param node [RubyVM::AbstractSyntaxTree::Node, Parser::AST::Node]
66
+ # @return [Range]
67
+ def self.from_node node
68
+ if defined?(RubyVM::AbstractSyntaxTree::Node)
69
+ if node.is_a?(RubyVM::AbstractSyntaxTree::Node)
70
+ Solargraph::Range.from_to(node.first_lineno - 1, node.first_column, node.last_lineno - 1, node.last_column)
71
+ end
72
+ elsif node.loc && node.loc.expression
73
+ from_expr(node.loc.expression)
74
+ end
75
+ end
76
+
77
+ # Get a range from a Parser range, usually found in
78
+ # Parser::AST::Node#location#expression.
79
+ #
80
+ # @param expr [Parser::Source::Range]
81
+ # @return [Range]
82
+ def self.from_expr expr
83
+ from_to(expr.line, expr.column, expr.last_line, expr.last_column)
84
+ end
85
+
86
+ def == other
87
+ return false unless other.is_a?(Range)
88
+ start == other.start && ending == other.ending
89
+ end
90
+
91
+ def inspect
92
+ "#<#{self.class} #{start.inspect} to #{ending.inspect}>"
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'socket'
4
+
5
+ module Solargraph
6
+ module ServerMethods
7
+ # @return [Integer]
8
+ def available_port
9
+ socket = Socket.new(:INET, :STREAM, 0)
10
+ socket.bind(Addrinfo.tcp("127.0.0.1", 0))
11
+ port = socket.local_address.ip_port
12
+ socket.close
13
+ port
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,221 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thor'
4
+
5
+ module Solargraph
6
+ class Shell < Thor
7
+ include Solargraph::ServerMethods
8
+
9
+ map %w[--version -v] => :version
10
+
11
+ desc "--version, -v", "Print the version"
12
+ def version
13
+ puts Solargraph::VERSION
14
+ end
15
+
16
+ desc 'socket', 'Run a Solargraph socket server'
17
+ option :host, type: :string, aliases: :h, desc: 'The server host', default: '127.0.0.1'
18
+ option :port, type: :numeric, aliases: :p, desc: 'The server port', default: 7658
19
+ def socket
20
+ require 'backport'
21
+ port = options[:port]
22
+ port = available_port if port.zero?
23
+ Backport.run do
24
+ Signal.trap("INT") do
25
+ Backport.stop
26
+ end
27
+ Signal.trap("TERM") do
28
+ Backport.stop
29
+ end
30
+ Backport.prepare_tcp_server host: options[:host], port: port, adapter: Solargraph::LanguageServer::Transport::Adapter
31
+ STDERR.puts "Solargraph is listening PORT=#{port} PID=#{Process.pid}"
32
+ end
33
+ end
34
+
35
+ desc 'stdio', 'Run a Solargraph stdio server'
36
+ def stdio
37
+ require 'backport'
38
+ Backport.run do
39
+ Signal.trap("INT") do
40
+ Backport.stop
41
+ end
42
+ Signal.trap("TERM") do
43
+ Backport.stop
44
+ end
45
+ Backport.prepare_stdio_server adapter: Solargraph::LanguageServer::Transport::Adapter
46
+ STDERR.puts "Solargraph is listening on stdio PID=#{Process.pid}"
47
+ end
48
+ end
49
+
50
+ desc 'config [DIRECTORY]', 'Create or overwrite a default configuration file'
51
+ option :extensions, type: :boolean, aliases: :e, desc: 'Add installed extensions', default: true
52
+ def config(directory = '.')
53
+ matches = []
54
+ if options[:extensions]
55
+ Gem::Specification.each do |g|
56
+ if g.name.match(/^solargraph\-[A-Za-z0-9_\-]*?\-ext/)
57
+ require g.name
58
+ matches.push g.name
59
+ end
60
+ end
61
+ end
62
+ conf = Solargraph::Workspace::Config.new.raw_data
63
+ unless matches.empty?
64
+ matches.each do |m|
65
+ conf['extensions'].push m
66
+ end
67
+ end
68
+ File.open(File.join(directory, '.solargraph.yml'), 'w') do |file|
69
+ file.puts conf.to_yaml
70
+ end
71
+ STDOUT.puts "Configuration file initialized."
72
+ end
73
+
74
+ desc 'download-core [VERSION]', 'Download core documentation'
75
+ def download_core version = nil
76
+ ver = version || Solargraph::YardMap::CoreDocs.best_download
77
+ puts "Downloading docs for #{ver}..."
78
+ Solargraph::YardMap::CoreDocs.download ver
79
+ # Clear cached documentation if it exists
80
+ FileUtils.rm_rf Dir.glob(File.join(Solargraph::YardMap::CoreDocs.cache_dir, ver, '*.ser'))
81
+ rescue ArgumentError => e
82
+ STDERR.puts "ERROR: #{e.message}"
83
+ STDERR.puts "Run `solargraph available-cores` for a list."
84
+ exit 1
85
+ end
86
+
87
+ desc 'list-cores', 'List the local documentation versions'
88
+ def list_cores
89
+ puts Solargraph::YardMap::CoreDocs.versions.join("\n")
90
+ end
91
+
92
+ desc 'available-cores', 'List available documentation versions'
93
+ def available_cores
94
+ puts Solargraph::YardMap::CoreDocs.available.join("\n")
95
+ end
96
+
97
+ desc 'clear', 'Delete all cached documentation'
98
+ long_desc %(
99
+ This command will delete all core and gem documentation from the cache.
100
+ You can also delete specific gem caches with the `uncache` command or
101
+ update documentation for specific Ruby versions with the `download-core`
102
+ command.
103
+ )
104
+ def clear
105
+ puts "Deleting the cached documentation"
106
+ Solargraph::YardMap::CoreDocs.clear
107
+ end
108
+ map 'clear-cache' => :clear
109
+ map 'clear-cores' => :clear
110
+
111
+ desc 'uncache GEM [...GEM]', "Delete cached gem documentation"
112
+ def uncache *gems
113
+ raise ArgumentError, 'No gems specified.' if gems.empty?
114
+ gems.each do |gem|
115
+ Dir[File.join(Solargraph::YardMap::CoreDocs.cache_dir, 'gems', "#{gem}-*")].each do |dir|
116
+ puts "Deleting cache: #{dir}"
117
+ FileUtils.remove_entry_secure dir
118
+ end
119
+ end
120
+ end
121
+
122
+ desc 'reporters', 'Get a list of diagnostics reporters'
123
+ def reporters
124
+ puts Solargraph::Diagnostics.reporters
125
+ end
126
+
127
+ desc 'typecheck [FILE(s)]', 'Run the type checker'
128
+ long_desc %(
129
+ Perform type checking on one or more files in a workspace. Check the
130
+ entire workspace if no files are specified.
131
+
132
+ Type checking levels are normal, typed, strict, and strong.
133
+ )
134
+ option :level, type: :string, aliases: [:mode, :m, :l], desc: 'Type checking level', default: 'normal'
135
+ option :directory, type: :string, aliases: :d, desc: 'The workspace directory', default: '.'
136
+ def typecheck *files
137
+ directory = File.realpath(options[:directory])
138
+ api_map = Solargraph::ApiMap.load(directory)
139
+ if files.empty?
140
+ files = api_map.source_maps.map(&:filename)
141
+ else
142
+ files.map! { |file| File.realpath(file) }
143
+ end
144
+ probcount = 0
145
+ filecount = 0
146
+ files.each do |file|
147
+ checker = TypeChecker.new(file, api_map: api_map, level: options[:level].to_sym)
148
+ problems = checker.problems
149
+ next if problems.empty?
150
+ problems.sort! { |a, b| a.location.range.start.line <=> b.location.range.start.line }
151
+ puts problems.map { |prob| "#{prob.location.filename}:#{prob.location.range.start.line + 1} - #{prob.message}" }.join("\n")
152
+ filecount += 1
153
+ probcount += problems.length
154
+ end
155
+ puts "#{probcount} problem#{probcount != 1 ? 's' : ''} found#{files.length != 1 ? " in #{filecount} of #{files.length} files" : ''}."
156
+ end
157
+
158
+ desc 'scan', 'Test the workspace for problems'
159
+ long_desc %(
160
+ A scan loads the entire workspace to make sure that the ASTs and
161
+ maps do not raise errors during analysis. It does not perform any type
162
+ checking or validation; it only confirms that the analysis itself is
163
+ error-free.
164
+ )
165
+ option :directory, type: :string, aliases: :d, desc: 'The workspace directory', default: '.'
166
+ option :verbose, type: :boolean, aliases: :v, desc: 'Verbose output', default: false
167
+ def scan
168
+ require 'benchmark'
169
+ directory = File.realpath(options[:directory])
170
+ api_map = nil
171
+ time = Benchmark.measure {
172
+ api_map = Solargraph::ApiMap.load(directory)
173
+ api_map.pins.each do |pin|
174
+ begin
175
+ puts pin_description(pin) if options[:verbose]
176
+ pin.typify api_map
177
+ pin.probe api_map
178
+ rescue StandardError => e
179
+ STDERR.puts "Error testing #{pin_description(pin)} #{pin.location ? "at #{pin.location.filename}:#{pin.location.range.start.line + 1}" : ''}"
180
+ STDERR.puts "[#{e.class}]: #{e.message}"
181
+ STDERR.puts e.backtrace.join("\n")
182
+ exit 1
183
+ end
184
+ end
185
+ }
186
+ puts "Scanned #{directory} (#{api_map.pins.length} pins) in #{time.real} seconds."
187
+ end
188
+
189
+ desc 'bundle', 'Generate documentation for bundled gems'
190
+ option :directory, type: :string, aliases: :d, desc: 'The workspace directory', default: '.'
191
+ option :rebuild, type: :boolean, aliases: :r, desc: 'Rebuild existing documentation', default: false
192
+ def bundle
193
+ Documentor.new(options[:directory], rebuild: options[:rebuild], out: STDOUT).document
194
+ end
195
+
196
+ desc 'rdoc GEM [VERSION]', 'Use RDoc to cache documentation'
197
+ def rdoc gem, version = '>= 0'
198
+ spec = Gem::Specification.find_by_name(gem, version)
199
+ puts "Caching #{spec.name} #{spec.version} from RDoc"
200
+ Solargraph::YardMap::RdocToYard.run(spec)
201
+ end
202
+
203
+ private
204
+
205
+ # @param pin [Solargraph::Pin::Base]
206
+ # @return [String]
207
+ def pin_description pin
208
+ desc = if pin.path.nil? || pin.path.empty?
209
+ if pin.closure
210
+ "#{pin.closure.path} | #{pin.name}"
211
+ else
212
+ "#{pin.context.namespace} | #{pin.name}"
213
+ end
214
+ else
215
+ pin.path
216
+ end
217
+ desc += " (#{pin.location.filename} #{pin.location.range.start.line})" if pin.location
218
+ desc
219
+ end
220
+ end
221
+ end