Class: Puppet::Pops::Evaluator::EvaluatorImpl

Inherits:
Object
  • Object
show all
Includes:
ExternalSyntaxSupport, Runtime3Support, Utils
Defined in:
lib/puppet/pops/evaluator/evaluator_impl.rb

Overview

This implementation of Puppet::Pops::Evaluator performs evaluation using the puppet 3.x runtime system in a manner largely compatible with Puppet 3.x, but adds new features and introduces constraints.

The evaluation uses _polymorphic dispatch_ which works by dispatching to the first found method named after the class or one of its super-classes. The EvaluatorImpl itself mainly deals with evaluation (it currently also handles assignment), and it uses a delegation pattern to more specialized handlers of some operators that in turn use polymorphic dispatch; this to not clutter EvaluatorImpl with too much responsibility).

Since a pattern is used, only the main entry points are fully documented. The parameters o and scope are the same in all the polymorphic methods, (the type of the parameter o is reflected in the method’s name; either the actual class, or one of its super classes). The scope parameter is always the scope in which the evaluation takes place. If nothing else is mentioned, the return is always the result of evaluation.

See Visitable and Visitor for more information about polymorphic calling.

Constant Summary collapse

EMPTY_STRING =
''.freeze
COMMA_SEPARATOR =
', '.freeze
Issues =

Reference to Issues name space makes it easier to refer to issues (Issues are shared with the validator).

Puppet::Pops::Issues

Constants included from ExternalSyntaxSupport

Puppet::Pops::Evaluator::ExternalSyntaxSupport::SERVICE_NAME, Puppet::Pops::Evaluator::ExternalSyntaxSupport::SERVICE_TYPE, Puppet::Pops::Evaluator::ExternalSyntaxSupport::TYPES

Constants included from Runtime3Support

Runtime3Support::CLASS_STRING, Runtime3Support::NAME_SPACE_SEPARATOR

Instance Method Summary collapse

Methods included from ExternalSyntaxSupport

#assert_external_syntax, #checker_for_syntax, #lookup_keys_for_syntax

Methods included from Runtime3Support

#add_relationship, #call_function, #capitalize_qualified_name, #coerce_numeric, #convert, #create_local_scope_from, #create_match_scope_from, #create_resource_defaults, #create_resource_overrides, #create_resource_parameter, #create_resources, #diagnostic_producer, #external_call_function, #extract_file_line, #fail, #find_closest_positioned, #find_resource, #get_resource_parameter_value, #get_scope_nesting_level, #get_variable_value, #is_boolean?, #is_parameter_of_resource?, #is_true?, #optionally_fail, #resource_to_ptype, #set_match_data, #set_scope_nesting_level, #set_variable, #variable_bound?, #variable_exists?

Methods included from Utils

find_adapter, find_closest_positioned, is_absolute?, is_numeric?, match_to_fp, name_to_segments, relativize_name, to_n, to_n_with_radix

Constructor Details

#initializeEvaluatorImpl

Returns a new instance of EvaluatorImpl.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/puppet/pops/evaluator/evaluator_impl.rb', line 41

def initialize
  @@eval_visitor     ||= Puppet::Pops::Visitor.new(self, "eval", 1, 1)
  @@lvalue_visitor   ||= Puppet::Pops::Visitor.new(self, "lvalue", 1, 1)
  @@assign_visitor   ||= Puppet::Pops::Visitor.new(self, "assign", 3, 3)
  @@string_visitor   ||= Puppet::Pops::Visitor.new(self, "string", 1, 1)

  @@type_calculator  ||= Puppet::Pops::Types::TypeCalculator.new()
  @@type_parser      ||= Puppet::Pops::Types::TypeParser.new()

  @@compare_operator     ||= Puppet::Pops::Evaluator::CompareOperator.new()
  @@relationship_operator ||= Puppet::Pops::Evaluator::RelationshipOperator.new()

  # Use null migration checker unless given in context
  @migration_checker = (Puppet.lookup(:migration_checker) { Puppet::Pops::Migration::MigrationChecker.new() })
end

Instance Method Details

#assign(target, value, o, scope) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Assigns the given value to the given target. The additional argument o is the instruction that produced the target/value tuple and it is used to set the origin of the result.

