Class: Puppet::Pops::Model::AstTransformer

Inherits:
Object
  • Object
show all
Defined in:
lib/puppet/pops/model/ast_transformer.rb

Overview

The receiver of ‘import(file)` calls; once per imported file, or nil if imports are ignored

Transforms a Pops::Model to classic Puppet AST. TODO: Documentation is currently skipped completely (it is only used for Rdoc)

Constant Summary collapse

AST =
Puppet::Parser::AST
Model =
Puppet::Pops::Model

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source_file = "unknown-file", importer = nil) ⇒ AstTransformer

Returns a new instance of AstTransformer.



13
14
15
16
17
18
19
# File 'lib/puppet/pops/model/ast_transformer.rb', line 13

def initialize(source_file = "unknown-file", importer=nil)
  @@transform_visitor ||= Puppet::Pops::Visitor.new(nil,"transform",0,0)
  @@query_transform_visitor ||= Puppet::Pops::Visitor.new(nil,"query",0,0)
  @@hostname_transform_visitor ||= Puppet::Pops::Visitor.new(nil,"hostname",0,0)
  @importer = importer
  @source_file = source_file
end

Instance Attribute Details

#importerObject (readonly)



12
13
14
# File 'lib/puppet/pops/model/ast_transformer.rb', line 12

def importer
  @importer
end

Instance Method Details

#ast(o, klass, hash = {}) ⇒ Object

Initialize klass from o (location) and hash (options to created instance). The object o is used to compute a source location. It may be nil. Source position is merged into the given options (non surgically). If o is non-nil, the first found source position going up the containment hierarchy is set. I.e. callers should pass nil if a source position is not wanted or known to be unobtainable for the object.

Parameters:

  • o (Object, nil)

    object from which source position / location is obtained, may be nil

  • klass (Class<Puppet::Parser::AST>)

    the ast class to create an instance of

  • hash (Hash) (defaults to: {})

    hash with options for the class to create



31
32
33
34
# File 'lib/puppet/pops/model/ast_transformer.rb', line 31

def ast(o, klass, hash={})
  # create and pass hash with file and line information
  klass.new(merge_location(hash, o))
end

#hostname(o) ⇒ Object

Transforms pops expressions into AST 3.1 hostnames



61
62
63
# File 'lib/puppet/pops/model/ast_transformer.rb', line 61

def hostname(o)
  @@hostname_transform_visitor.visit_this(self, o)
end

#hostname_Array(o) ⇒ Object

Transforms Array of host matching expressions into a (Ruby) array of AST::HostName



450
451
452
# File 'lib/puppet/pops/model/ast_transformer.rb', line 450

def hostname_Array(o)
  o.collect {|x| ast x, AST::HostName, :value => hostname(x) }
end

#hostname_LiteralDefault(o) ⇒ Object



466
467
468
# File 'lib/puppet/pops/model/ast_transformer.rb', line 466

def hostname_LiteralDefault(o)
  return 'default'
end

#hostname_LiteralNumber(o) ⇒ Object



462
463
464
# File 'lib/puppet/pops/model/ast_transformer.rb', line 462

def hostname_LiteralNumber(o)
  transform(o) # Number to string with correct radix
end

#hostname_LiteralRegularExpression(o) ⇒ Object



470
471
472
# File 'lib/puppet/pops/model/ast_transformer.rb', line 470

def hostname_LiteralRegularExpression(o)
  ast o, AST::Regex, :value => o.value
end

#hostname_LiteralValue(o) ⇒ Object



454
455
456
# File 'lib/puppet/pops/model/ast_transformer.rb', line 454

def hostname_LiteralValue(o)
  return o.value
end

#hostname_Object(o) ⇒ Object



474
475
476
# File 'lib/puppet/pops/model/ast_transformer.rb', line 474

def hostname_Object(o)
  raise "Illegal expression - unacceptable as a node name"
end

#hostname_QualifiedName(o) ⇒ Object



458
459
460
# File 'lib/puppet/pops/model/ast_transformer.rb', line 458

def hostname_QualifiedName(o)
  return o.value
end

#is_nop?(o) ⇒ Boolean

Nil, nop Bee bopp a luh-lah, a bop bop boom.

Returns:

  • (Boolean)


636
637
638
# File 'lib/puppet/pops/model/ast_transformer.rb', line 636

def is_nop?(o)
  o.nil? || o.is_a?(Model::Nop)
end

#merge_location(hash, o) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/puppet/pops/model/ast_transformer.rb', line 36

def merge_location(hash, o)
  if o
    pos = {}
    source_pos = Puppet::Pops::Utils.find_adapter(o, Puppet::Pops::Adapters::SourcePosAdapter)
    if source_pos
      pos[:line] = source_pos.line
      pos[:pos]  = source_pos.pos
    end
    pos[:file] = @source_file if @source_file
    hash = hash.merge(pos)
  end
  hash
end

#query(o) ⇒ Object

Transforms pops expressions into AST 3.1 query expressions



56
57
58
# File 'lib/puppet/pops/model/ast_transformer.rb', line 56

def query(o)
  @@query_transform_visitor.visit_this(self, o)
end

#query_AndExpression(o) ⇒ Object



196
197
198
# File 'lib/puppet/pops/model/ast_transformer.rb', line 196

def query_AndExpression(o)
  ast o, AST::CollExpr, :test1 => query(o.left_expr), :oper => 'and', :test2 => query(o.right_expr)
end

#query_ComparisonExpression(o) ⇒ Object

Puppet AST only allows == and !=, and left expr is restricted, but right value is an expression



188
189
190
191
192
193
194
# File 'lib/puppet/pops/model/ast_transformer.rb', line 188

def query_ComparisonExpression(o)
  if [:'==', :'!='].include? o.operator
    ast o, AST::CollExpr, :test1 => query(o.left_expr), :oper => o.operator.to_s, :test2 => transform(o.right_expr)
  else
    raise "Not a valid comparison operator in a collection query: " + o.operator.to_s
  end
end

#query_LiteralBoolean(o) ⇒ Object



226
227
228
# File 'lib/puppet/pops/model/ast_transformer.rb', line 226

def query_LiteralBoolean(o)
  transform(o)
end

#query_LiteralNumber(o) ⇒ Object



218
219
220
# File 'lib/puppet/pops/model/ast_transformer.rb', line 218

def query_LiteralNumber(o)
  transform(o) # number to string in correct radix
end

#query_LiteralString(o) ⇒ Object



222
223
224
# File 'lib/puppet/pops/model/ast_transformer.rb', line 222

def query_LiteralString(o)
  transform(o)
end

#query_Object(o) ⇒ Object

Ensures transformation fails if a 3.1 non supported object is encountered in a query expression



182
183
184
# File 'lib/puppet/pops/model/ast_transformer.rb', line 182

def query_Object(o)
  raise "Not a valid expression in a collection query: "+o.class.name
end

#query_OrExpression(o) ⇒ Object



200
201
202
# File 'lib/puppet/pops/model/ast_transformer.rb', line 200

def query_OrExpression(o)
  ast o, AST::CollExpr, :test1 => query(o.left_expr), :oper => 'or', :test2 => query(o.right_expr)
end

#query_ParenthesizedExpression(o) ⇒ Object



204
205
206
207
208
# File 'lib/puppet/pops/model/ast_transformer.rb', line 204

def query_ParenthesizedExpression(o)
  result = query(o.expr) # produces CollExpr
  result.parens = true
  result
end

#query_QualifiedName(o) ⇒ Object



214
215
216
# File 'lib/puppet/pops/model/ast_transformer.rb', line 214

def query_QualifiedName(o)
  transform(o)
end

#query_VariableExpression(o) ⇒ Object



210
211
212
# File 'lib/puppet/pops/model/ast_transformer.rb', line 210

def query_VariableExpression(o)
  transform(o)
end

#transform(o) ⇒ Object

Transforms pops expressions into AST 3.1 statements/expressions



51
52
53
# File 'lib/puppet/pops/model/ast_transformer.rb', line 51

def transform(o)
  @@transform_visitor.visit_this(self,o)
end

#transform_AccessExpression(o) ⇒ Object

Puppet AST only allows:

  • variable => Hasharray Access

  • NAME [expressions] => Resource Reference(s)

  • type [epxressions] => Resource Reference(s)

  • HashArrayAccesses => HasharrayAccesses

i.e. it is not possible to do ‘func()`, `[1,2,3]`, `foo=>10, bar=>20` etc. since LHS is not an expression

