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
@@ -12,7 +12,7 @@ module Solargraph
12
12
 
13
13
  private_class_method :new
14
14
 
15
- DIRECTIVE_REGEXP = /(@\!method|@\!attribute|@\!visibility|@\!domain|@\!macro|@\!parse|@\!override)/.freeze
15
+ DIRECTIVE_REGEXP = /(@!method|@!attribute|@!visibility|@!domain|@!macro|@!parse|@!override)/
16
16
 
17
17
  # Generate the data.
18
18
  #
@@ -24,14 +24,15 @@ module Solargraph
24
24
  @code = source.code
25
25
  @comments = source.comments
26
26
  @pins, @locals = Parser.map(source)
27
+ # @param p [Solargraph::Pin::Base]
27
28
  @pins.each { |p| p.source = :code }
28
29
  @locals.each { |l| l.source = :code }
29
30
  process_comment_directives
30
31
  [@pins, @locals]
31
- # rescue Exception => e
32
- # Solargraph.logger.warn "Error mapping #{source.filename}: [#{e.class}] #{e.message}"
33
- # Solargraph.logger.warn e.backtrace.join("\n")
34
- # [[], []]
32
+ # rescue Exception => e
33
+ # Solargraph.logger.warn "Error mapping #{source.filename}: [#{e.class}] #{e.message}"
34
+ # Solargraph.logger.warn e.backtrace.join("\n")
35
+ # [[], []]
35
36
  end
36
37
 
37
38
  # @param filename [String]
@@ -48,6 +49,7 @@ module Solargraph
48
49
  # @param source [Source]
49
50
  # @return [Array]
50
51
  def map source
52
+ # @sg-ignore Need to add nil check here
51
53
  return new.unmap(source.filename, source.code) unless source.parsed?
52
54
  new.map source
53
55
  end
@@ -61,8 +63,9 @@ module Solargraph
61
63
 
62
64
  # @param position [Solargraph::Position]
63
65
  # @return [Solargraph::Pin::Closure]
64
- def closure_at(position)
65
- pins.select{|pin| pin.is_a?(Pin::Closure) and pin.location.range.contain?(position)}.last
66
+ def closure_at position
67
+ # @sg-ignore Need to add nil check here
68
+ pins.select { |pin| pin.is_a?(Pin::Closure) and pin.location.range.contain?(position) }.last
66
69
  end
67
70
 
68
71
  # @param source_position [Position]
@@ -90,11 +93,13 @@ module Solargraph
90
93
  def find_directive_line_number comment, tag, start
91
94
  # Avoid overruning the index
92
95
  return start unless start < comment.lines.length
93
- num = comment.lines[start..-1].find_index do |line|
96
+ # @sg-ignore Need to add nil check here
97
+ num = comment.lines[start..].find_index do |line|
94
98
  # Legacy method directives might be `@method` instead of `@!method`
95
99
  # @todo Legacy syntax should probably emit a warning
96
100
  line.include?("@!#{tag}") || (tag == 'method' && line.include?("@#{tag}"))
97
101
  end
102
+ # @sg-ignore Need to add nil check here
98
103
  num.to_i + start
99
104
  end
100
105
 
@@ -103,35 +108,37 @@ module Solargraph
103
108
  # @param directive [YARD::Tags::Directive]
104
109
  # @return [void]
105
110
  def process_directive source_position, comment_position, directive
111
+ # @sg-ignore Need to add nil check here
106
112
  docstring = Solargraph::Source.parse_docstring(directive.tag.text).to_docstring
107
113
  location = Location.new(@filename, Range.new(comment_position, comment_position))
108
114
  case directive.tag.tag_name
109
115
  when 'method'
110
116
  namespace = closure_at(source_position) || @pins.first
111
- if namespace.location.range.start.line < comment_position.line
112
- namespace = closure_at(comment_position)
113
- end
117
+ # @sg-ignore Need to add nil check here
118
+ namespace = closure_at(comment_position) if namespace.location.range.start.line < comment_position.line
114
119
  begin
