solargraph 0.58.3 → 0.59.2

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 (229) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +3 -0
  3. data/.github/workflows/linting.yml +12 -5
  4. data/.github/workflows/plugins.yml +54 -34
  5. data/.github/workflows/rspec.yml +15 -28
  6. data/.github/workflows/typecheck.yml +6 -3
  7. data/.rubocop.yml +38 -6
  8. data/.rubocop_todo.yml +53 -966
  9. data/CHANGELOG.md +24 -0
  10. data/Gemfile +3 -1
  11. data/README.md +3 -3
  12. data/Rakefile +26 -23
  13. data/bin/solargraph +2 -1
  14. data/lib/solargraph/api_map/cache.rb +3 -3
  15. data/lib/solargraph/api_map/constants.rb +12 -3
  16. data/lib/solargraph/api_map/index.rb +29 -18
  17. data/lib/solargraph/api_map/source_to_yard.rb +22 -9
  18. data/lib/solargraph/api_map/store.rb +40 -30
  19. data/lib/solargraph/api_map.rb +160 -78
  20. data/lib/solargraph/bench.rb +2 -3
  21. data/lib/solargraph/complex_type/conformance.rb +176 -0
  22. data/lib/solargraph/complex_type/type_methods.rb +31 -18
  23. data/lib/solargraph/complex_type/unique_type.rb +221 -63
  24. data/lib/solargraph/complex_type.rb +173 -59
  25. data/lib/solargraph/convention/active_support_concern.rb +111 -111
  26. data/lib/solargraph/convention/base.rb +50 -50
  27. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +1 -1
  28. data/lib/solargraph/convention/data_definition/data_definition_node.rb +7 -5
  29. data/lib/solargraph/convention/data_definition.rb +5 -2
  30. data/lib/solargraph/convention/gemfile.rb +1 -1
  31. data/lib/solargraph/convention/gemspec.rb +1 -1
  32. data/lib/solargraph/convention/rakefile.rb +1 -1
  33. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +2 -1
  34. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +4 -3
  35. data/lib/solargraph/convention/struct_definition.rb +8 -4
  36. data/lib/solargraph/convention.rb +2 -2
  37. data/lib/solargraph/converters/dd.rb +2 -0
  38. data/lib/solargraph/converters/dl.rb +2 -0
  39. data/lib/solargraph/converters/dt.rb +2 -0
  40. data/lib/solargraph/converters/misc.rb +2 -0
  41. data/lib/solargraph/diagnostics/require_not_found.rb +1 -0
  42. data/lib/solargraph/diagnostics/rubocop.rb +11 -10
  43. data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
  44. data/lib/solargraph/diagnostics/type_check.rb +11 -10
  45. data/lib/solargraph/diagnostics/update_errors.rb +4 -8
  46. data/lib/solargraph/diagnostics.rb +55 -55
  47. data/lib/solargraph/doc_map.rb +38 -39
  48. data/lib/solargraph/environ.rb +52 -52
  49. data/lib/solargraph/equality.rb +4 -4
  50. data/lib/solargraph/gem_pins.rb +4 -15
  51. data/lib/solargraph/language_server/error_codes.rb +10 -10
  52. data/lib/solargraph/language_server/host/diagnoser.rb +1 -1
  53. data/lib/solargraph/language_server/host/dispatch.rb +3 -3
  54. data/lib/solargraph/language_server/host/message_worker.rb +4 -3
  55. data/lib/solargraph/language_server/host/sources.rb +2 -1
  56. data/lib/solargraph/language_server/host.rb +35 -28
  57. data/lib/solargraph/language_server/message/base.rb +1 -1
  58. data/lib/solargraph/language_server/message/client/register_capability.rb +1 -3
  59. data/lib/solargraph/language_server/message/completion_item/resolve.rb +6 -8
  60. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +12 -18
  61. data/lib/solargraph/language_server/message/extended/document.rb +1 -0
  62. data/lib/solargraph/language_server/message/extended/document_gems.rb +7 -7
  63. data/lib/solargraph/language_server/message/extended/download_core.rb +2 -1
  64. data/lib/solargraph/language_server/message/extended/environment.rb +25 -25
  65. data/lib/solargraph/language_server/message/extended/search.rb +1 -1
  66. data/lib/solargraph/language_server/message/initialize.rb +20 -14
  67. data/lib/solargraph/language_server/message/initialized.rb +28 -28
  68. data/lib/solargraph/language_server/message/text_document/completion.rb +10 -8
  69. data/lib/solargraph/language_server/message/text_document/definition.rb +41 -32
  70. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +17 -10
  71. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +29 -19
  72. data/lib/solargraph/language_server/message/text_document/formatting.rb +8 -6
  73. data/lib/solargraph/language_server/message/text_document/hover.rb +5 -5
  74. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +13 -6
  75. data/lib/solargraph/language_server/message/text_document/references.rb +17 -10
  76. data/lib/solargraph/language_server/message/text_document/rename.rb +20 -13
  77. data/lib/solargraph/language_server/message/text_document/signature_help.rb +3 -2
  78. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -17
  79. data/lib/solargraph/language_server/message/text_document.rb +28 -28
  80. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +34 -28
  81. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +38 -30
  82. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +23 -17
  83. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +27 -17
  84. data/lib/solargraph/language_server/message.rb +1 -1
  85. data/lib/solargraph/language_server/progress.rb +143 -143
  86. data/lib/solargraph/language_server/request.rb +4 -2
  87. data/lib/solargraph/language_server/transport/adapter.rb +68 -68
  88. data/lib/solargraph/language_server/transport/data_reader.rb +11 -13
  89. data/lib/solargraph/language_server/uri_helpers.rb +2 -2
  90. data/lib/solargraph/language_server.rb +20 -20
  91. data/lib/solargraph/library.rb +57 -38
  92. data/lib/solargraph/location.rb +17 -14
  93. data/lib/solargraph/logging.rb +22 -4
  94. data/lib/solargraph/page.rb +1 -1
  95. data/lib/solargraph/parser/comment_ripper.rb +19 -4
  96. data/lib/solargraph/parser/flow_sensitive_typing.rb +324 -108
  97. data/lib/solargraph/parser/node_processor/base.rb +34 -4
  98. data/lib/solargraph/parser/node_processor.rb +8 -7
  99. data/lib/solargraph/parser/parser_gem/class_methods.rb +30 -14
  100. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -1
  101. data/lib/solargraph/parser/parser_gem/node_chainer.rb +51 -25
  102. data/lib/solargraph/parser/parser_gem/node_methods.rb +181 -73
  103. data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +24 -24
  104. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +4 -4
  105. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +13 -11
  106. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +9 -0
  107. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +11 -12
  108. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +36 -36
  109. data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +24 -24
  110. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +10 -3
  111. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +9 -8
  112. data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +24 -24
  113. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +36 -6
  114. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +5 -3
  115. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +1 -0
  116. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +3 -1
  117. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +40 -40
  118. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +3 -3
  119. data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
  120. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -1
  121. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
  122. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -5
  123. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +124 -113
  124. data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +20 -20
  125. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +1 -1
  126. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
  127. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +6 -2
  128. data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
  129. data/lib/solargraph/parser/parser_gem.rb +2 -0
  130. data/lib/solargraph/parser/region.rb +9 -3
  131. data/lib/solargraph/parser/snippet.rb +3 -1
  132. data/lib/solargraph/parser.rb +2 -0
  133. data/lib/solargraph/pin/base.rb +126 -82
  134. data/lib/solargraph/pin/base_variable.rb +273 -24
  135. data/lib/solargraph/pin/block.rb +29 -6
  136. data/lib/solargraph/pin/breakable.rb +7 -1
  137. data/lib/solargraph/pin/callable.rb +65 -21
  138. data/lib/solargraph/pin/closure.rb +7 -10
  139. data/lib/solargraph/pin/common.rb +24 -6
  140. data/lib/solargraph/pin/compound_statement.rb +55 -0
  141. data/lib/solargraph/pin/constant.rb +3 -5
  142. data/lib/solargraph/pin/conversions.rb +10 -4
  143. data/lib/solargraph/pin/delegated_method.rb +19 -8
  144. data/lib/solargraph/pin/documenting.rb +4 -2
  145. data/lib/solargraph/pin/instance_variable.rb +5 -1
  146. data/lib/solargraph/pin/keyword.rb +0 -4
  147. data/lib/solargraph/pin/local_variable.rb +15 -59
  148. data/lib/solargraph/pin/method.rb +158 -104
  149. data/lib/solargraph/pin/method_alias.rb +8 -0
  150. data/lib/solargraph/pin/namespace.rb +19 -12
  151. data/lib/solargraph/pin/parameter.rb +102 -36
  152. data/lib/solargraph/pin/proxy_type.rb +4 -1
  153. data/lib/solargraph/pin/reference/override.rb +1 -1
  154. data/lib/solargraph/pin/reference/require.rb +14 -14
  155. data/lib/solargraph/pin/reference/superclass.rb +2 -0
  156. data/lib/solargraph/pin/reference/type_alias.rb +16 -0
  157. data/lib/solargraph/pin/reference.rb +20 -0
  158. data/lib/solargraph/pin/search.rb +8 -7
  159. data/lib/solargraph/pin/signature.rb +15 -12
  160. data/lib/solargraph/pin/singleton.rb +11 -11
  161. data/lib/solargraph/pin/symbol.rb +2 -1
  162. data/lib/solargraph/pin/until.rb +2 -4
  163. data/lib/solargraph/pin/while.rb +2 -4
  164. data/lib/solargraph/pin.rb +2 -0
  165. data/lib/solargraph/pin_cache.rb +22 -19
  166. data/lib/solargraph/position.rb +17 -10
  167. data/lib/solargraph/range.rb +16 -15
  168. data/lib/solargraph/rbs_map/conversions.rb +367 -231
  169. data/lib/solargraph/rbs_map/core_fills.rb +18 -11
  170. data/lib/solargraph/rbs_map/core_map.rb +24 -17
  171. data/lib/solargraph/rbs_map/stdlib_map.rb +33 -5
  172. data/lib/solargraph/rbs_map.rb +76 -32
  173. data/lib/solargraph/server_methods.rb +1 -1
  174. data/lib/solargraph/shell.rb +258 -66
  175. data/lib/solargraph/source/chain/array.rb +3 -12
  176. data/lib/solargraph/source/chain/block_symbol.rb +13 -13
  177. data/lib/solargraph/source/chain/block_variable.rb +13 -13
  178. data/lib/solargraph/source/chain/call.rb +96 -56
  179. data/lib/solargraph/source/chain/class_variable.rb +1 -1
  180. data/lib/solargraph/source/chain/constant.rb +5 -1
  181. data/lib/solargraph/source/chain/global_variable.rb +1 -1
  182. data/lib/solargraph/source/chain/hash.rb +8 -5
  183. data/lib/solargraph/source/chain/head.rb +19 -19
  184. data/lib/solargraph/source/chain/if.rb +12 -10
  185. data/lib/solargraph/source/chain/instance_variable.rb +24 -1
  186. data/lib/solargraph/source/chain/link.rb +12 -22
  187. data/lib/solargraph/source/chain/literal.rb +22 -15
  188. data/lib/solargraph/source/chain/or.rb +10 -4
  189. data/lib/solargraph/source/chain/q_call.rb +2 -0
  190. data/lib/solargraph/source/chain/variable.rb +3 -1
  191. data/lib/solargraph/source/chain/z_super.rb +1 -3
  192. data/lib/solargraph/source/chain.rb +51 -38
  193. data/lib/solargraph/source/change.rb +12 -5
  194. data/lib/solargraph/source/cursor.rb +33 -18
  195. data/lib/solargraph/source/encoding_fixes.rb +6 -7
  196. data/lib/solargraph/source/source_chainer.rb +56 -32
  197. data/lib/solargraph/source/updater.rb +5 -1
  198. data/lib/solargraph/source.rb +59 -35
  199. data/lib/solargraph/source_map/clip.rb +54 -30
  200. data/lib/solargraph/source_map/data.rb +4 -1
  201. data/lib/solargraph/source_map/mapper.rb +69 -42
  202. data/lib/solargraph/source_map.rb +21 -9
  203. data/lib/solargraph/type_checker/problem.rb +3 -1
  204. data/lib/solargraph/type_checker/rules.rb +81 -8
  205. data/lib/solargraph/type_checker.rb +196 -122
  206. data/lib/solargraph/version.rb +1 -1
  207. data/lib/solargraph/workspace/config.rb +14 -11
  208. data/lib/solargraph/workspace/gemspecs.rb +367 -0
  209. data/lib/solargraph/workspace/require_paths.rb +1 -0
  210. data/lib/solargraph/workspace.rb +50 -28
  211. data/lib/solargraph/yard_map/cache.rb +25 -25
  212. data/lib/solargraph/yard_map/helpers.rb +8 -3
  213. data/lib/solargraph/yard_map/mapper/to_constant.rb +28 -28
  214. data/lib/solargraph/yard_map/mapper/to_method.rb +13 -7
  215. data/lib/solargraph/yard_map/mapper/to_namespace.rb +2 -1
  216. data/lib/solargraph/yard_map/mapper.rb +13 -8
  217. data/lib/solargraph/yard_map.rb +17 -18
  218. data/lib/solargraph/yard_tags.rb +2 -2
  219. data/lib/solargraph/yardoc.rb +7 -4
  220. data/lib/solargraph.rb +33 -10
  221. data/rbs/fills/rubygems/0/dependency.rbs +193 -0
  222. data/rbs/shims/ast/0/node.rbs +1 -1
  223. data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
  224. data/solargraph.gemspec +37 -35
  225. metadata +41 -42
  226. data/lib/solargraph/type_checker/checks.rb +0 -124
  227. data/lib/solargraph/type_checker/param_def.rb +0 -37
  228. data/lib/solargraph/yard_map/to_method.rb +0 -89
  229. data/rbs/fills/tuple/tuple.rbs +0 -149
