solargraph 0.54.4 → 0.58.3

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 (238) 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 +185 -6
  5. data/.github/workflows/rspec.yml +55 -5
  6. data/.github/workflows/typecheck.yml +8 -3
  7. data/.gitignore +8 -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 +143 -0
  14. data/README.md +20 -6
  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 -167
  20. data/lib/solargraph/api_map/source_to_yard.rb +97 -88
  21. data/lib/solargraph/api_map/store.rb +384 -241
  22. data/lib/solargraph/api_map.rb +945 -875
  23. data/lib/solargraph/bench.rb +45 -28
  24. data/lib/solargraph/complex_type/type_methods.rb +228 -217
  25. data/lib/solargraph/complex_type/unique_type.rb +482 -386
  26. data/lib/solargraph/complex_type.rb +444 -394
  27. data/lib/solargraph/convention/active_support_concern.rb +111 -0
  28. data/lib/solargraph/convention/base.rb +20 -3
  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/gemfile.rb +15 -15
  33. data/lib/solargraph/convention/gemspec.rb +23 -22
  34. data/lib/solargraph/convention/rakefile.rb +17 -17
  35. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +61 -0
  36. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +102 -0
  37. data/lib/solargraph/convention/struct_definition.rb +164 -0
  38. data/lib/solargraph/convention.rb +78 -47
  39. data/lib/solargraph/converters/dd.rb +17 -17
  40. data/lib/solargraph/converters/dl.rb +15 -15
  41. data/lib/solargraph/converters/dt.rb +15 -15
  42. data/lib/solargraph/converters/misc.rb +1 -1
  43. data/lib/solargraph/diagnostics/require_not_found.rb +53 -53
  44. data/lib/solargraph/diagnostics/rubocop.rb +118 -113
  45. data/lib/solargraph/diagnostics/rubocop_helpers.rb +68 -66
  46. data/lib/solargraph/diagnostics/type_check.rb +55 -55
  47. data/lib/solargraph/diagnostics/update_errors.rb +41 -41
  48. data/lib/solargraph/doc_map.rb +439 -188
  49. data/lib/solargraph/environ.rb +9 -2
  50. data/lib/solargraph/equality.rb +34 -33
  51. data/lib/solargraph/gem_pins.rb +98 -72
  52. data/lib/solargraph/language_server/error_codes.rb +20 -20
  53. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  54. data/lib/solargraph/language_server/host/dispatch.rb +130 -128
  55. data/lib/solargraph/language_server/host/message_worker.rb +112 -106
  56. data/lib/solargraph/language_server/host/sources.rb +99 -99
  57. data/lib/solargraph/language_server/host.rb +878 -861
  58. data/lib/solargraph/language_server/message/base.rb +97 -96
  59. data/lib/solargraph/language_server/message/client/register_capability.rb +15 -15
  60. data/lib/solargraph/language_server/message/completion_item/resolve.rb +60 -60
  61. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +114 -112
  62. data/lib/solargraph/language_server/message/extended/document.rb +23 -20
  63. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
  64. data/lib/solargraph/language_server/message/extended/download_core.rb +19 -19
  65. data/lib/solargraph/language_server/message/extended/search.rb +20 -20
  66. data/lib/solargraph/language_server/message/initialize.rb +191 -191
  67. data/lib/solargraph/language_server/message/text_document/completion.rb +56 -56
  68. data/lib/solargraph/language_server/message/text_document/definition.rb +40 -38
  69. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +16 -16
  70. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +26 -26
  71. data/lib/solargraph/language_server/message/text_document/formatting.rb +148 -131
  72. data/lib/solargraph/language_server/message/text_document/hover.rb +58 -58
  73. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +11 -11
  74. data/lib/solargraph/language_server/message/text_document/references.rb +16 -16
  75. data/lib/solargraph/language_server/message/text_document/rename.rb +19 -19
  76. data/lib/solargraph/language_server/message/text_document/signature_help.rb +24 -24
  77. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -24
  78. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +35 -35
  79. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +40 -40
  80. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +26 -24
  81. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -23
  82. data/lib/solargraph/language_server/message.rb +94 -94
  83. data/lib/solargraph/language_server/progress.rb +8 -0
  84. data/lib/solargraph/language_server/request.rb +27 -24
  85. data/lib/solargraph/language_server/transport/data_reader.rb +74 -74
  86. data/lib/solargraph/language_server/uri_helpers.rb +49 -49
  87. data/lib/solargraph/library.rb +683 -662
  88. data/lib/solargraph/location.rb +82 -58
  89. data/lib/solargraph/logging.rb +37 -27
  90. data/lib/solargraph/page.rb +92 -89
  91. data/lib/solargraph/parser/comment_ripper.rb +69 -56
  92. data/lib/solargraph/parser/flow_sensitive_typing.rb +255 -0
  93. data/lib/solargraph/parser/node_processor/base.rb +92 -87
  94. data/lib/solargraph/parser/node_processor.rb +62 -45
  95. data/lib/solargraph/parser/parser_gem/class_methods.rb +149 -157
  96. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +19 -18
  97. data/lib/solargraph/parser/parser_gem/node_chainer.rb +166 -164
  98. data/lib/solargraph/parser/parser_gem/node_methods.rb +486 -495
  99. data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +2 -1
  100. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -0
  101. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +59 -57
  102. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +15 -15
  103. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +46 -43
  104. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +2 -1
  105. data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +2 -1
  106. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +53 -50
  107. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +37 -36
  108. data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +2 -1
  109. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +23 -0
  110. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +40 -38
  111. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +29 -28
  112. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +59 -53
  113. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +8 -7
  114. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -0
  115. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -16
  116. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +38 -36
  117. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +52 -42
  118. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +291 -259
  119. data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +3 -1
  120. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -0
  121. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +29 -0
  122. data/lib/solargraph/parser/parser_gem/node_processors.rb +70 -56
  123. data/lib/solargraph/parser/parser_gem.rb +12 -12
  124. data/lib/solargraph/parser/region.rb +69 -66
  125. data/lib/solargraph/parser/snippet.rb +17 -15
  126. data/lib/solargraph/parser.rb +23 -22
  127. data/lib/solargraph/pin/base.rb +729 -378
  128. data/lib/solargraph/pin/base_variable.rb +126 -118
  129. data/lib/solargraph/pin/block.rb +104 -101
  130. data/lib/solargraph/pin/breakable.rb +9 -0
  131. data/lib/solargraph/pin/callable.rb +231 -147
  132. data/lib/solargraph/pin/closure.rb +72 -57
  133. data/lib/solargraph/pin/common.rb +79 -70
  134. data/lib/solargraph/pin/constant.rb +45 -43
  135. data/lib/solargraph/pin/conversions.rb +123 -123
  136. data/lib/solargraph/pin/delegated_method.rb +120 -101
  137. data/lib/solargraph/pin/documenting.rb +114 -98
  138. data/lib/solargraph/pin/instance_variable.rb +34 -34
  139. data/lib/solargraph/pin/keyword.rb +20 -15
  140. data/lib/solargraph/pin/local_variable.rb +75 -67
  141. data/lib/solargraph/pin/method.rb +672 -527
  142. data/lib/solargraph/pin/method_alias.rb +34 -31
  143. data/lib/solargraph/pin/namespace.rb +115 -107
  144. data/lib/solargraph/pin/parameter.rb +275 -212
  145. data/lib/solargraph/pin/proxy_type.rb +39 -29
  146. data/lib/solargraph/pin/reference/override.rb +47 -29
  147. data/lib/solargraph/pin/reference/require.rb +2 -2
  148. data/lib/solargraph/pin/reference/superclass.rb +15 -10
  149. data/lib/solargraph/pin/reference.rb +39 -22
  150. data/lib/solargraph/pin/search.rb +61 -56
  151. data/lib/solargraph/pin/signature.rb +61 -17
  152. data/lib/solargraph/pin/singleton.rb +1 -1
  153. data/lib/solargraph/pin/symbol.rb +53 -47
  154. data/lib/solargraph/pin/until.rb +18 -0
  155. data/lib/solargraph/pin/while.rb +18 -0
  156. data/lib/solargraph/pin.rb +44 -41
  157. data/lib/solargraph/pin_cache.rb +245 -0
  158. data/lib/solargraph/position.rb +132 -107
  159. data/lib/solargraph/range.rb +112 -98
  160. data/lib/solargraph/rbs_map/conversions.rb +823 -646
  161. data/lib/solargraph/rbs_map/core_fills.rb +84 -50
  162. data/lib/solargraph/rbs_map/core_map.rb +58 -28
  163. data/lib/solargraph/rbs_map/stdlib_map.rb +43 -33
  164. data/lib/solargraph/rbs_map.rb +163 -93
  165. data/lib/solargraph/server_methods.rb +16 -16
  166. data/lib/solargraph/shell.rb +363 -269
  167. data/lib/solargraph/source/chain/array.rb +37 -33
  168. data/lib/solargraph/source/chain/block_symbol.rb +1 -1
  169. data/lib/solargraph/source/chain/block_variable.rb +1 -1
  170. data/lib/solargraph/source/chain/call.rb +337 -303
  171. data/lib/solargraph/source/chain/class_variable.rb +13 -13
  172. data/lib/solargraph/source/chain/constant.rb +26 -89
  173. data/lib/solargraph/source/chain/global_variable.rb +13 -13
  174. data/lib/solargraph/source/chain/hash.rb +34 -33
  175. data/lib/solargraph/source/chain/head.rb +1 -1
  176. data/lib/solargraph/source/chain/if.rb +28 -28
  177. data/lib/solargraph/source/chain/instance_variable.rb +13 -13
  178. data/lib/solargraph/source/chain/link.rb +109 -98
  179. data/lib/solargraph/source/chain/literal.rb +48 -28
  180. data/lib/solargraph/source/chain/or.rb +23 -23
  181. data/lib/solargraph/source/chain/q_call.rb +11 -11
  182. data/lib/solargraph/source/chain/variable.rb +13 -13
  183. data/lib/solargraph/source/chain/z_super.rb +30 -30
  184. data/lib/solargraph/source/chain.rb +291 -252
  185. data/lib/solargraph/source/change.rb +82 -82
  186. data/lib/solargraph/source/cursor.rb +166 -167
  187. data/lib/solargraph/source/encoding_fixes.rb +23 -23
  188. data/lib/solargraph/source/source_chainer.rb +194 -194
  189. data/lib/solargraph/source/updater.rb +55 -55
  190. data/lib/solargraph/source.rb +498 -495
  191. data/lib/solargraph/source_map/clip.rb +226 -232
  192. data/lib/solargraph/source_map/data.rb +34 -30
  193. data/lib/solargraph/source_map/mapper.rb +259 -255
  194. data/lib/solargraph/source_map.rb +212 -217
  195. data/lib/solargraph/type_checker/checks.rb +124 -120
  196. data/lib/solargraph/type_checker/param_def.rb +37 -35
  197. data/lib/solargraph/type_checker/problem.rb +32 -32
  198. data/lib/solargraph/type_checker/rules.rb +84 -62
  199. data/lib/solargraph/type_checker.rb +814 -672
  200. data/lib/solargraph/version.rb +5 -5
  201. data/lib/solargraph/views/_method.erb +10 -10
  202. data/lib/solargraph/views/_namespace.erb +3 -3
  203. data/lib/solargraph/views/document.erb +10 -10
  204. data/lib/solargraph/workspace/config.rb +255 -239
  205. data/lib/solargraph/workspace/require_paths.rb +97 -0
  206. data/lib/solargraph/workspace.rb +220 -239
  207. data/lib/solargraph/yard_map/helpers.rb +44 -16
  208. data/lib/solargraph/yard_map/mapper/to_constant.rb +7 -5
  209. data/lib/solargraph/yard_map/mapper/to_method.rb +130 -94
  210. data/lib/solargraph/yard_map/mapper/to_namespace.rb +31 -28
  211. data/lib/solargraph/yard_map/mapper.rb +79 -78
  212. data/lib/solargraph/yard_map/to_method.rb +89 -86
  213. data/lib/solargraph/yard_tags.rb +20 -20
  214. data/lib/solargraph/yardoc.rb +87 -52
  215. data/lib/solargraph.rb +105 -72
  216. data/rbs/fills/bundler/0/bundler.rbs +4271 -0
  217. data/rbs/fills/open3/0/open3.rbs +172 -0
  218. data/rbs/fills/rubygems/0/basic_specification.rbs +326 -0
  219. data/rbs/fills/rubygems/0/errors.rbs +364 -0
  220. data/rbs/fills/rubygems/0/spec_fetcher.rbs +107 -0
  221. data/rbs/fills/rubygems/0/specification.rbs +1753 -0
  222. data/rbs/fills/tuple/tuple.rbs +149 -0
  223. data/rbs/shims/ast/0/node.rbs +5 -0
  224. data/rbs/shims/ast/2.4/.rbs_meta.yaml +9 -0
  225. data/rbs/shims/ast/2.4/ast.rbs +73 -0
  226. data/rbs/shims/parser/3.2.0.1/builders/default.rbs +195 -0
  227. data/rbs/shims/parser/3.2.0.1/manifest.yaml +7 -0
  228. data/rbs/shims/parser/3.2.0.1/parser.rbs +201 -0
  229. data/rbs/shims/parser/3.2.0.1/polyfill.rbs +4 -0
  230. data/rbs/shims/thor/1.2.0.1/.rbs_meta.yaml +9 -0
  231. data/rbs/shims/thor/1.2.0.1/manifest.yaml +7 -0
  232. data/rbs/shims/thor/1.2.0.1/thor.rbs +17 -0
  233. data/rbs_collection.yaml +19 -0
  234. data/solargraph.gemspec +27 -5
  235. metadata +215 -18
  236. data/lib/.rubocop.yml +0 -22
  237. data/lib/solargraph/cache.rb +0 -77
  238. data/lib/solargraph/parser/node_methods.rb +0 -83
@@ -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'), Chain::UNDEFINED_CALL]) if phrase =~ /^[0-9]+\.$/
36
- return Chain.new([Chain::Literal.new('Symbol')]) 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