solargraph 0.56.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 (191) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -0
  3. data/.github/workflows/linting.yml +127 -0
  4. data/.github/workflows/plugins.yml +183 -7
  5. data/.github/workflows/rspec.yml +55 -5
  6. data/.github/workflows/typecheck.yml +6 -3
  7. data/.gitignore +6 -0
  8. data/.overcommit.yml +72 -0
  9. data/.rspec +1 -0
  10. data/.rubocop.yml +66 -0
  11. data/.rubocop_todo.yml +1279 -0
  12. data/.yardopts +1 -0
  13. data/CHANGELOG.md +92 -1
  14. data/README.md +8 -4
  15. data/Rakefile +125 -13
  16. data/bin/solargraph +3 -0
  17. data/lib/solargraph/api_map/cache.rb +110 -109
  18. data/lib/solargraph/api_map/constants.rb +279 -0
  19. data/lib/solargraph/api_map/index.rb +193 -175
  20. data/lib/solargraph/api_map/source_to_yard.rb +97 -88
  21. data/lib/solargraph/api_map/store.rb +384 -266
  22. data/lib/solargraph/api_map.rb +945 -973
  23. data/lib/solargraph/bench.rb +1 -0
  24. data/lib/solargraph/complex_type/type_methods.rb +228 -222
  25. data/lib/solargraph/complex_type/unique_type.rb +482 -475
  26. data/lib/solargraph/complex_type.rb +444 -423
  27. data/lib/solargraph/convention/active_support_concern.rb +111 -0
  28. data/lib/solargraph/convention/base.rb +17 -0
  29. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -0
  30. data/lib/solargraph/convention/data_definition/data_definition_node.rb +91 -0
  31. data/lib/solargraph/convention/data_definition.rb +105 -0
  32. data/lib/solargraph/convention/gemspec.rb +3 -2
  33. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +61 -60
  34. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +102 -100
  35. data/lib/solargraph/convention/struct_definition.rb +164 -101
  36. data/lib/solargraph/convention.rb +32 -2
  37. data/lib/solargraph/diagnostics/require_not_found.rb +53 -53
  38. data/lib/solargraph/diagnostics/rubocop.rb +118 -113
  39. data/lib/solargraph/diagnostics/rubocop_helpers.rb +68 -66
  40. data/lib/solargraph/diagnostics/type_check.rb +55 -55
  41. data/lib/solargraph/doc_map.rb +439 -405
  42. data/lib/solargraph/environ.rb +9 -2
  43. data/lib/solargraph/equality.rb +34 -33
  44. data/lib/solargraph/gem_pins.rb +98 -88
  45. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  46. data/lib/solargraph/language_server/host/dispatch.rb +130 -128
  47. data/lib/solargraph/language_server/host/message_worker.rb +112 -109
  48. data/lib/solargraph/language_server/host/sources.rb +99 -99
  49. data/lib/solargraph/language_server/host.rb +878 -871
  50. data/lib/solargraph/language_server/message/base.rb +2 -1
  51. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +114 -114
  52. data/lib/solargraph/language_server/message/extended/document.rb +23 -23
  53. data/lib/solargraph/language_server/message/text_document/completion.rb +56 -56
  54. data/lib/solargraph/language_server/message/text_document/definition.rb +40 -38
  55. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +26 -26
  56. data/lib/solargraph/language_server/message/text_document/formatting.rb +148 -131
  57. data/lib/solargraph/language_server/message/text_document/hover.rb +58 -58
  58. data/lib/solargraph/language_server/message/text_document/signature_help.rb +24 -24
  59. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -24
  60. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +2 -0
  61. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -23
  62. data/lib/solargraph/language_server/progress.rb +8 -0
  63. data/lib/solargraph/language_server/request.rb +4 -1
  64. data/lib/solargraph/library.rb +683 -666
  65. data/lib/solargraph/location.rb +82 -79
  66. data/lib/solargraph/logging.rb +37 -28
  67. data/lib/solargraph/page.rb +3 -0
  68. data/lib/solargraph/parser/comment_ripper.rb +69 -62
  69. data/lib/solargraph/parser/flow_sensitive_typing.rb +255 -227
  70. data/lib/solargraph/parser/node_processor/base.rb +92 -87
  71. data/lib/solargraph/parser/node_processor.rb +62 -46
  72. data/lib/solargraph/parser/parser_gem/class_methods.rb +149 -159
  73. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -0
  74. data/lib/solargraph/parser/parser_gem/node_chainer.rb +166 -164
  75. data/lib/solargraph/parser/parser_gem/node_methods.rb +486 -497
  76. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -21
  77. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +59 -59
  78. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +15 -15
  79. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +46 -45
  80. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +1 -21
  81. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +53 -53
  82. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +23 -21
  83. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +40 -40
  84. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +29 -29
  85. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +59 -53
  86. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +0 -22
  87. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -41
  88. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -16
  89. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +38 -37
  90. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +52 -43
  91. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +291 -271
  92. data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +1 -0
  93. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +29 -29
  94. data/lib/solargraph/parser/parser_gem/node_processors.rb +70 -66
  95. data/lib/solargraph/parser/region.rb +69 -66
  96. data/lib/solargraph/parser/snippet.rb +17 -15
  97. data/lib/solargraph/pin/base.rb +729 -651
  98. data/lib/solargraph/pin/base_variable.rb +126 -125
  99. data/lib/solargraph/pin/block.rb +104 -103
  100. data/lib/solargraph/pin/breakable.rb +9 -9
  101. data/lib/solargraph/pin/callable.rb +231 -218
  102. data/lib/solargraph/pin/closure.rb +72 -74
  103. data/lib/solargraph/pin/common.rb +79 -75
  104. data/lib/solargraph/pin/constant.rb +2 -0
  105. data/lib/solargraph/pin/conversions.rb +123 -123
  106. data/lib/solargraph/pin/delegated_method.rb +120 -120
  107. data/lib/solargraph/pin/documenting.rb +114 -114
  108. data/lib/solargraph/pin/instance_variable.rb +34 -34
  109. data/lib/solargraph/pin/keyword.rb +20 -20
  110. data/lib/solargraph/pin/local_variable.rb +75 -76
  111. data/lib/solargraph/pin/method.rb +672 -651
  112. data/lib/solargraph/pin/method_alias.rb +34 -31
  113. data/lib/solargraph/pin/namespace.rb +115 -115
  114. data/lib/solargraph/pin/parameter.rb +275 -261
  115. data/lib/solargraph/pin/proxy_type.rb +39 -35
  116. data/lib/solargraph/pin/reference/override.rb +47 -33
  117. data/lib/solargraph/pin/reference/superclass.rb +15 -10
  118. data/lib/solargraph/pin/reference.rb +39 -22
  119. data/lib/solargraph/pin/search.rb +61 -56
  120. data/lib/solargraph/pin/signature.rb +61 -59
  121. data/lib/solargraph/pin/symbol.rb +53 -48
  122. data/lib/solargraph/pin/until.rb +18 -18
  123. data/lib/solargraph/pin/while.rb +18 -18
  124. data/lib/solargraph/pin.rb +44 -44
  125. data/lib/solargraph/pin_cache.rb +245 -185
  126. data/lib/solargraph/position.rb +132 -116
  127. data/lib/solargraph/range.rb +112 -107
  128. data/lib/solargraph/rbs_map/conversions.rb +823 -773
  129. data/lib/solargraph/rbs_map/core_fills.rb +18 -0
  130. data/lib/solargraph/rbs_map/core_map.rb +58 -51
  131. data/lib/solargraph/rbs_map/stdlib_map.rb +43 -43
  132. data/lib/solargraph/rbs_map.rb +163 -150
  133. data/lib/solargraph/shell.rb +352 -268
  134. data/lib/solargraph/source/chain/call.rb +337 -333
  135. data/lib/solargraph/source/chain/constant.rb +26 -89
  136. data/lib/solargraph/source/chain/hash.rb +34 -34
  137. data/lib/solargraph/source/chain/if.rb +28 -28
  138. data/lib/solargraph/source/chain/instance_variable.rb +13 -13
  139. data/lib/solargraph/source/chain/link.rb +11 -2
  140. data/lib/solargraph/source/chain/literal.rb +48 -48
  141. data/lib/solargraph/source/chain/or.rb +23 -23
  142. data/lib/solargraph/source/chain.rb +291 -282
  143. data/lib/solargraph/source/change.rb +82 -82
  144. data/lib/solargraph/source/cursor.rb +166 -167
  145. data/lib/solargraph/source/encoding_fixes.rb +23 -23
  146. data/lib/solargraph/source/source_chainer.rb +194 -194
  147. data/lib/solargraph/source/updater.rb +55 -55
  148. data/lib/solargraph/source.rb +498 -495
  149. data/lib/solargraph/source_map/clip.rb +226 -234
  150. data/lib/solargraph/source_map/data.rb +34 -30
  151. data/lib/solargraph/source_map/mapper.rb +259 -259
  152. data/lib/solargraph/source_map.rb +212 -200
  153. data/lib/solargraph/type_checker/checks.rb +124 -124
  154. data/lib/solargraph/type_checker/param_def.rb +37 -35
  155. data/lib/solargraph/type_checker/problem.rb +32 -32
  156. data/lib/solargraph/type_checker/rules.rb +84 -62
  157. data/lib/solargraph/type_checker.rb +814 -699
  158. data/lib/solargraph/version.rb +5 -5
  159. data/lib/solargraph/workspace/config.rb +255 -239
  160. data/lib/solargraph/workspace/require_paths.rb +97 -0
  161. data/lib/solargraph/workspace.rb +220 -249
  162. data/lib/solargraph/yard_map/helpers.rb +44 -16
  163. data/lib/solargraph/yard_map/mapper/to_constant.rb +5 -5
  164. data/lib/solargraph/yard_map/mapper/to_method.rb +130 -134
  165. data/lib/solargraph/yard_map/mapper/to_namespace.rb +31 -30
  166. data/lib/solargraph/yard_map/mapper.rb +79 -79
  167. data/lib/solargraph/yard_map/to_method.rb +89 -88
  168. data/lib/solargraph/yardoc.rb +87 -49
  169. data/lib/solargraph.rb +105 -90
  170. data/rbs/fills/bundler/0/bundler.rbs +4271 -0
  171. data/rbs/fills/open3/0/open3.rbs +172 -0
  172. data/rbs/fills/rubygems/0/basic_specification.rbs +326 -0
  173. data/rbs/fills/rubygems/0/errors.rbs +364 -0
  174. data/rbs/fills/rubygems/0/spec_fetcher.rbs +107 -0
  175. data/rbs/fills/rubygems/0/specification.rbs +1753 -0
  176. data/rbs/fills/{tuple.rbs → tuple/tuple.rbs} +2 -3
  177. data/rbs/shims/ast/0/node.rbs +5 -0
  178. data/rbs/shims/ast/2.4/.rbs_meta.yaml +9 -0
  179. data/rbs/shims/ast/2.4/ast.rbs +73 -0
  180. data/rbs/shims/parser/3.2.0.1/builders/default.rbs +195 -0
  181. data/rbs/shims/parser/3.2.0.1/manifest.yaml +7 -0
  182. data/rbs/shims/parser/3.2.0.1/parser.rbs +201 -0
  183. data/rbs/shims/parser/3.2.0.1/polyfill.rbs +4 -0
  184. data/rbs/shims/thor/1.2.0.1/.rbs_meta.yaml +9 -0
  185. data/rbs/shims/thor/1.2.0.1/manifest.yaml +7 -0
  186. data/rbs/shims/thor/1.2.0.1/thor.rbs +17 -0
  187. data/rbs_collection.yaml +4 -4
  188. data/solargraph.gemspec +26 -5
  189. metadata +187 -15
  190. data/lib/.rubocop.yml +0 -22
  191. data/lib/solargraph/parser/node_methods.rb +0 -97
