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,194 +1,194 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- class Source
5
- # Information about a location in a source, including the location's word
6
- # and signature, literal values at the base of signatures, and whether the
7
- # location is inside a string or comment. ApiMaps use Fragments to provide
8
- # results for completion and definition queries.
9
- #
10
- class SourceChainer
11
- # include Source::NodeMethods
12
-
13
- private_class_method :new
14
-
15
- class << self
16
- # @param source [Source]
17
- # @param position [Position, Array(Integer, Integer)]
18
- # @return [Source::Chain]
19
- def chain source, position
20
- new(source, Solargraph::Position.normalize(position)).chain
21
- end
22
- end
23
-
24
- # @param source [Source]
25
- # @param position [Position]
26
- def initialize source, position
27
- @source = source
28
- @position = position
29
- @calculated_literal = false
30
- end
31
-
32
- # @return [Source::Chain]
33
- def chain
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
- return Chain.new([Chain::Literal.new('Symbol', phrase[1..].to_sym)]) if phrase.start_with?(':') && !phrase.start_with?('::')
37
- 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)
38
- begin
39
- return Chain.new([]) if phrase.end_with?('..')
40
- node = nil
41
- parent = nil
42
- if !source.repaired? && source.parsed? && source.synchronized?
43
- tree = source.tree_at(position.line, position.column)
44
- node, parent = tree[0..2]
45
- elsif source.parsed? && source.repaired? && end_of_phrase == '.'
46
- node, parent = source.tree_at(fixed_position.line, fixed_position.column)[0..2]
47
- node = Parser.parse(fixed_phrase) if node.nil?
48
- elsif source.repaired?
49
- node = Parser.parse(fixed_phrase)
50
- else
51
- 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)}
52
- # Exception for positions that chain literal nodes in unsynchronized sources
53
- node = nil unless source.synchronized? || !Parser.infer_literal_node_type(node).nil?
54
- node = Parser.parse(fixed_phrase) if node.nil?
55
- end
56
- rescue Parser::SyntaxError
57
- return Chain.new([Chain::UNDEFINED_CALL])
58
- end
59
- return Chain.new([Chain::UNDEFINED_CALL]) if node.nil? || (node.type == :sym && !phrase.start_with?(':'))
60
- # chain = NodeChainer.chain(node, source.filename, parent && parent.type == :block)
61
- chain = Parser.chain(node, source.filename, parent)
62
- if source.repaired? || !source.parsed? || !source.synchronized?
63
- if end_of_phrase.strip == '.'
64
- chain.links.push Chain::UNDEFINED_CALL
65
- elsif end_of_phrase.strip == '::'
66
- chain.links.push Chain::UNDEFINED_CONSTANT
67
- end
68
- elsif chain.links.last.is_a?(Source::Chain::Constant) && end_of_phrase.strip == '::'
69
- chain.links.push Source::Chain::UNDEFINED_CONSTANT
70
- end
71
- chain
72
- end
73
-
74
- private
75
-
76
- # @return [Position]
77
- attr_reader :position
78
-
79
- # @return [Solargraph::Source]
80
- attr_reader :source
81
-
82
- # @return [String]
83
- def phrase
84
- @phrase ||= source.code[signature_data..offset-1]
85
- end
86
-
87
- # @return [String]
88
- def fixed_phrase
89
- @fixed_phrase ||= phrase[0..-(end_of_phrase.length+1)]
90
- end
91
-
92
- # @return [Position]
93
- def fixed_position
94
- @fixed_position ||= Position.from_offset(source.code, offset - end_of_phrase.length)
95
- end
96
-
97
- # @return [String]
98
- def end_of_phrase
99
- @end_of_phrase ||= begin
100
- match = phrase.match(/[\s]*(\.{1}|::)[\s]*$/)
101
- if match
102
- match[0]
103
- else
104
- ''
105
- end
106
- end
107
- end
108
-
109
- # True if the current offset is inside a string.
110
- #
111
- # @return [Boolean]
112
- def string?
113
- # @string ||= (node.type == :str or node.type == :dstr)
114
- @string ||= @source.string_at?(position)
115
- end
116
-
117
- # @return [Integer]
118
- def offset
119
- @offset ||= get_offset(position.line, position.column)
120
- end
121
-
122
- # @param line [Integer]
123
- # @param column [Integer]
124
- # @return [Integer]
125
- def get_offset line, column
126
- Position.line_char_to_offset(@source.code, line, column)
127
- end
128
-
129
- # @return [Integer]
130
- def signature_data
131
- @signature_data ||= get_signature_data_at(offset)
132
- end
133
-
134
- # @param index [Integer]
135
- # @return [Integer]
136
- def get_signature_data_at index
137
- brackets = 0
138
- squares = 0
139
- parens = 0
140
- index -=1
141
- in_whitespace = false
142
- while index >= 0
143
- pos = Position.from_offset(@source.code, index)
144
- break if index > 0 and @source.comment_at?(pos)
145
- break if brackets > 0 or parens > 0 or squares > 0
146
- char = @source.code[index, 1]
147
- break if char.nil? # @todo Is this the right way to handle this?
148
- if brackets.zero? and parens.zero? and squares.zero? and [' ', "\r", "\n", "\t"].include?(char)
149
- in_whitespace = true
150
- else
151
- if brackets.zero? and parens.zero? and squares.zero? and in_whitespace
152
- unless char == '.' or @source.code[index+1..-1].strip.start_with?('.')
153
- old = @source.code[index+1..-1]
154
- nxt = @source.code[index+1..-1].lstrip
155
- index += (@source.code[index+1..-1].length - @source.code[index+1..-1].lstrip.length)
156
- break
157
- end
158
- end
159
- if char == ')'
160
- parens -=1
161
- elsif char == ']'
162
- squares -=1
163
- elsif char == '}'
164
- brackets -= 1
165
- elsif char == '('
166
- parens += 1
167
- elsif char == '{'
168
- brackets += 1
169
- elsif char == '['
170
- squares += 1
171
- end
172
- if brackets.zero? and parens.zero? and squares.zero?
173
- break if ['"', "'", ',', ';', '%'].include?(char)
174
- break if ['!', '?'].include?(char) && index < offset - 1
175
- break if char == '$'
176
- if char == '@'
177
- index -= 1
178
- if @source.code[index, 1] == '@'
179
- index -= 1
180
- end
181
- break
182
- end
183
- elsif parens == 1 || brackets == 1 || squares == 1
184
- break
185
- end
186
- in_whitespace = false
187
- end
188
- index -= 1
189
- end
190
- index + 1
191
- end
192
- end
193
- end
194
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ # Information about a location in a source, including the location's word
6
+ # and signature, literal values at the base of signatures, and whether the
7
+ # location is inside a string or comment. ApiMaps use Fragments to provide
8
+ # results for completion and definition queries.
9
+ #
10
+ class SourceChainer
11
+ # include Source::NodeMethods
12
+
13
+ private_class_method :new
14
+
15
+ class << self
16
+ # @param source [Source]
17
+ # @param position [Position, Array(Integer, Integer)]
18
+ # @return [Source::Chain]
19
+ def chain source, position
20
+ new(source, Solargraph::Position.normalize(position)).chain
21
+ end
22
+ end
23
+
24
+ # @param source [Source]
25
+ # @param position [Position]
26
+ def initialize source, position
27
+ @source = source
28
+ @position = position
29
+ @calculated_literal = false
30
+ end
31
+
32
+ # @return [Source::Chain]
33
+ def chain
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
+ return Chain.new([Chain::Literal.new('Symbol', phrase[1..].to_sym)]) if phrase.start_with?(':') && !phrase.start_with?('::')
37
+ 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)
38
+ begin
39
+ return Chain.new([]) if phrase.end_with?('..')
40
+ node = nil
41
+ parent = nil
42
+ if !source.repaired? && source.parsed? && source.synchronized?
43
+ tree = source.tree_at(position.line, position.column)
44
+ node, parent = tree[0..2]
45
+ elsif source.parsed? && source.repaired? && end_of_phrase == '.'
46
+ node, parent = source.tree_at(fixed_position.line, fixed_position.column)[0..2]
47
+ node = Parser.parse(fixed_phrase) if node.nil?
48
+ elsif source.repaired?
49
+ node = Parser.parse(fixed_phrase)
50
+ else
51
+ 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)}
52
+ # Exception for positions that chain literal nodes in unsynchronized sources
53
+ node = nil unless source.synchronized? || !Parser.infer_literal_node_type(node).nil?
54
+ node = Parser.parse(fixed_phrase) if node.nil?
55
+ end
56
+ rescue Parser::SyntaxError
57
+ return Chain.new([Chain::UNDEFINED_CALL])
58
+ end
59
+ return Chain.new([Chain::UNDEFINED_CALL]) if node.nil? || (node.type == :sym && !phrase.start_with?(':'))
60
+ # chain = NodeChainer.chain(node, source.filename, parent && parent.type == :block)
61
+ chain = Parser.chain(node, source.filename, parent)
62
+ if source.repaired? || !source.parsed? || !source.synchronized?
63
+ if end_of_phrase.strip == '.'
64
+ chain.links.push Chain::UNDEFINED_CALL
65
+ elsif end_of_phrase.strip == '::'
66
+ chain.links.push Chain::UNDEFINED_CONSTANT
67
+ end
68
+ elsif chain.links.last.is_a?(Source::Chain::Constant) && end_of_phrase.strip == '::'
69
+ chain.links.push Source::Chain::UNDEFINED_CONSTANT
70
+ end
71
+ chain
72
+ end
73
+
74
+ private
75
+
76
+ # @return [Position]
77
+ attr_reader :position
78
+
79
+ # @return [Solargraph::Source]
80
+ attr_reader :source
81
+
82
+ # @return [String]
83
+ def phrase
84
+ @phrase ||= source.code[signature_data..offset-1]
85
+ end
86
+
87
+ # @return [String]
88
+ def fixed_phrase
89
+ @fixed_phrase ||= phrase[0..-(end_of_phrase.length+1)]
90
+ end
91
+
92
+ # @return [Position]
93
+ def fixed_position
94
+ @fixed_position ||= Position.from_offset(source.code, offset - end_of_phrase.length)
95
+ end
96
+
97
+ # @return [String]
98
+ def end_of_phrase
99
+ @end_of_phrase ||= begin
100
+ match = phrase.match(/\s*(\.{1}|::)\s*$/)
101
+ if match
102
+ match[0]
103
+ else
104
+ ''
105
+ end
106
+ end
107
+ end
108
+
109
+ # True if the current offset is inside a string.
110
+ #
111
+ # @return [Boolean]
112
+ def string?
113
+ # @string ||= (node.type == :str or node.type == :dstr)
114
+ @string ||= @source.string_at?(position)
115
+ end
116
+
117
+ # @return [Integer]
118
+ def offset
119
+ @offset ||= get_offset(position.line, position.column)
120
+ end
121
+
122
+ # @param line [Integer]
123
+ # @param column [Integer]
124
+ # @return [Integer]
125
+ def get_offset line, column
126
+ Position.line_char_to_offset(@source.code, line, column)
127
+ end
128
+
129
+ # @return [Integer]
130
+ def signature_data
131
+ @signature_data ||= get_signature_data_at(offset)
132
+ end
133
+
134
+ # @param index [Integer]
135
+ # @return [Integer]
136
+ def get_signature_data_at index
137
+ brackets = 0
138
+ squares = 0
139
+ parens = 0
140
+ index -=1
141
+ in_whitespace = false
142
+ while index >= 0
143
+ pos = Position.from_offset(@source.code, index)
144
+ break if index > 0 and @source.comment_at?(pos)
145
+ break if brackets > 0 or parens > 0 or squares > 0
146
+ char = @source.code[index, 1]
147
+ break if char.nil? # @todo Is this the right way to handle this?
148
+ if brackets.zero? and parens.zero? and squares.zero? and [' ', "\r", "\n", "\t"].include?(char)
149
+ in_whitespace = true
150
+ else
151
+ if brackets.zero? and parens.zero? and squares.zero? and in_whitespace
152
+ unless char == '.' or @source.code[index+1..-1].strip.start_with?('.')
153
+ old = @source.code[index+1..-1]
154
+ nxt = @source.code[index+1..-1].lstrip
155
+ index += (@source.code[index+1..-1].length - @source.code[index+1..-1].lstrip.length)
156
+ break
157
+ end
158
+ end
159
+ if char == ')'
160
+ parens -=1
161
+ elsif char == ']'
162
+ squares -=1
163
+ elsif char == '}'
164
+ brackets -= 1
165
+ elsif char == '('
166
+ parens += 1
167
+ elsif char == '{'
168
+ brackets += 1
169
+ elsif char == '['
170
+ squares += 1
171
+ end
172
+ if brackets.zero? and parens.zero? and squares.zero?
173
+ break if ['"', "'", ',', ';', '%'].include?(char)
174
+ break if ['!', '?'].include?(char) && index < offset - 1
175
+ break if char == '$'
176
+ if char == '@'
177
+ index -= 1
178
+ if @source.code[index, 1] == '@'
179
+ index -= 1
180
+ end
181
+ break
182
+ end
183
+ elsif parens == 1 || brackets == 1 || squares == 1
184
+ break
185
+ end
186
+ in_whitespace = false
187
+ end
188
+ index -= 1
189
+ end
190
+ index + 1
191
+ end
192
+ end
193
+ end
194
+ end
@@ -1,55 +1,55 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- class Source
5
- # Updaters contain changes to be applied to a source. The source applies
6
- # the update via the Source#synchronize method.
7
- #
8
- class Updater
9
- # @return [String]
10
- attr_reader :filename
11
-
12
- # @return [Integer]
13
- attr_reader :version
14
-
15
- # @return [Array<Change>]
16
- attr_reader :changes
17
-
18
- # @param filename [String] The file to update.
19
- # @param version [Integer] A version number associated with this update.
20
- # @param changes [Array<Solargraph::Source::Change>] The changes.
21
- def initialize filename, version, changes
22
- @filename = filename
23
- @version = version
24
- @changes = changes
25
- @input = nil
26
- @did_nullify = nil
27
- @output = nil
28
- end
29
-
30
- # @param text [String]
31
- # @param nullable [Boolean]
32
- # @return [String]
33
- def write text, nullable = false
34
- can_nullify = (nullable and changes.length == 1)
35
- return @output if @input == text and can_nullify == @did_nullify
36
- @input = text
37
- @output = text
38
- @did_nullify = can_nullify
39
- changes.each do |ch|
40
- @output = ch.write(@output, can_nullify)
41
- end
42
- @output
43
- end
44
-
45
- # @param text [String]
46
- # @return [String]
47
- def repair text
48
- changes.each do |ch|
49
- text = ch.repair(text)
50
- end
51
- text
52
- end
53
- end
54
- end
55
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ # Updaters contain changes to be applied to a source. The source applies
6
+ # the update via the Source#synchronize method.
7
+ #
8
+ class Updater
9
+ # @return [String]
10
+ attr_reader :filename
11
+
12
+ # @return [Integer]
13
+ attr_reader :version
14
+
15
+ # @return [Array<Change>]
16
+ attr_reader :changes
17
+
18
+ # @param filename [String] The file to update.
19
+ # @param version [Integer] A version number associated with this update.
20
+ # @param changes [Array<Solargraph::Source::Change>] The changes.
21
+ def initialize filename, version, changes
22
+ @filename = filename
23
+ @version = version
24
+ @changes = changes
25
+ @input = nil
26
+ @did_nullify = nil
27
+ @output = nil
28
+ end
29
+
30
+ # @param text [String]
31
+ # @param nullable [Boolean]
32
+ # @return [String]
33
+ def write text, nullable = false
34
+ can_nullify = (nullable and changes.length == 1)
35
+ return @output if @input == text and can_nullify == @did_nullify
36
+ @input = text
37
+ @output = text
38
+ @did_nullify = can_nullify
39
+ changes.each do |ch|
40
+ @output = ch.write(@output, can_nullify)
41
+ end
42
+ @output
43
+ end
44
+
45
+ # @param text [String]
46
+ # @return [String]
47
+ def repair text
48
+ changes.each do |ch|
49
+ text = ch.repair(text)
50
+ end
51
+ text
52
+ end
53
+ end
54
+ end
55
+ end