solargraph 0.58.2 → 0.59.0.dev.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 (203) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +3 -0
  3. data/.github/workflows/linting.yml +4 -5
  4. data/.github/workflows/plugins.yml +41 -34
  5. data/.github/workflows/rspec.yml +44 -23
  6. data/.github/workflows/typecheck.yml +2 -2
  7. data/.rubocop.yml +32 -5
  8. data/.rubocop_todo.yml +50 -966
  9. data/Gemfile +3 -1
  10. data/README.md +3 -3
  11. data/Rakefile +26 -23
  12. data/bin/solargraph +2 -1
  13. data/lib/solargraph/api_map/cache.rb +3 -3
  14. data/lib/solargraph/api_map/constants.rb +13 -3
  15. data/lib/solargraph/api_map/index.rb +23 -18
  16. data/lib/solargraph/api_map/source_to_yard.rb +22 -9
  17. data/lib/solargraph/api_map/store.rb +33 -28
  18. data/lib/solargraph/api_map.rb +150 -82
  19. data/lib/solargraph/bench.rb +44 -45
  20. data/lib/solargraph/complex_type/conformance.rb +176 -0
  21. data/lib/solargraph/complex_type/type_methods.rb +28 -17
  22. data/lib/solargraph/complex_type/unique_type.rb +218 -57
  23. data/lib/solargraph/complex_type.rb +170 -57
  24. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -61
  25. data/lib/solargraph/convention/data_definition/data_definition_node.rb +7 -5
  26. data/lib/solargraph/convention/data_definition.rb +5 -2
  27. data/lib/solargraph/convention/gemfile.rb +15 -15
  28. data/lib/solargraph/convention/gemspec.rb +23 -23
  29. data/lib/solargraph/convention/rakefile.rb +17 -17
  30. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +2 -1
  31. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +4 -3
  32. data/lib/solargraph/convention/struct_definition.rb +8 -4
  33. data/lib/solargraph/convention.rb +78 -78
  34. data/lib/solargraph/converters/dd.rb +19 -17
  35. data/lib/solargraph/converters/dl.rb +17 -15
  36. data/lib/solargraph/converters/dt.rb +17 -15
  37. data/lib/solargraph/converters/misc.rb +3 -1
  38. data/lib/solargraph/diagnostics/require_not_found.rb +1 -0
  39. data/lib/solargraph/diagnostics/rubocop.rb +11 -10
  40. data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
  41. data/lib/solargraph/diagnostics/type_check.rb +11 -10
  42. data/lib/solargraph/diagnostics/update_errors.rb +37 -41
  43. data/lib/solargraph/doc_map.rb +133 -373
  44. data/lib/solargraph/equality.rb +4 -4
  45. data/lib/solargraph/gem_pins.rb +21 -20
  46. data/lib/solargraph/language_server/error_codes.rb +20 -20
  47. data/lib/solargraph/language_server/host/diagnoser.rb +1 -1
  48. data/lib/solargraph/language_server/host/dispatch.rb +3 -3
  49. data/lib/solargraph/language_server/host/message_worker.rb +4 -3
  50. data/lib/solargraph/language_server/host/sources.rb +2 -1
  51. data/lib/solargraph/language_server/host.rb +30 -22
  52. data/lib/solargraph/language_server/message/base.rb +97 -97
  53. data/lib/solargraph/language_server/message/client/register_capability.rb +13 -15
  54. data/lib/solargraph/language_server/message/completion_item/resolve.rb +58 -60
  55. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +12 -18
  56. data/lib/solargraph/language_server/message/extended/document.rb +1 -0
  57. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
  58. data/lib/solargraph/language_server/message/extended/download_core.rb +20 -19
  59. data/lib/solargraph/language_server/message/extended/search.rb +20 -20
  60. data/lib/solargraph/language_server/message/initialize.rb +197 -191
  61. data/lib/solargraph/language_server/message/text_document/completion.rb +10 -8
  62. data/lib/solargraph/language_server/message/text_document/definition.rb +41 -32
  63. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +23 -16
  64. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +29 -19
  65. data/lib/solargraph/language_server/message/text_document/formatting.rb +8 -6
  66. data/lib/solargraph/language_server/message/text_document/hover.rb +5 -5
  67. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +18 -11
  68. data/lib/solargraph/language_server/message/text_document/references.rb +23 -16
  69. data/lib/solargraph/language_server/message/text_document/rename.rb +26 -19
  70. data/lib/solargraph/language_server/message/text_document/signature_help.rb +3 -2
  71. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -17
  72. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +41 -35
  73. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +48 -40
  74. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +32 -26
  75. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +27 -17
  76. data/lib/solargraph/language_server/message.rb +94 -94
  77. data/lib/solargraph/language_server/request.rb +29 -27
  78. data/lib/solargraph/language_server/transport/data_reader.rb +72 -74
  79. data/lib/solargraph/language_server/uri_helpers.rb +49 -49
  80. data/lib/solargraph/library.rb +85 -44
  81. data/lib/solargraph/location.rb +17 -14
  82. data/lib/solargraph/logging.rb +24 -4
  83. data/lib/solargraph/page.rb +92 -92
  84. data/lib/solargraph/parser/comment_ripper.rb +19 -4
  85. data/lib/solargraph/parser/flow_sensitive_typing.rb +326 -108
  86. data/lib/solargraph/parser/node_processor/base.rb +34 -4
  87. data/lib/solargraph/parser/node_processor.rb +8 -7
  88. data/lib/solargraph/parser/parser_gem/class_methods.rb +32 -14
  89. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +19 -19
  90. data/lib/solargraph/parser/parser_gem/node_chainer.rb +50 -25
  91. data/lib/solargraph/parser/parser_gem/node_methods.rb +91 -70
  92. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +4 -4
  93. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +13 -11
  94. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +9 -0
  95. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +12 -12
  96. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +10 -3
  97. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +38 -37
  98. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +36 -6
  99. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +5 -3
  100. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +1 -0
  101. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +3 -1
  102. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +3 -3
  103. data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
  104. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -1
  105. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
  106. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -5
  107. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +124 -113
  108. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -29
  109. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
  110. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +6 -2
  111. data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
  112. data/lib/solargraph/parser/parser_gem.rb +14 -12
  113. data/lib/solargraph/parser/region.rb +9 -3
  114. data/lib/solargraph/parser/snippet.rb +3 -1
  115. data/lib/solargraph/parser.rb +25 -23
  116. data/lib/solargraph/pin/base.rb +126 -80
  117. data/lib/solargraph/pin/base_variable.rb +273 -24
  118. data/lib/solargraph/pin/block.rb +29 -6
  119. data/lib/solargraph/pin/breakable.rb +7 -1
  120. data/lib/solargraph/pin/callable.rb +65 -21
  121. data/lib/solargraph/pin/closure.rb +7 -10
  122. data/lib/solargraph/pin/common.rb +24 -6
  123. data/lib/solargraph/pin/compound_statement.rb +55 -0
  124. data/lib/solargraph/pin/constant.rb +43 -45
  125. data/lib/solargraph/pin/conversions.rb +10 -4
  126. data/lib/solargraph/pin/delegated_method.rb +19 -8
  127. data/lib/solargraph/pin/documenting.rb +4 -2
  128. data/lib/solargraph/pin/instance_variable.rb +5 -1
  129. data/lib/solargraph/pin/keyword.rb +0 -4
  130. data/lib/solargraph/pin/local_variable.rb +15 -59
  131. data/lib/solargraph/pin/method.rb +153 -104
  132. data/lib/solargraph/pin/method_alias.rb +8 -0
  133. data/lib/solargraph/pin/namespace.rb +19 -12
  134. data/lib/solargraph/pin/parameter.rb +100 -36
  135. data/lib/solargraph/pin/proxy_type.rb +4 -1
  136. data/lib/solargraph/pin/reference/override.rb +1 -1
  137. data/lib/solargraph/pin/reference/superclass.rb +2 -0
  138. data/lib/solargraph/pin/reference.rb +19 -0
  139. data/lib/solargraph/pin/search.rb +3 -2
  140. data/lib/solargraph/pin/signature.rb +15 -12
  141. data/lib/solargraph/pin/symbol.rb +2 -1
  142. data/lib/solargraph/pin/until.rb +2 -4
  143. data/lib/solargraph/pin/while.rb +2 -4
  144. data/lib/solargraph/pin.rb +2 -0
  145. data/lib/solargraph/pin_cache.rb +490 -73
  146. data/lib/solargraph/position.rb +14 -10
  147. data/lib/solargraph/range.rb +16 -15
  148. data/lib/solargraph/rbs_map/conversions.rb +343 -214
  149. data/lib/solargraph/rbs_map/core_fills.rb +91 -84
  150. data/lib/solargraph/rbs_map/core_map.rb +24 -17
  151. data/lib/solargraph/rbs_map/stdlib_map.rb +33 -5
  152. data/lib/solargraph/rbs_map.rb +77 -32
  153. data/lib/solargraph/server_methods.rb +16 -16
  154. data/lib/solargraph/shell.rb +128 -73
  155. data/lib/solargraph/source/chain/array.rb +39 -37
  156. data/lib/solargraph/source/chain/call.rb +96 -56
  157. data/lib/solargraph/source/chain/class_variable.rb +13 -13
  158. data/lib/solargraph/source/chain/constant.rb +5 -1
  159. data/lib/solargraph/source/chain/global_variable.rb +13 -13
  160. data/lib/solargraph/source/chain/hash.rb +8 -5
  161. data/lib/solargraph/source/chain/if.rb +12 -10
  162. data/lib/solargraph/source/chain/instance_variable.rb +24 -1
  163. data/lib/solargraph/source/chain/link.rb +99 -109
  164. data/lib/solargraph/source/chain/literal.rb +9 -6
  165. data/lib/solargraph/source/chain/or.rb +10 -4
  166. data/lib/solargraph/source/chain/q_call.rb +13 -11
  167. data/lib/solargraph/source/chain/variable.rb +15 -13
  168. data/lib/solargraph/source/chain/z_super.rb +28 -30
  169. data/lib/solargraph/source/chain.rb +49 -38
  170. data/lib/solargraph/source/change.rb +12 -5
  171. data/lib/solargraph/source/cursor.rb +23 -17
  172. data/lib/solargraph/source/encoding_fixes.rb +6 -7
  173. data/lib/solargraph/source/source_chainer.rb +56 -32
  174. data/lib/solargraph/source/updater.rb +5 -1
  175. data/lib/solargraph/source.rb +59 -35
  176. data/lib/solargraph/source_map/clip.rb +48 -29
  177. data/lib/solargraph/source_map/data.rb +4 -1
  178. data/lib/solargraph/source_map/mapper.rb +71 -42
  179. data/lib/solargraph/source_map.rb +21 -9
  180. data/lib/solargraph/type_checker/problem.rb +3 -1
  181. data/lib/solargraph/type_checker/rules.rb +81 -8
  182. data/lib/solargraph/type_checker.rb +195 -120
  183. data/lib/solargraph/version.rb +1 -1
  184. data/lib/solargraph/workspace/config.rb +13 -10
  185. data/lib/solargraph/workspace/gemspecs.rb +367 -0
  186. data/lib/solargraph/workspace/require_paths.rb +1 -0
  187. data/lib/solargraph/workspace.rb +149 -30
  188. data/lib/solargraph/yard_map/helpers.rb +8 -3
  189. data/lib/solargraph/yard_map/mapper/to_method.rb +13 -7
  190. data/lib/solargraph/yard_map/mapper/to_namespace.rb +2 -1
  191. data/lib/solargraph/yard_map/mapper.rb +13 -8
  192. data/lib/solargraph/yard_tags.rb +20 -20
  193. data/lib/solargraph/yardoc.rb +33 -23
  194. data/lib/solargraph.rb +29 -8
  195. data/rbs/fills/rubygems/0/dependency.rbs +193 -0
  196. data/rbs/fills/tuple/tuple.rbs +28 -0
  197. data/rbs/shims/ast/0/node.rbs +1 -1
  198. data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
  199. data/solargraph.gemspec +36 -34
  200. metadata +38 -33
  201. data/lib/solargraph/type_checker/checks.rb +0 -124
  202. data/lib/solargraph/type_checker/param_def.rb +0 -37
  203. data/lib/solargraph/yard_map/to_method.rb +0 -89
