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

COMMA_SEPARATOR =
', '.freeze
Issues =

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

Issues

Constants included from Runtime3Support

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_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, #runtime_issue, #set_match_data, #set_scope_nesting_level, #set_variable, #variable_bound?, #variable_exists?

Methods included from Utils

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


43
44
45
46
47
48
# File 'lib/puppet/pops/evaluator/evaluator_impl.rb', line 43

def initialize
  @@initialized ||= static_initialize

  # Use null migration checker unless given in context
  @migration_checker = Puppet.lookup(:migration_checker) { Migration::MigrationChecker.singleton }
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.


139
140
141
# File 'lib/puppet/pops/evaluator/evaluator_impl.rb', line 139

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.


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
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/puppet/pops/evaluator/evaluator_impl.rb', line 79

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

  rescue 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 StopIteration => e
    # Ensure these are not rescued as StandardError
    raise 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.


172
173
174
175
176
177
178
179
# File 'lib/puppet/pops/evaluator/evaluator_impl.rb', line 172

def evaluate_block_with_bindings(scope, variable_bindings, block_expr)
  scope.with_guarded_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.


149
150
151
# File 'lib/puppet/pops/evaluator/evaluator_impl.rb', line 149

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

#match?(left, right) ⇒ Boolean

Implementation of case option matching.

This is the type of matching performed in a case option, using == for every type of value except regular expression where a match is performed.


186
187
188
# File 'lib/puppet/pops/evaluator/evaluator_impl.rb', line 186

def match?(left, right)
  @@compare_operator.match(left, right, nil)
end

#string(o, scope) ⇒ Object

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


159
160
161
# File 'lib/puppet/pops/evaluator/evaluator_impl.rb', line 159

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.


66
67
68
# File 'lib/puppet/pops/evaluator/evaluator_impl.rb', line 66

def type_calculator
  @@type_calculator
end