Skip to content

Commit

Permalink
Preserve existing T::Struct initialize tags
Browse files Browse the repository at this point in the history
  • Loading branch information
dduugg committed Jul 20, 2021
1 parent 3480c2a commit 09fcb6e
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 14 deletions.
6 changes: 3 additions & 3 deletions lib/yard-sorbet/handlers/struct_class_handler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ def process_t_struct_props(props, class_ns)
# There is a chance that there is a custom initializer, so make sure we steal the existing docstring
# and source
docstring, directives = Directives.extract_directives(object.docstring)
# These should probably check for existing tags, and merge with any existing documentation:
object.tags.each { |tag| docstring.add_tag(tag) }
props.each do |prop|
docstring.add_tag(YARD::Tags::Tag.new(:param, prop.doc, prop.types, prop.prop_name))
TagUtils.upsert_tag(docstring, 'param', prop.types, prop.prop_name, prop.doc)
end
docstring.add_tag(YARD::Tags::Tag.new(:return, '', 'void'))
TagUtils.upsert_tag(docstring, 'return', ['void'])
decorate_t_struct_init(object, props, docstring, directives)
end

Expand Down
25 changes: 14 additions & 11 deletions lib/yard-sorbet/tag_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,26 @@ module YARDSorbet
module TagUtils
extend T::Sig

# @return the tag with the matching `tag_name` and `name`, or `nil`
sig do
params(docstring: YARD::Docstring, tag_name: String, name: T.nilable(String))
.returns(T.nilable(YARD::Tags::Tag))
end
def self.find_tag(docstring, tag_name, name)
docstring.tags.find { |t| t.tag_name == tag_name && t.name == name }
end

# Create or update a `YARD` tag with type information
sig do
params(
docstring: YARD::Docstring,
tag_name: String,
types: T.nilable(T::Array[String]),
name: T.nilable(String)
name: T.nilable(String),
text: String
).void
end
def self.upsert_tag(docstring, tag_name, types = nil, name = nil)
def self.upsert_tag(docstring, tag_name, types = nil, name = nil, text = '')
tag = find_tag(docstring, tag_name, name)
if tag
return unless types
Expand All @@ -24,18 +34,11 @@ def self.upsert_tag(docstring, tag_name, types = nil, name = nil)
docstring.delete_tag_if { |t| t == tag }
# overwrite any existing type annotation (sigs should win)
tag.types = types
tag.text = text unless text.empty?
else
tag = YARD::Tags::Tag.new(tag_name, '', types, name)
tag = YARD::Tags::Tag.new(tag_name, text, types, name)
end
docstring.add_tag(tag)
end

sig do
params(docstring: YARD::Docstring, tag_name: String, name: T.nilable(String))
.returns(T.nilable(YARD::Tags::Tag))
end
def self.find_tag(docstring, tag_name, name)
docstring.tags.find { |t| t.tag_name == tag_name && t.name == name }
end
end
end
2 changes: 2 additions & 0 deletions spec/data/struct_handler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class SpecializedPersonStruct < T::Struct
const :special, String

# This is a special intializer
# @param special a very special param
# @return an initialized struct
def initialize(special:)
raise ArgumentError.new("bad human") if special != "special"
super
Expand Down
27 changes: 27 additions & 0 deletions spec/yard_sorbet/handlers/struct_class_handler_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,33 @@
expect(node.docstring).to eq('This is a special intializer')
end

it 'preserves param tag text' do
node = YARD::Registry.at('SpecializedPersonStruct#initialize')
tag = YARDSorbet::TagUtils.find_tag(node.docstring, 'param', 'special')
expect(tag&.text).to eq('a very special param')
end

it 'adds param type to param tag' do
node = YARD::Registry.at('SpecializedPersonStruct#initialize')
tag = YARDSorbet::TagUtils.find_tag(node.docstring, 'param', 'special')
expect(tag&.types).to eq(['String'])
end

it 'preserves return tag text' do
node = YARD::Registry.at('SpecializedPersonStruct#initialize')
expect(node.tag(:return).text).to eq('an initialized struct')
end

it 'adds return type to return tag' do
node = YARD::Registry.at('SpecializedPersonStruct#initialize')
expect(node.tag(:return).types).to eq(['void'])
end

it 'adds raise tag' do
node = YARD::Registry.at('SpecializedPersonStruct#initialize')
expect(node.tag(:raise).types).to eq(['ArgumentError'])
end

it 'handles keyword node prop names' do
node = YARD::Registry.at('ExceptionalPersonStruct#initialize')
tag = YARDSorbet::TagUtils.find_tag(node.docstring, 'param', 'end')
Expand Down

0 comments on commit 09fcb6e

Please sign in to comment.