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
@@ -1,109 +1,99 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- class Source
5
- class Chain
6
- class Link
7
- include Equality
8
-
9
- # @return [String]
10
- attr_reader :word
11
-
12
- # @return [Pin::Base]
13
- attr_accessor :last_context
14
-
15
- # @param word [String]
16
- def initialize word = '<undefined>'
17
- @word = word
18
- end
19
-
20
- # @sg-ignore two problems - Declared return type
21
- # ::Solargraph::Source::Chain::Array does not match inferred
22
- # type ::Array(::Class<::Solargraph::Source::Chain::Link>,
23
- # ::String) for
24
- # Solargraph::Source::Chain::Link#equality_fields
25
- # and
26
- # Not enough arguments to Module#protected
27
- protected def equality_fields
28
- [self.class, word]
29
- end
30
-
31
- def undefined?
32
- word == '<undefined>'
33
- end
34
-
35
- def constant?
36
- is_a?(Chain::Constant)
37
- end
38
-
39
- # @param api_map [ApiMap]
40
- # @param name_pin [Pin::Base]
41
- # @param locals [::Array<Pin::Base>]
42
- # @return [::Array<Pin::Base>]
43
- def resolve api_map, name_pin, locals
44
- []
45
- end
46
-
47
- # debugging description of contents; not for machine use
48
- # @return [String]
49
- def desc
50
- word
51
- end
52
-
53
- def to_s
54
- desc
55
- end
56
-
57
- def inspect
58
- "#<#{self.class} - `#{self.desc}`>"
59
- end
60
-
61
- def head?
62
- @head ||= false
63
- end
64
-
65
- # Make a copy of this link marked as the head of a chain
66
- #
67
- # @return [self]
68
- def clone_head
69
- clone.mark_head(true)
70
- end
71
-
72
- # Make a copy of this link unmarked as the head of a chain
73
- #
74
- # @return [self]
75
- def clone_body
76
- clone.mark_head(false)
77
- end
78
-
79
- def nullable?
80
- false
81
- end
82
-
83
- # debugging description of contents; not for machine use
84
- #
85
- # @return [String]
86
- def desc
87
- word
88
- end
89
-
90
- def inspect
91
- "#<#{self.class} - `#{self.desc}`>"
92
- end
93
-
94
- include Logging
95
-
96
- protected
97
-
98
- # Mark whether this link is the head of a chain
99
- #
100
- # @param bool [Boolean]
101
- # @return [self]
102
- def mark_head bool
103
- @head = bool
104
- self
105
- end
106
- end
107
- end
108
- end
109
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ class Chain
6
+ class Link
7
+ include Equality
8
+
9
+ # @return [String]
10
+ attr_reader :word
11
+
12
+ # @return [Pin::Base]
13
+ attr_accessor :last_context
14
+
15
+ # @param word [String]
16
+ def initialize word = '<undefined>'
17
+ @word = word
18
+ end
19
+
20
+ def undefined?
21
+ word == '<undefined>'
22
+ end
23
+
24
+ def constant?
25
+ is_a?(Chain::Constant)
26
+ end
27
+
28
+ # @param api_map [ApiMap]
29
+ # @param name_pin [Pin::Base]
30
+ # @param locals [::Array<Pin::Base>]
31
+ # @return [::Array<Pin::Base>]
32
+ def resolve api_map, name_pin, locals
33
+ []
34
+ end
35
+
36
+ def to_s
37
+ desc
38
+ end
39
+
40
+ def inspect
41
+ "#<#{self.class} - `#{desc}`>"
42
+ end
43
+
44
+ def head?
45
+ @head ||= false
46
+ end
47
+
48
+ # Make a copy of this link marked as the head of a chain
49
+ #
50
+ # @return [self]
51
+ def clone_head
52
+ clone.mark_head(true)
53
+ end
54
+
55
+ # Make a copy of this link unmarked as the head of a chain
56
+ #
57
+ # @return [self]
58
+ def clone_body
59
+ clone.mark_head(false)
60
+ end
61
+
62
+ def nullable?
63
+ false
64
+ end
65
+
66
+ # debugging description of contents; not for machine use
67
+ #
68
+ # @return [String]
69
+ def desc
70
+ word
71
+ end
72
+
73
+ include Logging
74
+
75
+ protected
76
+
77
+ # @sg-ignore two problems - Declared return type
78
+ # ::Solargraph::Source::Chain::Array does not match inferred
79
+ # type ::Array(::Class<::Solargraph::Source::Chain::Link>,
80
+ # ::String) for
81
+ # Solargraph::Source::Chain::Link#equality_fields
82
+ # and
83
+ # Not enough arguments to Module#protected
84
+ def equality_fields
85
+ [self.class, word]
86
+ end
87
+
88
+ # Mark whether this link is the head of a chain
89
+ #
90
+ # @param bool [Boolean]
91
+ # @return [self]
92
+ def mark_head bool
93
+ @head = bool
94
+ self
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -6,21 +6,23 @@ module Solargraph
6
6
  class Source
