solargraph 0.54.4 → 0.57.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 (178) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/linting.yml +125 -0
  3. data/.github/workflows/plugins.yml +149 -5
  4. data/.github/workflows/rspec.yml +39 -4
  5. data/.github/workflows/typecheck.yml +8 -3
  6. data/.gitignore +7 -0
  7. data/.overcommit.yml +72 -0
  8. data/.rspec +1 -0
  9. data/.rubocop.yml +66 -0
  10. data/.rubocop_todo.yml +2627 -0
  11. data/.yardopts +1 -0
  12. data/CHANGELOG.md +104 -0
  13. data/README.md +20 -6
  14. data/Rakefile +125 -13
  15. data/lib/solargraph/api_map/cache.rb +3 -2
  16. data/lib/solargraph/api_map/constants.rb +218 -0
  17. data/lib/solargraph/api_map/index.rb +44 -42
  18. data/lib/solargraph/api_map/source_to_yard.rb +10 -4
  19. data/lib/solargraph/api_map/store.rb +165 -32
  20. data/lib/solargraph/api_map.rb +319 -243
  21. data/lib/solargraph/bench.rb +18 -1
  22. data/lib/solargraph/complex_type/type_methods.rb +7 -1
  23. data/lib/solargraph/complex_type/unique_type.rb +105 -16
  24. data/lib/solargraph/complex_type.rb +40 -7
  25. data/lib/solargraph/convention/active_support_concern.rb +111 -0
  26. data/lib/solargraph/convention/base.rb +20 -3
  27. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -0
  28. data/lib/solargraph/convention/data_definition/data_definition_node.rb +91 -0
  29. data/lib/solargraph/convention/data_definition.rb +105 -0
  30. data/lib/solargraph/convention/gemspec.rb +3 -2
  31. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +61 -0
  32. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +102 -0
  33. data/lib/solargraph/convention/struct_definition.rb +164 -0
  34. data/lib/solargraph/convention.rb +35 -4
  35. data/lib/solargraph/diagnostics/rubocop.rb +6 -1
  36. data/lib/solargraph/diagnostics/rubocop_helpers.rb +1 -1
  37. data/lib/solargraph/doc_map.rb +313 -65
  38. data/lib/solargraph/environ.rb +9 -2
  39. data/lib/solargraph/gem_pins.rb +60 -38
  40. data/lib/solargraph/language_server/host/dispatch.rb +2 -0
  41. data/lib/solargraph/language_server/host/message_worker.rb +13 -7
  42. data/lib/solargraph/language_server/host.rb +14 -3
  43. data/lib/solargraph/language_server/message/base.rb +2 -1
  44. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +2 -0
  45. data/lib/solargraph/language_server/message/extended/document.rb +5 -2
  46. data/lib/solargraph/language_server/message/extended/document_gems.rb +3 -3
  47. data/lib/solargraph/language_server/message/text_document/definition.rb +2 -0
  48. data/lib/solargraph/language_server/message/text_document/formatting.rb +16 -2
  49. data/lib/solargraph/language_server/message/text_document/type_definition.rb +1 -0
  50. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +2 -0
  51. data/lib/solargraph/language_server/progress.rb +8 -0
  52. data/lib/solargraph/language_server/request.rb +1 -0
  53. data/lib/solargraph/library.rb +53 -32
  54. data/lib/solargraph/location.rb +23 -0
  55. data/lib/solargraph/logging.rb +12 -2
  56. data/lib/solargraph/page.rb +4 -0
  57. data/lib/solargraph/parser/comment_ripper.rb +20 -7
  58. data/lib/solargraph/parser/flow_sensitive_typing.rb +255 -0
  59. data/lib/solargraph/parser/node_methods.rb +16 -2
  60. data/lib/solargraph/parser/node_processor/base.rb +10 -5
  61. data/lib/solargraph/parser/node_processor.rb +26 -9
  62. data/lib/solargraph/parser/parser_gem/class_methods.rb +17 -15
  63. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -0
  64. data/lib/solargraph/parser/parser_gem/node_chainer.rb +13 -11
  65. data/lib/solargraph/parser/parser_gem/node_methods.rb +8 -4
  66. data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +2 -1
  67. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +21 -0
  68. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +4 -2
  69. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +7 -4
  70. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +2 -1
  71. data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +2 -1
  72. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +6 -3
  73. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +2 -1
  74. data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +2 -1
  75. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +23 -0
  76. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +4 -2
  77. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +2 -1
  78. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +7 -1
  79. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +8 -7
  80. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +42 -0
  81. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -0
  82. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +3 -1
  83. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -3
  84. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +63 -30
  85. data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +3 -1
  86. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -0
  87. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +29 -0
  88. data/lib/solargraph/parser/parser_gem/node_processors.rb +14 -0
  89. data/lib/solargraph/parser/region.rb +4 -1
  90. data/lib/solargraph/parser/snippet.rb +2 -0
  91. data/lib/solargraph/parser.rb +1 -0
  92. data/lib/solargraph/pin/base.rb +360 -30
  93. data/lib/solargraph/pin/base_variable.rb +16 -10
  94. data/lib/solargraph/pin/block.rb +2 -0
  95. data/lib/solargraph/pin/breakable.rb +9 -0
  96. data/lib/solargraph/pin/callable.rb +83 -3
  97. data/lib/solargraph/pin/closure.rb +20 -1
  98. data/lib/solargraph/pin/common.rb +10 -1
  99. data/lib/solargraph/pin/constant.rb +2 -0
  100. data/lib/solargraph/pin/delegated_method.rb +21 -1
  101. data/lib/solargraph/pin/documenting.rb +16 -0
  102. data/lib/solargraph/pin/keyword.rb +7 -2
  103. data/lib/solargraph/pin/local_variable.rb +18 -6
  104. data/lib/solargraph/pin/method.rb +175 -46
  105. data/lib/solargraph/pin/method_alias.rb +3 -0
  106. data/lib/solargraph/pin/namespace.rb +17 -9
  107. data/lib/solargraph/pin/parameter.rb +78 -19
  108. data/lib/solargraph/pin/proxy_type.rb +13 -6
  109. data/lib/solargraph/pin/reference/override.rb +24 -6
  110. data/lib/solargraph/pin/reference/require.rb +2 -2
  111. data/lib/solargraph/pin/reference/superclass.rb +5 -0
  112. data/lib/solargraph/pin/reference.rb +26 -0
  113. data/lib/solargraph/pin/search.rb +3 -1
  114. data/lib/solargraph/pin/signature.rb +44 -0
  115. data/lib/solargraph/pin/singleton.rb +1 -1
  116. data/lib/solargraph/pin/symbol.rb +8 -2
  117. data/lib/solargraph/pin/until.rb +18 -0
  118. data/lib/solargraph/pin/while.rb +18 -0
  119. data/lib/solargraph/pin.rb +4 -1
  120. data/lib/solargraph/pin_cache.rb +245 -0
  121. data/lib/solargraph/position.rb +11 -0
  122. data/lib/solargraph/range.rb +10 -0
  123. data/lib/solargraph/rbs_map/conversions.rb +226 -70
  124. data/lib/solargraph/rbs_map/core_fills.rb +32 -16
  125. data/lib/solargraph/rbs_map/core_map.rb +37 -11
  126. data/lib/solargraph/rbs_map/stdlib_map.rb +15 -5
  127. data/lib/solargraph/rbs_map.rb +88 -18
  128. data/lib/solargraph/shell.rb +20 -18
  129. data/lib/solargraph/source/chain/array.rb +11 -7
  130. data/lib/solargraph/source/chain/block_symbol.rb +1 -1
  131. data/lib/solargraph/source/chain/block_variable.rb +1 -1
  132. data/lib/solargraph/source/chain/call.rb +53 -23
  133. data/lib/solargraph/source/chain/constant.rb +1 -1
  134. data/lib/solargraph/source/chain/hash.rb +4 -3
  135. data/lib/solargraph/source/chain/head.rb +1 -1
  136. data/lib/solargraph/source/chain/if.rb +1 -1
  137. data/lib/solargraph/source/chain/link.rb +12 -1
  138. data/lib/solargraph/source/chain/literal.rb +22 -2
  139. data/lib/solargraph/source/chain/or.rb +1 -1
  140. data/lib/solargraph/source/chain/z_super.rb +1 -1
  141. data/lib/solargraph/source/chain.rb +84 -47
  142. data/lib/solargraph/source/change.rb +2 -2
  143. data/lib/solargraph/source/cursor.rb +2 -3
  144. data/lib/solargraph/source/source_chainer.rb +3 -3
  145. data/lib/solargraph/source.rb +5 -2
  146. data/lib/solargraph/source_map/clip.rb +4 -2
  147. data/lib/solargraph/source_map/data.rb +4 -0
  148. data/lib/solargraph/source_map/mapper.rb +13 -7
  149. data/lib/solargraph/source_map.rb +21 -31
  150. data/lib/solargraph/type_checker/checks.rb +4 -0
  151. data/lib/solargraph/type_checker/param_def.rb +2 -0
  152. data/lib/solargraph/type_checker/rules.rb +8 -0
  153. data/lib/solargraph/type_checker.rb +208 -128
  154. data/lib/solargraph/version.rb +1 -1
  155. data/lib/solargraph/views/_method.erb +10 -10
  156. data/lib/solargraph/views/_namespace.erb +3 -3
  157. data/lib/solargraph/views/document.erb +10 -10
  158. data/lib/solargraph/workspace/config.rb +1 -3
  159. data/lib/solargraph/workspace/require_paths.rb +98 -0
  160. data/lib/solargraph/workspace.rb +38 -52
  161. data/lib/solargraph/yard_map/helpers.rb +29 -1
  162. data/lib/solargraph/yard_map/mapper/to_constant.rb +7 -5
  163. data/lib/solargraph/yard_map/mapper/to_method.rb +53 -18
  164. data/lib/solargraph/yard_map/mapper/to_namespace.rb +9 -7
  165. data/lib/solargraph/yard_map/mapper.rb +4 -3
  166. data/lib/solargraph/yard_map/to_method.rb +4 -2
  167. data/lib/solargraph/yardoc.rb +22 -10
  168. data/lib/solargraph.rb +34 -1
  169. data/rbs/fills/tuple.rbs +149 -0
  170. data/rbs_collection.yaml +19 -0
  171. data/sig/shims/parser/3.2.0.1/builders/default.rbs +195 -0
  172. data/sig/shims/thor/1.2.0.1/.rbs_meta.yaml +9 -0
  173. data/sig/shims/thor/1.2.0.1/manifest.yaml +7 -0
  174. data/sig/shims/thor/1.2.0.1/thor.rbs +17 -0
  175. data/solargraph.gemspec +15 -4
  176. metadata +157 -15
  177. data/lib/.rubocop.yml +0 -22
  178. data/lib/solargraph/cache.rb +0 -77