@@ -17,7 +17,7 @@ module Solargraph
17
17
  'warning' => Severities::WARNING,
18
18
  'error' => Severities::ERROR,
19
19
  'fatal' => Severities::ERROR
20
- }
20
+ }.freeze
21
21
 
22
22
  # @param source [Solargraph::Source]
23
23
  # @param _api_map [Solargraph::ApiMap]
@@ -25,6 +25,7 @@ module Solargraph
25
25
  def diagnose source, _api_map
26
26
  @source = source
27
27
  require_rubocop(rubocop_version)
28
+ # @sg-ignore Need to add nil check here
28
29
  options, paths = generate_options(source.filename, source.code)
29
30
  store = RuboCop::ConfigStore.new
30
31
  runner = RuboCop::Runner.new(options, store)
@@ -32,7 +33,7 @@ module Solargraph
32
33
  # a time - it uses 'chdir' to read config files with ERB,
33
34
  # which can conflict with other chdirs.
34
35
  result = Solargraph::CHDIR_MUTEX.synchronize do
35
- redirect_stdout{ runner.run(paths) }
36
+ redirect_stdout { runner.run(paths) }
36
37
  end
37
38
 
38
39
  return [] if result.empty?
@@ -76,7 +77,7 @@ module Solargraph
76
77
  severity: SEVERITIES[off['severity']],
