Logo Search packages:      
Sourcecode: vala version File versions

valadatatype.c

/* valatype.vala
 *
 * Copyright (C) 2006-2007  Jürg Billeter, Raffaele Sandrini
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.

 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 *
 * Author:
 *    Jürg Billeter <j@bitron.ch>
 *    Raffaele Sandrini <rasa@gmx.ch>
 */

#include "valadatatype.h"
#include <gee/arraylist.h>
#include <gee/list.h>
#include <gee/map.h>
#include <gee/readonlycollection.h>
#include <gee/hashmap.h>
#include <vala/valapointer.h>
#include <vala/valadatatype.h>
#include <vala/valasourcereference.h>
#include <vala/valasourcefile.h>
#include <vala/valascope.h>
#include <vala/valaarray.h>

struct _ValaDataTypePrivate {
      GeeList* cheader_filenames;
      ValaPointer* pointer_type;
      GeeMap* array_types;
};
#define VALA_DATA_TYPE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), VALA_TYPE_DATA_TYPE, ValaDataTypePrivate))
enum  {
      VALA_DATA_TYPE_DUMMY_PROPERTY
};
static gboolean vala_data_type_real_is_reference_type (ValaDataType* self);
static char* vala_data_type_real_get_dup_function (ValaDataType* self);
static char* vala_data_type_real_get_free_function (ValaDataType* self);
static gboolean vala_data_type_real_is_reference_counting (ValaDataType* self);
static char* vala_data_type_real_get_ref_function (ValaDataType* self);
static char* vala_data_type_real_get_unref_function (ValaDataType* self);
static char* vala_data_type_real_get_type_id (ValaDataType* self);
static char* vala_data_type_real_get_marshaller_type_name (ValaDataType* self);
static char* vala_data_type_real_get_get_value_function (ValaDataType* self);
static char* vala_data_type_real_get_set_value_function (ValaDataType* self);
static char* vala_data_type_real_get_upper_case_cname (ValaDataType* self, const char* infix);
static char* vala_data_type_real_get_default_value (ValaDataType* self);
static GeeCollection* vala_data_type_real_get_cheader_filenames (ValaSymbol* base);
static gboolean vala_data_type_real_is_subtype_of (ValaDataType* self, ValaDataType* t);
static gint vala_data_type_real_get_type_parameter_index (ValaDataType* self, const char* name);
static gpointer vala_data_type_parent_class = NULL;
static void vala_data_type_dispose (GObject * obj);


char* vala_data_type_get_cname (ValaDataType* self, gboolean const_type)
{
      return VALA_DATA_TYPE_GET_CLASS (self)->get_cname (self, const_type);
}


/**
 * Checks whether this data type has value or reference type semantics.
 *
 * @return true if this data type has reference type semantics
 */
static gboolean vala_data_type_real_is_reference_type (ValaDataType* self)
{
      g_return_val_if_fail (VALA_IS_DATA_TYPE (self), FALSE);
      return FALSE;
}


gboolean vala_data_type_is_reference_type (ValaDataType* self)
{
      return VALA_DATA_TYPE_GET_CLASS (self)->is_reference_type (self);
}


/**
 * Returns the C function name that duplicates instances of this data
 * type. The specified C function must accept one argument referencing
 * the instance of this data type and return a reference to the
 * duplicate.
 *
 * @return the name of the C function if supported or null otherwise
 */
static char* vala_data_type_real_get_dup_function (ValaDataType* self)
{
      g_return_val_if_fail (VALA_IS_DATA_TYPE (self), NULL);
      return NULL;
}


char* vala_data_type_get_dup_function (ValaDataType* self)
{
      return VALA_DATA_TYPE_GET_CLASS (self)->get_dup_function (self);
}


/**
 * Returns the C function name that frees instances of this data type.
 * This is only valid for data types with reference type semantics that
 * do not support reference counting. The specified C function must
 * accept one argument pointing to the instance to be freed.
 *
 * @return the name of the C function or null if this data type is not a
 *         reference type or if it supports reference counting
 */
static char* vala_data_type_real_get_free_function (ValaDataType* self)
{
      g_return_val_if_fail (VALA_IS_DATA_TYPE (self), NULL);
      return NULL;
}


char* vala_data_type_get_free_function (ValaDataType* self)
{
      return VALA_DATA_TYPE_GET_CLASS (self)->get_free_function (self);
}


/**
 * Checks whether this data type supports reference counting. This is
 * only valid for reference types.
 *
 * @return true if this data type supports reference counting
 */
