solargraph 0.59.0.dev.1 → 0.59.0.dev.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/plugins.yml +4 -1
  3. data/.github/workflows/rspec.yml +3 -14
  4. data/.gitignore +1 -0
  5. data/.rubocop.yml +32 -5
  6. data/.rubocop_todo.yml +37 -931
  7. data/CHANGELOG.md +7 -1
  8. data/Gemfile +3 -1
  9. data/Rakefile +25 -23
  10. data/bin/solargraph +2 -1
  11. data/lib/solargraph/api_map/index.rb +5 -11
  12. data/lib/solargraph/api_map/source_to_yard.rb +9 -8
  13. data/lib/solargraph/api_map/store.rb +22 -20
  14. data/lib/solargraph/api_map.rb +50 -37
  15. data/lib/solargraph/bench.rb +44 -45
  16. data/lib/solargraph/complex_type/type_methods.rb +12 -15
  17. data/lib/solargraph/complex_type/unique_type.rb +54 -43
  18. data/lib/solargraph/complex_type.rb +69 -61
  19. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -61
  20. data/lib/solargraph/convention/data_definition/data_definition_node.rb +4 -4
  21. data/lib/solargraph/convention/data_definition.rb +1 -1
  22. data/lib/solargraph/convention/gemfile.rb +15 -15
  23. data/lib/solargraph/convention/gemspec.rb +23 -23
  24. data/lib/solargraph/convention/rakefile.rb +17 -17
  25. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +1 -1
  26. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +3 -3
  27. data/lib/solargraph/convention/struct_definition.rb +3 -3
  28. data/lib/solargraph/convention.rb +78 -78
  29. data/lib/solargraph/converters/dd.rb +19 -17
  30. data/lib/solargraph/converters/dl.rb +17 -15
  31. data/lib/solargraph/converters/dt.rb +17 -15
  32. data/lib/solargraph/converters/misc.rb +3 -1
  33. data/lib/solargraph/diagnostics/rubocop.rb +10 -10
  34. data/lib/solargraph/diagnostics/rubocop_helpers.rb +3 -3
  35. data/lib/solargraph/diagnostics/type_check.rb +10 -10
  36. data/lib/solargraph/diagnostics/update_errors.rb +37 -41
  37. data/lib/solargraph/doc_map.rb +9 -10
  38. data/lib/solargraph/equality.rb +3 -3
  39. data/lib/solargraph/gem_pins.rb +7 -5
  40. data/lib/solargraph/language_server/error_codes.rb +20 -20
  41. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  42. data/lib/solargraph/language_server/host/dispatch.rb +2 -3
  43. data/lib/solargraph/language_server/host/message_worker.rb +2 -2
  44. data/lib/solargraph/language_server/host/sources.rb +1 -1
  45. data/lib/solargraph/language_server/host.rb +24 -21
  46. data/lib/solargraph/language_server/message/base.rb +97 -97
  47. data/lib/solargraph/language_server/message/client/register_capability.rb +13 -15
  48. data/lib/solargraph/language_server/message/completion_item/resolve.rb +58 -60
  49. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +10 -11
  50. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
  51. data/lib/solargraph/language_server/message/extended/download_core.rb +20 -19
  52. data/lib/solargraph/language_server/message/extended/search.rb +20 -20
  53. data/lib/solargraph/language_server/message/initialize.rb +197 -191
  54. data/lib/solargraph/language_server/message/text_document/completion.rb +8 -8
  55. data/lib/solargraph/language_server/message/text_document/definition.rb +41 -34
  56. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +23 -16
  57. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +29 -21
  58. data/lib/solargraph/language_server/message/text_document/formatting.rb +6 -6
  59. data/lib/solargraph/language_server/message/text_document/hover.rb +3 -5
  60. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +18 -11
  61. data/lib/solargraph/language_server/message/text_document/references.rb +23 -16
  62. data/lib/solargraph/language_server/message/text_document/rename.rb +26 -19
  63. data/lib/solargraph/language_server/message/text_document/signature_help.rb +2 -2
  64. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -19
  65. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +41 -35
  66. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +48 -40
  67. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +32 -26
  68. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +27 -19
  69. data/lib/solargraph/language_server/message.rb +94 -94
  70. data/lib/solargraph/language_server/request.rb +29 -27
  71. data/lib/solargraph/language_server/transport/data_reader.rb +72 -74
  72. data/lib/solargraph/language_server/uri_helpers.rb +49 -49
  73. data/lib/solargraph/library.rb +28 -33
  74. data/lib/solargraph/location.rb +10 -12
  75. data/lib/solargraph/logging.rb +4 -4
  76. data/lib/solargraph/page.rb +92 -92
  77. data/lib/solargraph/parser/comment_ripper.rb +12 -4
  78. data/lib/solargraph/parser/flow_sensitive_typing.rb +32 -42
  79. data/lib/solargraph/parser/node_processor/base.rb +4 -4
  80. data/lib/solargraph/parser/node_processor.rb +1 -1
  81. data/lib/solargraph/parser/parser_gem/class_methods.rb +4 -4
  82. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +19 -19
  83. data/lib/solargraph/parser/parser_gem/node_chainer.rb +20 -20
  84. data/lib/solargraph/parser/parser_gem/node_methods.rb +66 -65
  85. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +12 -12
  86. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +1 -1
  87. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +3 -3
  88. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +38 -37
  89. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +3 -3
  90. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +2 -1
  91. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +1 -1
  92. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +3 -5
  93. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +118 -112
  94. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -29
  95. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +1 -1
  96. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +1 -1
  97. data/lib/solargraph/parser/parser_gem.rb +14 -12
  98. data/lib/solargraph/parser/snippet.rb +2 -0
  99. data/lib/solargraph/parser.rb +25 -23
  100. data/lib/solargraph/pin/base.rb +78 -64
  101. data/lib/solargraph/pin/base_variable.rb +28 -71
  102. data/lib/solargraph/pin/block.rb +3 -2
  103. data/lib/solargraph/pin/breakable.rb +2 -0
  104. data/lib/solargraph/pin/callable.rb +23 -26
  105. data/lib/solargraph/pin/closure.rb +5 -4
  106. data/lib/solargraph/pin/common.rb +5 -2
  107. data/lib/solargraph/pin/compound_statement.rb +3 -3
  108. data/lib/solargraph/pin/constant.rb +43 -45
  109. data/lib/solargraph/pin/conversions.rb +9 -4
  110. data/lib/solargraph/pin/delegated_method.rb +4 -4
  111. data/lib/solargraph/pin/documenting.rb +3 -2
  112. data/lib/solargraph/pin/local_variable.rb +4 -4
  113. data/lib/solargraph/pin/method.rb +71 -70
  114. data/lib/solargraph/pin/namespace.rb +13 -12
  115. data/lib/solargraph/pin/parameter.rb +28 -27
  116. data/lib/solargraph/pin/proxy_type.rb +2 -0
  117. data/lib/solargraph/pin/reference.rb +17 -0
  118. data/lib/solargraph/pin/search.rb +2 -2
  119. data/lib/solargraph/pin/signature.rb +9 -14
  120. data/lib/solargraph/pin/symbol.rb +1 -0
  121. data/lib/solargraph/pin/until.rb +1 -3
  122. data/lib/solargraph/pin/while.rb +1 -3
  123. data/lib/solargraph/pin_cache.rb +16 -19
  124. data/lib/solargraph/position.rb +35 -17
  125. data/lib/solargraph/range.rb +10 -9
  126. data/lib/solargraph/rbs_map/conversions.rb +312 -206
  127. data/lib/solargraph/rbs_map/core_fills.rb +91 -84
  128. data/lib/solargraph/rbs_map/stdlib_map.rb +0 -1
  129. data/lib/solargraph/rbs_map.rb +3 -12
  130. data/lib/solargraph/server_methods.rb +16 -16
  131. data/lib/solargraph/shell.rb +63 -53
  132. data/lib/solargraph/source/chain/array.rb +39 -37
  133. data/lib/solargraph/source/chain/call.rb +49 -44
  134. data/lib/solargraph/source/chain/class_variable.rb +13 -13
  135. data/lib/solargraph/source/chain/constant.rb +3 -1
  136. data/lib/solargraph/source/chain/global_variable.rb +13 -13
  137. data/lib/solargraph/source/chain/hash.rb +8 -6
  138. data/lib/solargraph/source/chain/if.rb +11 -10
  139. data/lib/solargraph/source/chain/instance_variable.rb +3 -1
  140. data/lib/solargraph/source/chain/link.rb +99 -109
  141. data/lib/solargraph/source/chain/literal.rb +4 -6
  142. data/lib/solargraph/source/chain/or.rb +2 -4
  143. data/lib/solargraph/source/chain/q_call.rb +13 -11
  144. data/lib/solargraph/source/chain/variable.rb +15 -13
  145. data/lib/solargraph/source/chain/z_super.rb +28 -30
  146. data/lib/solargraph/source/chain.rb +24 -16
  147. data/lib/solargraph/source/change.rb +3 -3
  148. data/lib/solargraph/source/cursor.rb +18 -18
  149. data/lib/solargraph/source/encoding_fixes.rb +6 -7
  150. data/lib/solargraph/source/source_chainer.rb +46 -32
  151. data/lib/solargraph/source/updater.rb +1 -1
  152. data/lib/solargraph/source.rb +27 -29
  153. data/lib/solargraph/source_map/clip.rb +38 -30
  154. data/lib/solargraph/source_map/mapper.rb +52 -46
  155. data/lib/solargraph/source_map.rb +8 -4
  156. data/lib/solargraph/type_checker/rules.rb +8 -8
  157. data/lib/solargraph/type_checker.rb +95 -101
  158. data/lib/solargraph/version.rb +1 -1
  159. data/lib/solargraph/workspace/config.rb +10 -9
  160. data/lib/solargraph/workspace/gemspecs.rb +1 -1
  161. data/lib/solargraph/workspace.rb +21 -44
  162. data/lib/solargraph/yard_map/helpers.rb +6 -2
  163. data/lib/solargraph/yard_map/mapper/to_method.rb +8 -6
  164. data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -1
  165. data/lib/solargraph/yard_map/mapper.rb +12 -12
  166. data/lib/solargraph/yard_tags.rb +20 -20
  167. data/lib/solargraph.rb +5 -5
  168. data/solargraph.gemspec +35 -34
  169. metadata +28 -28
