(PDOC-3) Switch to one line class declarations
Prior to this commit, many of the classes in this project were declared in two lines. The first line would put them in the context of the module they belonged to, and the second line would declare the class and deal with inheritance. In order to make the code more readable and to allow require statements to be moved to the top level, turn all class declarations into one line statements.
This commit is contained in:
parent
df648a246f
commit
f0da72b2b7
|
@ -1,5 +1,4 @@
|
|||
require 'puppet/face'
|
||||
require 'puppetx/puppetlabs/strings/actions'
|
||||
|
||||
Puppet::Face.define(:strings, '0.0.1') do
|
||||
summary "Generate Puppet documentation with YARD."
|
||||
|
@ -34,6 +33,7 @@ Puppet::Face.define(:strings, '0.0.1') do
|
|||
|
||||
when_invoked do |*args|
|
||||
check_required_features
|
||||
require 'puppetx/puppetlabs/strings/actions'
|
||||
|
||||
yardoc_actions = Puppetx::PuppetLabs::Strings::Actions.new(Puppet[:debug], Puppet[:trace])
|
||||
|
||||
|
@ -63,6 +63,7 @@ Puppet::Face.define(:strings, '0.0.1') do
|
|||
|
||||
when_invoked do |*args|
|
||||
check_required_features
|
||||
require 'puppetx/puppetlabs/strings/actions'
|
||||
|
||||
server_actions = Puppetx::PuppetLabs::Strings::Actions.new(Puppet[:debug], Puppet[:trace])
|
||||
|
||||
|
|
|
@ -6,6 +6,11 @@ module Puppetx::PuppetLabs
|
|||
|
||||
# This submodule contains bits that interface with the YARD plugin system.
|
||||
module YARD
|
||||
module Handlers
|
||||
end
|
||||
|
||||
module CodeObjects
|
||||
end
|
||||
end
|
||||
|
||||
# This submodule contains bits that operate on the Pops module produced by
|
||||
|
|
|
@ -3,76 +3,73 @@ require 'puppet/pops'
|
|||
|
||||
require 'puppetx/puppetlabs/strings'
|
||||
|
||||
module Puppetx::PuppetLabs::Strings::Pops
|
||||
# An adapter class that conforms a Pops model instance + adapters to the
|
||||
# interface expected by YARD handlers.
|
||||
#
|
||||
# FIXME: Inhertiting from OpenStruct is a bit of a hack. It allows attributes
|
||||
# to be declared as needed but in the long run understandibility of the code
|
||||
# would be improved by having a concrete model.
|
||||
class YARDStatement < OpenStruct
|
||||
attr_reader :pops_obj, :comments
|
||||
# An adapter class that conforms a Pops model instance + adapters to the
|
||||
# interface expected by YARD handlers.
|
||||
#
|
||||
# FIXME: Inhertiting from OpenStruct is a bit of a hack. It allows attributes
|
||||
# to be declared as needed but in the long run understandibility of the code
|
||||
# would be improved by having a concrete model.
|
||||
class Puppetx::PuppetLabs::Strings::Pops::YARDStatement < OpenStruct
|
||||
attr_reader :pops_obj, :comments
|
||||
|
||||
def initialize(pops_obj)
|
||||
# Initialize OpenStruct
|
||||
super({})
|
||||
def initialize(pops_obj)
|
||||
# Initialize OpenStruct
|
||||
super({})
|
||||
|
||||
unless pops_obj.is_a? Puppet::Pops::Model::PopsObject
|
||||
raise ArgumentError, "A YARDStatement can only be initialized from a PopsObject. Got a: #{pops_obj.class}"
|
||||
unless pops_obj.is_a? Puppet::Pops::Model::PopsObject
|
||||
raise ArgumentError, "A YARDStatement can only be initialized from a PopsObject. Got a: #{pops_obj.class}"
|
||||
end
|
||||
|
||||
@pops_obj = pops_obj
|
||||
@pos_adapter = Puppet::Pops::Adapters::SourcePosAdapter.adapt(@pops_obj)
|
||||
# FIXME: Perhaps this should be a seperate adapter?
|
||||
@comments = extract_comments
|
||||
end
|
||||
|
||||
def type
|
||||
pops_obj.class
|
||||
end
|
||||
|
||||
def line
|
||||
@line ||= @pos_adapter.line
|
||||
end
|
||||
|
||||
def source
|
||||
@source ||= @pos_adapter.extract_text
|
||||
end
|
||||
|
||||
# FIXME: I don't know quite what these are supposed to do, but they show up
|
||||
# quite often in the YARD handler code. Figure out whether they are
|
||||
# necessary.
|
||||
alias_method :show, :source
|
||||
def comments_hash_flag; nil end
|
||||
def comments_range; nil end
|
||||
|
||||
private
|
||||
# TODO: This stuff should probably be part of a separate class/adapter.
|
||||
COMMENT_PATTERN = /^\s*#.*\n/
|
||||
|
||||
def extract_comments
|
||||
comments = []
|
||||
program = pops_obj.eAllContainers.find {|c| c.is_a?(Puppet::Pops::Model::Program) }
|
||||
# FIXME: Horribly inefficient. Multiple copies. Generator pattern would
|
||||
# be much better.
|
||||
source_text = program.source_text.lines.to_a
|
||||
|
||||
source_text.slice(0, line-1).reverse.each do |line|
|
||||
if COMMENT_PATTERN.match(line)
|
||||
# FIXME: The gsub trims comments, but is extremely optimistic: It
|
||||
# assumes only one space separates the comment body from the
|
||||
# comment character.
|
||||
comments.unshift line.gsub(/^\s*#\s/, '')
|
||||
else
|
||||
# No comment found on this line. We must be done piecing together a
|
||||
# comment block.
|
||||
break
|
||||
end
|
||||
|
||||
@pops_obj = pops_obj
|
||||
@pos_adapter = Puppet::Pops::Adapters::SourcePosAdapter.adapt(@pops_obj)
|
||||
# FIXME: Perhaps this should be a seperate adapter?
|
||||
@comments = extract_comments
|
||||
end
|
||||
|
||||
def type
|
||||
pops_obj.class
|
||||
end
|
||||
|
||||
def line
|
||||
@line ||= @pos_adapter.line
|
||||
end
|
||||
|
||||
def source
|
||||
@source ||= @pos_adapter.extract_text
|
||||
end
|
||||
|
||||
# FIXME: I don't know quite what these are supposed to do, but they show up
|
||||
# quite often in the YARD handler code. Figure out whether they are
|
||||
# necessary.
|
||||
alias_method :show, :source
|
||||
def comments_hash_flag; nil end
|
||||
def comments_range; nil end
|
||||
|
||||
private
|
||||
# TODO: This stuff should probably be part of a separate class/adapter.
|
||||
COMMENT_PATTERN = /^\s*#.*\n/
|
||||
|
||||
def extract_comments
|
||||
comments = []
|
||||
program = pops_obj.eAllContainers.find {|c| c.is_a?(Puppet::Pops::Model::Program) }
|
||||
# FIXME: Horribly inefficient. Multiple copies. Generator pattern would
|
||||
# be much better.
|
||||
source_text = program.source_text.lines.to_a
|
||||
|
||||
source_text.slice(0, line-1).reverse.each do |line|
|
||||
if COMMENT_PATTERN.match(line)
|
||||
# FIXME: The gsub trims comments, but is extremely optimistic: It
|
||||
# assumes only one space separates the comment body from the
|
||||
# comment character.
|
||||
comments.unshift line.gsub(/^\s*#\s/, '')
|
||||
else
|
||||
# No comment found on this line. We must be done piecing together a
|
||||
# comment block.
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
# Stick everything back together.
|
||||
comments.join
|
||||
end
|
||||
|
||||
# Stick everything back together.
|
||||
comments.join
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,52 +2,50 @@ require 'puppet/pops'
|
|||
require 'puppetx/puppetlabs/strings'
|
||||
require 'puppetx/puppetlabs/strings/pops/yard_statement'
|
||||
|
||||
module Puppetx::PuppetLabs::Strings::Pops
|
||||
# Loosely based on the TreeDumper classes in Pops::Model. The responsibility of
|
||||
# this class is to walk a Pops::Model and output objects that can be consumed
|
||||
# by YARD handlers.
|
||||
#
|
||||
# @note Currently, this class only extracts node, host class and type
|
||||
# definitions.
|
||||
class YARDTransformer
|
||||
def initialize
|
||||
@transform_visitor = Puppet::Pops::Visitor.new(self, 'transform')
|
||||
# Loosely based on the TreeDumper classes in Pops::Model. The responsibility of
|
||||
# this class is to walk a Pops::Model and output objects that can be consumed
|
||||
# by YARD handlers.
|
||||
#
|
||||
# @note Currently, this class only extracts node, host class and type
|
||||
# definitions.
|
||||
class Puppetx::PuppetLabs::Strings::Pops::YARDTransformer
|
||||
def initialize
|
||||
@transform_visitor = Puppet::Pops::Visitor.new(self, 'transform')
|
||||
end
|
||||
|
||||
def transform(o)
|
||||
@transform_visitor.visit(o)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def transform_Factory(o)
|
||||
transform(o.current)
|
||||
end
|
||||
|
||||
def transform_Program(o)
|
||||
o.definitions.map{|d| transform(d)}
|
||||
end
|
||||
|
||||
# Extract comments from type definitions and class definitions. Wrap them
|
||||
# into YARDStatement objects that provide an interface for YARD handlers.
|
||||
def transform_NamedDefinition(o)
|
||||
obj = Puppetx::PuppetLabs::Strings::Pops::YARDStatement.new(o)
|
||||
obj.parameters = o.parameters.map do |p|
|
||||
param_tuple = [transform(p)]
|
||||
param_tuple << ( p.value.nil? ? nil : transform(p.value) )
|
||||
end
|
||||
|
||||
def transform(o)
|
||||
@transform_visitor.visit(o)
|
||||
end
|
||||
obj
|
||||
end
|
||||
|
||||
private
|
||||
# Catch-all visitor.
|
||||
def transform_Positioned(o)
|
||||
Puppetx::PuppetLabs::Strings::Pops::YARDStatement.new(o)
|
||||
end
|
||||
|
||||
def transform_Factory(o)
|
||||
transform(o.current)
|
||||
end
|
||||
|
||||
def transform_Program(o)
|
||||
o.definitions.map{|d| transform(d)}
|
||||
end
|
||||
|
||||
# Extract comments from type definitions and class definitions. Wrap them
|
||||
# into YARDStatement objects that provide an interface for YARD handlers.
|
||||
def transform_NamedDefinition(o)
|
||||
obj = YARDStatement.new(o)
|
||||
obj.parameters = o.parameters.map do |p|
|
||||
param_tuple = [transform(p)]
|
||||
param_tuple << ( p.value.nil? ? nil : transform(p.value) )
|
||||
end
|
||||
|
||||
obj
|
||||
end
|
||||
|
||||
# Catch-all visitor.
|
||||
def transform_Positioned(o)
|
||||
YARDStatement.new(o)
|
||||
end
|
||||
|
||||
# nil in... nil out!
|
||||
def transform_NilClass(o)
|
||||
nil
|
||||
end
|
||||
# nil in... nil out!
|
||||
def transform_NilClass(o)
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,10 +2,8 @@ require 'puppet/pops'
|
|||
|
||||
require 'puppetx/puppetlabs/strings/yard/code_objects/puppet_namespace_object'
|
||||
|
||||
module Puppetx::PuppetLabs::Strings::YARD::CodeObjects
|
||||
class DefinedTypeObject < PuppetNamespaceObject
|
||||
# A list of parameters attached to this class.
|
||||
# @return [Array<Array(String, String)>]
|
||||
attr_accessor :parameters
|
||||
end
|
||||
class Puppetx::PuppetLabs::Strings::YARD::CodeObjects::DefinedTypeObject < Puppetx::PuppetLabs::Strings::YARD::CodeObjects::PuppetNamespaceObject
|
||||
# A list of parameters attached to this class.
|
||||
# @return [Array<Array(String, String)>]
|
||||
attr_accessor :parameters
|
||||
end
|
||||
|
|
|
@ -1,26 +1,24 @@
|
|||
require 'puppetx/puppetlabs/strings/yard/code_objects/defined_type_object'
|
||||
|
||||
module Puppetx::PuppetLabs::Strings::YARD::CodeObjects
|
||||
class HostClassObject < DefinedTypeObject
|
||||
# The {HostClassObject} that this class inherits from, if any.
|
||||
# @return [HostClassObject, Proxy, nil]
|
||||
attr_accessor :parent_class
|
||||
class Puppetx::PuppetLabs::Strings::YARD::CodeObjects::HostClassObject < Puppetx::PuppetLabs::Strings::YARD::CodeObjects::DefinedTypeObject
|
||||
# The {HostClassObject} that this class inherits from, if any.
|
||||
# @return [HostClassObject, Proxy, nil]
|
||||
attr_accessor :parent_class
|
||||
|
||||
# NOTE: `include_mods` is never used as it makes no sense for Puppet, but
|
||||
# this is called by `YARD::Registry` and it will pass a parameter.
|
||||
def inheritance_tree(include_mods = false)
|
||||
if parent_class.is_a?(HostClassObject)
|
||||
# Cool. We got a host class. Return self + parent inheritance tree.
|
||||
[self] + parent_class.inheritance_tree
|
||||
elsif parent_class.is_a?(YARD::CodeObjects::Proxy)
|
||||
# We have a reference to a parent that has not been created yet. Just
|
||||
# return it.
|
||||
[self, parent_class]
|
||||
else
|
||||
# Most likely no parent class. But also possibly an object that we
|
||||
# shouldn't inherit from. Just return self.
|
||||
[self]
|
||||
end
|
||||
# NOTE: `include_mods` is never used as it makes no sense for Puppet, but
|
||||
# this is called by `YARD::Registry` and it will pass a parameter.
|
||||
def inheritance_tree(include_mods = false)
|
||||
if parent_class.is_a?(Puppetx::PuppetLabs::Strings::YARD::CodeObjects::HostClassObject)
|
||||
# Cool. We got a host class. Return self + parent inheritance tree.
|
||||
[self] + parent_class.inheritance_tree
|
||||
elsif parent_class.is_a?(YARD::CodeObjects::Proxy)
|
||||
# We have a reference to a parent that has not been created yet. Just
|
||||
# return it.
|
||||
[self, parent_class]
|
||||
else
|
||||
# Most likely no parent class. But also possibly an object that we
|
||||
# shouldn't inherit from. Just return self.
|
||||
[self]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,35 +1,33 @@
|
|||
require 'yard'
|
||||
require 'puppetx/puppetlabs/strings'
|
||||
|
||||
module Puppetx::PuppetLabs::Strings::YARD::CodeObjects
|
||||
class PuppetNamespaceObject < YARD::CodeObjects::NamespaceObject
|
||||
# NOTE: `YARD::Registry#resolve` requires a method with this signature to
|
||||
# be present on all subclasses of `NamespaceObject`.
|
||||
def inheritance_tree(include_mods = false)
|
||||
[self]
|
||||
end
|
||||
|
||||
# FIXME: We used to override `self.new` to ensure no YARD proxies were
|
||||
# created for namespaces segments that did not map to a host class or
|
||||
# defined type. Fighting the system in this way turned out to be
|
||||
# counter-productive.
|
||||
#
|
||||
# However, if a proxy is left in, YARD will drop back to namspace-mangling
|
||||
# heuristics that are very specific to Ruby and which produce ugly paths in
|
||||
# the resulting output. Need to find a way to address this.
|
||||
#
|
||||
# Tried:
|
||||
#
|
||||
# - Overriding self.new in the code object. Failed because self.new
|
||||
# overrides are gross and difficult to pull off. Especially when
|
||||
# replacing an existing override.
|
||||
#
|
||||
# - Adding functionality to the base handler to ensure something other
|
||||
# than a proxy occupies each namespace segment. Failed because once a
|
||||
# code object is created with a namespace, it will never update.
|
||||
# Unless that namespace is set to a Proxy.
|
||||
#
|
||||
# def self.new(namespace, name, *args, &block)
|
||||
class Puppetx::PuppetLabs::Strings::YARD::CodeObjects::PuppetNamespaceObject < YARD::CodeObjects::NamespaceObject
|
||||
# NOTE: `YARD::Registry#resolve` requires a method with this signature to
|
||||
# be present on all subclasses of `NamespaceObject`.
|
||||
def inheritance_tree(include_mods = false)
|
||||
[self]
|
||||
end
|
||||
|
||||
# FIXME: We used to override `self.new` to ensure no YARD proxies were
|
||||
# created for namespaces segments that did not map to a host class or
|
||||
# defined type. Fighting the system in this way turned out to be
|
||||
# counter-productive.
|
||||
#
|
||||
# However, if a proxy is left in, YARD will drop back to namspace-mangling
|
||||
# heuristics that are very specific to Ruby and which produce ugly paths in
|
||||
# the resulting output. Need to find a way to address this.
|
||||
#
|
||||
# Tried:
|
||||
#
|
||||
# - Overriding self.new in the code object. Failed because self.new
|
||||
# overrides are gross and difficult to pull off. Especially when
|
||||
# replacing an existing override.
|
||||
#
|
||||
# - Adding functionality to the base handler to ensure something other
|
||||
# than a proxy occupies each namespace segment. Failed because once a
|
||||
# code object is created with a namespace, it will never update.
|
||||
# Unless that namespace is set to a Proxy.
|
||||
#
|
||||
# def self.new(namespace, name, *args, &block)
|
||||
end
|
||||
|
||||
|
|
|
@ -4,16 +4,14 @@ require 'puppet/pops'
|
|||
require 'puppetx/puppetlabs/strings'
|
||||
require 'puppetx/puppetlabs/strings/yard/code_objects'
|
||||
|
||||
module Puppetx::PuppetLabs::Strings::YARD::Handlers
|
||||
class Base < YARD::Handlers::Base
|
||||
# Easy access to Pops model objects for handler matching.
|
||||
include Puppet::Pops::Model
|
||||
# Easy access to custom code objects from which documentation is generated.
|
||||
include Puppetx::PuppetLabs::Strings::YARD::CodeObjects
|
||||
|
||||
def self.handles?(statement)
|
||||
handlers.any? {|h| h == statement.type}
|
||||
end
|
||||
class Puppetx::PuppetLabs::Strings::YARD::Handlers::Base < YARD::Handlers::Base
|
||||
# Easy access to Pops model objects for handler matching.
|
||||
include Puppet::Pops::Model
|
||||
# Easy access to custom code objects from which documentation is generated.
|
||||
include Puppetx::PuppetLabs::Strings::YARD::CodeObjects
|
||||
|
||||
def self.handles?(statement)
|
||||
handlers.any? {|h| h == statement.type}
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
require 'puppetx/puppetlabs/strings/yard/handlers/base'
|
||||
|
||||
module Puppetx::PuppetLabs::Strings::YARD::Handlers
|
||||
class DefinedTypeHandler < Base
|
||||
handles ResourceTypeDefinition
|
||||
class Puppetx::PuppetLabs::Strings::YARD::Handlers::DefinedTypeHandler < Puppetx::PuppetLabs::Strings::YARD::Handlers:: Base
|
||||
handles ResourceTypeDefinition
|
||||
|
||||
process do
|
||||
obj = DefinedTypeObject.new(:root, statement.pops_obj.name) do |o|
|
||||
o.parameters = statement.parameters.map do |a|
|
||||
param_tuple = [a[0].pops_obj.name]
|
||||
param_tuple << ( a[1].nil? ? nil : a[1].source )
|
||||
end
|
||||
process do
|
||||
obj = DefinedTypeObject.new(:root, statement.pops_obj.name) do |o|
|
||||
o.parameters = statement.parameters.map do |a|
|
||||
param_tuple = [a[0].pops_obj.name]
|
||||
param_tuple << ( a[1].nil? ? nil : a[1].source )
|
||||
end
|
||||
|
||||
register obj
|
||||
end
|
||||
|
||||
register obj
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,24 +1,22 @@
|
|||
require 'puppetx/puppetlabs/strings/yard/handlers/base'
|
||||
|
||||
module Puppetx::PuppetLabs::Strings::YARD::Handlers
|
||||
class HostClassHandler < Base
|
||||
handles HostClassDefinition
|
||||
class Puppetx::PuppetLabs::Strings::YARD::Handlers::HostClassHandler < Puppetx::PuppetLabs::Strings::YARD::Handlers::Base
|
||||
handles HostClassDefinition
|
||||
|
||||
process do
|
||||
obj = HostClassObject.new(:root, statement.pops_obj.name) do |o|
|
||||
o.parameters = statement.parameters.map do |a|
|
||||
param_tuple = [a[0].pops_obj.name]
|
||||
param_tuple << ( a[1].nil? ? nil : a[1].source )
|
||||
end
|
||||
process do
|
||||
obj = HostClassObject.new(:root, statement.pops_obj.name) do |o|
|
||||
o.parameters = statement.parameters.map do |a|
|
||||
param_tuple = [a[0].pops_obj.name]
|
||||
param_tuple << ( a[1].nil? ? nil : a[1].source )
|
||||
end
|
||||
|
||||
statement.pops_obj.tap do |o|
|
||||
if o.parent_class
|
||||
obj.parent_class = P(:root, o.parent_class)
|
||||
end
|
||||
end
|
||||
|
||||
register obj
|
||||
end
|
||||
|
||||
statement.pops_obj.tap do |o|
|
||||
if o.parent_class
|
||||
obj.parent_class = P(:root, o.parent_class)
|
||||
end
|
||||
end
|
||||
|
||||
register obj
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,87 +2,86 @@
|
|||
require 'puppet/util/docs'
|
||||
require 'puppetx/puppetlabs/strings/yard/code_objects'
|
||||
|
||||
module Puppetx::PuppetLabs::Strings::YARD::Handlers
|
||||
class Puppet3xFunctionHandler < YARD::Handlers::Ruby::Base
|
||||
include Puppetx::PuppetLabs::Strings::YARD::CodeObjects
|
||||
class Puppetx::PuppetLabs::Strings::YARD::Handlers::Puppet3xFunctionHandler < YARD::Handlers::Ruby::Base
|
||||
include Puppetx::PuppetLabs::Strings::YARD::CodeObjects
|
||||
|
||||
handles method_call(:newfunction)
|
||||
handles method_call(:newfunction)
|
||||
|
||||
process do
|
||||
name, options = process_parameters
|
||||
process do
|
||||
name, options = process_parameters
|
||||
|
||||
obj = MethodObject.new(function_namespace, name)
|
||||
obj = MethodObject.new(function_namespace, name)
|
||||
|
||||
register obj
|
||||
if options['doc']
|
||||
register_docstring(obj, options['doc'], nil)
|
||||
end
|
||||
|
||||
# This has to be done _after_ register_docstring as all tags on the
|
||||
# object are overwritten by tags parsed out of the docstring.
|
||||
return_type = options['type']
|
||||
return_type ||= 'statement' # Default for newfunction
|
||||
obj.add_tag YARD::Tags::Tag.new(:return, '', return_type)
|
||||
|
||||
# FIXME: This is a hack that allows us to document the Puppet Core which
|
||||
# uses `--no-transitive-tag api` and then only shows things explicitly
|
||||
# tagged with `public` or `private` api. This is kind of insane and
|
||||
# should be fixed upstream.
|
||||
obj.add_tag YARD::Tags::Tag.new(:api, 'public')
|
||||
register obj
|
||||
if options['doc']
|
||||
register_docstring(obj, options['doc'], nil)
|
||||
end
|
||||
|
||||
private
|
||||
# This has to be done _after_ register_docstring as all tags on the
|
||||
# object are overwritten by tags parsed out of the docstring.
|
||||
return_type = options['type']
|
||||
return_type ||= 'statement' # Default for newfunction
|
||||
obj.add_tag YARD::Tags::Tag.new(:return, '', return_type)
|
||||
|
||||
# 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 ::Puppet3xFunctions, then there will be a clash. Hopefully the name
|
||||
# is sufficiently uncommon.
|
||||
obj = P(:root, 'Puppet3xFunctions')
|
||||
if obj.is_a? Proxy
|
||||
namespace_obj = PuppetNamespaceObject.new(:root, 'Puppet3xFunctions')
|
||||
namespace_obj.add_tag YARD::Tags::Tag.new(:api, 'public')
|
||||
# FIXME: This is a hack that allows us to document the Puppet Core which
|
||||
# uses `--no-transitive-tag api` and then only shows things explicitly
|
||||
# tagged with `public` or `private` api. This is kind of insane and
|
||||
# should be fixed upstream.
|
||||
obj.add_tag YARD::Tags::Tag.new(:api, 'public')
|
||||
end
|
||||
|
||||
register namespace_obj
|
||||
end
|
||||
private
|
||||
|
||||
obj
|
||||
# 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 ::Puppet3xFunctions, then there will be a clash. Hopefully the name
|
||||
# is sufficiently uncommon.
|
||||
obj = P(:root, 'Puppet3xFunctions')
|
||||
if obj.is_a? Proxy
|
||||
namespace_obj = PuppetNamespaceObject.new(:root, 'Puppet3xFunctions')
|
||||
namespace_obj.add_tag YARD::Tags::Tag.new(:api, 'public')
|
||||
|
||||
register namespace_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.
|
||||
obj
|
||||
end
|
||||
|
||||
# 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, opts = statement.parameters(false).compact
|
||||
# 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.
|
||||
|
||||
name = process_element(name)
|
||||
# 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, opts = statement.parameters(false).compact
|
||||
|
||||
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
|
||||
name = process_element(name)
|
||||
|
||||
[name, Hash[opts]]
|
||||
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
|
||||
|
||||
# Sometimes the YARD parser returns Heredoc strings that start with `<-`
|
||||
# instead of `<<-`.
|
||||
HEREDOC_START = /^<?<-/
|
||||
[name, Hash[opts]]
|
||||
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.
|
||||
#
|
||||
|
@ -104,20 +103,19 @@ module Puppetx::PuppetLabs::Strings::YARD::Handlers
|
|||
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
|
||||
# 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
|
||||
# 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
|
||||
# This utility method normalizes indentation and trims whitespace.
|
||||
Puppet::Util::Docs.scrub(source.join)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,98 +1,97 @@
|
|||
require 'puppetx/puppetlabs/strings/yard/code_objects'
|
||||
|
||||
module Puppetx::PuppetLabs::Strings::YARD::Handlers
|
||||
# Handles `dispatch` calls within a future parser function declaration. For
|
||||
# now, it just treats any docstring as an `@overlaod` tag and attaches the
|
||||
# overload to the parent function.
|
||||
class Puppet4xFunctionHandler < YARD::Handlers::Ruby::Base
|
||||
include Puppetx::PuppetLabs::Strings::YARD::CodeObjects
|
||||
# Handles `dispatch` calls within a future parser function declaration. For
|
||||
# now, it just treats any docstring as an `@overlaod` tag and attaches the
|
||||
# overload to the parent function.
|
||||
class Puppetx::PuppetLabs::Strings::YARD::Handlers::Puppet4xFunctionHandler < YARD::Handlers::Ruby::Base
|
||||
include Puppetx::PuppetLabs::Strings::YARD::CodeObjects
|
||||
|
||||
handles method_call(:dispatch)
|
||||
handles method_call(:dispatch)
|
||||
|
||||
process do
|
||||
return unless owner.is_a?(MethodObject) && owner['puppet_4x_function']
|
||||
return unless statement.docstring
|
||||
process do
|
||||
return unless owner.is_a?(MethodObject) && owner['puppet_4x_function']
|
||||
return unless statement.docstring
|
||||
|
||||
docstring = ::YARD::Docstring.new(statement.docstring, nil)
|
||||
docstring = ::YARD::Docstring.new(statement.docstring, nil)
|
||||
|
||||
# FIXME: This does a wholesale copy of all possible tags. But, we're only
|
||||
# interested in the @overload tag.
|
||||
owner.add_tag *docstring.tags
|
||||
end
|
||||
# FIXME: This does a wholesale copy of all possible tags. But, we're only
|
||||
# interested in the @overload tag.
|
||||
owner.add_tag *docstring.tags
|
||||
end
|
||||
end
|
||||
|
||||
class Puppet4xFunctionHandler < YARD::Handlers::Ruby::Base
|
||||
include Puppetx::PuppetLabs::Strings::YARD::CodeObjects
|
||||
|
||||
handles method_call(:create_function)
|
||||
|
||||
process do
|
||||
name = process_parameters
|
||||
|
||||
obj = MethodObject.new(function_namespace, name)
|
||||
obj['puppet_4x_function'] = true
|
||||
|
||||
register obj
|
||||
|
||||
obj.add_tag YARD::Tags::Tag.new(:api, 'public')
|
||||
|
||||
blk = statement.block.children.first
|
||||
parse_block(blk, :owner => obj)
|
||||
end
|
||||
|
||||
class Puppet4xFunctionHandler < YARD::Handlers::Ruby::Base
|
||||
include Puppetx::PuppetLabs::Strings::YARD::CodeObjects
|
||||
private
|
||||
|
||||
handles method_call(:create_function)
|
||||
# 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 ::Puppet4xFunctions, then there will be a clash. Hopefully the name
|
||||
# is sufficiently uncommon.
|
||||
obj = P(:root, 'Puppet4xFunctions')
|
||||
if obj.is_a? Proxy
|
||||
namespace_obj = PuppetNamespaceObject.new(:root, 'Puppet4xFunctions')
|
||||
|
||||
process do
|
||||
name = process_parameters
|
||||
|
||||
obj = MethodObject.new(function_namespace, name)
|
||||
obj['puppet_4x_function'] = true
|
||||
|
||||
register obj
|
||||
|
||||
obj.add_tag YARD::Tags::Tag.new(:api, 'public')
|
||||
|
||||
blk = statement.block.children.first
|
||||
parse_block(blk, :owner => obj)
|
||||
register namespace_obj
|
||||
# FIXME: The docstring has to be cleared. Otherwise, the namespace
|
||||
# object will be registered using the docstring of the
|
||||
# `create_function` call that is currently being processed.
|
||||
#
|
||||
# Figure out how to properly register the namespace without using the
|
||||
# function handler object.
|
||||
register_docstring(namespace_obj, '', nil)
|
||||
namespace_obj.add_tag YARD::Tags::Tag.new(:api, 'public')
|
||||
end
|
||||
|
||||
private
|
||||
obj
|
||||
end
|
||||
|
||||
# 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 ::Puppet4xFunctions, then there will be a clash. Hopefully the name
|
||||
# is sufficiently uncommon.
|
||||
obj = P(:root, 'Puppet4xFunctions')
|
||||
if obj.is_a? Proxy
|
||||
namespace_obj = PuppetNamespaceObject.new(:root, 'Puppet4xFunctions')
|
||||
# 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.
|
||||
|
||||
register namespace_obj
|
||||
# FIXME: The docstring has to be cleared. Otherwise, the namespace
|
||||
# object will be registered using the docstring of the
|
||||
# `create_function` call that is currently being processed.
|
||||
#
|
||||
# Figure out how to properly register the namespace without using the
|
||||
# function handler object.
|
||||
register_docstring(namespace_obj, '', nil)
|
||||
namespace_obj.add_tag YARD::Tags::Tag.new(:api, 'public')
|
||||
end
|
||||
# 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
|
||||
|
||||
obj
|
||||
end
|
||||
name = process_element(name)
|
||||
|
||||
# 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.
|
||||
name
|
||||
end
|
||||
|
||||
# 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 = /^<?<-/
|
||||
# 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.
|
||||
#
|
||||
|
@ -114,20 +113,19 @@ module Puppetx::PuppetLabs::Strings::YARD::Handlers
|
|||
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
|
||||
# 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
|
||||
# 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
|
||||
# This utility method normalizes indentation and trims whitespace.
|
||||
Puppet::Util::Docs.scrub(source.join)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,29 +4,27 @@ require 'puppet/pops'
|
|||
require 'puppetx/puppetlabs/strings'
|
||||
require 'puppetx/puppetlabs/strings//pops/yard_transformer'
|
||||
|
||||
module Puppetx::PuppetLabs::Strings::YARD
|
||||
class PuppetParser < YARD::Parser::Base
|
||||
attr_reader :file, :source
|
||||
class Puppetx::PuppetLabs::Strings::YARD::PuppetParser < YARD::Parser::Base
|
||||
attr_reader :file, :source
|
||||
|
||||
def initialize(source, filename)
|
||||
@source = source
|
||||
@file = filename
|
||||
|
||||
@parser = Puppet::Pops::Parser::Parser.new()
|
||||
@transformer = Puppetx::PuppetLabs::Strings::Pops::YARDTransformer.new()
|
||||
end
|
||||
|
||||
def parse
|
||||
@parse_result ||= @parser.parse_string(source)
|
||||
self
|
||||
end
|
||||
|
||||
def enumerator
|
||||
statements = @transformer.transform(@parse_result)
|
||||
|
||||
# Ensure an array is returned and prune any nil values.
|
||||
Array(statements).compact
|
||||
end
|
||||
def initialize(source, filename)
|
||||
@source = source
|
||||
@file = filename
|
||||
|
||||
@parser = Puppet::Pops::Parser::Parser.new()
|
||||
@transformer = Puppetx::PuppetLabs::Strings::Pops::YARDTransformer.new()
|
||||
end
|
||||
|
||||
def parse
|
||||
@parse_result ||= @parser.parse_string(source)
|
||||
self
|
||||
end
|
||||
|
||||
def enumerator
|
||||
statements = @transformer.transform(@parse_result)
|
||||
|
||||
# Ensure an array is returned and prune any nil values.
|
||||
Array(statements).compact
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue