solargraph 0.58.3 → 0.60.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 (238) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +3 -0
  3. data/.github/workflows/linting.yml +12 -5
  4. data/.github/workflows/plugins.yml +54 -34
  5. data/.github/workflows/rspec.yml +18 -28
  6. data/.github/workflows/typecheck.yml +6 -3
  7. data/.rubocop.yml +39 -6
  8. data/.rubocop_todo.yml +53 -966
  9. data/CHANGELOG.md +35 -0
  10. data/Gemfile +6 -1
  11. data/README.md +3 -3
  12. data/Rakefile +26 -23
  13. data/bin/solargraph +2 -1
  14. data/lib/solargraph/api_map/cache.rb +3 -3
  15. data/lib/solargraph/api_map/constants.rb +12 -3
  16. data/lib/solargraph/api_map/index.rb +42 -20
  17. data/lib/solargraph/api_map/source_to_yard.rb +22 -9
  18. data/lib/solargraph/api_map/store.rb +61 -36
  19. data/lib/solargraph/api_map.rb +192 -78
  20. data/lib/solargraph/bench.rb +2 -3
  21. data/lib/solargraph/complex_type/conformance.rb +176 -0
  22. data/lib/solargraph/complex_type/type_methods.rb +31 -18
  23. data/lib/solargraph/complex_type/unique_type.rb +225 -63
  24. data/lib/solargraph/complex_type.rb +177 -59
  25. data/lib/solargraph/convention/active_support_concern.rb +111 -111
  26. data/lib/solargraph/convention/base.rb +50 -50
  27. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +1 -1
  28. data/lib/solargraph/convention/data_definition/data_definition_node.rb +7 -5
  29. data/lib/solargraph/convention/data_definition.rb +5 -2
  30. data/lib/solargraph/convention/gemfile.rb +1 -1
  31. data/lib/solargraph/convention/gemspec.rb +1 -1
  32. data/lib/solargraph/convention/rakefile.rb +1 -1
  33. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +2 -1
  34. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +4 -3
  35. data/lib/solargraph/convention/struct_definition.rb +8 -4
  36. data/lib/solargraph/convention.rb +2 -2
  37. data/lib/solargraph/converters/dd.rb +2 -0
  38. data/lib/solargraph/converters/dl.rb +2 -0
  39. data/lib/solargraph/converters/dt.rb +2 -0
  40. data/lib/solargraph/converters/misc.rb +2 -0
  41. data/lib/solargraph/diagnostics/require_not_found.rb +1 -0
  42. data/lib/solargraph/diagnostics/rubocop.rb +11 -10
  43. data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
  44. data/lib/solargraph/diagnostics/type_check.rb +11 -10
  45. data/lib/solargraph/diagnostics/update_errors.rb +4 -8
  46. data/lib/solargraph/diagnostics.rb +55 -55
  47. data/lib/solargraph/doc_map.rb +39 -39
  48. data/lib/solargraph/environ.rb +52 -52
  49. data/lib/solargraph/equality.rb +4 -4
  50. data/lib/solargraph/gem_pins.rb +4 -15
  51. data/lib/solargraph/language_server/error_codes.rb +10 -10
  52. data/lib/solargraph/language_server/host/diagnoser.rb +1 -1
  53. data/lib/solargraph/language_server/host/dispatch.rb +3 -3
  54. data/lib/solargraph/language_server/host/message_worker.rb +4 -3
  55. data/lib/solargraph/language_server/host/sources.rb +2 -1
  56. data/lib/solargraph/language_server/host.rb +35 -28
  57. data/lib/solargraph/language_server/message/base.rb +1 -1
  58. data/lib/solargraph/language_server/message/client/register_capability.rb +1 -3
  59. data/lib/solargraph/language_server/message/completion_item/resolve.rb +6 -8
  60. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +12 -18
  61. data/lib/solargraph/language_server/message/extended/document.rb +1 -0
  62. data/lib/solargraph/language_server/message/extended/document_gems.rb +7 -7
  63. data/lib/solargraph/language_server/message/extended/download_core.rb +2 -1
  64. data/lib/solargraph/language_server/message/extended/environment.rb +25 -25
  65. data/lib/solargraph/language_server/message/extended/search.rb +1 -1
  66. data/lib/solargraph/language_server/message/initialize.rb +20 -14
  67. data/lib/solargraph/language_server/message/initialized.rb +28 -28
  68. data/lib/solargraph/language_server/message/text_document/completion.rb +10 -8
  69. data/lib/solargraph/language_server/message/text_document/definition.rb +41 -32
  70. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +17 -10
  71. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +29 -19
  72. data/lib/solargraph/language_server/message/text_document/formatting.rb +8 -6
  73. data/lib/solargraph/language_server/message/text_document/hover.rb +5 -5
  74. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +13 -6
  75. data/lib/solargraph/language_server/message/text_document/references.rb +17 -10
  76. data/lib/solargraph/language_server/message/text_document/rename.rb +20 -13
  77. data/lib/solargraph/language_server/message/text_document/signature_help.rb +3 -2
  78. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -17
  79. data/lib/solargraph/language_server/message/text_document.rb +28 -28
  80. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +34 -28
  81. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +38 -30
  82. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +23 -17
  83. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +27 -17
  84. data/lib/solargraph/language_server/message.rb +1 -1
  85. data/lib/solargraph/language_server/progress.rb +143 -143
  86. data/lib/solargraph/language_server/request.rb +4 -2
  87. data/lib/solargraph/language_server/transport/adapter.rb +68 -68
  88. data/lib/solargraph/language_server/transport/data_reader.rb +11 -13
  89. data/lib/solargraph/language_server/uri_helpers.rb +2 -2
  90. data/lib/solargraph/language_server.rb +20 -20
  91. data/lib/solargraph/library.rb +57 -38
  92. data/lib/solargraph/location.rb +17 -14
  93. data/lib/solargraph/logging.rb +22 -4
  94. data/lib/solargraph/page.rb +1 -1
  95. data/lib/solargraph/parser/comment_ripper.rb +19 -4
  96. data/lib/solargraph/parser/flow_sensitive_typing.rb +324 -108
  97. data/lib/solargraph/parser/node_processor/base.rb +34 -4
  98. data/lib/solargraph/parser/node_processor.rb +8 -7
  99. data/lib/solargraph/parser/parser_gem/class_methods.rb +30 -14
  100. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -1
  101. data/lib/solargraph/parser/parser_gem/node_chainer.rb +51 -25
  102. data/lib/solargraph/parser/parser_gem/node_methods.rb +222 -72
  103. data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +24 -24
  104. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +4 -4
  105. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +13 -11
  106. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +9 -0
  107. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +11 -12
  108. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +36 -36
  109. data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +24 -24
  110. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +10 -3
  111. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +9 -8
  112. data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +24 -24
  113. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +36 -6
  114. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +5 -3
  115. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +1 -0
  116. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +3 -1
  117. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +64 -40
  118. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +3 -3
  119. data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
  120. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -1
  121. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
  122. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -5
  123. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +124 -113
  124. data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +20 -20
  125. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +1 -1
  126. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
  127. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +6 -2
  128. data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
  129. data/lib/solargraph/parser/parser_gem.rb +2 -0
  130. data/lib/solargraph/parser/region.rb +9 -3
  131. data/lib/solargraph/parser/snippet.rb +3 -1
  132. data/lib/solargraph/parser.rb +2 -0
  133. data/lib/solargraph/pin/base.rb +156 -84
  134. data/lib/solargraph/pin/base_variable.rb +273 -24
  135. data/lib/solargraph/pin/block.rb +29 -6
  136. data/lib/solargraph/pin/breakable.rb +7 -1
  137. data/lib/solargraph/pin/callable.rb +67 -23
  138. data/lib/solargraph/pin/closure.rb +7 -10
  139. data/lib/solargraph/pin/common.rb +36 -6
  140. data/lib/solargraph/pin/compound_statement.rb +55 -0
  141. data/lib/solargraph/pin/constant.rb +3 -5
  142. data/lib/solargraph/pin/conversions.rb +10 -4
  143. data/lib/solargraph/pin/delegated_method.rb +19 -8
  144. data/lib/solargraph/pin/documenting.rb +4 -2
  145. data/lib/solargraph/pin/instance_variable.rb +5 -1
  146. data/lib/solargraph/pin/keyword.rb +0 -4
  147. data/lib/solargraph/pin/local_variable.rb +15 -59
  148. data/lib/solargraph/pin/method.rb +205 -111
  149. data/lib/solargraph/pin/method_alias.rb +8 -0
  150. data/lib/solargraph/pin/namespace.rb +19 -12
  151. data/lib/solargraph/pin/parameter.rb +102 -36
  152. data/lib/solargraph/pin/proxy_type.rb +4 -1
  153. data/lib/solargraph/pin/reference/override.rb +1 -1
  154. data/lib/solargraph/pin/reference/require.rb +14 -14
  155. data/lib/solargraph/pin/reference/superclass.rb +2 -0
  156. data/lib/solargraph/pin/reference/type_alias.rb +16 -0
  157. data/lib/solargraph/pin/reference.rb +20 -0
  158. data/lib/solargraph/pin/search.rb +8 -7
  159. data/lib/solargraph/pin/signature.rb +15 -12
  160. data/lib/solargraph/pin/singleton.rb +11 -11
  161. data/lib/solargraph/pin/symbol.rb +2 -1
  162. data/lib/solargraph/pin/until.rb +2 -4
  163. data/lib/solargraph/pin/while.rb +2 -4
  164. data/lib/solargraph/pin.rb +2 -0
  165. data/lib/solargraph/pin_cache.rb +22 -19
  166. data/lib/solargraph/position.rb +17 -10
  167. data/lib/solargraph/range.rb +16 -15
  168. data/lib/solargraph/rbs_map/conversions.rb +278 -191
  169. data/lib/solargraph/rbs_map/core_fills.rb +18 -11
  170. data/lib/solargraph/rbs_map/core_map.rb +24 -17
  171. data/lib/solargraph/rbs_map/stdlib_map.rb +33 -5
  172. data/lib/solargraph/rbs_map.rb +76 -32
  173. data/lib/solargraph/rbs_translator.rb +206 -0
  174. data/lib/solargraph/server_methods.rb +1 -1
  175. data/lib/solargraph/shell.rb +330 -71
  176. data/lib/solargraph/source/chain/array.rb +3 -12
  177. data/lib/solargraph/source/chain/block_symbol.rb +13 -13
  178. data/lib/solargraph/source/chain/block_variable.rb +13 -13
  179. data/lib/solargraph/source/chain/call.rb +91 -119
  180. data/lib/solargraph/source/chain/class_variable.rb +1 -1
  181. data/lib/solargraph/source/chain/constant.rb +5 -1
  182. data/lib/solargraph/source/chain/global_variable.rb +1 -1
  183. data/lib/solargraph/source/chain/hash.rb +8 -5
  184. data/lib/solargraph/source/chain/head.rb +19 -19
  185. data/lib/solargraph/source/chain/if.rb +12 -10
  186. data/lib/solargraph/source/chain/instance_variable.rb +24 -1
  187. data/lib/solargraph/source/chain/link.rb +12 -22
  188. data/lib/solargraph/source/chain/literal.rb +22 -15
  189. data/lib/solargraph/source/chain/or.rb +10 -4
  190. data/lib/solargraph/source/chain/q_call.rb +2 -0
  191. data/lib/solargraph/source/chain/variable.rb +3 -1
  192. data/lib/solargraph/source/chain/z_super.rb +1 -3
  193. data/lib/solargraph/source/chain.rb +51 -38
  194. data/lib/solargraph/source/change.rb +12 -5
  195. data/lib/solargraph/source/cursor.rb +33 -18
  196. data/lib/solargraph/source/encoding_fixes.rb +6 -7
  197. data/lib/solargraph/source/source_chainer.rb +56 -32
  198. data/lib/solargraph/source/updater.rb +5 -1
  199. data/lib/solargraph/source.rb +59 -35
  200. data/lib/solargraph/source_map/clip.rb +54 -30
  201. data/lib/solargraph/source_map/data.rb +4 -1
  202. data/lib/solargraph/source_map/mapper.rb +28 -131
  203. data/lib/solargraph/source_map.rb +35 -9
  204. data/lib/solargraph/type_checker/problem.rb +3 -1
  205. data/lib/solargraph/type_checker/rules.rb +81 -8
  206. data/lib/solargraph/type_checker.rb +196 -122
  207. data/lib/solargraph/version.rb +19 -1
  208. data/lib/solargraph/workspace/config.rb +14 -11
  209. data/lib/solargraph/workspace/gemspecs.rb +367 -0
  210. data/lib/solargraph/workspace/require_paths.rb +1 -0
  211. data/lib/solargraph/workspace.rb +50 -28
  212. data/lib/solargraph/yard_map/cache.rb +25 -25
  213. data/lib/solargraph/yard_map/directives/attribute_directive.rb +65 -0
  214. data/lib/solargraph/yard_map/directives/domain_directive.rb +30 -0
  215. data/lib/solargraph/yard_map/directives/method_directive.rb +51 -0
  216. data/lib/solargraph/yard_map/directives/override_directive.rb +30 -0
  217. data/lib/solargraph/yard_map/directives/parse_directive.rb +53 -0
  218. data/lib/solargraph/yard_map/directives/visibility_directive.rb +70 -0
  219. data/lib/solargraph/yard_map/directives.rb +35 -0
  220. data/lib/solargraph/yard_map/helpers.rb +8 -3
  221. data/lib/solargraph/yard_map/macro.rb +113 -0
  222. data/lib/solargraph/yard_map/mapper/to_constant.rb +28 -28
  223. data/lib/solargraph/yard_map/mapper/to_method.rb +13 -7
  224. data/lib/solargraph/yard_map/mapper/to_namespace.rb +2 -1
  225. data/lib/solargraph/yard_map/mapper.rb +31 -8
  226. data/lib/solargraph/yard_map.rb +19 -18
  227. data/lib/solargraph/yard_tags.rb +2 -2
  228. data/lib/solargraph/yardoc.rb +7 -4
  229. data/lib/solargraph.rb +34 -10
  230. data/rbs/fills/rubygems/0/dependency.rbs +193 -0
  231. data/rbs/shims/ast/0/node.rbs +1 -1
  232. data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
  233. data/solargraph.gemspec +38 -35
  234. metadata +64 -42
  235. data/lib/solargraph/type_checker/checks.rb +0 -124
  236. data/lib/solargraph/type_checker/param_def.rb +0 -37
  237. data/lib/solargraph/yard_map/to_method.rb +0 -89
  238. data/rbs/fills/tuple/tuple.rbs +0 -149
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class YardMap
5
+ module Directives
6
+ module AttributeDirective
7
+ module_function
8
+
9
+ # @param source [Solargraph::Source]
10
+ # @param pins [Array<Solargraph::Pin::Base>]
11
+ # @param source_position [Position]
12
+ # @param comment_position [Position]
13
+ # @param directive [YARD::Tags::Directive]
14
+ # @return [Array<Solargraph::Pin::Method>]
15
+ def process_directive source, pins, source_position, comment_position, directive
16
+ new_pins = []
17
+ location = Location.new(source.filename, Range.new(comment_position, comment_position))
18
+ docstring = Solargraph::Source.parse_docstring(directive.tag.text.to_s).to_docstring
19
+ return [] if directive.tag.name.nil?
20
+ namespace = closure_at(pins, source_position)
21
+ t = directive.tag.types.nil? || directive.tag.types.empty? ? nil : directive.tag.types.join
22
+ if t.nil? || t.include?('r')
23
+ new_pins.push Solargraph::Pin::Method.new(
24
+ location: location,
25
+ closure: namespace,
26
+ name: directive.tag.name,
27
+ comments: docstring.all.to_s,
28
+ scope: namespace.is_a?(Pin::Singleton) ? :class : :instance,
29
+ visibility: :public,
30
+ explicit: false,
31
+ attribute: true,
32
+ source: :yard_map
33
+ )
34
+ end
35
+ if t.nil? || t.include?('w')
36
+ write_pin = Solargraph::Pin::Method.new(
37
+ location: location,
38
+ closure: namespace,
39
+ name: "#{directive.tag.name}=",
40
+ comments: docstring.all.to_s,
41
+ scope: namespace.is_a?(Pin::Singleton) ? :class : :instance,
42
+ visibility: :public,
43
+ attribute: true,
44
+ source: :yard_map
45
+ )
46
+ new_pins.push(write_pin)
47
+ write_pin.parameters.push Pin::Parameter.new(name: 'value', decl: :arg, closure: write_pin, source: :yard_map)
48
+ if write_pin.return_type&.defined?
49
+ write_pin.docstring.add_tag YARD::Tags::Tag.new(:param, '', write_pin.return_type.to_s.split(', '), 'value')
50
+ end
51
+ end
52
+
53
+ new_pins.compact
54
+ end
55
+
56
+ # @param [Array<Pin::Base>] pins
57
+ # @param [Position] position
58
+ # @return [Pin::Closure]
59
+ def closure_at pins, position
60
+ pins.select { |pin| pin.is_a?(Pin::Closure) and pin.location&.range&.contain?(position) }.last
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class YardMap
5
+ module Directives
6
+ module DomainDirective
7
+ module_function
8
+
9
+ # @param source [Solargraph::Source]
10
+ # @param pins [Array<Solargraph::Pin::Base>]
11
+ # @param source_position [Position]
12
+ # @param _comment_position [Position]
13
+ # @param directive [YARD::Tags::Directive]
14
+ # @return [Array<Solargraph::Pin::Method>]
15
+ def process_directive source, pins, source_position, _comment_position, directive
16
+ namespace = closure_at(pins, source_position) || Pin::ROOT_PIN
17
+ namespace.domains.concat directive.tag.types unless directive.tag.types.nil?
18
+ []
19
+ end
20
+
21
+ # @param [Array<Pin::Base>] pins
22
+ # @param [Position] position
23
+ # @return [Pin::Namespace]
24
+ def closure_at pins, position
25
+ pins.select { |pin| pin.is_a?(Pin::Namespace) and pin.location&.range&.contain?(position) }.last
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class YardMap
5
+ module Directives
6
+ module MethodDirective
7
+ module_function
8
+
9
+ # @param source [Solargraph::Source]
10
+ # @param pins [Array<Solargraph::Pin::Base>]
11
+ # @param source_position [Position]
12
+ # @param comment_position [Position]
13
+ # @param directive [YARD::Tags::Directive]
14
+ # @return [Array<Solargraph::Pin::Method>]
15
+ def process_directive source, pins, source_position, comment_position, directive
16
+ namespace = closure_at(pins, source_position) || pins.first
17
+
18
+ namespace = closure_at(pins, comment_position) if namespace.location&.range&.start&.line&.< comment_position.line # rubocop:disable Style/SafeNavigationChainLength
19
+ begin
20
+ src = Solargraph::Source.load_string("def #{directive.tag.name};end", source.filename)
21
+ region = Parser::Region.new(source: src, closure: namespace)
22
+ method_gen_pins = Parser.process_node(src.node, region).first.select { |pin| pin.is_a?(Pin::Method) }
23
+ gen_pin = method_gen_pins.last
24
+ return [] if gen_pin.nil?
25
+ # Move the location to the end of the line so it gets recognized
26
+ # as originating from a comment
27
+ shifted = Solargraph::Position.new(comment_position.line,
28
+ source.code.lines[comment_position.line].to_s.chomp.length)
29
+ comments = Solargraph::Source.parse_docstring(directive.tag.text.to_s).to_docstring.all.to_s
30
+ # @todo: Smelly instance variable access
31
+ gen_pin.instance_variable_set(:@comments, comments)
32
+ gen_pin.instance_variable_set(:@location,
33
+ Solargraph::Location.new(source.filename, Range.new(shifted, shifted)))
34
+ gen_pin.instance_variable_set(:@explicit, false)
35
+ [gen_pin]
36
+ rescue Parser::SyntaxError
37
+ # @todo Handle error in directive
38
+ []
39
+ end
40
+ end
41
+
42
+ # @param [Array<Pin::Base>] pins
43
+ # @param [Position] position
44
+ # @return [Pin::Closure]
45
+ def closure_at pins, position
46
+ pins.select { |pin| pin.is_a?(Pin::Closure) and pin.location&.range&.contain?(position) }.last
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class YardMap
5
+ module Directives
6
+ module OverrideDirective
7
+ module_function
8
+
9
+ # @param source [Solargraph::Source]
10
+ # @param _pins [Array<Solargraph::Pin::Base>]
11
+ # @param _source_position [Position]
12
+ # @param comment_position [Position]
13
+ # @param directive [YARD::Tags::Directive]
14
+ # @return [Array<Pin::Base>]
15
+ def process_directive source, _pins, _source_position, comment_position, directive
16
+ docstring = Solargraph::Source.parse_docstring(directive.tag.text.to_s).to_docstring
17
+ location = Location.new(source.filename, Range.new(comment_position, comment_position))
18
+ [Pin::Reference::Override.new(location, directive.tag.name.to_s, docstring.tags, source: :yard_map)]
19
+ end
20
+
21
+ # @param [Array<Pin::Base>] pins
22
+ # @param [Position] position
23
+ # @return [Pin::Closure]
24
+ def closure_at pins, position
25
+ pins.select { |pin| pin.is_a?(Pin::Closure) and pin.location&.range&.contain?(position) }.last
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class YardMap
5
+ module Directives
6
+ module ParseDirective
7
+ module_function
8
+
9
+ # @param source [Solargraph::Source]
10
+ # @param pins [Array<Solargraph::Pin::Base>]
11
+ # @param source_position [Position]
12
+ # @param comment_position [Position]
13
+ # @param directive [YARD::Tags::Directive]
14
+ # @return [Array<Solargraph::Pin::Base>]
15
+ def process_directive source, pins, source_position, comment_position, directive
16
+ ns = closure_at(pins, source_position)
17
+ pins_copy = pins.dup
18
+ src = Solargraph::Source.load_string(directive.tag.text.to_s, source.filename)
19
+ region = Parser::Region.new(source: src, closure: ns)
20
+ # @todo These pins may need to be marked not explicit
21
+ old_pins_index = pins.length
22
+ loff = if source.code.lines[comment_position.line].strip.end_with?('@!parse')
23
+ comment_position.line + 1
24
+ else
25
+ comment_position.line
26
+ end
27
+ Parser.process_node(src.node, region, pins_copy)
28
+ new_pins = pins_copy[old_pins_index..] || []
29
+ new_pins.each do |p|
30
+ # @todo Smelly instance variable access
31
+ next if p.location.nil?
32
+ # @sg-ignore Unresolved call to range on Solargraph::Location, nil - does not account for next clause above.
33
+ p.location.range.start.instance_variable_set(:@line, p.location.range.start.line + loff)
34
+ # @sg-ignore Unresolved call to range on Solargraph::Location, nil
35
+ p.location.range.ending.instance_variable_set(:@line, p.location.range.ending.line + loff)
36
+ end
37
+
38
+ new_pins
39
+ rescue Parser::SyntaxError
40
+ # @todo Handle parser errors in !parse directives
41
+ []
42
+ end
43
+
44
+ # @param [Array<Pin::Base>] pins
45
+ # @param [Position] position
46
+ # @return [Pin::Closure]
47
+ def closure_at pins, position
48
+ pins.select { |pin| pin.is_a?(Pin::Closure) and pin.location&.range&.contain?(position) }.last
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class YardMap
5
+ module Directives
6
+ module VisibilityDirective
7
+ module_function
8
+
9
+ VALID_VISIBILITIES = %i[public protected private].freeze
10
+
11
+ # @param source [Solargraph::Source]
12
+ # @param pins [Array<Solargraph::Pin::Base>]
13
+ # @param source_position [Position]
14
+ # @param comment_position [Position]
15
+ # @param directive [YARD::Tags::Directive]
16
+ # @return [Array<Solargraph::Pin::Base>]
17
+ def process_directive source, pins, source_position, comment_position, directive
18
+ kind = directive.tag.text&.to_sym
19
+
20
+ # @sg-ignore include? only expects Symbol, but receives Symbol or nil
21
+ return [] unless VALID_VISIBILITIES.include?(kind.to_sym)
22
+
23
+ name = directive.tag.name
24
+ closure = closure_at(pins, source_position) || pins.first
25
+ closure = closure_at(pins, comment_position) if closure.location&.range&.start&.line&.< comment_position.line # rubocop:disable Style/SafeNavigationChainLength
26
+ if closure.is_a?(Pin::Method) && no_empty_lines?(source.code, comment_position.line, source_position.line)
27
+ # @todo Smelly instance variable access
28
+ closure.instance_variable_set(:@visibility, kind)
29
+ else
30
+ namespace = closure_at(pins, source_position)
31
+ matches = pins.select do |pin|
32
+ if pin.is_a?(Pin::Method) &&
33
+ pin.name == name &&
34
+ pin.namespace == namespace &&
35
+ pin.context.scope == namespace.is_a?(Pin::Singleton)
36
+ :class
37
+ else
38
+ :instance
39
+ end
40
+ end
41
+
42
+ matches.each do |pin|
43
+ # @todo Smelly instance variable access
44
+ pin.instance_variable_set(:@visibility, kind)
45
+ end
46
+ end
47
+
48
+ []
49
+ end
50
+
51
+ # @param [String] code
52
+ # @param [Integer] line1
53
+ # @param [Integer] line2
54
+ # @return [Boolean]
55
+ # @sg-ignore return type could not be inferred
56
+ def no_empty_lines? code, line1, line2
57
+ # @sg-ignore unresolved call none? on the array.
58
+ code.lines[line1..line2].none? { |line| line.strip.empty? }
59
+ end
60
+
61
+ # @param [Array<Pin::Base>] pins
62
+ # @param [Position] position
63
+ # @return [Pin::Closure]
64
+ def closure_at pins, position
65
+ pins.select { |pin| pin.is_a?(Pin::Closure) and pin.location&.range&.contain?(position) }.last
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class YardMap
5
+ module Directives
6
+ autoload :AttributeDirective, 'solargraph/yard_map/directives/attribute_directive'
7
+ autoload :MethodDirective, 'solargraph/yard_map/directives/method_directive'
8
+ autoload :DomainDirective, 'solargraph/yard_map/directives/domain_directive'
9
+ autoload :OverrideDirective, 'solargraph/yard_map/directives/override_directive'
10
+ autoload :ParseDirective, 'solargraph/yard_map/directives/parse_directive'
11
+ autoload :VisibilityDirective, 'solargraph/yard_map/directives/visibility_directive'
12
+
13
+ # @param directive [YARD::Tags::Directive]
14
+ # @return [Class<AttributeDirective>, Class<MethodDirective>, Class<DomainDirective>, Class<OverrideDirective>, Class<ParseDirective>, Class<VisibilityDirective>, nil]
15
+ def self.for directive
16
+ case directive.tag.tag_name
17
+ when 'attribute'
18
+ AttributeDirective
19
+ when 'method'
20
+ MethodDirective
21
+ when 'domain'
22
+ DomainDirective
23
+ when 'override'
24
+ OverrideDirective
25
+ when 'parse'
26
+ ParseDirective
27
+ when 'visibility'
28
+ VisibilityDirective
29
+ else # rubocop:disable Style/EmptyElse
30
+ nil
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Solargraph
2
4
  class YardMap
