solargraph 0.46.0 → 0.54.5

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 (279) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +1 -0
  3. data/.github/workflows/plugins.yml +40 -0
  4. data/.github/workflows/rspec.yml +37 -41
  5. data/.github/workflows/typecheck.yml +34 -0
  6. data/.gitignore +9 -9
  7. data/.rspec +2 -2
  8. data/.yardopts +2 -2
  9. data/CHANGELOG.md +1338 -1115
  10. data/Gemfile +0 -0
  11. data/LICENSE +1 -1
  12. data/README.md +131 -128
  13. data/Rakefile +0 -0
  14. data/SPONSORS.md +10 -18
  15. data/bin/solargraph +0 -0
  16. data/lib/solargraph/api_map/cache.rb +109 -70
  17. data/lib/solargraph/api_map/index.rb +167 -0
  18. data/lib/solargraph/api_map/source_to_yard.rb +88 -81
  19. data/lib/solargraph/api_map/store.rb +260 -256
  20. data/lib/solargraph/api_map.rb +870 -686
  21. data/lib/solargraph/bench.rb +44 -27
  22. data/lib/solargraph/cache.rb +77 -0
  23. data/lib/solargraph/complex_type/type_methods.rb +217 -130
  24. data/lib/solargraph/complex_type/unique_type.rb +386 -75
  25. data/lib/solargraph/complex_type.rb +394 -221
  26. data/lib/solargraph/convention/base.rb +33 -33
  27. data/lib/solargraph/convention/gemfile.rb +15 -15
  28. data/lib/solargraph/convention/gemspec.rb +22 -22
  29. data/lib/solargraph/convention/rakefile.rb +17 -0
  30. data/lib/solargraph/convention.rb +47 -47
  31. data/lib/solargraph/converters/dd.rb +17 -12
  32. data/lib/solargraph/converters/dl.rb +15 -12
  33. data/lib/solargraph/converters/dt.rb +15 -12
  34. data/lib/solargraph/converters/misc.rb +1 -1
  35. data/lib/solargraph/diagnostics/base.rb +29 -29
  36. data/lib/solargraph/diagnostics/require_not_found.rb +53 -53
  37. data/lib/solargraph/diagnostics/rubocop.rb +113 -98
  38. data/lib/solargraph/diagnostics/rubocop_helpers.rb +66 -63
  39. data/lib/solargraph/diagnostics/severities.rb +15 -15
  40. data/lib/solargraph/diagnostics/type_check.rb +55 -54
  41. data/lib/solargraph/diagnostics/update_errors.rb +41 -41
  42. data/lib/solargraph/diagnostics.rb +55 -55
  43. data/lib/solargraph/doc_map.rb +188 -0
  44. data/lib/solargraph/environ.rb +45 -45
  45. data/lib/solargraph/equality.rb +33 -0
  46. data/lib/solargraph/gem_pins.rb +72 -0
  47. data/lib/solargraph/language_server/completion_item_kinds.rb +35 -35
  48. data/lib/solargraph/language_server/error_codes.rb +20 -20
  49. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  50. data/lib/solargraph/language_server/host/dispatch.rb +128 -111
  51. data/lib/solargraph/language_server/host/message_worker.rb +106 -59
  52. data/lib/solargraph/language_server/host/sources.rb +99 -156
  53. data/lib/solargraph/language_server/host.rb +861 -865
  54. data/lib/solargraph/language_server/message/base.rb +96 -89
  55. data/lib/solargraph/language_server/message/cancel_request.rb +13 -13
  56. data/lib/solargraph/language_server/message/client/register_capability.rb +15 -15
  57. data/lib/solargraph/language_server/message/client.rb +11 -11
  58. data/lib/solargraph/language_server/message/completion_item/resolve.rb +60 -58
  59. data/lib/solargraph/language_server/message/completion_item.rb +11 -11
  60. data/lib/solargraph/language_server/message/exit_notification.rb +13 -13
  61. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +112 -100
  62. data/lib/solargraph/language_server/message/extended/document.rb +20 -20
  63. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
  64. data/lib/solargraph/language_server/message/extended/download_core.rb +19 -23
  65. data/lib/solargraph/language_server/message/extended/environment.rb +25 -25
  66. data/lib/solargraph/language_server/message/extended/search.rb +20 -20
  67. data/lib/solargraph/language_server/message/extended.rb +21 -21
  68. data/lib/solargraph/language_server/message/initialize.rb +191 -162
  69. data/lib/solargraph/language_server/message/initialized.rb +28 -27
  70. data/lib/solargraph/language_server/message/method_not_found.rb +16 -16
  71. data/lib/solargraph/language_server/message/method_not_implemented.rb +14 -14
  72. data/lib/solargraph/language_server/message/shutdown.rb +13 -13
  73. data/lib/solargraph/language_server/message/text_document/base.rb +19 -19
  74. data/lib/solargraph/language_server/message/text_document/code_action.rb +17 -17
  75. data/lib/solargraph/language_server/message/text_document/completion.rb +56 -59
  76. data/lib/solargraph/language_server/message/text_document/definition.rb +38 -38
  77. data/lib/solargraph/language_server/message/text_document/did_change.rb +15 -15
  78. data/lib/solargraph/language_server/message/text_document/did_close.rb +15 -15
  79. data/lib/solargraph/language_server/message/text_document/did_open.rb +15 -15
  80. data/lib/solargraph/language_server/message/text_document/did_save.rb +17 -17
  81. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +16 -16
  82. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +26 -23
  83. data/lib/solargraph/language_server/message/text_document/folding_range.rb +26 -26
  84. data/lib/solargraph/language_server/message/text_document/formatting.rb +131 -126
  85. data/lib/solargraph/language_server/message/text_document/hover.rb +58 -54
  86. data/lib/solargraph/language_server/message/text_document/on_type_formatting.rb +34 -34
  87. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +11 -11
  88. data/lib/solargraph/language_server/message/text_document/references.rb +16 -16
  89. data/lib/solargraph/language_server/message/text_document/rename.rb +19 -19
  90. data/lib/solargraph/language_server/message/text_document/signature_help.rb +24 -29
  91. data/lib/solargraph/language_server/message/text_document/type_definition.rb +24 -0
  92. data/lib/solargraph/language_server/message/text_document.rb +28 -28
  93. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +35 -30
  94. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +40 -33
  95. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +24 -24
  96. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -23
  97. data/lib/solargraph/language_server/message/workspace.rb +14 -14
  98. data/lib/solargraph/language_server/message.rb +94 -93
  99. data/lib/solargraph/language_server/message_types.rb +14 -14
  100. data/lib/solargraph/language_server/progress.rb +135 -0
  101. data/lib/solargraph/language_server/request.rb +24 -24
  102. data/lib/solargraph/language_server/symbol_kinds.rb +36 -36
  103. data/lib/solargraph/language_server/transport/adapter.rb +68 -53
  104. data/lib/solargraph/language_server/transport/data_reader.rb +74 -72
  105. data/lib/solargraph/language_server/transport.rb +13 -13
  106. data/lib/solargraph/language_server/uri_helpers.rb +49 -49
  107. data/lib/solargraph/language_server.rb +20 -19
  108. data/lib/solargraph/library.rb +663 -546
  109. data/lib/solargraph/location.rb +58 -37
  110. data/lib/solargraph/logging.rb +27 -27
  111. data/lib/solargraph/page.rb +89 -83
  112. data/lib/solargraph/parser/comment_ripper.rb +56 -52
  113. data/lib/solargraph/parser/node_methods.rb +83 -43
  114. data/lib/solargraph/parser/node_processor/base.rb +87 -77
  115. data/lib/solargraph/parser/node_processor.rb +45 -43
  116. data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +153 -135
  117. data/lib/solargraph/parser/{legacy → parser_gem}/flawed_builder.rb +18 -16
  118. data/lib/solargraph/parser/{legacy → parser_gem}/node_chainer.rb +164 -148
  119. data/lib/solargraph/parser/parser_gem/node_methods.rb +495 -0
  120. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/alias_node.rb +23 -23
  121. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +57 -0
  122. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/begin_node.rb +15 -15
  123. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/block_node.rb +43 -42
  124. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/casgn_node.rb +35 -25
  125. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/cvasgn_node.rb +23 -23
  126. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/def_node.rb +50 -63
  127. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/defs_node.rb +36 -36
  128. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/gvasgn_node.rb +23 -23
  129. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/ivasgn_node.rb +38 -38
  130. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/lvasgn_node.rb +28 -28
  131. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +53 -0
  132. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/namespace_node.rb +39 -39
  133. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/orasgn_node.rb +16 -16
  134. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/resbody_node.rb +36 -36
  135. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +42 -0
  136. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +259 -257
  137. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/sym_node.rb +18 -18
  138. data/lib/solargraph/parser/parser_gem/node_processors.rb +56 -0
  139. data/lib/solargraph/parser/parser_gem.rb +12 -0
  140. data/lib/solargraph/parser/region.rb +66 -66
  141. data/lib/solargraph/parser/snippet.rb +15 -13
  142. data/lib/solargraph/parser.rb +22 -26
  143. data/lib/solargraph/pin/base.rb +378 -296
  144. data/lib/solargraph/pin/base_variable.rb +118 -84
  145. data/lib/solargraph/pin/block.rb +101 -72
  146. data/lib/solargraph/pin/callable.rb +147 -0
  147. data/lib/solargraph/pin/class_variable.rb +8 -8
  148. data/lib/solargraph/pin/closure.rb +57 -37
  149. data/lib/solargraph/pin/common.rb +70 -70
  150. data/lib/solargraph/pin/constant.rb +43 -43
  151. data/lib/solargraph/pin/conversions.rb +123 -96
  152. data/lib/solargraph/pin/delegated_method.rb +101 -0
  153. data/lib/solargraph/pin/documenting.rb +98 -105
  154. data/lib/solargraph/pin/duck_method.rb +16 -16
  155. data/lib/solargraph/pin/global_variable.rb +8 -8
  156. data/lib/solargraph/pin/instance_variable.rb +34 -30
  157. data/lib/solargraph/pin/keyword.rb +15 -15
  158. data/lib/solargraph/pin/keyword_param.rb +8 -8
  159. data/lib/solargraph/pin/local_variable.rb +67 -55
  160. data/lib/solargraph/pin/method.rb +527 -245
  161. data/lib/solargraph/pin/method_alias.rb +31 -31
  162. data/lib/solargraph/pin/namespace.rb +107 -91
  163. data/lib/solargraph/pin/parameter.rb +212 -201
  164. data/lib/solargraph/pin/proxy_type.rb +29 -29
  165. data/lib/solargraph/pin/reference/extend.rb +10 -10
  166. data/lib/solargraph/pin/reference/include.rb +10 -10
  167. data/lib/solargraph/pin/reference/override.rb +29 -29
  168. data/lib/solargraph/pin/reference/prepend.rb +10 -10
  169. data/lib/solargraph/pin/reference/require.rb +14 -14
  170. data/lib/solargraph/pin/reference/superclass.rb +10 -10
  171. data/lib/solargraph/pin/reference.rb +22 -14
  172. data/lib/solargraph/pin/search.rb +56 -56
  173. data/lib/solargraph/pin/signature.rb +17 -0
  174. data/lib/solargraph/pin/singleton.rb +11 -11
  175. data/lib/solargraph/pin/symbol.rb +47 -47
  176. data/lib/solargraph/pin.rb +41 -37
  177. data/lib/solargraph/position.rb +107 -100
  178. data/lib/solargraph/range.rb +98 -95
  179. data/lib/solargraph/rbs_map/conversions.rb +646 -0
  180. data/lib/solargraph/rbs_map/core_fills.rb +50 -0
  181. data/lib/solargraph/rbs_map/core_map.rb +28 -0
  182. data/lib/solargraph/rbs_map/stdlib_map.rb +33 -0
  183. data/lib/solargraph/rbs_map.rb +93 -0
  184. data/lib/solargraph/server_methods.rb +16 -16
  185. data/lib/solargraph/shell.rb +269 -226
  186. data/lib/solargraph/source/chain/array.rb +33 -0
  187. data/lib/solargraph/source/chain/block_symbol.rb +13 -0
  188. data/lib/solargraph/source/chain/block_variable.rb +13 -13
  189. data/lib/solargraph/source/chain/call.rb +303 -204
  190. data/lib/solargraph/source/chain/class_variable.rb +13 -13
  191. data/lib/solargraph/source/chain/constant.rb +89 -75
  192. data/lib/solargraph/source/chain/global_variable.rb +13 -13
  193. data/lib/solargraph/source/chain/hash.rb +33 -28
  194. data/lib/solargraph/source/chain/head.rb +19 -19
  195. data/lib/solargraph/source/chain/if.rb +28 -0
  196. data/lib/solargraph/source/chain/instance_variable.rb +13 -13
  197. data/lib/solargraph/source/chain/link.rb +98 -71
  198. data/lib/solargraph/source/chain/literal.rb +28 -23
  199. data/lib/solargraph/source/chain/or.rb +23 -23
  200. data/lib/solargraph/source/chain/q_call.rb +11 -11
  201. data/lib/solargraph/source/chain/variable.rb +13 -13
  202. data/lib/solargraph/source/chain/z_super.rb +30 -30
  203. data/lib/solargraph/source/chain.rb +252 -164
  204. data/lib/solargraph/source/change.rb +82 -79
  205. data/lib/solargraph/source/cursor.rb +167 -164
  206. data/lib/solargraph/source/source_chainer.rb +194 -191
  207. data/lib/solargraph/source/updater.rb +55 -54
  208. data/lib/solargraph/source.rb +495 -522
  209. data/lib/solargraph/source_map/clip.rb +232 -224
  210. data/lib/solargraph/source_map/completion.rb +23 -23
  211. data/lib/solargraph/source_map/data.rb +30 -0
  212. data/lib/solargraph/source_map/mapper.rb +255 -212
  213. data/lib/solargraph/source_map.rb +217 -180
  214. data/lib/solargraph/type_checker/checks.rb +120 -99
  215. data/lib/solargraph/type_checker/param_def.rb +35 -35
  216. data/lib/solargraph/type_checker/problem.rb +32 -32
  217. data/lib/solargraph/type_checker/rules.rb +62 -57
  218. data/lib/solargraph/type_checker.rb +672 -543
  219. data/lib/solargraph/version.rb +5 -5
  220. data/lib/solargraph/views/environment.erb +56 -58
  221. data/lib/solargraph/workspace/config.rb +239 -231
  222. data/lib/solargraph/workspace.rb +239 -215
  223. data/lib/solargraph/yard_map/cache.rb +25 -19
  224. data/lib/solargraph/yard_map/helpers.rb +16 -16
  225. data/lib/solargraph/yard_map/mapper/to_constant.rb +26 -25
  226. data/lib/solargraph/yard_map/mapper/to_method.rb +94 -78
  227. data/lib/solargraph/yard_map/mapper/to_namespace.rb +28 -27
  228. data/lib/solargraph/yard_map/mapper.rb +78 -77
  229. data/lib/solargraph/yard_map/to_method.rb +86 -79
  230. data/lib/solargraph/yard_map.rb +18 -460
  231. data/lib/solargraph/yard_tags.rb +20 -0
  232. data/lib/solargraph/yardoc.rb +52 -0
  233. data/lib/solargraph.rb +72 -69
  234. data/solargraph.gemspec +21 -10
  235. metadata +184 -115
  236. data/.travis.yml +0 -19
  237. data/lib/solargraph/api_map/bundler_methods.rb +0 -22
  238. data/lib/solargraph/compat.rb +0 -37
  239. data/lib/solargraph/convention/rspec.rb +0 -30
  240. data/lib/solargraph/documentor.rb +0 -76
  241. data/lib/solargraph/language_server/host/cataloger.rb +0 -56
  242. data/lib/solargraph/parser/legacy/node_methods.rb +0 -325
  243. data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +0 -23
  244. data/lib/solargraph/parser/legacy/node_processors/args_node.rb +0 -35
  245. data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
  246. data/lib/solargraph/parser/legacy/node_processors/def_node.rb +0 -63
  247. data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +0 -21
  248. data/lib/solargraph/parser/legacy/node_processors.rb +0 -54
  249. data/lib/solargraph/parser/legacy.rb +0 -12
  250. data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -144
  251. data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -160
  252. data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -315
  253. data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +0 -85
  254. data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +0 -42
  255. data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +0 -22
  256. data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +0 -23
  257. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -57
  258. data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +0 -23
  259. data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +0 -38
  260. data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +0 -39
  261. data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +0 -20
  262. data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +0 -27
  263. data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +0 -39
  264. data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +0 -26
  265. data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +0 -15
  266. data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +0 -45
  267. data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -21
  268. data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
  269. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -277
  270. data/lib/solargraph/parser/rubyvm/node_processors/sym_node.rb +0 -18
  271. data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -63
  272. data/lib/solargraph/parser/rubyvm.rb +0 -40
  273. data/lib/solargraph/yard_map/core_docs.rb +0 -170
  274. data/lib/solargraph/yard_map/core_fills.rb +0 -208
  275. data/lib/solargraph/yard_map/core_gen.rb +0 -76
  276. data/lib/solargraph/yard_map/rdoc_to_yard.rb +0 -140
  277. data/lib/solargraph/yard_map/stdlib_fills.rb +0 -43
  278. data/lib/yard-solargraph.rb +0 -33
  279. data/yardoc/2.2.2.tar.gz +0 -0