@@ -3,6 +3,7 @@
3
3
  require 'benchmark'
4
4
  require 'thor'
5
5
  require 'yard'
6
+ require 'yaml'
6
7
 
7
8
  module Solargraph
8
9
  class Shell < Thor
@@ -15,7 +16,7 @@ module Solargraph
15
16
 
16
17
  map %w[--version -v] => :version
17
18
 
18
- desc "--version, -v", "Print the version"
19
+ desc '--version, -v', 'Print the version'
19
20
  # @return [void]
20
21
  def version
21
22
  puts Solargraph::VERSION
@@ -30,15 +31,15 @@ module Solargraph
30
31
  port = options[:port]
31
32
  port = available_port if port.zero?
32
33
  Backport.run do
33
- Signal.trap("INT") do
34
+ Signal.trap('INT') do
34
35
  Backport.stop
35
36
  end
36
- Signal.trap("TERM") do
37
+ Signal.trap('TERM') do
37
38
  Backport.stop
38
39
  end
39
40
  # @sg-ignore Wrong argument type for Backport.prepare_tcp_server: adapter expected Backport::Adapter, received Module<Solargraph::LanguageServer::Transport::Adapter>
40
41
  Backport.prepare_tcp_server host: options[:host], port: port, adapter: Solargraph::LanguageServer::Transport::Adapter