@@ -13,6 +13,7 @@ module Solargraph
13
13
  autoload :NamespaceNode, 'solargraph/parser/parser_gem/node_processors/namespace_node'
14
14
  autoload :SclassNode, 'solargraph/parser/parser_gem/node_processors/sclass_node'
15
15
  autoload :IvasgnNode, 'solargraph/parser/parser_gem/node_processors/ivasgn_node'
16
+ autoload :IfNode, 'solargraph/parser/parser_gem/node_processors/if_node'
16
17
  autoload :CvasgnNode, 'solargraph/parser/parser_gem/node_processors/cvasgn_node'
17
18
  autoload :LvasgnNode, 'solargraph/parser/parser_gem/node_processors/lvasgn_node'
18
19
  autoload :GvasgnNode, 'solargraph/parser/parser_gem/node_processors/gvasgn_node'
@@ -22,8 +23,12 @@ module Solargraph
22
23
  autoload :ArgsNode, 'solargraph/parser/parser_gem/node_processors/args_node'
23
24
  autoload :BlockNode, 'solargraph/parser/parser_gem/node_processors/block_node'
24
25
  autoload :OrasgnNode, 'solargraph/parser/parser_gem/node_processors/orasgn_node'
26
+ autoload :OpasgnNode, 'solargraph/parser/parser_gem/node_processors/opasgn_node'
25
27
  autoload :SymNode, 'solargraph/parser/parser_gem/node_processors/sym_node'
