jimeh-solargraph 0.40.4.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 (252) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ci.yml +54 -0
  3. data/.gitignore +9 -0
  4. data/.rspec +2 -0
  5. data/.travis.yml +24 -0
  6. data/.yardopts +2 -0
  7. data/CHANGELOG.md +1003 -0
  8. data/Gemfile +7 -0
  9. data/LICENSE +21 -0
  10. data/README.md +123 -0
  11. data/Rakefile +25 -0
  12. data/SPONSORS.md +15 -0
  13. data/bin/solargraph +5 -0
  14. data/jimeh-solargraph.gemspec +44 -0
  15. data/lib/.rubocop.yml +21 -0
  16. data/lib/solargraph.rb +67 -0
  17. data/lib/solargraph/api_map.rb +752 -0
  18. data/lib/solargraph/api_map/bundler_methods.rb +27 -0
  19. data/lib/solargraph/api_map/cache.rb +70 -0
  20. data/lib/solargraph/api_map/source_to_yard.rb +81 -0
  21. data/lib/solargraph/api_map/store.rb +256 -0
  22. data/lib/solargraph/bench.rb +30 -0
  23. data/lib/solargraph/compat.rb +23 -0
  24. data/lib/solargraph/complex_type.rb +213 -0
  25. data/lib/solargraph/complex_type/type_methods.rb +127 -0
  26. data/lib/solargraph/complex_type/unique_type.rb +75 -0
  27. data/lib/solargraph/convention.rb +47 -0
  28. data/lib/solargraph/convention/base.rb +33 -0
  29. data/lib/solargraph/convention/gemfile.rb +15 -0
  30. data/lib/solargraph/convention/gemspec.rb +22 -0
  31. data/lib/solargraph/convention/rspec.rb +21 -0
  32. data/lib/solargraph/converters/dd.rb +12 -0
  33. data/lib/solargraph/converters/dl.rb +12 -0
  34. data/lib/solargraph/converters/dt.rb +12 -0
  35. data/lib/solargraph/converters/misc.rb +1 -0
  36. data/lib/solargraph/diagnostics.rb +55 -0
  37. data/lib/solargraph/diagnostics/base.rb +29 -0
  38. data/lib/solargraph/diagnostics/require_not_found.rb +37 -0
  39. data/lib/solargraph/diagnostics/rubocop.rb +90 -0
  40. data/lib/solargraph/diagnostics/rubocop_helpers.rb +45 -0
  41. data/lib/solargraph/diagnostics/severities.rb +15 -0
  42. data/lib/solargraph/diagnostics/type_check.rb +54 -0
  43. data/lib/solargraph/diagnostics/update_errors.rb +41 -0
  44. data/lib/solargraph/documentor.rb +78 -0
  45. data/lib/solargraph/environ.rb +45 -0
  46. data/lib/solargraph/language_server.rb +19 -0
  47. data/lib/solargraph/language_server/completion_item_kinds.rb +35 -0
  48. data/lib/solargraph/language_server/error_codes.rb +20 -0
  49. data/lib/solargraph/language_server/host.rb +746 -0
  50. data/lib/solargraph/language_server/host/cataloger.rb +56 -0
  51. data/lib/solargraph/language_server/host/diagnoser.rb +81 -0
  52. data/lib/solargraph/language_server/host/dispatch.rb +112 -0
  53. data/lib/solargraph/language_server/host/sources.rb +156 -0
  54. data/lib/solargraph/language_server/message.rb +92 -0
  55. data/lib/solargraph/language_server/message/base.rb +85 -0
  56. data/lib/solargraph/language_server/message/cancel_request.rb +13 -0
  57. data/lib/solargraph/language_server/message/client.rb +11 -0
  58. data/lib/solargraph/language_server/message/client/register_capability.rb +15 -0
  59. data/lib/solargraph/language_server/message/completion_item.rb +11 -0
  60. data/lib/solargraph/language_server/message/completion_item/resolve.rb +57 -0
  61. data/lib/solargraph/language_server/message/exit_notification.rb +13 -0
  62. data/lib/solargraph/language_server/message/extended.rb +21 -0
  63. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +100 -0
  64. data/lib/solargraph/language_server/message/extended/document.rb +20 -0
  65. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -0
  66. data/lib/solargraph/language_server/message/extended/download_core.rb +23 -0
  67. data/lib/solargraph/language_server/message/extended/environment.rb +25 -0
  68. data/lib/solargraph/language_server/message/extended/search.rb +20 -0
  69. data/lib/solargraph/language_server/message/initialize.rb +153 -0
  70. data/lib/solargraph/language_server/message/initialized.rb +26 -0
  71. data/lib/solargraph/language_server/message/method_not_found.rb +16 -0
  72. data/lib/solargraph/language_server/message/method_not_implemented.rb +14 -0
  73. data/lib/solargraph/language_server/message/shutdown.rb +13 -0
  74. data/lib/solargraph/language_server/message/text_document.rb +28 -0
  75. data/lib/solargraph/language_server/message/text_document/base.rb +19 -0
  76. data/lib/solargraph/language_server/message/text_document/code_action.rb +17 -0
  77. data/lib/solargraph/language_server/message/text_document/completion.rb +57 -0
  78. data/lib/solargraph/language_server/message/text_document/definition.rb +38 -0
  79. data/lib/solargraph/language_server/message/text_document/did_change.rb +15 -0
  80. data/lib/solargraph/language_server/message/text_document/did_close.rb +15 -0
  81. data/lib/solargraph/language_server/message/text_document/did_open.rb +15 -0
  82. data/lib/solargraph/language_server/message/text_document/did_save.rb +17 -0
  83. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +23 -0
  84. data/lib/solargraph/language_server/message/text_document/folding_range.rb +26 -0
  85. data/lib/solargraph/language_server/message/text_document/formatting.rb +105 -0
  86. data/lib/solargraph/language_server/message/text_document/hover.rb +44 -0
  87. data/lib/solargraph/language_server/message/text_document/on_type_formatting.rb +34 -0
  88. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +11 -0
  89. data/lib/solargraph/language_server/message/text_document/references.rb +16 -0
  90. data/lib/solargraph/language_server/message/text_document/rename.rb +19 -0
  91. data/lib/solargraph/language_server/message/text_document/signature_help.rb +29 -0
  92. data/lib/solargraph/language_server/message/workspace.rb +14 -0
  93. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +29 -0
  94. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +33 -0
  95. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +24 -0
  96. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -0
  97. data/lib/solargraph/language_server/message_types.rb +14 -0
  98. data/lib/solargraph/language_server/request.rb +24 -0
  99. data/lib/solargraph/language_server/symbol_kinds.rb +36 -0
  100. data/lib/solargraph/language_server/transport.rb +13 -0
  101. data/lib/solargraph/language_server/transport/adapter.rb +56 -0
  102. data/lib/solargraph/language_server/transport/data_reader.rb +72 -0
  103. data/lib/solargraph/language_server/uri_helpers.rb +49 -0
  104. data/lib/solargraph/library.rb +426 -0
  105. data/lib/solargraph/location.rb +37 -0
  106. data/lib/solargraph/logging.rb +27 -0
  107. data/lib/solargraph/page.rb +83 -0
  108. data/lib/solargraph/parser.rb +26 -0
  109. data/lib/solargraph/parser/comment_ripper.rb +52 -0
  110. data/lib/solargraph/parser/legacy.rb +12 -0
  111. data/lib/solargraph/parser/legacy/class_methods.rb +109 -0
  112. data/lib/solargraph/parser/legacy/flawed_builder.rb +16 -0
  113. data/lib/solargraph/parser/legacy/node_chainer.rb +118 -0
  114. data/lib/solargraph/parser/legacy/node_methods.rb +311 -0
  115. data/lib/solargraph/parser/legacy/node_processors.rb +54 -0
  116. data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +23 -0
  117. data/lib/solargraph/parser/legacy/node_processors/args_node.rb +35 -0
  118. data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +15 -0
  119. data/lib/solargraph/parser/legacy/node_processors/block_node.rb +22 -0
  120. data/lib/solargraph/parser/legacy/node_processors/casgn_node.rb +25 -0
  121. data/lib/solargraph/parser/legacy/node_processors/cvasgn_node.rb +23 -0
  122. data/lib/solargraph/parser/legacy/node_processors/def_node.rb +63 -0
  123. data/lib/solargraph/parser/legacy/node_processors/defs_node.rb +36 -0
  124. data/lib/solargraph/parser/legacy/node_processors/gvasgn_node.rb +23 -0
  125. data/lib/solargraph/parser/legacy/node_processors/ivasgn_node.rb +38 -0
  126. data/lib/solargraph/parser/legacy/node_processors/lvasgn_node.rb +28 -0
  127. data/lib/solargraph/parser/legacy/node_processors/namespace_node.rb +39 -0
  128. data/lib/solargraph/parser/legacy/node_processors/orasgn_node.rb +16 -0
  129. data/lib/solargraph/parser/legacy/node_processors/resbody_node.rb +36 -0
  130. data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +21 -0
  131. data/lib/solargraph/parser/legacy/node_processors/send_node.rb +257 -0
  132. data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +18 -0
  133. data/lib/solargraph/parser/node_methods.rb +43 -0
  134. data/lib/solargraph/parser/node_processor.rb +43 -0
  135. data/lib/solargraph/parser/node_processor/base.rb +80 -0
  136. data/lib/solargraph/parser/region.rb +66 -0
  137. data/lib/solargraph/parser/rubyvm.rb +40 -0
  138. data/lib/solargraph/parser/rubyvm/class_methods.rb +150 -0
  139. data/lib/solargraph/parser/rubyvm/node_chainer.rb +135 -0
  140. data/lib/solargraph/parser/rubyvm/node_methods.rb +301 -0
  141. data/lib/solargraph/parser/rubyvm/node_processors.rb +62 -0
  142. data/lib/solargraph/parser/rubyvm/node_processors/alias_node.rb +23 -0
  143. data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +86 -0
  144. data/lib/solargraph/parser/rubyvm/node_processors/begin_node.rb +15 -0
  145. data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +22 -0
  146. data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +22 -0
  147. data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +23 -0
  148. data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +64 -0
  149. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +57 -0
  150. data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +23 -0
  151. data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +38 -0
  152. data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +39 -0
  153. data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +20 -0
  154. data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +27 -0
  155. data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +39 -0
  156. data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +26 -0
  157. data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +15 -0
  158. data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +45 -0
  159. data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +21 -0
  160. data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +15 -0
  161. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +277 -0
  162. data/lib/solargraph/parser/rubyvm/node_processors/sym_node.rb +18 -0
  163. data/lib/solargraph/parser/snippet.rb +13 -0
  164. data/lib/solargraph/pin.rb +36 -0
  165. data/lib/solargraph/pin/base.rb +296 -0
  166. data/lib/solargraph/pin/base_variable.rb +84 -0
  167. data/lib/solargraph/pin/block.rb +62 -0
  168. data/lib/solargraph/pin/class_variable.rb +8 -0
  169. data/lib/solargraph/pin/closure.rb +37 -0
  170. data/lib/solargraph/pin/common.rb +70 -0
  171. data/lib/solargraph/pin/constant.rb +43 -0
  172. data/lib/solargraph/pin/conversions.rb +96 -0
  173. data/lib/solargraph/pin/documenting.rb +105 -0
  174. data/lib/solargraph/pin/duck_method.rb +16 -0
  175. data/lib/solargraph/pin/global_variable.rb +8 -0
  176. data/lib/solargraph/pin/instance_variable.rb +30 -0
  177. data/lib/solargraph/pin/keyword.rb +15 -0
  178. data/lib/solargraph/pin/keyword_param.rb +8 -0
  179. data/lib/solargraph/pin/local_variable.rb +21 -0
  180. data/lib/solargraph/pin/localized.rb +43 -0
  181. data/lib/solargraph/pin/method.rb +245 -0
  182. data/lib/solargraph/pin/method_alias.rb +31 -0
  183. data/lib/solargraph/pin/namespace.rb +85 -0
  184. data/lib/solargraph/pin/parameter.rb +206 -0
  185. data/lib/solargraph/pin/proxy_type.rb +29 -0
  186. data/lib/solargraph/pin/reference.rb +14 -0
  187. data/lib/solargraph/pin/reference/extend.rb +10 -0
  188. data/lib/solargraph/pin/reference/include.rb +10 -0
  189. data/lib/solargraph/pin/reference/override.rb +29 -0
  190. data/lib/solargraph/pin/reference/prepend.rb +10 -0
  191. data/lib/solargraph/pin/reference/require.rb +14 -0
  192. data/lib/solargraph/pin/reference/superclass.rb +10 -0
  193. data/lib/solargraph/pin/singleton.rb +11 -0
  194. data/lib/solargraph/pin/symbol.rb +47 -0
  195. data/lib/solargraph/position.rb +100 -0
  196. data/lib/solargraph/range.rb +95 -0
  197. data/lib/solargraph/server_methods.rb +16 -0
  198. data/lib/solargraph/shell.rb +222 -0
  199. data/lib/solargraph/source.rb +537 -0
  200. data/lib/solargraph/source/chain.rb +154 -0
  201. data/lib/solargraph/source/chain/block_variable.rb +13 -0
  202. data/lib/solargraph/source/chain/call.rb +203 -0
  203. data/lib/solargraph/source/chain/class_variable.rb +13 -0
  204. data/lib/solargraph/source/chain/constant.rb +75 -0
  205. data/lib/solargraph/source/chain/global_variable.rb +13 -0
  206. data/lib/solargraph/source/chain/head.rb +35 -0
  207. data/lib/solargraph/source/chain/instance_variable.rb +13 -0
  208. data/lib/solargraph/source/chain/link.rb +67 -0
  209. data/lib/solargraph/source/chain/literal.rb +23 -0
  210. data/lib/solargraph/source/chain/or.rb +23 -0
  211. data/lib/solargraph/source/chain/variable.rb +13 -0
  212. data/lib/solargraph/source/chain/z_super.rb +30 -0
  213. data/lib/solargraph/source/change.rb +79 -0
  214. data/lib/solargraph/source/cursor.rb +164 -0
  215. data/lib/solargraph/source/encoding_fixes.rb +23 -0
  216. data/lib/solargraph/source/source_chainer.rb +190 -0
  217. data/lib/solargraph/source/updater.rb +54 -0
  218. data/lib/solargraph/source_map.rb +188 -0
  219. data/lib/solargraph/source_map/clip.rb +224 -0
  220. data/lib/solargraph/source_map/completion.rb +23 -0
  221. data/lib/solargraph/source_map/mapper.rb +215 -0
  222. data/lib/solargraph/type_checker.rb +503 -0
  223. data/lib/solargraph/type_checker/checks.rb +99 -0
  224. data/lib/solargraph/type_checker/param_def.rb +35 -0
  225. data/lib/solargraph/type_checker/problem.rb +32 -0
  226. data/lib/solargraph/type_checker/rules.rb +57 -0
  227. data/lib/solargraph/version.rb +5 -0
  228. data/lib/solargraph/views/_method.erb +62 -0
  229. data/lib/solargraph/views/_name_type_tag.erb +10 -0
  230. data/lib/solargraph/views/_namespace.erb +24 -0
  231. data/lib/solargraph/views/document.erb +23 -0
  232. data/lib/solargraph/views/environment.erb +58 -0
  233. data/lib/solargraph/views/layout.erb +44 -0
  234. data/lib/solargraph/views/search.erb +11 -0
  235. data/lib/solargraph/workspace.rb +209 -0
  236. data/lib/solargraph/workspace/config.rb +230 -0
  237. data/lib/solargraph/yard_map.rb +435 -0
  238. data/lib/solargraph/yard_map/cache.rb +19 -0
  239. data/lib/solargraph/yard_map/core_docs.rb +170 -0
  240. data/lib/solargraph/yard_map/core_fills.rb +185 -0
  241. data/lib/solargraph/yard_map/core_gen.rb +76 -0
  242. data/lib/solargraph/yard_map/helpers.rb +16 -0
  243. data/lib/solargraph/yard_map/mapper.rb +77 -0
  244. data/lib/solargraph/yard_map/mapper/to_constant.rb +25 -0
  245. data/lib/solargraph/yard_map/mapper/to_method.rb +78 -0
  246. data/lib/solargraph/yard_map/mapper/to_namespace.rb +27 -0
  247. data/lib/solargraph/yard_map/rdoc_to_yard.rb +140 -0
  248. data/lib/solargraph/yard_map/stdlib_fills.rb +43 -0
  249. data/lib/solargraph/yard_map/to_method.rb +79 -0
  250. data/lib/yard-solargraph.rb +30 -0
  251. data/yardoc/2.2.2.tar.gz +0 -0
  252. metadata +564 -0