3
5
  module Helpers
@@ -5,7 +7,7 @@ module Solargraph
5
7
 
6
8
  # @param code_object [YARD::CodeObjects::Base]
7
9
  # @param spec [Gem::Specification, nil]
8
- # @return [Solargraph::Location, nil]
10
+ # @return [Solargraph::Location]
9
11
  def object_location code_object, spec
10
12
  if spec.nil? || code_object.nil? || code_object.file.nil? || code_object.line.nil?
11
13
  if code_object.namespace.is_a?(YARD::CodeObjects::NamespaceObject)
@@ -14,6 +16,7 @@ module Solargraph
14
16
  end
15
17
  return Solargraph::Location.new(__FILE__, Solargraph::Range.from_to(__LINE__ - 1, 0, __LINE__ - 1, 0))
16
18
  end
19
+ # @sg-ignore flow sensitive typing should be able to identify more blocks that always return
17
20
  file = File.join(spec.full_gem_path, code_object.file)
18
21
  Solargraph::Location.new(file, Solargraph::Range.from_to(code_object.line - 1, 0, code_object.line - 1, 0))
19
22
  end
@@ -21,10 +24,12 @@ module Solargraph
21
24
  # @param code_object [YARD::CodeObjects::Base]
22
25
  # @param spec [Gem::Specification, nil]