26
28
  autoload :ResbodyNode, 'solargraph/parser/parser_gem/node_processors/resbody_node'
29
+ autoload :UntilNode, 'solargraph/parser/parser_gem/node_processors/until_node'
30
+ autoload :WhileNode, 'solargraph/parser/parser_gem/node_processors/while_node'
31
+ autoload :AndNode, 'solargraph/parser/parser_gem/node_processors/and_node'
27
32
  end
28
33
  end
29
34
 
@@ -35,7 +40,10 @@ module Solargraph
35
40
  register :resbody, ParserGem::NodeProcessors::ResbodyNode
36
41
  register :def, ParserGem::NodeProcessors::DefNode
37
42
  register :defs, ParserGem::NodeProcessors::DefsNode
43
+ register :if, ParserGem::NodeProcessors::IfNode
38
44
  register :send, ParserGem::NodeProcessors::SendNode
45
+ register :class, Convention::StructDefinition::NodeProcessors::StructNode
46
+ register :class, Convention::DataDefinition::NodeProcessors::DataNode
39
47
  register :class, ParserGem::NodeProcessors::NamespaceNode
40
48
  register :module, ParserGem::NodeProcessors::NamespaceNode
41
49
  register :sclass, ParserGem::NodeProcessors::SclassNode
@@ -43,6 +51,8 @@ module Solargraph
43
51
  register :cvasgn, ParserGem::NodeProcessors::CvasgnNode
44
52
  register :lvasgn, ParserGem::NodeProcessors::LvasgnNode
45
53
  register :gvasgn, ParserGem::NodeProcessors::GvasgnNode
54
+ register :casgn, Convention::StructDefinition::NodeProcessors::StructNode
55
+ register :casgn, Convention::DataDefinition::NodeProcessors::DataNode
46
56
  register :casgn, ParserGem::NodeProcessors::CasgnNode
47
57
  register :masgn, ParserGem::NodeProcessors::MasgnNode
48
58
  register :alias, ParserGem::NodeProcessors::AliasNode
@@ -50,7 +60,11 @@ module Solargraph
50
60
  register :forward_args, ParserGem::NodeProcessors::ArgsNode
51
61
  register :block, ParserGem::NodeProcessors::BlockNode
