solargraph 0.58.0 → 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 (150) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -0
  3. data/.gitignore +1 -0
  4. data/CHANGELOG.md +9 -0
  5. data/bin/solargraph +8 -8
  6. data/lib/solargraph/api_map/cache.rb +110 -110
  7. data/lib/solargraph/api_map/constants.rb +279 -279
  8. data/lib/solargraph/api_map/index.rb +193 -193
  9. data/lib/solargraph/api_map/source_to_yard.rb +97 -97
  10. data/lib/solargraph/api_map/store.rb +384 -384
  11. data/lib/solargraph/api_map.rb +945 -945
  12. data/lib/solargraph/complex_type/type_methods.rb +228 -228
  13. data/lib/solargraph/complex_type/unique_type.rb +482 -482
  14. data/lib/solargraph/complex_type.rb +444 -444
  15. data/lib/solargraph/convention/data_definition/data_definition_node.rb +91 -91
  16. data/lib/solargraph/convention/data_definition.rb +105 -105
  17. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +61 -61
  18. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +102 -102
  19. data/lib/solargraph/convention/struct_definition.rb +164 -164
  20. data/lib/solargraph/diagnostics/require_not_found.rb +53 -53
  21. data/lib/solargraph/diagnostics/rubocop.rb +118 -118
  22. data/lib/solargraph/diagnostics/rubocop_helpers.rb +68 -68
  23. data/lib/solargraph/diagnostics/type_check.rb +55 -55
  24. data/lib/solargraph/doc_map.rb +439 -439
  25. data/lib/solargraph/equality.rb +34 -34
  26. data/lib/solargraph/gem_pins.rb +98 -98
  27. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  28. data/lib/solargraph/language_server/host/dispatch.rb +130 -130
  29. data/lib/solargraph/language_server/host/message_worker.rb +112 -112
  30. data/lib/solargraph/language_server/host/sources.rb +99 -99
  31. data/lib/solargraph/language_server/host.rb +878 -878
  32. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +114 -114
  33. data/lib/solargraph/language_server/message/extended/document.rb +23 -23
  34. data/lib/solargraph/language_server/message/text_document/completion.rb +56 -56
  35. data/lib/solargraph/language_server/message/text_document/definition.rb +40 -40
  36. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +26 -26
  37. data/lib/solargraph/language_server/message/text_document/formatting.rb +148 -148
  38. data/lib/solargraph/language_server/message/text_document/hover.rb +58 -58
  39. data/lib/solargraph/language_server/message/text_document/signature_help.rb +24 -24
  40. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -25
  41. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -23
  42. data/lib/solargraph/library.rb +683 -683
  43. data/lib/solargraph/location.rb +82 -82
  44. data/lib/solargraph/logging.rb +37 -37
  45. data/lib/solargraph/parser/comment_ripper.rb +69 -69
  46. data/lib/solargraph/parser/flow_sensitive_typing.rb +255 -255
  47. data/lib/solargraph/parser/node_processor/base.rb +92 -92
  48. data/lib/solargraph/parser/node_processor.rb +62 -62
  49. data/lib/solargraph/parser/parser_gem/class_methods.rb +149 -149
  50. data/lib/solargraph/parser/parser_gem/node_chainer.rb +166 -166
  51. data/lib/solargraph/parser/parser_gem/node_methods.rb +486 -486
  52. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -22
  53. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +59 -59
  54. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +15 -15
  55. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +46 -46
  56. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +53 -53
  57. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +23 -23
  58. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +40 -40
  59. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +29 -29
  60. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +59 -59
  61. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -98
  62. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -17
  63. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +38 -38
  64. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +52 -52
  65. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +291 -291
  66. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +29 -29
  67. data/lib/solargraph/parser/parser_gem/node_processors.rb +70 -70
  68. data/lib/solargraph/parser/region.rb +69 -69
  69. data/lib/solargraph/parser/snippet.rb +17 -17
  70. data/lib/solargraph/pin/base.rb +729 -729
  71. data/lib/solargraph/pin/base_variable.rb +126 -126
  72. data/lib/solargraph/pin/block.rb +104 -104
  73. data/lib/solargraph/pin/breakable.rb +9 -9
  74. data/lib/solargraph/pin/callable.rb +231 -231
  75. data/lib/solargraph/pin/closure.rb +72 -72
  76. data/lib/solargraph/pin/common.rb +79 -79
  77. data/lib/solargraph/pin/conversions.rb +123 -123
  78. data/lib/solargraph/pin/delegated_method.rb +120 -120
  79. data/lib/solargraph/pin/documenting.rb +114 -114
  80. data/lib/solargraph/pin/instance_variable.rb +34 -34
  81. data/lib/solargraph/pin/keyword.rb +20 -20
  82. data/lib/solargraph/pin/local_variable.rb +75 -75
  83. data/lib/solargraph/pin/method.rb +672 -672
  84. data/lib/solargraph/pin/method_alias.rb +34 -34
  85. data/lib/solargraph/pin/namespace.rb +115 -115
  86. data/lib/solargraph/pin/parameter.rb +275 -275
  87. data/lib/solargraph/pin/proxy_type.rb +39 -39
  88. data/lib/solargraph/pin/reference/override.rb +47 -47
  89. data/lib/solargraph/pin/reference/superclass.rb +15 -15
  90. data/lib/solargraph/pin/reference.rb +39 -39
  91. data/lib/solargraph/pin/search.rb +61 -61
  92. data/lib/solargraph/pin/signature.rb +61 -61
  93. data/lib/solargraph/pin/symbol.rb +53 -53
  94. data/lib/solargraph/pin/until.rb +18 -18
  95. data/lib/solargraph/pin/while.rb +18 -18
  96. data/lib/solargraph/pin.rb +44 -44
  97. data/lib/solargraph/pin_cache.rb +245 -245
  98. data/lib/solargraph/position.rb +132 -119
  99. data/lib/solargraph/range.rb +112 -112
  100. data/lib/solargraph/rbs_map/conversions.rb +823 -823
  101. data/lib/solargraph/rbs_map/core_map.rb +58 -58
  102. data/lib/solargraph/rbs_map/stdlib_map.rb +43 -43
  103. data/lib/solargraph/rbs_map.rb +163 -163
  104. data/lib/solargraph/shell.rb +352 -352
  105. data/lib/solargraph/source/chain/call.rb +337 -337
  106. data/lib/solargraph/source/chain/constant.rb +26 -26
  107. data/lib/solargraph/source/chain/hash.rb +34 -34
  108. data/lib/solargraph/source/chain/if.rb +28 -28
  109. data/lib/solargraph/source/chain/instance_variable.rb +13 -13
  110. data/lib/solargraph/source/chain/literal.rb +48 -48
  111. data/lib/solargraph/source/chain/or.rb +23 -23
  112. data/lib/solargraph/source/chain.rb +291 -291
  113. data/lib/solargraph/source/change.rb +82 -82
  114. data/lib/solargraph/source/cursor.rb +166 -166
  115. data/lib/solargraph/source/encoding_fixes.rb +23 -23
  116. data/lib/solargraph/source/source_chainer.rb +194 -194
  117. data/lib/solargraph/source/updater.rb +55 -55
  118. data/lib/solargraph/source.rb +498 -498
  119. data/lib/solargraph/source_map/clip.rb +226 -226
  120. data/lib/solargraph/source_map/data.rb +34 -34
  121. data/lib/solargraph/source_map/mapper.rb +259 -259
  122. data/lib/solargraph/source_map.rb +212 -212
  123. data/lib/solargraph/type_checker/checks.rb +124 -124
  124. data/lib/solargraph/type_checker/param_def.rb +37 -37
  125. data/lib/solargraph/type_checker/problem.rb +32 -32
  126. data/lib/solargraph/type_checker/rules.rb +84 -84
  127. data/lib/solargraph/type_checker.rb +814 -814
  128. data/lib/solargraph/version.rb +5 -5
  129. data/lib/solargraph/workspace/config.rb +255 -255
  130. data/lib/solargraph/workspace/require_paths.rb +97 -97
  131. data/lib/solargraph/workspace.rb +220 -220
  132. data/lib/solargraph/yard_map/helpers.rb +44 -44
  133. data/lib/solargraph/yard_map/mapper/to_method.rb +130 -130
  134. data/lib/solargraph/yard_map/mapper/to_namespace.rb +31 -31
  135. data/lib/solargraph/yard_map/mapper.rb +79 -79
  136. data/lib/solargraph/yard_map/to_method.rb +89 -89
  137. data/lib/solargraph/yardoc.rb +87 -87
  138. data/lib/solargraph.rb +105 -105
  139. data/rbs_collection.yaml +1 -1
  140. metadata +13 -12
  141. /data/{sig → rbs}/shims/ast/0/node.rbs +0 -0
  142. /data/{sig → rbs}/shims/ast/2.4/.rbs_meta.yaml +0 -0
  143. /data/{sig → rbs}/shims/ast/2.4/ast.rbs +0 -0
  144. /data/{sig → rbs}/shims/parser/3.2.0.1/builders/default.rbs +0 -0
  145. /data/{sig → rbs}/shims/parser/3.2.0.1/manifest.yaml +0 -0
  146. /data/{sig → rbs}/shims/parser/3.2.0.1/parser.rbs +0 -0
  147. /data/{sig → rbs}/shims/parser/3.2.0.1/polyfill.rbs +0 -0
  148. /data/{sig → rbs}/shims/thor/1.2.0.1/.rbs_meta.yaml +0 -0
  149. /data/{sig → rbs}/shims/thor/1.2.0.1/manifest.yaml +0 -0
  150. /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