Class: Puppet::Pops::Loader::TypeDefinitionInstantiator

Inherits:
Object
  • Object
show all
Defined in:
lib/puppet/pops/loader/type_definition_instantiator.rb

Class Method Summary collapse

Class Method Details

.create(loader, typed_name, source_ref, pp_code_string) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/puppet/pops/loader/type_definition_instantiator.rb', line 6

def self.create(loader, typed_name, source_ref, pp_code_string)
  # parse and validate
  parser = Parser::EvaluatingParser.new()
  model = parser.parse_string(pp_code_string, source_ref)
  # Only one type is allowed (and no other definitions)

  name = typed_name.name
  case model.definitions.size
  when 0
    raise ArgumentError, _("The code loaded from %{source_ref} does not define the type '%{name}' - it is empty.") % { source_ref: source_ref, name: name }
  when 1
    # ok
  else
    raise ArgumentError,
      _("The code loaded from %{source_ref} must contain only the type '%{name}' - it has additional definitions.") % { source_ref: source_ref, name: name }
  end
  type_definition = model.definitions[0]

  unless type_definition.is_a?(Model::TypeAlias) || type_definition.is_a?(Model::TypeDefinition)
    raise ArgumentError,
      _("The code loaded from %{source_ref} does not define the type '%{name}' - no type alias or type definition found.") % { source_ref: source_ref, name: name }
  end

  actual_name = type_definition.name
  unless name == actual_name.downcase
    raise ArgumentError,
      _("The code loaded from %{source_ref} produced type with the wrong name, expected '%{name}', actual '%{actual_name}'") % { source_ref: source_ref, name: name, actual_name: actual_name }
  end

  unless model.body == type_definition
    raise ArgumentError,
      _("The code loaded from %{source_ref} contains additional logic - can only contain the type '%{name}'") % { source_ref: source_ref, name: name }
  end

  # Adapt the type definition with loader - this is used from logic contained in its body to find the
  # loader to use when resolving contained aliases API. Such logic have a hard time finding the closure (where
  # the loader is known - hence this mechanism
  private_loader = loader.private_loader
  Adapters::LoaderAdapter.adapt(type_definition).loader_name = private_loader.loader_name
  create_runtime_type(type_definition)
end

.create_from_model(type_definition, loader) ⇒ Object



48
49
50
51
52
53
54
55
56
# File 'lib/puppet/pops/loader/type_definition_instantiator.rb', line 48

def self.create_from_model(type_definition, loader)
  typed_name = TypedName.new(:type, type_definition.name)
  type = create_runtime_type(type_definition)
  loader.set_entry(
    typed_name,
    type,
    type_definition.locator.to_uri(type_definition))
  type
end

.create_named_type(name, type_name, type_expr, name_authority) ⇒ 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.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/puppet/pops/loader/type_definition_instantiator.rb', line 72

def self.create_named_type(name, type_name, type_expr, name_authority)
  case type_name
  when 'Object'
    # No need for an alias. The Object type itself will receive the name instead
    type_expr = type_expr.keys.empty? ? nil : type_expr.keys[0] unless type_expr.is_a?(Hash)
    Types::PObjectType.new(name, type_expr)
  when 'TypeSet'
    # No need for an alias. The Object type itself will receive the name instead
    type_expr = type_expr.keys.empty? ? nil : type_expr.keys[0] unless type_expr.is_a?(Hash)
    Types::PTypeSetType.new(name, type_expr, name_authority)
  else
    Types::PTypeAliasType.new(name, type_expr)
  end
end

.create_runtime_type(type_definition) ⇒ 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.



59
60
61
62
63
64
# File 'lib/puppet/pops/loader/type_definition_instantiator.rb', line 59

def self.create_runtime_type(type_definition)
  # Using the RUNTIME_NAME_AUTHORITY as the name_authority is motivated by the fact that the type
  # alias name (managed by the runtime) becomes the name of the created type
  #
  create_type(type_definition.name, type_definition.type_expr, Pcore::RUNTIME_NAME_AUTHORITY)
end

.create_type(name, type_expr, name_authority) ⇒ 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.



67
68
69
# File 'lib/puppet/pops/loader/type_definition_instantiator.rb', line 67

def self.create_type(name, type_expr, name_authority)
  create_named_type(name, named_definition(type_expr), type_expr, name_authority)
end

.named_definition(te) ⇒ 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.



88
89
90
# File 'lib/puppet/pops/loader/type_definition_instantiator.rb', line 88

def self.named_definition(te)
  te.is_a?(Model::AccessExpression) && (left = te.left_expr).is_a?(Model::QualifiedReference) ? left.cased_value : nil
end