solargraph 0.44.2 → 0.46.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 (246) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rspec.yml +41 -0
  3. data/.gitignore +9 -9
  4. data/.rspec +2 -2
  5. data/.travis.yml +19 -19
  6. data/CHANGELOG.md +1115 -1088
  7. data/Gemfile +0 -0
  8. data/LICENSE +0 -0
  9. data/README.md +128 -120
  10. data/Rakefile +0 -0
  11. data/SPONSORS.md +18 -15
  12. data/bin/solargraph +0 -0
  13. data/lib/solargraph/api_map/bundler_methods.rb +22 -22
  14. data/lib/solargraph/api_map/cache.rb +70 -70
  15. data/lib/solargraph/api_map/source_to_yard.rb +81 -81
  16. data/lib/solargraph/api_map/store.rb +256 -256
  17. data/lib/solargraph/api_map.rb +686 -681
  18. data/lib/solargraph/bench.rb +27 -27
  19. data/lib/solargraph/compat.rb +37 -37
  20. data/lib/solargraph/complex_type/type_methods.rb +130 -130
  21. data/lib/solargraph/complex_type/unique_type.rb +75 -75
  22. data/lib/solargraph/complex_type.rb +221 -221
  23. data/lib/solargraph/convention/base.rb +33 -33
  24. data/lib/solargraph/convention/gemfile.rb +15 -15
  25. data/lib/solargraph/convention/gemspec.rb +22 -22
  26. data/lib/solargraph/convention/rspec.rb +30 -21
  27. data/lib/solargraph/convention.rb +47 -47
  28. data/lib/solargraph/converters/dd.rb +12 -12
  29. data/lib/solargraph/converters/dl.rb +12 -12
  30. data/lib/solargraph/converters/dt.rb +12 -12
  31. data/lib/solargraph/converters/misc.rb +1 -1
  32. data/lib/solargraph/diagnostics/base.rb +29 -29
  33. data/lib/solargraph/diagnostics/require_not_found.rb +53 -37
  34. data/lib/solargraph/diagnostics/rubocop.rb +98 -98
  35. data/lib/solargraph/diagnostics/rubocop_helpers.rb +63 -63
  36. data/lib/solargraph/diagnostics/severities.rb +15 -15
  37. data/lib/solargraph/diagnostics/type_check.rb +54 -54
  38. data/lib/solargraph/diagnostics/update_errors.rb +41 -41
  39. data/lib/solargraph/diagnostics.rb +55 -55
  40. data/lib/solargraph/documentor.rb +76 -76
  41. data/lib/solargraph/environ.rb +45 -45
  42. data/lib/solargraph/language_server/completion_item_kinds.rb +35 -35
  43. data/lib/solargraph/language_server/error_codes.rb +20 -20
  44. data/lib/solargraph/language_server/host/cataloger.rb +56 -56
  45. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  46. data/lib/solargraph/language_server/host/dispatch.rb +111 -111
  47. data/lib/solargraph/language_server/host/message_worker.rb +59 -59
  48. data/lib/solargraph/language_server/host/sources.rb +156 -156
  49. data/lib/solargraph/language_server/host.rb +865 -865
  50. data/lib/solargraph/language_server/message/base.rb +89 -89
  51. data/lib/solargraph/language_server/message/cancel_request.rb +13 -13
  52. data/lib/solargraph/language_server/message/client/register_capability.rb +15 -15
  53. data/lib/solargraph/language_server/message/client.rb +11 -11
  54. data/lib/solargraph/language_server/message/completion_item/resolve.rb +58 -58
  55. data/lib/solargraph/language_server/message/completion_item.rb +11 -11
  56. data/lib/solargraph/language_server/message/exit_notification.rb +13 -13
  57. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +100 -100
  58. data/lib/solargraph/language_server/message/extended/document.rb +20 -20
  59. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
  60. data/lib/solargraph/language_server/message/extended/download_core.rb +23 -23
  61. data/lib/solargraph/language_server/message/extended/environment.rb +25 -25
  62. data/lib/solargraph/language_server/message/extended/search.rb +20 -20
  63. data/lib/solargraph/language_server/message/extended.rb +21 -21
  64. data/lib/solargraph/language_server/message/initialize.rb +162 -162
  65. data/lib/solargraph/language_server/message/initialized.rb +27 -27
  66. data/lib/solargraph/language_server/message/method_not_found.rb +16 -16
  67. data/lib/solargraph/language_server/message/method_not_implemented.rb +14 -14
  68. data/lib/solargraph/language_server/message/shutdown.rb +13 -13
  69. data/lib/solargraph/language_server/message/text_document/base.rb +19 -19
  70. data/lib/solargraph/language_server/message/text_document/code_action.rb +17 -17
  71. data/lib/solargraph/language_server/message/text_document/completion.rb +59 -59
  72. data/lib/solargraph/language_server/message/text_document/definition.rb +38 -38
  73. data/lib/solargraph/language_server/message/text_document/did_change.rb +15 -15
  74. data/lib/solargraph/language_server/message/text_document/did_close.rb +15 -15
  75. data/lib/solargraph/language_server/message/text_document/did_open.rb +15 -15
  76. data/lib/solargraph/language_server/message/text_document/did_save.rb +17 -17
  77. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +16 -16
  78. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +23 -23
  79. data/lib/solargraph/language_server/message/text_document/folding_range.rb +26 -26
  80. data/lib/solargraph/language_server/message/text_document/formatting.rb +126 -126
  81. data/lib/solargraph/language_server/message/text_document/hover.rb +54 -44
  82. data/lib/solargraph/language_server/message/text_document/on_type_formatting.rb +34 -34
  83. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +11 -11
  84. data/lib/solargraph/language_server/message/text_document/references.rb +16 -16
  85. data/lib/solargraph/language_server/message/text_document/rename.rb +19 -19
  86. data/lib/solargraph/language_server/message/text_document/signature_help.rb +29 -29
  87. data/lib/solargraph/language_server/message/text_document.rb +28 -28
  88. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +30 -30
  89. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +33 -33
  90. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +24 -24
  91. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -23
  92. data/lib/solargraph/language_server/message/workspace.rb +14 -14
  93. data/lib/solargraph/language_server/message.rb +93 -93
  94. data/lib/solargraph/language_server/message_types.rb +14 -14
  95. data/lib/solargraph/language_server/request.rb +24 -24
  96. data/lib/solargraph/language_server/symbol_kinds.rb +36 -36
  97. data/lib/solargraph/language_server/transport/adapter.rb +53 -53
  98. data/lib/solargraph/language_server/transport/data_reader.rb +72 -72
  99. data/lib/solargraph/language_server/transport.rb +13 -13
  100. data/lib/solargraph/language_server/uri_helpers.rb +49 -49
  101. data/lib/solargraph/language_server.rb +19 -19
  102. data/lib/solargraph/library.rb +546 -546
  103. data/lib/solargraph/location.rb +37 -37
  104. data/lib/solargraph/logging.rb +27 -27
  105. data/lib/solargraph/page.rb +83 -83
  106. data/lib/solargraph/parser/comment_ripper.rb +52 -52
  107. data/lib/solargraph/parser/legacy/class_methods.rb +135 -140
  108. data/lib/solargraph/parser/legacy/flawed_builder.rb +16 -16
  109. data/lib/solargraph/parser/legacy/node_chainer.rb +148 -148
  110. data/lib/solargraph/parser/legacy/node_methods.rb +325 -325
  111. data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +23 -23
  112. data/lib/solargraph/parser/legacy/node_processors/args_node.rb +35 -35
  113. data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +15 -15
  114. data/lib/solargraph/parser/legacy/node_processors/block_node.rb +42 -42
  115. data/lib/solargraph/parser/legacy/node_processors/casgn_node.rb +25 -25
  116. data/lib/solargraph/parser/legacy/node_processors/cvasgn_node.rb +23 -23
  117. data/lib/solargraph/parser/legacy/node_processors/def_node.rb +63 -63
  118. data/lib/solargraph/parser/legacy/node_processors/defs_node.rb +36 -36
  119. data/lib/solargraph/parser/legacy/node_processors/gvasgn_node.rb +23 -23
  120. data/lib/solargraph/parser/legacy/node_processors/ivasgn_node.rb +38 -38
  121. data/lib/solargraph/parser/legacy/node_processors/lvasgn_node.rb +28 -28
  122. data/lib/solargraph/parser/legacy/node_processors/namespace_node.rb +39 -39
  123. data/lib/solargraph/parser/legacy/node_processors/orasgn_node.rb +16 -16
  124. data/lib/solargraph/parser/legacy/node_processors/resbody_node.rb +36 -36
  125. data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +21 -21
  126. data/lib/solargraph/parser/legacy/node_processors/send_node.rb +257 -257
  127. data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +18 -18
  128. data/lib/solargraph/parser/legacy/node_processors.rb +54 -54
  129. data/lib/solargraph/parser/legacy.rb +12 -12
  130. data/lib/solargraph/parser/node_methods.rb +43 -43
  131. data/lib/solargraph/parser/node_processor/base.rb +77 -77
  132. data/lib/solargraph/parser/node_processor.rb +43 -43
  133. data/lib/solargraph/parser/region.rb +66 -66
  134. data/lib/solargraph/parser/rubyvm/class_methods.rb +144 -155
  135. data/lib/solargraph/parser/rubyvm/node_chainer.rb +160 -160
  136. data/lib/solargraph/parser/rubyvm/node_methods.rb +315 -315
  137. data/lib/solargraph/parser/rubyvm/node_processors/alias_node.rb +23 -23
  138. data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +85 -85
  139. data/lib/solargraph/parser/rubyvm/node_processors/begin_node.rb +15 -15
  140. data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +42 -42
  141. data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +22 -22
  142. data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +23 -23
  143. data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +63 -64
  144. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +57 -57
  145. data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +23 -23
  146. data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +38 -38
  147. data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +39 -39
  148. data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +20 -20
  149. data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +27 -27
  150. data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +39 -39
  151. data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +26 -26
  152. data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +15 -15
  153. data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +45 -45
  154. data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +21 -21
  155. data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +15 -15
  156. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +277 -277
  157. data/lib/solargraph/parser/rubyvm/node_processors/sym_node.rb +18 -18
  158. data/lib/solargraph/parser/rubyvm/node_processors.rb +63 -62
  159. data/lib/solargraph/parser/rubyvm.rb +40 -40
  160. data/lib/solargraph/parser/snippet.rb +13 -13
  161. data/lib/solargraph/parser.rb +26 -26
  162. data/lib/solargraph/pin/base.rb +296 -296
  163. data/lib/solargraph/pin/base_variable.rb +84 -84
  164. data/lib/solargraph/pin/block.rb +72 -72
  165. data/lib/solargraph/pin/class_variable.rb +8 -8
  166. data/lib/solargraph/pin/closure.rb +37 -37
  167. data/lib/solargraph/pin/common.rb +70 -70
  168. data/lib/solargraph/pin/constant.rb +43 -43
  169. data/lib/solargraph/pin/conversions.rb +96 -96
  170. data/lib/solargraph/pin/documenting.rb +105 -105
  171. data/lib/solargraph/pin/duck_method.rb +16 -16
  172. data/lib/solargraph/pin/global_variable.rb +8 -8
  173. data/lib/solargraph/pin/instance_variable.rb +30 -30
  174. data/lib/solargraph/pin/keyword.rb +15 -15
  175. data/lib/solargraph/pin/keyword_param.rb +8 -8
  176. data/lib/solargraph/pin/local_variable.rb +55 -55
  177. data/lib/solargraph/pin/method.rb +245 -245
  178. data/lib/solargraph/pin/method_alias.rb +31 -31
  179. data/lib/solargraph/pin/namespace.rb +91 -91
  180. data/lib/solargraph/pin/parameter.rb +201 -206
  181. data/lib/solargraph/pin/proxy_type.rb +29 -29
  182. data/lib/solargraph/pin/reference/extend.rb +10 -10
  183. data/lib/solargraph/pin/reference/include.rb +10 -10
  184. data/lib/solargraph/pin/reference/override.rb +29 -29
  185. data/lib/solargraph/pin/reference/prepend.rb +10 -10
  186. data/lib/solargraph/pin/reference/require.rb +14 -14
  187. data/lib/solargraph/pin/reference/superclass.rb +10 -10
  188. data/lib/solargraph/pin/reference.rb +14 -14
  189. data/lib/solargraph/pin/search.rb +56 -0
  190. data/lib/solargraph/pin/singleton.rb +11 -11
  191. data/lib/solargraph/pin/symbol.rb +47 -47
  192. data/lib/solargraph/pin.rb +37 -36
  193. data/lib/solargraph/position.rb +100 -100
  194. data/lib/solargraph/range.rb +95 -95
  195. data/lib/solargraph/server_methods.rb +16 -16
  196. data/lib/solargraph/shell.rb +226 -226
  197. data/lib/solargraph/source/chain/block_variable.rb +13 -13
  198. data/lib/solargraph/source/chain/call.rb +204 -204
  199. data/lib/solargraph/source/chain/class_variable.rb +13 -13
  200. data/lib/solargraph/source/chain/constant.rb +75 -75
  201. data/lib/solargraph/source/chain/global_variable.rb +13 -13
  202. data/lib/solargraph/source/chain/hash.rb +28 -28
  203. data/lib/solargraph/source/chain/head.rb +19 -19
  204. data/lib/solargraph/source/chain/instance_variable.rb +13 -13
  205. data/lib/solargraph/source/chain/link.rb +71 -71
  206. data/lib/solargraph/source/chain/literal.rb +23 -23
  207. data/lib/solargraph/source/chain/or.rb +23 -23
  208. data/lib/solargraph/source/chain/q_call.rb +11 -11
  209. data/lib/solargraph/source/chain/variable.rb +13 -13
  210. data/lib/solargraph/source/chain/z_super.rb +30 -30
  211. data/lib/solargraph/source/chain.rb +164 -164
  212. data/lib/solargraph/source/change.rb +79 -79
  213. data/lib/solargraph/source/cursor.rb +164 -164
  214. data/lib/solargraph/source/source_chainer.rb +191 -191
  215. data/lib/solargraph/source/updater.rb +54 -54
  216. data/lib/solargraph/source.rb +522 -522
  217. data/lib/solargraph/source_map/clip.rb +224 -224
  218. data/lib/solargraph/source_map/completion.rb +23 -23
  219. data/lib/solargraph/source_map/mapper.rb +212 -212
  220. data/lib/solargraph/source_map.rb +180 -189
  221. data/lib/solargraph/type_checker/checks.rb +99 -99
  222. data/lib/solargraph/type_checker/param_def.rb +35 -35
  223. data/lib/solargraph/type_checker/problem.rb +32 -32
  224. data/lib/solargraph/type_checker/rules.rb +57 -57
  225. data/lib/solargraph/type_checker.rb +543 -510
  226. data/lib/solargraph/version.rb +5 -5
  227. data/lib/solargraph/views/environment.erb +58 -58
  228. data/lib/solargraph/workspace/config.rb +231 -231
  229. data/lib/solargraph/workspace.rb +215 -214
  230. data/lib/solargraph/yard_map/cache.rb +19 -19
  231. data/lib/solargraph/yard_map/core_docs.rb +170 -170
  232. data/lib/solargraph/yard_map/core_fills.rb +208 -203
  233. data/lib/solargraph/yard_map/core_gen.rb +76 -76
  234. data/lib/solargraph/yard_map/helpers.rb +16 -16
  235. data/lib/solargraph/yard_map/mapper/to_constant.rb +25 -25
  236. data/lib/solargraph/yard_map/mapper/to_method.rb +78 -78
  237. data/lib/solargraph/yard_map/mapper/to_namespace.rb +27 -27
  238. data/lib/solargraph/yard_map/mapper.rb +77 -77
  239. data/lib/solargraph/yard_map/rdoc_to_yard.rb +140 -140
  240. data/lib/solargraph/yard_map/stdlib_fills.rb +43 -43
  241. data/lib/solargraph/yard_map/to_method.rb +79 -79
  242. data/lib/solargraph/yard_map.rb +460 -443
  243. data/lib/solargraph.rb +69 -69
  244. data/lib/yard-solargraph.rb +33 -33
  245. data/solargraph.gemspec +0 -0
  246. metadata +14 -12