@@ -1,200 +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::LocalVariable>]
25
- def locals
26
- data.locals
27
- end
28
-
29
- # @param source [Source]
30
- def initialize source
31
- @source = source
32
-
33
- environ.merge Convention.for_local(self) unless filename.nil?
34
- self.convention_pins = environ.pins
35
- @pin_select_cache = {}
36
- end
37
-
38
- # @param klass [Class]
39
- # @return [Array<Pin::Base>]
40
- def pins_by_class klass
41
- @pin_select_cache[klass] ||= pin_class_hash.select { |key, _| key <= klass }.values.flatten
42
- end
43
-
44
- # A hash representing the state of the source map's API.
45
- #
46
- # ApiMap#catalog uses this value to determine whether it needs to clear its
47
- # cache.
48
- #
49
- # @return [Integer]
50
- def api_hash
51
- @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
52
- end
53
-
54
- # @return [String]
55
- def filename
56
- source.filename
57
- end
58
-
59
- # @return [String]
60
- def code
61
- source.code
62
- end
63
-
64
- # @return [Array<Pin::Reference::Require>]
65
- def requires
66
- pins_by_class(Pin::Reference::Require)
67
- end
68
-
69
- # @return [Environ]
70
- def environ
71
- @environ ||= Environ.new
72
- end
73
-
74
- # all pins except Solargraph::Pin::Reference::Reference
75
- # @return [Array<Pin::Base>]
76
- def document_symbols
77
- @document_symbols ||= (pins + convention_pins).select do |pin|
78
- pin.path && !pin.path.empty?
79
- end
80
- end
81
-
82
- # @param query [String]
83
- # @return [Array<Pin::Base>]
84
- def query_symbols query
85
- Pin::Search.new(document_symbols, query).results
86
- end
87
-
88
- # @param position [Position]
89
- # @return [Source::Cursor]
90
- def cursor_at position
91
- Source::Cursor.new(source, position)
92
- end
93
-
94
- # @param path [String]
95
- # @return [Pin::Base]
96
- def first_pin path
97
- pins.select { |p| p.path == path }.first
98
- end
99
-
100
- # @param location [Solargraph::Location]
101
- # @return [Array<Solargraph::Pin::Base>]
102
- def locate_pins location
103
- # return nil unless location.start_with?("#{filename}:")
104
- (pins + locals).select { |pin| pin.location == location }
105
- end
106
-
107
- # @param line [Integer]
108
- # @param character [Integer]
109
- # @return [Pin::Method,Pin::Namespace]
110
- def locate_named_path_pin line, character
111
- _locate_pin line, character, Pin::Namespace, Pin::Method
112
- end
113
-
114
- # @param line [Integer]
115
- # @param character [Integer]
116
- # @return [Pin::Namespace,Pin::Method,Pin::Block]
117
- def locate_block_pin line, character
118
- _locate_pin line, character, Pin::Namespace, Pin::Method, Pin::Block
119
- end
120
-
121
- # @param name [String]
122
- # @return [Array<Location>]
123
- def references name
124
- source.references name
125
- end
126
-
127
- # @param location [Location]
128
- # @return [Array<Pin::LocalVariable>]
129
- def locals_at(location)
130
- return [] if location.filename != filename
131
- closure = locate_named_path_pin(location.range.start.line, location.range.start.character)
132
- locals.select { |pin| pin.visible_at?(closure, location) }
133
- end
134
-
135
- class << self
136
- # @param filename [String]
137
- # @return [SourceMap]
138
- def load filename
139
- source = Solargraph::Source.load(filename)
140
- SourceMap.map(source)
141
- end
142
-
143
- # @param code [String]
144
- # @param filename [String, nil]
145
- # @return [SourceMap]
146
- def load_string code, filename = nil
147
- source = Solargraph::Source.load_string(code, filename)
148
- SourceMap.map(source)
149
- end
150
-
151
- # @deprecated
152
- # @param source [Source]
153
- # @return [SourceMap]
154
- def map source
155
- new(source)
156
- end
157
- end
158
-
159
- private
160
-
161
- def pin_class_hash
162
- @pin_class_hash ||= pins.to_set.classify(&:class).transform_values(&:to_a)
163
- end
164
-
165
- def data
166
- @data ||= Data.new(source)
167
- end
168
-
169
- # @return [Array<Pin::Base>]
170
- def convention_pins
171
- @convention_pins || []
172
- end
173
-
174
- # @param pins [Array<Pin::Base>]
175
- # @return [Array<Pin::Base>]
176
- def convention_pins=(pins)
177
- # unmemoizing the document_symbols in case it was called from any of conventions
178
- @document_symbols = nil
179
- @convention_pins = pins
180
- end
181
-
182
- # @param line [Integer]
183
- # @param character [Integer]
184
- # @param klasses [Array<Class>]
185
- # @return [Pin::Base, nil]
186
- def _locate_pin line, character, *klasses
187
- position = Position.new(line, character)
188
- found = nil
189
- pins.each do |pin|
190
- # @todo Attribute pins should not be treated like closures, but
191
- # there's probably a better way to handle it
192
- next if pin.is_a?(Pin::Method) && pin.attribute?
193
- found = pin if (klasses.empty? || klasses.any? { |kls| pin.is_a?(kls) } ) && pin.location.range.contain?(position)
194
- break if pin.location.range.start.line > line
195
- end
196
- # Assuming the root pin is always valid
197
- found || pins.first
198
- end
199
- end
200
- 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