52
62
  register :or_asgn, ParserGem::NodeProcessors::OrasgnNode
63
+ register :op_asgn, ParserGem::NodeProcessors::OpasgnNode
53
64
  register :sym, ParserGem::NodeProcessors::SymNode
65
+ register :until, ParserGem::NodeProcessors::UntilNode
66
+ register :while, ParserGem::NodeProcessors::WhileNode
67
+ register :and, ParserGem::NodeProcessors::AndNode
54
68
  end
55
69
  end
56
70
  end
@@ -23,13 +23,15 @@ module Solargraph
23
23
 
24
24
  # @param source [Source]
25
25
  # @param namespace [String]
26
+ # @param closure [Pin::Closure, nil]
26
27
  # @param scope [Symbol, nil]
27
28
  # @param visibility [Symbol]
29
+ # @param lvars [Array<Symbol>]
28
30
  def initialize source: Solargraph::Source.load_string(''), closure: nil,
29
31
  scope: nil, visibility: :public, lvars: []
30
32
  @source = source
31
33
  # @closure = closure
32
- @closure = closure || Pin::Namespace.new(name: '', location: source.location)
34
+ @closure = closure || Pin::Namespace.new(name: '', location: source.location, source: :parser)
33
35
  @scope = scope
34
36
  @visibility = visibility
35
37
  @lvars = lvars
@@ -45,6 +47,7 @@ module Solargraph
45
47
  # @param closure [Pin::Closure, nil]
46
48
  # @param scope [Symbol, nil]
47
49
  # @param visibility [Symbol, nil]
50
+ # @param lvars [Array<Symbol>, nil]
48
51
  # @return [Region]
49
52
  def update closure: nil, scope: nil, visibility: nil, lvars: nil
