solargraph 0.56.1 → 0.56.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 (32) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +60 -0
  4. data/lib/solargraph/convention/data_definition/data_definition_node.rb +89 -0
  5. data/lib/solargraph/convention/data_definition.rb +104 -0
  6. data/lib/solargraph/convention/gemspec.rb +2 -1
  7. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +1 -1
  8. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +1 -1
  9. data/lib/solargraph/convention/struct_definition.rb +60 -20
  10. data/lib/solargraph/convention.rb +1 -0
  11. data/lib/solargraph/library.rb +9 -9
  12. data/lib/solargraph/parser/node_processor/base.rb +9 -4
  13. data/lib/solargraph/parser/node_processor.rb +19 -7
  14. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +1 -21
  15. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +4 -1
  16. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +0 -22
  17. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +1 -0
  18. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -0
  19. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +1 -0
  20. data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +1 -0
  21. data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
  22. data/lib/solargraph/pin/base.rb +15 -0
  23. data/lib/solargraph/pin/method.rb +4 -2
  24. data/lib/solargraph/rbs_map/conversions.rb +41 -14
  25. data/lib/solargraph/version.rb +1 -1
  26. data/lib/solargraph/workspace/config.rb +1 -1
  27. data/lib/solargraph/yard_map/helpers.rb +29 -1
  28. data/lib/solargraph/yard_map/mapper/to_constant.rb +5 -5
  29. data/lib/solargraph/yard_map/mapper/to_method.rb +1 -6
  30. data/lib/solargraph/yard_map/mapper/to_namespace.rb +7 -7
  31. data/lib/solargraph.rb +13 -0
  32. metadata +5 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ed69bea4d42d6605dab61eb153507927ac3104946f39eb1ff8380676df9d0cbc
4
- data.tar.gz: 569b85b0c73b81135d93d814db90ffbb861a0c752515c689edaa60742d0d0f81
3
+ metadata.gz: 82754cd0869fed91a86a2bfb08ca0f54d6468f942620cddd3148bad99724ad88
4
+ data.tar.gz: 4e017a78936b0d24eaa6d5db7edcd01ea2b43d6cb365eb5b4892576a141ca2b7
5
5
  SHA512:
