solargraph 0.56.0 → 0.58.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -0
  3. data/.github/workflows/linting.yml +127 -0
  4. data/.github/workflows/plugins.yml +183 -7
  5. data/.github/workflows/rspec.yml +55 -5
  6. data/.github/workflows/typecheck.yml +6 -3
  7. data/.gitignore +6 -0
  8. data/.overcommit.yml +72 -0
  9. data/.rspec +1 -0
  10. data/.rubocop.yml +66 -0
  11. data/.rubocop_todo.yml +1279 -0
  12. data/.yardopts +1 -0
  13. data/CHANGELOG.md +92 -1
  14. data/README.md +8 -4
  15. data/Rakefile +125 -13
  16. data/bin/solargraph +3 -0
  17. data/lib/solargraph/api_map/cache.rb +110 -109
  18. data/lib/solargraph/api_map/constants.rb +279 -0
  19. data/lib/solargraph/api_map/index.rb +193 -175
  20. data/lib/solargraph/api_map/source_to_yard.rb +97 -88
  21. data/lib/solargraph/api_map/store.rb +384 -266
  22. data/lib/solargraph/api_map.rb +945 -973
  23. data/lib/solargraph/bench.rb +1 -0
  24. data/lib/solargraph/complex_type/type_methods.rb +228 -222
  25. data/lib/solargraph/complex_type/unique_type.rb +482 -475
  26. data/lib/solargraph/complex_type.rb +444 -423
  27. data/lib/solargraph/convention/active_support_concern.rb +111 -0
  28. data/lib/solargraph/convention/base.rb +17 -0
  29. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -0
  30. data/lib/solargraph/convention/data_definition/data_definition_node.rb +91 -0
  31. data/lib/solargraph/convention/data_definition.rb +105 -0
  32. data/lib/solargraph/convention/gemspec.rb +3 -2
  33. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +61 -60
  34. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +102 -100
  35. data/lib/solargraph/convention/struct_definition.rb +164 -101
  36. data/lib/solargraph/convention.rb +32 -2
  37. data/lib/solargraph/diagnostics/require_not_found.rb +53 -53
  38. data/lib/solargraph/diagnostics/rubocop.rb +118 -113
  39. data/lib/solargraph/diagnostics/rubocop_helpers.rb +68 -66
  40. data/lib/solargraph/diagnostics/type_check.rb +55 -55
  41. data/lib/solargraph/doc_map.rb +439 -405
  42. data/lib/solargraph/environ.rb +9 -2
  43. data/lib/solargraph/equality.rb +34 -33
  44. data/lib/solargraph/gem_pins.rb +98 -88
  45. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  46. data/lib/solargraph/language_server/host/dispatch.rb +130 -128
  47. data/lib/solargraph/language_server/host/message_worker.rb +112 -109
  48. data/lib/solargraph/language_server/host/sources.rb +99 -99
  49. data/lib/solargraph/language_server/host.rb +878 -871
  50. data/lib/solargraph/language_server/message/base.rb +2 -1
  51. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +114 -114
  52. data/lib/solargraph/language_server/message/extended/document.rb +23 -23
  53. data/lib/solargraph/language_server/message/text_document/completion.rb +56 -56
  54. data/lib/solargraph/language_server/message/text_document/definition.rb +40 -38
  55. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +26 -26
  56. data/lib/solargraph/language_server/message/text_document/formatting.rb +148 -131
  57. data/lib/solargraph/language_server/message/text_document/hover.rb +58 -58
  58. data/lib/solargraph/language_server/message/text_document/signature_help.rb +24 -24
  59. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -24
  60. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +2 -0
  61. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -23
  62. data/lib/solargraph/language_server/progress.rb +8 -0
  63. data/lib/solargraph/language_server/request.rb +4 -1
  64. data/lib/solargraph/library.rb +683 -666
  65. data/lib/solargraph/location.rb +82 -79
  66. data/lib/solargraph/logging.rb +37 -28
  67. data/lib/solargraph/page.rb +3 -0
  68. data/lib/solargraph/parser/comment_ripper.rb +69 -62
  69. data/lib/solargraph/parser/flow_sensitive_typing.rb +255 -227
  70. data/lib/solargraph/parser/node_processor/base.rb +92 -87
  71. data/lib/solargraph/parser/node_processor.rb +62 -46
  72. data/lib/solargraph/parser/parser_gem/class_methods.rb +149 -159
  73. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -0
  74. data/lib/solargraph/parser/parser_gem/node_chainer.rb +166 -164
  75. data/lib/solargraph/parser/parser_gem/node_methods.rb +486 -497
  76. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -21
  77. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +59 -59
  78. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +15 -15
  79. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +46 -45
  80. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +1 -21
  81. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +53 -53
  82. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +23 -21
  83. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +40 -40
  84. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +29 -29
  85. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +59 -53
  86. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +0 -22
  87. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -41
  88. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -16
  89. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +38 -37
  90. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +52 -43
  91. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +291 -271
  92. data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +1 -0
  93. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +29 -29
  94. data/lib/solargraph/parser/parser_gem/node_processors.rb +70 -66
  95. data/lib/solargraph/parser/region.rb +69 -66
  96. data/lib/solargraph/parser/snippet.rb +17 -15
  97. data/lib/solargraph/pin/base.rb +729 -651
  98. data/lib/solargraph/pin/base_variable.rb +126 -125
  99. data/lib/solargraph/pin/block.rb +104 -103
  100. data/lib/solargraph/pin/breakable.rb +9 -9
  101. data/lib/solargraph/pin/callable.rb +231 -218
  102. data/lib/solargraph/pin/closure.rb +72 -74
  103. data/lib/solargraph/pin/common.rb +79 -75
  104. data/lib/solargraph/pin/constant.rb +2 -0
  105. data/lib/solargraph/pin/conversions.rb +123 -123
  106. data/lib/solargraph/pin/delegated_method.rb +120 -120
  107. data/lib/solargraph/pin/documenting.rb +114 -114
  108. data/lib/solargraph/pin/instance_variable.rb +34 -34
  109. data/lib/solargraph/pin/keyword.rb +20 -20
  110. data/lib/solargraph/pin/local_variable.rb +75 -76
  111. data/lib/solargraph/pin/method.rb +672 -651
  112. data/lib/solargraph/pin/method_alias.rb +34 -31
  113. data/lib/solargraph/pin/namespace.rb +115 -115
  114. data/lib/solargraph/pin/parameter.rb +275 -261
  115. data/lib/solargraph/pin/proxy_type.rb +39 -35
  116. data/lib/solargraph/pin/reference/override.rb +47 -33
  117. data/lib/solargraph/pin/reference/superclass.rb +15 -10
  118. data/lib/solargraph/pin/reference.rb +39 -22
  119. data/lib/solargraph/pin/search.rb +61 -56
  120. data/lib/solargraph/pin/signature.rb +61 -59
  121. data/lib/solargraph/pin/symbol.rb +53 -48
  122. data/lib/solargraph/pin/until.rb +18 -18
  123. data/lib/solargraph/pin/while.rb +18 -18
  124. data/lib/solargraph/pin.rb +44 -44
  125. data/lib/solargraph/pin_cache.rb +245 -185
  126. data/lib/solargraph/position.rb +132 -116
  127. data/lib/solargraph/range.rb +112 -107
  128. data/lib/solargraph/rbs_map/conversions.rb +823 -773
  129. data/lib/solargraph/rbs_map/core_fills.rb +18 -0
  130. data/lib/solargraph/rbs_map/core_map.rb +58 -51
  131. data/lib/solargraph/rbs_map/stdlib_map.rb +43 -43
  132. data/lib/solargraph/rbs_map.rb +163 -150
  133. data/lib/solargraph/shell.rb +352 -268
  134. data/lib/solargraph/source/chain/call.rb +337 -333
  135. data/lib/solargraph/source/chain/constant.rb +26 -89
  136. data/lib/solargraph/source/chain/hash.rb +34 -34
  137. data/lib/solargraph/source/chain/if.rb +28 -28
  138. data/lib/solargraph/source/chain/instance_variable.rb +13 -13
  139. data/lib/solargraph/source/chain/link.rb +11 -2
  140. data/lib/solargraph/source/chain/literal.rb +48 -48
  141. data/lib/solargraph/source/chain/or.rb +23 -23
  142. data/lib/solargraph/source/chain.rb +291 -282
  143. data/lib/solargraph/source/change.rb +82 -82
  144. data/lib/solargraph/source/cursor.rb +166 -167
  145. data/lib/solargraph/source/encoding_fixes.rb +23 -23
  146. data/lib/solargraph/source/source_chainer.rb +194 -194
  147. data/lib/solargraph/source/updater.rb +55 -55
  148. data/lib/solargraph/source.rb +498 -495
  149. data/lib/solargraph/source_map/clip.rb +226 -234
  150. data/lib/solargraph/source_map/data.rb +34 -30
  151. data/lib/solargraph/source_map/mapper.rb +259 -259
  152. data/lib/solargraph/source_map.rb +212 -200
  153. data/lib/solargraph/type_checker/checks.rb +124 -124
  154. data/lib/solargraph/type_checker/param_def.rb +37 -35
  155. data/lib/solargraph/type_checker/problem.rb +32 -32
  156. data/lib/solargraph/type_checker/rules.rb +84 -62
  157. data/lib/solargraph/type_checker.rb +814 -699
  158. data/lib/solargraph/version.rb +5 -5
  159. data/lib/solargraph/workspace/config.rb +255 -239
  160. data/lib/solargraph/workspace/require_paths.rb +97 -0
  161. data/lib/solargraph/workspace.rb +220 -249
  162. data/lib/solargraph/yard_map/helpers.rb +44 -16
  163. data/lib/solargraph/yard_map/mapper/to_constant.rb +5 -5
  164. data/lib/solargraph/yard_map/mapper/to_method.rb +130 -134
  165. data/lib/solargraph/yard_map/mapper/to_namespace.rb +31 -30
  166. data/lib/solargraph/yard_map/mapper.rb +79 -79
  167. data/lib/solargraph/yard_map/to_method.rb +89 -88
  168. data/lib/solargraph/yardoc.rb +87 -49
  169. data/lib/solargraph.rb +105 -90
  170. data/rbs/fills/bundler/0/bundler.rbs +4271 -0
  171. data/rbs/fills/open3/0/open3.rbs +172 -0
  172. data/rbs/fills/rubygems/0/basic_specification.rbs +326 -0
  173. data/rbs/fills/rubygems/0/errors.rbs +364 -0
  174. data/rbs/fills/rubygems/0/spec_fetcher.rbs +107 -0
  175. data/rbs/fills/rubygems/0/specification.rbs +1753 -0
  176. data/rbs/fills/{tuple.rbs → tuple/tuple.rbs} +2 -3
  177. data/rbs/shims/ast/0/node.rbs +5 -0
  178. data/rbs/shims/ast/2.4/.rbs_meta.yaml +9 -0
  179. data/rbs/shims/ast/2.4/ast.rbs +73 -0
  180. data/rbs/shims/parser/3.2.0.1/builders/default.rbs +195 -0
  181. data/rbs/shims/parser/3.2.0.1/manifest.yaml +7 -0
  182. data/rbs/shims/parser/3.2.0.1/parser.rbs +201 -0
  183. data/rbs/shims/parser/3.2.0.1/polyfill.rbs +4 -0
  184. data/rbs/shims/thor/1.2.0.1/.rbs_meta.yaml +9 -0
  185. data/rbs/shims/thor/1.2.0.1/manifest.yaml +7 -0
  186. data/rbs/shims/thor/1.2.0.1/thor.rbs +17 -0
  187. data/rbs_collection.yaml +4 -4
  188. data/solargraph.gemspec +26 -5
  189. metadata +187 -15
  190. data/lib/.rubocop.yml +0 -22
  191. data/lib/solargraph/parser/node_methods.rb +0 -97
