Method: Puppet::Pops::Loader::TypeDefinitionInstantiator.create

Defined in:
lib/puppet/pops/loader/type_definition_instantiator.rb

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



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
47
48
# File 'lib/puppet/pops/loader/type_definition_instantiator.rb', line 8

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