6
- metadata.gz: 84ed3ec4cd5c58a28311964b7f201dc98c2aeaff25e383e96cf9b05a8d90a9a65552b818ee033c5a16a45d4c584069696c90299d5bc831b85985ae14f823718b
7
- data.tar.gz: e1eb56a9f697e2cc3873ab1e60eec0608cec014d599b3ac40b832c96d3e9a90fdba4a3846127b4dc6c1270cf94344721fe0bf2d79d0db4db57cde999c418f4b2
6
+ metadata.gz: 304fb86181925f916d7119da44b85a3753fc33d961da8a61c5525dbcb8d814a87baeeb9767d17b7ec6548c3ffe725bfda6eafbfd7ea75e8bdddf3f1a1a5c103b
7
+ data.tar.gz: 73d437e753be70628008f09a7846cba5e16fd47d045017b41c0b301d8a5b34ca04a45127a37c6eada4e61287944ca1af659ecab8df4681bab42a8ecc37d73bc4
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 0.56.2 - July 29, 2025
2
+ - Add support for Ruby Data.define (#970)
3
+ - Ensure that pin locations are always populated (#965)
4
+ - Improve struct support (#992)
5
+ - Include Rakefile, Gemfile, and gemspec files in config by default (#984)
6
+ - Use Open3 to cache gemspecs (#1000)
7
+ - Eager load node processors (#1002)
8
+
1
9
  ## 0.56.1 - July 13, 2025
2
10
  - Library avoids blocking on pending yardoc caches (#990)
3
11
  - DocMap checks for default Gemfile (#989)
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Convention
5
+ module DataDefinition
6
+ # A node wrapper for a Data definition via const assignment.
7
+ # @example
8
+ # MyData = Data.new(:bar, :baz) do
9
+ # def foo
10
+ # end
11
+ # end
12
+ class DataAssignmentNode < DataDefintionNode
13
+ class << self
14
+ # @example
15
+ # s(:casgn, nil, :Foo,
16
+ # s(:block,
17
+ # s(:send,
18
+ # s(:const, nil, :Data), :define,
19
+ # s(:sym, :bar),
20
+ # s(:sym, :baz)),
21
+ # s(:args),
22
+ # s(:def, :foo,
23
+ # s(:args),
24
+ # s(:send, nil, :bar))))
25
+ def match?(node)
26
+ return false unless node&.type == :casgn
27
+ return false if node.children[2].nil?
28
+
29
+ data_node = if node.children[2].type == :block
30
+ node.children[2].children[0]
31
+ else
32
+ node.children[2]
33
+ end
34
+
35
+ data_definition_node?(data_node)
36
+ end
37
+ end
38
+
39
+ def class_name
40
+ if node.children[0]
41
+ Parser::NodeMethods.unpack_name(node.children[0]) + "::#{node.children[1]}"
42
+ else
43
+ node.children[1].to_s
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ # @return [Parser::AST::Node]
50
+ def data_node
51
+ if node.children[2].type == :block
52
+ node.children[2].children[0]
53
+ else
54
+ node.children[2]
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Convention
5
+ module DataDefinition
6
+ # A node wrapper for a Data definition via inheritance.
7
+ # @example
8
+ # class MyData < Data.new(:bar, :baz)
9
+ # def foo
10
+ # end
11
+ # end
12
+ class DataDefintionNode
13
+ class << self
14
+ # @example
15
+ # s(:class,
16
+ # s(:const, nil, :Foo),
17
+ # s(:send,
18
+ # s(:const, nil, :Data), :define,
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 match?(node)
29
+ return false unless node&.type == :class
30
+
31
+ data_definition_node?(node.children[1])
32
+ end
33
+
34
+ private
35
+
36
+ # @param data_node [Parser::AST::Node]
37
+ # @return [Boolean]
38
+ def data_definition_node?(data_node)
39
+ return false unless data_node.is_a?(::Parser::AST::Node)
40
+ return false unless data_node&.type == :send
41
+ return false unless data_node.children[0]&.type == :const
42
+ return false unless data_node.children[0].children[1] == :Data
43
+ return false unless data_node.children[1] == :define
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
+ data_attribute_nodes.map do |data_def_param|
62
+ next unless data_def_param.type == :sym
63
+ [data_def_param, data_def_param.children[0].to_s]
64
+ end.compact
65
+ end
66
+
67
+ # @return [Parser::AST::Node]
68
+ def body_node
69
+ node.children[2]
70
+ end
71
+
72
+ private
73
+
74
+ # @return [Parser::AST::Node]
75
+ attr_reader :node
76
+
77
+ # @return [Parser::AST::Node]
78
+ def data_node
79
+ node.children[1]
80
+ end
81
+
82
+ # @return [Array<Parser::AST::Node>]
83
+ def data_attribute_nodes
84
+ data_node.children[2..-1]
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Convention
5
+ module DataDefinition
6
+ autoload :DataDefintionNode, 'solargraph/convention/data_definition/data_definition_node'
7
+ autoload :DataAssignmentNode, 'solargraph/convention/data_definition/data_assignment_node'
8
+
9
+ module NodeProcessors
10
+ class DataNode < Parser::NodeProcessor::Base
11
+ # @return [Boolean] continue processing the next processor of the same node.
12
+ def process
13
+ return true if data_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: data_definition_node.class_name,
21
+ comments: comments_for(node),
22
+ visibility: :public,
23
+ gates: region.closure.gates.freeze
24
+ )
25
+ pins.push nspin
26
+
27
+ # define initialize method
28
+ initialize_method_pin = Pin::Method.new(
29
+ name: 'initialize',
30
+ parameters: [],
31
+ scope: :instance,
32
+ location: get_node_location(node),
33
+ closure: nspin,
34
+ visibility: :private,
35
+ comments: comments_for(node)
36
+ )
37
+
38
+ # TODO: Support both arg and kwarg initializers for Data.define
39
+ # Solargraph::SourceMap::Clip#complete_keyword_parameters does not seem to currently take into account [Pin::Method#signatures] hence we only one for :kwarg
40
+ pins.push initialize_method_pin
41
+
42
+ data_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: :kwarg,
47
+ location: get_node_location(attribute_node),
48
+ closure: initialize_method_pin
49
+ )
50
+ )
51
+ end
52
+
53
+ # define attribute readers and instance variables
54
+ data_definition_node.attributes.each do |attribute_node, attribute_name|
55
+ name = attribute_name.to_s
56
+ method_pin = Pin::Method.new(
57
+ name: name,
58
+ parameters: [],
59
+ scope: :instance,
60
+ location: get_node_location(attribute_node),
61
+ closure: nspin,
62
+ comments: attribute_comments(attribute_node, attribute_name),
63
+ visibility: :public
64
+ )
65
+
66
+ pins.push method_pin
67
+
68
+ pins.push Pin::InstanceVariable.new(name: "@#{attribute_name}",
69
+ closure: method_pin,
70
+ location: get_node_location(attribute_node),
71
+ comments: attribute_comments(attribute_node, attribute_name))
72
+ end
73
+
74
+ process_children region.update(closure: nspin, visibility: :public)
75
+
76
+ false
77
+ end
78
+
79
+ private
80
+
81
+ # @return [DataDefintionNode, nil]
82
+ def data_definition_node
83
+ @data_definition_node ||= if DataDefintionNode.match?(node)
84
+ DataDefintionNode.new(node)
85
+ elsif DataAssignmentNode.match?(node)
86
+ DataAssignmentNode.new(node)
87
+ end
88
+ end
89
+
90
+ # @param attribute_node [Parser::AST::Node]
91
+ # @return [String, nil]
92
+ def attribute_comments(attribute_node, attribute_name)
93
+ data_comments = comments_for(attribute_node)
94
+ return if data_comments.nil? || data_comments.empty?
95
+
96
+ data_comments.split("\n").find do |row|
97
+ row.include?(attribute_name)
98
+ end&.gsub('@param', '@return')&.gsub(attribute_name, '')
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -12,7 +12,8 @@ module Solargraph
12
12
  'Gem::Specification.new',
13
13
  %(
14
14
  @yieldparam [self]
15
- )
15
+ ),
16
+ source: :gemspec
16
17
  )
17
18
  ]
18
19
  )
@@ -22,7 +22,7 @@ module Solargraph
22
22
  # s(:def, :foo,
23
23
  # s(:args),
24
24
  # s(:send, nil, :bar))))
25
- def valid?(node)
25
+ def match?(node)
26
26
  return false unless node&.type == :casgn
27
27
  return false if node.children[2].nil?
28
28
 
@@ -25,7 +25,7 @@ module Solargraph
25
25
  # s(:def, :foo,
26
26
  # s(:args),
27
27
  # s(:send, nil, :bar)))
28
- def valid?(node)
28
+ def match?(node)
29
29
  return false unless node&.type == :class
30
30
 
31
31
  struct_definition_node?(node.children[1])
@@ -8,8 +8,9 @@ module Solargraph
8
8
 
9
9
  module NodeProcessors
10
10
  class StructNode < Parser::NodeProcessor::Base
11
+ # @return [Boolean] continue processing the next processor of the same node.
11
12
  def process
12
- return if struct_definition_node.nil?
13
+ return true if struct_definition_node.nil?
13
14
 
14
15
  loc = get_node_location(node)
15
16
  nspin = Solargraph::Pin::Namespace.new(
@@ -17,7 +18,7 @@ module Solargraph
17
18
  location: loc,
18
19
  closure: region.closure,
19
20
  name: struct_definition_node.class_name,
20
- comments: comments_for(node),
21
+ docstring: docstring,
21
22
  visibility: :public,
22
23
  gates: region.closure.gates.freeze
23
24
  )
@@ -31,7 +32,7 @@ module Solargraph
31
32
  location: get_node_location(node),
32
33
  closure: nspin,
33
34
  visibility: :private,
34
- comments: comments_for(node)
35
+ docstring: docstring
35
36
  )