77
78
  source: 'rubocop',
78
79
  code: off['cop_name'],
79
- message: off['message'].gsub(/^#{off['cop_name']}\:/, '')
80
+ message: off['message'].gsub(/^#{off['cop_name']}:/, '')
80
81
  }
81
82
  end
82
83
 
@@ -95,22 +96,22 @@ module Solargraph
95
96
  # @param off [Hash{String => Hash{String => Integer}}]
96
97
  # @return [Position]
97
98
  def offense_ending_position off
98
- if off['location']['start_line'] != off['location']['last_line']
99
- Position.new(off['location']['start_line'], 0)
100
- else
99
+ if off['location']['start_line'] == off['location']['last_line']
101
100
  start_line = off['location']['start_line'] - 1
102
101
  # @type [Integer]
103
102
  last_column = off['location']['last_column']
104
103
  line = @source.code.lines[start_line]
105
104
  col_off = if line.nil? || line.empty?
106
- 1
107
- else
108
- 0
109
- end
105
+ 1
106
+ else
107
+ 0
108
+ end
110
109
 
111
110
  Position.new(
112
111
  start_line, last_column - col_off
113
112
  )
113
+ else
114
+ Position.new(off['location']['start_line'], 0)
114
115
  end
115
116
  end
116
117
  end
@@ -13,17 +13,18 @@ module Solargraph
13
13
  # @param version [String, nil]
14
14
  # @raise [InvalidRubocopVersionError] if _version_ is not installed
15
15
  # @return [void]
16
- def require_rubocop(version = nil)
16
+ def require_rubocop version = nil
17
17
  begin
18
18
  # @type [String]
19
19
  gem_path = Gem::Specification.find_by_name('rubocop', version).full_gem_path
20
20
  gem_lib_path = File.join(gem_path, 'lib')
21
+ # @sg-ignore Should better support meaning of '&' in RBS
21
22
  $LOAD_PATH.unshift(gem_lib_path) unless $LOAD_PATH.include?(gem_lib_path)
22
23
  rescue Gem::MissingSpecVersionError => e
23
24
  # @type [Array<Gem::Specification>]
24
25
  specs = e.specs
25
26
  raise InvalidRubocopVersionError,
26
- "could not find '#{e.name}' (#{e.requirement}) - "\
27
+ "could not find '#{e.name}' (#{e.requirement}) - " \
27
28
  "did find: [#{specs.map { |s| s.version.version }.join(', ')}]"
28
29
  end
29
30
  require 'rubocop'
@@ -50,7 +51,8 @@ module Solargraph
50
51
  # @return [String]
51
52
  def fix_drive_letter path
52
53
  return path unless path.match(/^[a-z]:/)
53
- path[0].upcase + path[1..-1]
54
+ # @sg-ignore Need to add nil check here
55
+ path[0].upcase + path[1..]
54
56
  end
55
57
 
56
58
  # @todo This is a smelly way to redirect output, but the RuboCop specs do
@@ -10,18 +10,19 @@ module Solargraph
10
10
  def diagnose source, api_map
11
11
  # return [] unless args.include?('always') || api_map.workspaced?(source.filename)
12
12
  severity = Diagnostics::Severities::ERROR
13
- level = (args.reverse.find { |a| ['normal', 'typed', 'strict', 'strong'].include?(a) }) || :normal
13
+ level = args.reverse.find { |a| %w[normal typed strict strong].include?(a) } || :normal
14
+ # @sg-ignore sensitive typing needs to handle || on nil types
14
15
  checker = Solargraph::TypeChecker.new(source.filename, api_map: api_map, level: level.to_sym)
15
16
  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
17
+ .sort { |a, b| a.location.range.start.line <=> b.location.range.start.line }
18
+ .map do |problem|
19
+ {
20
+ range: extract_first_line(problem.location, source),
21
+ severity: severity,
22
+ source: 'Typecheck',
23
+ message: problem.message
24
+ }
25
+ end
25
26
  end
26
27
 
27
28
  private
@@ -4,16 +4,12 @@ module Solargraph
4
4
  module Diagnostics
5
5
  class UpdateErrors < Base
6
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,
7
+ combine_ranges(source.code, source.error_ranges).map do |range|
8
+ { range: range.to_hash,
11
9
  severity: Diagnostics::Severities::ERROR,
12
10
  source: 'Solargraph',
13
- message: 'Syntax error'
14
- )
11
+ message: 'Syntax error' }
15
12
  end
