Class: Puppet::Pops::Types::PObjectType::PAnnotatedMember Abstract

Inherits:
Object
  • Object
show all
Includes:
Annotatable, InvocableMember
Defined in:
lib/puppet/pops/types/p_object_type.rb

Overview

This class is abstract.

Encapsulates behavior common to PAttribute and PFunction

Direct Known Subclasses

PAttribute, PFunction

Constant Summary

Constants included from Annotatable

Annotatable::TYPE_ANNOTATIONS

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Annotatable

#annotatable_accept, #annotations, #init_annotatable

Constructor Details

#initialize(name, container, init_hash) ⇒ PAnnotatedMember

Returns a new instance of PAnnotatedMember.

Parameters:

  • name (String)

    The name of the member

  • container (PObjectType)

    The containing object type

  • init_hash (Hash{String=>Object})

    Hash containing feature options

Options Hash (init_hash):

  • 'type' (PAnyType)

    The member type (required)

  • 'override' (Boolean)

    ‘true` if this feature must override an inherited feature. Default is `false`.

  • 'final' (Boolean)

    ‘true` if this feature cannot be overridden. Default is `false`.

  • 'annotations' (Hash{PTypeType => Hash})

    Annotations hash. Default is ‘nil`.



126
127
128
129
130
131
132
133
134
135
# File 'lib/puppet/pops/types/p_object_type.rb', line 126

def initialize(name, container, init_hash)
  @name = name
  @container = container
  @type = init_hash[KEY_TYPE]
  @override = init_hash[KEY_OVERRIDE]
  @override = false if @override.nil?
  @final = init_hash[KEY_FINAL]
  @final = false if @final.nil?
  init_annotatable(init_hash)
end

Instance Attribute Details

#containerPObjectType (readonly)

Returns the object type containing this member.

Returns:

  • (PObjectType)

    the object type containing this member



108
109
110
# File 'lib/puppet/pops/types/p_object_type.rb', line 108

def container
  @container
end

#nameString (readonly)

Returns the name of this member.

Returns:

  • (String)

    the name of this member



112
113
114
# File 'lib/puppet/pops/types/p_object_type.rb', line 112

def name
  @name
end

#typePAnyType (readonly)

Returns the type of this member.

Returns:

  • (PAnyType)

    the type of this member



116
117
118
# File 'lib/puppet/pops/types/p_object_type.rb', line 116

def type
  @type
end

Class Method Details

.feature_typeObject

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.

Raises:

  • (NotImplementedError)


274
275
276
# File 'lib/puppet/pops/types/p_object_type.rb', line 274

def self.feature_type
  raise NotImplementedError, "'#{self.class.name}' should implement #feature_type"
end

.label(container, name) ⇒ Object



278
279
280
# File 'lib/puppet/pops/types/p_object_type.rb', line 278

def self.label(container, name)
  "#{feature_type} #{container.label}[#{name}]"
end

Instance Method Details

#==(o) ⇒ Object



217
218
219
# File 'lib/puppet/pops/types/p_object_type.rb', line 217

def ==(o)
  eql?(o)
end

#_pcore_init_hashHash{String=>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.

Returns the member as a hash suitable as an argument for constructor. Name is excluded

Returns:

  • (Hash{String=>Object})

    the initialization hash



224
225
226
227
228
229
230
# File 'lib/puppet/pops/types/p_object_type.rb', line 224

def _pcore_init_hash
  hash = { KEY_TYPE => @type }
  hash[KEY_FINAL] = true if @final
  hash[KEY_OVERRIDE] = true if @override
  hash[KEY_ANNOTATIONS] = @annotations unless @annotations.nil?
  hash
end

#accept(visitor, guard) ⇒ Object

Delegates to the contained type

Parameters:



141
142
143
144
# File 'lib/puppet/pops/types/p_object_type.rb', line 141

def accept(visitor, guard)
  annotatable_accept(visitor, guard)
  @type.accept(visitor, guard)
end

#assert_can_be_overridden(member) ⇒ PAnnotatedMember

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.

Checks if the given member can override this member.

Parameters:

Returns:



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/puppet/pops/types/p_object_type.rb', line 172

def assert_can_be_overridden(member)
  unless instance_of?(member.class)
    raise Puppet::ParseError, _("%{member} attempts to override %{label}") % { member: member.label, label: label }
  end
  if @final && !(constant? && member.constant?)
    raise Puppet::ParseError, _("%{member} attempts to override final %{label}") % { member: member.label, label: label }
  end
  unless member.override?
    # TRANSLATOR 'override => true' is a puppet syntax and should not be translated
    raise Puppet::ParseError, _("%{member} attempts to override %{label} without having override => true") % { member: member.label, label: label }
  end
  unless @type.assignable?(member.type)
    raise Puppet::ParseError, _("%{member} attempts to override %{label} with a type that does not match") % { member: member.label, label: label }
  end

  member
end

#assert_override(parent_members) ⇒ PAnnotatedMember

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.

Checks if the this member overrides an inherited member, and if so, that this member is declared with override = true and that the inherited member accepts to be overridden by this member.

Parameters:

  • parent_members (Hash{String=>PAnnotatedMember})

    the hash of inherited members

Returns:



153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/puppet/pops/types/p_object_type.rb', line 153

def assert_override(parent_members)
  parent_member = parent_members[@name]
  if parent_member.nil?
    if @override
      raise Puppet::ParseError, _("expected %{label} to override an inherited %{feature_type}, but no such %{feature_type} was found") %
                                { label: label, feature_type: feature_type }
    end
    self
  else
    parent_member.assert_can_be_overridden(self)
  end
end

#constant?Boolean

Returns:

  • (Boolean)


190
191
192
# File 'lib/puppet/pops/types/p_object_type.rb', line 190

def constant?
  false
end

#create_dispatch(instance) ⇒ 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.



262
263
264
265
266
267
268
269
270
271
# File 'lib/puppet/pops/types/p_object_type.rb', line 262

def create_dispatch(instance)
  # TODO: Assumes Ruby implementation for now
  if callable_type.is_a?(PVariantType)
    callable_type.types.map do |ct|
      Functions::Dispatch.new(ct, RubyGenerator.protect_reserved_name(name), [], false, ct.block_type.nil? ? nil : 'block')
    end
  else
    [Functions::Dispatch.new(callable_type, RubyGenerator.protect_reserved_name(name), [], false, callable_type.block_type.nil? ? nil : 'block')]
  end
end

#eql?(o) ⇒ Boolean

Returns:

  • (Boolean)


212
213
214
# File 'lib/puppet/pops/types/p_object_type.rb', line 212

def eql?(o)
  self.class == o.class && @name == o.name && @type == o.type && @override == o.override? && @final == o.final?
end

#feature_typeObject

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.



233
234
235
# File 'lib/puppet/pops/types/p_object_type.rb', line 233

def feature_type
  self.class.feature_type
end

#final?Boolean

Returns ‘true` if this feature cannot be overridden.