36
37
 
37
38
  pins.push initialize_method_pin
@@ -50,49 +51,88 @@ module Solargraph
50
51
  # define attribute accessors and instance variables
51
52
  struct_definition_node.attributes.each do |attribute_node, attribute_name|
52
53
  [attribute_name, "#{attribute_name}="].each do |name|
54
+ docs = docstring.tags.find { |t| t.tag_name == 'param' && t.name == attribute_name }
55
+
53
56
  method_pin = Pin::Method.new(
54
57
  name: name,
55
58
  parameters: [],
56
59
  scope: :instance,
57
60
  location: get_node_location(attribute_node),
58
61
  closure: nspin,
59
- comments: attribute_comments(attribute_node, attribute_name),
62
+ # even assignments return the value
63
+ comments: attribute_comment(docs, false),
60
64
  visibility: :public
61
65
  )
62
66
 
63
- pins.push method_pin
67
+ if name.end_with?('=')
68
+ method_pin.parameters << Pin::Parameter.new(
69
+ name: attribute_name,
70
+ location: get_node_location(attribute_node),
71
+ closure: nspin,
72
+ comments: attribute_comment(docs, true)
73
+ )
64
74
 
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))
75
+ pins.push Pin::InstanceVariable.new(name: "@#{attribute_name}",
76
+ closure: method_pin,
77
+ location: get_node_location(attribute_node),
78
+ comments: attribute_comment(docs, false))
79
+ end
80
+
81
+ pins.push method_pin
70
82
  end
71
83
  end
72
84
 
73
85
  process_children region.update(closure: nspin, visibility: :public)
86
+ false
74
87
  end
75
88
 
76
89
  private
77
90
 
78
91
  # @return [StructDefintionNode, nil]
79
92
  def struct_definition_node
80
- @struct_definition_node ||= if StructDefintionNode.valid?(node)
93
+ @struct_definition_node ||= if StructDefintionNode.match?(node)
81
94
  StructDefintionNode.new(node)
82
- elsif StructAssignmentNode.valid?(node)
95
+ elsif StructAssignmentNode.match?(node)
83
96
  StructAssignmentNode.new(node)
84
97
  end
85
98
  end
86
99
 
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?
100
+ # Gets/generates the relevant docstring for this struct & it's attributes
101
+ # @return [YARD::Docstring]
102
+ def docstring
103
+ @docstring ||= parse_comments
104
+ end
105
+
106
+ # Parses any relevant comments for a struct int a yard docstring
107
+ # @return [YARD::Docstring]
108
+ def parse_comments
109
+ struct_comments = comments_for(node) || ''
110
+ struct_definition_node.attributes.each do |attr_node, attr_name|
111
+ comment = comments_for(attr_node)
112
+ next if comment.nil?
113
+
114
+ # We should support specific comments for an attribute, and that can be either a @return on an @param
115
+ # But since we merge into the struct_comments, then we should interpret either as a param
116
+ comment = '@param ' + attr_name + comment[7..] if comment.start_with?('@return')
117
+
118
+ struct_comments += "\n#{comment}"
119
+ end
120
+
121
+ Solargraph::Source.parse_docstring(struct_comments).to_docstring
122
+ end
123
+
124
+ # @param tag [YARD::Tags::Tag, nil] The param tag for this attribute. If nil, this method is a no-op
125
+ # @param for_setter [Boolean] If true, will return a @param tag instead of a @return tag
126
+ def attribute_comment(tag, for_setter)
127
+ return "" if tag.nil?
128
+
129
+ suffix = "[#{tag.types&.join(',') || 'undefined'}] #{tag.text}"
92
130
 
93
- struct_comments.split("\n").find do |row|
94
- row.include?(attribute_name)
95
- end&.gsub('@param', '@return')&.gsub(attribute_name, '')
131
+ if for_setter
132
+ "@param #{tag.name} #{suffix}"
133
+ else
134
+ "@return #{suffix}"
135
+ end
96
136
  end
97
137
  end
98
138
  end
@@ -11,6 +11,7 @@ module Solargraph
11
11
  autoload :Gemspec, 'solargraph/convention/gemspec'
12
12
  autoload :Rakefile, 'solargraph/convention/rakefile'
13
13
  autoload :StructDefinition, 'solargraph/convention/struct_definition'
