class HereDocHelper # NOTE: The following methods duplicate functionality from # Puppet::Util::Reference and Puppet::Parser::Functions.functiondocs # # However, implementing this natively in YARD is a good test for the # feasibility of extracting custom Ruby documentation. In the end, the # existing approach taken by Puppet::Util::Reference may be the best due to # the heavy use of metaprogramming in Types and Providers. # Extracts the Puppet function name and options hash from the parsed # definition. # # @return [(String, Hash{String => String})] def process_parameters(statement) # Passing `false` to prameters excludes the block param from the returned # list. name, opts = statement.parameters(false).compact name = process_element(name) # Don't try to process options if we don't have any if !opts.nil? opts = opts.map do |tuple| # Jump down into the S-Expression that represents a hashrocket, `=>`, # and the values on either side of it. tuple.jump(:assoc).map{|e| process_element(e)} end options = Hash[opts] else options = {} end [name, options] end # Sometimes the YARD parser returns Heredoc strings that start with `<-` # instead of `<<-`. HEREDOC_START = /^<?<-/ def is_heredoc?(str) HEREDOC_START.match(str) end # Turns an entry in the method parameter list into a string. # # @param ele [YARD::Parser::Ruby::AstNode] # @return [String] def process_element(ele) ele = ele.jump(:ident, :symbol, :string_content) case ele.type when :ident ele.source when :symbol ele.source[1..-1] when :string_content source = ele.source if is_heredoc? source process_heredoc(source) else source end end end # Cleans up and formats Heredoc contents parsed by YARD. # # @param source [String] # @return [String] def process_heredoc(source) source = source.lines.to_a # YARD adds a line of source context on either side of the Heredoc # contents. source.shift source.pop # This utility method normalizes indentation and trims whitespace. Puppet::Util::Docs.scrub(source.join) end end