16
- result
17
13
  end
18
14
 
19
15
  private
@@ -26,7 +22,7 @@ module Solargraph
26
22
  def combine_ranges code, ranges
27
23
  result = []
28
24
  lines = []
29
- ranges.sort{|a, b| a.start.line <=> b.start.line}.each do |rng|
25
+ ranges.sort { |a, b| a.start.line <=> b.start.line }.each do |rng|
30
26
  next if rng.nil? || lines.include?(rng.start.line)
31
27
  lines.push rng.start.line
32
28
  next if rng.start.line >= code.lines.length
@@ -1,55 +1,55 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- # The Diagnostics library provides reporters for analyzing problems in code
5
- # and providing the results to language server clients.
6
- #
7
- module Diagnostics
8
- autoload :Base, 'solargraph/diagnostics/base'
9
- autoload :Severities, 'solargraph/diagnostics/severities'
10
- autoload :Rubocop, 'solargraph/diagnostics/rubocop'
11
- autoload :RubocopHelpers, 'solargraph/diagnostics/rubocop_helpers'
12
- autoload :RequireNotFound, 'solargraph/diagnostics/require_not_found'
13
- autoload :UpdateErrors, 'solargraph/diagnostics/update_errors'
14
- autoload :TypeCheck, 'solargraph/diagnostics/type_check'
15
-
16
- class << self
17
- # Add a reporter with a name to identify it in .solargraph.yml files.
18
- #
19
- # @param name [String] The name
20
- # @param klass [Class<Solargraph::Diagnostics::Base>] The class implementation
21
- # @return [void]
22
- def register name, klass
23
- reporter_hash[name] = klass
24
- end
25
-
26
- # Get an array of reporter names.
27
- #
28
- # @return [Array<String>]
29
- def reporters
30
- reporter_hash.keys - ['type_not_defined'] # @todo Hide type_not_defined for now
31
- end
32
-
33
- # Find a reporter by name.
34
- #
35
- # @param name [String] The name with which the reporter was registered
36
- # @return [Class<Solargraph::Diagnostics::Base>, nil]
37
- def reporter name
38
- reporter_hash[name]
39
- end
40
-
41
- private
42
-
43
- # @return [Hash{String => Class<Solargraph::Diagnostics::Base>}]
44
- def reporter_hash
45
- @reporter_hash ||= {}
46
- end
47
- end
48
-
49
- register 'rubocop', Rubocop
50
- register 'require_not_found', RequireNotFound
51
- register 'typecheck', TypeCheck
52
- register 'update_errors', UpdateErrors
53
- register 'type_not_defined', TypeCheck # @todo Retained for backwards compatibility
54
- end
55
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ # The Diagnostics library provides reporters for analyzing problems in code
5
+ # and providing the results to language server clients.
6
+ #
7
+ module Diagnostics
8
+ autoload :Base, 'solargraph/diagnostics/base'
9
+ autoload :Severities, 'solargraph/diagnostics/severities'
10
+ autoload :Rubocop, 'solargraph/diagnostics/rubocop'
11
+ autoload :RubocopHelpers, 'solargraph/diagnostics/rubocop_helpers'
12
+ autoload :RequireNotFound, 'solargraph/diagnostics/require_not_found'
13
+ autoload :UpdateErrors, 'solargraph/diagnostics/update_errors'
14
+ autoload :TypeCheck, 'solargraph/diagnostics/type_check'
15
+
16
+ class << self
17
+ # Add a reporter with a name to identify it in .solargraph.yml files.
18
+ #
19
+ # @param name [String] The name
20
+ # @param klass [Class<Solargraph::Diagnostics::Base>] The class implementation
21
+ # @return [void]
22
+ def register name, klass
23
+ reporter_hash[name] = klass
24
+ end
25
+
26
+ # Get an array of reporter names.
27
+ #
28
+ # @return [Array<String>]
29
+ def reporters
30
+ reporter_hash.keys - ['type_not_defined'] # @todo Hide type_not_defined for now
31
+ end
32
+
33
+ # Find a reporter by name.
34
+ #
35
+ # @param name [String] The name with which the reporter was registered
36
+ # @return [Class<Solargraph::Diagnostics::Base>, nil]
37
+ def reporter name
38
+ reporter_hash[name]
39
+ end
40
+
41
+ private
42
+
43
+ # @return [Hash{String => Class<Solargraph::Diagnostics::Base>}]
44
+ def reporter_hash
45
+ @reporter_hash ||= {}
46
+ end
47
+ end
48
+
49
+ register 'rubocop', Rubocop
50
+ register 'require_not_found', RequireNotFound
51
+ register 'typecheck', TypeCheck
52
+ register 'update_errors', UpdateErrors
53
+ register 'type_not_defined', TypeCheck # @todo Retained for backwards compatibility
54
+ end
55
+ end
@@ -46,11 +46,10 @@ module Solargraph
46
46
  attr_reader :environ