41
- STDERR.puts "Solargraph is listening PORT=#{port} PID=#{Process.pid}"
42
+ warn "Solargraph is listening PORT=#{port} PID=#{Process.pid}"
42
43
  end
43
44
  end
44
45
 
@@ -47,15 +48,15 @@ module Solargraph
47
48
  def stdio
48
49
  require 'backport'
49
50
  Backport.run do
50
- Signal.trap("INT") do
51
+ Signal.trap('INT') do
51
52
  Backport.stop
52
53
  end
53
- Signal.trap("TERM") do
54
+ Signal.trap('TERM') do
54
55
  Backport.stop
55
56
  end
56
57
  # @sg-ignore Wrong argument type for Backport.prepare_stdio_server: adapter expected Backport::Adapter, received Module<Solargraph::LanguageServer::Transport::Adapter>
57
58
  Backport.prepare_stdio_server adapter: Solargraph::LanguageServer::Transport::Adapter
58
- STDERR.puts "Solargraph is listening on stdio PID=#{Process.pid}"
59
+ warn "Solargraph is listening on stdio PID=#{Process.pid}"
59
60
  end
60
61
  end
61
62
 
@@ -63,11 +64,11 @@ module Solargraph
63
64
  option :extensions, type: :boolean, aliases: :e, desc: 'Add installed extensions', default: true