14
+ autoload :DataDefinition, 'solargraph/convention/data_definition'
14
15
 
15
16
  # @type [Set<Convention::Base>]
16
17
  @@conventions = Set.new
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'pathname'
4
4
  require 'observer'
5
+ require 'open3'
5
6
 
6
7
  module Solargraph
7
8
  # A Library handles coordination between a Workspace and an ApiMap.
@@ -604,16 +605,15 @@ module Solargraph
604
605
  else
605
606
  logger.info "Caching #{spec.name} #{spec.version}"
606
607
  Thread.new do
607
- cache_pid = Process.spawn(workspace.command_path, 'cache', spec.name, spec.version.to_s)
608
608
  report_cache_progress spec.name, pending
609
- Process.wait(cache_pid)
610
- logger.info "Cached #{spec.name} #{spec.version}"
611
- rescue Errno::EINVAL => _e
612
- logger.info "Cached #{spec.name} #{spec.version} with EINVAL"
613
- rescue StandardError => e
614
- cache_errors.add spec
615
- Solargraph.logger.warn "Error caching gemspec #{spec.name} #{spec.version}: [#{e.class}] #{e.message}"
616
- ensure
609
+ _o, e, s = Open3.capture3(workspace.command_path, 'cache', spec.name, spec.version.to_s)
610
+ if s.success?
611
+ logger.info "Cached #{spec.name} #{spec.version}"
612
+ else
613
+ cache_errors.add spec
614
+ logger.warn "Error caching gemspec #{spec.name} #{spec.version}"
615
+ logger.warn e
616
+ end
617
617
  end_cache_progress
618
618
  catalog
619
619
  sync_catalog
@@ -30,9 +30,12 @@ module Solargraph
30
30
 
31
31
  # Subclasses should override this method to generate new pins.
32
32
  #
33
- # @return [void]
33
+ # @return [Boolean] continue processing the next processor of the same node type.
34
+ # @return [void] In case there is only one processor registered for the node type, it can be void.
34
35
  def process
35
36
  process_children
37
+
38
+ true
36
39
  end
37
40
 
38
41
  private
@@ -64,7 +67,9 @@ module Solargraph
64
67
  # @param position [Solargraph::Position]
65
68
  # @return [Pin::Closure, nil]
66
69
  def named_path_pin position
67
- pins.select{|pin| pin.is_a?(Pin::Closure) && pin.path && !pin.path.empty? && pin.location.range.contain?(position)}.last
70
+ pins.select do |pin|
71
+ pin.is_a?(Pin::Closure) && pin.path && !pin.path.empty? && pin.location.range.contain?(position)
72
+ end.last
68
73
  end
69
74
 
70
75
  # @todo Candidate for deprecation
@@ -72,14 +77,14 @@ module Solargraph
72
77
  # @return [Pin::Closure, nil]
73
78
  def block_pin position
74
79
  # @todo determine if this can return a Pin::Block
75
- pins.select{|pin| pin.is_a?(Pin::Closure) && pin.location.range.contain?(position)}.last
80
+ pins.select { |pin| pin.is_a?(Pin::Closure) && pin.location.range.contain?(position) }.last
76
81
  end
77
82
 
78
83
  # @todo Candidate for deprecation
79
84
  # @param position [Solargraph::Position]
80
85
  # @return [Pin::Closure, nil]
81
86
  def closure_pin position
82
- pins.select{|pin| pin.is_a?(Pin::Closure) && pin.location.range.contain?(position)}.last
87
+ pins.select { |pin| pin.is_a?(Pin::Closure) && pin.location.range.contain?(position) }.last
83
88
  end
84
89
  end
85
90
  end
@@ -9,16 +9,22 @@ module Solargraph
9
9
  autoload :Base, 'solargraph/parser/node_processor/base'
10
10
 
11
11
  class << self
12
- # @type [Hash{Symbol => Class<NodeProcessor::Base>}]
12
+ # @type [Hash<Symbol, Array<Class<NodeProcessor::Base>>>]
13
13
  @@processors ||= {}
14
14
 
15
- # Register a processor for a node type.
15
+ # Register a processor for a node type. You can register multiple processors for the same type.
16
+ # If a node processor returns true, it will skip the next processor of the same node type.
16
17
  #
17
18
  # @param type [Symbol]
18
19
  # @param cls [Class<NodeProcessor::Base>]
19
20
  # @return [Class<NodeProcessor::Base>]
20
21
  def register type, cls
21
- @@processors[type] = cls
22
+ @@processors[type] ||= []
23
+ @@processors[type] << cls
24
+ end
25
+
26
+ def deregister type, cls
27
+ @@processors[type].delete(cls)
22
28
  end
23
29
  end
24
30
 
@@ -36,10 +42,16 @@ module Solargraph
36
42
  )
37
43
  end
38
44
  return [pins, locals] unless Parser.is_ast_node?(node)
39
- klass = @@processors[node.type] || NodeProcessor::Base
40
- processor = klass.new(node, region, pins, locals)
41
- processor.process
42
- [processor.pins, processor.locals]
45
+ node_processor_classes = @@processors[node.type] || [NodeProcessor::Base]
46
+
47
+ node_processor_classes.each do |klass|
48
+ processor = klass.new(node, region, pins, locals)
49
+ process_next = processor.process
50
+
51
+ break unless process_next
52
+ end
53
+
54
+ [pins, locals]
43
55
  end
44
56
  end
45
57
  end
@@ -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
@@ -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
  #
