diff --git a/lib/puppetx/yardoc/yard/handlers.rb b/lib/puppetx/yardoc/yard/handlers.rb index 0870f17..71a966b 100644 --- a/lib/puppetx/yardoc/yard/handlers.rb +++ b/lib/puppetx/yardoc/yard/handlers.rb @@ -1,4 +1,6 @@ require_relative 'handlers/base' require_relative 'handlers/defined_type_handler' require_relative 'handlers/host_class_handler' + require_relative 'handlers/parser_function_handler' +require_relative 'handlers/future_parser_function_handler' diff --git a/lib/puppetx/yardoc/yard/handlers/future_parser_function_handler.rb b/lib/puppetx/yardoc/yard/handlers/future_parser_function_handler.rb new file mode 100644 index 0000000..6824bd3 --- /dev/null +++ b/lib/puppetx/yardoc/yard/handlers/future_parser_function_handler.rb @@ -0,0 +1,103 @@ +require_relative '../code_objects' + +module Puppetx::Yardoc::YARD::Handlers + class FutureParserFunctionHandler < YARD::Handlers::Ruby::Base + include Puppetx::Yardoc::YARD::CodeObjects + + handles method_call(:create_function) + + process do + name = process_parameters + + obj = MethodObject.new(function_namespace, name) + + register obj + + obj.add_tag YARD::Tags::Tag.new(:api, 'public') + end + + private + + # Returns a {PuppetNamespaceObject} for holding functions. Creates this + # object if necessary. + # + # @return [PuppetNamespaceObject] + def function_namespace + # NOTE: This tricky. If there is ever a Ruby class or module with the + # name ::ParserFunctions, then there will be a clash. Hopefully the name + # is sufficiently uncommon. + obj = P(:root, 'FutureParserFunctions') + if obj.is_a? Proxy + namespace_obj = PuppetNamespaceObject.new(:root, 'FutureParserFunctions') + + register namespace_obj + register_docstring(namespace_obj, '', nil) + namespace_obj.add_tag YARD::Tags::Tag.new(:api, 'public') + end + + obj + end + + # 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 + # Passing `false` to prameters excludes the block param from the returned + # list. + name, _ = statement.parameters(false).compact + + name = process_element(name) + + name + end + + # Sometimes the YARD parser returns Heredoc strings that start with `<-` + # instead of `<<-`. + HEREDOC_START = /^<-/ + + # 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, :string_content) + + case ele.type + when :ident + ele.source + when :string_content + source = ele.source + if HEREDOC_START.match(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 +end diff --git a/lib/puppetx/yardoc/yard/templates/default/fulldoc/html/full_list_puppet_plugin.erb b/lib/puppetx/yardoc/yard/templates/default/fulldoc/html/full_list_puppet_plugin.erb index a8692c9..ffa7eec 100644 --- a/lib/puppetx/yardoc/yard/templates/default/fulldoc/html/full_list_puppet_plugin.erb +++ b/lib/puppetx/yardoc/yard/templates/default/fulldoc/html/full_list_puppet_plugin.erb @@ -8,3 +8,14 @@ <%= namespace_list(:root => P(:root,'ParserFunctions'), :namespace_types => [:puppetnamespace, :method]) %> <% end %> + +<% unless P(:root, 'FutureParserFunctions').is_a?(CodeObjects::Proxy) %> +