64
65
  # @param directory [String]
65
66
  # @return [void]
66
- def config(directory = '.')
67
+ def config directory = '.'
67
68
  matches = []
68
69
  if options[:extensions]
69
70
  Gem::Specification.each do |g|
70
- if g.name.match(/^solargraph\-[A-Za-z0-9_\-]*?\-ext/)
71
+ if g.name.match(/^solargraph-[A-Za-z0-9_-]*?-ext/)
71
72
  require g.name
72
73
  matches.push g.name
73
74
  end
@@ -83,7 +84,7 @@ module Solargraph
83
84
  File.open(File.join(directory, '.solargraph.yml'), 'w') do |file|
84
85
  file.puts conf.to_yaml
85
86
  end
86
- STDOUT.puts "Configuration file initialized."
87
+ $stdout.puts 'Configuration file initialized.'
87
88
  end
88
89
 
89
90
  desc 'clear', 'Delete all cached documentation'
@@ -92,7 +93,7 @@ module Solargraph
92
93
  )
93
94
  # @return [void]
94
95
  def clear
95
- puts "Deleting all cached documentation (gems, core and stdlib)"
96
+ puts 'Deleting all cached documentation (gems, core and stdlib)'
96
97
  Solargraph::PinCache.clear
97
98
  end
98
99
  map 'clear-cache' => :clear