@@ -40,7 +41,9 @@ module Solargraph
40
41
  # @todo in line below, nothing in typechecking alerts
41
42
  # when a non-existant method is called on 'l'
42
43
  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}" }
44
+ Solargraph.logger.debug do
45
+ "Could not find local for masgn= value in location #{location.inspect} in #{lhs_arr} - masgn = #{masgn}, lhs.type = #{lhs.type}"
46
+ end
44
47
  next
45
48
  end
46
49
  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])
@@ -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
@@ -51,6 +51,14 @@ module Solargraph
51
51
  @docstring = docstring
52
52
  @directives = directives
53
53
  assert_source_provided
54
+ assert_location_provided
55
+ end
56
+
57
+ # @return [void]
58
+ def assert_location_provided
59
+ return unless best_location.nil? && %i[yardoc source rbs].include?(source)
60
+
61
+ Solargraph.assert_or_log(:best_location, "Neither location nor type_location provided - #{path} #{source} #{self.class}")
54
62
  end
55
63
 
56
64
  # @param other [self]
@@ -290,6 +298,9 @@ module Solargraph
290
298
  choose_pin_attr(other, attr)
291
299
  end
292
300
 
301
+ # @param other [self]
302
+ # @param attr [::Symbol]
303
+ # @return [undefined]
293
304
  def choose_pin_attr(other, attr)
294
305
  # @type [Pin::Base, nil]
295
306
  val1 = send(attr)
@@ -304,6 +315,7 @@ module Solargraph
304
315
  [val1, val2].compact.min_by { _1.best_location.to_s }
305
316
  end
306
317
 
318
+ # @return [void]
307
319
  def assert_source_provided
308
320
  Solargraph.assert_or_log(:source, "source not provided - #{@path} #{@source} #{self.class}") if source.nil?
309
321
  end
@@ -548,6 +560,7 @@ module Solargraph
548
560
  "name=#{name.inspect} return_type=#{type_desc}, context=#{context.rooted_tags}, closure=#{closure_info}, binder=#{binder_info}"
549
561
  end
550
562
 
563
+ # @return [String]
551
564
  def desc
552
565
  "[#{inner_desc}]"
553
566
  end
@@ -557,6 +570,7 @@ module Solargraph
557
570
  "#<#{self.class} `#{self.inner_desc}`#{all_location_text} via #{source.inspect}>"
558
571
  end
559
572
 
573
+ # @return [String]
560
574
  def all_location_text
561
575
  if location.nil? && type_location.nil?
562
576
  ''
@@ -569,6 +583,7 @@ module Solargraph
569
583
  end
570
584
  end
571
585
 
586
+ # @return [void]
572
587
  def reset_generated!
573
588
  end
574
589
 
@@ -199,9 +199,11 @@ module Solargraph
199
199
  )
200
200
  end
201
201
  yield_return_type = ComplexType.try_parse(*yieldreturn_tags.flat_map(&:types))
202
- block = Signature.new(generics: generics, parameters: yield_parameters, return_type: yield_return_type, source: source, closure: self)
202
+ block = Signature.new(generics: generics, parameters: yield_parameters, return_type: yield_return_type, source: source,
203
+ closure: self, location: location, type_location: type_location)
203
204
  end
204
- signature = Signature.new(generics: generics, parameters: parameters, return_type: return_type, block: block, closure: self, source: source)
205
+ signature = Signature.new(generics: generics, parameters: parameters, return_type: return_type, block: block, closure: self, source: source,
206
+ location: location, type_location: type_location)
205
207
  block.closure = signature if block
206
208
  signature
207
209
  end
@@ -22,12 +22,14 @@ module Solargraph
22
22
  end
23
23
  end
24
24
 
25
+ # @param loader [RBS::EnvironmentLoader]
25
26
  def initialize(loader:)
26
27
  @loader = loader
27
28
  @pins = []
28
29
  load_environment_to_pins(loader)
29
30
  end
30
31
 
32
+ # @return [RBS::EnvironmentLoader]
31
33
  attr_reader :loader
32
34
 
33
35
  # @return [Array<Pin::Base>]
@@ -106,14 +108,14 @@ module Solargraph
106
108
  # @param closure [Pin::Namespace]
107
109
  # @return [void]
108
110
  def convert_members_to_pins decl, closure
109
- context = Context.new
111
+ context = Conversions::Context.new
110
112
  decl.members.each { |m| context = convert_member_to_pin(m, closure, context) }
111
113
  end
112
114
 
113
115
  # @param member [RBS::AST::Members::Base,RBS::AST::Declarations::Base]
114
116
  # @param closure [Pin::Namespace]
115
117
  # @param context [Context]
116
- # @return [void]
118
+ # @return [Context]
117
119
  def convert_member_to_pin member, closure, context
118
120
  case member
119
121
  when RBS::AST::Members::MethodDefinition
@@ -295,6 +297,7 @@ module Solargraph
295
297
  name: name,
296
298
  closure: closure,
297
299
  comments: decl.comment&.string,
300
+ type_location: location_decl_to_pin_location(decl.location),
298
301
  source: :rbs
299
302
  )
300
303
  rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags
@@ -316,6 +319,7 @@ module Solargraph
316
319
  # related overrides
317
320
  # @todo externalize remaining overrides into yaml file, then
318
321
  # allow that to be extended via .solargraph.yml