Validation for 3.x semantics should validate the illegal cases. This transformation may fail, or ignore excess information if the expressions are not correct. This means that the transformation does not have to evaluate the lhs to detect the target expression.

Hm, this seems to have changed, the LHS (variable) is evaluated if evaluateable, else it is used as is.



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/puppet/pops/model/ast_transformer.rb', line 119

def transform_AccessExpression(o)
  case o.left_expr
  when Model::QualifiedName
    ast o, AST::ResourceReference, :type => o.left_expr.value, :title => transform(o.keys)

  when Model::QualifiedReference
    ast o, AST::ResourceReference, :type => o.left_expr.value, :title => transform(o.keys)

  when Model::VariableExpression
    ast o, AST::HashOrArrayAccess, :variable => transform(o.left_expr), :key => transform(o.keys()[0])

  else
    ast o, AST::HashOrArrayAccess, :variable => transform(o.left_expr), :key => transform(o.keys()[0])
  end
end

#transform_AndExpression(o) ⇒ Object



242
243
244
# File 'lib/puppet/pops/model/ast_transformer.rb', line 242

def transform_AndExpression(o)
  ast o, AST::BooleanOperator, :operator => 'and', :lval => transform(o.left_expr), :rval => transform(o.right_expr)
end

#transform_ArithmeticExpression(o) ⇒ Object