@@ -104,12 +105,11 @@ module Solargraph
104
105
  # @param gem [String]
105
106
  # @param version [String, nil]
106
107
  def cache gem, version = nil
107
- api_map = Solargraph::ApiMap.load(Dir.pwd)
108
- spec = Gem::Specification.find_by_name(gem, version)
109
- api_map.cache_gem(spec, rebuild: options[:rebuild], out: $stdout)
108
+ gems(gem + (version ? "=#{version}" : ''))
109
+ # '
110
110
  end
111
111
 
112
- desc 'uncache GEM [...GEM]', "Delete specific cached gem documentation"
112
+ desc 'uncache GEM [...GEM]', 'Delete specific cached gem documentation'
113
113
  long_desc %(
114
114
  Specify one or more gem names to clear. 'core' or 'stdlib' may
115
115
  also be specified to clear cached system documentation.
@@ -119,39 +119,83 @@ module Solargraph
119
119
  # @return [void]
120
120
  def uncache *gems
121
121
  raise ArgumentError, 'No gems specified.' if gems.empty?
122
+ workspace = Solargraph::Workspace.new(Dir.pwd)
123
+
122
124
  gems.each do |gem|
123
125
  if gem == 'core'
124
- PinCache.uncache_core
126
+ PinCache.uncache_core(out: $stdout)
125
127
  next
126
128
  end
127
129
 
128
130
  if gem == 'stdlib'
129
- PinCache.uncache_stdlib
131
+ PinCache.uncache_stdlib(out: $stdout)
130
132
  next
131
133
  end
132
134
 
133
- spec = Gem::Specification.find_by_name(gem)
134
- PinCache.uncache_gem(spec, out: $stdout)
135
+ spec = workspace.find_gem(gem)
136
+ raise Thor::InvocationError, "Gem '#{gem}' not found" if spec.nil?
137
+
138
+ # @sg-ignore flow sensitive typing needs to handle 'raise if'
139
+ workspace.uncache_gem(spec, out: $stdout)
135
140
  end
136
141
  end
137
142
 
138
- desc 'gems [GEM[=VERSION]]', 'Cache documentation for installed gems'
143
+ desc 'gems [GEM[=VERSION]...] [STDLIB...] [core]', 'Cache documentation for
144
+ installed libraries'
145
+ long_desc %( This command will cache the
146
+ generated type documentation for the specified libraries. While
147
+ Solargraph will generate this on the fly when needed, it takes
148
+ time. This command will generate it in advance, which can be
149
+ useful for CI scenarios.
150
+
151
+ With no arguments, it will cache all libraries in the current
152
+ workspace. If a gem or standard library name is specified, it
153
+ will cache that library's type documentation.
154
+
155
+ An equals sign after a gem will allow a specific gem version
156
+ to be cached.
157
+
158
+ The 'core' argument can be used to cache the type
159
+ documentation for the core Ruby libraries.
160
+
161
+ If the library is already cached, it will be rebuilt if the
162
+ --rebuild option is set.
163
+
164
+ Cached documentation is stored in #{PinCache.base_dir}, which
165
+ can be stored between CI runs.
166
+ )
139
167
  option :rebuild, type: :boolean, desc: 'Rebuild existing documentation', default: false
140
168
  # @param names [Array<String>]
141
169
  # @return [void]
142
170
  def gems *names
143
- api_map = ApiMap.load('.')
171
+ # print time with ms
172
+ workspace = Solargraph::Workspace.new('.')
173
+
144
174
  if names.empty?
145
- Gem::Specification.to_a.each { |spec| do_cache spec, api_map }
146
- STDERR.puts "Documentation cached for all #{Gem::Specification.count} gems."
175
+ workspace.cache_all_for_workspace!($stdout, rebuild: options[:rebuild])
147
176
  else
177
+ warn("Caching these gems: #{names}")
148
178
  names.each do |name|
149
- spec = Gem::Specification.find_by_name(*name.split('='))
150
- do_cache spec, api_map
179
+ if name == 'core'
180
+ PinCache.cache_core(out: $stdout) if !PinCache.core? || options[:rebuild]
181
+ next
182
+ end
183
+
184
+ gemspec = workspace.find_gem(*name.split('='))
185
+ if gemspec.nil?
186
+ warn "Gem '#{name}' not found"
187
+ else
188
+ workspace.cache_gem(gemspec, rebuild: options[:rebuild], out: $stdout)
189
+ end
151
190
  rescue Gem::MissingSpecError
152
191
  warn "Gem '#{name}' not found"
192
+ rescue Gem::Requirement::BadRequirementError => e
193
+ warn "Gem '#{name}' failed while loading"
194
+ warn e.message
195
+ # @sg-ignore Need to add nil check here
196
+ warn e.backtrace.join("\n")
153
197
  end
154
- STDERR.puts "Documentation cached for #{names.count} gems."
198
+ warn "Documentation cached for #{names.count} gems."
155
199
  end
156
200
  end
157
201
 
@@ -168,7 +212,7 @@ module Solargraph
168
212
 
169
213
  Type checking levels are normal, typed, strict, and strong.
170
214
  )