@@ -1,100 +1,102 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- module Convention
5
- module StructDefinition
6
- # A node wrapper for a Struct definition via inheritance.
7
- # @example
8
- # class MyStruct < Struct.new(:bar, :baz)
9
- # def foo
10
- # end
11
- # end
12
- class StructDefintionNode
13
- class << self
14
- # @example
15
- # s(:class,
16
- # s(:const, nil, :Foo),
17
- # s(:send,
18
- # s(:const, nil, :Struct), :new,
19
- # s(:sym, :bar),
20
- # s(:sym, :baz)),
21
- # s(:hash,
22
- # s(:pair,
23
- # s(:sym, :keyword_init),
24
- # s(:true)))),
25
- # s(:def, :foo,
26
- # s(:args),
27
- # s(:send, nil, :bar)))
28
- def valid?(node)
29
- return false unless node&.type == :class
30
-
31
- struct_definition_node?(node.children[1])
32
- end
33
-
34
- private
35
-
36
- # @param struct_node [Parser::AST::Node]
37
- # @return [Boolean]
38
- def struct_definition_node?(struct_node)
39
- return false unless struct_node.is_a?(::Parser::AST::Node)
40
- return false unless struct_node&.type == :send
41
- return false unless struct_node.children[0]&.type == :const
42
- return false unless struct_node.children[0].children[1] == :Struct
43
- return false unless struct_node.children[1] == :new
44
-
45
- true
46
- end
47
- end
48
-
49
- # @return [Parser::AST::Node]
50
- def initialize(node)
51
- @node = node
52
- end
53
-
54
- # @return [String]
55
- def class_name
56
- Parser::NodeMethods.unpack_name(node)
57
- end
58
-
59
- # @return [Array<Array(Parser::AST::Node, String)>]
60
- def attributes
61
- struct_attribute_nodes.map do |struct_def_param|
62
- next unless struct_def_param.type == :sym
63
- [struct_def_param, struct_def_param.children[0].to_s]
64
- end.compact
65
- end
66
-
67
- def keyword_init?
68
- keyword_init_param = struct_attribute_nodes.find do |struct_def_param|
69
- struct_def_param.type == :hash && struct_def_param.children[0].type == :pair &&
70
- struct_def_param.children[0].children[0].children[0] == :keyword_init
71
- end
72
-
73
- return false if keyword_init_param.nil?
74
-
75
- keyword_init_param.children[0].children[1].type == :true
76
- end
77
-
78
- # @return [Parser::AST::Node]
79
- def body_node
80
- node.children[2]
81
- end
82
-
83
- private
84
-
85
- # @return [Parser::AST::Node]
86
- attr_reader :node
87
-
88
- # @return [Parser::AST::Node]
89
- def struct_node
90
- node.children[1]
91
- end
92
-
93
- # @return [Array<Parser::AST::Node>]
94
- def struct_attribute_nodes
95
- struct_node.children[2..-1]
96
- end
97
- end
98
- end
99
- end
100
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Convention
5
+ module StructDefinition
6
+ # A node wrapper for a Struct definition via inheritance.
7
+ # @example
8
+ # class MyStruct < Struct.new(:bar, :baz)
9
+ # def foo
10
+ # end
11
+ # end
12
+ class StructDefintionNode
13
+ class << self
14
+ # @example
15
+ # s(:class,
16
+ # s(:const, nil, :Foo),
17
+ # s(:send,
18
+ # s(:const, nil, :Struct), :new,
19
+ # s(:sym, :bar),
20
+ # s(:sym, :baz)),
21
+ # s(:hash,
22
+ # s(:pair,
23
+ # s(:sym, :keyword_init),
24
+ # s(:true)))),
25
+ # s(:def, :foo,
26
+ # s(:args),
27
+ # s(:send, nil, :bar)))
28
+ #
29
+ # @param node [Parser::AST::Node]
30
+ def match?(node)
31
+ return false unless node&.type == :class
32
+
33
+ struct_definition_node?(node.children[1])
34
+ end
35
+
36
+ private
37
+
38
+ # @param struct_node [Parser::AST::Node]
39
+ # @return [Boolean]
40
+ def struct_definition_node?(struct_node)
41
+ return false unless struct_node.is_a?(::Parser::AST::Node)
42
+ return false unless struct_node&.type == :send
43
+ return false unless struct_node.children[0]&.type == :const
44
+ return false unless struct_node.children[0].children[1] == :Struct
45
+ return false unless struct_node.children[1] == :new
46
+
47
+ true
48
+ end
49
+ end
50
+
51
+ # @param node [Parser::AST::Node]
52
+ def initialize(node)
53
+ @node = node
54
+ end
55
+
56
+ # @return [String]
57
+ def class_name
58
+ Parser::NodeMethods.unpack_name(node)
59
+ end
60
+
61
+ # @return [Array<Array(Parser::AST::Node, String)>]
62
+ def attributes
63
+ struct_attribute_nodes.map do |struct_def_param|
64
+ next unless struct_def_param.type == :sym
65
+ [struct_def_param, struct_def_param.children[0].to_s]
66
+ end.compact
67
+ end
68
+
69
+ def keyword_init?
70
+ keyword_init_param = struct_attribute_nodes.find do |struct_def_param|
71
+ struct_def_param.type == :hash && struct_def_param.children[0].type == :pair &&
72
+ struct_def_param.children[0].children[0].children[0] == :keyword_init
73
+ end
74
+
75
+ return false if keyword_init_param.nil?
76
+
77
+ keyword_init_param.children[0].children[1].type == :true
78
+ end
79
+
80
+ # @return [Parser::AST::Node]
81
+ def body_node
82
+ node.children[2]
83
+ end
84
+
85
+ private
86
+
87
+ # @return [Parser::AST::Node]
88
+ attr_reader :node
89
+
90
+ # @return [Parser::AST::Node]
91
+ def struct_node
92
+ node.children[1]
93
+ end
94
+
95
+ # @return [Array<Parser::AST::Node>]
96
+ def struct_attribute_nodes
97
+ struct_node.children[2..-1]
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -1,101 +1,164 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- module Convention
5
- module StructDefinition
6
- autoload :StructDefintionNode, 'solargraph/convention/struct_definition/struct_definition_node'
7
- autoload :StructAssignmentNode, 'solargraph/convention/struct_definition/struct_assignment_node'
8
-
9
- module NodeProcessors
10
- class StructNode < Parser::NodeProcessor::Base
11
- def process
12
- return if struct_definition_node.nil?
13
-
14
- loc = get_node_location(node)
15
- nspin = Solargraph::Pin::Namespace.new(
16
- type: :class,
17
- location: loc,
18
- closure: region.closure,
19
- name: struct_definition_node.class_name,
20
- comments: comments_for(node),
21
- visibility: :public,
22
- gates: region.closure.gates.freeze
23
- )
24
- pins.push nspin
25
-
26
- # define initialize method
27
- initialize_method_pin = Pin::Method.new(
28
- name: 'initialize',
29
- parameters: [],
30
- scope: :instance,
31
- location: get_node_location(node),
32
- closure: nspin,
33
- visibility: :private,
34
- comments: comments_for(node)
35
- )
36
-
37
- pins.push initialize_method_pin
38
-
39
- struct_definition_node.attributes.map do |attribute_node, attribute_name|
40
- initialize_method_pin.parameters.push(
41
- Pin::Parameter.new(
42
- name: attribute_name,
43
- decl: struct_definition_node.keyword_init? ? :kwarg : :arg,
44
- location: get_node_location(attribute_node),
45
- closure: initialize_method_pin
46
- )
47
- )
48
- end
49
-
50
- # define attribute accessors and instance variables
51
- struct_definition_node.attributes.each do |attribute_node, attribute_name|
52
- [attribute_name, "#{attribute_name}="].each do |name|
53
- method_pin = Pin::Method.new(
54
- name: name,
55
- parameters: [],
56
- scope: :instance,
57
- location: get_node_location(attribute_node),
58
- closure: nspin,
59
- comments: attribute_comments(attribute_node, attribute_name),
60
- visibility: :public
61
- )
62
-
63
- pins.push method_pin
64
-
65
- next unless name.include?('=') # setter
66
- pins.push Pin::InstanceVariable.new(name: "@#{attribute_name}",
67
- closure: method_pin,
68
- location: get_node_location(attribute_node),
69
- comments: attribute_comments(attribute_node, attribute_name))
70
- end
71
- end
72
-
73
- process_children region.update(closure: nspin, visibility: :public)
74
- end
75
-
76
- private
77
-
78
- # @return [StructDefintionNode, nil]
79
- def struct_definition_node
80
- @struct_definition_node ||= if StructDefintionNode.valid?(node)
81
- StructDefintionNode.new(node)
82
- elsif StructAssignmentNode.valid?(node)
83
- StructAssignmentNode.new(node)
84
- end
85
- end
86
-
87
- # @param attribute_node [Parser::AST::Node]
88
- # @return [String, nil]
89
- def attribute_comments(attribute_node, attribute_name)
90
- struct_comments = comments_for(attribute_node)
91
- return if struct_comments.nil? || struct_comments.empty?
92
-
93
- struct_comments.split("\n").find do |row|
94
- row.include?(attribute_name)
95
- end&.gsub('@param', '@return')&.gsub(attribute_name, '')
96
- end
97
- end
98
- end
99
- end
100
- end
101
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Convention
5
+ module StructDefinition
6
+ autoload :StructDefintionNode, 'solargraph/convention/struct_definition/struct_definition_node'
7
+ autoload :StructAssignmentNode, 'solargraph/convention/struct_definition/struct_assignment_node'
8
+
9
+ module NodeProcessors
10
+ class StructNode < Parser::NodeProcessor::Base
11
+ # @return [Boolean] continue processing the next processor of the same node.
12
+ def process
13
+ return true if struct_definition_node.nil?
14
+
15
+ loc = get_node_location(node)
16
+ nspin = Solargraph::Pin::Namespace.new(
17
+ type: :class,
18
+ location: loc,
19
+ closure: region.closure,
20
+ name: struct_definition_node.class_name,
21
+ docstring: docstring,
22
+ visibility: :public,
23
+ gates: region.closure.gates.freeze,
24
+ source: :struct_definition
25
+ )
26
+ pins.push nspin
27
+
28
+ # define initialize method
29
+ initialize_method_pin = Pin::Method.new(
30
+ name: 'initialize',
31
+ parameters: [],
32
+ scope: :instance,
33
+ location: get_node_location(node),
34
+ closure: nspin,
35
+ visibility: :private,
36
+ docstring: docstring,
37
+ source: :struct_definition
38
+ )
39
+
40
+ pins.push initialize_method_pin
41
+
42
+ struct_definition_node.attributes.map do |attribute_node, attribute_name|
43
+ initialize_method_pin.parameters.push(
44
+ Pin::Parameter.new(
45
+ name: attribute_name,
46
+ decl: struct_definition_node.keyword_init? ? :kwarg : :arg,
47
+ location: get_node_location(attribute_node),
48
+ closure: initialize_method_pin,
49
+ source: :struct_definition
50
+ )
51
+ )
52
+ end
53
+
54
+ # define attribute accessors and instance variables
55
+ struct_definition_node.attributes.each do |attribute_node, attribute_name|
56
+ [attribute_name, "#{attribute_name}="].each do |name|
57
+ docs = docstring.tags.find { |t| t.tag_name == 'param' && t.name == attribute_name }
58
+
59
+ attribute_type = ComplexType.parse(tag_string(docs))
60
+ return_type_comment = attribute_comment(docs, false)
61
+ param_comment = attribute_comment(docs, true)
62
+
63
+ method_pin = Pin::Method.new(
64
+ name: name,
65
+ parameters: [],
66
+ scope: :instance,
67
+ location: get_node_location(attribute_node),
68
+ closure: nspin,
69
+ docstring: YARD::Docstring.new(return_type_comment),
70
+ # even assignments return the value
71
+ comments: return_type_comment,
72
+ return_type: attribute_type,
73
+ visibility: :public,
74
+ source: :struct_definition
75
+ )
76
+
77
+ if name.end_with?('=')
78
+ method_pin.parameters << Pin::Parameter.new(
79
+ name: attribute_name,
80
+ location: get_node_location(attribute_node),
81
+ closure: method_pin,
82
+ return_type: attribute_type,
83
+ comments: param_comment,
84
+ source: :struct_definition
85
+ )
86
+
87
+ pins.push Pin::InstanceVariable.new(name: "@#{attribute_name}",
88
+ closure: method_pin,
89
+ location: get_node_location(attribute_node),
90
+ return_type: attribute_type,
91
+ comments: "@type [#{attribute_type.rooted_tags}]",
92
+ source: :struct_definition)
93
+ end
94
+
95
+ pins.push method_pin
96
+ end
97
+ end
98
+
99
+ process_children region.update(closure: nspin, visibility: :public)
100
+ false
101
+ end
102
+
103
+ private
104
+
105
+ # @return [StructDefintionNode, StructAssignmentNode, nil]
106
+ def struct_definition_node
107
+ @struct_definition_node ||= if StructDefintionNode.match?(node)
108
+ StructDefintionNode.new(node)
109
+ elsif StructAssignmentNode.match?(node)
110
+ StructAssignmentNode.new(node)
111
+ end
112
+ end
113
+
114
+ # Gets/generates the relevant docstring for this struct & it's attributes
115
+ # @return [YARD::Docstring]
116
+ def docstring
117
+ @docstring ||= parse_comments
118
+ end
119
+
120
+ # Parses any relevant comments for a struct int a yard docstring
121
+ # @return [YARD::Docstring]
122
+ def parse_comments
123
+ struct_comments = comments_for(node) || ''
124
+ struct_definition_node.attributes.each do |attr_node, attr_name|
125
+ comment = comments_for(attr_node)
126
+ next if comment.nil?
127
+
128
+ # We should support specific comments for an attribute, and that can be either a @return on an @param
129
+ # But since we merge into the struct_comments, then we should interpret either as a param
130
+ comment = "@param #{attr_name}#{comment[7..]}" if comment.start_with?('@return')
131
+
132
+ struct_comments += "\n#{comment}"
133
+ end
134
+
135
+ Solargraph::Source.parse_docstring(struct_comments).to_docstring
136
+ end
137
+
138
+ # @param tag [YARD::Tags::Tag, nil] The param tag for this attribute.xtract_
139
+ #
140
+ # @return [String]
141
+ def tag_string(tag)
142
+ tag&.types&.join(',') || 'undefined'
143
+ end
144
+
145
+ # @param tag [YARD::Tags::Tag, nil] The param tag for this attribute. If nil, this method is a no-op
146
+ # @param for_setter [Boolean] If true, will return a @param tag instead of a @return tag
147
+ #
148
+ # @return [String] The formatted comment for the attribute
149
+ def attribute_comment(tag, for_setter)
150
+ return "" if tag.nil?
151
+
152
+ suffix = "[#{tag_string(tag)}] #{tag.text}"
153
+
154
+ if for_setter
155
+ "@param #{tag.name} #{suffix}"
156
+ else
157
+ "@return #{suffix}"
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
-
4
3
  module Solargraph
