Skip to content

Commit 8e22db8

Browse files
authored
Merge branch 'master' into 2025-07-02
2 parents b863262 + dcb8252 commit 8e22db8

21 files changed

Lines changed: 641 additions & 82 deletions

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 0.56.1 - July 13, 2025
2+
- Library avoids blocking on pending yardoc caches (#990)
3+
- DocMap checks for default Gemfile (#989)
4+
- [Bug fix] Fixed an error in rbs/fills/tuple.rbs (#993)
5+
16
## 0.56.0 - July 1, 2025
27
- [regression] Gem caching perf and logging fixes #983
38

lib/solargraph/convention.rb

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ module Solargraph
66
# one of its sources.
77
#
88
module Convention
9-
autoload :Base, 'solargraph/convention/base'
10-
autoload :Gemfile, 'solargraph/convention/gemfile'
11-
autoload :Gemspec, 'solargraph/convention/gemspec'
12-
autoload :Rakefile, 'solargraph/convention/rakefile'
13-
autoload :StructDefinition, 'solargraph/convention/struct_definition'
9+
autoload :Base, 'solargraph/convention/base'
10+
autoload :Gemfile, 'solargraph/convention/gemfile'
11+
autoload :Gemspec, 'solargraph/convention/gemspec'
12+
autoload :Rakefile, 'solargraph/convention/rakefile'
13+
autoload :StructDefinition, 'solargraph/convention/struct_definition'
14+
autoload :DataDefinition, 'solargraph/convention/data_definition'
1415
autoload :ActiveSupportConcern, 'solargraph/convention/active_support_concern'
1516

1617
# @type [Set<Convention::Base>]
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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 commit comments

Comments
 (0)