7
7
  class Chain
8
8
  class Literal < Link
9
- def word
10
- @word ||= "<#{@type}>"
11
- end
12
-
13
- attr_reader :value
9
+ attr_reader :word, :value
14
10
 
15
11
  # @param type [String]
16
12
  # @param node [Parser::AST::Node, Object]
17
13
  def initialize type, node
14
+ super("<#{type}>")
15
+
18
16
  if node.is_a?(::Parser::AST::Node)
17
+ # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
19
18
  if node.type == :true
20
19
  @value = true
20
+ # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
21
21
  elsif node.type == :false
22
22
  @value = false
23
- elsif [:int, :sym].include?(node.type)
23
+ # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
24
+ elsif %i[int sym].include?(node.type)
25
+ # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
24
26
  @value = node.children.first
25
27
  end
26
28
  end
@@ -31,6 +33,7 @@ module Solargraph
31
33
 
32
34
  # @sg-ignore Fix "Not enough arguments to Module#protected"
33
35
  protected def equality_fields
36
+ # @sg-ignore literal arrays in this module turn into ::Solargraph::Source::Chain::Array
34
37
  super + [@value, @type, @literal_type, @complex_type]
35
38
  end
36
39
 
@@ -4,18 +4,24 @@ module Solargraph
4
4
  class Source
5
5
  class Chain
6
6
  class Or < Link
7
- def word
8
- '<or>'
9
- end
7
+ attr_reader :links
10
8
 
11
9
  # @param links [::Array<Chain>]
12
10
  def initialize links
11
+ super('<or>')
12
+
13
13
  @links = links
14
14
  end
15
15
 
16
16
  def resolve api_map, name_pin, locals
17
17
  types = @links.map { |link| link.infer(api_map, name_pin, locals) }
18
- [Solargraph::Pin::ProxyType.anonymous(Solargraph::ComplexType.new(types.uniq), source: :chain)]
18
+ combined_type = Solargraph::ComplexType.new(types)
19
+ unless types.all?(&:nullable?)
20
+ # @sg-ignore flow sensitive typing should be able to handle redefinition
21
+ combined_type = combined_type.without_nil
22
+ end
23
+
24
+ [Solargraph::Pin::ProxyType.anonymous(combined_type, source: :chain)]
19
25
  end
20
26
  end
21
27
  end
