solargraph 0.58.1 → 0.58.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 (147) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +7 -1
  4. data/lib/solargraph/api_map/cache.rb +110 -110
  5. data/lib/solargraph/api_map/constants.rb +279 -279
  6. data/lib/solargraph/api_map/index.rb +193 -193
  7. data/lib/solargraph/api_map/source_to_yard.rb +97 -97
  8. data/lib/solargraph/api_map/store.rb +384 -384
  9. data/lib/solargraph/api_map.rb +945 -945
  10. data/lib/solargraph/complex_type/type_methods.rb +228 -228
  11. data/lib/solargraph/complex_type/unique_type.rb +482 -482
  12. data/lib/solargraph/complex_type.rb +444 -444
  13. data/lib/solargraph/convention/data_definition/data_definition_node.rb +91 -91
  14. data/lib/solargraph/convention/data_definition.rb +105 -105
  15. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +61 -61
  16. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +102 -102
  17. data/lib/solargraph/convention/struct_definition.rb +164 -164
  18. data/lib/solargraph/diagnostics/require_not_found.rb +53 -53
  19. data/lib/solargraph/diagnostics/rubocop.rb +118 -118
  20. data/lib/solargraph/diagnostics/rubocop_helpers.rb +68 -68
  21. data/lib/solargraph/diagnostics/type_check.rb +55 -55
  22. data/lib/solargraph/doc_map.rb +439 -439
  23. data/lib/solargraph/equality.rb +34 -34
  24. data/lib/solargraph/gem_pins.rb +98 -98
  25. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  26. data/lib/solargraph/language_server/host/dispatch.rb +130 -130
  27. data/lib/solargraph/language_server/host/message_worker.rb +112 -112
  28. data/lib/solargraph/language_server/host/sources.rb +99 -99
  29. data/lib/solargraph/language_server/host.rb +878 -878
  30. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +114 -114
  31. data/lib/solargraph/language_server/message/extended/document.rb +23 -23
  32. data/lib/solargraph/language_server/message/text_document/completion.rb +56 -56
  33. data/lib/solargraph/language_server/message/text_document/definition.rb +40 -40
  34. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +26 -26
  35. data/lib/solargraph/language_server/message/text_document/formatting.rb +148 -148
  36. data/lib/solargraph/language_server/message/text_document/hover.rb +58 -58
  37. data/lib/solargraph/language_server/message/text_document/signature_help.rb +24 -24
  38. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -25
  39. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -23
  40. data/lib/solargraph/library.rb +683 -683
  41. data/lib/solargraph/location.rb +82 -82
  42. data/lib/solargraph/logging.rb +37 -37
  43. data/lib/solargraph/parser/comment_ripper.rb +69 -69
  44. data/lib/solargraph/parser/flow_sensitive_typing.rb +255 -255
  45. data/lib/solargraph/parser/node_processor/base.rb +92 -92
  46. data/lib/solargraph/parser/node_processor.rb +62 -62
  47. data/lib/solargraph/parser/parser_gem/class_methods.rb +149 -149
  48. data/lib/solargraph/parser/parser_gem/node_chainer.rb +166 -166
  49. data/lib/solargraph/parser/parser_gem/node_methods.rb +486 -486
  50. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -22
  51. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +59 -59
  52. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +15 -15
  53. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +46 -46
  54. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +53 -53
  55. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +23 -23
  56. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +40 -40
  57. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +29 -29
  58. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +59 -59
  59. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -98
  60. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -17
  61. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +38 -38
  62. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +52 -52
  63. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +291 -291
  64. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +29 -29
  65. data/lib/solargraph/parser/parser_gem/node_processors.rb +70 -70
  66. data/lib/solargraph/parser/region.rb +69 -69
  67. data/lib/solargraph/parser/snippet.rb +17 -17
  68. data/lib/solargraph/pin/base.rb +729 -729
  69. data/lib/solargraph/pin/base_variable.rb +126 -126
  70. data/lib/solargraph/pin/block.rb +104 -104
  71. data/lib/solargraph/pin/breakable.rb +9 -9
  72. data/lib/solargraph/pin/callable.rb +231 -231
  73. data/lib/solargraph/pin/closure.rb +72 -72
  74. data/lib/solargraph/pin/common.rb +79 -79
  75. data/lib/solargraph/pin/conversions.rb +123 -123
  76. data/lib/solargraph/pin/delegated_method.rb +120 -120
  77. data/lib/solargraph/pin/documenting.rb +114 -114
  78. data/lib/solargraph/pin/instance_variable.rb +34 -34
  79. data/lib/solargraph/pin/keyword.rb +20 -20
  80. data/lib/solargraph/pin/local_variable.rb +75 -75
  81. data/lib/solargraph/pin/method.rb +672 -672
  82. data/lib/solargraph/pin/method_alias.rb +34 -34
  83. data/lib/solargraph/pin/namespace.rb +115 -115
  84. data/lib/solargraph/pin/parameter.rb +275 -275
  85. data/lib/solargraph/pin/proxy_type.rb +39 -39
  86. data/lib/solargraph/pin/reference/override.rb +47 -47
  87. data/lib/solargraph/pin/reference/superclass.rb +15 -15
  88. data/lib/solargraph/pin/reference.rb +39 -39
  89. data/lib/solargraph/pin/search.rb +61 -61
  90. data/lib/solargraph/pin/signature.rb +61 -61
  91. data/lib/solargraph/pin/symbol.rb +53 -53
  92. data/lib/solargraph/pin/until.rb +18 -18
  93. data/lib/solargraph/pin/while.rb +18 -18
  94. data/lib/solargraph/pin.rb +44 -44
  95. data/lib/solargraph/pin_cache.rb +245 -245
  96. data/lib/solargraph/position.rb +132 -119
  97. data/lib/solargraph/range.rb +112 -112
  98. data/lib/solargraph/rbs_map/conversions.rb +823 -823
  99. data/lib/solargraph/rbs_map/core_map.rb +58 -58
  100. data/lib/solargraph/rbs_map/stdlib_map.rb +43 -43
  101. data/lib/solargraph/rbs_map.rb +163 -163
  102. data/lib/solargraph/shell.rb +352 -352
  103. data/lib/solargraph/source/chain/call.rb +337 -337
  104. data/lib/solargraph/source/chain/constant.rb +26 -26
  105. data/lib/solargraph/source/chain/hash.rb +34 -34
  106. data/lib/solargraph/source/chain/if.rb +28 -28
  107. data/lib/solargraph/source/chain/instance_variable.rb +13 -13
  108. data/lib/solargraph/source/chain/literal.rb +48 -48
  109. data/lib/solargraph/source/chain/or.rb +23 -23
  110. data/lib/solargraph/source/chain.rb +291 -291
  111. data/lib/solargraph/source/change.rb +82 -82
  112. data/lib/solargraph/source/cursor.rb +166 -166
  113. data/lib/solargraph/source/source_chainer.rb +194 -194
  114. data/lib/solargraph/source/updater.rb +55 -55
  115. data/lib/solargraph/source.rb +498 -498
  116. data/lib/solargraph/source_map/clip.rb +226 -226
  117. data/lib/solargraph/source_map/data.rb +34 -34
  118. data/lib/solargraph/source_map/mapper.rb +259 -259
  119. data/lib/solargraph/source_map.rb +212 -212
  120. data/lib/solargraph/type_checker/checks.rb +124 -124
  121. data/lib/solargraph/type_checker/param_def.rb +37 -37
  122. data/lib/solargraph/type_checker/problem.rb +32 -32
  123. data/lib/solargraph/type_checker/rules.rb +84 -84
  124. data/lib/solargraph/type_checker.rb +814 -814
  125. data/lib/solargraph/version.rb +1 -1
  126. data/lib/solargraph/workspace/config.rb +255 -255
  127. data/lib/solargraph/workspace/require_paths.rb +97 -97
  128. data/lib/solargraph/workspace.rb +220 -220
  129. data/lib/solargraph/yard_map/helpers.rb +44 -44
  130. data/lib/solargraph/yard_map/mapper/to_method.rb +130 -130
  131. data/lib/solargraph/yard_map/mapper/to_namespace.rb +31 -31
  132. data/lib/solargraph/yard_map/mapper.rb +79 -79
  133. data/lib/solargraph/yard_map/to_method.rb +89 -89
  134. data/lib/solargraph/yardoc.rb +87 -87
  135. data/lib/solargraph.rb +105 -105
  136. data/rbs_collection.yaml +1 -1
  137. metadata +12 -12
  138. /data/{sig → rbs}/shims/ast/0/node.rbs +0 -0
  139. /data/{sig → rbs}/shims/ast/2.4/.rbs_meta.yaml +0 -0
  140. /data/{sig → rbs}/shims/ast/2.4/ast.rbs +0 -0
  141. /data/{sig → rbs}/shims/parser/3.2.0.1/builders/default.rbs +0 -0
  142. /data/{sig → rbs}/shims/parser/3.2.0.1/manifest.yaml +0 -0
  143. /data/{sig → rbs}/shims/parser/3.2.0.1/parser.rbs +0 -0
  144. /data/{sig → rbs}/shims/parser/3.2.0.1/polyfill.rbs +0 -0
  145. /data/{sig → rbs}/shims/thor/1.2.0.1/.rbs_meta.yaml +0 -0
  146. /data/{sig → rbs}/shims/thor/1.2.0.1/manifest.yaml +0 -0
  147. /data/{sig → rbs}/shims/thor/1.2.0.1/thor.rbs +0 -0
