solargraph 0.58.0 → 0.59.0

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 (219) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +3 -0
  3. data/.gitattributes +2 -0
  4. data/.github/workflows/linting.yml +6 -5
  5. data/.github/workflows/plugins.yml +48 -35
  6. data/.github/workflows/rspec.yml +15 -28
  7. data/.github/workflows/typecheck.yml +3 -2
  8. data/.gitignore +1 -0
  9. data/.rubocop.yml +38 -6
  10. data/.rubocop_todo.yml +53 -966
  11. data/CHANGELOG.md +24 -0
  12. data/Gemfile +3 -1
  13. data/README.md +3 -3
  14. data/Rakefile +26 -23
  15. data/bin/solargraph +9 -8
  16. data/lib/solargraph/api_map/cache.rb +110 -110
  17. data/lib/solargraph/api_map/constants.rb +288 -279
  18. data/lib/solargraph/api_map/index.rb +204 -193
  19. data/lib/solargraph/api_map/source_to_yard.rb +110 -97
  20. data/lib/solargraph/api_map/store.rb +395 -384
  21. data/lib/solargraph/api_map.rb +1029 -945
  22. data/lib/solargraph/bench.rb +44 -45
  23. data/lib/solargraph/complex_type/conformance.rb +176 -0
  24. data/lib/solargraph/complex_type/type_methods.rb +240 -228
  25. data/lib/solargraph/complex_type/unique_type.rb +641 -482
  26. data/lib/solargraph/complex_type.rb +557 -444
  27. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -61
  28. data/lib/solargraph/convention/data_definition/data_definition_node.rb +93 -91
  29. data/lib/solargraph/convention/data_definition.rb +108 -105
  30. data/lib/solargraph/convention/gemfile.rb +15 -15
  31. data/lib/solargraph/convention/gemspec.rb +23 -23
  32. data/lib/solargraph/convention/rakefile.rb +17 -17
  33. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +62 -61
  34. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +103 -102
  35. data/lib/solargraph/convention/struct_definition.rb +168 -164
  36. data/lib/solargraph/convention.rb +78 -78
  37. data/lib/solargraph/converters/dd.rb +19 -17
  38. data/lib/solargraph/converters/dl.rb +17 -15
  39. data/lib/solargraph/converters/dt.rb +17 -15
  40. data/lib/solargraph/converters/misc.rb +3 -1
  41. data/lib/solargraph/diagnostics/require_not_found.rb +54 -53
  42. data/lib/solargraph/diagnostics/rubocop.rb +119 -118
  43. data/lib/solargraph/diagnostics/rubocop_helpers.rb +70 -68
  44. data/lib/solargraph/diagnostics/type_check.rb +56 -55
  45. data/lib/solargraph/diagnostics/update_errors.rb +37 -41
  46. data/lib/solargraph/doc_map.rb +438 -439
  47. data/lib/solargraph/equality.rb +34 -34
  48. data/lib/solargraph/gem_pins.rb +98 -98
  49. data/lib/solargraph/language_server/error_codes.rb +20 -20
  50. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  51. data/lib/solargraph/language_server/host/dispatch.rb +130 -130
  52. data/lib/solargraph/language_server/host/message_worker.rb +113 -112
  53. data/lib/solargraph/language_server/host/sources.rb +100 -99
  54. data/lib/solargraph/language_server/host.rb +886 -878
  55. data/lib/solargraph/language_server/message/base.rb +97 -97
  56. data/lib/solargraph/language_server/message/client/register_capability.rb +13 -15
  57. data/lib/solargraph/language_server/message/completion_item/resolve.rb +58 -60
  58. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +108 -114
  59. data/lib/solargraph/language_server/message/extended/document.rb +24 -23
  60. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
  61. data/lib/solargraph/language_server/message/extended/download_core.rb +20 -19
  62. data/lib/solargraph/language_server/message/extended/search.rb +20 -20
  63. data/lib/solargraph/language_server/message/initialize.rb +197 -191
  64. data/lib/solargraph/language_server/message/text_document/completion.rb +58 -56
  65. data/lib/solargraph/language_server/message/text_document/definition.rb +49 -40
  66. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +23 -16
  67. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +36 -26
  68. data/lib/solargraph/language_server/message/text_document/formatting.rb +150 -148
  69. data/lib/solargraph/language_server/message/text_document/hover.rb +58 -58
  70. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +18 -11
  71. data/lib/solargraph/language_server/message/text_document/references.rb +23 -16
  72. data/lib/solargraph/language_server/message/text_document/rename.rb +26 -19
  73. data/lib/solargraph/language_server/message/text_document/signature_help.rb +25 -24
  74. data/lib/solargraph/language_server/message/text_document/type_definition.rb +33 -25
  75. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +41 -35
  76. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +48 -40
  77. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +32 -26
  78. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +33 -23
  79. data/lib/solargraph/language_server/message.rb +94 -94
  80. data/lib/solargraph/language_server/request.rb +29 -27
  81. data/lib/solargraph/language_server/transport/data_reader.rb +72 -74
  82. data/lib/solargraph/language_server/uri_helpers.rb +49 -49
  83. data/lib/solargraph/library.rb +702 -683
  84. data/lib/solargraph/location.rb +85 -82
  85. data/lib/solargraph/logging.rb +55 -37
  86. data/lib/solargraph/page.rb +92 -92
  87. data/lib/solargraph/parser/comment_ripper.rb +84 -69
  88. data/lib/solargraph/parser/flow_sensitive_typing.rb +471 -255
  89. data/lib/solargraph/parser/node_processor/base.rb +122 -92
  90. data/lib/solargraph/parser/node_processor.rb +63 -62
  91. data/lib/solargraph/parser/parser_gem/class_methods.rb +165 -149
  92. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +19 -19
  93. data/lib/solargraph/parser/parser_gem/node_chainer.rb +191 -166
  94. data/lib/solargraph/parser/parser_gem/node_methods.rb +507 -486
  95. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -22
  96. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +61 -59
  97. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +24 -15
  98. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +45 -46
  99. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +60 -53
  100. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +38 -37
  101. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +53 -23
  102. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +42 -40
  103. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +30 -29
  104. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +61 -59
  105. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -98
  106. data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
  107. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -17
  108. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +39 -38
  109. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +51 -52
  110. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +302 -291
  111. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -29
  112. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
  113. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +33 -29
  114. data/lib/solargraph/parser/parser_gem/node_processors.rb +74 -70
  115. data/lib/solargraph/parser/parser_gem.rb +14 -12
  116. data/lib/solargraph/parser/region.rb +75 -69
  117. data/lib/solargraph/parser/snippet.rb +19 -17
  118. data/lib/solargraph/parser.rb +25 -23
  119. data/lib/solargraph/pin/base.rb +773 -729
  120. data/lib/solargraph/pin/base_variable.rb +375 -126
  121. data/lib/solargraph/pin/block.rb +127 -104
  122. data/lib/solargraph/pin/breakable.rb +15 -9
  123. data/lib/solargraph/pin/callable.rb +275 -231
  124. data/lib/solargraph/pin/closure.rb +69 -72
  125. data/lib/solargraph/pin/common.rb +97 -79
  126. data/lib/solargraph/pin/compound_statement.rb +55 -0
  127. data/lib/solargraph/pin/constant.rb +43 -45
  128. data/lib/solargraph/pin/conversions.rb +129 -123
  129. data/lib/solargraph/pin/delegated_method.rb +131 -120
  130. data/lib/solargraph/pin/documenting.rb +116 -114
  131. data/lib/solargraph/pin/instance_variable.rb +38 -34
  132. data/lib/solargraph/pin/keyword.rb +16 -20
  133. data/lib/solargraph/pin/local_variable.rb +31 -75
  134. data/lib/solargraph/pin/method.rb +724 -672
  135. data/lib/solargraph/pin/method_alias.rb +42 -34
  136. data/lib/solargraph/pin/namespace.rb +122 -115
  137. data/lib/solargraph/pin/parameter.rb +339 -275
  138. data/lib/solargraph/pin/proxy_type.rb +42 -39
  139. data/lib/solargraph/pin/reference/override.rb +47 -47
  140. data/lib/solargraph/pin/reference/superclass.rb +17 -15
  141. data/lib/solargraph/pin/reference/type_alias.rb +16 -0
  142. data/lib/solargraph/pin/reference.rb +59 -39
  143. data/lib/solargraph/pin/search.rb +62 -61
  144. data/lib/solargraph/pin/signature.rb +64 -61
  145. data/lib/solargraph/pin/symbol.rb +54 -53
  146. data/lib/solargraph/pin/until.rb +16 -18
  147. data/lib/solargraph/pin/while.rb +16 -18
  148. data/lib/solargraph/pin.rb +46 -44
  149. data/lib/solargraph/pin_cache.rb +248 -245
  150. data/lib/solargraph/position.rb +139 -119
  151. data/lib/solargraph/range.rb +113 -112
  152. data/lib/solargraph/rbs_map/conversions.rb +952 -823
  153. data/lib/solargraph/rbs_map/core_fills.rb +91 -84
  154. data/lib/solargraph/rbs_map/core_map.rb +65 -58
  155. data/lib/solargraph/rbs_map/stdlib_map.rb +71 -43
  156. data/lib/solargraph/rbs_map.rb +207 -163
  157. data/lib/solargraph/server_methods.rb +16 -16
  158. data/lib/solargraph/shell.rb +555 -352
  159. data/lib/solargraph/source/chain/array.rb +39 -37
  160. data/lib/solargraph/source/chain/call.rb +377 -337
  161. data/lib/solargraph/source/chain/class_variable.rb +13 -13
  162. data/lib/solargraph/source/chain/constant.rb +30 -26
  163. data/lib/solargraph/source/chain/global_variable.rb +13 -13
  164. data/lib/solargraph/source/chain/hash.rb +37 -34
  165. data/lib/solargraph/source/chain/if.rb +30 -28
  166. data/lib/solargraph/source/chain/instance_variable.rb +36 -13
  167. data/lib/solargraph/source/chain/link.rb +99 -109
  168. data/lib/solargraph/source/chain/literal.rb +51 -48
  169. data/lib/solargraph/source/chain/or.rb +29 -23
  170. data/lib/solargraph/source/chain/q_call.rb +13 -11
  171. data/lib/solargraph/source/chain/variable.rb +15 -13
  172. data/lib/solargraph/source/chain/z_super.rb +28 -30
  173. data/lib/solargraph/source/chain.rb +304 -291
  174. data/lib/solargraph/source/change.rb +89 -82
  175. data/lib/solargraph/source/cursor.rb +172 -166
  176. data/lib/solargraph/source/encoding_fixes.rb +22 -23
  177. data/lib/solargraph/source/source_chainer.rb +218 -194
  178. data/lib/solargraph/source/updater.rb +59 -55
  179. data/lib/solargraph/source.rb +522 -498
  180. data/lib/solargraph/source_map/clip.rb +245 -226
  181. data/lib/solargraph/source_map/data.rb +37 -34
  182. data/lib/solargraph/source_map/mapper.rb +286 -259
  183. data/lib/solargraph/source_map.rb +224 -212
  184. data/lib/solargraph/type_checker/problem.rb +34 -32
  185. data/lib/solargraph/type_checker/rules.rb +157 -84
  186. data/lib/solargraph/type_checker.rb +888 -814
  187. data/lib/solargraph/version.rb +5 -5
  188. data/lib/solargraph/workspace/config.rb +258 -255
  189. data/lib/solargraph/workspace/gemspecs.rb +367 -0
  190. data/lib/solargraph/workspace/require_paths.rb +98 -97
  191. data/lib/solargraph/workspace.rb +242 -220
  192. data/lib/solargraph/yard_map/helpers.rb +49 -44
  193. data/lib/solargraph/yard_map/mapper/to_method.rb +136 -130
  194. data/lib/solargraph/yard_map/mapper/to_namespace.rb +32 -31
  195. data/lib/solargraph/yard_map/mapper.rb +84 -79
  196. data/lib/solargraph/yard_map.rb +17 -18
  197. data/lib/solargraph/yard_tags.rb +20 -20
  198. data/lib/solargraph/yardoc.rb +90 -87
  199. data/lib/solargraph.rb +128 -105
  200. data/rbs/fills/rubygems/0/dependency.rbs +193 -0
  201. data/rbs/fills/tuple/tuple.rbs +28 -0
  202. data/rbs/shims/ast/0/node.rbs +5 -0
  203. data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
  204. data/rbs_collection.yaml +1 -1
  205. data/solargraph.gemspec +37 -35
  206. metadata +52 -51
  207. data/lib/solargraph/type_checker/checks.rb +0 -124
  208. data/lib/solargraph/type_checker/param_def.rb +0 -37
  209. data/lib/solargraph/yard_map/to_method.rb +0 -89
  210. data/sig/shims/ast/0/node.rbs +0 -5
  211. /data/{sig → rbs}/shims/ast/2.4/.rbs_meta.yaml +0 -0
  212. /data/{sig → rbs}/shims/ast/2.4/ast.rbs +0 -0
  213. /data/{sig → rbs}/shims/parser/3.2.0.1/builders/default.rbs +0 -0
  214. /data/{sig → rbs}/shims/parser/3.2.0.1/manifest.yaml +0 -0
  215. /data/{sig → rbs}/shims/parser/3.2.0.1/parser.rbs +0 -0
  216. /data/{sig → rbs}/shims/parser/3.2.0.1/polyfill.rbs +0 -0
  217. /data/{sig → rbs}/shims/thor/1.2.0.1/.rbs_meta.yaml +0 -0
  218. /data/{sig → rbs}/shims/thor/1.2.0.1/manifest.yaml +0 -0
  219. /data/{sig → rbs}/shims/thor/1.2.0.1/thor.rbs +0 -0