@@ -1,11 +1,13 @@
1
- module Solargraph
2
- class Source
3
- class Chain
4
- class QCall < Call
5
- def nullable?
6
- true
7
- end
8
- end
9
- end
10
- end
11
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ class Chain
6
+ class QCall < Call
7
+ def nullable?
8
+ true
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,13 +1,15 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- class Source
5
- class Chain
6
- class Variable < Link
7
- def resolve api_map, name_pin, locals
8
- api_map.get_instance_variable_pins(name_pin.context.namespace, name_pin.context.scope).select{|p| p.name == word}
9
- end
10
- end
11
- end
12
- end
13
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ class Chain
6
+ class Variable < Link
7
+ def resolve api_map, name_pin, locals
8
+ api_map.get_instance_variable_pins(name_pin.context.namespace, name_pin.context.scope).select do |p|
9
+ p.name == word
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,30 +1,28 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- class Source
5
- class Chain
6
- class ZSuper < Call
7
- # @return [String]
8
- attr_reader :word
9
-
10
- # @return [::Array<Chain>]
11
- attr_reader :arguments
12
-
13
- # @param word [String]
14
- # @param arguments [::Array<Chain>]
15
- # @param with_block [Boolean] True if the chain is inside a block
16
- # @param head [Boolean] True if the call is the start of its chain
17
- def initialize word, with_block = false
18
- super(word, nil, [], with_block)
19
- end
20
-
21
- # @param api_map [ApiMap]
22
- # @param name_pin [Pin::Base]
23
- # @param locals [::Array<Pin::Base>]
24
- def resolve api_map, name_pin, locals
25
- return super_pins(api_map, name_pin)
26
- end
27
- end
28
- end
29
- end
30
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ class Chain
6
+ class ZSuper < Call
7
+ # @return [String]
8
+ attr_reader :word
9
+
10
+ # @return [::Array<Chain>]
11
+ attr_reader :arguments
12
+
13
+ # @param word [String]
14
+ # @param with_block [Boolean] True if the chain is inside a block
15
+ def initialize word, with_block = false
16
+ super(word, nil, [], with_block)
17
+ end
18
+
19
+ # @param api_map [ApiMap]
20
+ # @param name_pin [Pin::Base]
21
+ # @param locals [::Array<Pin::Base>]
22
+ def resolve api_map, name_pin, locals
23
+ super_pins(api_map, name_pin)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -48,11 +48,6 @@ module Solargraph
48
48
 
49
49
  attr_reader :node
50
50
 
51
- # @sg-ignore Fix "Not enough arguments to Module#protected"
52
- protected def equality_fields
53
- [links, node]
54
- end
55
-
56
51
  # @param node [Parser::AST::Node, nil]
57
52
  # @param links [::Array<Chain::Link>]
58
53
  # @param splat [Boolean]
@@ -71,6 +66,7 @@ module Solargraph
71
66
 
72
67
  # @return [Chain]
73
68
  def base
69
+ # @sg-ignore Need to add nil check here
74
70
  @base ||= Chain.new(links[0..-2])
75
71
  end
76
72
 
@@ -78,25 +74,25 @@ module Solargraph
78
74
  #
79
75
  # @param api_map [ApiMap]
80
76
  #
81
- # @param name_pin [Pin::Base] A pin
82
- # representing the place in which expression is evaluated (e.g.,
83
- # a Method pin, or a Module or Class pin if not run within a
84
- # method - both in terms of the closure around the chain, as well
85
- # as the self type used for any method calls in head position.
77
+ # @param name_pin [Pin::Base] A pin representing the closure in
78
+ # which expression is evaluated (e.g., a Method pin, or a
79
+ # Module or Class pin if not run within a method - both in
80
+ # terms of the closure around the chain, as well as the self
81
+ # type used for any method calls in head position.
86
82
  #
87
83
  # Requirements for name_pin:
88
84
  #
89
85
  # * name_pin.context: This should be a type representing the
90
- # namespace where we can look up non-local variables and
91
- # method names. If it is a Class<X>, we will look up
92
- # :class scoped methods/variables.
86
+ # namespace where we can look up non-local variables. If
87
+ # it is a Class<X>, we will look up :class scoped
88
+ # instance variables.
93
89
  #
94
90
  # * name_pin.binder: Used for method call lookups only
95
91
  # (Chain::Call links). For method calls as the first
96
92
  # element in the chain, 'name_pin.binder' should be the
97
93
  # same as name_pin.context above. For method calls later