23
26
  # @return [Solargraph::Pin::Namespace]
24
- def create_closure_namespace_for(code_object, spec)
27
+ def create_closure_namespace_for code_object, spec
25
28
  code_object_for_location = code_object
26
29
  # code_object.namespace is sometimes a YARD proxy object pointing to a method path ("Object#new")
27
- code_object_for_location = code_object.namespace if code_object.namespace.is_a?(YARD::CodeObjects::NamespaceObject)
30
+ if code_object.namespace.is_a?(YARD::CodeObjects::NamespaceObject)
31
+ code_object_for_location = code_object.namespace
32
+ end
28
33
  namespace_location = object_location(code_object_for_location, spec)
29
34
  ns_name = code_object.namespace.to_s
30
35
  if ns_name.empty?
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class YardMap
5
+ class Macro
6
+ PROCESSABLE_DIRECTIVES = %w[method attribute parse].freeze
7
+
8
+ class << self
9
+ # @param directive [YARD::Tags::Directive]
10
+ # @param method_pin [Pin::Method]
11
+ # @return [Macro]
12
+ def from_directive directive, method_pin
13
+ macro_name = directive.tag.name.empty? ? method_pin.path.downcase : directive.tag.name
14
+ method_object = method_object_from_pin(method_pin)
15
+ code = directive.tag.text.to_s.gsub(/\n(?!@!|\s)/, "\n ")
16
+ macro_object = YARD::CodeObjects::MacroObject.create(macro_name.to_s, code, method_object)
17
+ new(macro_object, method_pin, directive)
18
+ end
19
+
20
+ private
21
+
22
+ # @param method_pin [Pin::Method]
23
+ # @return [YARD::CodeObjects::MethodObject]
24
+ def method_object_from_pin method_pin
25
+ namespace_object = nil
26
+ method_pin.each_closure do |namespace_pin|
27
+ next if namespace_pin.name.empty?
28
+
29
+ namespace_object = YARD::CodeObjects::NamespaceObject.new(
30
+ namespace_object,
31
+ namespace_pin.name.to_sym
32
+ )
33
+ end
34
+ # @sg-ignore Wrong argument type for YARD::CodeObjects::MethodObject.new: namespace
35
+ # expected YARD::CodeObjects::NamespaceObject, got nil.
36
+ # False positive because namespace_object is set in the loop above.
37
+ YARD::CodeObjects::MethodObject.new(namespace_object, method_pin.name)
38
+ end
39
+ end
40
+
41
+ # @return [YARD::Tags::MacroDirective]
42
+ attr_reader :directive
43
+ # @return [YARD::CodeObjects::MacroObject]
44
+ attr_reader :macro_object
45
+
46
+ # @param macro_object [YARD::CodeObjects::MacroObject]
47
+ # @param method_pin [Pin::Method]
48
+ # @param directive [YARD::Tags::Directive]
49
+ def initialize macro_object, method_pin, directive
50
+ @macro_object = macro_object
51
+ @method_pin = method_pin
52
+ @directive = directive
53
+ end
54
+
55
+ # @return [String]
56
+ def name
57
+ @directive.tag.name.to_s
58
+ end
59
+
60
+ # @return [String]
61
+ def text
62
+ @directive.tag.text.to_s
63
+ end
64
+
65
+ # @return [YARD::Tags::Tag]
66
+ def tag
67
+ @directive.tag
68
+ end
69
+
70
+ # @param chain [Source::Chain]
71
+ # @param pin [Pin::Closure]
72
+ # @param source_map [SourceMap]
73
+ # @return [Array<Pin::Base>]
74
+ def generate_pins_from chain, pin, source_map
75
+ call_location = Solargraph::Location.from_node(chain.node)
76
+ # @param generated_pins [Array<Pin::Base>]
77
+ generate_yardoc_from(chain, source_map).reduce([]) do |generated_pins, directive|
78
+ directive_processor = YardMap::Directives.for(directive)
79
+ next generated_pins unless directive_processor && call_location
80
+ generated_pins + directive_processor.process_directive(
81
+ source_map.source, source_map.pins, call_location.range.start, call_location.range.start, directive
82
+ )
83
+ end
84
+ end
85
+
86
+ private
87
+
88
+ # @param chain [Solargraph::Source::Chain]
89
+ # @param [SourceMap] source_map
90
+ # @return [Array<YARD::Tags::Directive>]
91
+ def generate_yardoc_from chain, source_map
92
+ name = chain.links.last.word
93
+ # @sg-ignore chain.links.last is assumed to be a Chain::Call
94
+ values = chain.links.last.arguments.map(&:node).map { |arg| Solargraph::Parser::ParserGem::NodeMethods.simple_convert(arg).to_s }
95
+ # @sg-ignore chain.node is assumed to exist
96
+ code = source_map.source.code_for(chain.node)
97
+ expanded_comment = macro_object.expand([name, *values], code)
98
+ .gsub(/\n(?!@!|\s)/, "\n ")
99
+ directives = Solargraph::Source.parse_docstring(expanded_comment).directives.select do |directive|
100
+ PROCESSABLE_DIRECTIVES.include?(directive.tag.tag_name)
101
+ end
102
+ directives.each do |directive|
103
+ # @sg-ignore chain.node is assumed to exist
104
+ comments = source_map.source.comments_for(chain.node)
105
+ if comments&.length&.positive? && directive.tag.tag_name != 'parse'
106
+ directive.tag.text += "\n#{comments}"
107
+ end
108
+ end
109
+ directives
110
+ end
111
+ end
112
+ end
113
+ end
@@ -1,28 +1,28 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- class YardMap
5
- class Mapper
6
- module ToConstant
7
- extend YardMap::Helpers
8
-
9
- # @param code_object [YARD::CodeObjects::Base]
10
- # @param closure [Pin::Closure, nil]
11
- # @param spec [Gem::Specification, nil]
12
- # @return [Pin::Constant]
13
- def self.make code_object, closure = nil, spec = nil
14
- closure ||= create_closure_namespace_for(code_object, spec)
15
-
16
- Pin::Constant.new(
17
- location: object_location(code_object, spec),
18
- closure: closure,
19
- name: code_object.name.to_s,
20
- comments: code_object.docstring ? code_object.docstring.all.to_s : '',
21
- visibility: code_object.visibility,
22
- source: :yardoc
23
- )
24
- end
25
- end
26
- end
27
- end
28
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class YardMap
5
+ class Mapper
6
+ module ToConstant
7
+ extend YardMap::Helpers
8
+
9
+ # @param code_object [YARD::CodeObjects::Base]
10
+ # @param closure [Pin::Closure, nil]
11
+ # @param spec [Gem::Specification, nil]
12
+ # @return [Pin::Constant]
13
+ def self.make code_object, closure = nil, spec = nil
14
+ closure ||= create_closure_namespace_for(code_object, spec)
15
+
16
+ Pin::Constant.new(
17
+ location: object_location(code_object, spec),
18
+ closure: closure,
19
+ name: code_object.name.to_s,
20
+ comments: code_object.docstring ? code_object.docstring.all.to_s : '',
21
+ visibility: code_object.visibility,
22
+ source: :yardoc
23
+ )
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -6,10 +6,11 @@ module Solargraph
6
6
  module ToMethod
7
7
  extend YardMap::Helpers
8
8
 
9
+ # @type [Hash{Array<String, Symbol, String> => Symbol}]
9
10
  VISIBILITY_OVERRIDE = {
10
11
  # YARD pays attention to 'private' statements prior to class methods but shouldn't
11
- ["Rails::Engine", :class, "find_root_with_flag"] => :public
12
- }
12
+ ['Rails::Engine', :class, 'find_root_with_flag'] => :public
13
+ }.freeze
13
14
 
14
15
  # @param code_object [YARD::CodeObjects::MethodObject]
15
16
  # @param name [String, nil]
@@ -25,10 +26,15 @@ module Solargraph
25
26
  return_type = ComplexType::SELF if name == 'new'
26
27
  comments = code_object.docstring ? code_object.docstring.all.to_s : ''
27
28
  final_scope = scope || code_object.scope
29
+ # @sg-ignore Need to add nil check here
28
30
  override_key = [closure.path, final_scope, name]
29
31
  final_visibility = VISIBILITY_OVERRIDE[override_key]
32
+ # @sg-ignore Need to add nil check here
30
33
  final_visibility ||= VISIBILITY_OVERRIDE[[closure.path, final_scope]]
31
- final_visibility ||= :private if closure.path == 'Kernel' && Kernel.private_instance_methods(false).include?(name.to_sym)
34
+ # @sg-ignore Need to add nil check here
35
+ if closure.path == 'Kernel' && Kernel.private_method_defined?(name.to_sym, false)
36
+ final_visibility ||= :private
37
+ end
32
38
  final_visibility ||= visibility
