class PuppetStrings::Yard::Handlers::Ruby::FunctionHandler
Implements the handler for Puppet functions written in Ruby.
Constants
- DISPATCH_METHOD_NAMES
Represents the list of Puppet 4.x function API methods to support.
Private Instance Methods
add_method_overload(object, node)
click to toggle source
# File lib/puppet-strings/yard/handlers/ruby/function_handler.rb, line 206 def add_method_overload(object, node) overload_tag = PuppetStrings::Yard::Tags::OverloadTag.new(object.name, node.docstring || '') param_tags = overload_tag.tags(:param) parameters = node.parameters # Populate the required parameters params = parameters.unnamed_required_params if params params.each do |parameter| add_param_tag( overload_tag, param_tags, parameter.source, parameter.file, parameter.line ) end end # Populate the optional parameters params = parameters.unnamed_optional_params if params params.each do |parameter| add_param_tag( overload_tag, param_tags, parameter[0].source, parameter.file, parameter.line, nil, parameter[1].source, true ) end end # Populate the splat parameter param = parameters.splat_param if param add_param_tag( overload_tag, param_tags, param.source, param.file, param.line, nil, nil, false, true ) end # Populate the block parameter param = parameters.block_param if param add_param_tag( overload_tag, param_tags, param.source, param.file, param.line, nil, nil, false, false, true ) end # Add a return tag if missing add_return_tag(overload_tag, node.file, node.line) # Validate that tags have parameters validate_overload(overload_tag, node.file, node.line) object.add_tag overload_tag end
add_overload_tag(object, node)
click to toggle source
# File lib/puppet-strings/yard/handlers/ruby/function_handler.rb, line 114 def add_overload_tag(object, node) # Look for a call to a dispatch method with a block return unless node.is_a?(YARD::Parser::Ruby::MethodCallNode) && node.method_name && node.method_name.source == 'dispatch' && node.parameters(false).count == 1 && node.block && node.block.count >= 2 overload_tag = PuppetStrings::Yard::Tags::OverloadTag.new(object.name, node.docstring || '') param_tags = overload_tag.tags(:param) block = nil node.block[1].children.each do |child| next unless child.is_a?(YARD::Parser::Ruby::MethodCallNode) && child.method_name method_name = child.method_name.source next unless DISPATCH_METHOD_NAMES.include?(method_name) # Check for block if method_name.include?('block') if block log.warn "A duplicate block parameter was found for Puppet function '#{object.name}' at #{child.file}:#{child.line}." next end # Store the block; needs to be appended last block = child next end # Ensure two parameters to parameter definition parameters = child.parameters(false) unless parameters.count == 2 log.warn "Expected 2 arguments to '#{method_name}' call at #{child.file}:#{child.line}: parameter information may not be correct." next end add_param_tag( overload_tag, param_tags, node_as_string(parameters[1]), child.file, child.line, node_as_string(parameters[0]), nil, # TODO: determine default from corresponding Ruby method signature? method_name.include?('optional'), method_name.include?('repeated') ) end # Handle the block parameter after others so it appears last in the list if block parameters = block.parameters(false) if parameters.empty? name = 'block' type = 'Callable' elsif parameters.count == 1 name = node_as_string(parameters[0]) type = 'Callable' elsif parameters.count == 2 type = node_as_string(parameters[0]) name = node_as_string(parameters[1]) else log.warn "Unexpected number of arguments to block definition at #{block.file}:#{block.line}." end if name && type add_param_tag( overload_tag, param_tags, name, block.file, block.line, type, nil, # TODO: determine default from corresponding Ruby method signature? block.method_name.source.include?('optional'), false, # Not repeated true # Is block ) end end # Add a return tag if missing add_return_tag(overload_tag, node.file, node.line) # Validate that tags have parameters validate_overload(overload_tag, node.file, node.line) object.add_tag overload_tag end
add_param_tag(object, tags, name, file, line, type = nil, default = nil, optional = false, repeated = false, block = false)
click to toggle source
# File lib/puppet-strings/yard/handlers/ruby/function_handler.rb, line 285 def add_param_tag(object, tags, name, file, line, type = nil, default = nil, optional = false, repeated = false, block = false) tag = tags.find { |tag| tag.name == name } if tags log.warn "Missing @param tag for parameter '#{name}' near #{file}:#{line}." unless tag || object.docstring.all.empty? log.warn "The @param tag for parameter '#{name}' should not contain a type specification near #{file}:#{line}: ignoring in favor of dispatch type information." if type && tag && tag.types && !tag.types.empty? if repeated name = '*' + name elsif block name = '&' + name end unless type type = tag && tag.types ? tag.type : 'Any' end type = optional ? "Optional[#{type}]" : type object.parameters << [name, to_puppet_literal(default)] if tag tag.name = name tag.types = [type] else object.add_tag YARD::Tags::Tag.new(:param, '', type, name) end end
add_return_tag(object, file, line)
click to toggle source
# File lib/puppet-strings/yard/handlers/ruby/function_handler.rb, line 311 def add_return_tag(object, file, line) tag = object.tag(:return) if tag tag.types = ['Any'] unless tag.types return end log.warn "Missing @return tag near #{file}:#{line}." object.add_tag YARD::Tags::Tag.new(:return, '', 'Any') end
get_3x_docstring(name)
click to toggle source
# File lib/puppet-strings/yard/handlers/ruby/function_handler.rb, line 329 def get_3x_docstring(name) parameters = statement.parameters(false) if parameters.count >= 2 parameters[1].each do |kvp| next unless kvp.count == 2 next unless node_as_string(kvp[0]) == 'doc' docstring = node_as_string(kvp[1]) log.error "Failed to parse docstring for 3.x Puppet function '#{name}' near #{statement.file}:#{statement.line}." and return nil unless docstring return Puppet::Util::Docs.scrub(docstring) end end # Log a warning for missing docstring log.warn "Missing documentation for Puppet function '#{name}' at #{statement.file}:#{statement.line}." nil end
get_name()
click to toggle source
# File lib/puppet-strings/yard/handlers/ruby/function_handler.rb, line 63 def get_name parameters = statement.parameters(false) raise YARD::Parser::UndocumentableError, "Expected at least one parameter to Puppet::Functions.create_function at #{statement.file}:#{statement.line}." if parameters.empty? name = node_as_string(parameters.first) raise YARD::Parser::UndocumentableError, "Expected a symbol or string literal for first parameter but found '#{parameters.first.type}' at #{statement.file}:#{statement.line}." unless name name end
to_puppet_literal(literal)
click to toggle source
# File lib/puppet-strings/yard/handlers/ruby/function_handler.rb, line 347 def to_puppet_literal(literal) case literal when 'nil' 'undef' when ':default' 'default' else literal end end
validate_overload(overload, file, line)
click to toggle source
# File lib/puppet-strings/yard/handlers/ruby/function_handler.rb, line 321 def validate_overload(overload, file, line) # Validate that tags have matching parameters overload.tags(:param).each do |tag| next if overload.parameters.find { |p| tag.name == p[0] } log.warn "The @param tag for parameter '#{tag.name}' has no matching parameter at #{file}:#{line}." end end