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
@@ -5,11 +5,10 @@ module Solargraph
5
5
  #
6
6
  class TypeChecker
7
7
  autoload :Problem, 'solargraph/type_checker/problem'
8
- autoload :ParamDef, 'solargraph/type_checker/param_def'
9
8
  autoload :Rules, 'solargraph/type_checker/rules'
10
- autoload :Checks, 'solargraph/type_checker/checks'
11
9
 
12
- include Checks
10
+ # @!parse
11
+ # include Solargraph::Parser::ParserGem::NodeMethods
13
12
  include Parser::NodeMethods
14
13
 
15
14
  # @return [String]
@@ -26,8 +25,6 @@ module Solargraph
26
25
  # @param level [Symbol] Don't complain about anything above this level
27
26
  # @param workspace [Workspace, nil] Workspace to use for loading
28
27
  # type checker rules modified by user config
29
- # @param type_checker_rules [Hash{Symbol => Symbol}] Overrides for
30
- # type checker rules - e.g., :report_undefined => :strong
31
28
  # @param rules [Rules] Type checker rules object
32
29
  def initialize filename,
33
30
  api_map: nil,
@@ -36,7 +33,8 @@ module Solargraph
36
33
  rules: workspace ? workspace.rules(level) : Rules.new(level, {})
37
34
  @filename = filename
38
35
  # @todo Smarter directory resolution
39
- @api_map = api_map || Solargraph::ApiMap.load(File.dirname(filename))
36
+ @api_map = api_map || Solargraph::ApiMap.load(File.dirname(filename),
37
+ loose_unions: !rules.require_all_unique_types_support_call?)
40
38
  @rules = rules
41
39
  # @type [Array<Range>]
42
40
  @marked_ranges = []
@@ -49,18 +47,51 @@ module Solargraph
49
47
 
50
48
  # @return [Source]
51
49
  def source
52
- @source_map.source
50
+ source_map.source
51
+ end
52
+
53
+ # @param inferred [ComplexType, ComplexType::UniqueType]
54
+ # @param expected [ComplexType, ComplexType::UniqueType]
55
+ def return_type_conforms_to? inferred, expected
56
+ conforms_to?(inferred, expected, :return_type)
57
+ end
58
+
59
+ # @param inferred [ComplexType, ComplexType::UniqueType]
60
+ # @param expected [ComplexType, ComplexType::UniqueType]
61
+ def arg_conforms_to? inferred, expected
62
+ conforms_to?(inferred, expected, :method_call)
63
+ end
64
+
65
+ # @param inferred [ComplexType, ComplexType::UniqueType]
66
+ # @param expected [ComplexType, ComplexType::UniqueType]
67
+ def assignment_conforms_to? inferred, expected
68
+ conforms_to?(inferred, expected, :assignment)
69
+ end
70
+
71
+ # @param inferred [ComplexType, ComplexType::UniqueType]
72
+ # @param expected [ComplexType, ComplexType::UniqueType]
73
+ # @param scenario [Symbol]
74
+ def conforms_to? inferred, expected, scenario
75
+ rules_arr = []
76
+ rules_arr << :allow_empty_params unless rules.require_inferred_type_params?
77
+ rules_arr << :allow_any_match unless rules.require_all_unique_types_match_expected?
78
+ rules_arr << :allow_undefined unless rules.require_no_undefined_args?
79
+ rules_arr << :allow_unresolved_generic unless rules.require_generics_resolved?
80
+ rules_arr << :allow_unmatched_interface unless rules.require_interfaces_resolved?
81
+ rules_arr << :allow_reverse_match unless rules.require_downcasts?
82
+ inferred.conforms_to?(api_map, expected, scenario,
83
+ rules_arr)
53
84
  end
54
85
 
55
86
  # @return [Array<Problem>]
56
87
  def problems
57
88
  @problems ||= begin
58
- all = method_tag_problems
59
- .concat(variable_type_tag_problems)
60
- .concat(const_problems)
61
- .concat(call_problems)
62
- unignored = without_ignored(all)
63
- unignored.concat(unneeded_sgignore_problems)
89
+ all = method_tag_problems
90
+ .concat(variable_type_tag_problems)
91
+ .concat(const_problems)
92
+ .concat(call_problems)
93
+ unignored = without_ignored(all)
94
+ unignored.concat(unneeded_sgignore_problems)
64
95
  end
65
96
  end
66
97
 
@@ -70,20 +101,26 @@ module Solargraph
70
101
  # @return [self]
71
102
  def load filename, level = :normal
72
103
  source = Solargraph::Source.load(filename)
73
- api_map = Solargraph::ApiMap.new
104
+ rules = Rules.new(level, {})
105
+ api_map = Solargraph::ApiMap.new(loose_unions:
106
+ !rules.require_all_unique_types_support_call?)
74
107
  api_map.map(source)