5
4
  # Conventions provide a way to modify an ApiMap based on expectations about
6
5
  # one of its sources.
@@ -11,6 +10,8 @@ module Solargraph
11
10
  autoload :Gemspec, 'solargraph/convention/gemspec'
12
11
  autoload :Rakefile, 'solargraph/convention/rakefile'
13
12
  autoload :StructDefinition, 'solargraph/convention/struct_definition'
13
+ autoload :DataDefinition, 'solargraph/convention/data_definition'
14
+ autoload :ActiveSupportConcern, 'solargraph/convention/active_support_concern'
14
15
 
15
16
  # @type [Set<Convention::Base>]
16
17
  @@conventions = Set.new
@@ -21,6 +22,12 @@ module Solargraph
21
22
  @@conventions.add convention.new
22
23
  end
23
24
 
25
+ # @param convention [Class<Convention::Base>]
26
+ # @return [void]
27
+ def self.unregister convention
28
+ @@conventions.delete_if { |c| c.is_a?(convention) }
29
+ end
30
+
24
31
  # @param source_map [SourceMap]
25
32
  # @return [Environ]
26
33
  def self.for_local(source_map)
@@ -31,7 +38,7 @@ module Solargraph
31
38
  result
32
39
  end
33
40
 
34
- # @param yard_map [DocMap]
41
+ # @param doc_map [DocMap]
35
42
  # @return [Environ]
