(PDOC-125) Display all puppet function signatures in top-level signature array

This commit adds a new top-level key to the JSON schema for Ruby 3x/4x
puppet functions: `signatures`. This key is an array and is constructed entirely
with data from existing elements of the puppet function object. The data
structure itself remains unchanged, as this commit only affects the final
JSON output for functions.

In the case of a puppet 4x function with multiple dispatches (overloads),
the signatures key is populated with the equivalent of an overload tag
for each which includes the signature and any param or return tags for
the dispatch.

In the case of a puppet function with only one dispatch, the array is
simply populated with a single element containing a lone dispatch
and its param and return tags.

Note that this change does not affect the internal structure or
representation of puppet function objects, but rather only affects
its final display form when serialized into JSON. All prior data
has been left intact, and the only change here is the addition
of the `signatures` member to the JSON output.
This commit is contained in:
Will Hopper 2016-11-01 10:52:33 -07:00
parent 70d5b1ccd7
commit 6ad74b0500
4 changed files with 34 additions and 15 deletions

View File

@ -25,23 +25,32 @@ module PuppetStrings::Json
end
end
# Converts a list of tags into an array of hashes.
# @param [Array] tags List of tags to be converted into an array of hashes.
# @return [Array] Returns an array of tag hashes.
def self.tags_to_hashes(tags)
# Skip over the API tags that are public
tags.select { |t| (t.tag_name != 'api' || t.text != 'public') }.map do |t|
next t.to_hash if t.respond_to?(:to_hash)
tag = { tag_name: t.tag_name }
tag[:text] = t.text if t.text
tag[:types] = t.types if t.types
tag[:name] = t.name if t.name
tag
end
end
# Converts a YARD::Docstring (or String) to a docstring hash for JSON output.
# @param [YARD::Docstring, String] docstring The docstring to convert to a hash.
# @param [Array] select_tags List of tags to select. Other tags will be filtered out.
# @return [Hash] Returns a hash representation of the given docstring.
def self.docstring_to_hash(docstring)
def self.docstring_to_hash(docstring, select_tags=nil)
hash = {}
hash[:text] = docstring
if docstring.is_a? YARD::Docstring
# Skip over the API tags that are public
tags = docstring.tags.select { |t| t.tag_name != 'api' || t.text != 'public' }.map do |t|
next t.to_hash if t.respond_to?(:to_hash)
tags = tags_to_hashes(docstring.tags.select { |t| select_tags.nil? || select_tags.include?(t.tag_name.to_sym) })
tag = { tag_name: t.tag_name }
tag[:text] = t.text if t.text
tag[:types] = t.types if t.types
tag[:name] = t.name if t.name
tag
end
hash[:tags] = tags unless tags.empty?
end
hash

View File

@ -64,7 +64,7 @@ class PuppetStrings::Yard::CodeObjects::Function < PuppetStrings::Yard::CodeObje
tags = self.tags(:param)
args = @parameters.map do |parameter|
name, default = parameter
tag = tags.find { |tag| tag.name == name } if tags
tag = tags.find { |t| t.name == name } if tags
type = tag && tag.types ? "#{tag.type} " : 'Any '
prefix = "#{name[0]}" if name.start_with?('*', '&')
name = name[1..-1] if prefix
@ -78,12 +78,22 @@ class PuppetStrings::Yard::CodeObjects::Function < PuppetStrings::Yard::CodeObje
# @return [Hash] Returns a hash representation of the code object.
def to_hash
hash = {}
hash[:name] = name
hash[:file] = file
hash[:line] = line
hash[:type] = @function_type.to_s
signature = self.signature
hash[:signature] = signature unless signature.empty?
hash[:signatures] = []
if self.has_tag? :overload
# loop over overloads and append onto the signatures array
self.tags(:overload).each do |o|
hash[:signatures] << { :signature => o.signature, :docstring => PuppetStrings::Json.docstring_to_hash(o.docstring, [:param, :return]) }
end
else
hash[:signatures] << { :signature => self.signature, :docstring => PuppetStrings::Json.docstring_to_hash(docstring, [:param, :return]) }
end
hash[:docstring] = PuppetStrings::Json.docstring_to_hash(docstring)
defaults = Hash[*parameters.select{ |p| !p[1].nil? }.flatten]
hash[:defaults] = defaults unless defaults.empty?

View File

@ -21,7 +21,7 @@ class PuppetStrings::Yard::Tags::OverloadTag < YARD::Tags::Tag
tags = self.tags(:param)
args = @parameters.map do |parameter|
name, default = parameter
tag = tags.find { |tag| tag.name == name } if tags
tag = tags.find { |t| t.name == name } if tags
type = tag && tag.types ? "#{tag.type} " : 'Any '
prefix = "#{name[0]}" if name.start_with?('*', '&')
name = name[1..-1] if prefix

View File

@ -1,5 +1,5 @@
<% if object.has_tag?(:overload) && object.tags(:overload).any? {|o| !o.docstring.blank? } %>
<p class="tag_title">Overloads:</p>
<p class="tag_title">Signatures:</p>
<ul class="overload">
<% object.tags(:overload).each_with_index do |overload, index| %>
<% next if overload.docstring.blank? %>