75
- new(filename, api_map: api_map, level: level)
108
+ new(filename, api_map: api_map, level: level, rules: rules)
76
109
  end
77
110
 
78
111
  # @param code [String]
79
112
  # @param filename [String, nil]
80
113
  # @param level [Symbol]
114
+ # @param api_map [Solargraph::ApiMap, nil]
81
115
  # @return [self]
82
- def load_string code, filename = nil, level = :normal
116
+ def load_string code, filename = nil, level = :normal, api_map: nil
83
117
  source = Solargraph::Source.load_string(code, filename)
84
- api_map = Solargraph::ApiMap.new
118
+ rules = Rules.new(level, {})
119
+ api_map ||= Solargraph::ApiMap.new(loose_unions:
120
+ !rules.require_all_unique_types_support_call?)
121
+ # @sg-ignore flow sensitive typing needs better handling of ||= on lvars
85
122
  api_map.map(source)
86
- new(filename, api_map: api_map, level: level)
123
+ new(filename, api_map: api_map, level: level, rules: rules)
87
124
  end
88
125
  end
89
126
 
@@ -107,13 +144,18 @@ module Solargraph
107
144
  result = []
108
145
  declared = pin.typify(api_map).self_to_type(pin.full_context).qualify(api_map, *pin.gates)
109
146
  if declared.undefined?
147
+ # @sg-ignore Need to add nil check here
110
148
  if pin.return_type.undefined? && rules.require_type_tags?
111
149
  if pin.attribute?
112
150
  inferred = pin.probe(api_map).self_to_type(pin.full_context)
113
- result.push Problem.new(pin.location, "Missing @return tag for #{pin.path}", pin: pin) unless inferred.defined?
151
+ unless inferred.defined?
152
+ result.push Problem.new(pin.location, "Missing @return tag for #{pin.path}",
153
+ pin: pin)
154
+ end
114
155
  else
115
156
  result.push Problem.new(pin.location, "Missing @return tag for #{pin.path}", pin: pin)
116
157
  end
158
+ # @sg-ignore Need to add nil check here
117
159
  elsif pin.return_type.defined? && !resolved_constant?(pin)
118
160
  result.push Problem.new(pin.location, "Unresolved return type #{pin.return_type} for #{pin.path}", pin: pin)
119
161
  elsif rules.must_tag_or_infer? && pin.probe(api_map).undefined?
@@ -127,8 +169,9 @@ module Solargraph
127
169
  result.push Problem.new(pin.location, "#{pin.path} return type could not be inferred", pin: pin)
128
170
  end
129
171
  else
130
- unless (rules.require_all_return_types_match_inferred? ? all_types_match?(api_map, inferred, declared) : any_types_match?(api_map, declared, inferred))
131
- result.push Problem.new(pin.location, "Declared return type #{declared.rooted_tags} does not match inferred type #{inferred.rooted_tags} for #{pin.path}", pin: pin)
172
+ unless return_type_conforms_to?(inferred, declared)
173
+ result.push Problem.new(pin.location,
174
+ "Declared return type #{declared.rooted_tags} does not match inferred type #{inferred.rooted_tags} for #{pin.path}", pin: pin)
132
175
  end
133
176
  end
134
177
  end
@@ -144,7 +187,7 @@ module Solargraph
144
187
  def resolved_constant? pin
145
188
  return true if pin.typify(api_map).defined?
146
189
  constant_pins = api_map.get_constants('', *pin.closure.gates)
147
- .select { |p| p.name == pin.return_type.namespace }
190
+ .select { |p| p.name == pin.return_type.namespace }
148
191
  return true if constant_pins.find { |p| p.typify(api_map).defined? }
149
192
  # will need to probe when a constant name is assigned to a
150
193
  # class/module (alias)
@@ -154,6 +197,7 @@ module Solargraph
154
197
 
155
198
  # @param pin [Pin::Base]
156
199
  def virtual_pin? pin
200
+ # @sg-ignore Need to add nil check here
157
201
  pin.location && source.comment_at?(pin.location.range.ending)
158
202
  end
159
203
 
@@ -165,19 +209,19 @@ module Solargraph
165
209
  pin.signatures.each do |sig|
166
210
  params = param_details_from_stack(sig, stack)
167
211
  if rules.require_type_tags?