36
43
  def self.for_global(doc_map)
37
44
  result = Environ.new
@@ -41,8 +48,31 @@ module Solargraph
41
48
  result
42
49
  end
43
50
 
51
+ # Provides any additional method pins based on the described object.
52
+ #
53
+ # @param api_map [ApiMap]
54
+ # @param rooted_tag [String] A fully qualified namespace, with
55
+ # generic parameter values if applicable
56
+ # @param scope [Symbol] :class or :instance
57
+ # @param visibility [Array<Symbol>] :public, :protected, and/or :private
58
+ # @param deep [Boolean]
59
+ # @param skip [Set<String>]
60
+ # @param no_core [Boolean] Skip core classes if true
61
+ #
62
+ # @return [Environ]
63
+ def self.for_object api_map, rooted_tag, scope, visibility,
64
+ deep, skip, no_core
65
+ result = Environ.new
66
+ @@conventions.each do |conv|
67
+ result.merge conv.object(api_map, rooted_tag, scope, visibility,
68
+ deep, skip, no_core)
69
+ end
70
+ result
71
+ end
72
+
44
73
  register Gemfile
45
74
  register Gemspec
46
75
  register Rakefile
76
+ register ActiveSupportConcern
47
77
  end
48
78
  end
@@ -1,53 +1,53 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- module Diagnostics
5
- # RequireNotFound reports required paths that could not be resolved to
6
- # either a file in the workspace or a gem.
7
- #
8
- class RequireNotFound < Base
9
- def diagnose source, api_map
10
- return [] unless source.parsed? && source.synchronized?
11
- result = []
12
- refs = {}
13
- map = api_map.source_map(source.filename)
14
- map.requires.each { |ref| refs[ref.name] = ref }
15
- api_map.missing_docs.each do |r|
16
- next unless refs.key?(r)
17
- result.push docs_error(r, refs[r].location)
18
- end
19
- api_map.unresolved_requires.each do |r|
20
- next unless refs.key?(r)
21
- result.push require_error(r, refs[r].location)
22
- end
23
- result
24
- end
25
-
26
- private
27
-
28
- # @param path [String]
29
- # @param location [Location]
30
- # @return [Hash]
31
- def docs_error path, location
32
- {
33
- range: location.range.to_hash,
34
- severity: Diagnostics::Severities::WARNING,
35
- source: 'RequireNotFound',
36
- message: "YARD docs not found for #{path}"
37
- }
38
- end
39
-
40
- # @param path [String]
41
- # @param location [Location]
42
- # @return [Hash]
43
- def require_error path, location
44
- {
45
- range: location.range.to_hash,
46
- severity: Diagnostics::Severities::WARNING,
47
- source: 'RequireNotFound',
48
- message: "Required path #{path} could not be resolved."
49
- }
50
- end
51
- end
52
- end
53
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Diagnostics
5
+ # RequireNotFound reports required paths that could not be resolved to
6
+ # either a file in the workspace or a gem.
7
+ #
8
+ class RequireNotFound < Base
9
+ def diagnose source, api_map
10
+ return [] unless source.parsed? && source.synchronized?
11
+ result = []
12
+ refs = {}
13
+ map = api_map.source_map(source.filename)
14
+ map.requires.each { |ref| refs[ref.name] = ref }
15
+ api_map.missing_docs.each do |r|
16
+ next unless refs.key?(r)
17
+ result.push docs_error(r, refs[r].location)
18
+ end
19
+ api_map.unresolved_requires.each do |r|
20
+ next unless refs.key?(r)
21
+ result.push require_error(r, refs[r].location)
22
+ end
23
+ result
24
+ end
25
+
26
+ private
27
+
28
+ # @param path [String]
29
+ # @param location [Location]
30
+ # @return [Hash]
31
+ def docs_error path, location
32
+ {
33
+ range: location.range.to_hash,
34
+ severity: Diagnostics::Severities::WARNING,
35
+ source: 'RequireNotFound',
36
+ message: "YARD docs not found for #{path}"
37
+ }
38
+ end
39
+
40
+ # @param path [String]
41
+ # @param location [Location]
42
+ # @return [Hash]
43
+ def require_error path, location
44
+ {
45
+ range: location.range.to_hash,
46
+ severity: Diagnostics::Severities::WARNING,
47
+ source: 'RequireNotFound',
48
+ message: "Required path #{path} could not be resolved."
49
+ }
50
+ end
51
+ end
52
+ end
53
+ end