@@ -1,30 +1,28 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- class Source
5
- class Chain
6
- class ZSuper < Call
7
- # @return [String]
8
- attr_reader :word
9
-
10
- # @return [::Array<Chain>]
11
- attr_reader :arguments
12
-
13
- # @param word [String]
14
- # @param arguments [::Array<Chain>]
15
- # @param with_block [Boolean] True if the chain is inside a block
16
- # @param head [Boolean] True if the call is the start of its chain
17
- def initialize word, with_block = false
18
- super(word, nil, [], with_block)
19
- end
20
-
21
- # @param api_map [ApiMap]
22
- # @param name_pin [Pin::Base]
23
- # @param locals [::Array<Pin::Base>]
24
- def resolve api_map, name_pin, locals
25
- return super_pins(api_map, name_pin)
26
- end
27
- end
28
- end
29
- end
30
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ class Chain
6
+ class ZSuper < Call
7
+ # @return [String]
8
+ attr_reader :word
9
+
10
+ # @return [::Array<Chain>]
11
+ attr_reader :arguments
12
+
13
+ # @param word [String]
14
+ # @param with_block [Boolean] True if the chain is inside a block
15
+ def initialize word, with_block = false
16
+ super(word, nil, [], with_block)
17
+ end
18
+
19
+ # @param api_map [ApiMap]
20
+ # @param name_pin [Pin::Base]
21
+ # @param locals [::Array<Pin::Base>]
22
+ def resolve api_map, name_pin, locals
23
+ super_pins(api_map, name_pin)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -48,11 +48,6 @@ module Solargraph
48
48
 