@@ -1,212 +1,212 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- class SourceMap
5
- # The Mapper generates pins and other data for SourceMaps.
6
- #
7
- # This class is used internally by the SourceMap class. Users should not
8
- # normally need to call it directly.
9
- #
10
- class Mapper
11
- # include Source::NodeMethods
12
-
13
- private_class_method :new
14
-
15
- MACRO_REGEXP = /(@\!method|@\!attribute|@\!domain|@\!macro|@\!parse|@\!override)/.freeze
16
-
17
- # Generate the data.
18
- #
19
- # @param source [Source]
20
- # @return [Array]
21
- def map source
22
- @source = source
23
- @filename = source.filename
24
- @code = source.code
25
- @comments = source.comments
26
- @pins, @locals = Parser.map(source)
27
- process_comment_directives
28
- [@pins, @locals]
29
- # rescue Exception => e
30
- # Solargraph.logger.warn "Error mapping #{source.filename}: [#{e.class}] #{e.message}"
31
- # Solargraph.logger.warn e.backtrace.join("\n")
32
- # [[], []]
33
- end
34
-
35
- # @param filename [String]
36
- # @param code [String]
37
- # @return [Array]
38
- def unmap filename, code
39
- s = Position.new(0, 0)
40
- e = Position.from_offset(code, code.length)
41
- location = Location.new(filename, Range.new(s, e))
42
- [[Pin::Namespace.new(location: location, name: '')], []]
43
- end
44
-
45
- class << self
46
- # @param source [Source]
47
- # @return [Array]
48
- def map source
49
- return new.unmap(source.filename, source.code) unless source.parsed?
50
- new.map source
51
- end
52
- end
53
-
54
- # @return [Array<Solargraph::Pin::Base>]
55
- def pins
56
- @pins ||= []
57
- end
58
-
59
- def closure_at(position)
60
- @pins.select{|pin| pin.is_a?(Pin::Closure) and pin.location.range.contain?(position)}.last
61
- end
62
-
63
- def process_comment source_position, comment_position, comment
64
- return unless comment.encode('UTF-8', invalid: :replace, replace: '?') =~ MACRO_REGEXP
65
- cmnt = remove_inline_comment_hashes(comment)
66
- parse = Solargraph::Source.parse_docstring(cmnt)
67
- last_line = 0
68
- # @param d [YARD::Tags::Directive]
69
- parse.directives.each do |d|
70
- line_num = find_directive_line_number(cmnt, d.tag.tag_name, last_line)
71
- pos = Solargraph::Position.new(comment_position.line + line_num - 1, comment_position.column)
72
- process_directive(source_position, pos, d)
73
- last_line = line_num + 1
74
- end
75
- end
76
-
77
- # @param comment [String]
78
- # @return [Integer]
79
- def find_directive_line_number comment, tag, start
80
- # Avoid overruning the index
81
- return start unless start < comment.lines.length
82
- num = comment.lines[start..-1].find_index do |line|
83
- # Legacy method directives might be `@method` instead of `@!method`
84
- # @todo Legacy syntax should probably emit a warning
85
- line.include?("@!#{tag}") || (tag == 'method' && line.include?("@#{tag}"))
86
- end
87
- num.to_i + start
88
- end
89
-
90
- # @param source_position [Position]
91
- # @param comment_position [Position]
92
- # @param directive [YARD::Tags::Directive]
93
- # @return [void]
94
- def process_directive source_position, comment_position, directive
95
- docstring = Solargraph::Source.parse_docstring(directive.tag.text).to_docstring
96
- location = Location.new(@filename, Range.new(comment_position, comment_position))
97
- case directive.tag.tag_name
98
- when 'method'
99
- namespace = closure_at(source_position) || @pins.first
100
- if namespace.location.range.start.line < comment_position.line
101
- namespace = closure_at(comment_position)
102
- end
103
- begin
104
- src = Solargraph::Source.load_string("def #{directive.tag.name};end", @source.filename)
105
- region = Parser::Region.new(source: src, closure: namespace)
106
- gen_pin = Parser.process_node(src.node, region).first.last
107
- return if gen_pin.nil?
108
- # Move the location to the end of the line so it gets recognized
109
- # as originating from a comment
110
- shifted = Solargraph::Position.new(comment_position.line, @code.lines[comment_position.line].to_s.chomp.length)
111
- # @todo: Smelly instance variable access
112
- gen_pin.instance_variable_set(:@comments, docstring.all.to_s)
113
- gen_pin.instance_variable_set(:@location, Solargraph::Location.new(@filename, Range.new(shifted, shifted)))
114
- gen_pin.instance_variable_set(:@explicit, false)
115
- @pins.push gen_pin
116
- rescue Parser::SyntaxError => e
117
- # @todo Handle error in directive
118
- end
119
- when 'attribute'
120
- return if directive.tag.name.nil?
121
- namespace = closure_at(source_position)
122
- t = (directive.tag.types.nil? || directive.tag.types.empty?) ? nil : directive.tag.types.flatten.join('')
123
- if t.nil? || t.include?('r')
124
- pins.push Solargraph::Pin::Method.new(
125
- location: location,
126
- closure: namespace,
127
- name: directive.tag.name,
128
- comments: docstring.all.to_s,
129
- scope: namespace.is_a?(Pin::Singleton) ? :class : :instance,
130
- visibility: :public,
131
- explicit: false,
132
- attribute: true
133
- )
134
- end
135
- if t.nil? || t.include?('w')
136
- pins.push Solargraph::Pin::Method.new(
137
- location: location,
138
- closure: namespace,
139
- name: "#{directive.tag.name}=",
140
- comments: docstring.all.to_s,
141
- scope: namespace.is_a?(Pin::Singleton) ? :class : :instance,
142
- visibility: :public,
143
- attribute: true
144
- )
145
- pins.last.parameters.push Pin::Parameter.new(name: 'value', decl: :arg, closure: pins.last)
146
- if pins.last.return_type.defined?
147
- pins.last.docstring.add_tag YARD::Tags::Tag.new(:param, '', pins.last.return_type.to_s.split(', '), 'value')
148
- end
149
- end
150
- when 'parse'
151
- begin
152
- ns = closure_at(source_position)
153
- src = Solargraph::Source.load_string(directive.tag.text, @source.filename)
154
- region = Parser::Region.new(source: src, closure: ns)
155
- # @todo These pins may need to be marked not explicit
156
- index = @pins.length
157
- loff = if @code.lines[comment_position.line].strip.end_with?('@!parse')
158
- comment_position.line + 1
159
- else
160
- comment_position.line
161
- end
162
- Parser.process_node(src.node, region, @pins)
163
- @pins[index..-1].each do |p|
164
- # @todo Smelly instance variable access
165
- p.location.range.start.instance_variable_set(:@line, p.location.range.start.line + loff)
166
- p.location.range.ending.instance_variable_set(:@line, p.location.range.ending.line + loff)
167
- end
168
- rescue Parser::SyntaxError => e
169
- # @todo Handle parser errors in !parse directives
170
- end
171
- when 'domain'
172
- namespace = closure_at(source_position) || Pin::ROOT_PIN
173
- namespace.domains.concat directive.tag.types unless directive.tag.types.nil?
174
- when 'override'
175
- pins.push Pin::Reference::Override.new(location, directive.tag.name, docstring.tags)
176
- end
177
- end
178
-
179
- def remove_inline_comment_hashes comment
180
- ctxt = ''
181
- num = nil
182
- started = false
183
- comment.lines.each { |l|
184
- # Trim the comment and minimum leading whitespace
185
- p = l.encode('UTF-8', invalid: :replace, replace: '?').gsub(/^#/, '')
186
- if num.nil? && !p.strip.empty?
187
- num = p.index(/[^ ]/)
188
- started = true
189
- elsif started && !p.strip.empty?
190
- cur = p.index(/[^ ]/)
191
- num = cur if cur < num
192
- end
193
- ctxt += "#{p[num..-1]}" if started
194
- }
195
- ctxt
196
- end
197
-
198
- # @return [void]
199
- def process_comment_directives
200
- return unless @code.encode('UTF-8', invalid: :replace, replace: '?') =~ MACRO_REGEXP
201
- code_lines = @code.lines
202
- @source.associated_comments.each do |line, comments|
203
- src_pos = line ? Position.new(line, code_lines[line].to_s.chomp.index(/[^\s]/) || 0) : Position.new(code_lines.length, 0)
204
- com_pos = Position.new(line + 1 - comments.lines.length, 0)
205
- process_comment(src_pos, com_pos, comments)
206
- end
207
- rescue StandardError => e
208
- raise e.class, "Error processing comment directives in #{@filename}: #{e.message}"
209
- end
210
- end
211
- end
212
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class SourceMap
5
+ # The Mapper generates pins and other data for SourceMaps.
6
+ #
7
+ # This class is used internally by the SourceMap class. Users should not
8
+ # normally need to call it directly.
9
+ #
10
+ class Mapper
11
+ # include Source::NodeMethods
12
+
13
+ private_class_method :new
14
+
15
+ MACRO_REGEXP = /(@\!method|@\!attribute|@\!domain|@\!macro|@\!parse|@\!override)/.freeze
16
+
17
+ # Generate the data.
18
+ #
19
+ # @param source [Source]
20
+ # @return [Array]
21
+ def map source
22
+ @source = source
23
+ @filename = source.filename
24
+ @code = source.code
25
+ @comments = source.comments
26
+ @pins, @locals = Parser.map(source)
27
+ process_comment_directives
28
+ [@pins, @locals]
29
+ # rescue Exception => e
30
+ # Solargraph.logger.warn "Error mapping #{source.filename}: [#{e.class}] #{e.message}"
31
+ # Solargraph.logger.warn e.backtrace.join("\n")
32
+ # [[], []]
33
+ end
34
+
35
+ # @param filename [String]
36
+ # @param code [String]
37
+ # @return [Array]
38
+ def unmap filename, code
39
+ s = Position.new(0, 0)
40
+ e = Position.from_offset(code, code.length)
41
+ location = Location.new(filename, Range.new(s, e))
42
+ [[Pin::Namespace.new(location: location, name: '')], []]
43
+ end
44
+
45
+ class << self
46
+ # @param source [Source]
47
+ # @return [Array]
48
+ def map source
49
+ return new.unmap(source.filename, source.code) unless source.parsed?
50
+ new.map source
51
+ end
52
+ end
53
+
54
+ # @return [Array<Solargraph::Pin::Base>]
55
+ def pins
56
+ @pins ||= []
57
+ end
58
+
59
+ def closure_at(position)
60
+ @pins.select{|pin| pin.is_a?(Pin::Closure) and pin.location.range.contain?(position)}.last
61
+ end
62
+
63
+ def process_comment source_position, comment_position, comment
64
+ return unless comment.encode('UTF-8', invalid: :replace, replace: '?') =~ MACRO_REGEXP
65
+ cmnt = remove_inline_comment_hashes(comment)
66
+ parse = Solargraph::Source.parse_docstring(cmnt)
67
+ last_line = 0
68
+ # @param d [YARD::Tags::Directive]
69
+ parse.directives.each do |d|
70
+ line_num = find_directive_line_number(cmnt, d.tag.tag_name, last_line)
71
+ pos = Solargraph::Position.new(comment_position.line + line_num - 1, comment_position.column)
72
+ process_directive(source_position, pos, d)
73
+ last_line = line_num + 1
74
+ end
75
+ end
76
+
77
+ # @param comment [String]
78
+ # @return [Integer]
79
+ def find_directive_line_number comment, tag, start
80
+ # Avoid overruning the index
81
+ return start unless start < comment.lines.length
82
+ num = comment.lines[start..-1].find_index do |line|
83
+ # Legacy method directives might be `@method` instead of `@!method`
84
+ # @todo Legacy syntax should probably emit a warning
85
+ line.include?("@!#{tag}") || (tag == 'method' && line.include?("@#{tag}"))
86
+ end
87
+ num.to_i + start
88
+ end
89
+
90
+ # @param source_position [Position]
91
+ # @param comment_position [Position]
92
+ # @param directive [YARD::Tags::Directive]
93
+ # @return [void]
94
+ def process_directive source_position, comment_position, directive
95
+ docstring = Solargraph::Source.parse_docstring(directive.tag.text).to_docstring
96
+ location = Location.new(@filename, Range.new(comment_position, comment_position))
97
+ case directive.tag.tag_name
98
+ when 'method'
99
+ namespace = closure_at(source_position) || @pins.first
100
+ if namespace.location.range.start.line < comment_position.line
101
+ namespace = closure_at(comment_position)
102
+ end
103
+ begin
104
+ src = Solargraph::Source.load_string("def #{directive.tag.name};end", @source.filename)
105
+ region = Parser::Region.new(source: src, closure: namespace)
106
+ gen_pin = Parser.process_node(src.node, region).first.last
107
+ return if gen_pin.nil?
108
+ # Move the location to the end of the line so it gets recognized
109
+ # as originating from a comment
110
+ shifted = Solargraph::Position.new(comment_position.line, @code.lines[comment_position.line].to_s.chomp.length)
111
+ # @todo: Smelly instance variable access
112
+ gen_pin.instance_variable_set(:@comments, docstring.all.to_s)
113
+ gen_pin.instance_variable_set(:@location, Solargraph::Location.new(@filename, Range.new(shifted, shifted)))
114
+ gen_pin.instance_variable_set(:@explicit, false)
115
+ @pins.push gen_pin
116
+ rescue Parser::SyntaxError => e
117
+ # @todo Handle error in directive
118
+ end
119
+ when 'attribute'
120
+ return if directive.tag.name.nil?
121
+ namespace = closure_at(source_position)
122
+ t = (directive.tag.types.nil? || directive.tag.types.empty?) ? nil : directive.tag.types.flatten.join('')
123
+ if t.nil? || t.include?('r')
124
+ pins.push Solargraph::Pin::Method.new(
125
+ location: location,
126
+ closure: namespace,
127
+ name: directive.tag.name,
128
+ comments: docstring.all.to_s,
129
+ scope: namespace.is_a?(Pin::Singleton) ? :class : :instance,
130
+ visibility: :public,
131
+ explicit: false,
132
+ attribute: true
133
+ )
134
+ end
135
+ if t.nil? || t.include?('w')
136
+ pins.push Solargraph::Pin::Method.new(
137
+ location: location,
138
+ closure: namespace,
139
+ name: "#{directive.tag.name}=",
140
+ comments: docstring.all.to_s,
141
+ scope: namespace.is_a?(Pin::Singleton) ? :class : :instance,
142
+ visibility: :public,
143
+ attribute: true
144
+ )
145
+ pins.last.parameters.push Pin::Parameter.new(name: 'value', decl: :arg, closure: pins.last)
146
+ if pins.last.return_type.defined?
147
+ pins.last.docstring.add_tag YARD::Tags::Tag.new(:param, '', pins.last.return_type.to_s.split(', '), 'value')
148
+ end
149
+ end
150
+ when 'parse'
151
+ begin
152
+ ns = closure_at(source_position)
153
+ src = Solargraph::Source.load_string(directive.tag.text, @source.filename)
154
+ region = Parser::Region.new(source: src, closure: ns)
155
+ # @todo These pins may need to be marked not explicit
156
+ index = @pins.length
157
+ loff = if @code.lines[comment_position.line].strip.end_with?('@!parse')
158
+ comment_position.line + 1
159
+ else
160
+ comment_position.line
161
+ end
162
+ Parser.process_node(src.node, region, @pins)
163
+ @pins[index..-1].each do |p|
164
+ # @todo Smelly instance variable access
165
+ p.location.range.start.instance_variable_set(:@line, p.location.range.start.line + loff)
166
+ p.location.range.ending.instance_variable_set(:@line, p.location.range.ending.line + loff)
167
+ end
168
+ rescue Parser::SyntaxError => e
169
+ # @todo Handle parser errors in !parse directives
170
+ end
171
+ when 'domain'
172
+ namespace = closure_at(source_position) || Pin::ROOT_PIN
173
+ namespace.domains.concat directive.tag.types unless directive.tag.types.nil?
174
+ when 'override'
175
+ pins.push Pin::Reference::Override.new(location, directive.tag.name, docstring.tags)
176
+ end
177
+ end
178
+
179
+ def remove_inline_comment_hashes comment
180
+ ctxt = ''
181
+ num = nil
182
+ started = false
183
+ comment.lines.each { |l|
184
+ # Trim the comment and minimum leading whitespace
185
+ p = l.encode('UTF-8', invalid: :replace, replace: '?').gsub(/^#/, '')
186
+ if num.nil? && !p.strip.empty?
187
+ num = p.index(/[^ ]/)
188
+ started = true
189
+ elsif started && !p.strip.empty?
190
+ cur = p.index(/[^ ]/)
191
+ num = cur if cur < num
192
+ end
193
+ ctxt += "#{p[num..-1]}" if started
194
+ }
195
+ ctxt
196
+ end
197
+
198
+ # @return [void]
199
+ def process_comment_directives
200
+ return unless @code.encode('UTF-8', invalid: :replace, replace: '?') =~ MACRO_REGEXP
201
+ code_lines = @code.lines
202
+ @source.associated_comments.each do |line, comments|
203
+ src_pos = line ? Position.new(line, code_lines[line].to_s.chomp.index(/[^\s]/) || 0) : Position.new(code_lines.length, 0)
204
+ com_pos = Position.new(line + 1 - comments.lines.length, 0)
205
+ process_comment(src_pos, com_pos, comments)
206
+ end
207
+ rescue StandardError => e
208
+ raise e.class, "Error processing comment directives in #{@filename}: #{e.message}"
209
+ end
210
+ end
211
+ end
212
+ end