47
47
 
48
48
  # @param requires [Array<String>]
49
- # @param preferences [Array<Gem::Specification>]
50
49
  # @param workspace [Workspace, nil]
51
- def initialize(requires, preferences, workspace = nil)
50
+ # @param [Object] out
51
+ def initialize requires, workspace, out: $stderr
52
52
  @requires = requires.compact
53
- @preferences = preferences.compact
54
53
  @workspace = workspace
55
54
  @rbs_collection_path = workspace&.rbs_collection_path
56
55
  @rbs_collection_config_path = workspace&.rbs_collection_config_path
@@ -58,11 +57,13 @@ module Solargraph
58
57
  @requires.concat @environ.requires if @environ
59
58
  load_serialized_gem_pins
60
59
  pins.concat @environ.pins
60
+ @out = out
61
61
  end
62
62
 
63
- # @param out [IO]
63
+ # @param out [IO, StringIO, nil]
64
64
  # @return [void]
65
- def cache_all!(out)
65
+ # @param [Boolean] rebuild
66
+ def cache_all! out, rebuild: false
66
67
  # if we log at debug level:
67
68
  if logger.info?
68
69
  gem_desc = uncached_gemspecs.map { |gemspec| "#{gemspec.name}:#{gemspec.version}" }.join(', ')
@@ -72,7 +73,7 @@ module Solargraph
72
73
  logger.debug { "Caching for RBS collection: #{uncached_rbs_collection_gemspecs.map(&:name)}" }
73
74
  load_serialized_gem_pins
74
75
  uncached_gemspecs.each do |gemspec|
75
- cache(gemspec, out: out)
76
+ cache(gemspec, rebuild: rebuild, out: out)
76
77
  end
77
78
  load_serialized_gem_pins
78
79
  @uncached_rbs_collection_gemspecs = []
@@ -80,18 +81,18 @@ module Solargraph
80
81
  end
81
82
 
82
83
  # @param gemspec [Gem::Specification]
83
- # @param out [IO]
84
+ # @param out [IO, StringIO, nil]
84
85
  # @return [void]
85
- def cache_yard_pins(gemspec, out)
86
+ def cache_yard_pins gemspec, out
86
87
  pins = GemPins.build_yard_pins(yard_plugins, gemspec)
87
88
  PinCache.serialize_yard_gem(gemspec, pins)
88
89
  logger.info { "Cached #{pins.length} YARD pins for gem #{gemspec.name}:#{gemspec.version}" } unless pins.empty?
89
90
  end
90
91
 
91
92
  # @param gemspec [Gem::Specification]
92
- # @param out [IO]
93
+ # @param out [IO, StringIO, nil]
93
94
  # @return [void]
94
- def cache_rbs_collection_pins(gemspec, out)
95
+ def cache_rbs_collection_pins gemspec, out
95
96
  rbs_map = RbsMap.from_gemspec(gemspec, rbs_collection_path, rbs_collection_config_path)
96
97
  pins = rbs_map.pins
97
98
  rbs_version_cache_key = rbs_map.cache_key
@@ -103,16 +104,16 @@ module Solargraph
103
104
 
104
105
  # @param gemspec [Gem::Specification]
105
106
  # @param rebuild [Boolean] whether to rebuild the pins even if they are cached
106
- # @param out [IO, nil] output stream for logging
107
+ # @param out [IO, StringIO, nil] output stream for logging
107
108
  # @return [void]
108
- def cache(gemspec, rebuild: false, out: nil)
109
+ def cache gemspec, rebuild: false, out: nil
109
110
  build_yard = uncached_yard_gemspecs.include?(gemspec) || rebuild
110
111
  build_rbs_collection = uncached_rbs_collection_gemspecs.include?(gemspec) || rebuild
111
112
  if build_yard || build_rbs_collection
112
113
  type = []
113
114
  type << 'YARD' if build_yard
114
115
  type << 'RBS collection' if build_rbs_collection
115
- out.puts("Caching #{type.join(' and ')} pins for gem #{gemspec.name}:#{gemspec.version}") if out
116
+ out&.puts("Caching #{type.join(' and ')} pins for gem #{gemspec.name}:#{gemspec.version}")
116
117
  end
117
118
  cache_yard_pins(gemspec, out) if build_yard
118
119
  cache_rbs_collection_pins(gemspec, out) if build_rbs_collection
@@ -130,12 +131,12 @@ module Solargraph
130
131
 
131
132
  # @return [Hash{Array(String, String) => Array<Pin::Base>}] Indexed by gemspec name and version
132
133
  def self.all_yard_gems_in_memory
133
- @yard_gems_in_memory ||= {}
134
+ @all_yard_gems_in_memory ||= {}
134
135
  end
135
136
 
136
137
  # @return [Hash{String => Hash{Array(String, String) => Array<Pin::Base>}}] stored by RBS collection path
137
138
  def self.all_rbs_collection_gems_in_memory
138
- @rbs_collection_gems_in_memory ||= {}
139
+ @all_rbs_collection_gems_in_memory ||= {}
139
140
  end
140
141
 
141
142
  # @return [Hash{Array(String, String) => Array<Pin::Base>}] Indexed by gemspec name and version
@@ -145,12 +146,13 @@ module Solargraph
145
146
 
146
147
  # @return [Hash{Array(String, String) => Array<Pin::Base>}] Indexed by gemspec name and version
147
148
  def rbs_collection_pins_in_memory
149
+ # @sg-ignore rbs_collection_path is String | nil but used as hash key
148
150
  self.class.all_rbs_collection_gems_in_memory[rbs_collection_path] ||= {}
149
151
  end
150
152
 
151
153
  # @return [Hash{Array(String, String) => Array<Pin::Base>}] Indexed by gemspec name and version
152
154
  def self.all_combined_pins_in_memory
153
- @combined_pins_in_memory ||= {}
155
+ @all_combined_pins_in_memory ||= {}
154
156
  end
155
157
 
156
158
  # @todo this should also include an index by the hash of the RBS collection
@@ -177,18 +179,16 @@ module Solargraph
177
179
  @uncached_yard_gemspecs = []
178
180
  @uncached_rbs_collection_gemspecs = []
179
181
  with_gemspecs, without_gemspecs = required_gems_map.partition { |_, v| v }
180
- # @sg-ignore Need support for RBS duck interfaces like _ToHash
181
182
  # @type [Array<String>]
182
- paths = Hash[without_gemspecs].keys
183
- # @sg-ignore Need support for RBS duck interfaces like _ToHash
183
+ paths = without_gemspecs.to_h.keys
184
184
  # @type [Array<Gem::Specification>]
185
- gemspecs = Hash[with_gemspecs].values.flatten.compact + dependencies.to_a
185
+ gemspecs = with_gemspecs.to_h.values.flatten.compact + dependencies.to_a
186
186
 
187
187
  paths.each do |path|
188
- rbs_pins = deserialize_stdlib_rbs_map path
188
+ deserialize_stdlib_rbs_map path
189
189
  end
190
190
 
191
- logger.debug { "DocMap#load_serialized_gem_pins: Combining pins..." }
191
+ logger.debug { 'DocMap#load_serialized_gem_pins: Combining pins...' }
192
192
  time = Benchmark.measure do
193
193
  gemspecs.each do |gemspec|
194
194
  pins = deserialize_combined_pin_cache gemspec
@@ -232,7 +232,7 @@ module Solargraph
232
232
 
233
233
  # @param gemspec [Gem::Specification]
234
234
  # @return [void]
235
- def deserialize_combined_pin_cache(gemspec)
235
+ def deserialize_combined_pin_cache gemspec
236
236
  unless combined_pins_in_memory[[gemspec.name, gemspec.version]].nil?
237
237
  return combined_pins_in_memory[[gemspec.name, gemspec.version]]
238
238
  end
@@ -263,14 +263,14 @@ module Solargraph
263
263
  if !yard_pins.nil?
264
264
  logger.debug { "Using only YARD pins for #{gemspec.name}:#{gemspec.version}" }
265
265
  combined_pins_in_memory[[gemspec.name, gemspec.version]] = yard_pins
266
- return combined_pins_in_memory[[gemspec.name, gemspec.version]]
266
+ combined_pins_in_memory[[gemspec.name, gemspec.version]]
267
267
  elsif !rbs_collection_pins.nil?
268
268
  logger.debug { "Using only RBS collection pins for #{gemspec.name}:#{gemspec.version}" }
269
269
  combined_pins_in_memory[[gemspec.name, gemspec.version]] = rbs_collection_pins
270
- return combined_pins_in_memory[[gemspec.name, gemspec.version]]
270
+ combined_pins_in_memory[[gemspec.name, gemspec.version]]
271
271
  else
272
272
  logger.debug { "Pins not yet cached for #{gemspec.name}:#{gemspec.version}" }
273
- return nil
273
+ nil
274
274
  end
275
275
  end
276
276
 
@@ -322,9 +322,7 @@ module Solargraph
322
322
  # a Gemfile; Gem doesn't try to index the paths in that case.
323
323
  #
324
324
  # See if we can make a good guess:
325
- potential_gemspec = Gem::Specification.find_by_name(gem_name_guess)
326
- file = "lib/#{path}.rb"
327
- gemspec = potential_gemspec if potential_gemspec.files.any? { |gemspec_file| file == gemspec_file }
325
+ gemspec = Gem::Specification.find_by_name(gem_name_guess)
328
326
  rescue Gem::MissingSpecError
329
327
  logger.debug { "Require path #{path} could not be resolved to a gem via find_by_path or guess of #{gem_name_guess}" }
330
328
  []
@@ -346,7 +344,7 @@ module Solargraph
346
344
  end
347
345
 
348
346
  # @param gemspec [Gem::Specification]
349
- # @param version [Gem::Version]
347
+ # @param version [Gem::Version, String]
350
348
  # @return [Gem::Specification]
351
349
  def change_gemspec_version gemspec, version
352
350
  Gem::Specification.find_by_name(gemspec.name, "= #{version}")
@@ -364,12 +362,10 @@ module Solargraph
364
362
  Solargraph.logger.info "Adding #{spec.name} dependency for #{gemspec.name}"
365
363
  dep = Gem.loaded_specs[spec.name]
366
364
  # @todo is next line necessary?
367
- # @sg-ignore Unresolved call to requirement on Gem::Dependency
368
365
  dep ||= Gem::Specification.find_by_name(spec.name, spec.requirement)
369
366
  deps.merge fetch_dependencies(dep) if deps.add?(dep)
370
367
  rescue Gem::MissingSpecError
371
- # @sg-ignore Unresolved call to requirement on Gem::Dependency
372
- Solargraph.logger.warn "Gem dependency #{spec.name} #{spec.requirement} for #{gemspec.name} not found in RubyGems."
368
+ Solargraph.logger.warn "Gem dependency #{spec.name} for #{gemspec.name} not found in RubyGems."
373
369
  end.to_a
374
370
  end
375
371
 
@@ -379,7 +375,6 @@ module Solargraph
379
375
  gemspec.dependencies - gemspec.development_dependencies
380
376
  end
381
377
 
382
-
383
378
  def inspect
384
379
  self.class.inspect
385
380
  end
@@ -387,9 +382,10 @@ module Solargraph
387
382
  # @return [Array<Gem::Specification>, nil]
388
383
  def gemspecs_required_from_bundler
389
384
  # @todo Handle projects with custom Bundler/Gemfile setups
390
- return unless workspace.gemfile?
385
+ return unless workspace&.gemfile?
391
386
 
392
- if workspace.gemfile? && Bundler.definition&.lockfile&.to_s&.start_with?(workspace.directory)
387
+ # @sg-ignore workspace is checked for nil above
388
+ if workspace.gemfile? && Bundler.definition&.lockfile&.to_s&.start_with?(workspace.directory) # rubocop:disable Style/SafeNavigationChainLength
393
389
  # Find only the gems bundler is now using
394
390
  Bundler.definition.locked_gems.specs.flat_map do |lazy_spec|