@@ -1,82 +1,89 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- class Source
5
- # A change to be applied to text.
6
- #
7
- class Change
8
- include EncodingFixes
9
-
10
- # @return [Range]
11
- attr_reader :range
12
-
13
- # @return [String]
14
- attr_reader :new_text
15
-
16
- # @param range [Range] The starting and ending positions of the change.
17
- # If nil, the original text will be overwritten.
18
- # @param new_text [String] The text to be changed.
19
- def initialize range, new_text
20
- @range = range
21
- @new_text = new_text
22
- end
23
-
24
- # Write the change to the specified text.
25
- #
26
- # @param text [String] The text to be changed.
27
- # @param nullable [Boolean] If true, minor changes that could generate
28
- # syntax errors will be repaired.
29
- # @return [String] The updated text.
30
- def write text, nullable = false
31
- if nullable and !range.nil? and new_text.match(/[.\[{(@$:]$/)
32
- [':', '@'].each do |dupable|
33
- next unless new_text == dupable
34
- offset = Position.to_offset(text, range.start)
35
- if text[offset - 1] == dupable
36
- p = Position.from_offset(text, offset - 1)
37
- r = Change.new(Range.new(p, range.start), ' ')
38
- text = r.write(text)
39
- end
40
- break
41
- end
42
- commit text, "#{new_text[0..-2]} "
43
- elsif range.nil?
44
- new_text
45
- else
46
- commit text, new_text
47
- end
48
- end
49
-
50
- # Repair an update by replacing the new text with similarly formatted
51
- # whitespace.
52
- #
53
- # @param text [String] The text to be changed.
54
- # @return [String] The updated text.
55
- def repair text
56
- fixed = new_text.gsub(/[^\s]/, ' ')
57
- if range.nil?
58
- fixed
59
- else
60
- result = commit text, fixed
61
- off = Position.to_offset(text, range.start)
62
- match = result[0, off].match(/[.:]+\z/)
63
- if match
64
- result = result[0, off].sub(/#{match[0]}\z/, ' ' * match[0].length) + result[off..-1]
65
- end
66
- result
67
- end
68
- end
69
-
70
- private
71
-
72
- # @param text [String]
73
- # @param insert [String]
74
- # @return [String]
75
- def commit text, insert
76
- start_offset = Position.to_offset(text, range.start)
77
- 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
79
- end
80
- end
81
- end
82
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ # A change to be applied to text.
6
+ #
7
+ class Change
8
+ include EncodingFixes
9
+
10
+ # @return [Range, nil]
11
+ attr_reader :range
12
+
13
+ # @return [String]
14
+ attr_reader :new_text
15
+
16
+ # @param range [Range, nil] The starting and ending positions of the change.
17
+ # If nil, the original text will be overwritten.
18
+ # @param new_text [String] The text to be changed.
19
+ def initialize range, new_text
20
+ @range = range
21
+ @new_text = new_text
22
+ end
23
+
24
+ # Write the change to the specified text.
25
+ #
26
+ # @param text [String] The text to be changed.
27
+ # @param nullable [Boolean] If true, minor changes that could generate
28
+ # syntax errors will be repaired.
29
+ # @return [String] The updated text.
30
+ def write text, nullable = false
31
+ if nullable && !range.nil? && new_text.match(/[.\[{(@$:]$/)
32
+ [':', '@'].each do |dupable|
33
+ next unless new_text == dupable
34
+ # @sg-ignore flow sensitive typing needs to handle attrs
35
+ offset = Position.to_offset(text, range.start)
36
+ if text[offset - 1] == dupable
37
+ p = Position.from_offset(text, offset - 1)
38
+ # @sg-ignore flow sensitive typing needs to handle attrs
39
+ r = Change.new(Range.new(p, range.start), ' ')
40
+ text = r.write(text)
41
+ end
42
+ break
43
+ end
44
+ commit text, "#{new_text[0..-2]} "
45
+ elsif range.nil?
46
+ new_text
47
+ else
48
+ commit text, new_text
49
+ end
50
+ end
51
+
52
+ # Repair an update by replacing the new text with similarly formatted
53
+ # whitespace.
54
+ #
55
+ # @param text [String] The text to be changed.
56
+ # @return [String] The updated text.
57
+ def repair text
58
+ fixed = new_text.gsub(/[^\s]/, ' ')
59
+ if range.nil?
60
+ fixed
61
+ else
62
+ result = commit text, fixed
63
+ # @sg-ignore flow sensitive typing needs to handle attrs
64
+ off = Position.to_offset(text, range.start)
65
+ # @sg-ignore Need to add nil check here
66
+ match = result[0, off].match(/[.:]+\z/)
67
+ if match
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..]
70
+ end
71
+ result
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ # @param text [String]
78
+ # @param insert [String]
79
+ # @return [String]
80
+ def commit text, insert
81
+ # @sg-ignore Need to add nil check here
82
+ start_offset = Position.to_offset(text, range.start)
83
+ # @sg-ignore Need to add nil check here
84
+ end_offset = Position.to_offset(text, range.ending)
85
+ (start_offset.zero? ? '' : text[0..(start_offset - 1)].to_s) + normalize(insert) + text[end_offset..].to_s
86
+ end
87
+ end
88
+ end
89
+ end
@@ -1,166 +1,172 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- class Source
5
- # Information about a single Position in a Source, including the
6
- # word located there.
7
- #
8
- class Cursor
9
- # @return [Position]
10
- attr_reader :position
11
-
12
- # @return [Source]
13
- attr_reader :source
14
-
15
- # @param source [Source]
16
- # @param position [Position, Array(Integer, Integer)]
17
- def initialize source, position
18
- @source = source
19
- @position = Position.normalize(position)
20
- end
21
-
22
- # @return [String]
23
- def filename
24
- source.filename
25
- end
26
-
27
- # The whole word at the current position. Given the text `foo.bar`, the
28
- # word at position(0,6) is `bar`.
29
- #
30
- # @return [String]
31
- def word
32
- @word ||= start_of_word + end_of_word
33
- end
34
-
35
- # The part of the word before the current position. Given the text
36
- # `foo.bar`, the start_of_word at position(0, 6) is `ba`.
37
- #
38
- # @return [String]
39
- def start_of_word
40
- @start_of_word ||= begin
41
- match = source.code[0..offset-1].to_s.match(start_word_pattern)
42
- result = (match ? match[0] : '')
43
- # Including the preceding colon if the word appears to be a symbol
44
- result = ":#{result}" if source.code[0..offset-result.length-1].end_with?(':') and !source.code[0..offset-result.length-1].end_with?('::')
45
- result
46
- end
47
- end
48
-
49
- # The part of the word after the current position. Given the text
50
- # `foo.bar`, the end_of_word at position (0,6) is `r`.
51
- #
52
- # @return [String]
53
- def end_of_word
54
- @end_of_word ||= begin
55
- match = source.code[offset..-1].to_s.match(end_word_pattern)
56
- match ? match[0] : ''
57
- end
58
- end
59
-
60
- # @return [Boolean]
61
- def start_of_constant?
62
- source.code[offset-2, 2] == '::'
63
- end
64
-
65
- # The range of the word at the current position.
66
- #
67
- # @return [Range]
68
- def range
69
- @range ||= begin
70
- s = Position.from_offset(source.code, offset - start_of_word.length)
71
- e = Position.from_offset(source.code, offset + end_of_word.length)
72
- Solargraph::Range.new(s, e)
73
- end
74
- end
75
-
76
- # @return [Chain]
77
- def chain
78
- @chain ||= SourceChainer.chain(source, position)
79
- end
80
-
81
- # True if the statement at the cursor is an argument to a previous
82
- # method.
83
- #
84
- # Given the code `process(foo)`, a cursor pointing at `foo` would
85
- # identify it as an argument being passed to the `process` method.
86
- #
87
- # If #argument? is true, the #recipient method will return a cursor that
88
- # points to the method receiving the argument.
89
- #
90
- # @return [Boolean]
91
- def argument?
92
- # @argument ||= !signature_position.nil?
93
- @argument ||= !recipient.nil?
94
- end
95
-
96
- # @return [Boolean]
97
- def comment?
98
- @comment ||= source.comment_at?(position)
99
- end
100
-
101
- # @return [Boolean]
102
- def string?
103
- @string ||= source.string_at?(position)
104
- end
105
-
106
- # Get a cursor pointing to the method that receives the current statement
107
- # as an argument.
108
- #
109
- # @return [Cursor, nil]
110
- def recipient
111
- @recipient ||= begin
112
- node = recipient_node
113
- node ? Cursor.new(source, Range.from_node(node).ending) : nil
114
- end
115
- end
116
- alias receiver recipient
117
-
118
- # @return [AST::Node]
119
- def node
120
- @node ||= source.node_at(position.line, position.column)
121
- end
122
-
123
- # @return [Position]
124
- def node_position
125
- @node_position ||= begin
126
- if start_of_word.empty?
127
- match = source.code[0, offset].match(/\s*(\.|:+)\s*$/)
128
- if match
129
- Position.from_offset(source.code, offset - match[0].length)
130
- else
131
- position
132
- end
133
- else
134
- position
135
- end
136
- end
137
- end
138
-
139
- # @return [Parser::AST::Node, nil]
140
- def recipient_node
141
- @recipient_node ||= Solargraph::Parser::NodeMethods.find_recipient_node(self)
142
- end
143
-
144
- # @return [Integer]
145
- def offset
146
- @offset ||= Position.to_offset(source.code, position)
147
- end
148
-
149
- private
150
-
151
- # A regular expression to find the start of a word from an offset.
152
- #
153
- # @return [Regexp]
154
- def start_word_pattern
155
- /(@{1,2}|\$)?([a-z0-9_]|[^\u0000-\u007F])*\z/i
156
- end
157
-
158
- # A regular expression to find the end of a word from an offset.
159
- #
160
- # @return [Regexp]
161
- def end_word_pattern
162
- /^([a-z0-9_]|[^\u0000-\u007F])*[?!]?/i
163
- end
164
- end
165
- end
166
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ # Information about a single Position in a Source, including the
6
+ # word located there.
7
+ #
8
+ class Cursor
9
+ # @return [Position]
10
+ attr_reader :position
11
+
12
+ # @return [Source]
13
+ attr_reader :source
14
+
15
+ # @param source [Source]
16
+ # @param position [Position, Array(Integer, Integer)]
17
+ def initialize source, position
18
+ @source = source
19
+ @position = Position.normalize(position)
20
+ end
21
+
22
+ # @return [String, nil]
23
+ def filename
24
+ source.filename
25
+ end
26
+
27
+ # The whole word at the current position. Given the text `foo.bar`, the
28
+ # word at position(0,6) is `bar`.
29
+ #
30
+ # @return [String]
31
+ def word
32
+ @word ||= start_of_word + end_of_word
33
+ end
34
+
35
+ # The part of the word before the current position. Given the text
36
+ # `foo.bar`, the start_of_word at position(0, 6) is `ba`.
37
+ #
38
+ # @sg-ignore Need to add nil check here
39
+ # @return [String]
40
+ def start_of_word
41
+ @start_of_word ||= begin
42
+ match = source.code[0..(offset - 1)].to_s.match(start_word_pattern)
43
+ result = (match ? match[0] : '')
44
+ # Including the preceding colon if the word appears to be a symbol
45
+ # @sg-ignore Need to add nil check here
46
+ if source.code[0..(offset - result.length - 1)].end_with?(':') && !source.code[0..(offset - result.length - 1)].end_with?('::')
47
+ result = ":#{result}"
48
+ end
49
+ result
50
+ end
51
+ end
52
+
53
+ # The part of the word after the current position. Given the text
54
+ # `foo.bar`, the end_of_word at position (0,6) is `r`.
55
+ #
56
+ # @return [String]
57
+ # @sg-ignore Need to add nil check here
58
+ def end_of_word
59
+ @end_of_word ||= begin
60
+ match = source.code[offset..].to_s.match(end_word_pattern)
61
+ match ? match[0] : ''
62
+ end
63
+ end
64
+
65
+ # @return [Boolean]
66
+ def start_of_constant?
67
+ source.code[offset - 2, 2] == '::'
68
+ end
69
+
70
+ # The range of the word at the current position.
71
+ #
72
+ # @return [Range]
73
+ def range
74
+ @range ||= begin
75
+ s = Position.from_offset(source.code, offset - start_of_word.length)
76
+ e = Position.from_offset(source.code, offset + end_of_word.length)
77
+ Solargraph::Range.new(s, e)
78
+ end
79
+ end
80
+
81
+ # @return [Chain]
82
+ def chain
83
+ @chain ||= SourceChainer.chain(source, position)
84
+ end
85
+
86
+ # True if the statement at the cursor is an argument to a previous
87
+ # method.
88
+ #
89
+ # Given the code `process(foo)`, a cursor pointing at `foo` would
90
+ # identify it as an argument being passed to the `process` method.
91
+ #
92
+ # If #argument? is true, the #recipient method will return a cursor that
93
+ # points to the method receiving the argument.
94
+ #
95
+ # @return [Boolean]
96
+ def argument?
97
+ # @argument ||= !signature_position.nil?
98
+ @argument ||= !recipient.nil?
99
+ end
100
+
101
+ # @return [Boolean]
102
+ def comment?
103
+ @comment ||= source.comment_at?(position)
104
+ end
105
+
106
+ # @return [Boolean]
107
+ def string?
108
+ @string ||= source.string_at?(position)
109
+ end
110
+
111
+ # Get a cursor pointing to the method that receives the current statement
112
+ # as an argument.
113
+ #
114
+ # @return [Cursor, nil]
115
+ def recipient
116
+ @recipient ||= begin
117
+ node = recipient_node
118
+ # @sg-ignore Need to add nil check here
119
+ node ? Cursor.new(source, Range.from_node(node).ending) : nil
120
+ end
121
+ end
122
+ alias receiver recipient
123
+
124
+ # @return [AST::Node]
125
+ def node
126
+ @node ||= source.node_at(position.line, position.column)
127
+ end
128
+
129
+ # @return [Position]
130
+ def node_position
131
+ @node_position ||= if start_of_word.empty?
132
+ # @sg-ignore Need to add nil check here
133
+ match = source.code[0, offset].match(/\s*(\.|:+)\s*$/)
134
+ if match
135
+ # @sg-ignore Need to add nil check here
136
+ Position.from_offset(source.code, offset - match[0].length)
137
+ else
138
+ position
139
+ end
140
+ else
141
+ position
142
+ end
143
+ end
144
+
145
+ # @return [Parser::AST::Node, nil]
146
+ def recipient_node
147
+ @recipient_node ||= Solargraph::Parser::NodeMethods.find_recipient_node(self)
148
+ end
149
+
150
+ # @return [Integer]
151
+ def offset
152
+ @offset ||= Position.to_offset(source.code, position)
153
+ end
154
+
155
+ private
156
+
157
+ # A regular expression to find the start of a word from an offset.
158
+ #
159
+ # @return [Regexp]
160
+ def start_word_pattern
161
+ /(@{1,2}|\$)?([a-z0-9_]|[^\u0000-\u007F])*\z/i
162
+ end
163
+
164
+ # A regular expression to find the end of a word from an offset.
165
+ #
166
+ # @return [Regexp]
167
+ def end_word_pattern
168
+ /^([a-z0-9_]|[^\u0000-\u007F])*[?!]?/i
169
+ end
170
+ end
171
+ end
172
+ end
@@ -1,23 +1,22 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- class Source
5
- module EncodingFixes
6
- module_function
7
-
8
- # Convert strings to normalized UTF-8.
9
- #
10
- # @param string [String]
11
- # @return [String]
12
- def normalize string
13
- begin
14
- string.dup.force_encoding('UTF-8')
15
- rescue ::Encoding::CompatibilityError, ::Encoding::UndefinedConversionError, ::Encoding::InvalidByteSequenceError => e
16
- # @todo Improve error handling
17
- Solargraph::Logging.logger.warn "Normalize error: #{e.message}"
18
- string
19
- end
20
- end
21
- end
22
- end
23
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ module EncodingFixes
6
+ module_function
7
+
8
+ # Convert strings to normalized UTF-8.
9
+ #
10
+ # @param string [String]
11
+ # @return [String]
12
+ def normalize string
13
+ string.dup.force_encoding('UTF-8')
14
+ rescue ::Encoding::CompatibilityError, ::Encoding::UndefinedConversionError,
15
+ ::Encoding::InvalidByteSequenceError => e
16
+ # @todo Improve error handling
17
+ Solargraph::Logging.logger.warn "Normalize error: #{e.message}"
18
+ string
19
+ end
20
+ end
21
+ end
22
+ end