From 6ad74b0500cc7d438a217213af5fd2bf6b152454 Mon Sep 17 00:00:00 2001 From: Will Hopper Date: Tue, 1 Nov 2016 10:52:33 -0700 Subject: [PATCH 1/3] (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. --- lib/puppet-strings/json.rb | 29 ++++++++++++------- .../yard/code_objects/function.rb | 16 ++++++++-- lib/puppet-strings/yard/tags/overload_tag.rb | 2 +- .../default/tags/html/puppet_overload.erb | 2 +- 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/lib/puppet-strings/json.rb b/lib/puppet-strings/json.rb index d6d2e42..ae433c1 100644 --- a/lib/puppet-strings/json.rb +++ b/lib/puppet-strings/json.rb @@ -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 diff --git a/lib/puppet-strings/yard/code_objects/function.rb b/lib/puppet-strings/yard/code_objects/function.rb index f295d29..4c2edf2 100644 --- a/lib/puppet-strings/yard/code_objects/function.rb +++ b/lib/puppet-strings/yard/code_objects/function.rb @@ -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? diff --git a/lib/puppet-strings/yard/tags/overload_tag.rb b/lib/puppet-strings/yard/tags/overload_tag.rb index e7557f7..9bbb684 100644 --- a/lib/puppet-strings/yard/tags/overload_tag.rb +++ b/lib/puppet-strings/yard/tags/overload_tag.rb @@ -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 diff --git a/lib/puppet-strings/yard/templates/default/tags/html/puppet_overload.erb b/lib/puppet-strings/yard/templates/default/tags/html/puppet_overload.erb index 3d12d59..93add67 100644 --- a/lib/puppet-strings/yard/templates/default/tags/html/puppet_overload.erb +++ b/lib/puppet-strings/yard/templates/default/tags/html/puppet_overload.erb @@ -1,5 +1,5 @@ <% if object.has_tag?(:overload) && object.tags(:overload).any? {|o| !o.docstring.blank? } %> -

Overloads:

+

Signatures: