File: //usr/share/ruby/vendor_ruby/puppet/parser/e_parser_adapter.rb
require 'puppet/pops'
module Puppet; module Parser; end; end;
# Adapts an egrammar/eparser to respond to the public API of the classic parser
#
class Puppet::Parser::EParserAdapter
def initialize(classic_parser)
@classic_parser = classic_parser
@file = ''
@string = ''
@use = :undefined
end
def file=(file)
@classic_parser.file = file
@file = file
@use = :file
end
def parse(string = nil)
if @file =~ /\.rb$/
return parse_ruby_file
else
self.string= string if string
parser = Puppet::Pops::Parser::Parser.new()
parse_result = if @use == :string
parser.parse_string(@string)
else
parser.parse_file(@file)
end
# Compute the source_file to set in created AST objects (it was either given, or it may be unknown
# if caller did not set a file and the present a string.
#
source_file = @file || "unknown-source-location"
# Validate
validate(parse_result)
# Transform the result, but only if not nil
parse_result = Puppet::Pops::Model::AstTransformer.new(source_file, @classic_parser).transform(parse_result) if parse_result
if parse_result && !parse_result.is_a?(Puppet::Parser::AST::BlockExpression)
# Need to transform again, if result is not wrapped in something iterable when handed off to
# a new Hostclass as its code.
parse_result = Puppet::Parser::AST::BlockExpression.new(:children => [parse_result]) if parse_result
end
end
Puppet::Parser::AST::Hostclass.new('', :code => parse_result)
end
def validate(parse_result)
# TODO: This is too many hoops to jump through... ugly API
# could reference a ValidatorFactory.validator_3_1(acceptor) instead.
# and let the factory abstract the rest.
#
return unless parse_result
acceptor = Puppet::Pops::Validation::Acceptor.new
validator = Puppet::Pops::Validation::ValidatorFactory_3_1.new().validator(acceptor)
validator.validate(parse_result)
max_errors = Puppet[:max_errors]
max_warnings = Puppet[:max_warnings] + 1
max_deprecations = Puppet[:max_deprecations] + 1
# If there are warnings output them
warnings = acceptor.warnings
if warnings.size > 0
formatter = Puppet::Pops::Validation::DiagnosticFormatterPuppetStyle.new
emitted_w = 0
emitted_dw = 0
acceptor.warnings.each {|w|
if w.severity == :deprecation
# Do *not* call Puppet.deprecation_warning it is for internal deprecation, not
# deprecation of constructs in manifests! (It is not designed for that purpose even if
# used throughout the code base).
#
Puppet.warning(formatter.format(w)) if emitted_dw < max_deprecations
emitted_dw += 1
else
Puppet.warning(formatter.format(w)) if emitted_w < max_warnings
emitted_w += 1
end
break if emitted_w > max_warnings && emitted_dw > max_deprecations # but only then
}
end
# If there were errors, report the first found. Use a puppet style formatter.
errors = acceptor.errors
if errors.size > 0
formatter = Puppet::Pops::Validation::DiagnosticFormatterPuppetStyle.new
if errors.size == 1 || max_errors <= 1
# raise immediately
raise Puppet::ParseError.new(formatter.format(errors[0]))
end
emitted = 0
errors.each do |e|
Puppet.err(formatter.format(e))
emitted += 1
break if emitted >= max_errors
end
warnings_message = warnings.size > 0 ? ", and #{warnings.size} warnings" : ""
giving_up_message = "Found #{errors.size} errors#{warnings_message}. Giving up"
exception = Puppet::ParseError.new(giving_up_message)
exception.file = errors[0].file
raise exception
end
end
def string=(string)
@classic_parser.string = string
@string = string
@use = :string
end
def parse_ruby_file
@classic_parser.parse
end
end