98
- # in the chain (e.g., 'b' in a.b.c), it should represent
99
- # 'a'.
94
+ # in the chain, it changes. (e.g., for 'b' in a.b.c, it
95
+ # should represent the type of 'a').
100
96
  #
101
97
  # @param locals [::Array<Pin::LocalVariable>] Any local
102
98
  # variables / method parameters etc visible by the statement
@@ -113,11 +109,14 @@ module Solargraph
113
109
  #
114
110
  # @todo ProxyType uses 'type' for the binder, but '
115
111
  working_pin = name_pin
112
+ # @sg-ignore Need to add nil check here
116
113
  links[0..-2].each do |link|
117
114
  pins = link.resolve(api_map, working_pin, locals)
118
115
  type = infer_from_definitions(pins, working_pin, api_map, locals)
119
116
  if type.undefined?
120
- logger.debug { "Chain#define(links=#{links.map(&:desc)}, name_pin=#{name_pin.inspect}, locals=#{locals}) => [] - undefined type from #{link.desc}" }
117
+ logger.debug do
118
+ "Chain#define(links=#{links.map(&:desc)}, name_pin=#{name_pin.inspect}, locals=#{locals}) => [] - undefined type from #{link.desc}"
119
+ end
121
120
  return []
122
121
  end
123
122
  # We continue to use the context from the head pin, in case
@@ -126,7 +125,9 @@ module Solargraph
126
125
  # for the binder, as this is chaining off of it, and the
127
126
  # binder is now the lhs of the rhs we are evaluating.
128
127
  working_pin = Pin::ProxyType.anonymous(name_pin.context, binder: type, closure: name_pin, source: :chain)
129
- logger.debug { "Chain#define(links=#{links.map(&:desc)}, name_pin=#{name_pin.inspect}, locals=#{locals}) - after processing #{link.desc}, new working_pin=#{working_pin} with binder #{working_pin.binder}" }
128
+ logger.debug do
129
+ "Chain#define(links=#{links.map(&:desc)}, name_pin=#{name_pin.inspect}, locals=#{locals}) - after processing #{link.desc}, new working_pin=#{working_pin} with binder #{working_pin.binder}"
130
+ end
130
131
  end
131
132
  links.last.last_context = working_pin
132
133
  links.last.resolve(api_map, working_pin, locals)
@@ -138,7 +139,8 @@ module Solargraph
138
139
  # @return [ComplexType]
139
140
  # @sg-ignore
140
141
  def infer api_map, name_pin, locals
141
- cache_key = [node, node&.location, links, name_pin&.return_type, locals]
142
+ # includes binder as it is mutable in Pin::Block
143
+ cache_key = [node, node&.location, links, name_pin&.return_type, name_pin&.binder, locals]
142
144
  if @@inference_invalidation_key == api_map.hash
143
145
  cached = @@inference_cache[cache_key]
144
146
  return cached if cached
@@ -147,23 +149,29 @@ module Solargraph
147
149
  @@inference_cache = {}
148
150
  end
149
151
  out = infer_uncached(api_map, name_pin, locals).downcast_to_literal_if_possible
150
- logger.debug { "Chain#infer() - caching result - cache_key_hash=#{cache_key.hash}, links.map(&:hash)=#{links.map(&:hash)}, links=#{links}, cache_key.map(&:hash) = #{cache_key.map(&:hash)}, cache_key=#{cache_key}" }
152
+ logger.debug do
153
+ "Chain#infer() - caching result - cache_key_hash=#{cache_key.hash}, links.map(&:hash)=#{links.map(&:hash)}, links=#{links}, cache_key.map(&:hash) = #{cache_key.map(&:hash)}, cache_key=#{cache_key}"
154
+ end
151
155
  @@inference_cache[cache_key] = out
152
156
  end
153
157
 
154
158
  # @param api_map [ApiMap]
155
159
  # @param name_pin [Pin::Base]
156
160
  # @param locals [::Array<Pin::LocalVariable>]