171
- option :level, type: :string, aliases: [:mode, :m, :l], desc: 'Type checking level', default: 'normal'
215
+ option :level, type: :string, aliases: %i[mode m l], desc: 'Type checking level', default: 'normal'
172
216
  option :directory, type: :string, aliases: :d, desc: 'The workspace directory', default: '.'
173
217
  # @return [void]
174
218
  def typecheck *files
@@ -176,7 +220,10 @@ module Solargraph
176
220
  workspace = Solargraph::Workspace.new(directory)
177
221
  level = options[:level].to_sym
178
222
  rules = workspace.rules(level)
179
- api_map = Solargraph::ApiMap.load_with_cache(directory, $stdout)
223
+ api_map =
224
+ Solargraph::ApiMap.load_with_cache(directory, $stdout,
225
+ loose_unions:
226
+ !rules.require_all_unique_types_support_call?)
180
227
  probcount = 0
181
228
  if files.empty?
182
229
  files = api_map.source_maps.map(&:filename)
@@ -184,23 +231,28 @@ module Solargraph
184
231
  files.map! { |file| File.realpath(file) }
185
232
  end
186
233
  filecount = 0
187
-
188
- time = Benchmark.measure {
234
+ time = Benchmark.measure do
189
235
  files.each do |file|
190
- checker = TypeChecker.new(file, api_map: api_map, level: options[:level].to_sym, workspace: workspace)
236
+ checker = TypeChecker.new(file, api_map: api_map, rules: rules, level: options[:level].to_sym,
237
+ workspace: workspace)
191
238
  problems = checker.problems
192
239
  next if problems.empty?
193
240
  problems.sort! { |a, b| a.location.range.start.line <=> b.location.range.start.line }
194
- puts problems.map { |prob| "#{prob.location.filename}:#{prob.location.range.start.line + 1} - #{prob.message}" }.join("\n")
241
+ puts problems.map { |prob|
242
+ "#{prob.location.filename}:#{prob.location.range.start.line + 1} - #{prob.message}"
243
+ }.join("\n")
195
244
  filecount += 1
196
245
  probcount += problems.length
197
246
  end
198
- # "
199
- }
247
+ end
200
248
  puts "Typecheck finished in #{time.real} seconds."
201
- puts "#{probcount} problem#{probcount != 1 ? 's' : ''} found#{files.length != 1 ? " in #{filecount} of #{files.length} files" : ''}."
249
+ puts "#{probcount} problem#{if probcount != 1
250
+ 's'
251
+ end} found#{if files.length != 1
252
+ " in #{filecount} of #{files.length} files"
253
+ end}."
202
254
  # "
203
- exit 1 if probcount > 0
255
+ exit 1 if probcount.positive?
204
256
  end
205
257
 
206
258
  desc 'scan', 'Test the workspace for problems'
@@ -217,21 +269,27 @@ module Solargraph
217
269
  directory = File.realpath(options[:directory])
218
270
  # @type [Solargraph::ApiMap, nil]
219
271
  api_map = nil