@@ -1,98 +1,113 @@
1
- # frozen_string_literal: true
2
-
3
- require 'stringio'
4
-
5
- module Solargraph
6
- module Diagnostics
7
- # This reporter provides linting through RuboCop.
8
- #
9
- class Rubocop < Base
10
- include RubocopHelpers
11
-
12
- # Conversion of RuboCop severity names to LSP constants
13
- SEVERITIES = {
14
- 'refactor' => Severities::HINT,
15
- 'convention' => Severities::INFORMATION,
16
- 'warning' => Severities::WARNING,
17
- 'error' => Severities::ERROR,
18
- 'fatal' => Severities::ERROR
19
- }
20
-
21
- # @param source [Solargraph::Source]
22
- # @param _api_map [Solargraph::ApiMap]
23
- # @return [Array<Hash>]
24
- def diagnose source, _api_map
25
- require_rubocop(rubocop_version)
26
- options, paths = generate_options(source.filename, source.code)
27
- store = RuboCop::ConfigStore.new
28
- runner = RuboCop::Runner.new(options, store)
29
- result = redirect_stdout{ runner.run(paths) }
30
- make_array JSON.parse(result)
31
- rescue RuboCop::ValidationError, RuboCop::ConfigNotFoundError => e
32
- raise DiagnosticsError, "Error in RuboCop configuration: #{e.message}"
33
- rescue JSON::ParserError
34
- raise DiagnosticsError, 'RuboCop returned invalid data'
35
- end
36
-
37
- private
38
-
39
- # Extracts the rubocop version from _args_
40
- #
41
- # @return [String]
42
- def rubocop_version
43
- args.find { |a| a =~ /version=/ }.to_s.split('=').last
44
- end
45
-
46
- # @param resp [Hash]
47
- # @return [Array<Hash>]
48
- def make_array resp
49
- diagnostics = []
50
- resp['files'].each do |file|
51
- file['offenses'].each do |off|
52
- diagnostics.push offense_to_diagnostic(off)
53
- end
54
- end
55
- diagnostics
56
- end
57
-
58
- # Convert a RuboCop offense to an LSP diagnostic
59
- #
60
- # @param off [Hash] Offense received from Rubocop
61
- # @return [Hash] LSP diagnostic
62
- def offense_to_diagnostic off
63
- {
64
- range: offense_range(off).to_hash,
65
- # 1 = Error, 2 = Warning, 3 = Information, 4 = Hint
66
- severity: SEVERITIES[off['severity']],
67
- source: 'rubocop',
68
- code: off['cop_name'],
69
- message: off['message'].gsub(/^#{off['cop_name']}\:/, '')
70
- }
71
- end
72
-
73
- # @param off [Hash]
74
- # @return [Range]
75
- def offense_range off
76
- Range.new(offense_start_position(off), offense_ending_position(off))
77
- end
78
-
79
- # @param off [Hash]
80
- # @return [Position]
81
- def offense_start_position off
82
- Position.new(off['location']['start_line'] - 1, off['location']['start_column'] - 1)
83
- end
84
-
85
- # @param off [Hash]
86
- # @return [Position]
87
- def offense_ending_position off
88
- if off['location']['start_line'] != off['location']['last_line']
89
- Position.new(off['location']['start_line'], 0)
90
- else
91
- Position.new(
92
- off['location']['start_line'] - 1, off['location']['last_column']
93
- )
94
- end
95
- end
96
- end
97
- end
98
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'stringio'
4
+
5
+ module Solargraph
6
+ module Diagnostics
7
+ # This reporter provides linting through RuboCop.
8
+ #
9
+ class Rubocop < Base
10
+ include RubocopHelpers
11
+
12
+ # Conversion of RuboCop severity names to LSP constants
13
+ SEVERITIES = {
14
+ 'info' => Severities::HINT,
15
+ 'refactor' => Severities::HINT,
16
+ 'convention' => Severities::INFORMATION,
17
+ 'warning' => Severities::WARNING,
18
+ 'error' => Severities::ERROR,
19
+ 'fatal' => Severities::ERROR
20
+ }
21
+
22
+ # @param source [Solargraph::Source]
23
+ # @param _api_map [Solargraph::ApiMap]
24
+ # @return [Array<Hash>]
25
+ def diagnose source, _api_map
26
+ @source = source
27
+ require_rubocop(rubocop_version)
28
+ options, paths = generate_options(source.filename, source.code)
29
+ store = RuboCop::ConfigStore.new
30
+ runner = RuboCop::Runner.new(options, store)
31
+ result = redirect_stdout{ runner.run(paths) }
32
+
33
+ return [] if result.empty?
34
+
35
+ make_array JSON.parse(result)
36
+ rescue RuboCop::ValidationError, RuboCop::ConfigNotFoundError => e
37
+ raise DiagnosticsError, "Error in RuboCop configuration: #{e.message}"
38
+ rescue JSON::ParserError => e
39
+ raise DiagnosticsError, "RuboCop returned invalid data: #{e.message}"
40
+ end
41
+
42
+ private
43
+
44
+ # Extracts the rubocop version from _args_
45
+ #
46
+ # @return [String]
47
+ def rubocop_version
48
+ args.find { |a| a =~ /version=/ }.to_s.split('=').last
49
+ end
50
+
51
+ # @param resp [Hash{String => Array<Hash{String => Array<Hash{String => undefined}>}>}]
52
+ # @return [Array<Hash>]
53
+ def make_array resp
54
+ diagnostics = []
55
+ resp['files'].each do |file|
56
+ file['offenses'].each do |off|
57
+ diagnostics.push offense_to_diagnostic(off)
58
+ end
59
+ end
60
+ diagnostics
61
+ end
62
+
63
+ # Convert a RuboCop offense to an LSP diagnostic
64
+ #
65
+ # @param off [Hash{String => unknown}] Offense received from Rubocop
66
+ # @return [Hash{Symbol => Hash, String, Integer}] LSP diagnostic
67
+ def offense_to_diagnostic off
68
+ {
69
+ range: offense_range(off).to_hash,
70
+ # 1 = Error, 2 = Warning, 3 = Information, 4 = Hint
71
+ severity: SEVERITIES[off['severity']],
72
+ source: 'rubocop',
73
+ code: off['cop_name'],
74
+ message: off['message'].gsub(/^#{off['cop_name']}\:/, '')
75
+ }
76
+ end
77
+
78
+ # @param off [Hash]
79
+ # @return [Range]
80
+ def offense_range off
81
+ Range.new(offense_start_position(off), offense_ending_position(off))
82
+ end
83
+
84
+ # @param off [Hash{String => Hash{String => Integer}}]
85
+ # @return [Position]
86
+ def offense_start_position off
87
+ Position.new(off['location']['start_line'] - 1, off['location']['start_column'] - 1)
88
+ end
89
+
90
+ # @param off [Hash{String => Hash{String => Integer}}]
91
+ # @return [Position]
92
+ def offense_ending_position off
93
+ if off['location']['start_line'] != off['location']['last_line']
94
+ Position.new(off['location']['start_line'], 0)
95
+ else
96
+ start_line = off['location']['start_line'] - 1
97
+ # @type [Integer]
98
+ last_column = off['location']['last_column']
99
+ line = @source.code.lines[start_line]
100
+ col_off = if line.nil? || line.empty?
101
+ 1
102
+ else
103
+ 0
104
+ end
105
+
106
+ Position.new(
107
+ start_line, last_column - col_off
108
+ )
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -1,63 +1,66 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- module Diagnostics
5
- # Utility methods for the RuboCop diagnostics reporter.
6
- #
7
- module RubocopHelpers
8
- module_function
9
-
10
- # Requires a specific version of rubocop, or the latest installed version
11
- # if _version_ is `nil`.
12
- #
13
- # @param version [String]
14
- # @raise [InvalidRubocopVersionError] if _version_ is not installed
15
- def require_rubocop(version = nil)
16
- begin
17
- gem_path = Gem::Specification.find_by_name('rubocop', version).full_gem_path
18
- gem_lib_path = File.join(gem_path, 'lib')
19
- $LOAD_PATH.unshift(gem_lib_path) unless $LOAD_PATH.include?(gem_lib_path)
20
- rescue Gem::MissingSpecVersionError => e
21
- raise InvalidRubocopVersionError,
22
- "could not find '#{e.name}' (#{e.requirement}) - "\
23
- "did find: [#{e.specs.map { |s| s.version.version }.join(', ')}]"
24
- end
25
- require 'rubocop'
26
- end
27
-
28
- # Generate command-line options for the specified filename and code.
29
- #
30
- # @param filename [String]
31
- # @param code [String]
32
- # @return [Array(Array<String>, Array<String>)]
33
- def generate_options filename, code
34
- args = ['-f', 'j', '--force-exclusion', filename]
35
- base_options = RuboCop::Options.new
36
- options, paths = base_options.parse(args)
37
- options[:stdin] = code
38
- [options, paths]
39
- end
40
-
41
- # RuboCop internally uses capitalized drive letters for Windows paths,
42
- # so we need to convert the paths provided to the command.
43
- #
44
- # @param path [String]
45
- # @return [String]
46
- def fix_drive_letter path
47
- return path unless path.match(/^[a-z]:/)
48
- path[0].upcase + path[1..-1]
49
- end
50
-
51
- # @todo This is a smelly way to redirect output, but the RuboCop specs do
52
- # the same thing.
53
- # @return [String]
54
- def redirect_stdout
55
- redir = StringIO.new
56
- $stdout = redir
57
- yield if block_given?
58
- $stdout = STDOUT
59
- redir.string
60
- end
61
- end
62
- end
63
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Diagnostics
5
+ # Utility methods for the RuboCop diagnostics reporter.
6
+ #
7
+ module RubocopHelpers
8
+ module_function
9
+
10
+ # Requires a specific version of rubocop, or the latest installed version
11
+ # if _version_ is `nil`.
12
+ #
13
+ # @param version [String, nil]
14
+ # @raise [InvalidRubocopVersionError] if _version_ is not installed
15
+ # @return [void]
16
+ def require_rubocop(version = nil)
17
+ begin
18
+ gem_path = Gem::Specification.find_by_name('rubocop', version).full_gem_path
19
+ gem_lib_path = File.join(gem_path, 'lib')
20
+ $LOAD_PATH.unshift(gem_lib_path) unless $LOAD_PATH.include?(gem_lib_path)
21
+ # @todo Gem::MissingSpecVersionError is undocumented for some reason
22
+ # @sg-ignore
23
+ rescue Gem::MissingSpecVersionError => e
24
+ raise InvalidRubocopVersionError,
25
+ "could not find '#{e.name}' (#{e.requirement}) - "\
26
+ "did find: [#{e.specs.map { |s| s.version.version }.join(', ')}]"
27
+ end
28
+ require 'rubocop'
29
+ end
30
+
31
+ # Generate command-line options for the specified filename and code.
32
+ #
33
+ # @param filename [String]
34
+ # @param code [String]
35
+ # @return [Array(Array<String>, Array<String>)]
36
+ def generate_options filename, code
37
+ args = ['-f', 'j', '--force-exclusion', filename]
38
+ base_options = RuboCop::Options.new
39
+ options, paths = base_options.parse(args)
40
+ options[:stdin] = code
41
+ [options, paths]
42
+ end
43
+
44
+ # RuboCop internally uses capitalized drive letters for Windows paths,
45
+ # so we need to convert the paths provided to the command.
46
+ #
47
+ # @param path [String]
48
+ # @return [String]
49
+ def fix_drive_letter path
50
+ return path unless path.match(/^[a-z]:/)
51
+ path[0].upcase + path[1..-1]
52
+ end
53
+
54
+ # @todo This is a smelly way to redirect output, but the RuboCop specs do
55
+ # the same thing.
56
+ # @return [String]
57
+ def redirect_stdout
58
+ redir = StringIO.new
59
+ $stdout = redir
60
+ yield if block_given?
61
+ $stdout = STDOUT
62
+ redir.string
63
+ end
64
+ end
65
+ end
66
+ end
@@ -1,15 +1,15 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- module Diagnostics
5
- # These severity constants match the DiagnosticSeverity constants in the
6
- # language server protocol.
7
- #
8
- module Severities
9
- ERROR = 1
10
- WARNING = 2
11
- INFORMATION = 3
12
- HINT = 4
13
- end
14
- end
15
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Diagnostics
5
+ # These severity constants match the DiagnosticSeverity constants in the
6
+ # language server protocol.
7
+ #
8
+ module Severities
9
+ ERROR = 1
10
+ WARNING = 2
11
+ INFORMATION = 3
12
+ HINT = 4
13
+ end
14
+ end
15
+ end
@@ -1,54 +1,55 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- module Diagnostics
5
- # TypeCheck reports methods with undefined return types, untagged
6
- # parameters, and invalid param tags.
7
- #
8
- class TypeCheck < Base
9
- def diagnose source, api_map
10
- # return [] unless args.include?('always') || api_map.workspaced?(source.filename)
11
- severity = Diagnostics::Severities::ERROR
12
- level = (args.reverse.find { |a| ['normal', 'typed', 'strict', 'strong'].include?(a) }) || :normal
13
- checker = Solargraph::TypeChecker.new(source.filename, api_map: api_map, level: level.to_sym)
14
- checker.problems
15
- .sort { |a, b| a.location.range.start.line <=> b.location.range.start.line }
16
- .map do |problem|
17
- {
18
- range: extract_first_line(problem.location, source),
19
- severity: severity,
20
- source: 'Typecheck',
21
- message: problem.message
22
- }
23
- end
24
- end
25
-
26
- private
27
-
28
- # @param location [Location]
29
- # @param source [Source]
30
- # @return [Hash]
31
- def extract_first_line location, source
32
- return location.range.to_hash if location.range.start.line == location.range.ending.line
33
- {
34
- start: {
35
- line: location.range.start.line,
36
- character: location.range.start.character
37
- },
38
- end: {
39
- line: location.range.start.line,
40
- character: last_character(location.range.start, source)
41
- }
42
- }
43
- end
44
-
45
- # @param position [Solargraph::Position]
46
- # @param source [Solargraph::Source]
47
- # @return [Integer]
48
- def last_character position, source
49
- cursor = Position.to_offset(source.code, position)
50
- source.code.index(/[\r\n]/, cursor) || source.code.length
51
- end
52
- end
53
- end
54
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Diagnostics
5
+ # TypeCheck reports methods with undefined return types, untagged
6
+ # parameters, and invalid param tags.
7
+ #
8
+ class TypeCheck < Base
9
+ # @return [Array<Hash>]
10
+ def diagnose source, api_map
11
+ # return [] unless args.include?('always') || api_map.workspaced?(source.filename)
12
+ severity = Diagnostics::Severities::ERROR
13
+ level = (args.reverse.find { |a| ['normal', 'typed', 'strict', 'strong'].include?(a) }) || :normal
14
+ checker = Solargraph::TypeChecker.new(source.filename, api_map: api_map, level: level.to_sym)
15
+ checker.problems
16
+ .sort { |a, b| a.location.range.start.line <=> b.location.range.start.line }
17
+ .map do |problem|
18
+ {
19
+ range: extract_first_line(problem.location, source),
20
+ severity: severity,
21
+ source: 'Typecheck',
22
+ message: problem.message
23
+ }
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ # @param location [Location]
30
+ # @param source [Source]
31
+ # @return [Hash]
32
+ def extract_first_line location, source
33
+ return location.range.to_hash if location.range.start.line == location.range.ending.line
34
+ {
35
+ start: {
36
+ line: location.range.start.line,
37
+ character: location.range.start.character
38
+ },
39
+ end: {
40
+ line: location.range.start.line,
41
+ character: last_character(location.range.start, source)
42
+ }
43
+ }
44
+ end
45
+
46
+ # @param position [Solargraph::Position]
47
+ # @param source [Solargraph::Source]
48
+ # @return [Integer]
49
+ def last_character position, source
50
+ cursor = Position.to_offset(source.code, position)
51
+ source.code.index(/[\r\n]/, cursor) || source.code.length
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,41 +1,41 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- module Diagnostics
5
- class UpdateErrors < Base
6
- def diagnose source, api_map
7
- result = []
8
- combine_ranges(source.code, source.error_ranges).each do |range|
9
- result.push(
10
- range: range.to_hash,
11
- severity: Diagnostics::Severities::ERROR,
12
- source: 'Solargraph',
13
- message: 'Syntax error'
14
- )
15
- end
16
- result
17
- end
18
-
19
- private
20
-
21
- # Combine an array of ranges by their starting lines.
22
- #
23
- # @param code [String]
24
- # @param ranges [Array<Range>]
25
- # @return [Array<Range>]
26
- def combine_ranges code, ranges
27
- result = []
28
- lines = []
29
- ranges.sort{|a, b| a.start.line <=> b.start.line}.each do |rng|
30
- next if rng.nil? || lines.include?(rng.start.line)
31
- lines.push rng.start.line
32
- next if rng.start.line >= code.lines.length
33
- scol = code.lines[rng.start.line].index(/[^\s]/) || 0
34
- ecol = code.lines[rng.start.line].length
35
- result.push Range.from_to(rng.start.line, scol, rng.start.line, ecol)
36
- end
37
- result
38
- end
39
- end
40
- end
41
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Diagnostics
5
+ class UpdateErrors < Base
6
+ def diagnose source, api_map
7
+ result = []
8
+ combine_ranges(source.code, source.error_ranges).each do |range|
9
+ result.push(
10
+ range: range.to_hash,
11
+ severity: Diagnostics::Severities::ERROR,
12
+ source: 'Solargraph',
13
+ message: 'Syntax error'
14
+ )
15
+ end
16
+ result
17
+ end
18
+
19
+ private
20
+
21
+ # Combine an array of ranges by their starting lines.
22
+ #
23
+ # @param code [String]
24
+ # @param ranges [Array<Range>]
25
+ # @return [Array<Range>]
26
+ def combine_ranges code, ranges
27
+ result = []
28
+ lines = []
29
+ ranges.sort{|a, b| a.start.line <=> b.start.line}.each do |rng|
30
+ next if rng.nil? || lines.include?(rng.start.line)
31
+ lines.push rng.start.line
32
+ next if rng.start.line >= code.lines.length
33
+ scol = code.lines[rng.start.line].index(/[^\s]/) || 0
34
+ ecol = code.lines[rng.start.line].length
35
+ result.push Range.from_to(rng.start.line, scol, rng.start.line, ecol)
36
+ end
37
+ result
38
+ end
39
+ end
40
+ end
41
+ end