95
96
97
98
# File 'lib/puppet/pops/model/ast_transformer.rb', line 95

def transform_ArithmeticExpression(o)
  ast o, AST::ArithmeticOperator2, :lval => transform(o.left_expr), :rval=>transform(o.right_expr),
  :operator => o.operator.to_s
end

#transform_Array(o) ⇒ Object



100
101
102
# File 'lib/puppet/pops/model/ast_transformer.rb', line 100

def transform_Array(o)
  ast nil, AST::ASTArray, :children => o.collect {|x| transform(x) }
end

#transform_AssignmentExpression(o) ⇒ Object

Assignment in AST 3.1 is to variable or hasharray accesses !!! See Bug #16116



278
279
280
281
282
283
284
285
286
287
288
289
290
291
# File 'lib/puppet/pops/model/ast_transformer.rb', line 278

def transform_AssignmentExpression(o)
  args = {:value => transform(o.right_expr) }
  args[:append] = true if o.operator == :'+='

  args[:name] = case o.left_expr
  when Model::VariableExpression
    ast o, AST::Name, {:value => o.left_expr.expr.value }
  when Model::AccessExpression
    transform(o.left_expr)
  else
    raise "LHS is not an expression that can be assigned to"
  end
  ast o, AST::VarDef, args
end

#transform_AttributeOperation(o) ⇒ Object

Produces (name => expr) or (name +> expr)



294
295
296
297
298
299
# File 'lib/puppet/pops/model/ast_transformer.rb', line 294

def transform_AttributeOperation(o)
  args = { :value => transform(o.value_expr) }
  args[:add] = true if o.operator == :'+>'
  args[:param] = o.attribute_name
  ast o, AST::ResourceParam, args
end

#transform_BlockExpression(o) ⇒ Object

Puppet 3.1 representation of a BlockExpression is an AST::Array - this makes it impossible to differentiate between a LiteralArray and a Sequence. (Should it return the collected array, or the last expression?) (A BlockExpression has now been introduced in the AST to solve this).



413
414
415
416
417
418
# File 'lib/puppet/pops/model/ast_transformer.rb', line 413

def transform_BlockExpression(o)
  children = []
  # remove nops resulting from import
  o.statements.each {|s| r = transform(s); children << r unless is_nop?(r) }
  ast o, AST::BlockExpression, :children => children  # o.statements.collect {|s| transform(s) }
end

#transform_CallMethodExpression(o) ⇒ Object

Transformation of CallMethodExpression handles a NamedAccessExpression functor and turns this into a 3.1 AST::MethodCall.