static gboolean vala_data_type_real_is_reference_counting (ValaDataType* self)
{
      g_return_val_if_fail (VALA_IS_DATA_TYPE (self), FALSE);
      return FALSE;
}


gboolean vala_data_type_is_reference_counting (ValaDataType* self)
{
      return VALA_DATA_TYPE_GET_CLASS (self)->is_reference_counting (self);
}


/**
 * Returns the C function name that increments the reference count of
 * instances of this data type. This is only valid for data types
 * supporting reference counting. The specified C function must accept
 * one argument referencing the instance of this data type and return
 * the reference.
 *
 * @return the name of the C function or null if this data type does not
 *         support reference counting
 */
static char* vala_data_type_real_get_ref_function (ValaDataType* self)
{
      g_return_val_if_fail (VALA_IS_DATA_TYPE (self), NULL);
      return NULL;
}


char* vala_data_type_get_ref_function (ValaDataType* self)
{
      return VALA_DATA_TYPE_GET_CLASS (self)->get_ref_function (self);
}


/**
 * Returns the C function name that decrements the reference count of
 * instances of this data type. This is only valid for data types
 * supporting reference counting. The specified C function must accept
 * one argument referencing the instance of this data type.
 *
 * @return the name of the C function or null if this data type does not
 *         support reference counting
 */
static char* vala_data_type_real_get_unref_function (ValaDataType* self)
{
      g_return_val_if_fail (VALA_IS_DATA_TYPE (self), NULL);
      return NULL;
}


char* vala_data_type_get_unref_function (ValaDataType* self)
{
      return VALA_DATA_TYPE_GET_CLASS (self)->get_unref_function (self);
}


/**
 * Returns the C symbol representing the runtime type id for this data
 * type. The specified symbol must express a registered GType.
 *
 * @return the name of the GType name in C code or null if this data
 *         type is not registered with GType
 */
static char* vala_data_type_real_get_type_id (ValaDataType* self)
{
      g_return_val_if_fail (VALA_IS_DATA_TYPE (self), NULL);
      return NULL;
}


char* vala_data_type_get_type_id (ValaDataType* self)
{
      return VALA_DATA_TYPE_GET_CLASS (self)->get_type_id (self);
}


/**
 * Returns the name of this data type as used in C code marshallers
 *
 * @return type name for marshallers
 */
static char* vala_data_type_real_get_marshaller_type_name (ValaDataType* self)
{
      g_return_val_if_fail (VALA_IS_DATA_TYPE (self), NULL);
      return NULL;
}


char* vala_data_type_get_marshaller_type_name (ValaDataType* self)
{
      return VALA_DATA_TYPE_GET_CLASS (self)->get_marshaller_type_name (self);
}


/**
 * Returns the cname of the GValue getter function,
 */
static char* vala_data_type_real_get_get_value_function (ValaDataType* self)
{
      g_return_val_if_fail (VALA_IS_DATA_TYPE (self), NULL);
      return NULL;
}


char* vala_data_type_get_get_value_function (ValaDataType* self)
{
      return VALA_DATA_TYPE_GET_CLASS (self)->get_get_value_function (self);
}


/**
 * Returns the cname of the GValue setter function,
 */
static char* vala_data_type_real_get_set_value_function (ValaDataType* self)
{
      g_return_val_if_fail (VALA_IS_DATA_TYPE (self), NULL);
      return NULL;
}


char* vala_data_type_get_set_value_function (ValaDataType* self)
{
      return VALA_DATA_TYPE_GET_CLASS (self)->get_set_value_function (self);
}


/**
 * Returns the C name of this data type in upper case. Words are
 * separated by underscores. The upper case C name of the namespace is
 * prefix of the result.
 *
 * @param infix a string to be placed between namespace and data type
 *              name or null
 * @return      the upper case name to be used in C code
 */
static char* vala_data_type_real_get_upper_case_cname (ValaDataType* self, const char* infix)
{
      g_return_val_if_fail (VALA_IS_DATA_TYPE (self), NULL);
      return NULL;
}


char* vala_data_type_get_upper_case_cname (ValaDataType* self, const char* infix)
{
      return VALA_DATA_TYPE_GET_CLASS (self)->get_upper_case_cname (self, infix);
}


/**
 * Returns the default value for the given type. Returning null means
 * there is no default value (i.e. not that the default name is NULL).
 *
 * @returnthe name of the default value
 */
static char* vala_data_type_real_get_default_value (ValaDataType* self)
{
      g_return_val_if_fail (VALA_IS_DATA_TYPE (self), NULL);
      return NULL;
}