322
+ # @type [Hash{Array(String, Symbol, String) => Symbol}
319
323
  VISIBILITY_OVERRIDE = {
320
324
  ["Rails::Engine", :instance, "run_tasks_blocks"] => :protected,
321
325
  # Should have been marked as both instance and class method in module -e.g., 'module_function'
@@ -340,6 +344,13 @@ module Solargraph
340
344
  ["Rainbow::Presenter", :instance, "wrap_with_sgr"] => :private,
341
345
  }
342
346
 
347
+ # @param decl [RBS::AST::Members::MethodDefinition, RBS::AST::Members::AttrReader, RBS::AST::Members::AttrAccessor]
348
+ # @param closure [Pin::Namespace]
349
+ # @param context [Context]
350
+ # @param scope [Symbol] :instance or :class
351
+ # @param name [String] The name of the method
352
+ # @sg-ignore
353
+ # @return [Symbol]
343
354
  def calculate_method_visibility(decl, context, closure, scope, name)
344
355
  override_key = [closure.path, scope, name]
345
356
  visibility = VISIBILITY_OVERRIDE[override_key]
@@ -414,15 +425,16 @@ module Solargraph
414
425
  # @return [void]
415
426
  def method_def_to_sigs decl, pin
416
427
  decl.overloads.map do |overload|
428
+ type_location = location_decl_to_pin_location(overload.method_type.location)
417
429
  generics = overload.method_type.type_params.map(&:name).map(&:to_s)
418
430
  signature_parameters, signature_return_type = parts_of_function(overload.method_type, pin)
419
431
  block = if overload.method_type.block
420
432
  block_parameters, block_return_type = parts_of_function(overload.method_type.block, pin)
421
- Pin::Signature.new(generics: generics, parameters: block_parameters, return_type: block_return_type,
422
- closure: pin, source: :rbs)
433
+ Pin::Signature.new(generics: generics, parameters: block_parameters, return_type: block_return_type, source: :rbs,
434
+ type_location: type_location, closure: pin)
423
435
  end
424
- Pin::Signature.new(generics: generics, parameters: signature_parameters, return_type: signature_return_type, block: block,
425
- closure: pin, source: :rbs)
436
+ Pin::Signature.new(generics: generics, parameters: signature_parameters, return_type: signature_return_type, block: block, source: :rbs,
437
+ type_location: type_location, closure: pin)
426
438
  end
427
439
  end
428
440
 
@@ -441,44 +453,52 @@ module Solargraph
441
453
  # @param pin [Pin::Method]
442
454
  # @return [Array(Array<Pin::Parameter>, ComplexType)]
443
455
  def parts_of_function type, pin
444
- return [[Solargraph::Pin::Parameter.new(decl: :restarg, name: 'arg', closure: pin, source: :rbs)], ComplexType.try_parse(method_type_to_tag(type)).force_rooted] if defined?(RBS::Types::UntypedFunction) && type.type.is_a?(RBS::Types::UntypedFunction)
456
+ type_location = pin.type_location
457
+ if defined?(RBS::Types::UntypedFunction) && type.type.is_a?(RBS::Types::UntypedFunction)
458
+ return [
459
+ [Solargraph::Pin::Parameter.new(decl: :restarg, name: 'arg', closure: pin, source: :rbs, type_location: type_location)],
460
+ ComplexType.try_parse(method_type_to_tag(type)).force_rooted
461
+ ]
462
+ end
445
463
 
446
464
  parameters = []
447
465
  arg_num = -1
448
466
  type.type.required_positionals.each do |param|
449
467
  name = param.name ? param.name.to_s : "arg_#{arg_num += 1}"
450
- parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin, return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted, source: :rbs)
468
+ parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin, return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted, source: :rbs, type_location: type_location)
451
469
  end
452
470
  type.type.optional_positionals.each do |param|
453
471
  name = param.name ? param.name.to_s : "arg_#{arg_num += 1}"
454
472
  parameters.push Solargraph::Pin::Parameter.new(decl: :optarg, name: name, closure: pin,
455
473
  return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted,
474
+ type_location: type_location,
456
475
  source: :rbs)
457
476
  end
458
477
  if type.type.rest_positionals
459
478
  name = type.type.rest_positionals.name ? type.type.rest_positionals.name.to_s : "arg_#{arg_num += 1}"
460
- parameters.push Solargraph::Pin::Parameter.new(decl: :restarg, name: name, closure: pin, source: :rbs)
479
+ parameters.push Solargraph::Pin::Parameter.new(decl: :restarg, name: name, closure: pin, source: :rbs, type_location: type_location)
461
480
  end
462
481
  type.type.trailing_positionals.each do |param|
463
482
  name = param.name ? param.name.to_s : "arg_#{arg_num += 1}"
464
- parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin, source: :rbs)
483
+ parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin, source: :rbs, type_location: type_location)
465
484
  end
466
485
  type.type.required_keywords.each do |orig, param|
467
486
  name = orig ? orig.to_s : "arg_#{arg_num += 1}"
468
487
  parameters.push Solargraph::Pin::Parameter.new(decl: :kwarg, name: name, closure: pin,
469
488
  return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted,
470
- source: :rbs)
489
+ source: :rbs, type_location: type_location)
471
490
  end
472
491
  type.type.optional_keywords.each do |orig, param|
473
492
  name = orig ? orig.to_s : "arg_#{arg_num += 1}"
474
493
  parameters.push Solargraph::Pin::Parameter.new(decl: :kwoptarg, name: name, closure: pin,
475
494
  return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted,
495
+ type_location: type_location,
476
496
  source: :rbs)
477
497
  end