@@ -1,212 +1,212 @@
1
- # frozen_string_literal: true
2
-
3
- require 'yard'
4
- require 'solargraph/yard_tags'
5
-
6
- module Solargraph
7
- # An index of Pins and other ApiMap-related data for a single Source
8
- # that can be queried.
9
- #
10
- class SourceMap
11
- autoload :Mapper, 'solargraph/source_map/mapper'
12
- autoload :Clip, 'solargraph/source_map/clip'
13
- autoload :Completion, 'solargraph/source_map/completion'
14
- autoload :Data, 'solargraph/source_map/data'
15
-
16
- # @return [Source]
17
- attr_reader :source
18
-
19
- # @return [Array<Pin::Base>]
20
- def pins
21
- data.pins
22
- end
23
-
24
- # @return [Array<Pin::Base>]
25
- def all_pins
26
- pins + convention_pins
27
- end
28
-
29
- # @return [Array<Pin::LocalVariable>]
30
- def locals
31
- data.locals
32
- end
33
-
34
- # @param source [Source]
35
- def initialize source
36
- @source = source
37
-
38
- conventions_environ.merge Convention.for_local(self) unless filename.nil?
39
- # FIXME: unmemoizing the document_symbols in case it was called and memoized from any of conventions above
40
- # this is to ensure that the convention_pins from all conventions are used in the document_symbols.
41
- # solargraph-rails is known to use this method to get the document symbols. It should probably be removed.
42
- @document_symbols = nil
43
- self.convention_pins = conventions_environ.pins
44
- # @type [Hash{Class<Pin::Base> => Array<Pin::Base>}]
45
- @pin_select_cache = {}
46
- end
47
-
48
- # @generic T
49
- # @param klass [Class<generic<T>>]
50
- #
51
- # @return [Array<generic<T>>]
52
- def pins_by_class klass
53
- @pin_select_cache[klass] ||= pin_class_hash.select { |key, _| key <= klass }.values.flatten
54
- end
55
-
56
- # A hash representing the state of the source map's API.
57
- #
58
- # ApiMap#catalog uses this value to determine whether it needs to clear its
59
- # cache.
60
- #
61
- # @return [Integer]
62
- 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
64
- end
65
-
66
- # @return [String]
67
- def filename
68
- source.filename
69
- end
70
-
71
- # @return [String]
72
- def code
73
- source.code
74
- end
75
-
76
- # @return [Array<Pin::Reference::Require>]
77
- def requires
78
- pins_by_class(Pin::Reference::Require)
79
- end
80
-
81
- # @return [Environ]
82
- def conventions_environ
83
- @conventions_environ ||= Environ.new
84
- end
85
-
86
- # all pins except Solargraph::Pin::Reference::Reference
87
- # @return [Array<Pin::Base>]
88
- def document_symbols
89
- @document_symbols ||= (pins + convention_pins).select do |pin|
90
- pin.path && !pin.path.empty?
91
- end
92
- end
93
-
94
- # @param query [String]
95
- # @return [Array<Pin::Base>]
96
- def query_symbols query
97
- Pin::Search.new(document_symbols, query).results
98
- end
99
-
100
- # @param position [Position]
101
- # @return [Source::Cursor]
102
- def cursor_at position
103
- Source::Cursor.new(source, position)
104
- end
105
-
106
- # @param path [String]
107
- # @return [Pin::Base]
108
- def first_pin path
109
- pins.select { |p| p.path == path }.first
110
- end
111
-
112
- # @param location [Solargraph::Location]
113
- # @return [Array<Solargraph::Pin::Base>]
114
- def locate_pins location
115
- # return nil unless location.start_with?("#{filename}:")
116
- (pins + locals).select { |pin| pin.location == location }
117
- end
118
-
119
- # @param line [Integer]
120
- # @param character [Integer]
121
- # @return [Pin::Method,Pin::Namespace]
122
- def locate_named_path_pin line, character
123
- _locate_pin line, character, Pin::Namespace, Pin::Method
124
- end
125
-
126
- # @param line [Integer]
127
- # @param character [Integer]
128
- # @return [Pin::Namespace,Pin::Method,Pin::Block]
129
- def locate_closure_pin line, character
130
- _locate_pin line, character, Pin::Closure
131
- end
132
-
133
- # @deprecated Please use locate_closure_pin instead
134
- alias locate_block_pin locate_closure_pin
135
-
136
- # @param name [String]
137
- # @return [Array<Location>]
138
- def references name
139
- source.references name
140
- end
141
-
142
- # @param location [Location]
143
- # @return [Array<Pin::LocalVariable>]
144
- def locals_at(location)
145
- return [] if location.filename != filename
146
- closure = locate_named_path_pin(location.range.start.line, location.range.start.character)
147
- locals.select { |pin| pin.visible_at?(closure, location) }
148
- end
149
-
150
- class << self
151
- # @param filename [String]
152
- # @return [SourceMap]
153
- def load filename
154
- source = Solargraph::Source.load(filename)
155
- SourceMap.map(source)
156
- end
157
-
158
- # @param code [String]
159
- # @param filename [String, nil]
160
- # @return [SourceMap]
161
- def load_string code, filename = nil
162
- source = Solargraph::Source.load_string(code, filename)
163
- SourceMap.map(source)
164
- end
165
-
166
- # @deprecated
167
- # @param source [Source]
168
- # @return [SourceMap]
169
- def map source
170
- new(source)
171
- end
172
- end
173
-
174
- private
175
-
176
- # @return [Array<Pin::Base>]
177
- attr_writer :convention_pins
178
-
179
- # @return [Hash{Class<Pin::Base> => Array<Pin::Base>}]
180
- def pin_class_hash
181
- @pin_class_hash ||= pins.to_set.classify(&:class).transform_values(&:to_a)
182
- end
183
-
184
- # @return [Data]
185
- def data
186
- @data ||= Data.new(source)
187
- end
188
-
189
- # @return [Array<Pin::Base>]
190
- def convention_pins
191
- @convention_pins || []
192
- end
193
-
194
- # @param line [Integer]
195
- # @param character [Integer]
196
- # @param klasses [Array<Class>]
197
- # @return [Pin::Base, nil]
198
- def _locate_pin line, character, *klasses
199
- position = Position.new(line, character)
200
- found = nil
201
- pins.each do |pin|
202
- # @todo Attribute pins should not be treated like closures, but
203
- # there's probably a better way to handle it
204
- 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)
206
- break if pin.location.range.start.line > line
207
- end
208
- # Assuming the root pin is always valid
209
- found || pins.first
210
- end
211
- end
212
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'yard'
4
+ require 'solargraph/yard_tags'
5
+
6
+ module Solargraph
7
+ # An index of Pins and other ApiMap-related data for a single Source
8
+ # that can be queried.
9
+ #
10
+ class SourceMap
11
+ autoload :Mapper, 'solargraph/source_map/mapper'
12
+ autoload :Clip, 'solargraph/source_map/clip'
13
+ autoload :Completion, 'solargraph/source_map/completion'
14
+ autoload :Data, 'solargraph/source_map/data'
15
+
16
+ # @return [Source]
17
+ attr_reader :source
18
+
19
+ # @return [Array<Pin::Base>]
20
+ def pins
21
+ data.pins
22
+ end
23
+
24
+ # @return [Array<Pin::Base>]
25
+ def all_pins
26
+ pins + convention_pins
27
+ end
28
+
29
+ # @return [Array<Pin::LocalVariable>]
30
+ def locals
31
+ data.locals
32
+ end
33
+
34
+ # @param source [Source]
35
+ def initialize source
36
+ @source = source
37
+
38
+ conventions_environ.merge Convention.for_local(self) unless filename.nil?
39
+ # FIXME: unmemoizing the document_symbols in case it was called and memoized from any of conventions above
40
+ # this is to ensure that the convention_pins from all conventions are used in the document_symbols.
41
+ # solargraph-rails is known to use this method to get the document symbols. It should probably be removed.
42
+ @document_symbols = nil
43
+ self.convention_pins = conventions_environ.pins
44
+ # @type [Hash{Class<Pin::Base> => Array<Pin::Base>}]
45
+ @pin_select_cache = {}
46
+ end
47
+
48
+ # @generic T
49
+ # @param klass [Class<generic<T>>]
50
+ #
51
+ # @return [Array<generic<T>>]
52
+ def pins_by_class klass
53
+ @pin_select_cache[klass] ||= pin_class_hash.select { |key, _| key <= klass }.values.flatten
54
+ end
55
+
56
+ # A hash representing the state of the source map's API.
57
+ #
58
+ # ApiMap#catalog uses this value to determine whether it needs to clear its
59
+ # cache.
60
+ #
61
+ # @return [Integer]
62
+ 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
64
+ end
65
+
66
+ # @return [String]
67
+ def filename
68
+ source.filename
69
+ end
70
+
71
+ # @return [String]
72
+ def code
73
+ source.code
74
+ end
75
+
76
+ # @return [Array<Pin::Reference::Require>]
77
+ def requires
78
+ pins_by_class(Pin::Reference::Require)
79
+ end
80
+
81
+ # @return [Environ]
82
+ def conventions_environ
83
+ @conventions_environ ||= Environ.new
84
+ end
85
+
86
+ # all pins except Solargraph::Pin::Reference::Reference
87
+ # @return [Array<Pin::Base>]
88
+ def document_symbols
89
+ @document_symbols ||= (pins + convention_pins).select do |pin|
90
+ pin.path && !pin.path.empty?
91
+ end
92
+ end
93
+
94
+ # @param query [String]
95
+ # @return [Array<Pin::Base>]
96
+ def query_symbols query
97
+ Pin::Search.new(document_symbols, query).results
98
+ end
99
+
100
+ # @param position [Position]
101
+ # @return [Source::Cursor]
102
+ def cursor_at position
103
+ Source::Cursor.new(source, position)
104
+ end
105
+
106
+ # @param path [String]
107
+ # @return [Pin::Base]
108
+ def first_pin path
109
+ pins.select { |p| p.path == path }.first
110
+ end
111
+
112
+ # @param location [Solargraph::Location]
113
+ # @return [Array<Solargraph::Pin::Base>]
114
+ def locate_pins location
115
+ # return nil unless location.start_with?("#{filename}:")
116
+ (pins + locals).select { |pin| pin.location == location }
117
+ end
118
+
119
+ # @param line [Integer]
120
+ # @param character [Integer]
121
+ # @return [Pin::Method,Pin::Namespace]
122
+ def locate_named_path_pin line, character
123
+ _locate_pin line, character, Pin::Namespace, Pin::Method
124
+ end
125
+
126
+ # @param line [Integer]
127
+ # @param character [Integer]
128
+ # @return [Pin::Namespace,Pin::Method,Pin::Block]
129
+ def locate_closure_pin line, character
130
+ _locate_pin line, character, Pin::Closure
131
+ end
132
+
133
+ # @deprecated Please use locate_closure_pin instead
134
+ alias locate_block_pin locate_closure_pin
135
+
136
+ # @param name [String]
137
+ # @return [Array<Location>]
138
+ def references name
139
+ source.references name
140
+ end
141
+
142
+ # @param location [Location]
143
+ # @return [Array<Pin::LocalVariable>]
144
+ def locals_at(location)
145
+ return [] if location.filename != filename
146
+ closure = locate_named_path_pin(location.range.start.line, location.range.start.character)
147
+ locals.select { |pin| pin.visible_at?(closure, location) }
148
+ end
149
+
150
+ class << self
151
+ # @param filename [String]
152
+ # @return [SourceMap]
153
+ def load filename
154
+ source = Solargraph::Source.load(filename)
155
+ SourceMap.map(source)
156
+ end
157
+
158
+ # @param code [String]
159
+ # @param filename [String, nil]
160
+ # @return [SourceMap]
161
+ def load_string code, filename = nil
162
+ source = Solargraph::Source.load_string(code, filename)
163
+ SourceMap.map(source)
164
+ end
165
+
166
+ # @deprecated
167
+ # @param source [Source]
168
+ # @return [SourceMap]
169
+ def map source
170
+ new(source)
171
+ end
172
+ end
173
+
174
+ private
175
+
176
+ # @return [Array<Pin::Base>]
177
+ attr_writer :convention_pins
178
+
179
+ # @return [Hash{Class<Pin::Base> => Array<Pin::Base>}]
180
+ def pin_class_hash
181
+ @pin_class_hash ||= pins.to_set.classify(&:class).transform_values(&:to_a)
182
+ end
183
+
184
+ # @return [Data]
185
+ def data
186
+ @data ||= Data.new(source)
187
+ end
188
+
189
+ # @return [Array<Pin::Base>]
190
+ def convention_pins
191
+ @convention_pins || []
192
+ end
193
+
194
+ # @param line [Integer]
195
+ # @param character [Integer]
196
+ # @param klasses [Array<Class>]
197
+ # @return [Pin::Base, nil]
198
+ def _locate_pin line, character, *klasses
199
+ position = Position.new(line, character)
200
+ found = nil
201
+ pins.each do |pin|
202
+ # @todo Attribute pins should not be treated like closures, but
203
+ # there's probably a better way to handle it
204
+ 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)
206
+ break if pin.location.range.start.line > line
207
+ end
208
+ # Assuming the root pin is always valid
209
+ found || pins.first
210
+ end
211
+ end
212
+ end
@@ -1,124 +1,124 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- class TypeChecker
5
- # Helper methods for performing type checks
6
- #
7
- module Checks
8
- module_function
9
-
10
- # Compare an expected type with an inferred type. Common usage is to
11
- # check if the type declared in a method's @return tag matches the type
12
- # inferred from static analysis of the code.
13
- #
14
- # @param api_map [ApiMap]
15
- # @param expected [ComplexType]
16
- # @param inferred [ComplexType]
17
- # @return [Boolean]
18
- def types_match? api_map, expected, inferred
19
- return true if expected.to_s == inferred.to_s
20
- matches = []
21
- expected.each do |exp|
22
- found = false
23
- inferred.each do |inf|
24
- # if api_map.super_and_sub?(fuzz(inf), fuzz(exp))
25
- if either_way?(api_map, inf, exp)
26
- found = true
27
- matches.push inf
28
- break
29
- end
30
- end
31
- return false unless found
32
- end
33
- inferred.each do |inf|
34
- next if matches.include?(inf)
35
- found = false
36
- expected.each do |exp|
37
- # if api_map.super_and_sub?(fuzz(inf), fuzz(exp))
38
- if either_way?(api_map, inf, exp)
39
- found = true
40
- break
41
- end
42
- end
43
- return false unless found
44
- end
45
- true
46
- end
47
-
48
- # @param api_map [ApiMap]
49
- # @param expected [ComplexType]
50
- # @param inferred [ComplexType]
51
- # @return [Boolean]
52
- def any_types_match? api_map, expected, inferred
53
- expected = expected.downcast_to_literal_if_possible
54
- inferred = inferred.downcast_to_literal_if_possible
55
- return duck_types_match?(api_map, expected, inferred) if expected.duck_type?
56
- # walk through the union expected type and see if any members
57
- # of the union match the inferred type
58
- expected.each do |exp|
59
- next if exp.duck_type?
60
- # @todo: there should be a level of typechecking where all
61
- # unique types in the inferred must match one of the
62
- # expected unique types
63
- inferred.each do |inf|
64
- # return true if exp == inf || api_map.super_and_sub?(fuzz(inf), fuzz(exp))
65
- return true if exp == inf || either_way?(api_map, inf, exp)
66
- end
67
- end
68
- false
69
- end
70
-
71
- # @param api_map [ApiMap]
72
- # @param inferred [ComplexType]
73
- # @param expected [ComplexType]
74
- # @return [Boolean]
75
- def all_types_match? api_map, inferred, expected
76
- expected = expected.downcast_to_literal_if_possible
77
- inferred = inferred.downcast_to_literal_if_possible
78
- return duck_types_match?(api_map, expected, inferred) if expected.duck_type?
79
- inferred.each do |inf|
80
- next if inf.duck_type?
81
- return false unless expected.any? { |exp| exp == inf || either_way?(api_map, inf, exp) }
82
- end
83
- true
84
- end
85
-
86
- # @param api_map [ApiMap]
87
- # @param expected [ComplexType]
88
- # @param inferred [ComplexType]
89
- # @return [Boolean]
90
- def duck_types_match? api_map, expected, inferred
91
- raise ArgumentError, 'Expected type must be duck type' unless expected.duck_type?
92
- expected.each do |exp|
93
- next unless exp.duck_type?
94
- quack = exp.to_s[1..-1]
95
- return false if api_map.get_method_stack(inferred.namespace, quack, scope: inferred.scope).empty?
96
- end
97
- true
98
- end
99
-
100
- # @param type [ComplexType::UniqueType]
101
- # @return [String]
102
- def fuzz type
103
- if type.parameters?
104
- type.name
105
- else
106
- type.tag
107
- end
108
- end
109
-
110
- # @param api_map [ApiMap]
111
- # @param cls1 [ComplexType::UniqueType]
112
- # @param cls2 [ComplexType::UniqueType]
113
- # @return [Boolean]
114
- def either_way?(api_map, cls1, cls2)
115
- # @todo there should be a level of typechecking which uses the
116
- # full tag with parameters to determine compatibility
117
- f1 = cls1.name
118
- f2 = cls2.name
119
- api_map.type_include?(f1, f2) || api_map.super_and_sub?(f1, f2) || api_map.super_and_sub?(f2, f1)
120
- # api_map.type_include?(f1, f2) || api_map.super_and_sub?(f1, f2) || api_map.super_and_sub?(f2, f1)
121
- end
122
- end
123
- end
124
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class TypeChecker
5
+ # Helper methods for performing type checks
6
+ #
7
+ module Checks
8
+ module_function
9
+
10
+ # Compare an expected type with an inferred type. Common usage is to
11
+ # check if the type declared in a method's @return tag matches the type
12
+ # inferred from static analysis of the code.
13
+ #
14
+ # @param api_map [ApiMap]
15
+ # @param expected [ComplexType]
16
+ # @param inferred [ComplexType]
17
+ # @return [Boolean]
18
+ def types_match? api_map, expected, inferred
19
+ return true if expected.to_s == inferred.to_s
20
+ matches = []
21
+ expected.each do |exp|
22
+ found = false
23
+ inferred.each do |inf|
24
+ # if api_map.super_and_sub?(fuzz(inf), fuzz(exp))
25
+ if either_way?(api_map, inf, exp)
26
+ found = true
27
+ matches.push inf
28
+ break
29
+ end
30
+ end
31
+ return false unless found
32
+ end
33
+ inferred.each do |inf|
34
+ next if matches.include?(inf)
35
+ found = false
36
+ expected.each do |exp|
37
+ # if api_map.super_and_sub?(fuzz(inf), fuzz(exp))
38
+ if either_way?(api_map, inf, exp)
39
+ found = true
40
+ break
41
+ end
42
+ end
43
+ return false unless found
44
+ end
45
+ true
46
+ end
47
+
48
+ # @param api_map [ApiMap]
49
+ # @param expected [ComplexType]
50
+ # @param inferred [ComplexType]
51
+ # @return [Boolean]
52
+ def any_types_match? api_map, expected, inferred
53
+ expected = expected.downcast_to_literal_if_possible
54
+ inferred = inferred.downcast_to_literal_if_possible
55
+ return duck_types_match?(api_map, expected, inferred) if expected.duck_type?
56
+ # walk through the union expected type and see if any members
57
+ # of the union match the inferred type
58
+ expected.each do |exp|
59
+ next if exp.duck_type?
60
+ # @todo: there should be a level of typechecking where all
61
+ # unique types in the inferred must match one of the
62
+ # expected unique types
63
+ inferred.each do |inf|
64
+ # return true if exp == inf || api_map.super_and_sub?(fuzz(inf), fuzz(exp))
65
+ return true if exp == inf || either_way?(api_map, inf, exp)
66
+ end
67
+ end
68
+ false
69
+ end
70
+
71
+ # @param api_map [ApiMap]
72
+ # @param inferred [ComplexType]
73
+ # @param expected [ComplexType]
74
+ # @return [Boolean]
75
+ def all_types_match? api_map, inferred, expected
76
+ expected = expected.downcast_to_literal_if_possible
77
+ inferred = inferred.downcast_to_literal_if_possible
78
+ return duck_types_match?(api_map, expected, inferred) if expected.duck_type?
79
+ inferred.each do |inf|
80
+ next if inf.duck_type?
81
+ return false unless expected.any? { |exp| exp == inf || either_way?(api_map, inf, exp) }
82
+ end
83
+ true
84
+ end
85
+
86
+ # @param api_map [ApiMap]
87
+ # @param expected [ComplexType]
88
+ # @param inferred [ComplexType]
89
+ # @return [Boolean]
90
+ def duck_types_match? api_map, expected, inferred
91
+ raise ArgumentError, 'Expected type must be duck type' unless expected.duck_type?
92
+ expected.each do |exp|
93
+ next unless exp.duck_type?
94
+ quack = exp.to_s[1..-1]
95
+ return false if api_map.get_method_stack(inferred.namespace, quack, scope: inferred.scope).empty?
96
+ end
97
+ true
98
+ end
99
+
100
+ # @param type [ComplexType::UniqueType]
101
+ # @return [String]
102
+ def fuzz type
103
+ if type.parameters?
104
+ type.name
105
+ else
106
+ type.tag
107
+ end
108
+ end
109
+
110
+ # @param api_map [ApiMap]
111
+ # @param cls1 [ComplexType::UniqueType]
112
+ # @param cls2 [ComplexType::UniqueType]
113
+ # @return [Boolean]
114
+ def either_way?(api_map, cls1, cls2)
115
+ # @todo there should be a level of typechecking which uses the
116
+ # full tag with parameters to determine compatibility
117
+ f1 = cls1.name
118
+ f2 = cls2.name
119
+ api_map.type_include?(f1, f2) || api_map.super_and_sub?(f1, f2) || api_map.super_and_sub?(f2, f1)
120
+ # api_map.type_include?(f1, f2) || api_map.super_and_sub?(f1, f2) || api_map.super_and_sub?(f2, f1)
121
+ end
122
+ end
123
+ end
124
+ end