573
574
575
576
577
578
579
580
581
# File 'lib/puppet/pops/model/ast_transformer.rb', line 573

def transform_CallMethodExpression(o)
  name = o.functor_expr
  raise "Unacceptable expression for name of function" unless name.is_a? Model::NamedAccessExpression
  # transform of NamedAccess produces a hash, add arguments to it
  astargs = transform(name).merge(:arguments => transform(o.arguments))
  astargs.merge!(:lambda => transform(o.lambda)) if o.lambda # do not want a Nop as the lambda
  ast o, AST::MethodCall, astargs

end

#transform_CallNamedFunctionExpression(o) ⇒ Object

Puppet 3.1 AST only supports calling a function by name (it is not possible to produce a function that is then called). rval_required (for an expression) functor_expr (lhs - the “name” expression) arguments - list of arguments



558
559
560
561
562
563
564
565
566
567
568
# File 'lib/puppet/pops/model/ast_transformer.rb', line 558

def transform_CallNamedFunctionExpression(o)
  name = o.functor_expr
  raise "Unacceptable expression for name of function" unless name.is_a? Model::QualifiedName
  args = {
    :name => name.value,
    :arguments => transform(o.arguments),
    :ftype => o.rval_required ? :rvalue : :statement
  }
  args[:pblock] = transform(o.lambda) if o.lambda
  ast o, AST::Function, args
end

#transform_CaseExpression(o) ⇒ Object



583
584
585
586
# File 'lib/puppet/pops/model/ast_transformer.rb', line 583

def transform_CaseExpression(o)
  # Expects expression, AST::ASTArray of AST
  ast o, AST::CaseStatement, :test => transform(o.test), :options => transform(o.options)
end

#transform_CaseOption(o) ⇒ Object



588
589
590
# File 'lib/puppet/pops/model/ast_transformer.rb', line 588

def transform_CaseOption(o)
  ast o, AST::CaseOpt, :value => transform(o.values), :statements => transform(o.then_expr)
end

#transform_CollectExpression(o) ⇒ Object

Puppet AST has a complicated structure LHS can not be an expression, it must be a type (which is downcased). type = a downcased QualifiedName



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/puppet/pops/model/ast_transformer.rb', line 139

def transform_CollectExpression(o)
  raise "LHS is not a type" unless o.type_expr.is_a? Model::QualifiedReference
  type = o.type_expr.value().downcase()
  args = { :type => type }

  # This somewhat peculiar encoding is used by the 3.1 AST.
  query = transform(o.query)
  if query.is_a? Symbol
    args[:form] =  query
  else
    args[:form] = query.form
    args[:query] = query
    query.type = type
  end

  if o.operations.size > 0
    args[:override] = transform(o.operations)
  end
  ast o, AST::Collection, args
end

#transform_ComparisonExpression(o) ⇒ Object



238
239
240
# File 'lib/puppet/pops/model/ast_transformer.rb', line 238

def transform_ComparisonExpression(o)
  ast o, AST::ComparisonOperator, :operator => o.operator.to_s, :lval => transform(o.left_expr), :rval => transform(o.right_expr)
end

#transform_ConcatenatedString(o) ⇒ Object

Interpolated strings are kept in an array of AST (string or other expression).



421
422
423
# File 'lib/puppet/pops/model/ast_transformer.rb', line 421

def transform_ConcatenatedString(o)
  ast o, AST::Concat, :value => o.segments.collect {|x| transform(x)}
end

#transform_ExportedQuery(o) ⇒ Object



160
161
162
163
164
165
166
167
168
# File 'lib/puppet/pops/model/ast_transformer.rb', line 160

def transform_ExportedQuery(o)
  if is_nop?(o.expr)
    result = :exported
  else
    result = query(o.expr)
    result.form = :exported
  end
  result
end

#transform_Factory(o) ⇒ Object



91
92
93
# File 'lib/puppet/pops/model/ast_transformer.rb', line 91

def transform_Factory(o)
  transform(o.current)
end

#transform_HostClassDefinition(o) ⇒ Object



425
426
427
428
429
430
431
432
433
# File 'lib/puppet/pops/model/ast_transformer.rb', line 425