168
- sig.parameters.each do |par|
169
- break if par.decl == :restarg || par.decl == :kwrestarg || par.decl == :blockarg
170
- unless params[par.name]
171
- if pin.attribute?
172
- inferred = pin.probe(api_map).self_to_type(pin.full_context)
173
- if inferred.undefined?
174
- result.push Problem.new(pin.location, "Missing @param tag for #{par.name} on #{pin.path}", pin: pin)
175
- end
176
- else
212
+ sig.parameters.each do |par|
213
+ break if %i[restarg kwrestarg blockarg].include?(par.decl)
214
+ unless params[par.name]
215
+ if pin.attribute?
216
+ inferred = pin.probe(api_map).self_to_type(pin.full_context)
217
+ if inferred.undefined?
177
218
  result.push Problem.new(pin.location, "Missing @param tag for #{par.name} on #{pin.path}", pin: pin)
178
219
  end
220
+ else
221
+ result.push Problem.new(pin.location, "Missing @param tag for #{par.name} on #{pin.path}", pin: pin)
179
222
  end
180
223
  end
224
+ end
181
225
  end
182
226
  # @param name [String]
183
227
  # @param data [Hash{Symbol => BasicObject}]
@@ -185,7 +229,8 @@ module Solargraph
185
229
  # @type [ComplexType]
186
230
  type = data[:qualified]
187
231
  if type.undefined?
188
- result.push Problem.new(pin.location, "Unresolved type #{data[:tagged]} for #{name} param on #{pin.path}", pin: pin)
232
+ result.push Problem.new(pin.location, "Unresolved type #{data[:tagged]} for #{name} param on #{pin.path}",
233
+ pin: pin)
189
234
  end
190
235
  end
191
236
  end
@@ -201,6 +246,7 @@ module Solargraph
201
246
  def variable_type_tag_problems
202
247
  result = []
203
248
  all_variables.each do |pin|
249
+ # @sg-ignore Need to add nil check here
204
250
  if pin.return_type.defined?
205
251
  declared = pin.typify(api_map)
206
252
  next if declared.duck_type?
@@ -215,21 +261,21 @@ module Solargraph
215
261
  result.push Problem.new(pin.location, "Variable type could not be inferred for #{pin.name}", pin: pin)
216
262
  end
217
263
  else
218
- unless any_types_match?(api_map, declared, inferred)
219
- result.push Problem.new(pin.location, "Declared type #{declared} does not match inferred type #{inferred} for variable #{pin.name}", pin: pin)
264
+ unless assignment_conforms_to?(inferred, declared)
265
+ result.push Problem.new(pin.location,
266
+ "Declared type #{declared} does not match inferred type #{inferred} for variable #{pin.name}", pin: pin)
220
267
  end
221
268
  end
222
269
  elsif declared_externally?(pin)
223
270
  ignored_pins.push pin
224
271
  end
225
272
  elsif !pin.is_a?(Pin::Parameter) && !resolved_constant?(pin)
226
- result.push Problem.new(pin.location, "Unresolved type #{pin.return_type} for variable #{pin.name}", pin: pin)
273
+ result.push Problem.new(pin.location, "Unresolved type #{pin.return_type} for variable #{pin.name}",
274
+ pin: pin)
227
275
  end
228
276
  elsif pin.assignment
229
277
  inferred = pin.probe(api_map)
230
- if inferred.undefined? && declared_externally?(pin)
231
- ignored_pins.push pin
232
- end
278
+ ignored_pins.push pin if inferred.undefined? && declared_externally?(pin)
233
279
  end
234
280
  end
235
281
  result
@@ -247,8 +293,10 @@ module Solargraph
247
293
  Solargraph::Parser::NodeMethods.const_nodes_from(source.node).each do |const|
248
294
  rng = Solargraph::Range.from_node(const)
249
295
  chain = Solargraph::Parser.chain(const, filename)
296
+ # @sg-ignore Need to add nil check here
250
297
  closure_pin = source_map.locate_closure_pin(rng.start.line, rng.start.column)
251
298
  closure_pin.rebind(api_map)
299
+ # @sg-ignore Need to add nil check here
252
300
  location = Location.new(filename, rng)
253
301
  locals = source_map.locals_at(location)
254
302
  pins = chain.define(api_map, closure_pin, locals)
@@ -265,44 +313,55 @@ module Solargraph
265
313
  result = []
266
314
  Solargraph::Parser::NodeMethods.call_nodes_from(source.node).each do |call|
267
315
  rng = Solargraph::Range.from_node(call)
316
+ # @sg-ignore Need to add nil check here
268
317
  next if @marked_ranges.any? { |d| d.contain?(rng.start) }
269
318
  chain = Solargraph::Parser.chain(call, filename)
319
+ # @sg-ignore Need to add nil check here
270
320
  closure_pin = source_map.locate_closure_pin(rng.start.line, rng.start.column)
271
- namespace_pin = closure_pin
272
321
  if call.type == :block
273
322
  # blocks in the AST include the method call as well, so the