char* vala_data_type_get_default_value (ValaDataType* self)
{
      return VALA_DATA_TYPE_GET_CLASS (self)->get_default_value (self);
}


static GeeCollection* vala_data_type_real_get_cheader_filenames (ValaSymbol* base)
{
      ValaDataType * self;
      self = ((ValaDataType*) base);
      if (gee_collection_get_size (((GeeCollection*) self->priv->cheader_filenames)) == 0) {
            {
                  GeeCollection* filename_collection;
                  GeeIterator* filename_it;
                  filename_collection = vala_symbol_get_cheader_filenames (vala_symbol_get_parent_symbol (((ValaSymbol*) self)));
                  filename_it = gee_iterable_iterator (GEE_ITERABLE (filename_collection));
                  while (gee_iterator_next (filename_it)) {
                        char* filename;
                        filename = gee_iterator_get (filename_it);
                        {
                              /* default to header filenames of the namespace */
                              vala_data_type_add_cheader_filename (self, filename);
                              (filename = (g_free (filename), NULL));
                        }
                  }
                  (filename_collection == NULL ? NULL : (filename_collection = (g_object_unref (filename_collection), NULL)));
                  (filename_it == NULL ? NULL : (filename_it = (g_object_unref (filename_it), NULL)));
            }
            if (gee_collection_get_size (((GeeCollection*) self->priv->cheader_filenames)) == 0 && vala_code_node_get_source_reference (((ValaCodeNode*) self)) != NULL && !vala_source_file_get_pkg (vala_source_reference_get_file (vala_code_node_get_source_reference (((ValaCodeNode*) self))))) {
                  char* __temp12;
                  /* don't add default include directives for VAPI files*/
                  __temp12 = NULL;
                  gee_collection_add (GEE_COLLECTION (self->priv->cheader_filenames), (__temp12 = vala_source_file_get_cinclude_filename (vala_source_reference_get_file (vala_code_node_get_source_reference (((ValaCodeNode*) self))))));
                  (__temp12 = (g_free (__temp12), NULL));
            }
      }
      return GEE_COLLECTION (gee_read_only_collection_new (g_strdup, g_free, GEE_COLLECTION (self->priv->cheader_filenames)));
}


/**
 * Adds a filename to the list of C header filenames users of this data
 * type must include.
 *
 * @param filename a C header filename
 */
void vala_data_type_add_cheader_filename (ValaDataType* self, const char* filename)
{
      g_return_if_fail (VALA_IS_DATA_TYPE (self));
      g_return_if_fail (filename != NULL);
      gee_collection_add (GEE_COLLECTION (self->priv->cheader_filenames), filename);
}


/**
 * Returns the pointer type of this data type.
 *
 * @return pointer-type for this data type
 */
ValaPointer* vala_data_type_get_pointer (ValaDataType* self)
{
      ValaPointer* __temp15;
      g_return_val_if_fail (VALA_IS_DATA_TYPE (self), NULL);
      if (self->priv->pointer_type == NULL) {
            ValaPointer* __temp14;
            __temp14 = NULL;
            self->priv->pointer_type = (__temp14 = vala_pointer_new (self, vala_code_node_get_source_reference (((ValaCodeNode*) self))), (self->priv->pointer_type == NULL ? NULL : (self->priv->pointer_type = (g_object_unref (self->priv->pointer_type), NULL))), __temp14);
            /* create a new Symbol */
            vala_scope_add (vala_symbol_get_scope (vala_symbol_get_parent_symbol (((ValaSymbol*) self))), vala_symbol_get_name (((ValaSymbol*) self->priv->pointer_type)), VALA_SYMBOL (self->priv->pointer_type));
            /* link the namespace */
            vala_symbol_set_owner (VALA_SYMBOL (self->priv->pointer_type), vala_symbol_get_scope (vala_symbol_get_parent_symbol (((ValaSymbol*) self))));
      }
      __temp15 = NULL;
      return (__temp15 = self->priv->pointer_type, (__temp15 == NULL ? NULL : g_object_ref (__temp15)));
}


/**
 * Returns the array type for elements of this data type.
 *
 * @param rank the rank the array should be of
 * @return array type for this data type
 */