def transform_HostClassDefinition(o)
  parameters = o.parameters.collect {|p| transform(p) }
  args = {
    :arguments => parameters,
    :parent => o.parent_class,
  }
  args[:code] = transform(o.body) unless is_nop?(o.body)
  Puppet::Parser::AST::Hostclass.new(o.name, merge_location(args, o))
end

#transform_IfExpression(o) ⇒ Object



536
537
538
539
540
# File 'lib/puppet/pops/model/ast_transformer.rb', line 536

def transform_IfExpression(o)
  args = { :test => transform(o.test), :statements => transform(o.then_expr) }
  args[:else] = transform(o.else_expr) # Tests say Nop should be there (unless is_nop? o.else_expr), probably not needed
  ast o, AST::IfStatement, args
end

#transform_ImportExpression(o) ⇒ Object

This is a complex transformation from a modeled import to a Nop result (where the import took place), and calls to perform import/parsing etc. during the transformation. When testing syntax, the @importer does not have to be set, but it is not possible to check the actual import without inventing a new AST::ImportExpression with nop effect when evaluating.



258
259
260
261
262
263
264
265
266
267
268
269
270
271
# File 'lib/puppet/pops/model/ast_transformer.rb', line 258

def transform_ImportExpression(o)
  if importer
    o.files.each {|f|
      unless f.is_a? Model::LiteralString
        raise "Illegal import file expression. Must be a single quoted string"
      end
      importer.import(f.value)
    }
  end
  # Crazy stuff
  # Transformation of "import" needs to parse the other files at the time of transformation.
  # Then produce a :nop, since nothing should be evaluated.
  ast o, AST::Nop, {}
end

#transform_InExpression(o) ⇒ Object



250
251
252
# File 'lib/puppet/pops/model/ast_transformer.rb', line 250

def transform_InExpression(o)
  ast o, AST::InOperator, :lval => transform(o.left_expr), :rval => transform(o.right_expr)
end

#transform_InstanceReferences(o) ⇒ Object



273
274
275
# File 'lib/puppet/pops/model/ast_transformer.rb', line 273

def transform_InstanceReferences(o)
  ast o, AST::ResourceReference, :type => o.type_name.value, :title => transform(o.names)
end

#transform_KeyedEntry(o) ⇒ Object