157
- # @return [ComplexType]
161
+ # @return [ComplexType, ComplexType::UniqueType]
158
162
  def infer_uncached api_map, name_pin, locals
159
163
  pins = define(api_map, name_pin, locals)
160
164
  if pins.empty?
161
- logger.debug { "Chain#infer_uncached(links=#{links.map(&:desc)}, locals=#{locals.map(&:desc)}) => undefined - no pins" }
165
+ logger.debug do
166
+ "Chain#infer_uncached(links=#{links.map(&:desc)}, locals=#{locals.map(&:desc)}) => undefined - no pins"
167
+ end
162
168
  return ComplexType::UNDEFINED
163
169
  end
164
170
  type = infer_from_definitions(pins, links.last.last_context, api_map, locals)
165
171
  out = maybe_nil(type)
166
- logger.debug { "Chain#infer_uncached(links=#{self.links.map(&:desc)}, locals=#{locals.map(&:desc)}, name_pin=#{name_pin}, name_pin.closure=#{name_pin.closure.inspect}, name_pin.binder=#{name_pin.binder}) => #{out.rooted_tags.inspect}" }
172
+ logger.debug do
173
+ "Chain#infer_uncached(links=#{links.map(&:desc)}, locals=#{locals.map(&:desc)}, name_pin=#{name_pin}, name_pin.closure=#{name_pin.closure.inspect}, name_pin.binder=#{name_pin.binder}) => #{out.rooted_tags.inspect}"
174
+ end
167
175
  out
168
176
  end
169
177
 
@@ -209,12 +217,12 @@ module Solargraph
209
217
  private
210
218
 
211
219
  # @param pins [::Array<Pin::Base>]
212
- # @param context [Pin::Base]
220
+ # @param name_pin [Pin::Base]
213
221
  # @param api_map [ApiMap]
214
222
  # @param locals [::Enumerable<Pin::LocalVariable>]
215
- # @return [ComplexType]
216
- def infer_from_definitions pins, context, api_map, locals
217
- # @type [::Array<ComplexType>]
223
+ # @return [ComplexType, ComplexType::UniqueType]
224
+ def infer_from_definitions pins, name_pin, api_map, locals
225
+ # @type [::Array<ComplexType, ComplexType::UniqueType>]
218
226
  types = []
219
227
  unresolved_pins = []
220
228
  # @todo this param tag shouldn't be needed to probe the type
@@ -232,7 +240,8 @@ module Solargraph
232
240
  # @todo even at strong, no typechecking complaint
233
241
  # happens when a [Pin::Base,nil] is passed into a method
234
242
  # that accepts only [Pin::Namespace] as an argument
235
- type = type.resolve_generics(pin.closure, context.binder)
243
+ # @sg-ignore Need to add nil check here
244
+ type = type.resolve_generics(pin.closure, name_pin.binder)
236
245
  end
237
246
  types << type
238
247
  else
@@ -241,17 +250,13 @@ module Solargraph
241
250
  end
242
251
 
243
252
  # Limit method inference recursion
244
- if @@inference_depth >= 10 && pins.first.is_a?(Pin::Method)
245
- return ComplexType::UNDEFINED
246
- end
253
+ return ComplexType::UNDEFINED if @@inference_depth >= 10 && pins.first.is_a?(Pin::Method)
247
254
 
248
255
  @@inference_depth += 1
249
256
  # @param pin [Pin::Base]
250
257
  unresolved_pins.each do |pin|
251
258
  # Avoid infinite recursion
252
- if @@inference_stack.include?(pin.identity)
253
- next
254
- end
259
+ next if @@inference_stack.include?(pin.identity)
255
260
 
256
261
  @@inference_stack.push(pin.identity)
257
262
  type = pin.probe(api_map)
@@ -271,21 +276,27 @@ module Solargraph
271
276
  else
272
277
  ComplexType.new(types)
273
278
  end