478
498
  if type.type.rest_keywords
479
499
  name = type.type.rest_keywords.name ? type.type.rest_keywords.name.to_s : "arg_#{arg_num += 1}"
480
500
  parameters.push Solargraph::Pin::Parameter.new(decl: :kwrestarg, name: type.type.rest_keywords.name.to_s, closure: pin,
481
- source: :rbs)
501
+ source: :rbs, type_location: type_location)
482
502
  end
483
503
 
484
504
  rooted_tag = method_type_to_tag(type)
@@ -488,6 +508,7 @@ module Solargraph
488
508
 
489
509
  # @param decl [RBS::AST::Members::AttrReader,RBS::AST::Members::AttrAccessor]
490
510
  # @param closure [Pin::Namespace]
511
+ # @param context [Context]
491
512
  # @return [void]
492
513
  def attr_reader_to_pin(decl, closure, context)
493
514
  name = decl.name.to_s
@@ -511,14 +532,16 @@ module Solargraph
511
532
 
512
533
  # @param decl [RBS::AST::Members::AttrWriter, RBS::AST::Members::AttrAccessor]
513
534
  # @param closure [Pin::Namespace]
535
+ # @param context [Context]
514
536
  # @return [void]
515
537
  def attr_writer_to_pin(decl, closure, context)
516
538
  final_scope = decl.kind == :instance ? :instance : :class
517
539
  name = "#{decl.name.to_s}="
518
540
  visibility = calculate_method_visibility(decl, context, closure, final_scope, name)
541
+ type_location = location_decl_to_pin_location(decl.location)
519
542
  pin = Solargraph::Pin::Method.new(
520
543
  name: name,
521
- type_location: location_decl_to_pin_location(decl.location),
544
+ type_location: type_location,
522
545
  closure: closure,
523
546
  parameters: [],
524
547
  comments: decl.comment&.string,
@@ -532,7 +555,8 @@ module Solargraph
532
555
  name: 'value',
533
556
  return_type: ComplexType.try_parse(other_type_to_tag(decl.type)).force_rooted,
534
557
  source: :rbs,
535
- closure: pin
558
+ closure: pin,
559
+ type_location: type_location
536
560
  )
537
561
  rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags
538
562
  pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', rooted_tag))
@@ -541,6 +565,7 @@ module Solargraph
541
565
 
542
566
  # @param decl [RBS::AST::Members::AttrAccessor]
543
567
  # @param closure [Pin::Namespace]
568
+ # @param context [Context]
544
569
  # @return [void]
545
570
  def attr_accessor_to_pin(decl, closure, context)
546
571
  attr_reader_to_pin(decl, closure, context)
@@ -572,6 +597,7 @@ module Solargraph
572
597
  name: name,
573
598
  closure: closure,
574
599
  comments: decl.comment&.string,
600
+ type_location: location_decl_to_pin_location(decl.location),
575
601
  source: :rbs
576
602
  )
577
603
  rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags
@@ -588,6 +614,7 @@ module Solargraph
588
614
  name: name,
589
615
  closure: closure,
590
616
  comments: decl.comment&.string,
617
+ type_location: location_decl_to_pin_location(decl.location),
591
618
  source: :rbs
592
619
  )
593
620
  rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Solargraph
4
- VERSION = '0.56.1'
4
+ VERSION = '0.56.2'
5
5
  end
@@ -151,7 +151,7 @@ module Solargraph
151
151
  # @return [Hash{String => Array, Hash, Integer}]
152
152
  def default_config