49
49
  attr_reader :node
50
50
 
51
- # @sg-ignore Fix "Not enough arguments to Module#protected"
52
- protected def equality_fields
53
- [links, node]
54
- end
55
-
56
51
  # @param node [Parser::AST::Node, nil]
57
52
  # @param links [::Array<Chain::Link>]
58
53
  # @param splat [Boolean]
@@ -119,7 +114,9 @@ module Solargraph
119
114
  pins = link.resolve(api_map, working_pin, locals)
120
115
  type = infer_from_definitions(pins, working_pin, api_map, locals)
121
116
  if type.undefined?
122
- logger.debug { "Chain#define(links=#{links.map(&:desc)}, name_pin=#{name_pin.inspect}, locals=#{locals}) => [] - undefined type from #{link.desc}" }
117
+ logger.debug do
118
+ "Chain#define(links=#{links.map(&:desc)}, name_pin=#{name_pin.inspect}, locals=#{locals}) => [] - undefined type from #{link.desc}"
119
+ end
123
120
  return []
124
121
  end
125
122
  # We continue to use the context from the head pin, in case
@@ -128,7 +125,9 @@ module Solargraph
128
125
  # for the binder, as this is chaining off of it, and the
129
126
  # binder is now the lhs of the rhs we are evaluating.
130
127
  working_pin = Pin::ProxyType.anonymous(name_pin.context, binder: type, closure: name_pin, source: :chain)
131
- logger.debug { "Chain#define(links=#{links.map(&:desc)}, name_pin=#{name_pin.inspect}, locals=#{locals}) - after processing #{link.desc}, new working_pin=#{working_pin} with binder #{working_pin.binder}" }
128
+ logger.debug do
129
+ "Chain#define(links=#{links.map(&:desc)}, name_pin=#{name_pin.inspect}, locals=#{locals}) - after processing #{link.desc}, new working_pin=#{working_pin} with binder #{working_pin.binder}"
130
+ end
132
131
  end