115
120
  src = Solargraph::Source.load_string("def #{directive.tag.name};end", @source.filename)
116
121
  region = Parser::Region.new(source: src, closure: namespace)
122
+ # @type [Array<Pin::Method>]
117
123
  method_gen_pins = Parser.process_node(src.node, region).first.select { |pin| pin.is_a?(Pin::Method) }
118
124
  gen_pin = method_gen_pins.last
119
125
  return if gen_pin.nil?
120
126
  # Move the location to the end of the line so it gets recognized
121
127
  # as originating from a comment
122
- shifted = Solargraph::Position.new(comment_position.line, @code.lines[comment_position.line].to_s.chomp.length)
128
+ shifted = Solargraph::Position.new(comment_position.line,
129
+ @code.lines[comment_position.line].to_s.chomp.length)
123
130
  # @todo: Smelly instance variable access
124
131
  gen_pin.instance_variable_set(:@comments, docstring.all.to_s)
125
132
  gen_pin.instance_variable_set(:@location, Solargraph::Location.new(@filename, Range.new(shifted, shifted)))
126
133
  gen_pin.instance_variable_set(:@explicit, false)
127
134
  @pins.push gen_pin
128
- rescue Parser::SyntaxError => e
135
+ rescue Parser::SyntaxError
129
136
  # @todo Handle error in directive
130
137
  end
131
138
  when 'attribute'
132
139
  return if directive.tag.name.nil?
133
140
  namespace = closure_at(source_position)
134
- t = (directive.tag.types.nil? || directive.tag.types.empty?) ? nil : directive.tag.types.flatten.join('')
141
+ t = directive.tag.types.nil? || directive.tag.types.empty? ? nil : directive.tag.types.join
135
142
  if t.nil? || t.include?('r')
136
143
  pins.push Solargraph::Pin::Method.new(
137
144
  location: location,
@@ -157,55 +164,64 @@ module Solargraph
157
164
  source: :source_map
158
165
  )
159
166
  pins.push method_pin
160
- method_pin.parameters.push Pin::Parameter.new(name: 'value', decl: :arg, closure: pins.last, source: :source_map)
167
+ method_pin.parameters.push Pin::Parameter.new(name: 'value', decl: :arg, closure: pins.last,
168
+ source: :source_map)
161
169
  if pins.last.return_type.defined?
162
- pins.last.docstring.add_tag YARD::Tags::Tag.new(:param, '', pins.last.return_type.to_s.split(', '), 'value')
170
+ pins.last.docstring.add_tag YARD::Tags::Tag.new(:param, '', pins.last.return_type.to_s.split(', '),
171
+ 'value')
163
172
  end
164
173
  end
165
174
  when 'visibility'
166
175
 
167
- kind = directive.tag.text&.to_sym
168
- return unless [:private, :protected, :public].include?(kind)
176
+ kind = directive.tag.text&.to_sym
177
+ return unless %i[private protected public].include?(kind)
169
178
 
170
- name = directive.tag.name
171
- closure = closure_at(source_position) || @pins.first
172
- if closure.location.range.start.line < comment_position.line
173
- closure = closure_at(comment_position)
179
+ name = directive.tag.name
180
+ closure = closure_at(source_position) || @pins.first
181
+ # @sg-ignore Need to add nil check here
182
+ closure = closure_at(comment_position) if closure.location.range.start.line < comment_position.line
183
+ if closure.is_a?(Pin::Method) && no_empty_lines?(comment_position.line, source_position.line)
184
+ # @todo Smelly instance variable access
185
+ closure.instance_variable_set(:@visibility, kind)
186
+ else
187
+ matches = pins.select do |pin|
188
+ pin.is_a?(Pin::Method) && pin.name == name && pin.namespace == namespace && pin.context.scope == namespace.is_a?(Pin::Singleton) ? :class : :instance
174
189
  end