@@ -0,0 +1,23 @@
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
@@ -0,0 +1,190 @@
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]
18
+ # @return [Source::Chain]
19
+ def chain source, position
20
+ new(source, 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
+ begin
38
+ return Chain.new([]) if phrase.end_with?('..')
39
+ node = nil
40
+ parent = nil
41
+ if !source.repaired? && source.parsed? && source.synchronized?
42
+ tree = source.tree_at(position.line, position.column)
43
+ # node, parent = source.tree_at(position.line, position.column)[0..2]
44
+ tree.shift while tree.length > 1 && tree.first.type == :SCOPE
45
+ node, parent = tree[0..2]
46
+ elsif source.parsed? && source.repaired? && end_of_phrase == '.'
47
+ node, parent = source.tree_at(fixed_position.line, fixed_position.column)[0..2]
48
+ node = Parser.parse(fixed_phrase) if node.nil?
49
+ else
50
+ 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)}
51
+ # Exception for positions that chain literal nodes in unsynchronized sources
52
+ node = nil unless source.synchronized? || !Parser.infer_literal_node_type(node).nil?
53
+ node = Parser.parse(fixed_phrase) if node.nil?
54
+ end
55
+ rescue Parser::SyntaxError
56
+ return Chain.new([Chain::UNDEFINED_CALL])
57
+ end
58
+ return Chain.new([Chain::UNDEFINED_CALL]) if node.nil? || (node.type == :sym && !phrase.start_with?(':'))
59
+ # chain = NodeChainer.chain(node, source.filename, parent && parent.type == :block)
60
+ chain = Parser.chain(node, source.filename, parent && [:ITER, :block].include?(parent.type))
61
+ if source.repaired? || !source.parsed? || !source.synchronized?
62
+ if end_of_phrase.strip == '.'
63
+ chain.links.push Chain::UNDEFINED_CALL
64
+ elsif end_of_phrase.strip == '::'
65
+ chain.links.push Chain::UNDEFINED_CONSTANT
66
+ end
67
+ elsif chain.links.last.is_a?(Source::Chain::Constant) && end_of_phrase.strip == '::' && !source.code[Position.to_offset(source.code, position)].match?(/[a-z]/i)
68
+ chain.links.push Source::Chain::UNDEFINED_CONSTANT
69
+ end
70
+ chain
71
+ end
72
+
73
+ private
74
+
75
+ # @return [Position]
76
+ attr_reader :position
77
+
78
+ # @return [Solargraph::Source]
79
+ attr_reader :source
80
+
81
+ # @return [String]
82
+ def phrase
83
+ @phrase ||= source.code[signature_data..offset-1]
84
+ end
85
+
86
+ # @return [String]
87
+ def fixed_phrase
88
+ @fixed_phrase ||= phrase[0..-(end_of_phrase.length+1)]
89
+ end
90
+
91
+ # @return [Position]
92
+ def fixed_position
93
+ @fixed_position ||= Position.from_offset(source.code, offset - end_of_phrase.length)
94
+ end
95
+
96
+ # @return [String]
97
+ def end_of_phrase
98
+ @end_of_phrase ||= begin
99
+ match = phrase.match(/[\s]*(\.{1}|::)[\s]*$/)
100
+ if match
101
+ match[0]
102
+ else
103
+ ''
104
+ end
105
+ end
106
+ end
107
+
108
+ # True if the current offset is inside a string.
109
+ #
110
+ # @return [Boolean]
111
+ def string?
112
+ # @string ||= (node.type == :str or node.type == :dstr)
113
+ @string ||= @source.string_at?(position)
114
+ end
115
+
116
+ # @return [Integer]
117
+ def offset
118
+ @offset ||= get_offset(position.line, position.column)
119
+ end
120
+
121
+ # @param line [Integer]
122
+ # @param column [Integer]
123
+ # @return [Integer]
124
+ def get_offset line, column
125
+ Position.line_char_to_offset(@source.code, line, column)
126
+ end
127
+
128
+ def signature_data
129
+ @signature_data ||= get_signature_data_at(offset)
130
+ end
131
+
132
+ def get_signature_data_at index
133
+ brackets = 0
134
+ squares = 0
135
+ parens = 0
136
+ index -=1
137
+ in_whitespace = false
138
+ while index >= 0
139
+ pos = Position.from_offset(@source.code, index)
140
+ break if index > 0 and @source.comment_at?(pos)
141
+ break if brackets > 0 or parens > 0 or squares > 0
142
+ char = @source.code[index, 1]
143
+ break if char.nil? # @todo Is this the right way to handle this?
144
+ if brackets.zero? and parens.zero? and squares.zero? and [' ', "\r", "\n", "\t"].include?(char)
145
+ in_whitespace = true
146
+ else
147
+ if brackets.zero? and parens.zero? and squares.zero? and in_whitespace
148
+ unless char == '.' or @source.code[index+1..-1].strip.start_with?('.')
149
+ old = @source.code[index+1..-1]
150
+ nxt = @source.code[index+1..-1].lstrip
151
+ index += (@source.code[index+1..-1].length - @source.code[index+1..-1].lstrip.length)
152
+ break
153
+ end
154
+ end
155
+ if char == ')'
156
+ parens -=1
157
+ elsif char == ']'
158
+ squares -=1
159
+ elsif char == '}'
160
+ brackets -= 1
161
+ elsif char == '('
162
+ parens += 1
163
+ elsif char == '{'
164
+ brackets += 1
165
+ elsif char == '['
166
+ squares += 1
167
+ end
168
+ if brackets.zero? and parens.zero? and squares.zero?
169
+ break if ['"', "'", ',', ';', '%'].include?(char)
170
+ break if ['!', '?'].include?(char) && index < offset - 1
171
+ break if char == '$'
172
+ if char == '@'
173
+ index -= 1
174
+ if @source.code[index, 1] == '@'
175
+ index -= 1
176
+ end
177
+ break
178
+ end
179
+ elsif parens == 1 || brackets == 1 || squares == 1
180
+ break
181
+ end
182
+ in_whitespace = false
183
+ end
184
+ index -= 1
185
+ end
186
+ index + 1
187
+ end
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,54 @@
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
+ # @return [String]
46
+ def repair text
47
+ changes.each do |ch|
48
+ text = ch.repair(text)
49
+ end
50
+ text
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,188 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jaro_winkler'
4
+ require 'yard'
5
+ require 'yard-solargraph'
6
+ require 'set'
7
+
8
+ module Solargraph
9
+ # An index of pins and other ApiMap-related data for a Source.
10
+ #
11
+ class SourceMap
12
+ autoload :Mapper, 'solargraph/source_map/mapper'
13
+ autoload :Clip, 'solargraph/source_map/clip'
14
+ autoload :Completion, 'solargraph/source_map/completion'
15
+
16
+ # @return [Source]
17
+ attr_reader :source
18
+
19
+ # @return [Array<Pin::Base>]
20
+ attr_reader :pins
21
+
22
+ # @return [Array<Pin::Base>]
23
+ attr_reader :locals
24
+
25
+ # @param source [Source]
26
+ # @param pins [Array<Pin::Base>]
27
+ # @param locals [Array<Pin::Base>]
28
+ def initialize source, pins, locals
29
+ # HACK: Keep the library from changing this
30
+ @source = source.dup
31
+ @pins = pins
32
+ @locals = locals
33
+ environ.merge Convention.for_local(self) unless filename.nil?
34
+ @pin_class_hash = pins.to_set.classify(&:class).transform_values(&:to_a)
35
+ @pin_select_cache = {}
36
+ end
37
+
38
+ def pins_by_class klass
39
+ @pin_select_cache[klass] ||= @pin_class_hash.select { |key, _| key <= klass }.values.flatten
40
+ end
41
+
42
+ def rebindable_method_names
43
+ @rebindable_method_names ||= pins_by_class(Pin::Method)
44
+ .select { |pin| pin.comments && pin.comments.include?('@yieldself') }
45
+ .map(&:name)
46
+ .to_set
47
+ end
48
+
49
+ # @return [String]
50
+ def filename
51
+ source.filename
52
+ end
53
+
54
+ # @return [String]
55
+ def code
56
+ source.code
57
+ end
58
+
59
+ # @return [Array<Pin::Reference::Require>]
60
+ def requires
61
+ pins_by_class(Pin::Reference::Require)
62
+ end
63
+
64
+ # @return [Environ]
65
+ def environ
66
+ @environ ||= Environ.new
67
+ end
68
+
69
+ # @return [Array<Pin::Base>]
70
+ def document_symbols
71
+ @document_symbols ||= pins.select { |pin|
72
+ pin.path && !pin.path.empty?
73
+ }
74
+ end
75
+
76
+ # @param query [String]
77
+ # @return [Array<Pin::Base>]
78
+ def query_symbols query
79
+ return document_symbols if query && query.empty?
80
+ document_symbols.select{ |pin| fuzzy_string_match(pin.path, query) || fuzzy_string_match(pin.name, query) }
81
+ end
82
+
83
+ # @param position [Position]
84
+ # @return [Source::Cursor]
85
+ def cursor_at position
86
+ Source::Cursor.new(source, position)
87
+ end
88
+
89
+ # @param path [String]
90
+ # @return [Pin::Base]
91
+ def first_pin path
92
+ pins.select { |p| p.path == path }.first
93
+ end
94
+
95
+ # @param location [Solargraph::Location]
96
+ # @return [Array<Solargraph::Pin::Base>]
97
+ def locate_pins location
98
+ # return nil unless location.start_with?("#{filename}:")
99
+ (pins + locals).select { |pin| pin.location == location }
100
+ end
101
+
102
+ def locate_named_path_pin line, character
103
+ _locate_pin line, character, Pin::Namespace, Pin::Method
104
+ end
105
+
106
+ def locate_block_pin line, character
107
+ _locate_pin line, character, Pin::Namespace, Pin::Method, Pin::Block
108
+ end
109
+
110
+ # @param other_map [SourceMap]
111
+ # @return [Boolean]
112
+ def try_merge! other_map
113
+ return false if pins.length != other_map.pins.length || locals.length != other_map.locals.length || requires.map(&:name).uniq.sort != other_map.requires.map(&:name).uniq.sort
114
+ pins.each_index do |i|
115
+ return false unless pins[i].try_merge!(other_map.pins[i])
116
+ end
117
+ locals.each_index do |i|
118
+ return false unless locals[i].try_merge!(other_map.locals[i])
119
+ end
120
+ @source = other_map.source
121
+ true
122
+ end
123
+
124
+ # @param name [String]
125
+ # @return [Array<Location>]
126
+ def references name
127
+ source.references name
128
+ end
129
+
130
+ # @param location [Location]
131
+ # @return [Array<Pin::LocalVariable>]
132
+ def locals_at(location)
133
+ return [] if location.filename != filename
134
+ locals.select { |pin| pin.visible_at?(location) }
135
+ end
136
+
137
+ class << self
138
+ # @param filename [String]
139
+ # @return [SourceMap]
140
+ def load filename
141
+ source = Solargraph::Source.load(filename)
142
+ SourceMap.map(source)
143
+ end
144
+
145
+ # @param code [String]
146
+ # @param filename [String, nil]
147
+ # @return [SourceMap]
148
+ def load_string code, filename = nil
149
+ source = Solargraph::Source.load_string(code, filename)
150
+ SourceMap.map(source)
151
+ end
152
+
153
+ # @param source [Source]
154
+ # @return [SourceMap]
155
+ def map source
156
+ result = SourceMap::Mapper.map(source)
157
+ new(source, *result)
158
+ end
159
+ end
160
+
161
+ private
162
+
163
+ # @param line [Integer]
164
+ # @param character [Integer]
165
+ # @param klasses [Array<Class>]
166
+ # @return [Pin::Base]
167
+ def _locate_pin line, character, *klasses
168
+ position = Position.new(line, character)
169
+ found = nil
170
+ pins.each do |pin|
171
+ # @todo Attribute pins should not be treated like closures, but
172
+ # there's probably a better way to handle it
173
+ next if pin.is_a?(Pin::Method) && pin.attribute?
174
+ found = pin if (klasses.empty? || klasses.any? { |kls| pin.is_a?(kls) } ) && pin.location.range.contain?(position)
175
+ break if pin.location.range.start.line > line
176
+ end
177
+ # Assuming the root pin is always valid
178
+ found || pins.first
179
+ end
180
+
181
+ # @param str1 [String]
182
+ # @param str2 [String]
183
+ # @return [Boolean]
184
+ def fuzzy_string_match str1, str2
185
+ JaroWinkler.distance(str1, str2) > 0.6
186
+ end
187
+ end
188
+ end