274
323
  # node returned by #call_nodes_from needs to be backed out
275
324
  # one closure
325
+ # @todo Need to add nil check here
326
+ # @todo Should warn on nil deference here
276
327
  closure_pin = closure_pin.closure
277
328
  end
329
+ # @sg-ignore Need to add nil check here
278
330
  closure_pin.rebind(api_map)
331
+ # @sg-ignore Need to add nil check here
279
332
  location = Location.new(filename, rng)
280
333
  locals = source_map.locals_at(location)
334
+ # @sg-ignore Need to add nil check here
281
335
  type = chain.infer(api_map, closure_pin, locals)
282
336
  if type.undefined? && !rules.ignore_all_undefined?
283
337
  base = chain
284
338
  missing = chain
339
+ # @type [Solargraph::Pin::Base, nil]
285
340
  found = nil
286
- closest = ComplexType::UNDEFINED
341
+ # @type [Array<Solargraph::Pin::Base>]
342
+ all_found = []
287
343
  until base.links.first.undefined?
288
- found = base.define(api_map, closure_pin, locals).first
344
+ # @sg-ignore Need to add nil check here
345
+ all_found = base.define(api_map, closure_pin, locals)
346
+ found = all_found.first
289
347
  break if found
290
348
  missing = base
291
349
  base = base.base
292
350
  end
293
- closest = found.typify(api_map) if found
351
+ all_closest = all_found.map { |pin| pin.typify(api_map) }
352
+ closest = ComplexType.new(all_closest.flat_map(&:items).uniq)
294
353
  # @todo remove the internal_or_core? check at a higher-than-strict level
295
- if !found || found.is_a?(Pin::BaseVariable) || (closest.defined? && internal_or_core?(found))
296
- unless closest.generic? || ignored_pins.include?(found)
297
- if closest.defined?
298
- result.push Problem.new(location, "Unresolved call to #{missing.links.last.word} on #{closest}")
299
- else
300
- result.push Problem.new(location, "Unresolved call to #{missing.links.last.word}")
301
- end
302
- @marked_ranges.push rng
354
+ # @sg-ignore Need to add nil check here
355
+ if (!found || found.is_a?(Pin::BaseVariable) || (closest.defined? && internal_or_core?(found))) && !(closest.generic? || ignored_pins.include?(found))
356
+ if closest.defined?
357
+ result.push Problem.new(location, "Unresolved call to #{missing.links.last.word} on #{closest}")
358
+ else
359
+ result.push Problem.new(location, "Unresolved call to #{missing.links.last.word}")
303
360
  end
361
+ @marked_ranges.push rng
304
362
  end
305
363
  end
364
+ # @sg-ignore Need to add nil check here
306
365
  result.concat argument_problems_for(chain, api_map, closure_pin, locals, location)
307
366
  end
308
367
  result
@@ -311,13 +370,12 @@ module Solargraph
311
370
  # @param chain [Solargraph::Source::Chain]
312
371
  # @param api_map [Solargraph::ApiMap]
313
372
  # @param closure_pin [Solargraph::Pin::Closure]
314
- # @param locals [Array<Solargraph::Pin::Base>]
373
+ # @param locals [Array<Solargraph::Pin::LocalVariable>]
315
374
  # @param location [Solargraph::Location]
316
375
  # @return [Array<Problem>]
317
376
  def argument_problems_for chain, api_map, closure_pin, locals, location
318
377
  result = []
319
378
  base = chain
320
- # @type last_base_link [Solargraph::Source::Chain::Call]
321
379
  last_base_link = base.links.last
322
380
  return [] unless last_base_link.is_a?(Solargraph::Source::Chain::Call)
323
381
 
@@ -340,6 +398,8 @@ module Solargraph
340
398
  base.base.infer(api_map, closure_pin, locals).namespace
341
399
  end
342
400
  init = api_map.get_method_stack(fqns, 'initialize').first
401
+
402
+ # @type [::Array<Solargraph::TypeChecker::Problem>]
343
403
  init ? arity_problems_for(init, arguments, location) : []
344
404
  else
345
405
  arity_problems_for(pin, arguments, location)
@@ -348,7 +408,7 @@ module Solargraph
348
408
  return [] if !rules.validate_calls? || base.links.first.is_a?(Solargraph::Source::Chain::ZSuper)
349
409
 
350
410
  all_errors = []
351
- pin.signatures.sort { |sig| sig.parameters.length }.each do |sig|
411
+ pin.signatures.sort_by { |sig| sig.parameters.length }.each do |sig|
352
412
  params = param_details_from_stack(sig, pins)
353
413
 
354
414
  signature_errors = signature_argument_problems_for location, locals, closure_pin, params, arguments, sig, pin