220
- time = Benchmark.measure {
272
+ time = Benchmark.measure do
221
273
  api_map = Solargraph::ApiMap.load_with_cache(directory, $stdout)
274
+ # @sg-ignore flow sensitive typing should be able to handle redefinition
222
275
  api_map.pins.each do |pin|
223
- begin
224
- puts pin_description(pin) if options[:verbose]
225
- pin.typify api_map
226
- pin.probe api_map
227
- rescue StandardError => e
228
- STDERR.puts "Error testing #{pin_description(pin)} #{pin.location ? "at #{pin.location.filename}:#{pin.location.range.start.line + 1}" : ''}"
229
- STDERR.puts "[#{e.class}]: #{e.message}"
230
- STDERR.puts e.backtrace.join("\n")
231
- exit 1
232
- end
276
+ puts pin_description(pin) if options[:verbose]
277
+ pin.typify api_map
278
+ pin.probe api_map
279
+ rescue StandardError => e
280
+ # @todo to add nil check here
281
+ # @todo should warn on nil dereference below
282
+ warn "Error testing #{pin_description(pin)} #{if pin.location
283
+ "at #{pin.location.filename}:#{pin.location.range.start.line + 1}"
284
+ end}"
285
+ warn "[#{e.class}]: #{e.message}"
286
+ # @todo Need to add nil check here
287
+ # @todo flow sensitive typing should be able to handle redefinition
288
+ warn e.backtrace.join("\n")
289
+ exit 1
233
290
  end
234
- }
291
+ end
292
+ # @sg-ignore Need to add nil check here
235
293
  puts "Scanned #{directory} (#{api_map.pins.length} pins) in #{time.real} seconds."
236
294
  end
237
295
 
@@ -245,12 +303,15 @@ module Solargraph
245
303
  puts "#{workspace.filenames.length} files total."
246
304
  end
247
305
 
248
- desc 'pin [PATH]', 'Describe a pin', hide: true
306
+ desc 'pin [PATH]', 'Describe a pin'
249
307
  option :rbs, type: :boolean, desc: 'Output the pin as RBS', default: false
250
- option :typify, type: :boolean, desc: 'Output the calculated return type of the pin from annotations', default: false
308
+ option :typify, type: :boolean, desc: 'Output the calculated return type of the pin from annotations',
309
+ default: false
251
310
  option :references, type: :boolean, desc: 'Show references', default: false
252
- option :probe, type: :boolean, desc: 'Output the calculated return type of the pin from annotations and inference', default: false
253
- option :stack, type: :boolean, desc: 'Show entire stack of a method pin by including definitions in superclasses', default: false
311
+ option :probe, type: :boolean, desc: 'Output the calculated return type of the pin from annotations and inference',
312
+ default: false
313
+ option :stack, type: :boolean, desc: 'Show entire stack of a method pin by including definitions in superclasses',
314
+ default: false
254
315
  # @param path [String] The path to the method pin, e.g. 'Class#method' or 'Class.method'
255
316
  # @return [void]
256
317
  def pin path
@@ -275,10 +336,11 @@ module Solargraph
275
336
  pin = pins.first
276
337
  case pin
277
338
  when nil
278
- $stderr.puts "Pin not found for path '#{path}'"
339
+ warn "Pin not found for path '#{path}'"
279
340
  exit 1
280
341
  when Pin::Namespace
281
342
  if options[:references]
343
+ # @sg-ignore Need to add nil check here
282
344
  superclass_tag = api_map.qualify_superclass(pin.return_type.tag)
283
345
  superclass_pin = api_map.get_path_pins(superclass_tag).first if superclass_tag
284
346
  references[:superclass] = superclass_pin if superclass_pin
@@ -308,30 +370,23 @@ module Solargraph
308
370
  # @return [String]
309
371
  def pin_description pin
310
372
  desc = if pin.path.nil? || pin.path.empty?
311
- if pin.closure
312
- "#{pin.closure.path} | #{pin.name}"
313
- else
314
- "#{pin.context.namespace} | #{pin.name}"
315
- end
316
- else
317
- pin.path
318
- end
373
+ if pin.closure
374
+ # @sg-ignore Need to add nil check here
375
+ "#{pin.closure.path} | #{pin.name}"
376
+ else
377
+ "#{pin.context.namespace} | #{pin.name}"
378
+ end
379
+ else
380
+ pin.path
381
+ end
382
+ # @sg-ignore Need to add nil check here
319
383
  desc += " (#{pin.location.filename} #{pin.location.range.start.line})" if pin.location