Returns:

  • (Boolean)

    ‘true` if this feature cannot be overridden



196
197
198
# File 'lib/puppet/pops/types/p_object_type.rb', line 196

def final?
  @final
end

#hashObject



207
208
209
# File 'lib/puppet/pops/types/p_object_type.rb', line 207

def hash
  @name.hash ^ @type.hash
end

#invoke(receiver, scope, args, &block) ⇒ 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.

Performs type checking of arguments and invokes the method that corresponds to this method. The result of the invocation is returned

Parameters:

  • receiver (Object)

    The receiver of the call

  • scope (Puppet::Parser::Scope)

    The caller scope

  • args (Array)

    Array of arguments.

Returns:

  • (Object)

    The result returned by the member function or attribute

Raises:

  • (ArgumentError)


251
252
253
254
255
256
257
258
259
# File 'lib/puppet/pops/types/p_object_type.rb', line 251

def invoke(receiver, scope, args, &block)
  @dispatch ||= create_dispatch(receiver)

  args_type = TypeCalculator.infer_set(block_given? ? args + [block] : args)
  found = @dispatch.find { |d| d.type.callable?(args_type) }
  raise ArgumentError, TypeMismatchDescriber.describe_signatures(label, @dispatch, args_type) if found.nil?

  found.invoke(receiver, scope, args, &block)
end

#labelObject

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.



238
239
240
# File 'lib/puppet/pops/types/p_object_type.rb', line 238

def label
  self.class.label(@container, @name)
end

#override?Boolean

Returns ‘true` if this feature must override an inherited feature.

Returns:

  • (Boolean)

    ‘true` if this feature must override an inherited feature



202
203
204
# File 'lib/puppet/pops/types/p_object_type.rb', line 202

def override?
  @override
end