153
153
  {
154
- 'include' => ['**/*.rb'],
154
+ 'include' => ['Rakefile', 'Gemfile', '*.gemspec', '**/*.rb'],
155
155
  'exclude' => ['spec/**/*', 'test/**/*', 'vendor/**/*', '.bundle/**/*'],
156
156
  'require' => [],
157
157
  'domains' => [],
@@ -7,10 +7,38 @@ module Solargraph
7
7
  # @param spec [Gem::Specification, nil]
8
8
  # @return [Solargraph::Location, nil]
9
9
  def object_location code_object, spec
10
- return nil if spec.nil? || code_object.nil? || code_object.file.nil? || code_object.line.nil?
10
+ if spec.nil? || code_object.nil? || code_object.file.nil? || code_object.line.nil?
11
+ if code_object.namespace.is_a?(YARD::CodeObjects::NamespaceObject)
12
+ # If the code object is a namespace, use the namespace's location
13
+ return object_location(code_object.namespace, spec)
14
+ end
15
+ return Solargraph::Location.new(__FILE__, Solargraph::Range.from_to(__LINE__ - 1, 0, __LINE__ - 1, 0))
16
+ end
11
17
  file = File.join(spec.full_gem_path, code_object.file)
12
18
  Solargraph::Location.new(file, Solargraph::Range.from_to(code_object.line - 1, 0, code_object.line - 1, 0))
13
19
  end
20
+
21
+ # @param code_object [YARD::CodeObjects::Base]
22
+ # @param spec [Gem::Specification, nil]
23
+ # @return [Solargraph::Pin::Namespace]
24
+ def create_closure_namespace_for(code_object, spec)
25
+ code_object_for_location = code_object
26
+ # code_object.namespace is sometimes a YARD proxy object pointing to a method path ("Object#new")
27
+ code_object_for_location = code_object.namespace if code_object.namespace.is_a?(YARD::CodeObjects::NamespaceObject)
28
+ namespace_location = object_location(code_object_for_location, spec)
29
+ ns_name = code_object.namespace.to_s
30
+ if ns_name.empty?
31
+ Solargraph::Pin::ROOT_PIN
32
+ else
33
+ Solargraph::Pin::Namespace.new(
34
+ name: ns_name,
35
+ closure: Pin::ROOT_PIN,
36
+ gates: [code_object.namespace.to_s],
37
+ source: :yardoc,
38
+ location: namespace_location
39
+ )
40
+ end
41
+ end
14
42
  end
15
43
  end
16
44
  end
@@ -7,12 +7,12 @@ module Solargraph
7
7
  extend YardMap::Helpers
8
8
 
9
9
  # @param code_object [YARD::CodeObjects::Base]
10
+ # @param closure [Pin::Closure, nil]
11
+ # @param spec [Gem::Specification, nil]
12
+ # @return [Pin::Constant]
10
13
  def self.make code_object, closure = nil, spec = nil
11
- closure ||= Solargraph::Pin::Namespace.new(
12
- name: code_object.namespace.to_s,
13
- gates: [code_object.namespace.to_s],
14
- source: :yardoc,
15
- )
14
+ closure ||= create_closure_namespace_for(code_object, spec)
15
+
16
16
  Pin::Constant.new(
17
17
  location: object_location(code_object, spec),
18
18
  closure: closure,
@@ -19,12 +19,7 @@ module Solargraph
19
19
  # @param spec [Gem::Specification, nil]
20
20
  # @return [Solargraph::Pin::Method]
21
21
  def self.make code_object, name = nil, scope = nil, visibility = nil, closure = nil, spec = nil
22
- closure ||= Solargraph::Pin::Namespace.new(
23
- name: code_object.namespace.to_s,
24
- gates: [code_object.namespace.to_s],
25
- type: code_object.namespace.is_a?(YARD::CodeObjects::ClassObject) ? :class : :module,
26
- source: :yardoc,
27
- )
22
+ closure ||= create_closure_namespace_for(code_object, spec)
28
23
  location = object_location(code_object, spec)
29
24
  name ||= code_object.name.to_s
30
25
  return_type = ComplexType::SELF if name == 'new'
@@ -7,15 +7,15 @@ module Solargraph
7
7
  extend YardMap::Helpers
8
8
 
9
9
  # @param code_object [YARD::CodeObjects::NamespaceObject]
10
+ # @param spec [Gem::Specification, nil]
11
+ # @param closure [Pin::Closure, nil]
12
+ # @return [Pin::Namespace]
10
13
  def self.make code_object, spec, closure = nil
11
- closure ||= Solargraph::Pin::Namespace.new(
12
- name: code_object.namespace.to_s,
13
- closure: Pin::ROOT_PIN,
14
- gates: [code_object.namespace.to_s],
15
- source: :yardoc,
16
- )
14
+ closure ||= create_closure_namespace_for(code_object, spec)
15
+ location = object_location(code_object, spec)
16
+
17
17
  Pin::Namespace.new(
18
- location: object_location(code_object, spec),
18
+ location: location,
19
19
  name: code_object.name.to_s,
20
20
  comments: code_object.docstring ? code_object.docstring.all.to_s : '',
21
21
  type: code_object.is_a?(YARD::CodeObjects::ClassObject) ? :class : :module,
data/lib/solargraph.rb CHANGED
@@ -65,6 +65,10 @@ module Solargraph
65
65
  end
66
66
  end
67
67
 
68
+ # @param type [Symbol] The type of assertion to perform.
69
+ # @param msg [String, nil] An optional message to log
70
+ # @param block [Proc] A block that returns a message to log
71
+ # @return [void]
68
72
  def self.assert_or_log(type, msg = nil, &block)
69
73
  raise (msg || block.call) if asserts_on?(type) && ![:combine_with_visibility].include?(type)
70
74
  logger.info msg, &block
@@ -79,6 +83,11 @@ module Solargraph
79
83
 
80
84
  # A helper method that runs Bundler.with_unbundled_env or falls back to
81
85
  # Bundler.with_clean_env for earlier versions of Bundler.
86
+ #
87
+ # @generic T
88
+ # @yieldreturn [generic<T>]
89
+ # @sg-ignore dynamic call, but both functions behave the same
90
+ # @return [generic<T>]
82
91
  def self.with_clean_env &block
83
92
  meth = if Bundler.respond_to?(:with_original_env)
84
93
  :with_original_env
@@ -88,3 +97,7 @@ module Solargraph
88
97
  Bundler.send meth, &block
89
98
  end
90
99
  end
100
+
101
+ # Ensure that ParserGem node processors are properly loaded to avoid conflicts
102
+ # with Convention node processors
103
+ require 'solargraph/parser/parser_gem/node_processors'
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solargraph
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.56.1
4
+ version: 0.56.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fred Snyder
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-07-13 00:00:00.000000000 Z
10
+ date: 2025-07-29 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: backport
@@ -419,6 +419,9 @@ files:
419
419
  - lib/solargraph/complex_type/unique_type.rb
420
420
  - lib/solargraph/convention.rb
421
421
  - lib/solargraph/convention/base.rb
422
+ - lib/solargraph/convention/data_definition.rb
423
+ - lib/solargraph/convention/data_definition/data_assignment_node.rb
424
+ - lib/solargraph/convention/data_definition/data_definition_node.rb
422
425
  - lib/solargraph/convention/gemfile.rb
423
426
  - lib/solargraph/convention/gemspec.rb
424
427
  - lib/solargraph/convention/rakefile.rb