@@ -368,11 +428,10 @@ module Solargraph
368
428
  # @param location [Location]
369
429
  # @param locals [Array<Pin::LocalVariable>]
370
430
  # @param closure_pin [Pin::Closure]
371
- # @param params [Hash{String => Hash{Symbol => String, Solargraph::ComplexType}}]
431
+ # @param params [Hash{String => undefined}]
372
432
  # @param arguments [Array<Source::Chain>]
373
433
  # @param sig [Pin::Signature]
374
434
  # @param pin [Pin::Method]
375
- # @param pins [Array<Pin::Method>]
376
435
  #
377
436
  # @return [Array<Problem>]
378
437
  def signature_argument_problems_for location, locals, closure_pin, params, arguments, sig, pin
@@ -382,31 +441,25 @@ module Solargraph
382
441
  # when possible, and when not, ensure provably
383
442
  # incorrect situations are detected.
384
443
  sig.parameters.each_with_index do |par, idx|
385
- return errors if par.decl == :restarg # bail out and assume the rest is valid pending better arg processing
444
+ return errors if par.decl == :restarg # bail out and assume the rest is valid pending better arg processing
386
445
  argchain = arguments[idx]
387
446
  if argchain.nil?
447
+ final_arg = arguments.last
388
448
  if par.decl == :arg
389
- final_arg = arguments.last
390
449
  if final_arg && final_arg.node.type == :splat
391
450
  argchain = final_arg
392
451
  return errors
393
452
  else
394
453
  errors.push Problem.new(location, "Not enough arguments to #{pin.path}")
395
454
  end
396
- else
397
- final_arg = arguments.last
398
- argchain = final_arg if final_arg && [:kwsplat, :hash].include?(final_arg.node.type)
455
+ elsif final_arg && %i[kwsplat hash].include?(final_arg.node.type)
456
+ argchain = final_arg
399
457
  end
400
458
  end
401
459
  if argchain
402
- if par.decl != :arg
403
- errors.concat kwarg_problems_for sig, argchain, api_map, closure_pin, locals, location, pin, params, idx
404
- next
405
- else
406
- if argchain.node.type == :splat && argchain == arguments.last
407
- final_arg = argchain
408
- end
409
- if (final_arg && final_arg.node.type == :splat)
460
+ if par.decl == :arg
461
+ final_arg = argchain if argchain.node.type == :splat && argchain == arguments.last
462
+ if final_arg && final_arg.node.type == :splat
410
463
  # The final argument given has been seen and was a
411
464
  # splat, which doesn't give us useful types or
412
465
  # arities against positional parameters, so let's
@@ -430,11 +483,15 @@ module Solargraph
430
483
  else
431
484
  argtype = argchain.infer(api_map, closure_pin, locals)
432
485
  argtype = argtype.self_to_type(closure_pin.context)
433
- if argtype.defined? && ptype.defined? && !any_types_match?(api_map, ptype, argtype)
434
- errors.push Problem.new(location, "Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}")
486
+ if argtype.defined? && ptype.defined? && !arg_conforms_to?(argtype, ptype)
487
+ errors.push Problem.new(location,
488
+ "Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}")
435
489
  return errors
436
490
  end
437
491
  end
492
+ else
493
+ errors.concat kwarg_problems_for sig, argchain, api_map, closure_pin, locals, location, pin, params, idx
494
+ next
438
495
  end
439
496
  elsif par.decl == :kwarg
440
497
  errors.push Problem.new(location, "Call to #{pin.path} is missing keyword argument #{par.name}")
@@ -445,13 +502,13 @@ module Solargraph
445
502
  end
446
503
 
447
504
  # @param sig [Pin::Signature]
448
- # @param argchain [Source::Chain]
505
+ # @param argchain [Solargraph::Source::Chain]
449
506
  # @param api_map [ApiMap]
450
507
  # @param closure_pin [Pin::Closure]
451
508
  # @param locals [Array<Pin::LocalVariable>]
452
509
  # @param location [Location]
453
510
  # @param pin [Pin::Method]
454
- # @param params [Hash{String => Hash{Symbol => String, Solargraph::ComplexType}}]
511
+ # @param params [Hash{String => Hash{Symbol => undefined}}]
455
512
  # @param idx [Integer]
456
513
  #
457
514
  # @return [Array<Problem>]
@@ -459,29 +516,30 @@ module Solargraph
459
516
  result = []
460
517
  kwargs = convert_hash(argchain.node)
461
518
  par = sig.parameters[idx]
519
+ # @type [Solargraph::Source::Chain]
462
520
  argchain = kwargs[par.name.to_sym]
463
521
  if par.decl == :kwrestarg || (par.decl == :optarg && idx == pin.parameters.length - 1 && par.asgn_code == '{}')