395
391
  logger.info "Handling #{lazy_spec.name}:#{lazy_spec.version}"
@@ -407,7 +403,7 @@ module Solargraph
407
403
  end
408
404
  end
409
405
 
410
- # @return [Array<Gem::Specification>, nil]
406
+ # @return [Array<Gem::Specification>]
411
407
  def gemspecs_required_from_external_bundle
412
408
  logger.info 'Fetching gemspecs required from external bundle'
413
409
  return [] unless workspace&.directory
@@ -415,7 +411,8 @@ module Solargraph
415
411
  Solargraph.with_clean_env do
416
412
  cmd = [
417
413
  'ruby', '-e',
418
- "require 'bundler'; require 'json'; Dir.chdir('#{workspace&.directory}') { puts Bundler.definition.locked_gems.specs.map { |spec| [spec.name, spec.version] }.to_h.to_json }"
414
+ # @sg-ignore return above ensures workspace.directory is not nil
415
+ "require 'bundler'; require 'json'; Dir.chdir('#{workspace.directory}') { puts Bundler.definition.locked_gems.specs.map { |spec| [spec.name, spec.version] }.to_h.to_json }"
419
416
  ]
420
417
  o, e, s = Open3.capture3(*cmd)
421
418
  if s.success?
@@ -431,7 +428,9 @@ module Solargraph
431
428
  next specs
432
429
  end.compact
433
430
  else
434
- Solargraph.logger.warn "Failed to load gems from bundle at #{workspace&.directory}: #{e}"
431
+ # @sg-ignore return above ensures workspace.directory is not nil
432
+ Solargraph.logger.warn "Failed to load gems from bundle at #{workspace.directory}: #{e}"
433
+ []
435
434
  end
436
435
  end
437
436
  end
@@ -1,52 +1,52 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- # A collection of additional data, such as map pins and required paths, that
5
- # can be added to an ApiMap.
6
- #
7
- # Conventions are used to add Environs.
8
- #
9
- class Environ
10
- # @return [Array<String>]
11
- attr_reader :requires
12
-
13
- # @return [Array<String>]
14
- attr_reader :domains
15
-
16
- # @return [Array<Pin::Base>]
17
- attr_reader :pins
18
-
19
- # @return [Array<String>]
20
- attr_reader :yard_plugins
21
-
22
- # @param requires [Array<String>]
23
- # @param domains [Array<String>]
24
- # @param pins [Array<Pin::Base>]
25
- # @param yard_plugins [Array<String>]
26
- def initialize requires: [], domains: [], pins: [], yard_plugins: []
27
- @requires = requires
28
- @domains = domains
29
- @pins = pins
30
- @yard_plugins = yard_plugins
31
- end
32
-
33
- # @return [self]
34
- def clear
35
- domains.clear
36
- requires.clear
37
- pins.clear
38
- yard_plugins.clear
39
- self
40
- end
41
-
42
- # @param other [Environ]
43
- # @return [self]
44
- def merge other
45
- domains.concat other.domains
46
- requires.concat other.requires
47
- pins.concat other.pins
48
- yard_plugins.concat other.yard_plugins
49
- self
50
- end
51
- end
52
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ # A collection of additional data, such as map pins and required paths, that
5
+ # can be added to an ApiMap.
6
+ #
7
+ # Conventions are used to add Environs.
8
+ #
9
+ class Environ
10
+ # @return [Array<String>]
11
+ attr_reader :requires
12
+
13
+ # @return [Array<String>]
14
+ attr_reader :domains
15
+
16
+ # @return [Array<Pin::Base>]
17
+ attr_reader :pins
18
+
19
+ # @return [Array<String>]
20
+ attr_reader :yard_plugins
21
+
22
+ # @param requires [Array<String>]
23
+ # @param domains [Array<String>]
24
+ # @param pins [Array<Pin::Base>]
25
+ # @param yard_plugins [Array<String>]
26
+ def initialize requires: [], domains: [], pins: [], yard_plugins: []
27
+ @requires = requires
28
+ @domains = domains
29
+ @pins = pins
30
+ @yard_plugins = yard_plugins
31
+ end
32
+
33
+ # @return [self]
34
+ def clear
35
+ domains.clear
36
+ requires.clear
37
+ pins.clear
38
+ yard_plugins.clear
39
+ self
40
+ end
41
+
42
+ # @param other [Environ]
43
+ # @return [self]
44
+ def merge other
45
+ domains.concat other.domains
46
+ requires.concat other.requires
47
+ pins.concat other.pins
48
+ yard_plugins.concat other.yard_plugins
49
+ self
50
+ end
51
+ end
52
+ end
@@ -10,16 +10,16 @@ module Solargraph
10
10
 
11
11
  # @param other [Object]
12
12
  # @return [Boolean]
13
- def eql?(other)
13
+ def eql? other
14
14
  self.class.eql?(other.class) &&
15
- # @sg-ignore https://github.com/castwide/solargraph/pull/1114
15
+ # @sg-ignore flow sensitive typing should support .class == .class
16
16
  equality_fields.eql?(other.equality_fields)
17
17
  end
18
18
 
19
19
  # @param other [Object]
20
20
  # @return [Boolean]
21
- def ==(other)
22
- self.eql?(other)
21
+ def == other
22
+ eql?(other)
23
23
  end
24
24
 
25
25
  def hash