solargraph 0.56.1 → 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 (132) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/linting.yml +125 -0
  3. data/.github/workflows/plugins.yml +148 -6
  4. data/.github/workflows/rspec.yml +39 -4
  5. data/.github/workflows/typecheck.yml +5 -2
  6. data/.gitignore +5 -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 +50 -0
  13. data/README.md +8 -4
  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 +20 -26
  18. data/lib/solargraph/api_map/source_to_yard.rb +10 -4
  19. data/lib/solargraph/api_map/store.rb +126 -18
  20. data/lib/solargraph/api_map.rb +212 -234
  21. data/lib/solargraph/bench.rb +1 -0
  22. data/lib/solargraph/complex_type/type_methods.rb +1 -0
  23. data/lib/solargraph/complex_type/unique_type.rb +7 -7
  24. data/lib/solargraph/complex_type.rb +5 -1
  25. data/lib/solargraph/convention/active_support_concern.rb +111 -0
  26. data/lib/solargraph/convention/base.rb +17 -0
  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 +2 -1
  32. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +4 -2
  33. data/lib/solargraph/convention/struct_definition.rb +87 -24
  34. data/lib/solargraph/convention.rb +32 -2
  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 +40 -12
  38. data/lib/solargraph/environ.rb +9 -2
  39. data/lib/solargraph/gem_pins.rb +17 -11
  40. data/lib/solargraph/language_server/host/dispatch.rb +2 -0
  41. data/lib/solargraph/language_server/host/message_worker.rb +3 -0
  42. data/lib/solargraph/language_server/host.rb +2 -1
  43. data/lib/solargraph/language_server/message/base.rb +2 -1
  44. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +1 -1
  45. data/lib/solargraph/language_server/message/text_document/definition.rb +2 -0
  46. data/lib/solargraph/language_server/message/text_document/formatting.rb +16 -2
  47. data/lib/solargraph/language_server/message/text_document/type_definition.rb +1 -0
  48. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +2 -0
  49. data/lib/solargraph/language_server/progress.rb +8 -0
  50. data/lib/solargraph/language_server/request.rb +1 -0
  51. data/lib/solargraph/library.rb +17 -24
  52. data/lib/solargraph/location.rb +2 -0
  53. data/lib/solargraph/logging.rb +11 -2
  54. data/lib/solargraph/page.rb +4 -0
  55. data/lib/solargraph/parser/comment_ripper.rb +8 -1
  56. data/lib/solargraph/parser/flow_sensitive_typing.rb +32 -4
  57. data/lib/solargraph/parser/node_methods.rb +2 -2
  58. data/lib/solargraph/parser/node_processor/base.rb +10 -5
  59. data/lib/solargraph/parser/node_processor.rb +24 -8
  60. data/lib/solargraph/parser/parser_gem/class_methods.rb +1 -1
  61. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -0
  62. data/lib/solargraph/parser/parser_gem/node_chainer.rb +3 -1
  63. data/lib/solargraph/parser/parser_gem/node_methods.rb +4 -2
  64. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +3 -2
  65. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +1 -21
  66. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +2 -0
  67. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +7 -1
  68. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +0 -22
  69. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +1 -0
  70. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -0
  71. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +1 -0
  72. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +35 -14
  73. data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +1 -0
  74. data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
  75. data/lib/solargraph/parser/region.rb +3 -0
  76. data/lib/solargraph/parser/snippet.rb +2 -0
  77. data/lib/solargraph/pin/base.rb +65 -8
  78. data/lib/solargraph/pin/base_variable.rb +1 -2
  79. data/lib/solargraph/pin/callable.rb +9 -0
  80. data/lib/solargraph/pin/closure.rb +2 -0
  81. data/lib/solargraph/pin/common.rb +6 -2
  82. data/lib/solargraph/pin/constant.rb +2 -0
  83. data/lib/solargraph/pin/delegated_method.rb +1 -0
  84. data/lib/solargraph/pin/local_variable.rb +4 -1
  85. data/lib/solargraph/pin/method.rb +12 -7
  86. data/lib/solargraph/pin/method_alias.rb +3 -0
  87. data/lib/solargraph/pin/parameter.rb +18 -8
  88. data/lib/solargraph/pin/proxy_type.rb +1 -0
  89. data/lib/solargraph/pin/reference/override.rb +15 -1
  90. data/lib/solargraph/pin/reference/superclass.rb +5 -0
  91. data/lib/solargraph/pin/reference.rb +26 -0
  92. data/lib/solargraph/pin/search.rb +3 -1
  93. data/lib/solargraph/pin/signature.rb +2 -0
  94. data/lib/solargraph/pin/symbol.rb +5 -0
  95. data/lib/solargraph/pin_cache.rb +64 -4
  96. data/lib/solargraph/position.rb +2 -0
  97. data/lib/solargraph/range.rb +1 -0
  98. data/lib/solargraph/rbs_map/conversions.rb +47 -18
  99. data/lib/solargraph/rbs_map/core_map.rb +3 -0
  100. data/lib/solargraph/rbs_map.rb +15 -2
  101. data/lib/solargraph/shell.rb +3 -0
  102. data/lib/solargraph/source/chain/link.rb +10 -1
  103. data/lib/solargraph/source/chain.rb +9 -2
  104. data/lib/solargraph/source/change.rb +2 -2
  105. data/lib/solargraph/source/cursor.rb +2 -3
  106. data/lib/solargraph/source/source_chainer.rb +1 -1
  107. data/lib/solargraph/source.rb +5 -2
  108. data/lib/solargraph/source_map/clip.rb +1 -1
  109. data/lib/solargraph/source_map/data.rb +4 -0
  110. data/lib/solargraph/source_map/mapper.rb +4 -2
  111. data/lib/solargraph/source_map.rb +21 -14
  112. data/lib/solargraph/type_checker/param_def.rb +2 -0
  113. data/lib/solargraph/type_checker/rules.rb +8 -0
  114. data/lib/solargraph/type_checker.rb +173 -120
  115. data/lib/solargraph/version.rb +1 -1
  116. data/lib/solargraph/workspace/config.rb +1 -3
  117. data/lib/solargraph/workspace/require_paths.rb +98 -0
  118. data/lib/solargraph/workspace.rb +16 -48
  119. data/lib/solargraph/yard_map/helpers.rb +29 -1
  120. data/lib/solargraph/yard_map/mapper/to_constant.rb +5 -5
  121. data/lib/solargraph/yard_map/mapper/to_method.rb +3 -8
  122. data/lib/solargraph/yard_map/mapper/to_namespace.rb +7 -7
  123. data/lib/solargraph/yardoc.rb +16 -3
  124. data/lib/solargraph.rb +15 -0
  125. data/rbs/fills/tuple.rbs +2 -3
  126. data/sig/shims/parser/3.2.0.1/builders/default.rbs +195 -0
  127. data/sig/shims/thor/1.2.0.1/.rbs_meta.yaml +9 -0
  128. data/sig/shims/thor/1.2.0.1/manifest.yaml +7 -0
  129. data/sig/shims/thor/1.2.0.1/thor.rbs +17 -0
  130. data/solargraph.gemspec +14 -4
  131. metadata +126 -9
  132. data/lib/.rubocop.yml +0 -22