175
- if closure.is_a?(Pin::Method) && no_empty_lines?(comment_position.line, source_position.line)
190
+ matches.each do |pin|
176
191
  # @todo Smelly instance variable access
177
- closure.instance_variable_set(:@visibility, kind)
178
- else
179
- matches = pins.select{ |pin| pin.is_a?(Pin::Method) && pin.name == name && pin.namespace == namespace && pin.context.scope == namespace.is_a?(Pin::Singleton) ? :class : :instance }
180
- matches.each do |pin|
181
- # @todo Smelly instance variable access
182
- pin.instance_variable_set(:@visibility, kind)
183
- end
192
+ pin.instance_variable_set(:@visibility, kind)
184
193
  end
194
+ end
185
195
 
186
196
  when 'parse'
187
197
  begin
188
198
  ns = closure_at(source_position)
199
+ # @sg-ignore Need to add nil check here
189
200
  src = Solargraph::Source.load_string(directive.tag.text, @source.filename)
190
201
  region = Parser::Region.new(source: src, closure: ns)
191
202
  # @todo These pins may need to be marked not explicit
192
203
  index = @pins.length
193
204
  loff = if @code.lines[comment_position.line].strip.end_with?('@!parse')
194
- comment_position.line + 1
195
- else
196
- comment_position.line
197
- end
198
- Parser.process_node(src.node, region, @pins)
199
- @pins[index..-1].each do |p|
205
+ comment_position.line + 1
206
+ else
207
+ comment_position.line
208
+ end
209
+ locals = []
210
+ ivars = []
211
+ Parser.process_node(src.node, region, @pins, locals, ivars)
212
+ @pins.concat ivars
213
+ # @sg-ignore Need to add nil check here
214
+ @pins[index..].each do |p|
200
215
  # @todo Smelly instance variable access
201
216
  p.location.range.start.instance_variable_set(:@line, p.location.range.start.line + loff)
202
217
  p.location.range.ending.instance_variable_set(:@line, p.location.range.ending.line + loff)
203
218
  end
204
- rescue Parser::SyntaxError => e
219
+ rescue Parser::SyntaxError
205
220
  # @todo Handle parser errors in !parse directives
206
221
  end
207
222
  when 'domain'
208
223
  namespace = closure_at(source_position) || Pin::ROOT_PIN
224
+ # @sg-ignore flow sensitive typing should be able to handle redefinition
209
225
  namespace.domains.concat directive.tag.types unless directive.tag.types.nil?
210
226
  when 'override'