133
132
  links.last.last_context = working_pin
134
133
  links.last.resolve(api_map, working_pin, locals)
@@ -150,7 +149,9 @@ module Solargraph
150
149
  @@inference_cache = {}
151
150
  end
152
151
  out = infer_uncached(api_map, name_pin, locals).downcast_to_literal_if_possible
153
- logger.debug { "Chain#infer() - caching result - cache_key_hash=#{cache_key.hash}, links.map(&:hash)=#{links.map(&:hash)}, links=#{links}, cache_key.map(&:hash) = #{cache_key.map(&:hash)}, cache_key=#{cache_key}" }
152
+ logger.debug do
153
+ "Chain#infer() - caching result - cache_key_hash=#{cache_key.hash}, links.map(&:hash)=#{links.map(&:hash)}, links=#{links}, cache_key.map(&:hash) = #{cache_key.map(&:hash)}, cache_key=#{cache_key}"
154
+ end
154
155
  @@inference_cache[cache_key] = out
155
156
  end
156
157
 
@@ -161,12 +162,16 @@ module Solargraph
161
162
  def infer_uncached api_map, name_pin, locals
162
163
  pins = define(api_map, name_pin, locals)
163
164
  if pins.empty?
164
- logger.debug { "Chain#infer_uncached(links=#{links.map(&:desc)}, locals=#{locals.map(&:desc)}) => undefined - no pins" }
165
+ logger.debug do
166
+ "Chain#infer_uncached(links=#{links.map(&:desc)}, locals=#{locals.map(&:desc)}) => undefined - no pins"
167
+ end
165
168
  return ComplexType::UNDEFINED
166
169
  end
167
170
  type = infer_from_definitions(pins, links.last.last_context, api_map, locals)
168
171
  out = maybe_nil(type)
169
- logger.debug { "Chain#infer_uncached(links=#{self.links.map(&:desc)}, locals=#{locals.map(&:desc)}, name_pin=#{name_pin}, name_pin.closure=#{name_pin.closure.inspect}, name_pin.binder=#{name_pin.binder}) => #{out.rooted_tags.inspect}" }
172
+ logger.debug do
173
+ "Chain#infer_uncached(links=#{links.map(&:desc)}, locals=#{locals.map(&:desc)}, name_pin=#{name_pin}, name_pin.closure=#{name_pin.closure.inspect}, name_pin.binder=#{name_pin.binder}) => #{out.rooted_tags.inspect}"
174
+ end
170
175
  out
171
176
  end
172
177
 
@@ -245,17 +250,13 @@ module Solargraph
245
250
  end
246
251
 
247
252
  # Limit method inference recursion
248
- if @@inference_depth >= 10 && pins.first.is_a?(Pin::Method)
249
- return ComplexType::UNDEFINED
250
- end
253
+ return ComplexType::UNDEFINED if @@inference_depth >= 10 && pins.first.is_a?(Pin::Method)
251
254
 
252
255
  @@inference_depth += 1
253
256
  # @param pin [Pin::Base]
254
257
  unresolved_pins.each do |pin|
255
258
  # Avoid infinite recursion
256
- if @@inference_stack.include?(pin.identity)
257
- next
258
- end
259
+ next if @@inference_stack.include?(pin.identity)
259
260
 
260
261
  @@inference_stack.push(pin.identity)
261
262
  type = pin.probe(api_map)
@@ -289,6 +290,13 @@ module Solargraph
289
290
  return type unless nullable?
290
291
  ComplexType.new(type.items + [ComplexType::NIL])
291
292
  end
293
+
294
+ protected
295
+
296
+ # @sg-ignore Fix "Not enough arguments to Module#protected"
297
+ def equality_fields
298
+ [links, node]
299
+ end
292
300
  end
293
301
  end
294
302
  end
@@ -28,7 +28,7 @@ module Solargraph
28
28
  # syntax errors will be repaired.
29
29
  # @return [String] The updated text.
30
30
  def write text, nullable = false