@@ -8,17 +8,6 @@ module Solargraph
8
8
  include ParserGem::NodeMethods
9
9
 
10
10
  def process
11
- if Convention::StructDefinition::StructAssignmentNode.valid?(node)
12
- process_struct_assignment
13
- else
14
- process_constant_assignment
15
- end
16
- end
17
-
18
- private
19
-
20
- # @return [void]
21
- def process_constant_assignment
22
11
  pins.push Solargraph::Pin::Constant.new(
23
12
  location: get_node_location(node),
24
13
  closure: region.closure,
@@ -30,16 +19,7 @@ module Solargraph
30
19
  process_children
31
20
  end
32
21
 
33
- # @todo Move this out of [CasgnNode] once [Solargraph::Parser::NodeProcessor] supports
34
- # multiple processors.
35
- def process_struct_assignment
36
- processor_klass = Convention::StructDefinition::NodeProcessors::StructNode
37
- processor = processor_klass.new(node, region, pins, locals)
38
- processor.process
39
-
40
- @pins = processor.pins
41
- @locals = processor.locals
42
- end
22
+ private
43
23
 
44
24
  # @return [String]
45
25
  def const_name
@@ -11,6 +11,8 @@ module Solargraph
11
11
  process_children
12
12
 
13
13
  position = get_node_start_position(node)
14
+ # @sg-ignore
15
+ # @type [Solargraph::Pin::Breakable, nil]
14
16
  enclosing_breakable_pin = pins.select{|pin| pin.is_a?(Pin::Breakable) && pin.location.range.contain?(position)}.last
15
17
  FlowSensitiveTyping.new(locals, enclosing_breakable_pin).process_if(node)
16
18
  end
@@ -7,6 +7,7 @@ module Solargraph
7
7
  class MasgnNode < Parser::NodeProcessor::Base
8
8
  include ParserGem::NodeMethods
9
9
 
10
+ # @return [void]
10
11
  def process
11
12
  # Example:
12
13
  #
@@ -21,8 +22,11 @@ module Solargraph
21
22
  # s(:int, 2),
22
23
  # s(:int, 3)))
23
24
  masgn = node
25
+ # @type [Parser::AST::Node]
24
26
  mlhs = masgn.children.fetch(0)
27
+ # @type [Array<Parser::AST::Node>]
25
28
  lhs_arr = mlhs.children
29
+ # @type [Parser::AST::Node]
26
30
  mass_rhs = node.children.fetch(1)
27
31
 
28
32
  # Get pins created for the mlhs node
@@ -40,7 +44,9 @@ module Solargraph
40
44
  # @todo in line below, nothing in typechecking alerts
41
45
  # when a non-existant method is called on 'l'
42
46
  if pin.nil?
43
- Solargraph.logger.debug { "Could not find local for masgn= value in location #{location.inspect} in #{lhs_arr} - masgn = #{masgn}, lhs.type = #{lhs.type}" }
47
+ Solargraph.logger.debug do
48
+ "Could not find local for masgn= value in location #{location.inspect} in #{lhs_arr} - masgn = #{masgn}, lhs.type = #{lhs.type}"
49
+ end
44
50
  next
45
51
  end
46
52
  pin.mass_assignment = [mass_rhs, i]
@@ -11,17 +11,6 @@ module Solargraph
11
11
  superclass_name = nil
12
12
  superclass_name = unpack_name(node.children[1]) if node.type == :class && node.children[1]&.type == :const
13
13
 
14
- if Convention::StructDefinition::StructDefintionNode.valid?(node)
15
- process_struct_definition
16
- else
17
- process_namespace(superclass_name)
18
- end
19
- end
20
-
21
- private
22
-
23
- # @param superclass_name [String, nil]
24
- def process_namespace(superclass_name)
25
14
  loc = get_node_location(node)
26
15
  nspin = Solargraph::Pin::Namespace.new(
27
16
  type: node.type,
@@ -44,17 +33,6 @@ module Solargraph
44
33
  end
45
34
  process_children region.update(closure: nspin, visibility: :public)
46
35
  end
47
-
48
- # @todo Move this out of [NamespaceNode] once [Solargraph::Parser::NodeProcessor] supports
49
- # multiple processors.
50
- def process_struct_definition
51
- processor_klass = Convention::StructDefinition::NodeProcessors::StructNode
52
- processor = processor_klass.new(node, region, pins, locals)
53
- processor.process
54
-
55
- @pins = processor.pins
56
- @locals = processor.locals
57
- end
58
36
  end
59
37
  end
60
38
  end
@@ -7,6 +7,7 @@ module Solargraph
7
7
  module ParserGem
8
8
  module NodeProcessors
9
9
  class OpasgnNode < Parser::NodeProcessor::Base
10
+ # @return [void]
10
11
  def process
11
12
  # Parser::CurrentRuby.parse("a += 2")
12
13
  # => s(:op_asgn,
@@ -5,6 +5,7 @@ module Solargraph
5
5
  module ParserGem
6
6
  module NodeProcessors
7
7
  class OrasgnNode < Parser::NodeProcessor::Base
8
+ # @return [void]
8
9
  def process
9
10
  new_node = node.updated(node.children[0].type, node.children[0].children + [node.children[1]])
10
11
  NodeProcessor.process(new_node, region, pins, locals)
@@ -7,6 +7,7 @@ module Solargraph
7
7
  class ResbodyNode < Parser::NodeProcessor::Base
8
8
  include ParserGem::NodeMethods
9
9
 
10
+ # @return [void]
10
11
  def process
11
12
  if node.children[1] # Exception local variable name
12
13
  here = get_node_start_position(node.children[1])
@@ -8,32 +8,44 @@ module Solargraph
8
8
  include ParserGem::NodeMethods
9
9
 
10
10
  def process
11
+ # @sg-ignore Variable type could not be inferred for method_name
12
+ # @type [Symbol]
13
+ method_name = node.children[1]
14
+ # :nocov:
15
+ unless method_name.instance_of?(Symbol)
16
+ Solargraph.assert_or_log(:parser_method_name, "Expected method name to be a Symbol, got #{method_name.class} for node #{node.inspect}")
17
+ return process_children
18
+ end
19
+ # :nocov:
11
20
  if node.children[0].nil?
12
- if [:private, :public, :protected].include?(node.children[1])
21
+ if [:private, :public, :protected].include?(method_name)
13
22
  process_visibility
14
- elsif node.children[1] == :module_function
23
+ elsif method_name == :module_function
15
24
  process_module_function
16
- elsif [:attr_reader, :attr_writer, :attr_accessor].include?(node.children[1])
25
+ elsif [:attr_reader, :attr_writer, :attr_accessor].include?(method_name)
17
26
  process_attribute
18
- elsif node.children[1] == :include
27
+ elsif method_name == :include
19
28
  process_include
20
- elsif node.children[1] == :extend
29
+ elsif method_name == :extend
21
30
  process_extend
22
- elsif node.children[1] == :prepend
31
+ elsif method_name == :prepend
23
32
  process_prepend
24
- elsif node.children[1] == :require
33
+ elsif method_name == :require
25
34
  process_require
26
- elsif node.children[1] == :autoload
35
+ elsif method_name == :autoload
27
36
  process_autoload
28
- elsif node.children[1] == :private_constant
37
+ elsif method_name == :private_constant
29
38
  process_private_constant
30
- elsif node.children[1] == :alias_method && node.children[2] && node.children[2] && node.children[2].type == :sym && node.children[3] && node.children[3].type == :sym
39
+ # @sg-ignore
40
+ elsif method_name == :alias_method && node.children[2] && node.children[2] && node.children[2].type == :sym && node.children[3] && node.children[3].type == :sym
31
41
  process_alias_method
32
- elsif node.children[1] == :private_class_method && node.children[2].is_a?(AST::Node)
42
+ # @sg-ignore
43
+ elsif method_name == :private_class_method && node.children[2].is_a?(AST::Node)
33
44
  # Processing a private class can potentially handle children on its own
34
45
  return if process_private_class_method
35
46
  end
36
- elsif node.children[1] == :require && node.children[0].to_s == '(const nil :Bundler)'
47
+ # @sg-ignore
48
+ elsif method_name == :require && node.children[0].to_s == '(const nil :Bundler)'
37
49
  pins.push Pin::Reference::Require.new(Solargraph::Location.new(region.filename, Solargraph::Range.from_to(0, 0, 0, 0)), 'bundler/require', source: :parser)
38
50
  end
39
51
  process_children
@@ -45,15 +57,24 @@ module Solargraph
45
57
  def process_visibility
46
58
  if (node.children.length > 2)
47
59
  node.children[2..-1].each do |child|
60
+ # @sg-ignore Variable type could not be inferred for method_name
61
+ # @type [Symbol]
62
+ visibility = node.children[1]
63
+ # :nocov:
64
+ unless visibility.instance_of?(Symbol)
65
+ Solargraph.assert_or_log(:parser_visibility, "Expected visibility name to be a Symbol, got #{visibility.class} for node #{node.inspect}")
66
+ return process_children
67
+ end
68
+ # :nocov:
48
69
  if child.is_a?(AST::Node) && (child.type == :sym || child.type == :str)
49
70
  name = child.children[0].to_s
50
71
  matches = pins.select{ |pin| pin.is_a?(Pin::Method) && pin.name == name && pin.namespace == region.closure.full_context.namespace && pin.context.scope == (region.scope || :instance)}
51
72
  matches.each do |pin|
52
73
  # @todo Smelly instance variable access
53
- pin.instance_variable_set(:@visibility, node.children[1])
74
+ pin.instance_variable_set(:@visibility, visibility)
54
75
  end
55
76
  else
56
- process_children region.update(visibility: node.children[1])
77
+ process_children region.update(visibility: visibility)
57
78
  end
58
79
  end
59
80
  else
@@ -5,6 +5,7 @@ module Solargraph
5
5
  module ParserGem
6
6
  module NodeProcessors
7
7
  class SymNode < Parser::NodeProcessor::Base
8
+ # @return [void]
8
9
  def process
9
10
  pins.push Solargraph::Pin::Symbol.new(
10
11
  get_node_location(node),
@@ -42,6 +42,8 @@ module Solargraph
42
42
  register :defs, ParserGem::NodeProcessors::DefsNode
43
43
  register :if, ParserGem::NodeProcessors::IfNode
44
44
  register :send, ParserGem::NodeProcessors::SendNode
45
+ register :class, Convention::StructDefinition::NodeProcessors::StructNode
46
+ register :class, Convention::DataDefinition::NodeProcessors::DataNode
45
47
  register :class, ParserGem::NodeProcessors::NamespaceNode
46
48
  register :module, ParserGem::NodeProcessors::NamespaceNode
47
49
  register :sclass, ParserGem::NodeProcessors::SclassNode
@@ -49,6 +51,8 @@ module Solargraph
49
51
  register :cvasgn, ParserGem::NodeProcessors::CvasgnNode
50
52
  register :lvasgn, ParserGem::NodeProcessors::LvasgnNode
51
53
  register :gvasgn, ParserGem::NodeProcessors::GvasgnNode
54
+ register :casgn, Convention::StructDefinition::NodeProcessors::StructNode
55
+ register :casgn, Convention::DataDefinition::NodeProcessors::DataNode
52
56
  register :casgn, ParserGem::NodeProcessors::CasgnNode
53
57
  register :masgn, ParserGem::NodeProcessors::MasgnNode
54
58
  register :alias, ParserGem::NodeProcessors::AliasNode
@@ -23,8 +23,10 @@ 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
@@ -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
@@ -13,10 +13,10 @@ module Solargraph
13
13
  # @return [YARD::CodeObjects::Base]
14
14
  attr_reader :code_object
15
15
 
16
- # @return [Solargraph::Location]
16
+ # @return [Solargraph::Location, nil]
17
17
  attr_reader :location
18
18
 
19
- # @return [Solargraph::Location]
19
+ # @return [Solargraph::Location, nil]
20
20
  attr_reader :type_location
21
21
 
22
22
  # @return [String]
@@ -28,6 +28,11 @@ module Solargraph
28
28
  # @return [::Symbol]
29
29
  attr_accessor :source
30
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
+
31
36
  def presence_certain?
32
37
  true
33
38
  end
@@ -40,7 +45,8 @@ module Solargraph
40
45
  # @param source [Symbol, nil]
41
46
  # @param docstring [YARD::Docstring, nil]
42
47
  # @param directives [::Array<YARD::Tags::Directive>, nil]
43
- def initialize location: nil, type_location: nil, closure: nil, source: nil, name: '', comments: '', docstring: nil, directives: 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
44
50
  @location = location
45
51
  @type_location = type_location
46
52
  @closure = closure
@@ -50,15 +56,35 @@ module Solargraph
50
56
  @identity = nil
51
57
  @docstring = docstring
52
58
  @directives = directives
59
+ @combine_priority = combine_priority
60
+
53
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
54
77
  end
55
78
 
56
79
  # @param other [self]
57
- # @param attrs [Hash{Symbol => Object}]
80
+ # @param attrs [Hash{::Symbol => Object}]
58
81
  #
59
82
  # @return [self]
60
83
  def combine_with(other, attrs={})
61
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
+
62
88
  type_location = choose(other, :type_location)
63
89
  location = choose(other, :location)
64
90
  combined_name = combine_name(other)
@@ -71,6 +97,7 @@ module Solargraph
71
97
  source: :combined,
72
98
  docstring: choose(other, :docstring),
73
99
  directives: combine_directives(other),
100
+ combine_priority: combine_priority
74
101
  }.merge(attrs)
75
102
  assert_same_macros(other)
76
103
  logger.debug { "Base#combine_with(path=#{path}) - other.comments=#{other.comments.inspect}, self.comments = #{self.comments}" }
@@ -79,6 +106,25 @@ module Solargraph
79
106
  out
80
107
  end
81
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
+
82
128
  # @param other [self]
83
129
  # @param attr [::Symbol]
84
130
  # @sg-ignore
@@ -90,7 +136,6 @@ module Solargraph
90
136
  val2 = other.send(attr)
91
137
  return val1 if val1 == val2
92
138
  return val2 if val1.nil?
93
- # @sg-ignore
94
139
  val1.length > val2.length ? val1 : val2
95
140
  end
96
141
 
@@ -180,7 +225,7 @@ module Solargraph
180
225
  end
181
226
 
182
227
  # @param other [self]
183
- # @param attr [Symbol]
228
+ # @param attr [::Symbol]
184
229
  # @sg-ignore
185
230
  # @return [undefined]
186
231
  def choose_node(other, attr)
@@ -229,7 +274,6 @@ module Solargraph
229
274
  raise "Expected #{attr} on #{other} to be an Enumerable, got #{arr2.class}" unless arr2.is_a?(::Enumerable)
230
275
  # @type arr2 [::Enumerable]
231
276
 
232
- # @sg-ignore
233
277
  # @type [undefined]
234
278
  values1 = arr1.map(&block)
235
279
  # @type [undefined]
@@ -261,7 +305,8 @@ module Solargraph
261
305
  # @param other [self]
262
306
  # @param attr [::Symbol]
263
307
  #
264
- # @return [Object, nil]
308
+ # @sg-ignore
309
+ # @return [undefined]
265
310
  def assert_same(other, attr)
266
311
  return false if other.nil?
267
312
  val1 = send(attr)
@@ -290,20 +335,29 @@ module Solargraph
290
335
  choose_pin_attr(other, attr)
291
336
  end
292
337
 
338
+ # @param other [self]
339
+ # @param attr [::Symbol]
340
+ #
341
+ # @sg-ignore
342
+ # @return [undefined]
293
343
  def choose_pin_attr(other, attr)
294
344
  # @type [Pin::Base, nil]
295
345
  val1 = send(attr)
296
346
  # @type [Pin::Base, nil]
297
347
  val2 = other.send(attr)
298
348
  if val1.class != val2.class
349
+ # :nocov:
299
350
  Solargraph.assert_or_log("combine_with_#{attr}_class".to_sym,
300
351
  "Inconsistent #{attr.inspect} class values between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self.#{attr} = #{val1.inspect}\nother.#{attr} = #{val2.inspect}")
301
352
  return val1
353
+ # :nocov:
302
354
  end
303
355
  # arbitrary way of choosing a pin
356
+ # @sg-ignore Need _1 support
304
357
  [val1, val2].compact.min_by { _1.best_location.to_s }
305
358
  end
306
359
 
360
+ # @return [void]
307
361
  def assert_source_provided
308
362
  Solargraph.assert_or_log(:source, "source not provided - #{@path} #{@source} #{self.class}") if source.nil?
309
363
  end
@@ -548,6 +602,7 @@ module Solargraph
548
602
  "name=#{name.inspect} return_type=#{type_desc}, context=#{context.rooted_tags}, closure=#{closure_info}, binder=#{binder_info}"
549
603
  end
550
604
 
605
+ # @return [String]
551
606
  def desc
552
607
  "[#{inner_desc}]"
553
608
  end
@@ -557,6 +612,7 @@ module Solargraph
557
612
  "#<#{self.class} `#{self.inner_desc}`#{all_location_text} via #{source.inspect}>"
558
613
  end
559
614
 
615
+ # @return [String]
560
616
  def all_location_text
561
617
  if location.nil? && type_location.nil?
562
618
  ''
@@ -569,6 +625,7 @@ module Solargraph
569
625
  end
570
626
  end
571
627
 
628
+ # @return [void]
572
629
  def reset_generated!
573
630
  end
574
631
 
@@ -3,8 +3,8 @@
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
@@ -43,7 +43,6 @@ module Solargraph
43
43
  @return_type ||= generate_complex_type
44
44
  end
45
45
 
46
- # @sg-ignore
47
46
  def nil_assignment?
48
47
  # this will always be false - should it be return_type ==
49
48
  # ComplexType::NIL or somesuch?
@@ -21,10 +21,13 @@ module Solargraph
21
21
  @parameters = parameters
22
22
  end
23
23
 
24
+ # @return [String]
24
25
  def method_namespace
25
26
  closure.namespace
26
27
  end
27
28
 
29
+ # @param other [self]
30
+ # @return [Pin::Block, nil]
28
31
  def combine_blocks(other)
29
32
  if block.nil?
30
33
  other.block
@@ -57,6 +60,8 @@ module Solargraph
57
60
  []
58
61
  end
59
62
 
63
+ # @param other [self]
64
+ # @return [Array<Pin::Parameter>]
60
65
  def choose_parameters(other)
61
66
  raise "Trying to combine two pins with different arities - \nself =#{inspect}, \nother=#{other.inspect}, \n\n self.arity=#{self.arity}, \nother.arity=#{other.arity}" if other.arity != arity
62
67
  parameters.zip(other.parameters).map do |param, other_param|
@@ -70,6 +75,7 @@ module Solargraph
70
75
  end
71
76
  end
72
77
 
78
+ # @return [Array<Pin::Parameter>]
73
79
  def blockless_parameters
74
80
  if parameters.last&.block?
75
81
  parameters[0..-2]
@@ -78,6 +84,7 @@ module Solargraph
78
84
  end
79
85
  end
80
86
 
87
+ # @return [Array]
81
88
  def arity
82
89
  [generics, blockless_parameters.map(&:arity_decl), block&.arity]
83
90
  end
@@ -125,6 +132,7 @@ module Solargraph
125
132
  end
126
133
  end
127
134
 
135
+ # @return [String]
128
136
  def method_name
129
137
  raise "closure was nil in #{self.inspect}" if closure.nil?
130
138
  @method_name ||= closure.name
@@ -197,6 +205,7 @@ module Solargraph
197
205
  true
198
206
  end
199
207
 
208
+ # @return [Integer]
200
209
  def mandatory_positional_param_count
201
210
  parameters.count(&:arg?)
202
211
  end
@@ -8,6 +8,7 @@ module Solargraph
8
8
 
9
9
  # @param scope [::Symbol] :class or :instance
10
10
  # @param generics [::Array<Pin::Parameter>, nil]
11
+ # @param generic_defaults [Hash{String => ComplexType}]
11
12
  def initialize scope: :class, generics: nil, generic_defaults: {}, **splat
12
13
  super(**splat)
13
14
  @scope = scope
@@ -15,6 +16,7 @@ module Solargraph
15
16
  @generic_defaults = generic_defaults
16
17
  end
17
18
 
19
+ # @return [Hash{String => ComplexType}]
18
20
  def generic_defaults
19
21
  @generic_defaults ||= {}
20
22
  end
@@ -3,12 +3,16 @@
3
3
  module Solargraph
4
4
  module Pin
5
5
  module Common
6
+ # @!method source
7
+ # @abstract
8
+ # @return [Source, nil]
9
+ # @type @closure [Pin::Closure, nil]
10
+
6
11
  # @return [Location]
7
12
  attr_reader :location
8
13
 
14
+ # @sg-ignore Solargraph::Pin::Common#closure return type could not be inferred
9
15
  # @return [Pin::Closure, nil]
10
- attr_reader :closure
11
-
12
16
  def closure
13
17
  Solargraph.assert_or_log(:closure, "Closure not set on #{self.class} #{name.inspect} from #{source.inspect}") unless @closure
14
18
  @closure
@@ -5,6 +5,8 @@ module Solargraph
5
5
  class Constant < BaseVariable
6
6
  attr_reader :visibility
7
7
 
8
+ # @param visibility [::Symbol] The visibility of the constant (:public, :protected, or :private)
9
+ # @param splat [Hash] Additional options supported by superclasses
8
10
  def initialize visibility: :public, **splat
9
11
  super(**splat)
10
12
  @visibility = visibility
@@ -51,6 +51,7 @@ module Solargraph
51
51
  %i[typify realize infer probe].each do |method|
52
52
  # @param api_map [ApiMap]
53
53
  define_method(method) do |api_map|
54
+ # @sg-ignore Unresolved call to resolve_method
54
55
  resolve_method(api_map)
55
56
  # @sg-ignore Need to set context correctly in define_method blocks
56
57
  @resolved_method ? @resolved_method.send(method, api_map) : super(api_map)
@@ -26,7 +26,10 @@ module Solargraph
26
26
  assignment: assert_same(other, :assignment),
27
27
  presence_certain: assert_same(other, :presence_certain?),
28
28
  }.merge(attrs)
29
- new_attrs[:presence] = assert_same(other, :presence) unless attrs.key?(:presence)
29
+ # @sg-ignore Wrong argument type for
30
+ # Solargraph::Pin::Base#assert_same: other expected
31
+ # Solargraph::Pin::Base, received self
32
+ new_attrs[:presence] = assert_same(other, :presence) unless attrs.key?(:presence)
30
33
 
31
34
  super(other, new_attrs)
32
35
  end