50
53
  Region.new(
@@ -6,6 +6,8 @@ module Solargraph
6
6
  # @return [String]
7
7
  attr_reader :text
8
8
 
9
+ # @param range [Solargraph::Range]
10
+ # @param text [String]
9
11
  def initialize range, text
10
12
  @range = range
11
13
  @text = text
@@ -4,6 +4,7 @@ module Solargraph
4
4
  autoload :ParserGem, 'solargraph/parser/parser_gem'
5
5
  autoload :Region, 'solargraph/parser/region'
6
6
  autoload :NodeProcessor, 'solargraph/parser/node_processor'
7
+ autoload :FlowSensitiveTyping, 'solargraph/parser/flow_sensitive_typing'
7
8
  autoload :Snippet, 'solargraph/parser/snippet'
8
9
 
9
10
  class SyntaxError < StandardError
@@ -8,14 +8,15 @@ module Solargraph
8
8
  include Common
9
9
  include Conversions
10
10
  include Documenting
11
+ include Logging
11
12
 
12
13
  # @return [YARD::CodeObjects::Base]
13
14
  attr_reader :code_object
14
15
 
15
- # @return [Solargraph::Location]
16
+ # @return [Solargraph::Location, nil]
16
17
  attr_reader :location
17
18
 
18
- # @return [Solargraph::Location]
19
+ # @return [Solargraph::Location, nil]
19
20
  attr_reader :type_location
20
21
 
21
22
  # @return [String]
@@ -27,17 +28,338 @@ module Solargraph
27
28
  # @return [::Symbol]
28
29
  attr_accessor :source
29
30
 
31
+ # @type [::Numeric, nil] A priority for determining if pins should be combined or not
32
+ # A nil priority is considered the be the lowest. All code, yard & rbs pins have nil priority
33
+ # Between 2 pins, the one with the higher priority gets chosen. If the priorities are equal, they are combined.
34
+ attr_reader :combine_priority
35
+
36
+ def presence_certain?
37
+ true
38
+ end
39
+
30
40
  # @param location [Solargraph::Location, nil]
31
41
  # @param type_location [Solargraph::Location, nil]
32
42
  # @param closure [Solargraph::Pin::Closure, nil]
33
43
  # @param name [String]
34
44
  # @param comments [String]
35
- def initialize location: nil, type_location: nil, closure: nil, name: '', comments: ''
45
+ # @param source [Symbol, nil]
46
+ # @param docstring [YARD::Docstring, nil]
47
+ # @param directives [::Array<YARD::Tags::Directive>, nil]
48
+ # @param combine_priority [::Numeric, nil] See attr_reader for combine_priority
49
+ def initialize location: nil, type_location: nil, closure: nil, source: nil, name: '', comments: '', docstring: nil, directives: nil, combine_priority: nil
36
50
  @location = location
37
51
  @type_location = type_location
38
52
  @closure = closure
39
53
  @name = name
40
54
  @comments = comments
55
+ @source = source
56
+ @identity = nil
57
+ @docstring = docstring
58
+ @directives = directives
59
+ @combine_priority = combine_priority
60
+
61
+ assert_source_provided
62
+ assert_location_provided
63
+ end
64
+
65
+ # @return [void]
66
+ def assert_location_provided
67
+ return unless best_location.nil? && %i[yardoc source rbs].include?(source)
68
+
69
+ Solargraph.assert_or_log(:best_location, "Neither location nor type_location provided - #{path} #{source} #{self.class}")
70
+ end
71
+
72
+ # @return [Pin::Closure, nil]
73
+ def closure
74
+ Solargraph.assert_or_log(:closure, "Closure not set on #{self.class} #{name.inspect} from #{source.inspect}") unless @closure
75
+ # @type [Pin::Closure, nil]
76
+ @closure
77
+ end
78
+
79
+ # @param other [self]
80
+ # @param attrs [Hash{::Symbol => Object}]
81
+ #
82
+ # @return [self]
83
+ def combine_with(other, attrs={})
84
+ raise "tried to combine #{other.class} with #{self.class}" unless other.class == self.class
85
+ priority_choice = choose_priority(other)
86
+ return priority_choice unless priority_choice.nil?
87
+
88
+ type_location = choose(other, :type_location)
89
+ location = choose(other, :location)
90
+ combined_name = combine_name(other)
91
+ new_attrs = {
92
+ location: location,
93
+ type_location: type_location,
94
+ name: combined_name,
95
+ closure: choose_pin_attr_with_same_name(other, :closure),
96
+ comments: choose_longer(other, :comments),
97
+ source: :combined,
98
+ docstring: choose(other, :docstring),
99
+ directives: combine_directives(other),
100
+ combine_priority: combine_priority
101
+ }.merge(attrs)
102
+ assert_same_macros(other)
103
+ logger.debug { "Base#combine_with(path=#{path}) - other.comments=#{other.comments.inspect}, self.comments = #{self.comments}" }
104
+ out = self.class.new(**new_attrs)
105
+ out.reset_generated!
106
+ out
107
+ end
108
+
109
+ # @param other [self]
110
+ # @return [self, nil] Returns either the pin chosen based on priority or nil
111
+ # A nil return means that the combination process must proceed
112
+ def choose_priority(other)
113
+ if combine_priority.nil? && !other.combine_priority.nil?
114
+ return other
115
+ elsif other.combine_priority.nil? && !combine_priority.nil?
116
+ return self
117
+ elsif !combine_priority.nil? && !other.combine_priority.nil?
118
+ if combine_priority > other.combine_priority
119
+ return self
120
+ elsif combine_priority < other.combine_priority
121
+ return other
122
+ end
123
+ end
124
+
125
+ nil
126
+ end
127
+
128
+ # @param other [self]
129
+ # @param attr [::Symbol]
130
+ # @sg-ignore
131
+ # @return [undefined]
132
+ def choose_longer(other, attr)
133
+ # @type [undefined]
134
+ val1 = send(attr)
135
+ # @type [undefined]
136
+ val2 = other.send(attr)
137
+ return val1 if val1 == val2
138
+ return val2 if val1.nil?
139
+ val1.length > val2.length ? val1 : val2
140
+ end
141
+
142
+ # @param other [self]
143
+ # @return [::Array<YARD::Tags::Directive>, nil]
144
+ def combine_directives(other)
145
+ return self.directives if other.directives.empty?
146
+ return other.directives if directives.empty?
147
+ [directives + other.directives].uniq
148
+ end
149
+
150
+ # @param other [self]
151
+ # @return [String]
152
+ def combine_name(other)
153
+ if needs_consistent_name? || other.needs_consistent_name?
154
+ assert_same(other, :name)
155
+ else
156
+ choose(other, :name)
157
+ end
158
+ end
159
+
160
+ # @return [void]
161
+ def reset_generated!
162
+ # @return_type doesn't go here as subclasses tend to assign it
163
+ # themselves in constructors, and they will deal with setting
164
+ # it in any methods that call this
165
+ #
166
+ # @docstring also doesn't go here, as there is code which
167
+ # directly manipulates docstring without editing comments
168
+ # (e.g., Api::Map::Store#index processes overrides that way
169
+ #
170
+ # Same with @directives, @macros, @maybe_directives, which
171
+ # regenerate docstring
172
+ @deprecated = nil
173
+ reset_conversions
174
+ end
175
+
176
+ def needs_consistent_name?
177
+ true
178
+ end
179
+
180
+ # @sg-ignore def should infer as symbol - "Not enough arguments to Module#protected"
181
+ protected def equality_fields
182
+ [name, location, type_location, closure, source]
183
+ end
184
+
185
+ # @param other [self]
186
+ # @return [ComplexType]
187
+ def combine_return_type(other)
188
+ if return_type.undefined?
189
+ other.return_type
190
+ elsif other.return_type.undefined?
191
+ return_type
192
+ elsif dodgy_return_type_source? && !other.dodgy_return_type_source?
193
+ other.return_type
194
+ elsif other.dodgy_return_type_source? && !dodgy_return_type_source?
195
+ return_type
196
+ else
197
+ all_items = return_type.items + other.return_type.items
198
+ if all_items.any? { |item| item.selfy? } && all_items.any? { |item| item.rooted_tag == context.rooted_tag }
199
+ # assume this was a declaration that should have said 'self'
200
+ all_items.delete_if { |item| item.rooted_tag == context.rooted_tag }
201
+ end
202
+ ComplexType.new(all_items)
203
+ end
204
+ end
205
+
206
+ def dodgy_return_type_source?
207
+ # uses a lot of 'Object' instead of 'self'
208
+ location&.filename&.include?('core_ext/object/')
209
+ end
210
+
211
+ # when choices are arbitrary, make sure the choice is consistent
212
+ #
213
+ # @param other [Pin::Base]
214
+ # @param attr [::Symbol]
215
+ #
216
+ # @return [Object, nil]
217
+ def choose(other, attr)
218
+ results = [self, other].map(&attr).compact
219
+ # true and false are different classes and can't be sorted
220
+ return true if results.any? { |r| r == true || r == false }
221
+ results.min
222
+ rescue
223
+ STDERR.puts("Problem handling #{attr} for \n#{self.inspect}\n and \n#{other.inspect}\n\n#{self.send(attr).inspect} vs #{other.send(attr).inspect}")
224
+ raise
225
+ end
226
+
227
+ # @param other [self]
228
+ # @param attr [::Symbol]
229
+ # @sg-ignore
230
+ # @return [undefined]
231
+ def choose_node(other, attr)
232
+ if other.object_id < attr.object_id
233
+ other.send(attr)
234
+ else
235
+ send(attr)
236
+ end
237
+ end
238
+
239
+ # @param other [self]
240
+ # @param attr [::Symbol]
241
+ # @sg-ignore
242
+ # @return [undefined]
243
+ def prefer_rbs_location(other, attr)
244
+ if rbs_location? && !other.rbs_location?
245
+ self.send(attr)
246
+ elsif !rbs_location? && other.rbs_location?
247
+ other.send(attr)
248
+ else
249
+ choose(other, attr)
250
+ end
251
+ end
252
+
253
+ def rbs_location?
254
+ type_location&.rbs?
255
+ end
256
+
257
+ # @param other [self]
258
+ # @return [void]
259
+ def assert_same_macros(other)
260
+ return unless self.source == :yardoc && other.source == :yardoc
261
+ assert_same_count(other, :macros)
262
+ assert_same_array_content(other, :macros) { |macro| macro.tag.name }
263
+ end
264
+
265
+ # @param other [self]
266
+ # @param attr [::Symbol]
267
+ # @return [void]
268
+ # @todo strong typechecking should complain when there are no block-related tags
269
+ def assert_same_array_content(other, attr, &block)
270
+ arr1 = send(attr)
271
+ raise "Expected #{attr} on #{self} to be an Enumerable, got #{arr1.class}" unless arr1.is_a?(::Enumerable)
272
+ # @type arr1 [::Enumerable]
273
+ arr2 = other.send(attr)
274
+ raise "Expected #{attr} on #{other} to be an Enumerable, got #{arr2.class}" unless arr2.is_a?(::Enumerable)
275
+ # @type arr2 [::Enumerable]
276
+
277
+ # @type [undefined]
278
+ values1 = arr1.map(&block)
279
+ # @type [undefined]
280
+ values2 = arr2.map(&block)
281
+ # @sg-ignore
282
+ return arr1 if values1 == values2
283
+ Solargraph.assert_or_log("combine_with_#{attr}".to_sym,
284
+ "Inconsistent #{attr.inspect} values between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self values = #{values1}\nother values =#{attr} = #{values2}")
285
+ arr1
286
+ end
287
+
288
+ # @param other [self]
289
+ # @param attr [::Symbol]
290
+ #
291
+ # @return [::Enumerable]
292
+ def assert_same_count(other, attr)
293
+ # @type [::Enumerable]
294
+ arr1 = self.send(attr)
295
+ raise "Expected #{attr} on #{self} to be an Enumerable, got #{arr1.class}" unless arr1.is_a?(::Enumerable)
296
+ # @type [::Enumerable]
297
+ arr2 = other.send(attr)
298
+ raise "Expected #{attr} on #{other} to be an Enumerable, got #{arr2.class}" unless arr2.is_a?(::Enumerable)
299
+ return arr1 if arr1.count == arr2.count
300
+ Solargraph.assert_or_log("combine_with_#{attr}".to_sym,
301
+ "Inconsistent #{attr.inspect} count value between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self.#{attr} = #{arr1.inspect}\nother.#{attr} = #{arr2.inspect}")
302
+ arr1
303
+ end
304
+
305
+ # @param other [self]
306
+ # @param attr [::Symbol]
307
+ #
308
+ # @sg-ignore
309
+ # @return [undefined]
310
+ def assert_same(other, attr)
311
+ return false if other.nil?
312
+ val1 = send(attr)
313
+ val2 = other.send(attr)
314
+ return val1 if val1 == val2
315
+ Solargraph.assert_or_log("combine_with_#{attr}".to_sym,
316
+ "Inconsistent #{attr.inspect} values between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self.#{attr} = #{val1.inspect}\nother.#{attr} = #{val2.inspect}")
317
+ val1
318
+ end
319
+
320
+ # @param other [self]
321
+ # @param attr [::Symbol]
322
+ # @sg-ignore
323
+ # @return [undefined]
324
+ def choose_pin_attr_with_same_name(other, attr)
325
+ # @type [Pin::Base, nil]
326
+ val1 = send(attr)
327
+ # @type [Pin::Base, nil]
328
+ val2 = other.send(attr)
329
+ raise "Expected pin for #{attr} on\n#{self.inspect},\ngot #{val1.inspect}" unless val1.nil? || val1.is_a?(Pin::Base)
330
+ raise "Expected pin for #{attr} on\n#{other.inspect},\ngot #{val2.inspect}" unless val2.nil? || val2.is_a?(Pin::Base)
331
+ if val1&.name != val2&.name
332
+ Solargraph.assert_or_log("combine_with_#{attr}_name".to_sym,
333
+ "Inconsistent #{attr.inspect} name values between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self.#{attr} = #{val1.inspect}\nother.#{attr} = #{val2.inspect}")
334
+ end
335
+ choose_pin_attr(other, attr)
336
+ end
337
+
338
+ # @param other [self]
339
+ # @param attr [::Symbol]
340
+ #
341
+ # @sg-ignore
342
+ # @return [undefined]
343
+ def choose_pin_attr(other, attr)
344
+ # @type [Pin::Base, nil]
345
+ val1 = send(attr)
346
+ # @type [Pin::Base, nil]
347
+ val2 = other.send(attr)
348
+ if val1.class != val2.class
349
+ # :nocov:
350
+ Solargraph.assert_or_log("combine_with_#{attr}_class".to_sym,
351
+ "Inconsistent #{attr.inspect} class values between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self.#{attr} = #{val1.inspect}\nother.#{attr} = #{val2.inspect}")
352
+ return val1
353
+ # :nocov:
354
+ end
355
+ # arbitrary way of choosing a pin
356
+ # @sg-ignore Need _1 support
357
+ [val1, val2].compact.min_by { _1.best_location.to_s }
358
+ end
359
+
360
+ # @return [void]
361
+ def assert_source_provided
362
+ Solargraph.assert_or_log(:source, "source not provided - #{@path} #{@source} #{self.class}") if source.nil?
41
363
  end
42
364
 
43
365
  # @return [String]
@@ -134,6 +456,7 @@ module Solargraph
134
456
  # Pin equality is determined using the #nearly? method and also
135
457
  # requiring both pins to have the same location.
136
458
  #
459
+ # @param other [self]
137
460
  def == other
138
461
  return false unless nearly? other
139
462
  comments == other.comments && location == other.location
@@ -148,13 +471,13 @@ module Solargraph
148
471
 
149
472
  # @return [YARD::Docstring]
150
473
  def docstring
151
- parse_comments unless defined?(@docstring)
474
+ parse_comments unless @docstring
152
475
  @docstring ||= Solargraph::Source.parse_docstring('').to_docstring
153
476
  end
154
477
 
155
478
  # @return [::Array<YARD::Tags::Directive>]
156
479
  def directives
157
- parse_comments unless defined?(@directives)
480
+ parse_comments unless @directives
158
481
  @directives
159
482
  end
160
483
 
@@ -172,7 +495,7 @@ module Solargraph
172
495
  #
173
496
  # @return [Boolean]
174
497
  def maybe_directives?
175
- return !@directives.empty? if defined?(@directives)
498
+ return !@directives.empty? if defined?(@directives) && @directives
176
499
  @maybe_directives ||= comments.include?('@!')
177
500
  end
178
501
 
@@ -211,26 +534,6 @@ module Solargraph
211
534
  probe api_map
212
535
  end
213
536
 
214
- # Try to merge data from another pin. Merges are only possible if the
215
- # pins are near matches (see the #nearly? method). The changes should
216
- # not have any side effects on the API surface.
217
- #
218
- # @param pin [Pin::Base] The pin to merge into this one
219
- # @return [Boolean] True if the pins were merged
220
- def try_merge! pin
221
- return false unless nearly?(pin)
222
- @location = pin.location
223
- @closure = pin.closure
224
- return true if comments == pin.comments
225
- @comments = pin.comments
226
- @docstring = pin.docstring
227
- @return_type = pin.return_type
228
- @documentation = nil
229
- @deprecated = nil
230
- reset_conversions
231
- true
232
- end
233
-
234
537
  def proxied?
235
538
  @proxied ||= false
236
539
  end
@@ -268,7 +571,7 @@ module Solargraph
268
571
  # @deprecated
269
572
  # @return [String]
270
573
  def identity
271
- @identity ||= "#{closure&.path}|#{name}"
574
+ @identity ||= "#{closure&.path}|#{name}|#{location}"
272
575
  end
273
576
 
274
577
  # @return [String, nil]
@@ -293,14 +596,37 @@ module Solargraph
293
596
  end
294
597
 
295
598
  # @return [String]
296
- def desc
599
+ def inner_desc
297
600
  closure_info = closure&.desc
298
601
  binder_info = binder&.desc
299
- "[#{type_desc}, closure=#{closure_info}, binder=#{binder}"
602
+ "name=#{name.inspect} return_type=#{type_desc}, context=#{context.rooted_tags}, closure=#{closure_info}, binder=#{binder_info}"
603
+ end
604
+
605
+ # @return [String]
606
+ def desc
607
+ "[#{inner_desc}]"
300
608
  end
301
609
 
610
+ # @return [String]
302
611
  def inspect
303
- "#<#{self.class} `#{self.desc}` at #{self.location.inspect}>"
612
+ "#<#{self.class} `#{self.inner_desc}`#{all_location_text} via #{source.inspect}>"
613
+ end
614
+
615
+ # @return [String]
616
+ def all_location_text
617
+ if location.nil? && type_location.nil?
618
+ ''
619
+ elsif !location.nil? && type_location.nil?
620
+ " at #{location.inspect})"
621
+ elsif !type_location.nil? && location.nil?
622
+ " at #{type_location.inspect})"
623
+ else
624
+ " at (#{location.inspect} and #{type_location.inspect})"
625
+ end
626
+ end
627
+
628
+ # @return [void]
629
+ def reset_generated!
304
630
  end
305
631
 
306
632
  protected
@@ -314,6 +640,10 @@ module Solargraph
314
640
  # @return [ComplexType]
315
641
  attr_writer :return_type
316
642
 
643
+ attr_writer :docstring
644
+
645
+ attr_writer :directives
646
+
317
647
  private
318
648
 
319
649
  # @return [void]
@@ -3,20 +3,31 @@
3
3
  module Solargraph
4
4
  module Pin
5
5
  class BaseVariable < Base
6
- include Solargraph::Parser::NodeMethods
7
6
  # include Solargraph::Source::NodeMethods
7
+ include Solargraph::Parser::NodeMethods
8
8
 
9
9
  # @return [Parser::AST::Node, nil]
10
10
  attr_reader :assignment
11
11
 
12
12
  attr_accessor :mass_assignment
13
13
 
14
+ # @param return_type [ComplexType, nil]
14
15
  # @param assignment [Parser::AST::Node, nil]
15
- def initialize assignment: nil, **splat
16
+ def initialize assignment: nil, return_type: nil, **splat
16
17
  super(**splat)
17
18
  @assignment = assignment
18
19
  # @type [nil, ::Array(Parser::AST::Node, Integer)]
19
20
  @mass_assignment = nil
21
+ @return_type = return_type
22
+ end
23
+
24
+ def combine_with(other, attrs={})
25
+ attrs.merge({
26
+ assignment: assert_same(other, :assignment),
27
+ mass_assignment: assert_same(other, :mass_assignment),
28
+ return_type: combine_return_type(other),
29
+ })
30
+ super(other, attrs)
20
31
  end
21
32
 
22
33
  def completion_item_kind
@@ -33,6 +44,8 @@ module Solargraph
33
44
  end
34
45
 
35
46
  def nil_assignment?
47
+ # this will always be false - should it be return_type ==
48
+ # ComplexType::NIL or somesuch?
36
49
  return_type.nil?
37
50
  end
38
51
 
@@ -88,19 +101,12 @@ module Solargraph
88
101
  ComplexType::UNDEFINED
89
102
  end
90
103
 
104
+ # @param other [Object]
91
105
  def == other
92
106
  return false unless super
93
107
  assignment == other.assignment
94
108
  end
95
109
 
96
- # @param pin [self]
97
- def try_merge! pin
98
- return false unless super
99
- @assignment = pin.assignment
100
- @return_type = pin.return_type
101
- true
102
- end
103
-
104
110
  def type_desc
105
111
  "#{super} = #{assignment&.type.inspect}"
106
112
  end
@@ -3,6 +3,8 @@
3
3
  module Solargraph
4
4
  module Pin
5
5
  class Block < Callable
6
+ include Breakable
7
+
6
8
  # @return [Parser::AST::Node]
7
9
  attr_reader :receiver
8
10
 
@@ -0,0 +1,9 @@
1
+ module Solargraph
2
+ module Pin
3
+ # Mix-in for pins which enclose code which the 'break' statement works with-in - e.g., blocks, when, until, ...
4
+ module Breakable
5
+ # @return [Parser::AST::Node]
6
+ attr_reader :node
7
+ end
8
+ end
9
+ end