Transforms entry into a hash (they are later merged with strange effects: Bug #19426). Puppet 3.x only allows:

  • NAME

  • quotedtext

As keys (quoted text can be an interpolated string which is compared as a key in a less than satisfactory way).



324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
# File 'lib/puppet/pops/model/ast_transformer.rb', line 324

def transform_KeyedEntry(o)
  value = transform(o.value)
  key = case o.key
  when Model::QualifiedName
    o.key.value
  when Model::LiteralString
    transform o.key
  when Model::LiteralNumber
    transform o.key
  when Model::ConcatenatedString
    transform o.key
  else
    raise "Illegal hash key expression of type (#{o.key.class})"
  end
  {key => value}
end

#transform_LambdaExpression(o) ⇒ Object



354
355
356
357
358
# File 'lib/puppet/pops/model/ast_transformer.rb', line 354

def transform_LambdaExpression(o)
  astargs = { :parameters => o.parameters.collect {|p| transform(p) } }
  astargs.merge!({ :children => transform(o.body) }) if o.body         # do not want children if it is nil/nop
  ast o, AST::Lambda, astargs
end

#transform_LiteralBoolean(o) ⇒ Object



87
88
89
# File 'lib/puppet/pops/model/ast_transformer.rb', line 87

def transform_LiteralBoolean(o)
  ast o, AST::Boolean, :value => o.value
end

#transform_LiteralDefault(o) ⇒ Object



360
361
362
# File 'lib/puppet/pops/model/ast_transformer.rb', line 360

def transform_LiteralDefault(o)
  ast o, AST::Default, :value => :default
end

#transform_LiteralHash(o) ⇒ Object

Literal hash has strange behavior in Puppet 3.1. See Bug #19426, and this implementation is bug compatible



308
309
310
311
312
313
314
315
316
# File 'lib/puppet/pops/model/ast_transformer.rb', line 308

def transform_LiteralHash(o)
  if o.entries.size == 0
    ast o, AST::ASTHash, {:value=> {}}
  else
    value = {}
    o.entries.each {|x| value.merge! transform(x) }
    ast o, AST::ASTHash, {:value=> value}
  end
end

#transform_LiteralList(o) ⇒ Object



301
302
303
304
# File 'lib/puppet/pops/model/ast_transformer.rb', line 301

def transform_LiteralList(o)
  # Uses default transform of Ruby Array to ASTArray
  transform(o.values)
end

#transform_LiteralNumber(o) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/puppet/pops/model/ast_transformer.rb', line 65

def transform_LiteralNumber(o)
  s = case o.radix
  when 10
    o.value.to_s
  when 8
    "0%o" % o.value
  when 16
    "0x%X" % o.value
  else
    "bad radix:" + o.value.to_s
  end

  # Numbers are Names in the AST !! (Name a.k.a BareWord)
  ast o, AST::Name, :value => s
end

#transform_LiteralRegularExpression(o) ⇒ Object



368
369
370
# File 'lib/puppet/pops/model/ast_transformer.rb', line 368

def transform_LiteralRegularExpression(o)
  ast o, AST::Regex, :value => o.value
end

#transform_LiteralString(o) ⇒ Object



345
346
347
# File 'lib/puppet/pops/model/ast_transformer.rb', line 345

def transform_LiteralString(o)
  ast o, AST::String, :value => o.value
end

#transform_LiteralText(o) ⇒ Object

Literal text in a concatenated string



350
351
352
# File 'lib/puppet/pops/model/ast_transformer.rb', line 350

def transform_LiteralText(o)
  ast o, AST::String, :value => o.value
end

#transform_LiteralUndef(o) ⇒ Object



364
365
366
# File 'lib/puppet/pops/model/ast_transformer.rb', line 364

def transform_LiteralUndef(o)
  ast o, AST::Undef, :value => :undef
end

#transform_LiteralValue(o) ⇒ Object

Transforms all literal values to string (override for those that should not be AST::String)



83
84
85
# File 'lib/puppet/pops/model/ast_transformer.rb', line 83

def transform_LiteralValue(o)
  ast o, AST::String, :value => o.value.to_s
end

#transform_MatchExpression(o) ⇒ Object



341
342
343
# File 'lib/puppet/pops/model/ast_transformer.rb', line 341

def transform_MatchExpression(o)
  ast o, AST::MatchOperator, :operator => o.operator.to_s, :lval => transform(o.left_expr), :rval => transform(o.right_expr)
end

#transform_NamedAccessExpression(o) ⇒ Object

In the 3.1. grammar this is a hash that is merged with other elements to form a method call Also in 3.1. grammar there are restrictions on the LHS (that are only there for grammar issues).



379
380
381
382
383
384
# File 'lib/puppet/pops/model/ast_transformer.rb', line 379

def transform_NamedAccessExpression(o)
  receiver = transform(o.left_expr)
  name = o.right_expr
  raise "Unacceptable function/method name" unless name.is_a? Model::QualifiedName
  {:receiver => receiver, :name => name.value}
end

#transform_NilClass(o) ⇒ Object



386
387
388
# File 'lib/puppet/pops/model/ast_transformer.rb', line 386

def transform_NilClass(o)
  ast o, AST::Nop, {}
end

#transform_NodeDefinition(o) ⇒ Object



435
436
437
438
439
440
441
442
443
444
445
446
447
# File 'lib/puppet/pops/model/ast_transformer.rb', line 435

def transform_NodeDefinition(o)
  # o.host_matches are expressions, and 3.1 AST requires special object AST::HostName
  # where a HostName is one of NAME, STRING, DEFAULT or Regexp - all of these are strings except regexp
  #
  args = {
    :code => transform(o.body)
  }
  args[:parent] = hostname(o.parent) unless is_nop?(o.parent)
  if(args[:parent].is_a?(Array))
    raise "Illegal expression - unacceptable as a node parent"
  end
  Puppet::Parser::AST::Node.new(hostname(o.host_matches), merge_location(args, o))
end

#transform_Nop(o) ⇒ Object



372
373
374
# File 'lib/puppet/pops/model/ast_transformer.rb', line 372

def transform_Nop(o)
  ast o, AST::Nop
end

#transform_NotExpression(o) ⇒ Object



390
391
392
# File 'lib/puppet/pops/model/ast_transformer.rb', line 390

def transform_NotExpression(o)
  ast o, AST::Not, :value => transform(o.expr)
end

#transform_Object(o) ⇒ Object



629
630
631
# File 'lib/puppet/pops/model/ast_transformer.rb', line 629

def transform_Object(o)
  raise "Unacceptable transform - found an Object without a rule: #{o.class}"
end

#transform_OrExpression(o) ⇒ Object



246
247
248
# File 'lib/puppet/pops/model/ast_transformer.rb', line 246

def transform_OrExpression(o)
  ast o, AST::BooleanOperator, :operator => 'or', :lval => transform(o.left_expr), :rval => transform(o.right_expr)
end

#transform_Parameter(o) ⇒ Object

Parameter is a parameter in a definition of some kind. It is transformed to an array on the form ‘[name]´, or `[name, value]´.



523
524
525
526
527
528
529
# File 'lib/puppet/pops/model/ast_transformer.rb', line 523

def transform_Parameter(o)
  if o.value
    [o.name, transform(o.value)]
  else
    [o.name]
  end
end

#transform_ParenthesizedExpression(o) ⇒ Object

For non query expressions, parentheses can be dropped in the resulting AST.



532
533
534
# File 'lib/puppet/pops/model/ast_transformer.rb', line 532

def transform_ParenthesizedExpression(o)
  transform(o.expr)
end

#transform_QualifiedName(o) ⇒ Object



230
231
232
# File 'lib/puppet/pops/model/ast_transformer.rb', line 230

def transform_QualifiedName(o)
  ast o, AST::Name, :value => o.value
end

#transform_QualifiedReference(o) ⇒ Object



234
235
236
# File 'lib/puppet/pops/model/ast_transformer.rb', line 234

def transform_QualifiedReference(o)
  ast o, AST::Type, :value => o.value
end

#transform_RelationshipExpression(o) ⇒ Object



478
479
480
# File 'lib/puppet/pops/model/ast_transformer.rb', line 478

def transform_RelationshipExpression(o)
  Puppet::Parser::AST::Relationship.new(transform(o.left_expr), transform(o.right_expr), o.operator.to_s, merge_location({}, o))
end

#transform_ResourceBody(o) ⇒ Object



592
593
594
595
# File 'lib/puppet/pops/model/ast_transformer.rb', line 592

def transform_ResourceBody(o)
  # expects AST, AST::ASTArray of AST
  ast o, AST::ResourceInstance, :title => transform(o.title), :parameters => transform(o.operations)
end

#transform_ResourceDefaultsExpression(o) ⇒ Object



597
598
599
# File 'lib/puppet/pops/model/ast_transformer.rb', line 597

def transform_ResourceDefaultsExpression(o)
  ast o, AST::ResourceDefaults, :type => o.type_ref.value, :parameters => transform(o.operations)
end

#transform_ResourceExpression(o) ⇒ Object

Transformation of ResourceExpression requires calling a method on the resulting AST::Resource if it is virtual or exported



604
605
606
607
608
609
# File 'lib/puppet/pops/model/ast_transformer.rb', line 604

def transform_ResourceExpression(o)
  raise "Unacceptable type name expression" unless o.type_name.is_a? Model::QualifiedName
  resource = ast o, AST::Resource, :type => o.type_name.value, :instances => transform(o.bodies)
  resource.send("#{o.form}=", true) unless o.form == :regular
  resource
end

#transform_ResourceOverrideExpression(o) ⇒ Object

Transformation of ResourceOverrideExpression is slightly more involved than a straight forward transformation. A ResourceOverrideExppression has “resources” which should be an AccessExpression on the form QualifiedName, or QualifiedReference to be valid. It also has a set of attribute operations.

The AST equivalence is an AST::ResourceOverride with a ResourceReference as its LHS, and a set of Parameters. ResourceReference has type as a string, and the expressions representing the “titles” to be an ASTArray.



501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
# File 'lib/puppet/pops/model/ast_transformer.rb', line 501

def transform_ResourceOverrideExpression(o)
  resource_ref = o.resources
  raise "Unacceptable expression for resource override" unless resource_ref.is_a? Model::AccessExpression

  type = case resource_ref.left_expr
  when Model::QualifiedName
    # This is deprecated "Resource references should now be capitalized" - this is caught elsewhere
    resource_ref.left_expr.value
  when Model::QualifiedReference
    resource_ref.left_expr.value
  else
    raise "Unacceptable expression for resource override; need NAME or CLASSREF"
  end

  result_ref = ast o, AST::ResourceReference, :type => type, :title => transform(resource_ref.keys)

  # title is one or more expressions, if more than one it should be an ASTArray
  ast o, AST::ResourceOverride, :object => result_ref, :parameters => transform(o.operations)
end

#transform_ResourceTypeDefinition(o) ⇒ Object



482
483
484
485
486
487
488
# File 'lib/puppet/pops/model/ast_transformer.rb', line 482

def transform_ResourceTypeDefinition(o)
  parameters = o.parameters.collect {|p| transform(p) }
  args = { :arguments => parameters }
  args[:code] = transform(o.body) unless is_nop?(o.body)

  Puppet::Parser::AST::Definition.new(o.name, merge_location(args, o))
end

#transform_SelectorEntry(o) ⇒ Object



625
626
627
# File 'lib/puppet/pops/model/ast_transformer.rb', line 625

def transform_SelectorEntry(o)
  ast o, AST::ResourceParam, :param => transform(o.matching_expr), :value => transform(o.value_expr)
end

#transform_SelectorExpression(o) ⇒ Object

Transformation of SelectorExpression is limited to certain types of expressions. This is probably due to constraints in the old grammar rather than any real concerns.



613
614
615
616
617
618
619
620
621
622
623
# File 'lib/puppet/pops/model/ast_transformer.rb', line 613

def transform_SelectorExpression(o)
  case o.left_expr
  when Model::CallNamedFunctionExpression
  when Model::AccessExpression
  when Model::VariableExpression
  when Model::ConcatenatedString
  else
    raise "Unacceptable select expression" unless o.left_expr.kind_of? Model::Literal
  end
  ast o, AST::Selector, :param => transform(o.left_expr), :values => transform(o.selectors)
end

#transform_TextExpression(o) ⇒ Object

In Puppet 3.1, the ConcatenatedString is responsible for the evaluation and stringification of expression segments. Expressions and Strings are kept in an array.



401
402
403
# File 'lib/puppet/pops/model/ast_transformer.rb', line 401

def transform_TextExpression(o)
  transform(o.expr)
end

#transform_UnaryMinusExpression(o) ⇒ Object



405
406
407
# File 'lib/puppet/pops/model/ast_transformer.rb', line 405

def transform_UnaryMinusExpression(o)
  ast o, AST::Minus, :value => transform(o.expr)
end

#transform_UnlessExpression(o) ⇒ Object

Unless is not an AST object, instead an AST::IfStatement is used with an AST::Not around the test



544
545
546
547
548
549
550
# File 'lib/puppet/pops/model/ast_transformer.rb', line 544

def transform_UnlessExpression(o)
  args = { :test => ast(o, AST::Not, :value => transform(o.test)),
    :statements => transform(o.then_expr) }
  # AST 3.1 does not allow else on unless in the grammar, but it is ok since unless is encoded as an if !x
  args.merge!({:else => transform(o.else_expr)}) unless is_nop?(o.else_expr)
  ast o, AST::IfStatement, args
end

#transform_VariableExpression(o) ⇒ Object



394
395
396
397
# File 'lib/puppet/pops/model/ast_transformer.rb', line 394

def transform_VariableExpression(o)
  # assumes the expression is a QualifiedName
  ast o, AST::Variable, :value => o.expr.value
end

#transform_VirtualQuery(o) ⇒ Object



170
171
172
173
174
175
176
177
178
# File 'lib/puppet/pops/model/ast_transformer.rb', line 170

def transform_VirtualQuery(o)
  if is_nop?(o.expr)
    result = :virtual
  else
    result = query(o.expr)
    result.form = :virtual
  end
  result
end