ValaArray* vala_data_type_get_array (ValaDataType* self, gint rank)
{
      ValaArray* array_type;
      g_return_val_if_fail (VALA_IS_DATA_TYPE (self), NULL);
      array_type = NULL;
      if (self->priv->array_types != NULL) {
            ValaArray* __temp17;
            __temp17 = NULL;
            array_type = (__temp17 = gee_map_get (((GeeMap*) self->priv->array_types), GINT_TO_POINTER (rank)), (array_type == NULL ? NULL : (array_type = (g_object_unref (array_type), NULL))), __temp17);
      }
      if (array_type == NULL) {
            ValaArray* new_array_type;
            ValaArrayLengthField* __temp20;
            ValaArrayLengthField* __temp19;
            ValaArrayResizeMethod* __temp22;
            ValaArrayResizeMethod* __temp21;
            ValaArrayMoveMethod* __temp24;
            ValaArrayMoveMethod* __temp23;
            ValaArray* __temp26;
            ValaArray* __temp25;
            if (self->priv->array_types == NULL) {
                  GeeMap* __temp18;
                  __temp18 = NULL;
                  self->priv->array_types = (__temp18 = GEE_MAP (gee_hash_map_new (NULL, NULL, g_object_ref, g_object_unref, g_direct_hash, g_direct_equal, g_direct_equal)), (self->priv->array_types == NULL ? NULL : (self->priv->array_types = (g_object_unref (self->priv->array_types), NULL))), __temp18);
            }
            new_array_type = vala_array_new (self, rank, vala_code_node_get_source_reference (((ValaCodeNode*) self)));
            vala_scope_add (vala_symbol_get_scope (vala_symbol_get_parent_symbol (((ValaSymbol*) self))), vala_symbol_get_name (((ValaSymbol*) new_array_type)), VALA_SYMBOL (new_array_type));
            /* add internal length field */
            __temp20 = NULL;
            __temp19 = NULL;
            vala_scope_add (vala_symbol_get_scope (((ValaSymbol*) new_array_type)), vala_symbol_get_name (((ValaSymbol*) (__temp19 = vala_array_get_length_field (new_array_type)))), VALA_SYMBOL ((__temp20 = vala_array_get_length_field (new_array_type))));
            (__temp20 == NULL ? NULL : (__temp20 = (g_object_unref (__temp20), NULL)));
            (__temp19 == NULL ? NULL : (__temp19 = (g_object_unref (__temp19), NULL)));
            /* add internal resize method */
            __temp22 = NULL;
            __temp21 = NULL;
            vala_scope_add (vala_symbol_get_scope (((ValaSymbol*) new_array_type)), vala_symbol_get_name (((ValaSymbol*) (__temp21 = vala_array_get_resize_method (new_array_type)))), VALA_SYMBOL ((__temp22 = vala_array_get_resize_method (new_array_type))));
            (__temp22 == NULL ? NULL : (__temp22 = (g_object_unref (__temp22), NULL)));
            (__temp21 == NULL ? NULL : (__temp21 = (g_object_unref (__temp21), NULL)));
            /* add internal move method */
            __temp24 = NULL;
            __temp23 = NULL;
            vala_scope_add (vala_symbol_get_scope (((ValaSymbol*) new_array_type)), vala_symbol_get_name (((ValaSymbol*) (__temp23 = vala_array_get_move_method (new_array_type)))), VALA_SYMBOL ((__temp24 = vala_array_get_move_method (new_array_type))));
            (__temp24 == NULL ? NULL : (__temp24 = (g_object_unref (__temp24), NULL)));
            (__temp23 == NULL ? NULL : (__temp23 = (g_object_unref (__temp23), NULL)));
            /* link the array type to the same source as the container type */
            vala_code_node_set_source_reference (VALA_CODE_NODE (new_array_type), vala_code_node_get_source_reference (((ValaCodeNode*) self)));
            gee_map_set (((GeeMap*) self->priv->array_types), GINT_TO_POINTER (rank), new_array_type);
            __temp26 = NULL;
            __temp25 = NULL;
            array_type = (__temp26 = (__temp25 = new_array_type, (__temp25 == NULL ? NULL : g_object_ref (__temp25))), (array_type == NULL ? NULL : (array_type = (g_object_unref (array_type), NULL))), __temp26);
            (new_array_type == NULL ? NULL : (new_array_type = (g_object_unref (new_array_type), NULL)));
      }
      return array_type;
      (array_type == NULL ? NULL : (array_type = (g_object_unref (array_type), NULL)));
}


/**
 * Checks whether this data type is a subtype of the specified data
 * type.
 *
 * @param t a data type
 * @return  true if t is a supertype of this data type, false otherwise
 */
static gboolean vala_data_type_real_is_subtype_of (ValaDataType* self, ValaDataType* t)
{
      g_return_val_if_fail (VALA_IS_DATA_TYPE (self), FALSE);
      g_return_val_if_fail (VALA_IS_DATA_TYPE (t), FALSE);
      return FALSE;
}


