Skip to content

Commit 4f331e3

Browse files
authored
Support nested structs of the form A::B = Struct.new(...) (#1599)
# Description On my codebase, yard fails when it happens to meet `Struct.new` assigned to a nested constant e.g. this code: ```ruby A::B = Struct.new(:a, :b, :c) ``` fails with the following error: ``` [warn]: in YARD::Handlers::Ruby::ConstantHandler: Undocumentable Struct assignment to A::B ``` # Completed Tasks - [x] I have read the [Contributing Guide][contrib]. - [x] The pull request is complete (implemented / written). - [x] Git commits have been cleaned up (squash WIP / revert commits). - [x] I wrote tests and ran `bundle exec rake` locally (if code is attached to PR). [contrib]: https://github.com/lsegal/yard/blob/main/CONTRIBUTING.md
2 parents 3cef453 + d8723f2 commit 4f331e3

File tree

3 files changed

+17
-4
lines changed

3 files changed

+17
-4
lines changed

lib/yard/handlers/ruby/constant_handler.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@ def process_constant(statement)
3434
end
3535

3636
def process_structclass(statement)
37-
lhs = statement[0][0]
38-
if lhs.type == :const
39-
klass = create_class(lhs[0], P(:Struct))
37+
lhs = statement[0]
38+
if (lhs.type == :var_field && lhs[0].type == :const) || lhs.type == :const_path_field
39+
klass = create_class(lhs.source, P(:Struct))
4040
create_attributes(klass, extract_parameters(statement[1]))
4141
parse_block(statement[1].block[1], :namespace => klass) unless statement[1].block.nil?
4242
else
43-
raise YARD::Parser::UndocumentableError, "Struct assignment to #{statement[0].source}"
43+
raise YARD::Parser::UndocumentableError, "Struct assignment to #{lhs.source}"
4444
end
4545
end
4646

spec/handlers/constant_handler_spec.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,18 @@
5757
expect(obj.attributes[:instance]).to be_empty
5858
end
5959

60+
it "turns A::Const = Struct.new(:sym) into class A::Const with attr :sym" do
61+
obj = Registry.at("A::NestedCompactStruct")
62+
expect(obj).to be_kind_of(CodeObjects::ClassObject)
63+
expect(obj.superclass).to eq P(:Struct)
64+
attrs = obj.attributes[:instance]
65+
[:b, :c].each do |key|
66+
expect(attrs).to have_key(key)
67+
expect(attrs[key][:read]).not_to be nil
68+
expect(attrs[key][:write]).not_to be nil
69+
end
70+
end
71+
6072
it "maintains docstrings on structs defined via constants" do
6173
obj = Registry.at("DocstringStruct")
6274
expect(obj).not_to be nil

spec/handlers/examples/constant_handler_001.rb.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ end
1717
MyClass = Struct.new(:a, :b, :c)
1818
NotMyClass = Struct.new("NotMyClass2", :b, :c)
1919
MyEmptyStruct = Struct.new
20+
A::NestedCompactStruct = Struct.new(:b, :c)
2021

2122
MyStructWithConstant = Struct.new do
2223
# A constant.

0 commit comments

Comments
 (0)