33
39
  final_visibility ||= :private if code_object.module_function? && final_scope == :instance
34
40
  final_visibility ||= :public if code_object.module_function? && final_scope == :class
@@ -46,9 +52,10 @@ module Solargraph
46
52
  explicit: code_object.is_explicit?,
47
53
  return_type: return_type,
48
54
  parameters: [],
49
- source: :yardoc,
55
+ source: :yardoc
50
56
  )
51
57
  else
58
+ # @sg-ignore Need to add nil check here
52
59
  pin = Pin::Method.new(
53
60
  location: location,
54
61
  closure: closure,
@@ -61,7 +68,7 @@ module Solargraph
61
68
  return_type: return_type,
62
69
  attribute: code_object.is_attribute?,
63
70
  parameters: [],
64
- source: :yardoc,
71
+ source: :yardoc
65
72
  )
66
73
  pin.parameters.concat get_parameters(code_object, location, comments, pin)
67
74
  pin.parameters.freeze
@@ -85,7 +92,6 @@ module Solargraph
85
92
  # HACK: Skip `nil` and `self` parameters that are sometimes emitted
86
93
  # for methods defined in C
87
94
  # See https://github.com/castwide/solargraph/issues/345
88
- # @sg-ignore https://github.com/castwide/solargraph/pull/1114
89
95
  code_object.parameters.select { |a| a[0] && a[0] != 'self' }.map do |a|
90
96
  Solargraph::Pin::Parameter.new(
91
97
  location: location,
@@ -95,7 +101,7 @@ module Solargraph
95
101
  presence: nil,
96
102
  decl: arg_type(a),
97
103
  asgn_code: a[1],
98
- source: :yardoc,
104
+ source: :yardoc
99
105
  )
100
106
  end
101
107
  end
@@ -21,8 +21,9 @@ module Solargraph
21
21
  type: code_object.is_a?(YARD::CodeObjects::ClassObject) ? :class : :module,
22
22
  visibility: code_object.visibility,
23
23
  closure: closure,
24
+ # @sg-ignore need to add a nil check here
24
25
  gates: closure.gates,
25
- source: :yardoc,
26
+ source: :yardoc
26
27
  )
27
28
  end
28
29
  end