211
227
  pins.push Pin::Reference::Override.new(location, directive.tag.name, docstring.tags,
@@ -217,7 +233,9 @@ module Solargraph
217
233
 
218
234
  # @param line1 [Integer]
219
235
  # @param line2 [Integer]
220
- def no_empty_lines?(line1, line2)
236
+ # @sg-ignore Need to add nil check here
237
+ def no_empty_lines? line1, line2
238
+ # @sg-ignore Need to add nil check here
221
239
  @code.lines[line1..line2].none? { |line| line.strip.empty? }
222
240
  end
223
241
 
@@ -227,7 +245,7 @@ module Solargraph
227
245
  ctxt = ''
228
246
  num = nil
229
247
  started = false
230
- comment.lines.each { |l|
248
+ comment.lines.each do |l|
231
249
  # Trim the comment and minimum leading whitespace
232
250
  p = l.encode('UTF-8', invalid: :replace, replace: '?').gsub(/^#+/, '')
233
251
  if num.nil? && !p.strip.empty?
@@ -235,10 +253,11 @@ module Solargraph
235
253
  started = true
236
254
  elsif started && !p.strip.empty?
237
255
  cur = p.index(/[^ ]/)
256
+ # @sg-ignore Need to add nil check here
238
257
  num = cur if cur < num
239
258
  end
240
- ctxt += "#{p[num..-1]}" if started
241
- }
259
+ ctxt += p[num..].to_s if started
260
+ end
242
261
  ctxt
243
262
  end
244
263
 
@@ -247,7 +266,15 @@ module Solargraph
247
266
  return unless @code.encode('UTF-8', invalid: :replace, replace: '?') =~ DIRECTIVE_REGEXP
248
267
  code_lines = @code.lines
249
268
  @source.associated_comments.each do |line, comments|
250
- src_pos = line ? Position.new(line, code_lines[line].to_s.chomp.index(/[^\s]/) || 0) : Position.new(code_lines.length, 0)
269
+ src_pos = if line
270
+ Position.new(line,
271
+ code_lines[line].to_s.chomp.index(/[^\s]/) || 0)
272
+ else
273
+ Position.new(
274
+ code_lines.length, 0
275
+ )
276
+ end
277
+ # @sg-ignore Need to add nil check here
251
278
  com_pos = Position.new(line + 1 - comments.lines.length, 0)
252
279
  process_comment(src_pos, com_pos, comments)
253
280
  end
@@ -34,6 +34,8 @@ module Solargraph
34
34
  # @param source [Source]
35
35
  def initialize source
36
36
  @source = source
37
+ # @type [Array<Pin::Base>, nil]
38
+ @convention_pins = nil
37
39
 
38
40
  conventions_environ.merge Convention.for_local(self) unless filename.nil?
39
41
  # FIXME: unmemoizing the document_symbols in case it was called and memoized from any of conventions above
@@ -60,10 +62,12 @@ module Solargraph
60
62
  #
61
63
  # @return [Integer]
62
64
  def api_hash
63
- @api_hash ||= (pins_by_class(Pin::Constant) + pins_by_class(Pin::Namespace).select { |pin| pin.namespace.to_s > '' } + pins_by_class(Pin::Reference) + pins_by_class(Pin::Method).map(&:node) + locals).hash
65
+ @api_hash ||= (pins_by_class(Pin::Constant) + pins_by_class(Pin::Namespace).select do |pin|
66
+ pin.namespace.to_s > ''
67
+ end + pins_by_class(Pin::Reference) + pins_by_class(Pin::Method).map(&:node) + locals).hash
64
68
  end
65
69
 
66
- # @return [String]
70
+ # @return [String, nil]
67
71
  def filename
68
72
  source.filename
69
73
  end
@@ -84,6 +88,7 @@ module Solargraph
84
88
  end
85
89
 
86
90
  # all pins except Solargraph::Pin::Reference::Reference
91
+ #
87
92
  # @return [Array<Pin::Base>]
88
93
  def document_symbols
89
94
  @document_symbols ||= (pins + convention_pins).select do |pin|
@@ -97,7 +102,7 @@ module Solargraph
97
102
  Pin::Search.new(document_symbols, query).results
98
103
  end
99
104
 
100
- # @param position [Position]
105
+ # @param position [Position, Array(Integer, Integer)]
101
106
  # @return [Source::Cursor]
102
107
  def cursor_at position
103
108
  Source::Cursor.new(source, position)
@@ -125,7 +130,7 @@ module Solargraph
125
130
 
126
131
  # @param line [Integer]
127
132
  # @param character [Integer]
128
- # @return [Pin::Namespace,Pin::Method,Pin::Block]
133
+ # @return [Pin::Closure]
129
134
  def locate_closure_pin line, character
130
135
  _locate_pin line, character, Pin::Closure
131
136
  end
@@ -141,9 +146,9 @@ module Solargraph
141
146
 
142
147
  # @param location [Location]
143
148
  # @return [Array<Pin::LocalVariable>]
144
- def locals_at(location)
149
+ def locals_at location
145
150
  return [] if location.filename != filename
146
- closure = locate_named_path_pin(location.range.start.line, location.range.start.character)
151
+ closure = locate_closure_pin(location.range.start.line, location.range.start.character)
147
152
  locals.select { |pin| pin.visible_at?(closure, location) }
148
153
  end
149
154
 
@@ -178,6 +183,7 @@ module Solargraph
178
183
 
179
184
  # @return [Hash{Class<Pin::Base> => Array<Pin::Base>}]
180
185
  def pin_class_hash
186
+ # @todo Need to support generic resolution in classify and transform_values
181
187
  @pin_class_hash ||= pins.to_set.classify(&:class).transform_values(&:to_a)
182
188
  end
183
189
 
@@ -191,10 +197,12 @@ module Solargraph
191
197
  @convention_pins || []
192
198
  end
193
199
 
200
+ # @generic T
194
201
  # @param line [Integer]
195
202
  # @param character [Integer]
196
- # @param klasses [Array<Class>]
197
- # @return [Pin::Base, nil]
203
+ # @param klasses [Array<Class<generic<T>>>]
204
+ # @return [generic<T>, nil]
205
+ # @sg-ignore Need better generic inference here
198
206
  def _locate_pin line, character, *klasses
199
207
  position = Position.new(line, character)
200
208
  found = nil
@@ -202,7 +210,11 @@ module Solargraph
202
210
  # @todo Attribute pins should not be treated like closures, but
203
211
  # there's probably a better way to handle it
204
212
  next if pin.is_a?(Pin::Method) && pin.attribute?
205
- found = pin if (klasses.empty? || klasses.any? { |kls| pin.is_a?(kls) } ) && pin.location.range.contain?(position)
213
+ found = pin if (klasses.empty? || klasses.any? do |kls|
214
+ pin.is_a?(kls)
215
+ # @sg-ignore Need to add nil check here
216
+ end) && pin.location.range.contain?(position)
217
+ # @sg-ignore Need to add nil check here
206
218
  break if pin.location.range.start.line > line
207
219
  end
208
220
  # Assuming the root pin is always valid
@@ -5,19 +5,21 @@ module Solargraph
5
5
  # A problem reported by TypeChecker.
6
6
  #
7
7
  class Problem
8
+ # @todo Missed nil violation
8
9
  # @return [Solargraph::Location]
9
10
  attr_reader :location
10
11
 
11
12
  # @return [String]
12
13
  attr_reader :message
13
14
 
15
+ # @todo Missed nil violation
14
16
  # @return [Pin::Base]
15
17
  attr_reader :pin
16
18
 
17
19
  # @return [String, nil]
18
20
  attr_reader :suggestion
19
21
 
20
- # @param location [Solargraph::Location]
22
+ # @param location [Solargraph::Location, nil]
21
23
  # @param message [String]
22
24
  # @param pin [Solargraph::Pin::Base, nil]
23
25
  # @param suggestion [String, nil]
@@ -23,11 +23,11 @@ module Solargraph
23
23
  # @param overrides [Hash{Symbol => Symbol}]
24
24
  def initialize level, overrides
25
25
  @rank = if LEVELS.key?(level)
26
- LEVELS[level]
27
- else
28
- Solargraph.logger.warn "Unrecognized TypeChecker level #{level}, assuming normal"
29
- 0
30
- end
26
+ LEVELS[level]
27
+ else
28
+ Solargraph.logger.warn "Unrecognized TypeChecker level #{level}, assuming normal"
29
+ 0
30
+ end
31
31
  @level = LEVELS[LEVELS.values.index(@rank)]
32
32
  @overrides = overrides
33
33
  end
@@ -60,8 +60,81 @@ module Solargraph
60
60
  report?(:validate_tags, :typed)
61
61
  end
62
62
 
63
- def require_all_return_types_match_inferred?
64
- report?(:require_all_return_types_match_inferred, :alpha)
63
+ def require_inferred_type_params?
64
+ report?(:require_inferred_type_params, :alpha)
65
+ end
66
+
67
+ #
68
+ # False negatives:
69
+ #
70
+ # @todo 4: Missed nil violation
71
+ #
72
+ # pending code fixes (277):
73
+ #
74
+ # @todo 281: Need to add nil check here
75
+ # @todo 22: Translate to something flow sensitive typing understands
76
+ # @todo 3: Need a downcast here
77
+ #
78
+ # flow sensitive typing could handle (96):
79
+ #
80
+ # @todo 36: flow sensitive typing needs to handle attrs
81
+ # @todo 29: flow sensitive typing should be able to handle redefinition
82
+ # @todo 19: flow sensitive typing needs to narrow down type with an if is_a? check
83
+ # @todo 13: Need to validate config
84
+ # @todo 8: flow sensitive typing should support .class == .class
85
+ # @todo 6: need boolish support for ? methods
86
+ # @todo 6: flow sensitive typing needs better handling of ||= on lvars
87
+ # @todo 5: literal arrays in this module turn into ::Solargraph::Source::Chain::Array
88
+ # @todo 5: flow sensitive typing needs to handle 'raise if'
89
+ # @todo 4: flow sensitive typing needs to eliminate literal from union with [:bar].include?(foo)
90
+ # @todo 4: nil? support in flow sensitive typing
91
+ # @todo 3: flow sensitive typing ought to be able to handle 'when ClassName'
92
+ # @todo 2: downcast output of Enumerable#select
93
+ # @todo 2: flow sensitive typing should handle return nil if location&.name.nil?
94
+ # @todo 2: flow sensitive typing should handle is_a? and next
95
+ # @todo 2: Need to look at Tuple#include? handling
96
+ # @todo 2: Should better support meaning of '&' in RBS
97
+ # @todo 2: (*) flow sensitive typing needs to handle "if foo = bar"
98
+ # @todo 2: flow sensitive typing needs to handle "if foo = bar"
99
+ # @todo 2: Need to handle duck-typed method calls on union types
100
+ # @todo 2: Need better handling of #compact
101
+ # @todo 2: flow sensitive typing should allow shadowing of Kernel#caller
102
+ # @todo 1: flow sensitive typing not smart enough to handle this case
103
+ # @todo 1: flow sensitive typing needs to handle if foo = bar
104
+ # @todo 1: flow sensitive typing needs to handle "if foo.nil?"
105
+ # @todo 1: flow sensitive typing should support case/when
106
+ # @todo 1: flow sensitive typing should support ivars
107
+ # @todo 1: Need to support this in flow sensitive typing
108
+ # @todo 1: flow sensitive typing needs to handle self.class == other.class
109
+ # @todo 1: flow sensitive typing needs to remove literal with
110
+ # @todo 1: flow sensitive typing needs to understand reassignment
111
+ # @todo 1: flow sensitive typing should be able to identify more blocks that always return
112
+ # @todo 1: should warn on nil dereference below
113
+ # @todo 1: flow sensitive typing needs to create separate ranges for postfix if
114
+ # @todo 1: flow sensitive typing needs to handle constants
115
+ # @todo 1: flow sensitive typing needs to eliminate literal from union with return if foo == :bar
116
+ def require_all_unique_types_match_expected?
117
+ report?(:require_all_unique_types_match_expected, :strong)
118
+ end
119
+
120
+ def require_all_unique_types_support_call?
121
+ report?(:require_all_unique_types_support_call, :strong)
122
+ end
123
+
124
+ def require_no_undefined_args?
125
+ report?(:require_no_undefined_args, :alpha)
126
+ end
127
+
128
+ def require_generics_resolved?
129
+ report?(:require_generics_resolved, :alpha)
130
+ end
131
+
132
+ def require_interfaces_resolved?
133
+ report?(:require_interfaces_resolved, :alpha)
134
+ end
135
+
136
+ def require_downcasts?
137
+ report?(:require_downcasts, :alpha)
65
138
  end
66
139
 
67
140
  # We keep this at strong because if you added an @ sg-ignore to
@@ -76,7 +149,7 @@ module Solargraph
76
149
 
77
150
  # @param type [Symbol]
78
151
  # @param level [Symbol]
79
- def report?(type, level)
152
+ def report? type, level
80
153
  rank >= LEVELS[@overrides.fetch(type, level)]
81
154
  end
82
155
  end