274
- if context.nil? || context.return_type.undefined?
279
+ if name_pin.nil? || name_pin.context.undefined?
275
280
  # up to downstream to resolve self type
276
281
  return type
277
282
  end
278
-
279
- type.self_to_type(context.return_type)
283
+ type.self_to_type(name_pin.context)
280
284
  end
281
285
 
282
- # @param type [ComplexType]
283
- # @return [ComplexType]
286
+ # @param type [ComplexType, ComplexType::UniqueType]
287
+ # @return [ComplexType, ComplexType::UniqueType]
284
288
  def maybe_nil type
285
289
  return type if type.undefined? || type.void? || type.nullable?
286
290
  return type unless nullable?
287
291
  ComplexType.new(type.items + [ComplexType::NIL])
288
292
  end
293
+
294
+ protected
295
+
296
+ # @sg-ignore Fix "Not enough arguments to Module#protected"
297
+ def equality_fields
298
+ [links, node]
299
+ end
289
300
  end
290
301
  end
291
302
  end
@@ -7,13 +7,13 @@ module Solargraph
7
7
  class Change
8
8
  include EncodingFixes
9
9
 
10
- # @return [Range]
10
+ # @return [Range, nil]
11
11
  attr_reader :range
12
12
 
13
13
  # @return [String]
14
14
  attr_reader :new_text
15
15
 
16
- # @param range [Range] The starting and ending positions of the change.
16
+ # @param range [Range, nil] The starting and ending positions of the change.
17
17
  # If nil, the original text will be overwritten.
18
18
  # @param new_text [String] The text to be changed.
19
19
  def initialize range, new_text
@@ -28,12 +28,14 @@ module Solargraph
28
28
  # syntax errors will be repaired.
29
29
  # @return [String] The updated text.
30
30
  def write text, nullable = false
31
- if nullable and !range.nil? and new_text.match(/[.\[{(@$:]$/)
31
+ if nullable && !range.nil? && new_text.match(/[.\[{(@$:]$/)
32
32
  [':', '@'].each do |dupable|
33
33
  next unless new_text == dupable
34
+ # @sg-ignore flow sensitive typing needs to handle attrs
34
35
  offset = Position.to_offset(text, range.start)
35
36
  if text[offset - 1] == dupable
36
37
  p = Position.from_offset(text, offset - 1)
38
+ # @sg-ignore flow sensitive typing needs to handle attrs
37
39
  r = Change.new(Range.new(p, range.start), ' ')
38
40
  text = r.write(text)
39
41
  end
@@ -58,10 +60,13 @@ module Solargraph
58
60
  fixed
59
61
  else
60
62
  result = commit text, fixed
63
+ # @sg-ignore flow sensitive typing needs to handle attrs
61
64
  off = Position.to_offset(text, range.start)
65
+ # @sg-ignore Need to add nil check here
62
66
  match = result[0, off].match(/[.:]+\z/)
63
67
  if match
64
- result = result[0, off].sub(/#{match[0]}\z/, ' ' * match[0].length) + result[off..-1]
68
+ # @sg-ignore flow sensitive typing should be able to handle redefinition
69
+ result = result[0, off].sub(/#{match[0]}\z/, ' ' * match[0].length) + result[off..]
65
70
  end
66
71
  result
67
72
  end
@@ -73,9 +78,11 @@ module Solargraph
73
78
  # @param insert [String]
74
79
  # @return [String]
75
80
  def commit text, insert
81
+ # @sg-ignore Need to add nil check here
76
82
  start_offset = Position.to_offset(text, range.start)
83
+ # @sg-ignore Need to add nil check here
77
84
  end_offset = Position.to_offset(text, range.ending)
78
- (start_offset == 0 ? '' : text[0..start_offset-1].to_s) + normalize(insert) + text[end_offset..-1].to_s
85
+ (start_offset.zero? ? '' : text[0..(start_offset - 1)].to_s) + normalize(insert) + text[end_offset..].to_s
79
86
  end
80
87
  end
81
88
  end