31
- if nullable and !range.nil? and new_text.match(/[.\[{(@$:]$/)
31
+ if nullable && !range.nil? && new_text.match(/[.\[{(@$:]$/)
32
32
  [':', '@'].each do |dupable|
33
33
  next unless new_text == dupable
34
34
  # @sg-ignore flow sensitive typing needs to handle attrs
@@ -66,7 +66,7 @@ module Solargraph
66
66
  match = result[0, off].match(/[.:]+\z/)
67
67
  if match
68
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..-1]
69
+ result = result[0, off].sub(/#{match[0]}\z/, ' ' * match[0].length) + result[off..]
70
70
  end
71
71
  result
72
72
  end
@@ -82,7 +82,7 @@ module Solargraph
82
82
  start_offset = Position.to_offset(text, range.start)
83
83
  # @sg-ignore Need to add nil check here
84
84
  end_offset = Position.to_offset(text, range.ending)
85
- (start_offset == 0 ? '' : text[0..start_offset-1].to_s) + normalize(insert) + text[end_offset..-1].to_s
85
+ (start_offset.zero? ? '' : text[0..(start_offset - 1)].to_s) + normalize(insert) + text[end_offset..].to_s
86
86
  end
87
87
  end
88
88
  end
@@ -39,11 +39,13 @@ module Solargraph
39
39
  # @return [String]
40
40
  def start_of_word
41
41
  @start_of_word ||= begin
42
- match = source.code[0..offset-1].to_s.match(start_word_pattern)
42
+ match = source.code[0..(offset - 1)].to_s.match(start_word_pattern)
43
43
  result = (match ? match[0] : '')
44
44
  # Including the preceding colon if the word appears to be a symbol
45
45
  # @sg-ignore Need to add nil check here
46
- result = ":#{result}" if source.code[0..offset-result.length-1].end_with?(':') and !source.code[0..offset-result.length-1].end_with?('::')
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
47
49
  result
48
50
  end
49
51
  end
@@ -55,14 +57,14 @@ module Solargraph
55
57
  # @sg-ignore Need to add nil check here
56
58
  def end_of_word
57
59
  @end_of_word ||= begin
58
- match = source.code[offset..-1].to_s.match(end_word_pattern)
60
+ match = source.code[offset..].to_s.match(end_word_pattern)
59
61
  match ? match[0] : ''
60
62
  end
61
63
  end
62
64
 
63
65
  # @return [Boolean]
64
66
  def start_of_constant?
65
- source.code[offset-2, 2] == '::'
67
+ source.code[offset - 2, 2] == '::'
66
68
  end
67
69
 
68
70
  # The range of the word at the current position.
@@ -126,20 +128,18 @@ module Solargraph
126
128
 
127
129
  # @return [Position]
128
130
  def node_position
129
- @node_position ||= begin
130
- if start_of_word.empty?
131
- # @sg-ignore Need to add nil check here
132
- match = source.code[0, offset].match(/\s*(\.|:+)\s*$/)
133
- if match
134
- # @sg-ignore Need to add nil check here
135
- Position.from_offset(source.code, offset - match[0].length)
136
- else
137
- position
138
- end
139
- else
140
- position
141
- end
142
- end
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
143
  end
144
144
 
145
145
  # @return [Parser::AST::Node, nil]
@@ -10,13 +10,12 @@ module Solargraph
10
10
  # @param string [String]
11
11
  # @return [String]
12
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
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
20
19
  end
21
20
  end
22
21
  end
@@ -32,10 +32,22 @@ module Solargraph
32
32
  # @return [Source::Chain]
33
33
  def chain
34
34
  # Special handling for files that end with an integer and a period
35
- return Chain.new([Chain::Literal.new('Integer', Integer(phrase[0..-2])), Chain::UNDEFINED_CALL]) if phrase =~ /^[0-9]+\.$/
36
- # @sg-ignore Need to add nil check here
37
- return Chain.new([Chain::Literal.new('Symbol', phrase[1..].to_sym)]) if phrase.start_with?(':') && !phrase.start_with?('::')
38
- return SourceChainer.chain(source, Position.new(position.line, position.character + 1)) if end_of_phrase.strip == '::' && source.code[Position.to_offset(source.code, position)].to_s.match?(/[a-z]/i)
35
+ if phrase =~ /^[0-9]+\.$/
36
+ return Chain.new([Chain::Literal.new('Integer', Integer(phrase[0..-2])),
37
+ Chain::UNDEFINED_CALL])
38
+ end
39
+ if phrase.start_with?(':') && !phrase.start_with?('::')
40
+ return Chain.new([Chain::Literal.new('Symbol',
41
+ # @sg-ignore Need to add nil check here
42
+ phrase[1..].to_sym)])
43
+ end
44
+ if end_of_phrase.strip == '::' && source.code[Position.to_offset(
45
+ source.code, position
46
+ )].to_s.match?(/[a-z]/i)
47
+ return SourceChainer.chain(source,
48
+ Position.new(position.line,
49
+ position.character + 1))
50
+ end
39
51
  begin
40
52
  return Chain.new([]) if phrase.end_with?('..')
41
53
  # @type [::Parser::AST::Node, nil]
@@ -52,7 +64,12 @@ module Solargraph
52
64
  elsif source.repaired?
53
65
  node = Parser.parse(fixed_phrase, source.filename, fixed_position.line)
54
66
  else
55
- node, parent = source.tree_at(fixed_position.line, fixed_position.column)[0..2] unless source.error_ranges.any?{|r| r.nil? || r.include?(fixed_position)}
67
+ unless source.error_ranges.any? do |r|
68
+ r.nil? || r.include?(fixed_position)
69
+ end
70
+ node, parent = source.tree_at(fixed_position.line,
71
+ fixed_position.column)[0..2]
72
+ end
56
73
  # Exception for positions that chain literal nodes in unsynchronized sources
57
74
  node = nil unless source.synchronized? || !Parser.infer_literal_node_type(node).nil?
58
75
  node = Parser.parse(fixed_phrase, source.filename, fixed_position.line) if node.nil?
@@ -86,13 +103,13 @@ module Solargraph
86
103
  # @sg-ignore Need to add nil check here
87
104
  # @return [String]
88
105
  def phrase
89
- @phrase ||= source.code[signature_data..offset-1]
106
+ @phrase ||= source.code[signature_data..(offset - 1)]
90
107
  end
91
108
 
92
109
  # @sg-ignore Need to add nil check here
93
110
  # @return [String]
94
111
  def fixed_phrase
95
- @fixed_phrase ||= phrase[0..-(end_of_phrase.length+1)]
112
+ @fixed_phrase ||= phrase[0..-(end_of_phrase.length + 1)]
96
113
  end
97
114
 
98
115
  # @return [Position]
@@ -144,50 +161,47 @@ module Solargraph
144
161
  brackets = 0
145
162
  squares = 0
146
163
  parens = 0
147
- index -=1
164
+ index -= 1
148
165
  in_whitespace = false
149
166
  while index >= 0
150
167
  pos = Position.from_offset(@source.code, index)
151
- break if index > 0 and @source.comment_at?(pos)
152
- break if brackets > 0 or parens > 0 or squares > 0
168
+ break if index.positive? && @source.comment_at?(pos)
169
+ break if brackets.positive? || parens.positive? || squares.positive?
153
170
  char = @source.code[index, 1]
154
171
  break if char.nil? # @todo Is this the right way to handle this?
155
- if brackets.zero? and parens.zero? and squares.zero? and [' ', "\r", "\n", "\t"].include?(char)
172
+ if brackets.zero? && parens.zero? && squares.zero? && [' ', "\r", "\n", "\t"].include?(char)
156
173
  in_whitespace = true
157
174
  else
158
- if brackets.zero? and parens.zero? and squares.zero? and in_whitespace
175
+ # @sg-ignore Need to add nil check here
176
+ if brackets.zero? && parens.zero? && squares.zero? && in_whitespace && !((char == '.') || @source.code[(index + 1)..].strip.start_with?('.'))
177
+ @source.code[(index + 1)..]
159
178
  # @sg-ignore Need to add nil check here
160
- unless char == '.' or @source.code[index+1..-1].strip.start_with?('.')
161
- old = @source.code[index+1..-1]
162
- # @sg-ignore Need to add nil check here
163
- nxt = @source.code[index+1..-1].lstrip
164
- # @sg-ignore Need to add nil check here
165
- index += (@source.code[index+1..-1].length - @source.code[index+1..-1].lstrip.length)
166
- break
167
- end
179
+ @source.code[(index + 1)..].lstrip
180
+ # @sg-ignore Need to add nil check here
181
+ index += (@source.code[(index + 1)..].length - @source.code[(index + 1)..].lstrip.length)
182
+ break
168
183
  end
169
- if char == ')'
170
- parens -=1
171
- elsif char == ']'
172
- squares -=1
173
- elsif char == '}'
184
+ case char
185
+ when ')'
186
+ parens -= 1
187
+ when ']'
188
+ squares -= 1
189
+ when '}'
174
190
  brackets -= 1
175
- elsif char == '('
191
+ when '('
176
192
  parens += 1
177
- elsif char == '{'
193
+ when '{'
178
194
  brackets += 1
179
- elsif char == '['
195
+ when '['
180
196
  squares += 1
181
197
  end
182
- if brackets.zero? and parens.zero? and squares.zero?
198
+ if brackets.zero? && parens.zero? && squares.zero?
183
199
  break if ['"', "'", ',', ';', '%'].include?(char)
184
200
  break if ['!', '?'].include?(char) && index < offset - 1
185
201
  break if char == '$'
186
202
  if char == '@'
187
203
  index -= 1
188
- if @source.code[index, 1] == '@'
189
- index -= 1
190
- end
204
+ index -= 1 if @source.code[index, 1] == '@'
191
205
  break
192
206
  end
193
207
  elsif parens == 1 || brackets == 1 || squares == 1
@@ -33,7 +33,7 @@ module Solargraph
33
33
  # @return [String]
34
34
  def write text, nullable = false
35
35
  can_nullify = (nullable and changes.length == 1)
36
- return @output if @input == text and can_nullify == @did_nullify
36
+ return @output if (@input == text) && (can_nullify == @did_nullify)
37
37
  @input = text
38
38
  @output = text
39
39
  @did_nullify = can_nullify
@@ -66,7 +66,7 @@ module Solargraph
66
66
  def from_to l1, c1, l2, c2
67
67
  b = Solargraph::Position.line_char_to_offset(code, l1, c1)
68
68
  e = Solargraph::Position.line_char_to_offset(code, l2, c2)
69
- code[b..e-1]
69
+ code[b..(e - 1)]
70
70
  end
71
71
 
72
72
  # Get the nearest node that contains the specified index.
@@ -74,7 +74,7 @@ module Solargraph
74
74
  # @param line [Integer]
75
75
  # @param column [Integer]
76
76
  # @return [AST::Node]
77
- def node_at(line, column)
77
+ def node_at line, column
78
78
  tree_at(line, column).first
79
79
  end
80
80
 
@@ -84,7 +84,7 @@ module Solargraph
84
84
  # @param line [Integer]
85
85
  # @param column [Integer]
86
86
  # @return [Array<Parser::AST::Node>]
87
- def tree_at(line, column)
87
+ def tree_at line, column
88
88
  position = Position.new(line, column)
89
89
  stack = []
90
90
  inner_tree_at node, position, stack
@@ -140,7 +140,7 @@ module Solargraph
140
140
  # @sg-ignore Need to add nil check here
141
141
  return true if node.type == :str && range.include?(position) && range.start != position
142
142
  # @sg-ignore Need to add nil check here
143
- return true if [:STR, :str].include?(node.type) && range.include?(position) && range.start != position
143
+ return true if %i[STR str].include?(node.type) && range.include?(position) && range.start != position
144
144
  if node.type == :dstr
145
145
  inner = node_at(position.line, position.column)
146
146
  next if inner.nil?
@@ -151,7 +151,7 @@ module Solargraph
151
151
  # @sg-ignore Need to add nil check here
152
152
  inner_code = at(Solargraph::Range.new(inner_range.start, position))
153
153
  # @sg-ignore Need to add nil check here
154
- return true if (inner.type == :dstr && inner_range.ending.character <= position.character) && !inner_code.end_with?('}') ||
154
+ return true if (inner.type == :dstr && inner_range.ending.character <= position.character && !inner_code.end_with?('}')) ||
155
155
  # @sg-ignore Need to add nil check here
156
156
  (inner.type != :dstr && inner_range.ending.line == position.line && position.character <= inner_range.ending.character && inner_code.end_with?('}'))
157
157
  end
@@ -171,7 +171,7 @@ module Solargraph
171
171
  def comment_at? position
172
172
  comment_ranges.each do |range|
173
173
  return true if range.include?(position) ||
174
- (range.ending.line == position.line && range.ending.column < position.column)
174
+ (range.ending.line == position.line && range.ending.column < position.column)
175
175
  break if range.ending.line > position.line
176
176
  end
177
177
  false
@@ -190,13 +190,13 @@ module Solargraph
190
190
 
191
191
  # @param node [Parser::AST::Node]
192
192
  # @return [String]
193
- def code_for(node)
193
+ def code_for node
194
194
  rng = Range.from_node(node)
195
195
  # @sg-ignore Need to add nil check here
196
196
  b = Position.line_char_to_offset(code, rng.start.line, rng.start.column)
197
197
  # @sg-ignore Need to add nil check here
198
198
  e = Position.line_char_to_offset(code, rng.ending.line, rng.ending.column)
199
- frag = code[b..e-1].to_s
199
+ frag = code[b..(e - 1)].to_s
200
200
  frag.strip.gsub(/,$/, '')
201
201
  end
202
202
 
@@ -224,8 +224,8 @@ module Solargraph
224
224
  end
225
225
 
226
226
  FOLDING_NODE_TYPES = %i[
227
- class sclass module def defs if str dstr array while unless kwbegin hash block
228
- ].freeze
227
+ class sclass module def defs if str dstr array while unless kwbegin hash block
228
+ ].freeze
229
229
 
230
230
  # Get an array of ranges that can be folded, e.g., the range of a class
231
231
  # definition or an if condition.
@@ -293,9 +293,8 @@ module Solargraph
293
293
  # @sg-ignore Translate to something flow sensitive typing understands
294
294
  range = Range.from_node(top)
295
295
  # @sg-ignore Need to add nil check here
296
- if result.empty? || range.start.line > result.last.start.line
297
- # @sg-ignore Need to add nil check here
298
- result.push range unless range.ending.line - range.start.line < 2
296
+ if (result.empty? || range.start.line > result.last.start.line) && range.ending.line - range.start.line >= 2
297
+ result.push range
299
298
  end
300
299
  end
301
300
  # @sg-ignore Translate to something flow sensitive typing understands
@@ -312,7 +311,7 @@ module Solargraph
312
311
  ctxt = String.new('')
313
312
  started = false
314
313
  skip = nil
315
- comments.lines.each { |l|
314
+ comments.lines.each do |l|
316
315
  # Trim the comment and minimum leading whitespace
317
316
  p = l.force_encoding('UTF-8').encode('UTF-8', invalid: :replace, replace: '?').gsub(/^#+/, '')
318
317
  if p.strip.empty?
@@ -322,10 +321,10 @@ module Solargraph
322
321
  here = p.index(/[^ \t]/)
323
322
  # @sg-ignore flow sensitive typing should be able to handle redefinition
324
323
  skip = here if skip.nil? || here < skip
325
- ctxt.concat p[skip..-1]
324
+ ctxt.concat p[skip..]
326
325
  end
327
326
  started = true
328
- }
327
+ end
329
328
  ctxt
330
329
  end
331
330
 
@@ -354,7 +353,7 @@ module Solargraph
354
353
  return [] unless synchronized?
355
354
  result = []
356
355
  grouped = []
357
- comments.keys.each do |l|
356
+ comments.each_key do |l|
358
357
  if grouped.empty? || l == grouped.last + 1
359
358
  grouped.push l
360
359
  else
@@ -372,11 +371,11 @@ module Solargraph
372
371
  result = []
373
372
  if Parser.is_ast_node?(n)
374
373
  # @sg-ignore Translate to something flow sensitive typing understands
375
- if n.type == :str || n.type == :dstr || n.type == :STR || n.type == :DSTR
374
+ if %i[str dstr STR DSTR].include?(n.type)
376
375
  result.push n
377
376
  else
378
377
  # @sg-ignore Translate to something flow sensitive typing understands
379
- n.children.each{ |c| result.concat string_nodes_in(c) }
378
+ n.children.each { |c| result.concat string_nodes_in(c) }
380
379
  end
381
380
  end
382
381
  result
@@ -390,13 +389,12 @@ module Solargraph
390
389
  return if node.nil?
391
390
  here = Range.from_node(node)
392
391
  # @sg-ignore Need to add nil check here
393
- if here.contain?(position)
394
- stack.unshift node
395
- node.children.each do |c|
396
- next unless Parser.is_ast_node?(c)
397
- next if c.loc.expression.nil?
398
- inner_tree_at(c, position, stack)
399
- end
392
+ return unless here.contain?(position)
393
+ stack.unshift node
394
+ node.children.each do |c|
395
+ next unless Parser.is_ast_node?(c)
396
+ next if c.loc.expression.nil?
397
+ inner_tree_at(c, position, stack)
400
398
  end
401
399
  end
402
400
 
@@ -425,7 +423,7 @@ module Solargraph
425
423
  @node, @comments = Solargraph::Parser.parse_with_comments(@code, filename, 0)
426
424
  @parsed = true
427
425
  @repaired = @code
428
- rescue Parser::SyntaxError, EncodingError => e
426
+ rescue Parser::SyntaxError, EncodingError
429
427
  @node = nil
430
428
  @comments = {}
431
429
  @parsed = false
@@ -440,7 +438,7 @@ module Solargraph
440
438
  begin
441
439
  @node, @comments = Solargraph::Parser.parse_with_comments(@repaired, filename, 0)
442
440
  @parsed = true
443
- rescue Parser::SyntaxError, EncodingError => e
441
+ rescue Parser::SyntaxError, EncodingError
444
442
  @node = nil
445
443
  @comments = {}
446
444
  @parsed = false
@@ -453,7 +451,7 @@ module Solargraph
453
451
 
454
452
  # @param val [String]
455
453
  # @return [String]
456
- def code=(val)
454
+ def code= val
457
455
  @code_lines = nil
458
456
  @finalized = false
459
457
  @code = val