class Wrapture::TypeSpec

A description of a type used in a specification.

Public Class Methods

new(spec = 'void') click to toggle source

Creates a parameter specification based on the provided hash spec. spec can be a string instead of a hash, in which case it will be used as the name of the type.

Type specs must have a 'name' key with either the type itself (for example 'const char *') or a keyword specifying some other type (for example 'equivalent-struct'). The only exception is for function pointers, which instead use a 'function' key that contains a FunctionSpec specification. This specification does not need to be definable, it only needs to have a parameter list and return type for the signature to be clear.

# File lib/wrapture/type_spec.rb, line 47
def initialize(spec = 'void')
  actual_spec = if spec.is_a?(String)
                  { 'name' => spec }
                else
                  spec
                end

  @spec = TypeSpec.normalize_spec_hash(actual_spec)
end
normalize_spec_hash(spec) click to toggle source

Returns a normalized copy of the hash specification of a type in spec. See normalize_spec_hash! for details.

# File lib/wrapture/type_spec.rb, line 26
def self.normalize_spec_hash(spec)
  normalize_spec_hash!(Marshal.load(Marshal.dump(spec)))
end
normalize_spec_hash!(spec) click to toggle source

Normalizes the hash specification of a type in spec in place. This will normalize the include list.

# File lib/wrapture/type_spec.rb, line 32
def self.normalize_spec_hash!(spec)
  spec['includes'] = Wrapture.normalize_includes(spec['includes'])
  spec
end

Public Instance Methods

==(other) click to toggle source

Compares this TypeSpec with other. Comparison happens by converting each object to a string using to_s and comparing.

Added in release 0.4.2.

# File lib/wrapture/type_spec.rb, line 61
def ==(other)
  to_s == other.to_s
end
base() click to toggle source

The name of this type with all special characters removed.

# File lib/wrapture/type_spec.rb, line 66
def base
  name.delete('*&').strip
end
cast_expression(expression) click to toggle source

An expression casting the result of a given expression into this type.

Added in release 0.4.2.

# File lib/wrapture/type_spec.rb, line 73
def cast_expression(expression)
  "( #{variable} )( #{expression} )"
end
equivalent_pointer?() click to toggle source

True if this type is an equivalent struct pointer reference.

# File lib/wrapture/type_spec.rb, line 78
def equivalent_pointer?
  name == EQUIVALENT_POINTER_KEYWORD
end
equivalent_struct?() click to toggle source

True if this type is an equivalent struct reference.

# File lib/wrapture/type_spec.rb, line 83
def equivalent_struct?
  name == EQUIVALENT_STRUCT_KEYWORD
end
function?() click to toggle source

True if this type is a function.

# File lib/wrapture/type_spec.rb, line 88
def function?
  @spec.key?('function')
end
includes() click to toggle source

A list of includes needed for this type.

# File lib/wrapture/type_spec.rb, line 93
def includes
  includes = @spec['includes'].dup

  if function?
    func = FunctionSpec.new(@spec['function'])
    includes.concat(func.declaration_includes)
  end

  includes.uniq
end
name() click to toggle source

The name of the type.

# File lib/wrapture/type_spec.rb, line 105
def name
  @spec['name']
end
pointer?() click to toggle source

True if this type is a pointer.

# File lib/wrapture/type_spec.rb, line 110
def pointer?
  name.end_with?('*')
end
resolve(owner) click to toggle source

Creates a new TypeSpec within the scope of owner that will be directly usable. This will replace equivalent structs, pointers, and self references with a usable type name.

# File lib/wrapture/type_spec.rb, line 117
def resolve(owner)
  owner.resolve_type(self)
end
return_expression(func, func_name: func.name) click to toggle source

A string with a declaration of FunctionSpec func with this type as the return value. func_name can be provided to override the function name, for example if a class name needs to be included.

# File lib/wrapture/type_spec.rb, line 124
def return_expression(func, func_name: func.name)
  name_part = String.new(func_name || '')
  param_part = String.new
  ret_part = name

  current_spec = @spec
  while current_spec.is_a?(Hash) && current_spec.key?('function')
    name_part.prepend('( *')

    current_func = FunctionSpec.new(current_spec['function'])
    param_part.concat(" )( #{current_func.param_list} )")

    current_spec = current_spec.dig('function', 'return', 'type')
    ret_part = current_spec
  end

  ret_part << ' ' unless ret_part.end_with?('*')

  "#{ret_part}#{name_part}( #{func.param_list} )#{param_part}"
end
self?() click to toggle source

True if this type is a reference to a class instance.

# File lib/wrapture/type_spec.rb, line 146
def self?
  name == SELF_REFERENCE_KEYWORD
end
to_s() click to toggle source

Gives a string representation of this type (its name).

Added in release 0.4.2.

# File lib/wrapture/type_spec.rb, line 153
def to_s
  name
end
variable(var_name = nil) click to toggle source

A string with a declaration of a variable named var_name of this type. If var_name is nil then this will simply be a type declaration.

# File lib/wrapture/type_spec.rb, line 159
def variable(var_name = nil)
  if variadic?
    '...'
  elsif function?
    func = FunctionSpec.new(@spec['function'])
    func_name = "( *#{var_name} )" || '(*)'
    func.return_expression(func_name: func_name)
  elsif var_name.nil?
    name
  else
    "#{name}#{' ' unless name.end_with?('*')}#{var_name}"
  end
end
variadic?() click to toggle source

True if this type is a variadic parameter type (name is equal to ...).

# File lib/wrapture/type_spec.rb, line 174
def variadic?
  name == '...'
end