Parameters:

  • target (Object)

    assignment target - see methods on the pattern assign_TYPE for actual supported types.

  • value (Object)

    the value to assign to ‘target`

  • o (Puppet::Pops::Model::PopsObject)

    originating instruction

  • scope (Object)

    the runtime specific scope where evaluation should take place



127
128
129
# File 'lib/puppet/pops/evaluator/evaluator_impl.rb', line 127

def assign(target, value, o, scope)
  @@assign_visitor.visit_this_3(self, target, value, o, scope)
end

#evaluate(target, scope) ⇒ Object

Evaluates the given target object in the given scope.

Parameters:

  • target (Object)

    evaluation target - see methods on the pattern assign_TYPE for actual supported types.

  • scope (Object)

    the runtime specific scope class where evaluation should take place

Returns:

  • (Object)

    the result of the evaluation



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/puppet/pops/evaluator/evaluator_impl.rb', line 71

def evaluate(target, scope)
  begin
    @@eval_visitor.visit_this_1(self, target, scope)

  rescue Puppet::Pops::SemanticError => e
    # A raised issue may not know the semantic target, use errors call stack, but fill in the 
    # rest from a supplied semantic object, or the target instruction if there is not semantic
    # object.
    #
    fail(e.issue, e.semantic || target, e.options, e)

  rescue Puppet::PreformattedError => e
    # Already formatted with location information, and with the wanted call stack.
    # Note this is currently a specialized ParseError, so rescue-order is important
    #
    raise e

  rescue Puppet::ParseError => e
    # ParseError may be raised in ruby code without knowing the location
    # in puppet code.
    # Accept a ParseError that has file or line information available
    # as an error that should be used verbatim. (Tests typically run without
    # setting a file name).
    # ParseError can supply an original - it is impossible to determine which
    # call stack that should be propagated, using the ParseError's backtrace.
    #
    if e.file || e.line
      raise e
    else
      # Since it had no location information, treat it as user intended a general purpose
      # error. Pass on its call stack.
      fail(Issues::RUNTIME_ERROR, target, {:detail => e.message}, e)
    end


  rescue Puppet::Error => e
    # PuppetError has the ability to wrap an exception, if so, use the wrapped exception's
    # call stack instead
    fail(Issues::RUNTIME_ERROR, target, {:detail => e.message}, e.original || e)

  rescue StandardError => e
    # All other errors, use its message and call stack
    fail(Issues::RUNTIME_ERROR, target, {:detail => e.message}, e)
  end
end

#evaluate_block_with_bindings(scope, variable_bindings, block_expr) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Evaluate a BlockExpression in a new scope with variables bound to the given values.

Parameters:



160
161
162
163
164
165
166
167
# File 'lib/puppet/pops/evaluator/evaluator_impl.rb', line 160

def evaluate_block_with_bindings(scope, variable_bindings, block_expr)
  with_guarded_scope(scope) do
    # change to create local scope_from - cannot give it file and line -
    # that is the place of the call, not "here"
    create_local_scope_from(variable_bindings, scope)
    evaluate(block_expr, scope)
  end
end

#lvalue(o, scope) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Computes a value that can be used as the LHS in an assignment.

Parameters:

  • o (Object)

    the expression to evaluate as a left (assignable) entity

  • scope (Object)

    the runtime specific scope where evaluation should take place



137
138
139
# File 'lib/puppet/pops/evaluator/evaluator_impl.rb', line 137

def lvalue(o, scope)
  @@lvalue_visitor.visit_this_1(self, o, scope)
end

#string(o, scope) ⇒ Object

Produces a String representation of the given object o as used in interpolation.

Parameters:

  • o (Object)

    the expression of which a string representation is wanted

  • scope (Object)

    the runtime specific scope where evaluation should take place



147
148
149
# File 'lib/puppet/pops/evaluator/evaluator_impl.rb', line 147

def string(o, scope)
  @@string_visitor.visit_this_1(self, o, scope)
end

#type_calculatorObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



58
59
60
# File 'lib/puppet/pops/evaluator/evaluator_impl.rb', line 58

def type_calculator
  @@type_calculator
end