464
522
  result.concat kwrestarg_problems_for(api_map, closure_pin, locals, location, pin, params, kwargs)
465
- else
466
- if argchain
467
- data = params[par.name]
468
- if data.nil?
469
- # @todo Some level (strong, I guess) should require the param here
470
- else
471
- ptype = data[:qualified]
472
- ptype = ptype.self_to_type(pin.context)
473
- unless ptype.undefined?
474
- # @sg-ignore https://github.com/castwide/solargraph/pull/1127
475
- argtype = argchain.infer(api_map, closure_pin, locals).self_to_type(closure_pin.context)
476
- # @sg-ignore Unresolved call to defined?
477
- if argtype.defined? && ptype && !any_types_match?(api_map, ptype, argtype)
478
- result.push Problem.new(location, "Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}")
479
- end
523
+ elsif argchain
524
+ data = params[par.name]
525
+ if data.nil?
526
+ # @todo Some level (strong, I guess) should require the param here
527
+ else
528
+ # @type [ComplexType, ComplexType::UniqueType]
529
+ ptype = data[:qualified]
530
+ ptype = ptype.self_to_type(pin.context)
531
+ unless ptype.undefined?
532
+ # @type [ComplexType]
533
+ argtype = argchain.infer(api_map, closure_pin, locals).self_to_type(closure_pin.context)
534
+ # @todo Unresolved call to defined?
535
+ if argtype.defined? && ptype && !arg_conforms_to?(argtype, ptype)
536
+ result.push Problem.new(location,
537
+ "Wrong argument type for #{pin.path}: #{par.name} expected #{ptype}, received #{argtype}")
480
538
  end
481
539
  end
482
- elsif par.decl == :kwarg
483
- result.push Problem.new(location, "Call to #{pin.path} is missing keyword argument #{par.name}")
484
540
  end
541
+ elsif par.decl == :kwarg
542
+ result.push Problem.new(location, "Call to #{pin.path} is missing keyword argument #{par.name}")
485
543
  end
486
544
  result
487
545
  end
@@ -491,19 +549,22 @@ module Solargraph
491
549
  # @param locals [Array<Pin::LocalVariable>]
492
550
  # @param location [Location]
493
551
  # @param pin [Pin::Method]
494
- # @param params [Hash{String => [nil, Hash]}]
552
+ # @param params [Hash{String => nil, Hash}]
495
553
  # @param kwargs [Hash{Symbol => Source::Chain}]
496
554
  # @return [Array<Problem>]
497
- def kwrestarg_problems_for(api_map, closure_pin, locals, location, pin, params, kwargs)
555
+ def kwrestarg_problems_for api_map, closure_pin, locals, location, pin, params, kwargs
498
556
  result = []
499
557
  kwargs.each_pair do |pname, argchain|
500
558
  next unless params.key?(pname.to_s)
501
- ptype = params[pname.to_s][:qualified]
502
- ptype = ptype.self_to_type(pin.context)
559
+ # @sg-ignore
560
+ # @type [ComplexType]
561
+ raw_ptype = params[pname.to_s][:qualified]
562
+ ptype = raw_ptype.self_to_type(pin.context)
503
563
  argtype = argchain.infer(api_map, closure_pin, locals)
504
564
  argtype = argtype.self_to_type(closure_pin.context)
505
- if argtype.defined? && ptype && !any_types_match?(api_map, ptype, argtype)
506
- result.push Problem.new(location, "Wrong argument type for #{pin.path}: #{pname} expected #{ptype}, received #{argtype}")
565
+ if argtype.defined? && ptype && !arg_conforms_to?(argtype, ptype)
566
+ result.push Problem.new(location,
567
+ "Wrong argument type for #{pin.path}: #{pname} expected #{ptype}, received #{argtype}")
507
568
  end
508
569
  end
509
570
  result
@@ -513,7 +574,7 @@ module Solargraph
513
574
  # @param pin [Pin::Method, Pin::Signature]
514
575
  # @param relevant_pin [Pin::Method, Pin::Signature] the pin which is under inspection
515
576
  # @return [void]
516
- def add_restkwarg_param_tag_details(param_details, pin, relevant_pin)
577
+ def add_restkwarg_param_tag_details param_details, pin, relevant_pin
517
578
  # see if we have additional tags to pay attention to from YARD -
518
579
  # e.g., kwargs in a **restkwargs splat
519
580
  tags = pin.docstring.tags(:param)
@@ -534,7 +595,7 @@ module Solargraph
534
595
 
535
596
  # @param pin [Pin::Signature]
536
597
  # @return [Hash{String => Hash{Symbol => String, ComplexType}}]
537
- def signature_param_details(pin)
598
+ def signature_param_details pin
538
599
  # @type [Hash{String => Hash{Symbol => String, ComplexType}}]
539
600
  result = {}
540
601
  pin.parameters.each do |param|
@@ -553,6 +614,7 @@ module Solargraph
553
614
  next if tag.types.nil?
554
615
  result[tag.name.to_s] = {
555
616
  tagged: tag.types.join(', '),
617
+ # @sg-ignore need to add a nil check here
556
618
  qualified: Solargraph::ComplexType.try_parse(*tag.types).qualify(api_map, *pin.closure.gates)
557
619
  }
558
620
  end
@@ -567,7 +629,7 @@ module Solargraph
567
629
  # @param new_param_details [Hash{String => Hash{Symbol => String, ComplexType}}]
568
630
  #
569
631
  # @return [void]
570
- def add_to_param_details(param_details, param_names, new_param_details)
632
+ def add_to_param_details param_details, param_names, new_param_details
571
633
  new_param_details.each do |param_name, details|
572
634
  next unless param_names.include?(param_name)
573
635
 
@@ -580,7 +642,7 @@ module Solargraph
580
642
  # @param signature [Pin::Signature]
581
643
  # @param method_pin_stack [Array<Pin::Method>]
582
644
  # @return [Hash{String => Hash{Symbol => String, ComplexType}}]
583
- def param_details_from_stack(signature, method_pin_stack)
645
+ def param_details_from_stack signature, method_pin_stack
584
646
  signature_type = signature.typify(api_map)
585
647
  signature = signature.proxy signature_type
586
648
  param_details = signature_param_details(signature)
@@ -602,6 +664,7 @@ module Solargraph
602
664
  # @param pin [Pin::Base]
603
665
  def internal? pin
604
666
  return false if pin.nil?
667
+ # @sg-ignore flow sensitive typing needs to handle attrs
605
668
  pin.location && api_map.bundled?(pin.location.filename)
606
669
  end
607
670
 
@@ -619,29 +682,32 @@ module Solargraph
619
682
 
620
683
  # @param pin [Pin::BaseVariable]
621
684
  def declared_externally? pin
622
- raise "No assignment found" if pin.assignment.nil?
685
+ raise 'No assignment found' if pin.assignment.nil?
623
686
 
624
687
  chain = Solargraph::Parser.chain(pin.assignment, filename)
688
+ # @sg-ignore flow sensitive typing needs to handle attrs
625
689
  rng = Solargraph::Range.from_node(pin.assignment)
690
+ # @sg-ignore Need to add nil check here
626
691
  closure_pin = source_map.locate_closure_pin(rng.start.line, rng.start.column)
692
+ # @sg-ignore flow sensitive typing needs to handle "if foo.nil?"
627
693
  location = Location.new(filename, Range.from_node(pin.assignment))
628
694
  locals = source_map.locals_at(location)
629
695
  type = chain.infer(api_map, closure_pin, locals)
630
696
  if type.undefined? && !rules.ignore_all_undefined?
631
697
  base = chain
632
- missing = chain
698
+ # @type [Solargraph::Pin::Base, nil]
633
699
  found = nil
634
- closest = ComplexType::UNDEFINED
700
+ # @type [Array<Solargraph::Pin::Base>]
701
+ all_found = []
635
702
  until base.links.first.undefined?
636
- found = base.define(api_map, closure_pin, locals).first
703
+ all_found = base.define(api_map, closure_pin, locals)
704
+ found = all_found.first
637
705
  break if found
638
- missing = base
639
706
  base = base.base
640
707
  end
641
- closest = found.typify(api_map) if found
642
- if !found || closest.defined? || internal?(found)
643
- return false
644
- end
708
+ all_closest = all_found.map { |pin| pin.typify(api_map) }
709
+ closest = ComplexType.new(all_closest.flat_map(&:items).uniq)
710
+ return false if !found || closest.defined? || internal?(found)
645
711
  end
646
712
  true
647
713
  end
@@ -664,7 +730,7 @@ module Solargraph
664
730
  # @param arguments [Array<Source::Chain>]
665
731
  # @param location [Location]
666
732
  # @return [Array<Problem>]
667
- def parameterized_arity_problems_for(pin, parameters, arguments, location)
733
+ def parameterized_arity_problems_for pin, parameters, arguments, location
668
734
  return [] unless pin.explicit?
669
735
  return [] if parameters.empty? && arguments.empty?
670
736
  return [] if pin.anon_splat?
@@ -679,7 +745,7 @@ module Solargraph
679
745
  settled_kwargs = parameters.count(&:keyword?)
680
746
  else
681
747
  kwargs = convert_hash(unchecked.last.node)