gboolean vala_data_type_is_subtype_of (ValaDataType* self, ValaDataType* t)
{
      return VALA_DATA_TYPE_GET_CLASS (self)->is_subtype_of (self, t);
}


/**
 * Return the index of the specified type parameter name.
 */
static gint vala_data_type_real_get_type_parameter_index (ValaDataType* self, const char* name)
{
      g_return_val_if_fail (VALA_IS_DATA_TYPE (self), 0);
      g_return_val_if_fail (name != NULL, 0);
      return -1;
}


gint vala_data_type_get_type_parameter_index (ValaDataType* self, const char* name)
{
      return VALA_DATA_TYPE_GET_CLASS (self)->get_type_parameter_index (self, name);
}


static void vala_data_type_class_init (ValaDataTypeClass * klass)
{
      vala_data_type_parent_class = g_type_class_peek_parent (klass);
      g_type_class_add_private (klass, sizeof (ValaDataTypePrivate));
      G_OBJECT_CLASS (klass)->dispose = vala_data_type_dispose;
      VALA_DATA_TYPE_CLASS (klass)->is_reference_type = vala_data_type_real_is_reference_type;
      VALA_DATA_TYPE_CLASS (klass)->get_dup_function = vala_data_type_real_get_dup_function;
      VALA_DATA_TYPE_CLASS (klass)->get_free_function = vala_data_type_real_get_free_function;
      VALA_DATA_TYPE_CLASS (klass)->is_reference_counting = vala_data_type_real_is_reference_counting;
      VALA_DATA_TYPE_CLASS (klass)->get_ref_function = vala_data_type_real_get_ref_function;
      VALA_DATA_TYPE_CLASS (klass)->get_unref_function = vala_data_type_real_get_unref_function;
      VALA_DATA_TYPE_CLASS (klass)->get_type_id = vala_data_type_real_get_type_id;
      VALA_DATA_TYPE_CLASS (klass)->get_marshaller_type_name = vala_data_type_real_get_marshaller_type_name;
      VALA_DATA_TYPE_CLASS (klass)->get_get_value_function = vala_data_type_real_get_get_value_function;
      VALA_DATA_TYPE_CLASS (klass)->get_set_value_function = vala_data_type_real_get_set_value_function;
      VALA_DATA_TYPE_CLASS (klass)->get_upper_case_cname = vala_data_type_real_get_upper_case_cname;
      VALA_DATA_TYPE_CLASS (klass)->get_default_value = vala_data_type_real_get_default_value;
      VALA_SYMBOL_CLASS (klass)->get_cheader_filenames = vala_data_type_real_get_cheader_filenames;
      VALA_DATA_TYPE_CLASS (klass)->is_subtype_of = vala_data_type_real_is_subtype_of;
      VALA_DATA_TYPE_CLASS (klass)->get_type_parameter_index = vala_data_type_real_get_type_parameter_index;
}


static void vala_data_type_init (ValaDataType * self)
{
      self->priv = VALA_DATA_TYPE_GET_PRIVATE (self);
      self->priv->cheader_filenames = GEE_LIST (gee_array_list_new (g_strdup, g_free, g_direct_equal));
}


static void vala_data_type_dispose (GObject * obj)
{
      ValaDataType * self;
      ValaDataTypeClass * klass;
      GObjectClass * parent_class;
      self = VALA_DATA_TYPE (obj);
      (self->priv->cheader_filenames == NULL ? NULL : (self->priv->cheader_filenames = (g_object_unref (self->priv->cheader_filenames), NULL)));
      (self->priv->pointer_type == NULL ? NULL : (self->priv->pointer_type = (g_object_unref (self->priv->pointer_type), NULL)));
      (self->priv->array_types == NULL ? NULL : (self->priv->array_types = (g_object_unref (self->priv->array_types), NULL)));
      klass = VALA_DATA_TYPE_CLASS (g_type_class_peek (VALA_TYPE_DATA_TYPE));
      parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
      parent_class->dispose (obj);
}


GType vala_data_type_get_type (void)
{
      static GType vala_data_type_type_id = 0;
      if (G_UNLIKELY (vala_data_type_type_id == 0)) {
            static const GTypeInfo g_define_type_info = { sizeof (ValaDataTypeClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) vala_data_type_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ValaDataType), 0, (GInstanceInitFunc) vala_data_type_init };
            vala_data_type_type_id = g_type_register_static (VALA_TYPE_SYMBOL, "ValaDataType", &g_define_type_info, G_TYPE_FLAG_ABSTRACT);
      }
      return vala_data_type_type_id;
}





Generated by  Doxygen 1.6.0   Back to index