320
384
  desc
321
385
  end
322
386
 
323
- # @param gemspec [Gem::Specification]
324
- # @param api_map [ApiMap]
325
- # @return [void]
326
- def do_cache gemspec, api_map
327
- # @todo if the rebuild: option is passed as a positional arg,
328
- # typecheck doesn't complain on the below line
329
- api_map.cache_gem(gemspec, rebuild: options.rebuild, out: $stdout)
330
- end
331
-
332
- # @param type [ComplexType]
387
+ # @param type [ComplexType, ComplexType::UniqueType]
333
388
  # @return [void]
334
- def print_type(type)
389
+ def print_type type
335
390
  if options[:rbs]
336
391
  puts type.to_rbs
337
392
  else
@@ -341,7 +396,7 @@ module Solargraph
341
396
 
342
397
  # @param pin [Solargraph::Pin::Base]
343
398
  # @return [void]
344
- def print_pin(pin)
399
+ def print_pin pin
345
400
  if options[:rbs]
346
401
  puts pin.to_rbs
347
402
  else
@@ -1,37 +1,39 @@
1
- module Solargraph
2
- class Source
3
- class Chain
4
- class Array < Literal
5
- # @param children [::Array<Chain>]
6
- # @param node [Parser::AST::Node]
7
- def initialize children, node
8
- super('::Array', node)
9
- @children = children
10
- end
11
-
12
- def word
13
- @word ||= "<#{@type}>"
14
- end
15
-
16
- # @param api_map [ApiMap]
17
- # @param name_pin [Pin::Base]
18
- # @param locals [::Array<Pin::Parameter, Pin::LocalVariable>]
19
- def resolve api_map, name_pin, locals
20
- child_types = @children.map do |child|
21
- child.infer(api_map, name_pin, locals).simplify_literals
22
- end
23
- type = if child_types.length == 0 || child_types.any?(&:undefined?)
24
- ComplexType::UniqueType.new('Array', rooted: true)
25
- elsif child_types.uniq.length == 1 && child_types.first.defined?
26
- ComplexType::UniqueType.new('Array', [], child_types.uniq, rooted: true, parameters_type: :list)
27
- elsif child_types.length == 0
28
- ComplexType::UniqueType.new('Array', rooted: true, parameters_type: :list)
29
- else
30
- ComplexType::UniqueType.new('Array', [], child_types, rooted: true, parameters_type: :fixed)
31
- end
32
- [Pin::ProxyType.anonymous(type, source: :chain)]
33
- end
34
- end
35
- end
36
- end
37
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ class Chain
6
+ class Array < Literal
7
+ # @param children [::Array<Chain>]
8
+ # @param node [Parser::AST::Node]
9
+ def initialize children, node
10
+ super('::Array', node)
11
+ @children = children
12
+ end
13
+
14
+ def word
15
+ @word ||= "<#{@type}>"
16
+ end
17
+
18
+ # @param api_map [ApiMap]
19
+ # @param name_pin [Pin::Base]
20
+ # @param locals [::Array<Pin::Parameter, Pin::LocalVariable>]
21
+ def resolve api_map, name_pin, locals
22
+ child_types = @children.map do |child|
23
+ child.infer(api_map, name_pin, locals).simplify_literals
24
+ end
25
+ type = if child_types.empty? || child_types.any?(&:undefined?)
26
+ ComplexType::UniqueType.new('Array', rooted: true)
27
+ elsif child_types.uniq.length == 1 && child_types.first.defined?
28
+ ComplexType::UniqueType.new('Array', [], child_types.uniq, rooted: true, parameters_type: :list)
29
+ elsif child_types.empty?
30
+ ComplexType::UniqueType.new('Array', rooted: true, parameters_type: :list)
31
+ else
32
+ ComplexType::UniqueType.new('Array', [], child_types, rooted: true, parameters_type: :fixed)
33
+ end
34
+ [Pin::ProxyType.anonymous(type, source: :chain)]
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end