682
- if parameters.any? { |param| [:kwarg, :kwoptarg].include?(param.decl) || param.kwrestarg? }
748
+ if parameters.any? { |param| %i[kwarg kwoptarg].include?(param.decl) || param.kwrestarg? }
683
749
  if kwargs.empty?
684
750
  add_params += 1
685
751
  else
@@ -708,10 +774,12 @@ module Solargraph
708
774
  return [] if parameters.any?(&:rest?)
709
775
  opt = optional_param_count(parameters)
710
776
  return [] if unchecked.length <= req + opt
711
- if req + add_params + 1 == unchecked.length && any_splatted_call?(unchecked.map(&:node)) && (parameters.map(&:decl) & [:kwarg, :kwoptarg, :kwrestarg]).any?
777
+ if req + add_params + 1 == unchecked.length && any_splatted_call?(unchecked.map(&:node)) && (parameters.map(&:decl) & %i[
778
+ kwarg kwoptarg kwrestarg
779
+ ]).any?
712
780
  return []
713
781
  end
714
- return [] if arguments.length - req == parameters.select { |p| [:optarg, :kwoptarg].include?(p.decl) }.length
782
+ return [] if arguments.length - req == parameters.select { |p| %i[optarg kwoptarg].include?(p.decl) }.length
715
783
  return [Problem.new(location, "Too many arguments to #{pin.path}")]
716
784
  elsif unchecked.length < req - settled_kwargs && (arguments.empty? || (!arguments.last.splat? && !arguments.last.links.last.is_a?(Solargraph::Source::Chain::Hash)))
717
785
  # HACK: Kernel#raise signature is incorrect in Ruby 2.7 core docs.
@@ -727,42 +795,48 @@ module Solargraph
727
795
  # @todo need to use generic types in method to choose correct
728
796
  # signature and generate Integer as return type
729
797
  # @return [Integer]
730
- def required_param_count(parameters)
798
+ def required_param_count parameters
731
799
  parameters.sum { |param| %i[arg kwarg].include?(param.decl) ? 1 : 0 }
732
800
  end
733
801
 
734
802
  # @param parameters [Enumerable<Pin::Parameter>]
735
- # @param pin [Pin::Method]
803
+ #
736
804
  # @return [Integer]
737
- def optional_param_count(parameters)
805
+ def optional_param_count parameters
738
806
  parameters.select { |p| p.decl == :optarg }.length
739
807
  end
740
808
 
741
809
  # @param pin [Pin::Method]
742
810
  def abstract? pin
743
811
  pin.docstring.has_tag?('abstract') ||
744
- (pin.closure && pin.closure.docstring.has_tag?('abstract'))
812
+ pin.closure&.docstring&.has_tag?('abstract')
745
813
  end
746
814
 
747
815
  # @param pin [Pin::Method]
748
816
  # @return [Array<Source::Chain>]
749
- def fake_args_for(pin)
817
+ def fake_args_for pin
750
818
  args = []
751
819
  with_opts = false
752
820
  with_block = false
821
+ # @param pin [Pin::Parameter]
753
822
  pin.parameters.each do |pin|
754
- if [:kwarg, :kwoptarg, :kwrestarg].include?(pin.decl)
823
+ # @sg-ignore flow sensitive typing should be able to handle redefinition
824
+ if %i[kwarg kwoptarg kwrestarg].include?(pin.decl)
755
825
  with_opts = true
826
+ # @sg-ignore flow sensitive typing should be able to handle redefinition
756
827
  elsif pin.decl == :block
757
828
  with_block = true
829
+ # @sg-ignore flow sensitive typing should be able to handle redefinition
758
830
  elsif pin.decl == :restarg
759
831
  args.push Solargraph::Source::Chain.new([Solargraph::Source::Chain::Variable.new(pin.name)], nil, true)
760
832
  else
761
833
  args.push Solargraph::Source::Chain.new([Solargraph::Source::Chain::Variable.new(pin.name)])
762
834
  end
763
835
  end
764
- args.push Solargraph::Parser.chain_string('{}') if with_opts
765
- args.push Solargraph::Parser.chain_string('&') if with_block
836
+ pin_location = pin.location
837
+ starting_line = pin_location ? pin_location.range.start.line : 0
838
+ args.push Solargraph::Parser.chain_string('{}', filename, starting_line) if with_opts
839
+ args.push Solargraph::Parser.chain_string('&', filename, starting_line) if with_block
766
840
  args
767
841
  end
768
842
 
@@ -774,6 +848,7 @@ module Solargraph
774
848
  # @return [Set<Integer>]
775
849
  def all_sg_ignore_lines
776
850
  source.associated_comments.select do |_line, text|
851
+ # @sg-ignore Need to add nil check here
777
852
  text.include?('@sg-ignore')
778
853
  end.keys.to_set
779
854
  end